@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(); }