diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 10d8d03ec8d..0b6c3b0f988 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -5876,4 +5876,52 @@ public class AST2TemplateTests extends AST2BaseTest { public void testConstInTypeParameter_377223() throws Exception { parseAndCheckBindings(); } + + // template + // struct integral_constant { + // static constexpr T value = v; + // typedef T value_type; + // typedef integral_constant type; + // }; + // + // typedef integral_constant true_type; + // + // typedef integral_constant false_type; + // + // template + // class helper { + // typedef char one; + // typedef struct { char arr[2]; } two; + // template struct Wrap_type {}; + // template static one test(Wrap_type*); + // template static two test(...); + // public: static const bool value = sizeof(test(0)) == 1; + // }; + // + // template + // struct has_category : integral_constant::value> {}; + // + // template::value> + // struct traits {}; + // + // template + // struct traits { + // typedef typename Iterator::value_type value_type; + // }; + // + // struct tag {}; + // + // struct C { + // typedef int value_type; + // typedef tag category; + // }; + // + // template::value_type> + // class A { + // }; + // + // typedef A type; + public void testSFINAE() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index 74788246143..acd6fc952c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -94,10 +94,10 @@ public class EvalBinding extends CPPEvaluation { t= ((ICPPTemplateNonTypeParameter) fBinding).getType(); } else if (fBinding instanceof IVariable) { t = ((IVariable) fBinding).getType(); - } else if (fBinding instanceof IFunction) { - t= ((IFunction) fBinding).getType(); } else if (fBinding instanceof ICPPUnknownBinding) { return true; + } else if (fBinding instanceof IFunction) { + t= ((IFunction) fBinding).getType(); } else { return false; } @@ -123,12 +123,12 @@ public class EvalBinding extends CPPEvaluation { if (fBinding instanceof IVariable) { return Value.isDependentValue(((IVariable) fBinding).getInitialValue()); } - if (fBinding instanceof IFunction) { - return false; - } if (fBinding instanceof ICPPUnknownBinding) { return true; } + if (fBinding instanceof IFunction) { + return false; + } return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java index 752cb08797c..fe5266bae77 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java @@ -173,14 +173,18 @@ public class EvalComma extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPEvaluation[] args = new ICPPEvaluation[fArguments.length]; - boolean changed = false; + ICPPEvaluation[] args = null; for (int i = 0; i < fArguments.length; i++) { - args[i] = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); - if (args[i] != fArguments[i]) - changed = true; + ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); + if (arg != fArguments[i]) { + if (args == null) { + args = new ICPPEvaluation[fArguments.length]; + System.arraycopy(fArguments, 0, args, 0, fArguments.length); + } + args[i] = arg; + } } - if (!changed) + if (args == null) return this; return new EvalComma(args); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index d7737ffc9e4..6cb3db90499 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -186,14 +186,18 @@ public class EvalFunctionCall extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPEvaluation[] args = new ICPPEvaluation[fArguments.length]; - boolean changed = false; + ICPPEvaluation[] args = null; for (int i = 0; i < fArguments.length; i++) { - args[i] = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); - if (args[i] != fArguments[i]) - changed = true; + ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); + if (arg != fArguments[i]) { + if (args == null) { + args = new ICPPEvaluation[fArguments.length]; + System.arraycopy(fArguments, 0, args, 0, fArguments.length); + } + args[i] = arg; + } } - if (!changed) + if (args == null) return this; if (args[0] instanceof EvalFunctionSet) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index f618cd64020..34d3d063c46 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -128,7 +128,7 @@ public class EvalID extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - // Name lookup is not needed here because it was already done in "instantiate" method. + // Name lookup is not needed here because it was already done in the "instantiate" method. // IBinding nameOwner = fNameOwner; // if (nameOwner == null && fFieldOwner != null) // nameOwner = (IBinding) fFieldOwner.getTypeOrFunctionSet(point); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java index e1d4b237e29..db7d1c46bba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java @@ -105,14 +105,18 @@ public class EvalInitList extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPEvaluation[] clauses = new ICPPEvaluation[fClauses.length]; - boolean changed = false; + ICPPEvaluation[] clauses = null; for (int i = 0; i < fClauses.length; i++) { - clauses[i] = fClauses[i].instantiate(tpMap, packOffset, within, maxdepth, point); - if (clauses[i] != fClauses[i]) - changed = true; + ICPPEvaluation clause = fClauses[i].instantiate(tpMap, packOffset, within, maxdepth, point); + if (clause != fClauses[i]) { + if (clauses == null) { + clauses = new ICPPEvaluation[fClauses.length]; + System.arraycopy(fClauses, 0, clauses, 0, fClauses.length); + } + clauses[i] = clause; + } } - if (!changed) + if (clauses == null) return this; return new EvalInitList(clauses); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java index 6e8ef088d12..c0c25271eba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -146,16 +146,23 @@ public class EvalTypeId extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPEvaluation[] args = new ICPPEvaluation[fArguments.length]; - boolean argsChanged = false; + ICPPEvaluation[] args = null; for (int i = 0; i < fArguments.length; i++) { - args[i] = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); - if (args[i] != fArguments[i]) - argsChanged = true; + ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); + if (arg != fArguments[i]) { + if (args == null) { + args = new ICPPEvaluation[fArguments.length]; + System.arraycopy(fArguments, 0, args, 0, fArguments.length); + } + args[i] = arg; + } } IType type = CPPTemplates.instantiateType(fInputType, tpMap, packOffset, within, point); - if (!argsChanged && type == fInputType) - return this; + if (args == null) { + if (type == fInputType) + return this; + args = fArguments; + } return new EvalTypeId(type, args); }