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
|
@ -2832,6 +2832,27 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
public void testInfiniteRecursionMarshallingTemplateDefinition_439923() throws Exception {
|
public void testInfiniteRecursionMarshallingTemplateDefinition_439923() throws Exception {
|
||||||
checkBindings();
|
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
|
// // Empty header file
|
||||||
|
|
||||||
|
@ -3068,4 +3089,6 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
public void testRegression_402498() throws Exception {
|
public void testRegression_402498() throws Exception {
|
||||||
checkBindings();
|
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.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
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.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
|
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
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.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionSpecialization;
|
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.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.ICPPParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
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.ProblemFunctionType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPComputableFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPComputableFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
|
||||||
|
@ -81,18 +78,36 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization
|
||||||
super(linkage, parent, (ICPPSpecialization) astFunction, specialized);
|
super(linkage, parent, (ICPPSpecialization) astFunction, specialized);
|
||||||
|
|
||||||
Database db = getDB();
|
Database db = getDB();
|
||||||
ICPPParameter[] astParams= astFunction.getParameters();
|
fAnnotations = PDOMCPPAnnotations.encodeFunctionAnnotations(astFunction);
|
||||||
IFunctionType astFt= astFunction.getType();
|
db.putShort(record + ANNOTATION, fAnnotations);
|
||||||
if (astFt != null) {
|
db.putShort(record + REQUIRED_ARG_COUNT , (short) astFunction.getRequiredArgumentCount());
|
||||||
getLinkage().storeType(record + FUNCTION_TYPE, astFt);
|
linkage.new ConfigureFunctionSpecialization(astFunction, this, specialized, point);
|
||||||
}
|
}
|
||||||
IFunctionType astDeclaredType = astFunction.getDeclaredType();
|
|
||||||
if (astDeclaredType != null) {
|
public PDOMCPPFunctionSpecialization(PDOMLinkage linkage, long bindingRecord) {
|
||||||
getLinkage().storeType(record + DECLARED_TYPE, astDeclaredType);
|
super(linkage, bindingRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
ICPPFunction origAstFunc= (ICPPFunction) ((ICPPSpecialization) astFunction).getSpecializedBinding();
|
public void initData(PDOMBinding specialized, ICPPFunctionType type, ICPPFunctionType declaredType,
|
||||||
ICPPParameter[] origAstParams= origAstFunc.getParameters();
|
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) {
|
if (origAstParams.length == 0) {
|
||||||
db.putInt(record + NUM_PARAMS, 0);
|
db.putInt(record + NUM_PARAMS, 0);
|
||||||
db.putRecPtr(record + FIRST_PARAM, 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());
|
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());
|
private void setType(ICPPFunctionType ft) throws CoreException {
|
||||||
long typelist= 0;
|
if (ft != null) {
|
||||||
if (astFunction instanceof ICPPMethod && ((ICPPMethod) astFunction).isImplicit()) {
|
fType = null;
|
||||||
// Don't store the exception specification, it is computed on demand.
|
getLinkage().storeType(record + FUNCTION_TYPE, ft);
|
||||||
} 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PDOMCPPFunctionSpecialization(PDOMLinkage linkage, long bindingRecord) {
|
private void setDeclaredType(ICPPFunctionType ft) throws CoreException {
|
||||||
super(linkage, bindingRecord);
|
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
|
@Override
|
||||||
protected int getRecordSize() {
|
protected int getRecordSize() {
|
||||||
|
|
|
@ -333,17 +333,42 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
|
|
||||||
class ConfigureFunctionSpecialization implements Runnable {
|
class ConfigureFunctionSpecialization implements Runnable {
|
||||||
private final PDOMCPPFunctionSpecialization fSpec;
|
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;
|
private final ICPPExecution fFunctionBody;
|
||||||
|
|
||||||
public ConfigureFunctionSpecialization(ICPPFunction original, PDOMCPPFunctionSpecialization spec, IASTNode point) {
|
public ConfigureFunctionSpecialization(ICPPFunction original, PDOMCPPFunctionSpecialization spec,
|
||||||
|
PDOMBinding specialized, IASTNode point) {
|
||||||
fSpec = spec;
|
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);
|
postProcesses.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
fSpec.initData(fFunctionBody);
|
fSpec.initData(fSpecialized, fType, fDeclaredType, fAstParams, fOrigAstParams, fExceptionSpec,
|
||||||
|
fFunctionBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue