| /* --COPYRIGHT--,EPL | |
| * Copyright (c) 2008 Texas Instruments 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 accompanies this distribution, and is available at | |
| * http://www.eclipse.org/legal/epl-v10.html | |
| * | |
| * Contributors: | |
| * Texas Instruments - initial implementation | |
| * | |
| * --/COPYRIGHT--*/ | |
| package xdc.services.spec; | |
| import java.util.*; | |
| public class Decl | |
| extends Node | |
| { | |
| // Static Serialization UID | |
| static final long serialVersionUID = 3468768778188819860L; | |
| Decl over = null; | |
| // Annexable | |
| public interface Annexable | |
| { | |
| } | |
| // AuxDef | |
| public interface AuxDef | |
| { | |
| } | |
| // IsType | |
| public interface IsType | |
| { | |
| } | |
| // LocalUnit | |
| public interface LocalUnit | |
| { | |
| Unit getUnit(); | |
| } | |
| // OverridableDef | |
| public interface OverridableDef | |
| { | |
| } | |
| // Signature | |
| public interface Signature | |
| { | |
| enum ObjKind { NONE, SINGLE, ARRAY }; | |
| Type getType(); | |
| String getTypeCode(); | |
| String getTypeSig(); | |
| } | |
| // Sizeable | |
| public interface Sizeable | |
| { | |
| void sizeof( List<String> sL ); | |
| } | |
| private static void checkSig( Signature sig ) | |
| { | |
| Signature.ObjKind kind = Decl.objKind(sig); | |
| if (kind == Signature.ObjKind.NONE) { | |
| return; | |
| } | |
| if (sig instanceof Decl.Field) { | |
| Decl.Struct str = (Decl.Struct)((Decl.Field)sig).getParent(); | |
| if (str.getName().equals("Module_State") || str.getName().equals("Instance_State")) { | |
| return; | |
| } | |
| } | |
| Decl decl = (Decl)sig; | |
| Session ses = decl.getSession(); | |
| ses.msg.error(decl.getAtom(), "bad use of Object type"); | |
| } | |
| // overrides | |
| public Decl overrides() | |
| { | |
| return this.over; | |
| } | |
| // finalCheck | |
| void finalCheck() | |
| { | |
| super.finalCheck(); | |
| List<? extends Decl> dL = this.getChildren(); | |
| if (dL == null) { | |
| return; | |
| } | |
| for (Decl d : dL) { | |
| d.finalCheck(); | |
| } | |
| } | |
| // getChildren | |
| public List<? extends Decl> getChildren() | |
| { | |
| return null; | |
| } | |
| // getQualName | |
| public String getQualName() | |
| { | |
| return this.parent.getQualName() + '.' + this.name.text; | |
| } | |
| // getXmlTag | |
| public String getXmlTag() | |
| { | |
| return this.getClass().getSimpleName().toLowerCase(); | |
| } | |
| /** | |
| * Generate the XDoc for a Decl. Unlike other Nodes, documentation | |
| * for a Decl accumulates any docs coming from parent interfaces. This | |
| * method collects the docs from the override chain, then appends the | |
| * docs specific for this Decl. | |
| */ | |
| void parseXDoc() { | |
| XDoc od = overrides() == null ? null : overrides().makeXDoc(); | |
| this.xdoc = new XDoc(getDocs(), od, summary, isNodoc); | |
| } | |
| // objKind | |
| public static final Decl.Signature.ObjKind objKind( Decl.Signature sig ) | |
| { | |
| return objKind(sig.getType(), sig.getTypeCode()); | |
| } | |
| public static final Decl.Signature.ObjKind objKind( Type type, String tcode ) | |
| { | |
| if (tcode.equals("O")) { | |
| return Decl.Signature.ObjKind.SINGLE; | |
| } | |
| else if (tcode.equals("AO")) { | |
| Type.Array tarr = (Type.Array)type; | |
| return tarr.getDim() != null ? Decl.Signature.ObjKind.ARRAY : Decl.Signature.ObjKind.NONE; | |
| } | |
| else { | |
| return Decl.Signature.ObjKind.NONE; | |
| } | |
| } | |
| // parseDocs | |
| void parseDocs() | |
| { | |
| super.parseDocs(); | |
| List<? extends Decl> dL = this.getChildren(); | |
| if (dL == null) { | |
| return; | |
| } | |
| for (Decl d : dL) { | |
| d.parseDocs(); | |
| } | |
| } | |
| // pass1Check | |
| void pass1Check() | |
| { | |
| List<? extends Decl> dL = this.getChildren(); | |
| if (dL == null) { | |
| return; | |
| } | |
| for (Decl d : dL) { | |
| d.bindParent(d instanceof Decl.EnumVal ? this.parent : this); | |
| Session ses = d.getSession(); | |
| if (!ses.enterNode(d.getQualName(), d)) { | |
| ses.msg.error(d.name, "multiple declaration in enclosing scope"); | |
| continue; | |
| } | |
| } | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| // TODO: common stuff ??? | |
| } | |
| // Decl.Arg | |
| static public class Arg | |
| extends Decl | |
| implements Decl.Signature | |
| { | |
| static final long serialVersionUID = -7298373774659045568L; | |
| Type type; | |
| Expr init; | |
| Arg( Atom name, EnumSet<Qual> quals, Type type ) | |
| { | |
| this(name, quals, type, null); | |
| } | |
| Arg( Atom name, EnumSet<Qual> quals, Type type, Expr init ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.type = type; | |
| this.init = init; | |
| } | |
| // getInit | |
| public final Expr getInit() | |
| { | |
| return this.init; | |
| } | |
| // getType | |
| public final Type getType() | |
| { | |
| return this.type; | |
| } | |
| // getTypeCode | |
| public final String getTypeCode() | |
| { | |
| return ((this.type == null) ? "" : this.type.tcode()); | |
| } | |
| // getTypeSig | |
| public final String getTypeSig() | |
| { | |
| return ((this.type == null) ? "" : this.type.tsig()); | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| if (this.type != null) { | |
| this.type.resolve(uspec); | |
| if (this.init != null) { | |
| this.init.resolve(uspec); | |
| } | |
| } | |
| Decl.checkSig(this); | |
| } | |
| } | |
| // Decl.Config | |
| static public class Config | |
| extends Decl | |
| implements Decl.Annexable, Decl.Signature | |
| { | |
| static final long serialVersionUID = -3472392753188999914L; | |
| Type type; | |
| Expr init; | |
| static HashSet<String> reservedAttrs = new HashSet(Arrays.asList(new String[] { | |
| Attr.A_Annex, | |
| Attr.A_CommandOption, | |
| Attr.A_Facet, | |
| Attr.A_System, | |
| })); | |
| Config( Atom name, EnumSet<Qual> quals, Type type, Expr init ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.type = type; | |
| this.init = init; | |
| } | |
| // checkFacet | |
| private void checkFacet() | |
| { | |
| if (!this.isMeta()) { | |
| ses.msg.error(this.name, "@Facet configs must be metaonly"); | |
| } | |
| Ref r = this.type.tspec().getRef(); | |
| Node n = r.getNode(); | |
| HashSet<String> facSet = ((Unit)this.getParent()).facSet; | |
| if (!(n instanceof Unit) || !n.hasAttr(Attr.A_Facet) || !r.getId().equals("Instance")) { | |
| ses.msg.error(this.name, "@Facet config types must be a @Facet Instance"); | |
| } | |
| else if (facSet.contains(n.getQualName())) { | |
| ses.msg.error(this.name, "multiple @Facet configs of the same type"); | |
| } | |
| else { | |
| facSet.add(n.getQualName()); | |
| } | |
| } | |
| // finalCheck | |
| void finalCheck() | |
| { | |
| super.finalCheck(); | |
| String tc = this.getTypeCode(); | |
| if (this.hasAttr(Attr.A_Facet)) { | |
| this.checkFacet(); | |
| } | |
| } | |
| // getInit | |
| public final Expr getInit() | |
| { | |
| return this.init; | |
| } | |
| // getType | |
| public final Type getType() | |
| { | |
| return this.type; | |
| } | |
| // getTypeCode | |
| public final String getTypeCode() | |
| { | |
| return ((this.type == null) ? "" : this.type.tcode()); | |
| } | |
| // getTypeSig | |
| public final String getTypeSig() | |
| { | |
| return ((this.type == null) ? "" : this.type.tsig()); | |
| } | |
| // overrides | |
| public final Decl.Config overrides() | |
| { | |
| return (Decl.Config) this.over; | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| this.enterAttrs(Decl.Config.reservedAttrs); | |
| if (this.type != null) { | |
| this.type.resolve(uspec, true); | |
| if (this.init != null) { | |
| this.init.resolve(uspec); | |
| } | |
| } | |
| Decl.checkSig(this); | |
| } | |
| } | |
| // Decl.Const | |
| static public class Const | |
| extends Decl | |
| implements Decl.AuxDef, Decl.OverridableDef, Decl.Signature | |
| { | |
| static final long serialVersionUID = -5129490619630763331L; | |
| Type type; | |
| Expr init; | |
| Const( Atom name, EnumSet<Qual> quals, Type type, Expr init ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.type = type; | |
| this.init = init; | |
| if (this.init != null) { | |
| this.quals.add(Qual.FINAL); | |
| } | |
| } | |
| // getInit | |
| public final Expr getInit() | |
| { | |
| return this.init; | |
| } | |
| // getType | |
| public final Type getType() | |
| { | |
| return this.type; | |
| } | |
| // getTypeCode | |
| public final String getTypeCode() | |
| { | |
| return ((this.type == null) ? "" : this.type.tcode()); | |
| } | |
| // getTypeSig | |
| public final String getTypeSig() | |
| { | |
| return ((this.type == null) ? "" : this.type.tsig()); | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| if (this.type != null) { | |
| this.type.resolve(uspec); | |
| if (this.init != null) { | |
| this.init.resolve(uspec); | |
| } | |
| else { | |
| ((Unit) this.parent).custHdr = true; | |
| } | |
| } | |
| Decl.checkSig(this); | |
| } | |
| } | |
| // Decl.Enum | |
| static public class Enum | |
| extends Decl | |
| implements Decl.AuxDef, Decl.IsType, Decl.Sizeable | |
| { | |
| static final long serialVersionUID = -7076604082337550848L; | |
| List<EnumVal> vals; | |
| Type.Spec rep; | |
| Enum( Atom name, EnumSet<Qual> quals, List<EnumVal> vals, Type.Spec rep ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.vals = vals; | |
| this.rep = rep; | |
| } | |
| // getChildren | |
| public List<EnumVal> getChildren() | |
| { | |
| return this.vals; | |
| } | |
| // getRep | |
| public final Type.Spec getRep() | |
| { | |
| return this.rep; | |
| } | |
| // getVals | |
| public final List<EnumVal> getVals() | |
| { | |
| return this.vals; | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| for (EnumVal e : this.vals) { | |
| if (e.init != null) { | |
| e.init.resolve(uspec); | |
| } | |
| } | |
| if (this.rep != null) { | |
| this.rep.resolve(uspec); | |
| } | |
| } | |
| // sizeof | |
| public void sizeof( List<String> sL ) | |
| { | |
| if (this.rep != null) { | |
| this.rep.sizeof(sL); | |
| } | |
| else { | |
| sL.add("N" + this.getQualName()); | |
| } | |
| } | |
| } | |
| // Decl.EnumVal | |
| static public class EnumVal | |
| extends Decl | |
| implements Decl.AuxDef | |
| { | |
| static final long serialVersionUID = -3594208666128592956L; | |
| Expr init; | |
| EnumVal( Atom name, EnumSet<Qual> quals, Expr init ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.init = init; | |
| } | |
| // getInit | |
| public final Expr getInit() | |
| { | |
| return this.init; | |
| } | |
| } | |
| // Decl.Error | |
| static class Error | |
| extends Decl | |
| { | |
| static final long serialVersionUID = 3065995409031385368L; | |
| Error() | |
| { | |
| } | |
| } | |
| // Decl.Extern | |
| static public class Extern | |
| extends Decl | |
| implements Decl.AuxDef, Decl.Signature | |
| { | |
| static final long serialVersionUID = -5537398406232068500L; | |
| Type type; | |
| Atom init; | |
| Extern( Atom name, EnumSet<Qual> quals, Type type, Atom init ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.type = type; | |
| this.init = init; | |
| } | |
| // finalCheck | |
| void finalCheck() | |
| { | |
| super.finalCheck(); | |
| if (!this.parent.isMod()) { | |
| ses.msg.error(this.name, "extern declaration permitted only in modules"); | |
| } | |
| } | |
| // getType | |
| public final Type getType() | |
| { | |
| return this.type; | |
| } | |
| // getTypeCode | |
| public final String getTypeCode() | |
| { | |
| return ((this.type == null) ? "" : this.type.tcode()); | |
| } | |
| // getTypeSig | |
| public final String getTypeSig() | |
| { | |
| return ((this.type == null) ? "" : this.type.tsig()); | |
| } | |
| // getValue | |
| public final String getValue() | |
| { | |
| return ((this.init == null) ? this.getQualName().replace('.', '_') : this.init.text); | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| if (this.type != null) { | |
| this.type.resolve(uspec); | |
| } | |
| Decl.checkSig(this); | |
| } | |
| } | |
| // Decl.Field | |
| static public class Field | |
| extends Decl | |
| implements Decl.Signature | |
| { | |
| static final long serialVersionUID = 1865932903245823181L; | |
| Type type; | |
| Field( Atom name, EnumSet<Qual> quals, Type type ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.type = type; | |
| } | |
| // getType | |
| public final Type getType() | |
| { | |
| return this.type; | |
| } | |
| // getTypeCode | |
| public final String getTypeCode() | |
| { | |
| return ((this.type == null) ? "" : this.type.tcode()); | |
| } | |
| // getTypeSig | |
| public final String getTypeSig() | |
| { | |
| return ((this.type == null) ? "" : this.type.tsig()); | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| if (this.type != null) { | |
| this.type.resolve(uspec); | |
| } | |
| Decl.checkSig(this); | |
| } | |
| } | |
| // Decl.Fxn | |
| static public class Fxn | |
| extends Decl | |
| implements Decl.Annexable, Decl.Signature | |
| { | |
| static final long serialVersionUID = 4734759580216702060L; | |
| Type type; | |
| List<Arg> args; | |
| boolean isVarg; | |
| int minargc = 0; | |
| String structName = null; | |
| static HashSet<String> reservedAttrs = new HashSet(Arrays.asList(new String[] { | |
| Attr.A_Annex, | |
| Attr.A_DirectCall, | |
| Attr.A_Macro, | |
| Attr.A_System, | |
| })); | |
| Fxn( Atom name, EnumSet<Qual> quals, Type type, List<Arg> args, boolean isVarg ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.type = type; | |
| this.args = args; | |
| this.isVarg = isVarg; | |
| } | |
| // finalCheck | |
| void finalCheck() | |
| { | |
| super.finalCheck(); | |
| if (this.type == null) { | |
| return; | |
| } | |
| if (this.type instanceof Type.Creator && this.isStatic()) { | |
| ses.msg.error(this.name, "declaration must be per-instance"); | |
| } | |
| Type t = this.type.root(); | |
| if (t != null && (t instanceof Type.Fxn || t instanceof Type.Array)) { | |
| ses.msg.error(this.name, "function can't return functions or arrays"); | |
| } | |
| if (!this.isStruct()) { | |
| return; | |
| } | |
| if (!this.isStatic()) { | |
| ses.msg.error(this.name, "struct-qualified functions must be module-wide"); | |
| } | |
| String fn = this.name.getText(); | |
| this.name.replaceText(fn.replace('.', '_')); | |
| int k = fn.lastIndexOf('.'); | |
| if (k != -1) { | |
| String sn = fn.substring(0, k); | |
| String qn = this.parent.getQualName() + '.' + sn; | |
| if (!(ses.lookup(qn) instanceof Decl.Struct)) { | |
| ses.msg.error(this.name, "qualified name must reference a struct in scope"); | |
| } | |
| } | |
| } | |
| // getArgs | |
| public final List<Arg> getArgs() | |
| { | |
| return this.args; | |
| } | |
| // getChildren | |
| public List<Arg> getChildren() | |
| { | |
| return this.args; | |
| } | |
| // getMinArgc | |
| public final int getMinArgc() | |
| { | |
| return this.minargc; | |
| } | |
| // getStructName | |
| public final String getStructName() | |
| { | |
| return this.structName; | |
| } | |
| // getType | |
| public final Type getType() | |
| { | |
| return this.type; | |
| } | |
| // getTypeCode | |
| public final String getTypeCode() | |
| { | |
| if (this.type == null) { | |
| return (""); | |
| } | |
| return this.type instanceof Type.Creator ? "C" : this.type.tcode(); | |
| } | |
| // getTypeSig | |
| public final String getTypeSig() | |
| { | |
| if (this.type == null) { | |
| return "void"; | |
| } | |
| String res = this.type instanceof Type.Creator ? "$Instance" : this.type.tsig(); | |
| res += "(*)("; | |
| String sp = ""; | |
| if (this.args.size() == 0 && !this.isVarg) { | |
| return res + "xdc_Void)"; | |
| } | |
| for (Arg arg : this.args) { | |
| res += sp + arg.type.tsig(); | |
| sp = ","; | |
| } | |
| res += this.isVarg ? ",...)" : ")"; | |
| return res; | |
| } | |
| // isLoggable | |
| public final boolean isLoggable() | |
| { | |
| return | |
| !this.isMeta() && | |
| !this.isSys() && | |
| !this.isInternal() && | |
| !this.hasAttr(Attr.A_Macro) && | |
| !this.hasAttr(Attr.A_DirectCall); | |
| } | |
| // isStruct | |
| public final boolean isStruct() | |
| { | |
| return this.structName != null; | |
| } | |
| // isVarg | |
| public final boolean isVarg() | |
| { | |
| return this.isVarg; | |
| } | |
| // overrides | |
| public final Decl.Fxn overrides() | |
| { | |
| return (Decl.Fxn) this.over; | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| this.enterAttrs(Decl.Fxn.reservedAttrs); | |
| if (this.hasAttr(Attr.A_Macro)) { | |
| ((Unit) this.parent).custHdr = true; | |
| } | |
| if (this.type == null) { | |
| return; | |
| } | |
| String fn = this.name.getText(); | |
| int k = fn.lastIndexOf('.'); | |
| if (k != -1) { | |
| this.structName = fn.substring(0, k); | |
| Decl.Arg arg = new Decl.Arg( | |
| new Atom("__this"), | |
| EnumSet.noneOf(Qual.class), | |
| new Type.Ptr( | |
| new Type.Declarator( | |
| new Type.Spec(new Ref(null, this.name.copy(this.structName)), null, false, null), | |
| new Atom("__this")), | |
| EnumSet.noneOf(Type.Modifier.class)), | |
| null); | |
| this.args.add(0, arg); | |
| } | |
| this.type.resolve(uspec); | |
| boolean defflg = false; | |
| for (Arg arg : this.args) { | |
| if (arg.init == null) { | |
| if (!defflg) { | |
| this.minargc++; | |
| } | |
| else { | |
| ses.msg.error(arg.name, "default value required"); | |
| } | |
| } | |
| else { | |
| defflg = true; | |
| } | |
| arg.resolve(uspec); | |
| } | |
| if (this.isStruct()) { | |
| if (!(this.args.get(0).getType().tspec().getRef().getNode() instanceof Decl.Struct)) { | |
| ses.msg.error(this.name, "qualified name does not reference a struct type"); | |
| } | |
| this.minargc--; | |
| } | |
| Decl.checkSig(this); | |
| } | |
| } | |
| // Decl.Imp | |
| static public class Imp | |
| extends Decl | |
| implements Decl.AuxDef, Decl.LocalUnit | |
| { | |
| static final long serialVersionUID = -2L; | |
| Import imp; | |
| Sup sup; | |
| Imp( Atom name, Import imp ) | |
| { | |
| this(name, imp, null); | |
| } | |
| Imp( Atom name, Sup sup ) | |
| { | |
| this(name, null, sup); | |
| } | |
| private Imp( Atom name, Import imp, Sup sup ) | |
| { | |
| this.name = name; | |
| this.imp = imp; | |
| this.sup = sup; | |
| this.quals = EnumSet.noneOf(Qual.class); | |
| } | |
| public final void bindImport( Import imp ) | |
| { | |
| this.imp = imp; | |
| } | |
| public final Import getImport() | |
| { | |
| return this.imp; | |
| } | |
| public final Unit getUnit() | |
| { | |
| return this.imp.unit; | |
| } | |
| // finalCheck | |
| void finalCheck() | |
| { | |
| super.finalCheck(); | |
| if (this.imp == null) { | |
| ses.msg.error(this.name, "no corresponding import"); | |
| } | |
| boolean found = true; | |
| if (this.sup != null) { | |
| found = false; | |
| for (Unit iu : this.getUnit().getInherits()) { | |
| if (iu == sup.getUnit()) { | |
| found = true; | |
| break; | |
| } | |
| } | |
| } | |
| if (!found) { | |
| ses.msg.error(this.name, "does not inherit from " + sup.getUnit().getQualName()); | |
| throw new SessionRuntimeException("parser failed"); | |
| } | |
| } | |
| // resolve | |
| void resolve( Unit u ) | |
| { | |
| if (this.sup != null) { | |
| this.sup.resolve(u); | |
| } | |
| } | |
| } | |
| // Decl.Proxy | |
| static public class Proxy | |
| extends Decl | |
| implements Decl.LocalUnit | |
| { | |
| static final long serialVersionUID = -5207411272617839552L; | |
| Sup sup; | |
| Unit unit; | |
| Proxy( Atom name, EnumSet<Qual> quals, Sup sup ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.sup = sup; | |
| } | |
| // getInherits | |
| public final Unit getInherits() | |
| { | |
| return this.sup.unit; | |
| } | |
| // getUnit | |
| public final Unit getUnit() | |
| { | |
| Unit u = this.getParent().getSession().findUnit( | |
| this.getParent().getQualName() + '_' + this.getName()); | |
| return u == null ? this.sup.unit : u; | |
| } | |
| } | |
| // Decl.Struct | |
| static public class Struct | |
| extends Decl | |
| implements Decl.AuxDef, Decl.IsType, Decl.Sizeable | |
| { | |
| static final long serialVersionUID = 8653474625146200716L; | |
| List<Field> flds; | |
| List<String> fldSizes; | |
| boolean uflag; | |
| static HashSet<String> reservedAttrs = new HashSet(Arrays.asList(new String[] { | |
| Attr.A_Opaque, | |
| Attr.A_XmlDtd, | |
| })); | |
| Struct( Atom name, EnumSet<Qual> quals, List<Field> flds, boolean uflag ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.flds = flds; | |
| this.uflag = uflag; | |
| this.fldSizes = new ArrayList(); | |
| } | |
| // finalCheck | |
| void finalCheck() | |
| { | |
| super.finalCheck(); | |
| if (this.name.text.equals("Object")) { | |
| ses.msg.error(this.name, "reserved name"); | |
| } | |
| } | |
| // getChildren | |
| public List<Field> getChildren() | |
| { | |
| return this.flds; | |
| } | |
| // getFields | |
| public final List<Field> getFields() | |
| { | |
| return this.flds; | |
| } | |
| // getSizes | |
| public final List<String> getSizes() | |
| { | |
| return this.fldSizes; | |
| } | |
| // getXmlTag | |
| public String getXmlTag() | |
| { | |
| return this.uflag ? "union" : "struct"; | |
| } | |
| // isAnon | |
| public final boolean isAnon() | |
| { | |
| return this.name.text.startsWith("__struct__"); | |
| } | |
| // isUnion | |
| public final boolean isUnion() | |
| { | |
| return this.uflag; | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| this.enterAttrs(Decl.Struct.reservedAttrs); | |
| if (this.flds == null) { | |
| return; | |
| } | |
| boolean isState = | |
| this.getName().equals("Module_State") || this.getName().equals("Instance_State"); | |
| for (Field fld : this.flds) { | |
| fld.resolve(uspec); | |
| } | |
| if (isState) { | |
| List<Field> fL = new ArrayList<Field>(); | |
| for (ListIterator<Field> it = this.flds.listIterator(); it.hasNext(); ) { | |
| Field fld = it.next(); | |
| if (Decl.objKind(fld) != Decl.Signature.ObjKind.NONE) { | |
| fL.add(fld); | |
| it.remove(); | |
| } | |
| } | |
| this.flds.addAll(fL); | |
| } | |
| for (Field fld : this.flds) { | |
| fld.type.sizeof(this.fldSizes); | |
| } | |
| } | |
| // sizeof | |
| public void sizeof( List<String> sL ) | |
| { | |
| Unit unit = (Unit) this.parent; | |
| sL.add("S" + unit.getQualName() + ';' + this.name.text); | |
| } | |
| } | |
| // Decl.Typedef | |
| static public class Typedef | |
| extends Decl | |
| implements Decl.AuxDef, Decl.IsType, Decl.Signature, Decl.Sizeable | |
| { | |
| static final long serialVersionUID = -3286912318315178858L; | |
| Type type; | |
| static HashSet<String> reservedAttrs = new HashSet(Arrays | |
| .asList(new String[] { Attr.A_Encoded, | |
| })); | |
| Typedef( Atom name, EnumSet<Qual> quals, Type type ) | |
| { | |
| this.name = name; | |
| this.quals = quals; | |
| this.type = type; | |
| } | |
| // getType | |
| public final Type getType() | |
| { | |
| return this.type; | |
| } | |
| // getTypeCode | |
| public final String getTypeCode() | |
| { | |
| return ((this.type == null) ? "" : this.type.tcode()); | |
| } | |
| // getTypeSig | |
| public final String getTypeSig() | |
| { | |
| return ((this.type == null) ? "" : this.type.tsig()); | |
| } | |
| // resolve | |
| void resolve( Unit uspec ) | |
| { | |
| this.enterAttrs(Decl.Typedef.reservedAttrs); | |
| if (this.hasAttr(Attr.A_Encoded)) { | |
| ((Unit) this.parent).custHdr = true; | |
| } | |
| if (this.type == null) { | |
| return; | |
| } | |
| this.type.resolve(uspec, this.attrBool(Attr.A_Encoded)); | |
| Type t = this.type; | |
| while (t instanceof Type.Declarator) { | |
| Node n = t.tspec().getRef().getNode(); | |
| if (n == this) { | |
| ses.msg.error(this.name, "circular typedef"); | |
| return; | |
| } | |
| if (!(n instanceof Typedef)) { | |
| break; | |
| } | |
| t = ((Typedef) n).getType(); | |
| } | |
| Decl.checkSig(this); | |
| } | |
| // sizeof | |
| public void sizeof( List<String> sL ) | |
| { | |
| if (this.attrBool(Attr.A_Encoded)) { | |
| Unit unit = (Unit) this.parent; | |
| sL.add("E" + unit.getQualName() + ';' + this.name.text); | |
| } | |
| else { | |
| this.type.sizeof(sL); | |
| } | |
| } | |
| } | |
| } |