Example #1
0
 @SuppressWarnings("unchecked")
 public void transformProcedure(Procedure proc) {
   List<ReturnStatement> ret_stmts =
       (new DFIterator<ReturnStatement>(proc, ReturnStatement.class)).getList();
   CompoundStatement body = proc.getBody();
   List ret_type = proc.getReturnType();
   // Remove scope qualifiers not necessary in type resolution
   while (ret_type.remove(Specifier.INLINE)) ;
   while (ret_type.remove(Specifier.STATIC)) ;
   while (ret_type.remove(Specifier.EXTERN)) ;
   boolean ret_type_void = (ret_type.contains(Specifier.VOID) && ret_type.size() == 1);
   Identifier ret_id = null;
   // add a variable _ret_val of the same type as the procedure return type
   if (!ret_type_void) {
     // check for implicit int (TODO - differentiate this from constructors)
     if (ret_type.isEmpty()) {
       ret_type.add(Specifier.INT);
     }
     ret_id = SymbolTools.getTemp(body, ret_type, "_ret_val");
   }
   // add a labeled return statement to the end of the procedure
   String done_label = "_done";
   body.addStatement(new Label(new NameID(done_label)));
   if (!ret_type_void) {
     body.addStatement(new ReturnStatement(ret_id.clone()));
   } else {
     body.addStatement(new ReturnStatement());
   }
   // redirect the preexisting return statements to the labeled return
   for (ReturnStatement ret_stmt : ret_stmts) {
     // Identify the parent compound statement.
     CompoundStatement comp_stmt = IRTools.getAncestorOfType(ret_stmt, CompoundStatement.class);
     // Add goto statement.
     Statement goto_stmt = new GotoStatement(new NameID(done_label));
     comp_stmt.addStatementAfter(ret_stmt, goto_stmt);
     // Add temporary assignments.
     if (!ret_type_void) {
       Statement new_stmt =
           new ExpressionStatement(
               new AssignmentExpression(
                   ret_id.clone(), AssignmentOperator.NORMAL, ret_stmt.getExpression().clone()));
       comp_stmt.addStatementBefore(goto_stmt, new_stmt);
     }
     // Remove the original return statement.
     comp_stmt.removeStatement(ret_stmt);
     // Add comments.
     /*
     CommentAnnotation info =
             new CommentAnnotation("Normalized Return: " + ret_stmt);
     info.setOneLiner(true);
     goto_stmt.annotateBefore(info);
     */
   }
 }
Example #2
0
 /**
  * Returns the string dump of this call site.
  *
  * @return string dump.
  */
 public String toString() {
   StringBuilder sb = new StringBuilder(80);
   sb.append(id).append(" ").append(caller.getName()).append("-->");
   sb.append(fcall.getName());
   if (PrintTools.getVerbosity() >= 3) {
     sb.append(" (").append(System.identityHashCode(fcall)).append(")");
   }
   if (callee == null) {
     sb.append(" <lib>");
   } else if (temp_assignments != null) {
     // normalized arguments
     String args = temp_assignments.toString().replaceAll("\n", " ");
     sb.append(" ").append(args);
   }
   if (PrintTools.getVerbosity() >= 3) {
     sb.append("\n        parent    = ").append(fcall.getParent());
     sb.append("\n        fcall     = ").append(fcall);
     sb.append("\n        args      = ").append(arguments);
     sb.append("\n        params    = ").append(getParameters());
     sb.append("\n        nargs     = ").append(norm_arguments);
     sb.append("\n        exception = ").append(exception);
   }
   return sb.toString();
 }
Example #3
0
 /**
  * Performs normalization of the non-identifier arguments. It creates a temporary compound
  * statement filled with the temporary assignments to set of identifiers that takes the original
  * arugments as RHS.
  */
 @SuppressWarnings("unchecked")
 protected void normalizeArguments() {
   if (exception != 0) { // no normalization is possible.
     return;
   }
   temp_assignments = new CompoundStatement();
   norm_arguments = new ArrayList<Expression>(4);
   for (int i = 0; i < arguments.size(); i++) {
     Symbol param = getParameters().get(i);
     Expression arg = Symbolic.simplify(arguments.get(i));
     // Allows normalization of identifers which are global array names.
     if (arg instanceof Identifier) {
       Symbol base = ((Identifier) arg).getSymbol();
       if (SymbolTools.isGlobal(base) && SymbolTools.isArray(base)) {
         arg =
             new UnaryExpression(
                 UnaryOperator.ADDRESS_OF, new ArrayAccess(arg.clone(), new IntegerLiteral(0)));
       }
     }
     Expression new_arg = arg;
     if (!(arg instanceof Literal || arg instanceof Identifier)) {
       arg = normalize(arg, param);
       List type_spec = param.getTypeSpecifiers();
       List array_spec = param.getArraySpecifiers();
       // Assumes there is only one element in array_spec.
       if (!array_spec.isEmpty()) {
         type_spec.add(PointerSpecifier.UNQUALIFIED);
       }
       new_arg = SymbolTools.getTemp(temp_assignments, type_spec, "arg");
       Expression assign =
           new AssignmentExpression(new_arg, AssignmentOperator.NORMAL, arg.clone());
       temp_assignments.addStatement(new ExpressionStatement(assign));
     }
     norm_arguments.add(new_arg);
   }
 }