1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 06:45:43 +02:00

Bug 442832 - Template instantiation broken due to signature collision

This commit is contained in:
Sergey Prigogin 2014-08-28 15:16:22 -07:00
parent 11f921e614
commit ca60372079
2 changed files with 97 additions and 54 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2013 IBM Corporation and others. * Copyright (c) 2005, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8553,4 +8553,32 @@ public class AST2TemplateTests extends AST2TestBase {
public void testNameLookupInDefaultTemplateArgument_399145() throws Exception { public void testNameLookupInDefaultTemplateArgument_399145() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename T>
// struct A {
// typedef T t;
// };
//
// void f(char*);
// void g(int);
//
// void test() {
// {
// struct B {
// typedef char* b;
// };
// A<B>::t::b a;
// f(a);
// }
// {
// struct B {
// typedef int b;
// };
// A<B>::t::b a;
// g(a);
// }
// }
public void testLocalTypeAsTemplateArgument_442832() throws Exception {
parseAndCheckBindings();
}
} }

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.core.dom.ast.c.ICQualifierType; 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.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
@ -58,11 +59,10 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
/** /**
* This is a utility class to help convert AST elements to Strings corresponding to * Collection of static methods for converting AST elements to {@link String}s corresponding to
* the AST element's type. * the AST element's type.
* *
* @noextend This class is not intended to be subclassed by clients. * @noextend This class is not intended to be subclassed by clients.
* @noinstantiate This class is not intended to be instantiated by clients.
*/ */
public class ASTTypeUtil { public class ASTTypeUtil {
private static final String COMMA_SPACE = ", "; //$NON-NLS-1$ private static final String COMMA_SPACE = ", "; //$NON-NLS-1$
@ -70,6 +70,8 @@ public class ASTTypeUtil {
private static final String SPACE = " "; //$NON-NLS-1$ private static final String SPACE = " "; //$NON-NLS-1$
private static final int DEAULT_ITYPE_SIZE = 2; private static final int DEAULT_ITYPE_SIZE = 2;
private ASTTypeUtil() {}
/** /**
* Returns a string representation for the parameters of the given function type. * Returns a string representation for the parameters of the given function type.
* The representation contains the comma-separated list of the normalized parameter * The representation contains the comma-separated list of the normalized parameter
@ -577,44 +579,42 @@ public class ASTTypeUtil {
boolean needSpace= false; boolean needSpace= false;
for (int j = numTypes; --j >= 0;) { for (int j = numTypes; --j >= 0;) {
IType tj = types[j]; IType tj = types[j];
if (tj != null) { if (j > 0 && types[j - 1] instanceof IQualifierType) {
if (j > 0 && types[j - 1] instanceof IQualifierType) { if (needSpace)
if (needSpace)
result.append(SPACE);
appendTypeString(types[j - 1], normalize, result);
result.append(SPACE); result.append(SPACE);
appendTypeString(tj, normalize, result); appendTypeString(types[j - 1], normalize, result);
needSpace= true; result.append(SPACE);
--j; appendTypeString(tj, normalize, result);
} else { needSpace= true;
// Handle post-fix. --j;
if (tj instanceof IFunctionType || tj instanceof IArrayType) { } else {
if (j == 0) { // Handle post-fix.
if (needSpace) if (tj instanceof IFunctionType || tj instanceof IArrayType) {
result.append(SPACE); if (j == 0) {
appendTypeString(tj, normalize, result);
needSpace= true;
} else {
if (postfix == null) {
postfix= new ArrayList<>();
}
postfix.add(tj);
needParenthesis= true;
}
} else {
if (needSpace) if (needSpace)
result.append(SPACE); result.append(SPACE);
if (needParenthesis && postfix != null) {
result.append('(');
if (parenthesis == null) {
parenthesis= new BitSet();
}
parenthesis.set(postfix.size() - 1);
}
appendTypeString(tj, normalize, result); appendTypeString(tj, normalize, result);
needParenthesis= false;
needSpace= true; needSpace= true;
} else {
if (postfix == null) {
postfix= new ArrayList<>();
}
postfix.add(tj);
needParenthesis= true;
} }
} else {
if (needSpace)
result.append(SPACE);
if (needParenthesis && postfix != null) {
result.append('(');
if (parenthesis == null) {
parenthesis= new BitSet();
}
parenthesis.set(postfix.size() - 1);
}
appendTypeString(tj, normalize, result);
needParenthesis= false;
needSpace= true;
} }
} }
} }
@ -749,9 +749,9 @@ public class ASTTypeUtil {
appendTemplateParameter(tpar, normalize, result); appendTemplateParameter(tpar, normalize, result);
} else { } else {
if (qualify) { if (qualify) {
int pos= result.length();
IBinding owner= binding.getOwner(); IBinding owner= binding.getOwner();
if (owner instanceof ICPPNamespace || owner instanceof IType) { if (owner instanceof ICPPNamespace || owner instanceof IType) {
int pos= result.length();
appendCppName(owner, normalize, qualify, result); appendCppName(owner, normalize, qualify, result);
if (owner instanceof ICPPNamespace && owner.getNameCharArray().length == 0) { if (owner instanceof ICPPNamespace && owner.getNameCharArray().length == 0) {
if (binding instanceof IIndexBinding) { if (binding instanceof IIndexBinding) {
@ -776,9 +776,20 @@ public class ASTTypeUtil {
} }
} }
} }
if (result.length() > pos) } else if (binding instanceof IType && owner instanceof ICPPFunction) {
result.append("::"); //$NON-NLS-1$ try {
IScope scope = binding.getScope();
if (scope != null) {
IASTNode node = ASTInternal.getPhysicalNodeOfScope(scope);
if (node != null)
appendNodeLocation(node, true, result);
}
} catch (DOMException e) {
// Ignore.
}
} }
if (result.length() > pos)
result.append("::"); //$NON-NLS-1$
} }
appendNameCheckAnonymous(binding, result); appendNameCheckAnonymous(binding, result);
} }
@ -833,24 +844,28 @@ public class ASTTypeUtil {
node= ((ICPPInternalBinding) binding).getDefinition(); node= ((ICPPInternalBinding) binding).getDefinition();
} }
if (node != null) { if (node != null) {
IASTFileLocation loc= node.getFileLocation(); appendNodeLocation(node, !(binding instanceof ICPPNamespace), buf);
if (loc == null) { }
node= node.getParent(); }
if (node != null) {
loc= node.getFileLocation(); private static void appendNodeLocation(IASTNode node, boolean includeOffset, StringBuilder buf) {
} IASTFileLocation loc= node.getFileLocation();
if (loc == null) {
node= node.getParent();
if (node != null) {
loc= node.getFileLocation();
} }
if (loc != null) { }
char[] fname= loc.getFileName().toCharArray(); if (loc != null) {
int fnamestart= findFileNameStart(fname); char[] fname= loc.getFileName().toCharArray();
buf.append('{'); int fnamestart= findFileNameStart(fname);
buf.append(fname, fnamestart, fname.length - fnamestart); buf.append('{');
if (!(binding instanceof ICPPNamespace)) { buf.append(fname, fnamestart, fname.length - fnamestart);
buf.append(':'); if (includeOffset) {
buf.append(loc.getNodeOffset()); buf.append(':');
} buf.append(loc.getNodeOffset());
buf.append('}');
} }
buf.append('}');
} }
} }