Esempio n. 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);
     */
   }
 }
  public Identifier getActualTaggedTypeName(TaggedTypeRef struct) {
    Identifier structName = null;
    Identifier tag = struct.getTag();
    if (tag == null || tag.isPlain() && tag.toString().startsWith("_")) {
      TypeDef parentDef = as(struct.getParentElement(), TypeDef.class);
      if (parentDef != null) {
        structName =
            new Identifier.SimpleIdentifier(JNAeratorUtils.findBestPlainStorageName(parentDef));
      } else if (tag != null) {
        String better = tag.toString().substring(1);
        Pair<TypeDef, Declarator> pair = result.typeDefs.get(better);
        if (pair != null
            && pair.getFirst().getValueType() != null
            && pair.getSecond() instanceof DirectDeclarator) {
          TypeRef tr = pair.getFirst().getValueType();
          DirectDeclarator dd = (DirectDeclarator) pair.getSecond();

          if (tr instanceof SimpleTypeRef) {
            if (tag.equals(((SimpleTypeRef) tr).getName())) structName = ident(dd.resolveName());
          } else if (tr instanceof TaggedTypeRef) {
            if (tag.equals(((TaggedTypeRef) tr).getTag())) structName = ident(dd.resolveName());
          }
        }
      }
    }
    if (structName == null || structName.toString().equals("")) structName = tag;
    return structName == null ? null : structName.clone();
  }