mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 09:16:02 +02:00
Bug 409444 - IllegalArgumentException while indexing
This commit is contained in:
parent
619e22ea88
commit
51e8509b3e
5 changed files with 89 additions and 27 deletions
|
@ -2313,4 +2313,13 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
public void testRegression_408314() throws Exception {
|
public void testRegression_408314() throws Exception {
|
||||||
checkBindings();
|
checkBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<typename T> struct A { enum { v = 0 }; };
|
||||||
|
// template<> struct A<int> { enum { v = 1 }; };
|
||||||
|
// template<> struct A<int> { enum { v = 1 }; };
|
||||||
|
|
||||||
|
// int main() {}
|
||||||
|
public void testSpecializationRedefinition_409444() throws Exception {
|
||||||
|
checkBindings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,20 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
@ -64,19 +73,10 @@ 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.ASTQueries;
|
||||||
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.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds common implementation of methods for ICPPClassType implementations that have
|
* Holds common implementation of methods for ICPPClassType implementations that have
|
||||||
* a corresponding textual definition in the source code.
|
* a corresponding textual definition in the source code.
|
||||||
|
@ -910,7 +910,7 @@ public class ClassTypeHelper {
|
||||||
ICPPClassType specialized = ((ICPPClassSpecialization) classType).getSpecializedBinding();
|
ICPPClassType specialized = ((ICPPClassSpecialization) classType).getSpecializedBinding();
|
||||||
if (!specialized.equals(member.getOwner())) {
|
if (!specialized.equals(member.getOwner())) {
|
||||||
if (!(member instanceof ICPPSpecialization))
|
if (!(member instanceof ICPPSpecialization))
|
||||||
throw new IllegalArgumentException(member.getName() + " is not a member of " + specialized.getName()); //$NON-NLS-1$
|
throw invalidMember(specialized, member);
|
||||||
member = ((ICPPSpecialization) member).getSpecializedBinding();
|
member = ((ICPPSpecialization) member).getSpecializedBinding();
|
||||||
}
|
}
|
||||||
return specialized.getVisibility(member);
|
return specialized.getVisibility(member);
|
||||||
|
@ -920,13 +920,46 @@ public class ClassTypeHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int visibility = classType.getKey() == ICPPClassType.k_class ?
|
ICPPASTCompositeTypeSpecifier classDeclSpec = classType.getCompositeTypeSpecifier();
|
||||||
ICPPClassType.v_private : ICPPClassType.v_public;
|
int visibility = getVisibility(classDeclSpec, member);
|
||||||
|
if (visibility >= 0)
|
||||||
|
return visibility;
|
||||||
|
|
||||||
IASTDeclaration[] hostMembers = classType.getCompositeTypeSpecifier().getMembers();
|
ICPPMethod[] implicitMethods = getImplicitMethods(classType, null);
|
||||||
|
for (ICPPMethod implicitMethod : implicitMethods) {
|
||||||
|
if (member.equals(implicitMethod)) {
|
||||||
|
return ICPPClassType.v_public;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's possible that we haven't found the member because the class was illegally redefined
|
||||||
|
// and the member belongs to another definition. Try to search the definition containing
|
||||||
|
// the member.
|
||||||
|
if (member instanceof ICPPInternalBinding) {
|
||||||
|
IASTNode node = ((ICPPInternalBinding) member).getDefinition();
|
||||||
|
if (node != null) {
|
||||||
|
IASTName ownerName = CPPVisitor.findDeclarationOwnerDefinition(node, false);
|
||||||
|
if (ownerName != null && !ownerName.equals(classDeclSpec.getName()) &&
|
||||||
|
ownerName.getPropertyInParent() == ICPPASTCompositeTypeSpecifier.TYPE_NAME) {
|
||||||
|
classDeclSpec = (ICPPASTCompositeTypeSpecifier) ownerName.getParent();
|
||||||
|
visibility = getVisibility(classDeclSpec, member);
|
||||||
|
if (visibility >= 0)
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw invalidMember(classType, member);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getVisibility(ICPPASTCompositeTypeSpecifier classDeclSpec, IBinding member) {
|
||||||
|
int visibility = classDeclSpec.getKey() == ICPPASTCompositeTypeSpecifier.k_class ?
|
||||||
|
ICPPClassType.v_private : ICPPClassType.v_public;
|
||||||
|
IASTDeclaration[] hostMembers = classDeclSpec.getMembers();
|
||||||
for (IASTDeclaration hostMember : hostMembers) {
|
for (IASTDeclaration hostMember : hostMembers) {
|
||||||
if (hostMember instanceof ICPPASTVisibilityLabel) {
|
if (hostMember instanceof ICPPASTVisibilityLabel) {
|
||||||
visibility = ((ICPPASTVisibilityLabel) hostMember).getVisibility();
|
visibility = ((ICPPASTVisibilityLabel) hostMember).getVisibility();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
while (hostMember instanceof ICPPASTTemplateDeclaration) {
|
while (hostMember instanceof ICPPASTTemplateDeclaration) {
|
||||||
hostMember = ((ICPPASTTemplateDeclaration) hostMember).getDeclaration();
|
hostMember = ((ICPPASTTemplateDeclaration) hostMember).getDeclaration();
|
||||||
|
@ -970,7 +1003,8 @@ public class ClassTypeHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (hostMember instanceof IASTFunctionDefinition) {
|
} else if (hostMember instanceof IASTFunctionDefinition) {
|
||||||
IASTFunctionDeclarator declarator = ((IASTFunctionDefinition) hostMember).getDeclarator();
|
IASTDeclarator declarator = ((IASTFunctionDefinition) hostMember).getDeclarator();
|
||||||
|
declarator = ASTQueries.findInnermostDeclarator(declarator);
|
||||||
IBinding functionBinding = declarator.getName().resolveBinding();
|
IBinding functionBinding = declarator.getName().resolveBinding();
|
||||||
if (member.equals(functionBinding)){
|
if (member.equals(functionBinding)){
|
||||||
return visibility;
|
return visibility;
|
||||||
|
@ -992,13 +1026,14 @@ public class ClassTypeHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ICPPMethod[] implicitMethods = getImplicitMethods(classType, null);
|
return -1;
|
||||||
for (ICPPMethod implicitMethod : implicitMethods) {
|
}
|
||||||
if (member.equals(implicitMethod)) {
|
|
||||||
return ICPPClassType.v_public;
|
private static IllegalArgumentException invalidMember(IBinding classType, IBinding member) {
|
||||||
}
|
String name = member.getName();
|
||||||
}
|
if (name.isEmpty())
|
||||||
throw new IllegalArgumentException(member.getName() + " is not a member of " + classType.getName()); //$NON-NLS-1$
|
name = "<anonymous>"; //$NON-NLS-1$
|
||||||
|
return new IllegalArgumentException(name + " is not a member of " + classType.getName()); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, List<ICPPMethod>> collectPureVirtualMethods(ICPPClassType classType,
|
private static Map<String, List<ICPPMethod>> collectPureVirtualMethods(ICPPClassType classType,
|
||||||
|
|
|
@ -2554,6 +2554,14 @@ public class CPPVisitor extends ASTQueries {
|
||||||
* of the above constructs.
|
* of the above constructs.
|
||||||
*/
|
*/
|
||||||
public static IBinding findDeclarationOwner(IASTNode node, boolean allowFunction) {
|
public static IBinding findDeclarationOwner(IASTNode node, boolean allowFunction) {
|
||||||
|
IASTName name = findDeclarationOwnerDefinition(node, allowFunction);
|
||||||
|
if (name == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return name.resolveBinding();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IASTName findDeclarationOwnerDefinition(IASTNode node, boolean allowFunction) {
|
||||||
// Search for declaration
|
// Search for declaration
|
||||||
boolean isNonSimpleElabDecl= false;
|
boolean isNonSimpleElabDecl= false;
|
||||||
while (!(node instanceof IASTDeclaration) && !(node instanceof ICPPASTLambdaExpression)) {
|
while (!(node instanceof IASTDeclaration) && !(node instanceof ICPPASTLambdaExpression)) {
|
||||||
|
@ -2605,10 +2613,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name == null)
|
return name;
|
||||||
return null;
|
|
||||||
|
|
||||||
return name.resolveBinding();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean doesNotSpecifyType(IASTDeclSpecifier declspec) {
|
public static boolean doesNotSpecifyType(IASTDeclSpecifier declspec) {
|
||||||
|
|
|
@ -668,6 +668,18 @@ public class PDOMASTAdapter {
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the original binding from an adapter previously returned by
|
||||||
|
* {@link #getAdapterForAnonymousASTBinding(IBinding)}. If the parameter binding is not
|
||||||
|
* an adapter, returns the binding itself.
|
||||||
|
*/
|
||||||
|
public static IBinding getOriginalForAdaptedBinding(IBinding binding) {
|
||||||
|
if (binding instanceof AnonymousCPPBinding) {
|
||||||
|
return ((AnonymousCPPBinding) binding).fDelegate;
|
||||||
|
}
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the name is empty and has no file location, either an adapter
|
* 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
|
* that has a file location is returned, or <code>null</code> if that
|
||||||
|
|
|
@ -529,6 +529,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
if (bindingOwner instanceof ICPPClassType) {
|
if (bindingOwner instanceof ICPPClassType) {
|
||||||
if (bindingOwner instanceof CPPClosureType)
|
if (bindingOwner instanceof CPPClosureType)
|
||||||
return ICPPClassType.v_public;
|
return ICPPClassType.v_public;
|
||||||
|
binding = PDOMASTAdapter.getOriginalForAdaptedBinding(binding);
|
||||||
visibility = ((ICPPClassType) bindingOwner).getVisibility(binding);
|
visibility = ((ICPPClassType) bindingOwner).getVisibility(binding);
|
||||||
}
|
}
|
||||||
return visibility;
|
return visibility;
|
||||||
|
|
Loading…
Add table
Reference in a new issue