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:
parent
0084cc2707
commit
5f937c0bf8
3 changed files with 98 additions and 41 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue