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 fdcaebd8894..1d9805e8d29 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 @@ -5188,7 +5188,7 @@ public class AST2TemplateTests extends AST2TestBase { // int x = sizeof(f(c)); // const int d[] = { 0 }; // int y = sizeof(f(d)); - public void testFunctionOverloadResolution() throws Exception { + public void testOverloadedFunctionTemplate_407579() throws Exception { parseAndCheckBindings(); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 54d2e340f7a..dc0ac44e8d3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -450,6 +450,20 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa assertInstance(b0, ICPPSpecialization.class); } + // template + // char (&f(T (&a)[N]))[N]; + // + // template + // char (&f(const T (&a)[N]))[N]; + // + // struct C { static const char c[]; }; + + // const char C::c[] = ""; + // int x = sizeof(f(C::c)); + public void testOverloadedFunctionTemplate_407579() throws Exception { + checkBindings(); + } + // template class S> // class Foo { // public: 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 1283f94e966..9d04101ab5b 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 @@ -15,8 +15,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunction; @@ -34,6 +38,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; @@ -256,7 +261,37 @@ public class EvalBinding extends CPPDependentEvaluation { return prvalueType(type); } if (binding instanceof IVariable) { - final IType type = ((IVariable) binding).getType(); + IType type = ((IVariable) binding).getType(); + if (type instanceof IArrayType && ((IArrayType) type).getSize() == null && + binding instanceof IIndexBinding && point != null) { + // Refine the type of the array variable by filling in missing size information. + // This may be necessary if the variable is declared outside of the current + // translation unit without providing array size information, but is defined in + // the current translation unit with such information. + // For example: + // header.h + // -------- + // struct S { + // static const char[] c; + // }; + // + // source.cpp + // ---------- + // #include "header.h" + // const char S::c[] = "abc"; + IASTTranslationUnit ast = point.getTranslationUnit(); + IASTName[] definitions = ast.getDefinitionsInAST(binding); + for (IASTName definition : definitions) { + IASTDeclarator declarator = CPPVisitor.findAncestorWithType(definition, IASTDeclarator.class); + if (declarator != null) { + IType localType = CPPVisitor.createType(declarator); + if (localType instanceof IArrayType && ((IArrayType) localType).getSize() != null) { + type = localType; + break; + } + } + } + } return SemanticUtil.mapToAST(glvalueType(type), point); } if (binding instanceof IFunction) {