mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +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 {
|
||||
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;
|
||||
|
||||
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.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
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.IASTName;
|
||||
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.ProblemBinding;
|
||||
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.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
|
||||
* a corresponding textual definition in the source code.
|
||||
|
@ -910,7 +910,7 @@ public class ClassTypeHelper {
|
|||
ICPPClassType specialized = ((ICPPClassSpecialization) classType).getSpecializedBinding();
|
||||
if (!specialized.equals(member.getOwner())) {
|
||||
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();
|
||||
}
|
||||
return specialized.getVisibility(member);
|
||||
|
@ -920,13 +920,46 @@ public class ClassTypeHelper {
|
|||
}
|
||||
}
|
||||
|
||||
int visibility = classType.getKey() == ICPPClassType.k_class ?
|
||||
ICPPClassType.v_private : ICPPClassType.v_public;
|
||||
ICPPASTCompositeTypeSpecifier classDeclSpec = classType.getCompositeTypeSpecifier();
|
||||
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) {
|
||||
if (hostMember instanceof ICPPASTVisibilityLabel) {
|
||||
visibility = ((ICPPASTVisibilityLabel) hostMember).getVisibility();
|
||||
continue;
|
||||
}
|
||||
while (hostMember instanceof ICPPASTTemplateDeclaration) {
|
||||
hostMember = ((ICPPASTTemplateDeclaration) hostMember).getDeclaration();
|
||||
|
@ -970,7 +1003,8 @@ public class ClassTypeHelper {
|
|||
}
|
||||
}
|
||||
} else if (hostMember instanceof IASTFunctionDefinition) {
|
||||
IASTFunctionDeclarator declarator = ((IASTFunctionDefinition) hostMember).getDeclarator();
|
||||
IASTDeclarator declarator = ((IASTFunctionDefinition) hostMember).getDeclarator();
|
||||
declarator = ASTQueries.findInnermostDeclarator(declarator);
|
||||
IBinding functionBinding = declarator.getName().resolveBinding();
|
||||
if (member.equals(functionBinding)){
|
||||
return visibility;
|
||||
|
@ -992,13 +1026,14 @@ public class ClassTypeHelper {
|
|||
}
|
||||
}
|
||||
}
|
||||
ICPPMethod[] implicitMethods = getImplicitMethods(classType, null);
|
||||
for (ICPPMethod implicitMethod : implicitMethods) {
|
||||
if (member.equals(implicitMethod)) {
|
||||
return ICPPClassType.v_public;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(member.getName() + " is not a member of " + classType.getName()); //$NON-NLS-1$
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static IllegalArgumentException invalidMember(IBinding classType, IBinding member) {
|
||||
String name = member.getName();
|
||||
if (name.isEmpty())
|
||||
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,
|
||||
|
|
|
@ -2554,6 +2554,14 @@ public class CPPVisitor extends ASTQueries {
|
|||
* of the above constructs.
|
||||
*/
|
||||
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
|
||||
boolean isNonSimpleElabDecl= false;
|
||||
while (!(node instanceof IASTDeclaration) && !(node instanceof ICPPASTLambdaExpression)) {
|
||||
|
@ -2605,10 +2613,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (name == null)
|
||||
return null;
|
||||
|
||||
return name.resolveBinding();
|
||||
return name;
|
||||
}
|
||||
|
||||
public static boolean doesNotSpecifyType(IASTDeclSpecifier declspec) {
|
||||
|
|
|
@ -668,6 +668,18 @@ public class PDOMASTAdapter {
|
|||
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
|
||||
* 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 CPPClosureType)
|
||||
return ICPPClassType.v_public;
|
||||
binding = PDOMASTAdapter.getOriginalForAdaptedBinding(binding);
|
||||
visibility = ((ICPPClassType) bindingOwner).getVisibility(binding);
|
||||
}
|
||||
return visibility;
|
||||
|
|
Loading…
Add table
Reference in a new issue