mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-09 01:05:38 +02:00
Bug 297457: Instantiation of std::endl.
This commit is contained in:
parent
83aed16ff8
commit
baee7308fe
5 changed files with 70 additions and 14 deletions
|
@ -26,8 +26,10 @@ import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
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;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
|
@ -5116,4 +5118,26 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
final String code= getAboveComment();
|
final String code= getAboveComment();
|
||||||
parseAndCheckBindings(code);
|
parseAndCheckBindings(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<typename _CharT> struct OutStream {
|
||||||
|
// OutStream& operator<<(OutStream& (*__pf)(OutStream&));
|
||||||
|
// };
|
||||||
|
// template<typename _CharT> OutStream<_CharT>& endl(OutStream<_CharT>& __os);
|
||||||
|
//
|
||||||
|
// void test() {
|
||||||
|
// OutStream<char> out;
|
||||||
|
// out << endl;
|
||||||
|
// }
|
||||||
|
public void testInstantiationOfEndl_297457() throws Exception {
|
||||||
|
final String code= getAboveComment();
|
||||||
|
IASTTranslationUnit tu= parseAndCheckBindings(code);
|
||||||
|
final IASTNodeSelector nodeSelector = tu.getNodeSelector(null);
|
||||||
|
|
||||||
|
IASTName methodName= nodeSelector.findEnclosingName(code.indexOf("operator<<"), 1);
|
||||||
|
IASTImplicitName name = nodeSelector.findImplicitName(code.indexOf("<< endl"), 2);
|
||||||
|
|
||||||
|
final IBinding method = methodName.resolveBinding();
|
||||||
|
final IBinding reference = name.resolveBinding();
|
||||||
|
assertSame(method, ((ICPPSpecialization) reference).getSpecializedBinding());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
|
@ -81,7 +82,13 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
||||||
|
|
||||||
protected IASTName findName(String section, int len) {
|
protected IASTName findName(String section, int len) {
|
||||||
IASTTranslationUnit ast = strategy.getAst();
|
IASTTranslationUnit ast = strategy.getAst();
|
||||||
return ast.getNodeSelector(null).findName(strategy.getTestData()[1].indexOf(section), len);
|
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
||||||
|
final int offset = strategy.getTestData()[1].indexOf(section);
|
||||||
|
IASTName name= nodeSelector.findName(offset, len);
|
||||||
|
if (name == null)
|
||||||
|
name= nodeSelector.findImplicitName(offset, len);
|
||||||
|
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1780,4 +1780,19 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
inst = getBindingFromASTName("g(1)", 1);
|
inst = getBindingFromASTName("g(1)", 1);
|
||||||
assertTrue(inst.isExplicitSpecialization());
|
assertTrue(inst.isExplicitSpecialization());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<typename _CharT> struct OutStream {
|
||||||
|
// OutStream& operator<<(OutStream& (*__pf)(OutStream&));
|
||||||
|
// };
|
||||||
|
// template<typename _CharT> OutStream<_CharT>& endl(OutStream<_CharT>& __os);
|
||||||
|
|
||||||
|
// void test() {
|
||||||
|
// OutStream<char> out;
|
||||||
|
// out << endl;
|
||||||
|
// }
|
||||||
|
public void testInstantiationOfEndl_297457() throws Exception {
|
||||||
|
final IBinding reference = getBindingFromASTName("<< endl", 2);
|
||||||
|
assertTrue(reference instanceof ICPPSpecialization);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1906,7 +1906,7 @@ public class CPPSemantics {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
type = temp;
|
type = temp;
|
||||||
} else if (!type.equals(temp)) {
|
} else if (!type.equals(temp)) {
|
||||||
int c = compareByRelevance(data, type, temp);
|
int c = compareByRelevance(data.tu, type, temp);
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
type= temp;
|
type= temp;
|
||||||
} else if (c == 0) {
|
} else if (c == 0) {
|
||||||
|
@ -1927,7 +1927,7 @@ public class CPPSemantics {
|
||||||
} else if (obj == temp) {
|
} else if (obj == temp) {
|
||||||
// Ok, delegates are synonyms.
|
// Ok, delegates are synonyms.
|
||||||
} else {
|
} else {
|
||||||
int c = compareByRelevance(data, obj, temp);
|
int c = compareByRelevance(data.tu, obj, temp);
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
obj= temp;
|
obj= temp;
|
||||||
} else if (c == 0) {
|
} else if (c == 0) {
|
||||||
|
@ -1966,7 +1966,7 @@ public class CPPSemantics {
|
||||||
|
|
||||||
if (obj != null && type != null) {
|
if (obj != null && type != null) {
|
||||||
if (obj instanceof ICPPNamespace) {
|
if (obj instanceof ICPPNamespace) {
|
||||||
if (compareByRelevance(data, type, obj) >= 0) {
|
if (compareByRelevance(data.tu, type, obj) >= 0) {
|
||||||
obj= null;
|
obj= null;
|
||||||
}
|
}
|
||||||
} else if (!data.typesOnly && overrulesByRelevance(data, type, obj)) {
|
} else if (!data.typesOnly && overrulesByRelevance(data, type, obj)) {
|
||||||
|
@ -2019,16 +2019,16 @@ public class CPPSemantics {
|
||||||
* the two bindings have the same relevance; -1 if <code>b1</code> is less relevant than
|
* the two bindings have the same relevance; -1 if <code>b1</code> is less relevant than
|
||||||
* <code>b2</code>.
|
* <code>b2</code>.
|
||||||
*/
|
*/
|
||||||
static int compareByRelevance(LookupData data, IBinding b1, IBinding b2) {
|
static int compareByRelevance(IASTTranslationUnit tu, IBinding b1, IBinding b2) {
|
||||||
boolean b1FromIndex= isFromIndex(b1);
|
boolean b1FromIndex= isFromIndex(b1);
|
||||||
boolean b2FromIndex= isFromIndex(b2);
|
boolean b2FromIndex= isFromIndex(b2);
|
||||||
if (b1FromIndex != b2FromIndex) {
|
if (b1FromIndex != b2FromIndex) {
|
||||||
return !b1FromIndex ? 1 : -1;
|
return !b1FromIndex ? 1 : -1;
|
||||||
} else if (b1FromIndex) {
|
} else if (b1FromIndex) {
|
||||||
// Both are from index.
|
// Both are from index.
|
||||||
if (data != null && data.tu != null) {
|
if (tu != null) {
|
||||||
boolean b1Reachable= isReachableFromAst(data.tu, b1);
|
boolean b1Reachable= isReachableFromAst(tu, b1);
|
||||||
boolean b2Reachable= isReachableFromAst(data.tu, b2);
|
boolean b2Reachable= isReachableFromAst(tu, b2);
|
||||||
if (b1Reachable != b2Reachable) {
|
if (b1Reachable != b2Reachable) {
|
||||||
return b1Reachable ? 1 : -1;
|
return b1Reachable ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
@ -2357,7 +2357,7 @@ public class CPPSemantics {
|
||||||
potentialCosts.add(fnCost);
|
potentialCosts.add(fnCost);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int cmp= fnCost.compareTo(data, bestFnCost);
|
int cmp= fnCost.compareTo(data.tu, bestFnCost);
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
bestFnCost= fnCost;
|
bestFnCost= fnCost;
|
||||||
ambiguousFunctions= null;
|
ambiguousFunctions= null;
|
||||||
|
@ -2369,7 +2369,7 @@ public class CPPSemantics {
|
||||||
if (potentialCosts != null) {
|
if (potentialCosts != null) {
|
||||||
for (FunctionCost fnCost : potentialCosts) {
|
for (FunctionCost fnCost : potentialCosts) {
|
||||||
if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC()) {
|
if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC()) {
|
||||||
int cmp= fnCost.compareTo(data, bestFnCost);
|
int cmp= fnCost.compareTo(data.tu, bestFnCost);
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
bestFnCost= fnCost;
|
bestFnCost= fnCost;
|
||||||
ambiguousFunctions= null;
|
ambiguousFunctions= null;
|
||||||
|
@ -2765,6 +2765,8 @@ public class CPPSemantics {
|
||||||
// Second pass, consider templates
|
// Second pass, consider templates
|
||||||
ICPPFunction result= null;
|
ICPPFunction result= null;
|
||||||
ICPPFunctionTemplate resultTemplate= null;
|
ICPPFunctionTemplate resultTemplate= null;
|
||||||
|
boolean isAmbiguous= false;
|
||||||
|
final IASTTranslationUnit tu= name.getTranslationUnit();
|
||||||
for (IFunction fn : fns) {
|
for (IFunction fn : fns) {
|
||||||
try {
|
try {
|
||||||
if (fn instanceof ICPPFunctionTemplate) {
|
if (fn instanceof ICPPFunctionTemplate) {
|
||||||
|
@ -2775,9 +2777,13 @@ public class CPPSemantics {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
cmp= CPPTemplates.orderTemplateFunctions(resultTemplate, template);
|
cmp= CPPTemplates.orderTemplateFunctions(resultTemplate, template);
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
return null;
|
cmp= compareByRelevance(tu, resultTemplate, template);
|
||||||
}
|
}
|
||||||
|
if (cmp == 0)
|
||||||
|
isAmbiguous= true;
|
||||||
|
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
|
isAmbiguous= false;
|
||||||
resultTemplate= template;
|
resultTemplate= template;
|
||||||
result= inst;
|
result= inst;
|
||||||
}
|
}
|
||||||
|
@ -2786,6 +2792,9 @@ public class CPPSemantics {
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isAmbiguous)
|
||||||
|
return null;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
@ -115,7 +116,7 @@ class FunctionCost {
|
||||||
/**
|
/**
|
||||||
* Compares this function call cost to another one.
|
* Compares this function call cost to another one.
|
||||||
*/
|
*/
|
||||||
public int compareTo(LookupData data, FunctionCost other) throws DOMException {
|
public int compareTo(IASTTranslationUnit tu, FunctionCost other) throws DOMException {
|
||||||
if (other == null)
|
if (other == null)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -163,7 +164,7 @@ class FunctionCost {
|
||||||
|
|
||||||
// if we are ambiguous at this point prefer non-index bindings
|
// if we are ambiguous at this point prefer non-index bindings
|
||||||
if (haveBetter == haveWorse) {
|
if (haveBetter == haveWorse) {
|
||||||
return -CPPSemantics.compareByRelevance(data, getFunction(), other.getFunction());
|
return -CPPSemantics.compareByRelevance(tu, getFunction(), other.getFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (haveBetter)
|
if (haveBetter)
|
||||||
|
|
Loading…
Add table
Reference in a new issue