/*******************************************************************************
- * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others
+ * Copyright (c) 2011, 2013 Ericsson, Ecole Polytechnique de Montreal and others
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0 which
import java.util.List;
/**
- * <b><u>StructDeclaration</u></b>
+ * A CTF structure declaration.
+ *
+ * A structure is similar to a C structure, it is a compound data type that
+ * contains other datatypes in fields. they are stored in an hashmap and indexed
+ * by names which are strings.
+ *
+ * @version 1.0
+ * @author Matthew Khouzam
+ * @author Simon Marchi
*/
public class StructDeclaration implements IDeclaration {
private final HashMap<String, IDeclaration> fields = new HashMap<String, IDeclaration>();
private final List<String> fieldsList = new LinkedList<String>();
- private long minAlign;
+ private long maxAlign;
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
- public StructDeclaration(long minAlign) {
- this.minAlign = minAlign;
+ /**
+ * The struct declaration, add fields later
+ *
+ * @param align
+ * the minimum alignment of the struct. (if a struct is 8bit
+ * aligned and has a 32 bit aligned field, the struct becomes 32
+ * bit aligned.
+ */
+ public StructDeclaration(long align) {
+ this.maxAlign = Math.max(align, 1);
}
// ------------------------------------------------------------------------
// Getters/Setters/Predicates
// ------------------------------------------------------------------------
- public long getMinAlign() {
- return this.minAlign;
- }
-
- public void setMinAlign(long minAlign) {
- this.minAlign = minAlign;
+ /**
+ * Get current alignment
+ * @return the alignment of the struct and all its fields
+ */
+ public long getMaxAlign() {
+ return maxAlign;
}
+ /**
+ * Query if the struct has a given field
+ * @param name the name of the field, scopeless please
+ * @return does the field exist?
+ */
public boolean hasField(String name) {
return this.fields.containsKey(name);
}
+ /**
+ * get the fields of the struct in a map. Faster access time than a list.
+ * @return a HashMap of the fields (key is the name)
+ */
public HashMap<String, IDeclaration> getFields() {
return this.fields;
}
+ /**
+ * Gets the field list. Very important since the map of fields does not retain the order of the fields.
+ * @return the field list.
+ */
public List<String> getFieldsList() {
return this.fieldsList;
}
@Override
public long getAlignment() {
- return getMinAlign();
+ return this.maxAlign;
}
+
// ------------------------------------------------------------------------
// Operations
// ------------------------------------------------------------------------
return new StructDefinition(this, definitionScope, fieldName);
}
+ /**
+ * Add a field to the struct
+ * @param name the name of the field, scopeless
+ * @param declaration the declaration of the field
+ */
public void addField(String name, IDeclaration declaration) {
- // TODO: update the minAlign to be the max of minAlign and the align
- // value of the new field.
this.fields.put(name, declaration);
this.fieldsList.add(name);
+ maxAlign = Math.max(maxAlign, declaration.getAlignment());
+ if (maxAlign == 1) {
+ maxAlign = 1;
+ }
}
@Override
return "[declaration] struct[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = (prime * result) + fieldsList.hashCode();
+ result = (prime * result) + (int) (maxAlign ^ (maxAlign >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof StructDeclaration)) {
+ return false;
+ }
+ StructDeclaration other = (StructDeclaration) obj;
+ if (!fieldsList.equals(other.fieldsList)) {
+ return false;
+ }
+ if (maxAlign != other.maxAlign) {
+ return false;
+ }
+ return true;
+ }
+
}