1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

Bug 423127 - Template resolution gets confused by "void" in a parameter

list

Change-Id: I6d2510ce7f1c8007da7121855bc4870e4a57d15d
Reviewed-on: https://git.eclipse.org/r/19355
Tested-by: Hudson CI
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Sergey Prigogin 2013-12-04 19:47:59 -08:00
parent ff8baa2754
commit 424c2898fe
14 changed files with 80 additions and 57 deletions

View file

@ -1275,17 +1275,13 @@ public class AST2CPPTests extends AST2TestBase {
ICPPConstructor[] ctors = A.getConstructors(); ICPPConstructor[] ctors = A.getConstructors();
assertNotNull(ctors); assertNotNull(ctors);
assertEquals(ctors.length, 2); assertEquals(2, ctors.length);
assertEquals(ctors[0].getParameters().length, 1); assertEquals(0, ctors[0].getParameters().length);
IType t = ctors[0].getParameters()[0].getType(); assertEquals(1, ctors[1].getParameters().length);
assertTrue(t instanceof IBasicType);
assertEquals(((IBasicType) t).getType(), IBasicType.t_void);
assertEquals(ctors[1].getParameters().length, 1); IType t = ctors[1].getParameters()[0].getType();
t = ctors[1].getParameters()[0].getType();
assertTrue(t instanceof ICPPReferenceType); assertTrue(t instanceof ICPPReferenceType);
assertTrue(((ICPPReferenceType) t).getType() instanceof IQualifierType); assertTrue(((ICPPReferenceType) t).getType() instanceof IQualifierType);
IQualifierType qt = (IQualifierType) ((ICPPReferenceType) t).getType(); IQualifierType qt = (IQualifierType) ((ICPPReferenceType) t).getType();
@ -1305,8 +1301,8 @@ public class AST2CPPTests extends AST2TestBase {
assertNotNull(ctors); assertNotNull(ctors);
assertEquals(ctors.length, 2); assertEquals(ctors.length, 2);
assertEquals(ctors[0].getParameters().length, 1); assertEquals(0, ctors[0].getParameters().length);
assertEquals(ctors[1].getParameters().length, 1); assertEquals(1, ctors[1].getParameters().length);
IType t = ctors[1].getParameters()[0].getType(); IType t = ctors[1].getParameters()[0].getType();
assertTrue(t instanceof ICPPReferenceType); assertTrue(t instanceof ICPPReferenceType);

View file

@ -5617,6 +5617,23 @@ public class AST2TemplateTests extends AST2TestBase {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <class T1, class T2, class U>
// void A(T1* obj, void (T2::*member)(U));
//
// template <class T1, class T2>
// void A(T1* obj, void (T2::*member)());
//
// class B {
// void m1(void);
//
// void m2() {
// A(this, &B::m1);
// }
// };
public void testFunctionWithVoidParamInTypeDeduction_423127() throws Exception {
parseAndCheckBindings();
}
// template<typename T, unsigned length> struct Templ { // template<typename T, unsigned length> struct Templ {
// Templ(){} // Templ(){}
// }; // };

View file

@ -22,6 +22,7 @@ import java.io.IOException;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException; import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
@ -41,7 +42,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
@ -2288,10 +2288,8 @@ public class AST2Tests extends AST2TestBase {
assertTrue(gt_2 instanceof IFunctionType); assertTrue(gt_2 instanceof IFunctionType);
IType gt_ret = ((IFunctionType) gt_2).getReturnType(); IType gt_ret = ((IFunctionType) gt_2).getReturnType();
assertTrue(gt_ret instanceof IBasicType); assertTrue(gt_ret instanceof IBasicType);
assertEquals(((IBasicType) gt_ret).getType(), IBasicType.t_int); assertEquals(((IBasicType) gt_ret).getKind(), IBasicType.Kind.eInt);
IType gt_parm = ((IFunctionType) gt_2).getParameterTypes()[0]; assertEquals(0, ((IFunctionType) gt_2).getParameterTypes().length);
assertTrue(gt_parm instanceof IBasicType);
assertEquals(((IBasicType) gt_parm).getType(), IBasicType.t_void);
// test tu.getDeclarationsInAST(IBinding) // test tu.getDeclarationsInAST(IBinding)
assertTrue(def.getDeclarator() instanceof IASTStandardFunctionDeclarator); assertTrue(def.getDeclarator() instanceof IASTStandardFunctionDeclarator);
@ -4970,31 +4968,24 @@ public class AST2Tests extends AST2TestBase {
} }
// typedef void VOID; // typedef void VOID;
// VOID func(VOID) { // VOID func(void) {
// } // }
public void testTypedefVoid_221567() throws Exception { public void testTypedefVoid_221567() throws Exception {
String code= getAboveComment(); String code= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) { for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(code, lang); BindingAssertionHelper ba= new BindingAssertionHelper(code, lang);
ITypedef td= ba.assertNonProblem("VOID;", 4, ITypedef.class); ITypedef td= ba.assertNonProblem("VOID;", 4, ITypedef.class);
IBinding ref= ba.assertNonProblem("VOID)", 4);
assertSame(td, ref);
IFunction func= ba.assertNonProblem("func", 4, IFunction.class); IFunction func= ba.assertNonProblem("func", 4, IFunction.class);
IFunctionType ft= func.getType(); IFunctionType ft= func.getType();
IType rt= ft.getReturnType(); IType rt= ft.getReturnType();
IType[] pts= ft.getParameterTypes(); IType[] pts= ft.getParameterTypes();
assertEquals(1, pts.length); assertEquals(0, pts.length);
IType pt = pts[0];
assertInstance(rt, ITypedef.class); assertInstance(rt, ITypedef.class);
assertInstance(pt, ITypedef.class);
rt= ((ITypedef) rt).getType(); rt= ((ITypedef) rt).getType();
pt= ((ITypedef) pt).getType();
assertTrue(rt instanceof IBasicType); assertTrue(rt instanceof IBasicType);
assertEquals(IBasicType.t_void, ((IBasicType) rt).getType()); assertEquals(IBasicType.Kind.eVoid, ((IBasicType) rt).getKind());
assertTrue(pt instanceof IBasicType);
assertEquals(IBasicType.t_void, ((IBasicType) pt).getType());
} }
} }

View file

@ -417,8 +417,7 @@ public class CompleteParser2Tests extends BaseTestCase {
IFunction foo = (IFunction) col.getName(0).resolveBinding(); IFunction foo = (IFunction) col.getName(0).resolveBinding();
IParameter p = (IParameter) col.getName(1).resolveBinding(); IParameter p = (IParameter) col.getName(1).resolveBinding();
assertEquals(foo.getParameters().length, 1); assertEquals(0, foo.getParameters().length);
assertSame(foo.getParameters()[0], p);
assertSame(p.getScope(), foo.getFunctionScope()); assertSame(p.getScope(), foo.getFunctionScope());
} }

