mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 09:46:02 +02:00
Bug 438114 - Friend function declaration is not reconciled with other
declarations
This commit is contained in:
parent
820b901b69
commit
e6b392ffbc
4 changed files with 109 additions and 21 deletions
|
@ -6891,6 +6891,27 @@ public class AST2CPPTests extends AST2TestBase {
|
|||
assertSame(g1, g2);
|
||||
}
|
||||
|
||||
// template <typename T>
|
||||
// class A {
|
||||
// template <typename U>
|
||||
// friend int func(int i);
|
||||
// };
|
||||
//
|
||||
// template <typename U>
|
||||
// int func(int i = 0);
|
||||
//
|
||||
// template <typename U>
|
||||
// int func(int i) { return i; }
|
||||
public void testFriendFunction_438114() throws Exception {
|
||||
BindingAssertionHelper bh = getAssertionHelper();
|
||||
ICPPFunction f1= bh.assertNonProblemOnFirstIdentifier("func(int i);");
|
||||
ICPPFunction f2= bh.assertNonProblemOnFirstIdentifier("func(int i = 0);");
|
||||
ICPPFunction f3= bh.assertNonProblemOnFirstIdentifier("func(int i) {");
|
||||
assertSame(f1, f2);
|
||||
assertSame(f2, f3);
|
||||
assertEquals(0, f1.getRequiredArgumentCount());
|
||||
}
|
||||
|
||||
// class A {
|
||||
// public:
|
||||
// void foo() const volatile;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2013 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2014 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
|
||||
|
@ -29,7 +29,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
|
@ -43,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||
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.ICPPFunction;
|
||||
|
@ -169,23 +169,46 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
|
|||
|
||||
@Override
|
||||
public ICPPParameter[] getParameters() {
|
||||
IASTStandardFunctionDeclarator dtor = getPreferredDtor();
|
||||
if (dtor == null) {
|
||||
ICPPASTFunctionDeclarator declarator = getDefinition();
|
||||
IASTDeclarator[] dtors = getDeclarations();
|
||||
if (dtors != null) {
|
||||
// In case of multiple function declarations we select the one with the most
|
||||
// default parameter values.
|
||||
int defaultValuePosition = -1;
|
||||
for (IASTDeclarator dtor : dtors) {
|
||||
if (dtor instanceof ICPPASTFunctionDeclarator) {
|
||||
if (declarator == null) {
|
||||
declarator = (ICPPASTFunctionDeclarator) dtor;
|
||||
} else {
|
||||
ICPPASTFunctionDeclarator contender = (ICPPASTFunctionDeclarator) dtor;
|
||||
if (defaultValuePosition < 0)
|
||||
defaultValuePosition = findFirstDefaultValue(declarator.getParameters());
|
||||
int pos = findFirstDefaultValue(contender.getParameters());
|
||||
if (pos < defaultValuePosition) {
|
||||
declarator = contender;
|
||||
defaultValuePosition = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (declarator == null) {
|
||||
return CPPBuiltinParameter.createParameterList(getType());
|
||||
}
|
||||
IASTParameterDeclaration[] params = dtor.getParameters();
|
||||
IASTParameterDeclaration[] params = declarator.getParameters();
|
||||
int size = params.length;
|
||||
ICPPParameter[] result = new ICPPParameter[size];
|
||||
if (size > 0) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
IASTParameterDeclaration p = params[i];
|
||||
final IASTName name = getParamName(p);
|
||||
IASTParameterDeclaration param = params[i];
|
||||
final IASTName name = getParamName(param);
|
||||
final IBinding binding= name.resolveBinding();
|
||||
if (binding instanceof ICPPParameter) {
|
||||
result[i]= (ICPPParameter) binding;
|
||||
} else {
|
||||
result[i] = new CPPParameter.CPPParameterProblem(p,
|
||||
IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
|
||||
result[i] = new CPPParameter.CPPParameterProblem(
|
||||
param, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +218,18 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the first parameter that has a default value.
|
||||
* If none of the parameters has a default value, return the number of parameters.
|
||||
*/
|
||||
static int findFirstDefaultValue(ICPPASTParameterDeclaration[] parameters) {
|
||||
for (int i = parameters.length; --i >= 0;) {
|
||||
if (parameters[i].getDeclarator().getInitializer() == null)
|
||||
return i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScope getFunctionScope() {
|
||||
resolveAllDeclarations();
|
||||
|
@ -598,7 +633,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
|
|||
return (ICPPASTFunctionDeclarator) declarator;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return dtor;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2012 IBM Corporation and others.
|
||||
* Copyright (c) 2005, 2014 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
|
||||
|
@ -46,7 +46,7 @@ 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.
|
||||
*/
|
||||
public class CPPFunctionTemplate extends CPPTemplateDefinition
|
||||
implements ICPPFunctionTemplate, ICPPInternalFunction {
|
||||
|
@ -99,23 +99,51 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
|
|||
|
||||
@Override
|
||||
public ICPPParameter[] getParameters() {
|
||||
ICPPASTFunctionDeclarator fdecl= getFirstFunctionDtor();
|
||||
if (fdecl != null) {
|
||||
IASTParameterDeclaration[] params = fdecl.getParameters();
|
||||
ICPPASTFunctionDeclarator declarator= null;
|
||||
IASTDeclarator dtor= getDeclaratorByName(getDefinition());
|
||||
if (dtor instanceof ICPPASTFunctionDeclarator)
|
||||
declarator = (ICPPASTFunctionDeclarator) dtor;
|
||||
|
||||
IASTNode[] decls = getDeclarations();
|
||||
if (decls != null) {
|
||||
// In case of multiple function declarations we select the one with the most
|
||||
// default parameter values.
|
||||
int defaultValuePosition = -1;
|
||||
for (IASTNode decl : decls) {
|
||||
dtor= getDeclaratorByName(decl);
|
||||
if (dtor instanceof ICPPASTFunctionDeclarator) {
|
||||
if (declarator == null) {
|
||||
declarator = (ICPPASTFunctionDeclarator) dtor;
|
||||
} else {
|
||||
ICPPASTFunctionDeclarator contender = (ICPPASTFunctionDeclarator) dtor;
|
||||
if (defaultValuePosition < 0)
|
||||
defaultValuePosition = CPPFunction.findFirstDefaultValue(declarator.getParameters());
|
||||
int pos = CPPFunction.findFirstDefaultValue(contender.getParameters());
|
||||
if (pos < defaultValuePosition) {
|
||||
declarator = contender;
|
||||
defaultValuePosition = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (declarator != null) {
|
||||
IASTParameterDeclaration[] params = declarator.getParameters();
|
||||
int size = params.length;
|
||||
if (size == 0) {
|
||||
return ICPPParameter.EMPTY_CPPPARAMETER_ARRAY;
|
||||
}
|
||||
ICPPParameter[] result = new ICPPParameter[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
IASTParameterDeclaration p = params[i];
|
||||
final IASTName pname = ASTQueries.findInnermostDeclarator(p.getDeclarator()).getName();
|
||||
IASTParameterDeclaration param = params[i];
|
||||
final IASTName pname = ASTQueries.findInnermostDeclarator(param.getDeclarator()).getName();
|
||||
final IBinding binding= pname.resolveBinding();
|
||||
if (binding instanceof ICPPParameter) {
|
||||
result[i]= (ICPPParameter) binding;
|
||||
} else {
|
||||
result[i] = new CPPParameter.CPPParameterProblem(p,
|
||||
IProblemBinding.SEMANTIC_INVALID_TYPE, pname.toCharArray());
|
||||
result[i] = new CPPParameter.CPPParameterProblem(
|
||||
param, IProblemBinding.SEMANTIC_INVALID_TYPE, pname.toCharArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2013 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2014 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
|
||||
|
@ -171,6 +171,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
|
||||
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.SizeofCalculator;
|
||||
|
@ -896,6 +897,9 @@ public class CPPVisitor extends ASTQueries {
|
|||
: new CPPFunction(typeRelevantDtor);
|
||||
}
|
||||
binding= CPPSemantics.checkDeclSpecifier(binding, name, parent);
|
||||
if (isFriendDecl && scope instanceof IASTInternalScope) {
|
||||
((IASTInternalScope) scope).addBinding(binding);
|
||||
}
|
||||
}
|
||||
|
||||
return binding;
|
||||
|
|
Loading…
Add table
Reference in a new issue