mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Bug 561088 - Some cleanups to VariableReadWriteFlags classes
Change-Id: I63c5333b4c97062229c7f421b4f152ba3f90a996
This commit is contained in:
parent
b65be51fc9
commit
65e8a04447
3 changed files with 52 additions and 114 deletions
|
@ -59,6 +59,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTStructuredBindingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||
|
||||
/**
|
||||
|
@ -242,79 +243,47 @@ public abstract class VariableReadWriteFlags {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if the function name expression involves a deferred function. Applicable
|
||||
* only to C++.
|
||||
* @param functionNameExpression The expression
|
||||
* @return The binding found, null otherwise
|
||||
* Helper method to take the union of two sets of read/write flags.
|
||||
* Note that "unknown" (represented as Optional.empty()) unioned
|
||||
* with anything is still "unknown", since "unknown" means that
|
||||
* potentially any type of access is possible.
|
||||
*/
|
||||
protected abstract IBinding getDeferredFunction(IASTExpression functionNameExpression);
|
||||
|
||||
/**
|
||||
* Evaluate the deferred function and check the flags for arguments passed. Applicable
|
||||
* only to C++.
|
||||
* @param funcCall The function call expression
|
||||
* @param arg The argument to be evaluated
|
||||
* @param argPos The argument position
|
||||
* @param indirection Level of indirection
|
||||
* @param defFunctionBinding The function binding
|
||||
* @return Access flags
|
||||
*/
|
||||
protected abstract Optional<Integer> evaluateDeferredFunction(final IASTFunctionCallExpression funcCall,
|
||||
final IASTInitializerClause arg, int argPos, int indirection, IBinding defFunctionBinding);
|
||||
|
||||
/**
|
||||
* Helper method to merge two optional flags containers
|
||||
* @param a A flag optional container
|
||||
* @param b A flag optional container
|
||||
* @return An optional with bit or operation between a and b
|
||||
*/
|
||||
protected Optional<Integer> bitwiseOr(Optional<Integer> a, Optional<Integer> b) {
|
||||
Optional<Integer> or = Optional.empty();
|
||||
if (a.isPresent()) {
|
||||
if (!b.isPresent()) {
|
||||
or = a;
|
||||
} else {
|
||||
or = Optional.of(a.get() | b.get());
|
||||
protected Optional<Integer> union(Optional<Integer> a, Optional<Integer> b) {
|
||||
if (a.isPresent() && b.isPresent()) {
|
||||
return Optional.of(a.get() | b.get());
|
||||
}
|
||||
} else {
|
||||
if (!b.isPresent()) {
|
||||
return or;
|
||||
} else {
|
||||
or = b;
|
||||
}
|
||||
}
|
||||
return or;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
protected Optional<Integer> rwArgumentForFunctionCall(final IASTFunctionCallExpression funcCall, IASTNode argument,
|
||||
int indirection) {
|
||||
final IASTInitializerClause[] args = funcCall.getArguments();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i] == argument) {
|
||||
int index = ArrayUtil.indexOf(args, argument);
|
||||
if (index == -1) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final IASTExpression functionNameExpression = funcCall.getFunctionNameExpression();
|
||||
if (functionNameExpression != null) {
|
||||
if (functionNameExpression == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
IType type = functionNameExpression.getExpressionType();
|
||||
IBinding deferredFunc = getDeferredFunction(functionNameExpression);
|
||||
if (deferredFunc != null) {
|
||||
return evaluateDeferredFunction(funcCall, args[i], i, indirection, deferredFunc);
|
||||
} else if (type instanceof IFunctionType) {
|
||||
return rwArgumentForFunctionCall((IFunctionType) type, i, args[i], indirection);
|
||||
IFunctionType functionType = null;
|
||||
if (type instanceof IFunctionType) {
|
||||
functionType = (IFunctionType) type;
|
||||
} else if (funcCall instanceof IASTImplicitNameOwner) {
|
||||
IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) funcCall).getImplicitNames();
|
||||
if (implicitNames.length == 1) {
|
||||
IASTImplicitName name = implicitNames[0];
|
||||
IBinding binding = name.resolveBinding();
|
||||
if (binding instanceof IFunction) {
|
||||
return rwArgumentForFunctionCall(((IFunction) binding).getType(), i, args[i],
|
||||
indirection);
|
||||
functionType = ((IFunction) binding).getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (functionType == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Optional.empty(); // Fallback
|
||||
return rwArgumentForFunctionCall(functionType, index, args[index], indirection);
|
||||
}
|
||||
|
||||
private IType getArgumentType(IASTInitializerClause argument) {
|
||||
|
|
|
@ -18,10 +18,8 @@ import java.util.Optional;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
|
@ -93,15 +91,4 @@ public final class CVariableReadWriteFlags extends VariableReadWriteFlags {
|
|||
}
|
||||
return Optional.empty(); // Fallback
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBinding getDeferredFunction(IASTExpression functionNameExpression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Integer> evaluateDeferredFunction(final IASTFunctionCallExpression funcCall,
|
||||
final IASTInitializerClause arg, int argPos, int indirection, IBinding defFunctionBinding) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||
|
@ -45,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredFunction;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.VariableReadWriteFlags;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
|
||||
|
@ -171,50 +171,32 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected IBinding getDeferredFunction(IASTExpression functionNameExpression) {
|
||||
protected Optional<Integer> rwArgumentForFunctionCall(final IASTFunctionCallExpression funcCall, IASTNode argument,
|
||||
int indirection) {
|
||||
// Handle deferred functions (unresolved overloads) by taking the union (bitwise or)
|
||||
// of the flags of each candidate function.
|
||||
IASTExpression functionNameExpression = funcCall.getFunctionNameExpression();
|
||||
if (functionNameExpression instanceof IASTIdExpression) {
|
||||
IBinding b = ((IASTIdExpression) functionNameExpression).getName().resolveBinding();
|
||||
if (b instanceof ICPPDeferredFunction) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Integer> evaluateDeferredFunction(final IASTFunctionCallExpression funcCall,
|
||||
final IASTInitializerClause arg, int argPos, int indirection, IBinding defFunctionBinding) {
|
||||
|
||||
ICPPDeferredFunction deferredFunc = (defFunctionBinding instanceof ICPPDeferredFunction)
|
||||
? (ICPPDeferredFunction) defFunctionBinding
|
||||
: null;
|
||||
|
||||
if (deferredFunc == null)
|
||||
return Optional.empty();
|
||||
|
||||
ICPPDeferredFunction deferredFunc = (ICPPDeferredFunction) b;
|
||||
ICPPFunction[] candidates = deferredFunc.getCandidates();
|
||||
if (candidates != null) {
|
||||
IASTInitializerClause[] args = funcCall.getArguments();
|
||||
int argPos = ArrayUtil.indexOf(args, argument);
|
||||
Optional<Integer> cumulative = Optional.empty();
|
||||
for (ICPPFunction f : candidates) {
|
||||
IType type = f.getType();
|
||||
if (type instanceof IFunctionType) {
|
||||
Optional<Integer> res = rwArgumentForFunctionCall((IFunctionType) type, argPos, arg, indirection);
|
||||
cumulative = bitwiseOr(cumulative, res);
|
||||
} else if (funcCall instanceof IASTImplicitNameOwner) {
|
||||
IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) funcCall).getImplicitNames();
|
||||
if (implicitNames.length == 1) {
|
||||
IASTImplicitName name = implicitNames[0];
|
||||
IBinding binding = name.resolveBinding();
|
||||
if (binding instanceof IFunction) {
|
||||
Optional<Integer> res = rwArgumentForFunctionCall(((IFunction) binding).getType(), argPos,
|
||||
arg, indirection);
|
||||
cumulative = bitwiseOr(cumulative, res);
|
||||
}
|
||||
}
|
||||
Optional<Integer> res = rwArgumentForFunctionCall((IFunctionType) type, argPos,
|
||||
args[argPos], indirection);
|
||||
cumulative = union(cumulative, res);
|
||||
}
|
||||
}
|
||||
return cumulative;
|
||||
}
|
||||
return Optional.empty(); // Fallback
|
||||
}
|
||||
}
|
||||
return super.rwArgumentForFunctionCall(funcCall, argument, indirection);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue