// @todo - how does the numbering here work? Start at 0 or 1? // does it include the 'this' parameter public System.Type ParamCLRType(int iParam) { // Parameter can be either a actual type or a reference to a type if (this.Node != null) { ParamVarExpEntry sym = Node.Params[iParam].ParamSymbol; return(sym.m_type.CLRType); } else if (this.Info != null) { return(Info.GetParameters()[iParam].ParameterType); } else { return(null); } } // end ParamCLRType
public ParamVarDecl(Identifier idName, NonRefTypeSig tType, EArgFlow eFlow) : base(idName, tType) { m_eFlow = eFlow; // Update tType to include the Ref/Out if (m_eFlow == EArgFlow.cOut || m_eFlow == EArgFlow.cRef) { this.m_tType = new RefTypeSig(tType); } m_symbol = new ParamVarExpEntry(); }
// Semantic checking public override void ResolveMember( TypeEntry symDefiningClass, ISemanticResolver s, ICLRtypeProvider provider ) { //TypeEntry tRetType = null; if (!IsCtor) { m_tRetType.ResolveType(s); //tRetType = m_tRetType.TypeRec; } else { ClassDecl nodeClass = symDefiningClass.Node; if (Mods.IsStatic) { // Checks on static ctors if (this.Params.Length != 0) { //s.ThrowError_NoParamsOnStaticCtor(this); ThrowError(SymbolError.NoParamsOnStaticCtor(this)); } // Rename to avoid a naming collision w/ a default ctor. // Since no one will call a static ctor (and codegen ignores ctor names), // we can pick anything here. //this.m_strName = "$static_ctor"; this.m_idName = new Identifier("$static_ctor", m_idName.Location); // Is there a static field initializer to chain to? if (nodeClass.StaticInitMethod != null) { /* Statement stmt = new ExpStatement( new MethodCallExp( null, new Identifier(nodeClass.StaticInitMethod.Name, nodeClass.StaticInitMethod.Location), new ArgExp[0] )); */ // If there are Static, ReadOnly fields, then they must be assigned directly // in a constructor, not in a function called by the constructor. Statement stmt = nodeClass.StaticInitMethod.Body; Body.InjectStatementAtHead(stmt); } } // static ctor else { if (nodeClass.InstanceInitMethod != null) { // Chain to an instance-field initializer if we don't chain to // a this() ctor. CtorChainStatement chain = (this.Body.Statements[0]) as CtorChainStatement; Debug.Assert(chain != null); if (chain.TargetType == CtorChainStatement.ETarget.cBase) { /* Statement stmt = new MethodCallStatement( new MethodCallExp( null, new Identifier(nodeClass.InstanceInitMethod.Name, nodeClass.InstanceInitMethod.Location), new ArgExp[0] )); */ // PEVerify barfs if we try to do an instance method call in the ctor, // so just inject the raw method body. It's just a bunch of assigns anyway, // so we're ok. Statement stmt = nodeClass.InstanceInitMethod.Body; Body.InjectStatementAtHead(stmt); } } } // instance ctor } // Add new sym entry to our parent class's scope MethodExpEntry m = new MethodExpEntry( Name, this, symDefiningClass, IsCtor ? null : m_tRetType.BlueType ); m.m_scope = new Scope( "method: " + symDefiningClass.m_strName + "." + Name, this, symDefiningClass.MemberScope); m_symbol = m; //s.PushScope(m.m_scope); Scope prev = s.SetCurrentContext(m.m_scope); // resolve params (because we'll need them for overloading) // Add param 0 for 'this' (if not static) // For structs, "this" is a reference, for classes, it's a value. if (!Mods.IsStatic) { ParamVarExpEntry e = new ParamVarExpEntry(); e.m_strName = "this"; TypeEntry t = m_symbol.SymbolClass; if (t.IsStruct) { t = new RefTypeEntry(t, s); } e.m_type = t; // 'this' is the type of the containg class e.CodeGenSlot = 0; s.GetCurrentContext().AddSymbol(e); } // do rest of the params foreach(ParamVarDecl param in m_arParams) { param.ResolveVarDecl(s); } //s.PopScope(m.m_scope); s.RestoreContext(prev); symDefiningClass.AddMethodToScope(m); }