/** * Return true if and only if this prototype and the given prototype match exactly, * except that they differ in return type or in type qualifiers of parameters. * Thus they are too similar to be overloads of one another, yet do not match * perfectly. * * @param functionPrototype The function prototype to be checked * @return true if and only if the prototypes clash */ public boolean clashes(FunctionPrototype functionPrototype) { if (matches(functionPrototype)) { return false; } if (!getName().equals(functionPrototype.getName())) { return false; } if (getNumParameters() != functionPrototype.getNumParameters()) { return false; } for (int i = 0; i < getNumParameters(); i++) { // If parameters differ after qualifier removal then there is no clash if (!getParameters().get(i).getType().getWithoutQualifiers().equals( functionPrototype.getParameters().get(i).getType().getWithoutQualifiers())) { return false; } } // We have two functions that do not match, yet have the same names and identical // parameter types once qualifiers are ignored. This is a clash. return true; }
private static void addBuiltin(Map<String, List<FunctionPrototype>> builtinsForVersion, String name, Type resultType, Type... args) { if (!builtinsForVersion.containsKey(name)) { builtinsForVersion.put(name, new ArrayList<>()); } builtinsForVersion.get(name).add(new FunctionPrototype(name, resultType, args)); }
@Override public void visitFunctionPrototype(FunctionPrototype functionPrototype) { if (!functionRenaming.containsKey(functionPrototype.getName())) { functionRenaming.put(functionPrototype.getName(), renameFunction(functionPrototype.getName())); } functionPrototype.setName(functionRenaming.get(functionPrototype.getName())); super.visitFunctionPrototype(functionPrototype); }
@Override public void visitFunctionPrototype(FunctionPrototype functionPrototype) { super.visitFunctionPrototype(functionPrototype); if (functionPrototype.getName().equals(functionDefinition.getPrototype().getName())) { // As we only apply this reduction opportunity if the function name is not overloaded, // this has to be a prototype for the relevant function (there could be multiple identical // prototypes). functionPrototype.removeParameter(paramIndex); } }
public FunctionCallExprTemplate(FunctionPrototype prototype) { this.name = prototype.getName(); this.resultType = prototype.getReturnType(); this.argTypes = new ArrayList<>(); for (ParameterDecl param : prototype.getParameters()) { assert param.getArrayInfo() == null; this.argTypes.add(param.getType()); } }
/** * Return true if and only if this prototype and the given prototype have identical names, * return types, and argument types. * * @param functionPrototype The function prototype to be checked * @return true if and only if the prototypes match */ public boolean matches(FunctionPrototype functionPrototype) { if (!getName().equals(functionPrototype.getName())) { return false; } if (getNumParameters() != functionPrototype.getNumParameters()) { return false; } if (!getReturnType().equals(functionPrototype.getReturnType())) { return false; } for (int i = 0; i < getNumParameters(); i++) { if (!getParameters().get(i).getType().equals(functionPrototype.getParameters() .get(i).getType())) { return false; } } return true; }
private Set<FunctionPrototype> findPossibleMatchesForCall(FunctionCallExpr functionCallExpr) { Set<FunctionPrototype> candidates = declaredFunctions.stream() .filter(proto -> proto.getName().equals(functionCallExpr.getCallee())) .filter(proto -> proto.getNumParameters() == functionCallExpr.getNumArgs()) .collect(Collectors.toSet()); for (int i = 0; i < functionCallExpr.getNumArgs(); i++) { if (!typer.hasType(functionCallExpr.getArg(i))) { // If we don't have a type for this argument, we're OK with any function prototype's type continue; } final int currentIndex = i; // Capture i in final variable so it can be used in lambda. candidates = candidates.stream().filter(proto -> typer.lookupType(functionCallExpr.getArg(currentIndex)).getWithoutQualifiers() .equals(proto.getParameters().get(currentIndex).getType().getWithoutQualifiers())) .collect(Collectors.toSet()); } return candidates; }
@Override public void visitFunctionPrototype(FunctionPrototype functionPrototype) { for (int i = 0; i < functionPrototype.getNumParameters(); i++) { visitChildFromParent(functionPrototype.getParameters().get(i), functionPrototype); } visitChildFromParent(functionPrototype.getReturnType(), functionPrototype); }
private boolean functionMatches(FunctionDefinition declaration) { final FunctionPrototype prototype = declaration.getPrototype(); if (!prototype.getName().equals(call.getCallee())) { return false; } if (prototype.getNumParameters() != call.getNumArgs()) { return false; } for (int i = 0; i < prototype.getNumParameters(); i++) { if (typer.lookupType(call.getArg(i)) == null) { continue; } if (!typer.lookupType(call.getArg(i)).getWithoutQualifiers() .equals(prototype.getParameter(i).getType().getWithoutQualifiers())) { return false; } } return true; }
if (prototype.getNumParameters() != functionCallExpr.getNumArgs()) { return false; for (int i = 0; i < prototype.getNumParameters(); i++) { Type argType = lookupType(functionCallExpr.getArg(i)); if (argType == null) { assert prototype.getParameters().get(i).getArrayInfo() == null; if (!argType.getWithoutQualifiers() .equals(prototype.getParameters().get(i).getType().getWithoutQualifiers())) { return false;
@Override public void visitFunctionPrototype(FunctionPrototype functionPrototype) { super.visitFunctionPrototype(functionPrototype); for (int i = 0; i < functionPrototype.getNumParameters(); i++) { if (functionPrototype.getParameter(i).getType().getWithoutQualifiers() .equals(declaration.getVariablesDeclaration().getBaseType().getWithoutQualifiers())) { assert declaration.getVariablesDeclaration().getDeclInfo(0).getName() .equals(functionPrototype.getParameter(i).getName()); functionPrototype.getParameter(i).setName(originalVariableInfo.getName()); functionPrototype.getParameter(i).setType(originalVariableInfo.getType()); } } }
@Override public boolean preconditionHolds() { return functionDefinition.getPrototype().getParameters().contains(parameterDecl); } }
private boolean compatibleDonor(TranslationUnit donor) { List<String> usedFunctionNames = functionPrototypes.stream().map(item -> item.getName()) .collect(Collectors.toList()); Set<String> usedGlobalVariableNames = globalVariables.keySet(); if (usedGlobalVariableNames.contains(donorPrototype.getName()) || usedStructNames.contains(donorPrototype.getName())) { return false; if (functionPrototypes.stream().anyMatch(item -> item.clashes(donorPrototype))) { return false;
private boolean incompatibleReturnTypes(FunctionDefinition f1, FunctionDefinition f2) { return !f1.getPrototype().getReturnType().equals(f2.getPrototype().getReturnType()); }
private boolean functionIsCalled(FunctionPrototype prototype) { return calledFunctions.stream().anyMatch(proto -> proto.matches(prototype)); }
.filter(item -> typer.prototypeMatches(item, (FunctionCallExpr) parent)) .collect(Collectors.toList())) { if (fp.getParameter(childIndex).getType().hasQualifier(TypeQualifier.OUT_PARAM) || fp.getParameter(childIndex).getType().hasQualifier(TypeQualifier.INOUT_PARAM)) { return false;
@Override public void visitFunctionPrototype(FunctionPrototype functionPrototype) { visit(functionPrototype.getReturnType()); out.append(" " + functionPrototype.getName() + "("); boolean first = true; for (ParameterDecl p : functionPrototype.getParameters()) { if (!first) { out.append(", "); } first = false; visit(p); } out.append(")"); if (!inFunctionDefinition) { out.append(";"); } out.append(newLine()); }
private boolean callMatchesPrototype(FunctionCallExpr call, FunctionPrototype prototype) { assert call.getNumArgs() == prototype.getNumParameters(); for (int i = 0; i < call.getNumArgs(); i++) { Type argType = typer.lookupType(call.getArg(i)); if (argType == null) { // With incomplete information we say there is a match continue; } if (!typesMatchWithoutQualifiers(argType, prototype.getParameters().get(i).getType())) { return false; } } return true; }