// Semantic resolution public override void ResolveType(ISemanticResolver s) { if (m_tRefEntry != null) return; m_tElem.ResolveType(s); m_tRefEntry = new RefTypeEntry(m_tElem.BlueType, s); }
// 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); }