1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Improved error reporting.

This commit is contained in:
Sergey Prigogin 2012-08-15 14:08:24 -07:00
parent 1585de5af4
commit e65a79e4cc
4 changed files with 93 additions and 60 deletions

View file

@ -42,12 +42,12 @@ import com.ibm.icu.text.MessageFormat;
*/ */
public class ProblemBinding extends PlatformObject implements IProblemBinding, IASTInternalScope { public class ProblemBinding extends PlatformObject implements IProblemBinding, IASTInternalScope {
public static ProblemBinding NOT_INITIALIZED= new ProblemBinding(null, 0); public static ProblemBinding NOT_INITIALIZED= new ProblemBinding(null, 0);
protected final int id; protected final int id;
protected char[] arg; protected char[] arg;
protected IASTNode node; protected IASTNode node;
private IBinding[] candidateBindings; private IBinding[] candidateBindings;
public ProblemBinding(IASTName name, int id) { public ProblemBinding(IASTName name, int id) {
this(name, id, null, null); this(name, id, null, null);
} }
@ -56,6 +56,37 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
this(name, id, null, candidateBindings); this(name, id, null, candidateBindings);
} }
/**
* @param name the name that could not be resolved, may be {@code null}
* @param point the point in code where the problem was encountered
* @param id the ID of the problem, see {@link IProblemBinding}
*/
public ProblemBinding(IASTName name, IASTNode point, int id) {
this(name, point, id, null);
}
/**
* @param name the name that could not be resolved, may be {@code null}
* @param point the point in code where the problem was encountered
* @param id the ID of the problem, see {@link IProblemBinding}
* @param candidateBindings candidate bindings that were rejected due to ambiguity or for other
* reasons, may be {@code null}
*/
public ProblemBinding(IASTName name, IASTNode point, int id, IBinding[] candidateBindings) {
this.id = id;
if (name != null && name.getTranslationUnit() != null) {
this.node = name;
} else {
this.node = point;
if (name != null) {
this.arg = name.getSimpleID();
} else if (candidateBindings != null && candidateBindings.length != 0) {
this.arg = candidateBindings[0].getNameCharArray();
}
}
this.candidateBindings = candidateBindings;
}
public ProblemBinding(IASTNode node, int id, char[] arg) { public ProblemBinding(IASTNode node, int id, char[] arg) {
this(node, id, arg, null); this(node, id, arg, null);
} }
@ -66,8 +97,8 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
this.node = node; this.node = node;
this.candidateBindings = candidateBindings; this.candidateBindings = candidateBindings;
} }
@Override @Override
public EScopeKind getKind() { public EScopeKind getKind() {
return EScopeKind.eLocal; return EScopeKind.eLocal;
} }
@ -81,28 +112,22 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
public IBinding[] getCandidateBindings() { public IBinding[] getCandidateBindings() {
return candidateBindings != null ? candidateBindings : IBinding.EMPTY_BINDING_ARRAY; return candidateBindings != null ? candidateBindings : IBinding.EMPTY_BINDING_ARRAY;
} }
public void setCandidateBindings(IBinding[] foundBindings) { public void setCandidateBindings(IBinding[] foundBindings) {
candidateBindings= foundBindings; candidateBindings= foundBindings;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getID()
*/
@Override @Override
public int getID() { public int getID() {
return id; return id;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IProblemBinding#getMessage()
*/
@Override @Override
public String getMessage() { public String getMessage() {
String msg = ParserMessages.getProblemPattern(this); String msg = ParserMessages.getProblemPattern(this);
if (msg == null) if (msg == null)
return ""; //$NON-NLS-1$ return ""; //$NON-NLS-1$
if (arg == null) { if (arg == null) {
if (node instanceof IASTName) { if (node instanceof IASTName) {
arg= ((IASTName) node).toCharArray(); arg= ((IASTName) node).toCharArray();
@ -110,7 +135,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
arg = candidateBindings[0].getNameCharArray(); arg = candidateBindings[0].getNameCharArray();
} }
} }
if (arg != null) { if (arg != null) {
msg = MessageFormat.format(msg, new Object[] { new String(arg) }); msg = MessageFormat.format(msg, new Object[] { new String(arg) });
} }
@ -150,7 +175,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
return getASTNode(); return getASTNode();
} }
@Override @Override
public Object clone() { public Object clone() {
// Don't clone problems // Don't clone problems
@ -263,7 +288,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
public ILinkage getLinkage() { public ILinkage getLinkage() {
return Linkage.NO_LINKAGE; return Linkage.NO_LINKAGE;
} }
@Override @Override
public String toString() { public String toString() {
return getMessage(); return getMessage();
@ -292,7 +317,8 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
} }
@Override @Override
public void removeNestedFromCache(IASTNode container) {} public void removeNestedFromCache(IASTNode container) {
}
// Dummy methods for derived classes // Dummy methods for derived classes
public IType getType() { public IType getType() {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2010 IBM Corporation and others. * Copyright (c) 2005, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -87,7 +87,7 @@ public class CPPClassSpecialization extends CPPSpecialization
fInProgress.set(set); fInProgress.set(set);
} }
if (!set.add(original)) if (!set.add(original))
return new RecursionResolvingBinding(null, null); return new RecursionResolvingBinding(point, original.getNameCharArray());
} }
IBinding result= CPPTemplates.createSpecialization(this, original, point); IBinding result= CPPTemplates.createSpecialization(this, original, point);

View file

@ -258,7 +258,7 @@ public class CPPSemantics {
((CPPASTNameBase) name).incResolutionDepth(); ((CPPASTNameBase) name).incResolutionDepth();
} }
// 1: Get some context info off of the name to figure out what kind of lookup we want // 1: Get some context info off of the name to figure out what kind of lookup we want.
LookupData data = createLookupData(name); LookupData data = createLookupData(name);
try { try {
@ -375,13 +375,13 @@ public class CPPSemantics {
node= node.getParent(); node= node.getParent();
} }
if (!ok) { if (!ok) {
binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_INVALID_TYPE, binding = new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings());
} }
} }
} }
} else if (binding instanceof ICPPDeferredClassInstance) { } else if (binding instanceof ICPPDeferredClassInstance) {
// try to replace binding by the one pointing to the enclosing template declaration. // Try to replace binding by the one pointing to the enclosing template declaration.
ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) binding; ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) binding;
IBinding usedHere= CPPTemplates.isUsedInClassTemplateScope(dcl.getClassTemplate(), lookupName); IBinding usedHere= CPPTemplates.isUsedInClassTemplateScope(dcl.getClassTemplate(), lookupName);
if (usedHere instanceof ICPPClassTemplatePartialSpecialization) { if (usedHere instanceof ICPPClassTemplatePartialSpecialization) {
@ -463,13 +463,13 @@ public class CPPSemantics {
if (parent instanceof IASTTypeId && parent.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) { if (parent instanceof IASTTypeId && parent.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) {
if (!(binding instanceof IType)) { if (!(binding instanceof IType)) {
// a type id needs to hold a type // a type id needs to hold a type
binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_INVALID_TYPE, binding = new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings());
} }
// don't create a problem here // don't create a problem here
} else { } else {
binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_INVALID_TYPE, binding = new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings());
} }
} }
} else if (namePropertyInParent == IASTIdExpression.ID_NAME) { } else if (namePropertyInParent == IASTIdExpression.ID_NAME) {
@ -484,8 +484,8 @@ public class CPPSemantics {
&& ((ICPPASTUnaryExpression) idExpr.getParent()).getOperator() == IASTUnaryExpression.op_sizeofParameterPack) { && ((ICPPASTUnaryExpression) idExpr.getParent()).getOperator() == IASTUnaryExpression.op_sizeofParameterPack) {
// Argument of sizeof... can be a type // Argument of sizeof... can be a type
} else { } else {
binding= new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_INVALID_TYPE, binding= new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings());
} }
} }
} }
@ -515,11 +515,11 @@ public class CPPSemantics {
// If we're still null... // If we're still null...
if (binding == null) { if (binding == null) {
if (name instanceof ICPPASTQualifiedName && declaration != null) { if (name instanceof ICPPASTQualifiedName && declaration != null) {
binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND, binding = new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND, data.getFoundBindings());
} else { } else {
binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, binding = new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.getFoundBindings());
} }
} }
return binding; return binding;
@ -1894,8 +1894,9 @@ public class CPPSemantics {
private static IBinding resolveAmbiguities(LookupData data) throws DOMException { private static IBinding resolveAmbiguities(LookupData data) throws DOMException {
if (!data.hasResults() || data.contentAssist) if (!data.hasResults() || data.contentAssist)
return null; return null;
final IASTName lookupName = data.getLookupName(); final IASTName lookupName = data.getLookupName();
IASTNode lookupPoint = data.getLookupPoint();
final boolean indexBased= data.getIndex() != null; final boolean indexBased= data.getIndex() != null;
final boolean checkWholeClass= lookupName == null || LookupData.checkWholeClassScope(lookupName); final boolean checkWholeClass= lookupName == null || LookupData.checkWholeClassScope(lookupName);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -1908,7 +1909,7 @@ public class CPPSemantics {
Object[] items = (Object[]) data.foundItems; Object[] items = (Object[]) data.foundItems;
for (int i = 0; i < items.length && items[i] != null; i++) { for (int i = 0; i < items.length && items[i] != null; i++) {
Object o = items[i]; Object o = items[i];
boolean declaredBefore = data.isIgnorePointOfDeclaration() || declaredBefore(o, data.getLookupPoint(), indexBased); boolean declaredBefore = data.isIgnorePointOfDeclaration() || declaredBefore(o, lookupPoint, indexBased);
boolean checkResolvedNamesOnly= false; boolean checkResolvedNamesOnly= false;
if (!checkWholeClass && !declaredBefore) { if (!checkWholeClass && !declaredBefore) {
if (lookupName != null && lookupName.getRoleOfName(false) != IASTNameOwner.r_reference) { if (lookupName != null && lookupName.getRoleOfName(false) != IASTNameOwner.r_reference) {
@ -1983,8 +1984,8 @@ public class CPPSemantics {
type= temp; type= temp;
} }
} else { } else {
return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, return new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
} }
} }
} }
@ -1998,8 +1999,8 @@ public class CPPSemantics {
if (c < 0) { if (c < 0) {
obj= temp; obj= temp;
} else if (c == 0) { } else if (c == 0) {
return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, return new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
} }
} }
} }
@ -2012,8 +2013,8 @@ public class CPPSemantics {
IFunction[] fnArray= fns.keyArray(IFunction.class); IFunction[] fnArray= fns.keyArray(IFunction.class);
cmp= compareByRelevance(data, obj, fnArray); cmp= compareByRelevance(data, obj, fnArray);
if (cmp == 0) { if (cmp == 0) {
return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, return new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
} }
} }
} }
@ -2057,8 +2058,8 @@ public class CPPSemantics {
if (obj != null) { if (obj != null) {
int cmp= compareByRelevance(data, obj, fnArray); int cmp= compareByRelevance(data, obj, fnArray);
if (cmp == 0) { if (cmp == 0) {
return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, return new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
} }
if (cmp > 0) { if (cmp > 0) {
return obj; return obj;
@ -2363,8 +2364,9 @@ public class CPPSemantics {
Arrays.asList(argTypes), Arrays.asList(argTypes),
Arrays.asList(data.getFunctionArgumentValueCategories()), Arrays.asList(data.getFunctionArgumentValueCategories()),
data.argsContainImpliedObject, lookupPoint); data.argsContainImpliedObject, lookupPoint);
if (tmp.length == 0 || tmp[0] == null) if (tmp.length == 0 || tmp[0] == null) {
return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns); return new ProblemBinding(lookupName, lookupPoint, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns);
}
int viableCount= 0; int viableCount= 0;
for (IFunction f : tmp) { for (IFunction f : tmp) {
@ -2377,7 +2379,7 @@ public class CPPSemantics {
++viableCount; ++viableCount;
} }
if (viableCount == 0) if (viableCount == 0)
return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns); return new ProblemBinding(lookupName, lookupPoint, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns);
// Check for dependent arguments // Check for dependent arguments
fns= tmp; fns= tmp;
@ -2450,12 +2452,12 @@ public class CPPSemantics {
if (ambiguousFunctions != null) { if (ambiguousFunctions != null) {
ambiguousFunctions= ArrayUtil.append(IFunction.class, ambiguousFunctions, bestFnCost.getFunction()); ambiguousFunctions= ArrayUtil.append(IFunction.class, ambiguousFunctions, bestFnCost.getFunction());
return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, return new ProblemBinding(lookupName, lookupPoint,
ambiguousFunctions); IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, ambiguousFunctions);
} }
if (bestFnCost.hasAmbiguousUserDefinedConversion()) { if (bestFnCost.hasAmbiguousUserDefinedConversion()) {
return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, return new ProblemBinding(lookupName, lookupPoint,
data.getFoundBindings()); IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
} }
for (int i = 0; i < argTypes.length; i++) { for (int i = 0; i < argTypes.length; i++) {
@ -2590,7 +2592,8 @@ public class CPPSemantics {
} }
} }
if (isAmbiguous) if (isAmbiguous)
return new ProblemBinding(data.getLookupName(), IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, fns); return new ProblemBinding(data.getLookupName(), data.getLookupPoint(),
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, fns);
return bestInst; return bestInst;
} }
@ -2738,7 +2741,8 @@ public class CPPSemantics {
ICPPASTConversionName astName= (ICPPASTConversionName) data.getLookupName(); ICPPASTConversionName astName= (ICPPASTConversionName) data.getLookupName();
IType t= CPPVisitor.createType(astName.getTypeId()); IType t= CPPVisitor.createType(astName.getTypeId());
if (t instanceof ISemanticProblem) { if (t instanceof ISemanticProblem) {
return new ProblemBinding(astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings()); return new ProblemBinding(astName, data.getLookupPoint(),
IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings());
} }
if (data.forDeclaration() == null || if (data.forDeclaration() == null ||
data.forExplicitFunctionSpecialization() || data.forExplicitFunctionInstantiation()) { data.forExplicitFunctionSpecialization() || data.forExplicitFunctionInstantiation()) {
@ -2758,7 +2762,8 @@ public class CPPSemantics {
} }
if (unknown != null) if (unknown != null)
return unknown; return unknown;
return new ProblemBinding(astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.getFoundBindings()); return new ProblemBinding(astName, data.getLookupPoint(),
IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.getFoundBindings());
} }
/** /**
@ -3670,7 +3675,7 @@ public class CPPSemantics {
data.typesOnly= unknown instanceof IType; data.typesOnly= unknown instanceof IType;
try { try {
// 2: lookup // 2: Lookup
lookup(data, scope); lookup(data, scope);
} catch (DOMException e) { } catch (DOMException e) {
data.problem = (ProblemBinding) e.getProblem(); data.problem = (ProblemBinding) e.getProblem();
@ -3679,7 +3684,7 @@ public class CPPSemantics {
if (data.problem != null) if (data.problem != null)
return data.problem; return data.problem;
// 3: resolve ambiguities // 3: Resolve ambiguities
IBinding binding; IBinding binding;
try { try {
binding = resolveAmbiguities(data); binding = resolveAmbiguities(data);
@ -3688,7 +3693,7 @@ public class CPPSemantics {
} }
// 4: Normal post processing is not possible, because the name is not rooted in AST // 4: Normal post processing is not possible, because the name is not rooted in AST
if (binding == null) if (binding == null)
binding = new ProblemBinding(unknownName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND); binding = new ProblemBinding(unknownName, point, IProblemBinding.SEMANTIC_NAME_NOT_FOUND);
return binding; return binding;
} }

View file

@ -989,7 +989,8 @@ public class CPPTemplates {
origType= ((ICPPParameterPackType) origType).getType(); origType= ((ICPPParameterPackType) origType).getType();
int packSize= determinePackSize(origType, tpMap); int packSize= determinePackSize(origType, tpMap);
if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) { if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) {
newType= new ProblemBinding(null, IProblemBinding.SEMANTIC_INVALID_TYPE); newType= new ProblemBinding(point, IProblemBinding.SEMANTIC_INVALID_TYPE,
types[i] instanceof IBinding ? ((IBinding) types[i]).getNameCharArray() : null);
} else if (packSize == PACK_SIZE_DEFER) { } else if (packSize == PACK_SIZE_DEFER) {
newType= origType; newType= origType;
} else { } else {
@ -1034,7 +1035,7 @@ public class CPPTemplates {
origArg= origArg.getExpansionPattern(); origArg= origArg.getExpansionPattern();
int packSize= determinePackSize(origArg, tpMap); int packSize= determinePackSize(origArg, tpMap);
if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) { if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) {
throw new DOMException(new ProblemBinding(null, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS)); throw new DOMException(new ProblemBinding(point, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, null));
} else if (packSize == PACK_SIZE_DEFER) { } else if (packSize == PACK_SIZE_DEFER) {
newArg= origArg; newArg= origArg;
} else { } else {
@ -1150,7 +1151,8 @@ public class CPPTemplates {
ICPPTemplateArgument[] args = tpMap.getPackExpansion(tpar); ICPPTemplateArgument[] args = tpMap.getPackExpansion(tpar);
if (args != null) { if (args != null) {
if (packOffset >= args.length) { if (packOffset >= args.length) {
return new ProblemBinding(null, IProblemBinding.SEMANTIC_INVALID_TYPE); return new ProblemBinding(point, IProblemBinding.SEMANTIC_INVALID_TYPE,
tpar.getNameCharArray());
} }
arg= args[packOffset]; arg= args[packOffset];
} }
@ -2430,7 +2432,7 @@ public class CPPTemplates {
} }
} }
} else if (t != owner) { } else if (t != owner) {
return new ProblemBinding(unknown.getUnknownName(), IProblemBinding.SEMANTIC_BAD_SCOPE); return new ProblemBinding(unknown.getUnknownName(), point, IProblemBinding.SEMANTIC_BAD_SCOPE);
} }
} }