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 f3c6064d706..d0026141c17 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 @@ -2832,6 +2832,27 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa public void testInfiniteRecursionMarshallingTemplateDefinition_439923() throws Exception { checkBindings(); } + + // template struct Constraint { + // typedef T Type; + // static const int Scale = 1; + // }; + // + // template struct Operations { + // template void operation(typename Constraint::Type); + // template void value(T) { + // } + // }; + // + // template<> template + // void Operations<4>::operation(typename Constraint::Type) { + // value(Constraint::Scale); + // } + + // // empty source file + public void testInfiniteRecursion_516648() throws Exception { + checkBindings(); + } // // Empty header file @@ -3068,4 +3089,6 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa public void testRegression_402498() throws Exception { checkBindings(); } + + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java index 2f34a9d1fef..367e7ef4216 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java @@ -14,17 +14,14 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPComputableFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution; @@ -81,18 +78,36 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization super(linkage, parent, (ICPPSpecialization) astFunction, specialized); Database db = getDB(); - ICPPParameter[] astParams= astFunction.getParameters(); - IFunctionType astFt= astFunction.getType(); - if (astFt != null) { - getLinkage().storeType(record + FUNCTION_TYPE, astFt); - } - IFunctionType astDeclaredType = astFunction.getDeclaredType(); - if (astDeclaredType != null) { - getLinkage().storeType(record + DECLARED_TYPE, astDeclaredType); - } + fAnnotations = PDOMCPPAnnotations.encodeFunctionAnnotations(astFunction); + db.putShort(record + ANNOTATION, fAnnotations); + db.putShort(record + REQUIRED_ARG_COUNT , (short) astFunction.getRequiredArgumentCount()); + linkage.new ConfigureFunctionSpecialization(astFunction, this, specialized, point); + } + + public PDOMCPPFunctionSpecialization(PDOMLinkage linkage, long bindingRecord) { + super(linkage, bindingRecord); + } - ICPPFunction origAstFunc= (ICPPFunction) ((ICPPSpecialization) astFunction).getSpecializedBinding(); - ICPPParameter[] origAstParams= origAstFunc.getParameters(); + public void initData(PDOMBinding specialized, ICPPFunctionType type, ICPPFunctionType declaredType, + ICPPParameter[] astParams, ICPPParameter[] origAstParams, IType[] exceptionSpec, + ICPPExecution functionBody) { + try { + setType(type); + setDeclaredType(declaredType); + setParameters(astParams, origAstParams, specialized); + storeExceptionSpec(exceptionSpec); + if (functionBody != null) { + getLinkage().storeExecution(record + FUNCTION_BODY, functionBody); + } + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + + private void setParameters(ICPPParameter[] astParams, ICPPParameter[] origAstParams, + PDOMBinding specialized) throws CoreException { + final PDOMCPPLinkage linkage = (PDOMCPPLinkage) getLinkage(); + final Database db = getDB(); if (origAstParams.length == 0) { db.putInt(record + NUM_PARAMS, 0); db.putRecPtr(record + FIRST_PARAM, 0); @@ -116,35 +131,29 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization } db.putRecPtr(record + FIRST_PARAM, next == null ? 0 : next.getRecord()); } - fAnnotations = PDOMCPPAnnotations.encodeFunctionAnnotations(astFunction); - db.putShort(record + ANNOTATION, fAnnotations); - db.putShort(record + REQUIRED_ARG_COUNT , (short) astFunction.getRequiredArgumentCount()); - long typelist= 0; - if (astFunction instanceof ICPPMethod && ((ICPPMethod) astFunction).isImplicit()) { - // Don't store the exception specification, it is computed on demand. - } else { - typelist = PDOMCPPTypeList.putTypes(this, astFunction.getExceptionSpecification()); - } - db.putRecPtr(record + EXCEPTION_SPEC, typelist); - if (!(astFunction instanceof ICPPTemplateInstance) - || ((ICPPTemplateInstance) astFunction).isExplicitSpecialization()) { - linkage.new ConfigureFunctionSpecialization(astFunction, this, point); + } + + private void setType(ICPPFunctionType ft) throws CoreException { + if (ft != null) { + fType = null; + getLinkage().storeType(record + FUNCTION_TYPE, ft); } } - public PDOMCPPFunctionSpecialization(PDOMLinkage linkage, long bindingRecord) { - super(linkage, bindingRecord); - } - - public void initData(ICPPExecution functionBody) { - if (functionBody == null) - return; - try { - getLinkage().storeExecution(record + FUNCTION_BODY, functionBody); - } catch (CoreException e) { - CCorePlugin.log(e); + private void setDeclaredType(ICPPFunctionType ft) throws CoreException { + if (ft != null) { + fType = null; + getLinkage().storeType(record + DECLARED_TYPE, ft); } } + + private void storeExceptionSpec(IType[] exceptionSpec) throws CoreException { + long typelist = 0; + if (exceptionSpec != null) { + typelist = PDOMCPPTypeList.putTypes(this, exceptionSpec); + } + getDB().putRecPtr(record + EXCEPTION_SPEC, typelist); + } @Override protected int getRecordSize() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 0dbc8d6e935..a61e6691603 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -333,17 +333,42 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { class ConfigureFunctionSpecialization implements Runnable { private final PDOMCPPFunctionSpecialization fSpec; + private final PDOMBinding fSpecialized; + private final ICPPFunctionType fType; + private final ICPPFunctionType fDeclaredType; + private final ICPPParameter[] fAstParams; + private final ICPPParameter[] fOrigAstParams; + private final IType[] fExceptionSpec; private final ICPPExecution fFunctionBody; - public ConfigureFunctionSpecialization(ICPPFunction original, PDOMCPPFunctionSpecialization spec, IASTNode point) { + public ConfigureFunctionSpecialization(ICPPFunction original, PDOMCPPFunctionSpecialization spec, + PDOMBinding specialized, IASTNode point) { fSpec = spec; - fFunctionBody = CPPFunction.getFunctionBodyExecution(original, point); + fSpecialized = specialized; + fType = original.getType(); + fDeclaredType = original.getDeclaredType(); + fAstParams = original.getParameters(); + ICPPFunction origAstFunc= (ICPPFunction) ((ICPPSpecialization) original).getSpecializedBinding(); + fOrigAstParams = origAstFunc.getParameters(); + if (original instanceof ICPPMethod && ((ICPPMethod) original).isImplicit()) { + // Don't store the exception specification, it is computed on demand. + fExceptionSpec = null; + } else { + fExceptionSpec = original.getExceptionSpecification(); + } + if (!(original instanceof ICPPTemplateInstance) + || ((ICPPTemplateInstance) original).isExplicitSpecialization()) { + fFunctionBody = CPPFunction.getFunctionBodyExecution(original, point); + } else { + fFunctionBody = null; // will be instantiated on request + } postProcesses.add(this); } @Override public void run() { - fSpec.initData(fFunctionBody); + fSpec.initData(fSpecialized, fType, fDeclaredType, fAstParams, fOrigAstParams, fExceptionSpec, + fFunctionBody); } }