1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-19 23:15:24 +02:00

Bug 516648 - Delay storing of the type, exception specification, and parameters of a function specialization in the index until the post-process

This is needed to avoid infinite recursion, and mirrors the way regular
functions are stored.

Change-Id: I72d0c9fb1567cb9d2ba8922d38e17ec63e1fe97a
This commit is contained in:
Nathan Ridge 2017-06-01 01:00:07 -04:00
parent 0084cc2707
commit 5f937c0bf8
3 changed files with 98 additions and 41 deletions

View file

@ -2833,6 +2833,27 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
checkBindings();
}
// template<typename T> struct Constraint {
// typedef T Type;
// static const int Scale = 1;
// };
//
// template<int N> struct Operations {
// template<typename T> void operation(typename Constraint<T>::Type);
// template<typename T> void value(T) {
// }
// };
//
// template<> template<typename Q>
// void Operations<4>::operation(typename Constraint<Q>::Type) {
// value<Q>(Constraint<Q>::Scale);
// }
// // empty source file
public void testInfiniteRecursion_516648() throws Exception {
checkBindings();
}
// // Empty header file
// typedef unsigned long size_t;
@ -3068,4 +3089,6 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
public void testRegression_402498() throws Exception {
checkBindings();
}
}

View file

@ -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);
}
ICPPFunction origAstFunc= (ICPPFunction) ((ICPPSpecialization) astFunction).getSpecializedBinding();
ICPPParameter[] origAstParams= origAstFunc.getParameters();
public PDOMCPPFunctionSpecialization(PDOMLinkage linkage, long bindingRecord) {
super(linkage, bindingRecord);
}
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,34 +131,28 @@ 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);
private void setDeclaredType(ICPPFunctionType ft) throws CoreException {
if (ft != null) {
fType = null;
getLinkage().storeType(record + DECLARED_TYPE, ft);
}
}
public void initData(ICPPExecution functionBody) {
if (functionBody == null)
return;
try {
getLinkage().storeExecution(record + FUNCTION_BODY, functionBody);
} catch (CoreException e) {
CCorePlugin.log(e);
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

View file

@ -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;
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);
}
}