View file

@ -70,11 +70,10 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
assertTrue(b0 instanceof IFunction); assertTrue(b0 instanceof IFunction);
IFunction f0 = (IFunction) b0; IFunction f0 = (IFunction) b0;
IParameter[] params= f0.getParameters(); IParameter[] params= f0.getParameters();
assertEquals(1, params.length); assertEquals(0, params.length);
IType param= params[0].getType();
assertTrue(param instanceof IBasicType);
IType returnType= f0.getType().getReturnType(); IType returnType= f0.getType().getReturnType();
assertTrue(returnType instanceof IBasicType); assertTrue(returnType instanceof IBasicType);
assertEquals(IBasicType.Kind.eVoid, ((IBasicType) returnType).getKind());
} }
// void func1(void); // void func1(void);

View file

@ -542,7 +542,7 @@ public class IndexUpdateTests extends IndexTestBase {
new String[] {IMPLICIT, PUBLIC}); new String[] {IMPLICIT, PUBLIC});
updateFile(); updateFile();
checkImplicitMethods("MyClass", checkImplicitMethods("MyClass",
null, // no default constructor, because we declared the copy constr. null, // no default constructor, because we declared the copy constructor.
new String[] {EXPLICIT, PRIVATE}, new String[] {EXPLICIT, PRIVATE},
new String[] {IMPLICIT, PUBLIC}); new String[] {IMPLICIT, PUBLIC});
updateFile(); updateFile();
@ -563,7 +563,7 @@ public class IndexUpdateTests extends IndexTestBase {
final char[] nchars = name.toCharArray(); final char[] nchars = name.toCharArray();
final String refType = name + " &"; final String refType = name + " &";
final String constRefType = "const " + refType; final String constRefType = "const " + refType;
IIndexBinding[] ctors= fIndex.findBindings(new char[][]{nchars, nchars}, IndexFilter.ALL_DECLARED_OR_IMPLICIT, npm()); IIndexBinding[] ctors= fIndex.findBindings(new char[][] {nchars, nchars}, IndexFilter.ALL_DECLARED_OR_IMPLICIT, npm());
int count= 0; int count= 0;
for (int i = 0; i < ctors.length; i++) { for (int i = 0; i < ctors.length; i++) {
@ -574,13 +574,13 @@ public class IndexUpdateTests extends IndexTestBase {
} }
assertEquals(m1 == null ? 1 : 2, count); assertEquals(m1 == null ? 1 : 2, count);
final IType[] parameterTypes = ((ICPPConstructor) ctors[0]).getType().getParameterTypes(); final IType[] parameterTypes = ((ICPPConstructor) ctors[0]).getType().getParameterTypes();
if (parameterTypes.length!=1 || !(parameterTypes[0] instanceof ICPPReferenceType)) { if (parameterTypes.length != 1 || !(parameterTypes[0] instanceof ICPPReferenceType)) {
IIndexBinding h= ctors[0]; ctors[0]= ctors[1]; ctors[1]= h; IIndexBinding h= ctors[0]; ctors[0]= ctors[1]; ctors[1]= h;
} }
if (m1 != null) { if (m1 != null) {
checkCppConstructor((ICPPConstructor) ctors[1], new String[]{"", "void"}, m1); checkCppConstructor((ICPPConstructor) ctors[1], new String[] {""}, m1);
} }
checkCppConstructor((ICPPConstructor) ctors[0], new String[]{"", constRefType}, m2); checkCppConstructor((ICPPConstructor) ctors[0], new String[] {"", constRefType}, m2);
IIndexBinding[] assignmentOps= fIndex.findBindings( IIndexBinding[] assignmentOps= fIndex.findBindings(
new char[][] {nchars, "operator =".toCharArray() }, IndexFilter.ALL_DECLARED_OR_IMPLICIT, npm()); new char[][] {nchars, "operator =".toCharArray() }, IndexFilter.ALL_DECLARED_OR_IMPLICIT, npm());

View file

@ -459,7 +459,9 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
private void function(String returnType, String name, String... parameterTypes) { private void function(String returnType, String name, String... parameterTypes) {
int len = parameterTypes.length; int len = parameterTypes.length;
boolean varargs= len > 0 && parameterTypes[len-1].equals("..."); if (len == 1 && parameterTypes[0].equals("void"))
len--;
boolean varargs= len > 0 && parameterTypes[len - 1].equals("...");
if (varargs) if (varargs)
len--; len--;
@ -473,9 +475,10 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
IType rt = toType(returnType); IType rt = toType(returnType);
IFunctionType ft = fCpp ? new CPPFunctionType(rt, pTypes) : new CFunctionType(rt, pTypes); IFunctionType ft = fCpp ? new CPPFunctionType(rt, pTypes) : new CFunctionType(rt, pTypes);
IBinding b = fCpp ? new CPPImplicitFunction(toCharArray(name), fScope, IBinding b = fCpp ?
(ICPPFunctionType) ft, (ICPPParameter[]) theParms, varargs) new CPPImplicitFunction(toCharArray(name), fScope, (ICPPFunctionType) ft,
: new CImplicitFunction(toCharArray(name), fScope, ft, theParms, varargs); (ICPPParameter[]) theParms, varargs) :
new CImplicitFunction(toCharArray(name), fScope, ft, theParms, varargs);
fBindingList.add(b); fBindingList.add(b);
} }

View file

@ -37,6 +37,7 @@ import org.eclipse.cdt.core.parser.util.AttributeUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
/** /**
@ -130,6 +131,9 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu
result[i] = (IParameter) ASTQueries.findInnermostDeclarator(p.getDeclarator()) result[i] = (IParameter) ASTQueries.findInnermostDeclarator(p.getDeclarator())
.getName().resolveBinding(); .getName().resolveBinding();
} }
if (result.length == 1 && SemanticUtil.isVoidType(result[0].getType()))
return IParameter.EMPTY_PARAMETER_ARRAY;
} }
return result; return result;
} }

View file

@ -103,6 +103,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory; import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory;
/** /**
@ -1375,6 +1376,9 @@ public class CVisitor extends ASTQueries {
for (int i = 0; i < parms.length; i++) { for (int i = 0; i < parms.length; i++) {
parmTypes[i] = createType(parms[i].getDeclarator()); parmTypes[i] = createType(parms[i].getDeclarator());
} }
if (parmTypes.length == 1 && SemanticUtil.isVoidType(parmTypes[0]))
return IType.EMPTY_TYPE_ARRAY; // f(void) is the same as f()
return parmTypes; return parmTypes;
} else if (decltor instanceof ICASTKnRFunctionDeclarator) { } else if (decltor instanceof ICASTKnRFunctionDeclarator) {
IASTName parms[] = ((ICASTKnRFunctionDeclarator) decltor).getParameterNames(); IASTName parms[] = ((ICASTKnRFunctionDeclarator) decltor).getParameterNames();

View file

@ -15,6 +15,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter.EMPTY_CPPPARAMETER_ARRAY;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
@ -102,7 +103,6 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
} }
char[] className = name.getLookupKey(); char[] className = name.getLookupKey();
ICPPParameter[] voidPs = new ICPPParameter[] { new CPPParameter(CPPSemantics.VOID_TYPE, 0) };
IType pType = new CPPReferenceType(SemanticUtil.constQualify(clsType), false); IType pType = new CPPReferenceType(SemanticUtil.constQualify(clsType), false);
ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) }; ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) };
@ -111,22 +111,21 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
implicits= new ICPPMethod[ia.getImplicitsToDeclareCount()]; implicits= new ICPPMethod[ia.getImplicitsToDeclareCount()];
if (!ia.hasUserDeclaredConstructor()) { if (!ia.hasUserDeclaredConstructor()) {
//default constructor: A(void) // Default constructor: A(void)
ICPPMethod m = new CPPImplicitConstructor(this, className, voidPs); ICPPMethod m = new CPPImplicitConstructor(this, className, EMPTY_CPPPARAMETER_ARRAY);
implicits[i++] = m; implicits[i++] = m;
addBinding(m); addBinding(m);
} }
if (!ia.hasUserDeclaredCopyConstructor()) { if (!ia.hasUserDeclaredCopyConstructor()) {
//copy constructor: A(const A &) // Copy constructor: A(const A &)
ICPPMethod m = new CPPImplicitConstructor(this, className, ps); ICPPMethod m = new CPPImplicitConstructor(this, className, ps);
implicits[i++] = m; implicits[i++] = m;
addBinding(m); addBinding(m);
} }
if (!ia.hasUserDeclaredCopyAssignmentOperator()) { if (!ia.hasUserDeclaredCopyAssignmentOperator()) {
//copy assignment operator: A& operator = (const A &) // Copy assignment operator: A& operator = (const A &)
IType refType = new CPPReferenceType(clsType, false); IType refType = new CPPReferenceType(clsType, false);
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, false, false); ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, false, false);
ICPPMethod m = new CPPImplicitMethod(this, OverloadableOperator.ASSIGN.toCharArray(), ft, ps); ICPPMethod m = new CPPImplicitMethod(this, OverloadableOperator.ASSIGN.toCharArray(), ft, ps);
@ -135,10 +134,10 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
} }
if (!ia.hasUserDeclaredDestructor()) { if (!ia.hasUserDeclaredDestructor()) {
//destructor: ~A() // Destructor: ~A()
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(new CPPBasicType(Kind.eUnspecified, 0), voidPs, false, false); ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(new CPPBasicType(Kind.eUnspecified, 0), EMPTY_CPPPARAMETER_ARRAY, false, false);
char[] dtorName = CharArrayUtils.concat("~".toCharArray(), className); //$NON-NLS-1$ char[] dtorName = CharArrayUtils.concat("~".toCharArray(), className); //$NON-NLS-1$
ICPPMethod m = new CPPImplicitMethod(this, dtorName, ft, voidPs); ICPPMethod m = new CPPImplicitMethod(this, dtorName, ft, EMPTY_CPPPARAMETER_ARRAY);
implicits[i++] = m; implicits[i++] = m;
addBinding(m); addBinding(m);
} }

View file

@ -184,10 +184,13 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
if (binding instanceof ICPPParameter) { if (binding instanceof ICPPParameter) {
result[i]= (ICPPParameter) binding; result[i]= (ICPPParameter) binding;
} else { } else {
result[i] = new CPPParameter.CPPParameterProblem(p, IProblemBinding.SEMANTIC_INVALID_TYPE, result[i] = new CPPParameter.CPPParameterProblem(p,
name.toCharArray()); IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
} }
} }
if (result.length == 1 && SemanticUtil.isVoidType(result[0].getType()))
return ICPPParameter.EMPTY_CPPPARAMETER_ARRAY; // f(void) is the same as f()
} }
return result; return result;
} }
@ -609,10 +612,10 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
final ICPPParameter p = pars[i]; final ICPPParameter p = pars[i];
if (p.hasDefaultValue() || p.isParameterPack()) { if (p.hasDefaultValue() || p.isParameterPack()) {
result--; result--;
} else { // } else {
if (pars.length == 1 && SemanticUtil.isVoidType(p.getType())) { // if (pars.length == 1 && SemanticUtil.isVoidType(p.getType())) {
return 0; // return 0;
} // }
} }
} }
return result; return result;

View file

@ -43,6 +43,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType; import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/** /**
* Implementation of function templates * Implementation of function templates
@ -117,6 +118,9 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
IProblemBinding.SEMANTIC_INVALID_TYPE, pname.toCharArray()); IProblemBinding.SEMANTIC_INVALID_TYPE, pname.toCharArray());
} }
} }
if (result.length == 1 && SemanticUtil.isVoidType(result[0].getType()))
return ICPPParameter.EMPTY_CPPPARAMETER_ARRAY; // f(void) is the same as f()
return result; return result;
} }
return CPPBuiltinParameter.createParameterList(getType()); return CPPBuiltinParameter.createParameterList(getType());

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -26,7 +26,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor { public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor {
public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params) { public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params) {
super( scope, name, createFunctionType(scope, params), params ); super(scope, name, createFunctionType(scope, params), params);
} }
private static ICPPFunctionType createFunctionType(ICPPClassScope scope, IParameter[] params) { private static ICPPFunctionType createFunctionType(ICPPClassScope scope, IParameter[] params) {

View file

@ -1837,6 +1837,10 @@ public class CPPVisitor extends ASTQueries {
for (int i = 0; i < params.length; i++) { for (int i = 0; i < params.length; i++) {
pTypes[i]= createType(params[i], true); pTypes[i]= createType(params[i], true);
} }
if (pTypes.length == 1 && SemanticUtil.isVoidType(pTypes[0])) {
return IType.EMPTY_TYPE_ARRAY; // f(void) is the same as f().
}
return pTypes; return pTypes;
} }