public StructDefinition(MemberFlags flags, string name, GenericSignature genericSignature, AstNode bases, AstNode children, TokenPosition position) : base(children, position) { SetName(name); this.flags = flags; this.bases = bases; this.genericSignature = genericSignature; this.defaultConstructor = null; this.genericScope = null; }
public override AstNode Visit(MemberAccess node) { // Evaluate the base reference. Expression baseReference = node.GetReference(); baseReference.SetHints(node.Hints); baseReference.Accept(this); // Get the base reference type. IChelaType baseRefType = baseReference.GetNodeType(); if(baseRefType.IsConstant()) baseRefType = DeConstType(baseRefType); // Set a default coercion type. node.SetCoercionType(baseRefType); // Get the scope. Scope scope = null; bool canStatic = true; bool canNoStatic = node.HasHints(Expression.MemberHint); bool suppressVirtual = false; bool implicitThis = false; if(baseRefType.IsMetaType()) { // Read the base reference type. baseRefType = ExtractActualType(node, baseRefType); // Handle incomplete types. if(baseRefType.IsIncompleteType()) { node.SetNodeType(baseRefType); return node; } // Handle built-in types if(!baseRefType.IsStructure() && !baseRefType.IsClass() && !baseRefType.IsInterface()) { baseRefType = currentModule.GetAssociatedClass(baseRefType); if(baseRefType == null) Error(node, "expected a known type."); } scope = (Scope) baseRefType; suppressVirtual = true; // Get the current container scope. Scope contScope = currentScope; while(contScope != null && (contScope.IsPseudoScope() || contScope.IsFunction() || contScope.IsLexicalScope())) contScope = contScope.GetParentScope(); // Check if the base type is a base of me. Structure building = contScope as Structure; if(building != null) { Structure scopeBuilding = (Structure) baseRefType; if(building.IsDerivedFrom(scopeBuilding)) { canNoStatic = true; implicitThis = true; } } } else if(baseRefType.IsNamespace()) { scope = (Namespace) baseReference.GetNodeValue(); } else if(baseRefType.IsReference()) { canStatic = false; canNoStatic = true; // Get the variable referenced type. ReferenceType refType = (ReferenceType)baseRefType; IChelaType objectType = refType.GetReferencedType(); if(objectType.IsReference()) { // Set the variable type as the coercion type. node.SetCoercionType(objectType); // Dereference. refType = (ReferenceType)objectType; objectType = refType.GetReferencedType(); } else if(objectType.IsStructure()) { // Use the structure type as the coercion type. node.SetCoercionType(objectType); } else if(objectType.IsPrimitive() || objectType.IsVector() || objectType.IsPlaceHolderType()) { node.SetCoercionType(objectType); } if(objectType.IsStructure() || objectType.IsClass() || objectType.IsInterface() || objectType.IsTypeInstance()) scope = (Scope)objectType; else if(objectType.IsPlaceHolderType()) scope = new PseudoScope((PlaceHolderType)objectType); else { scope = currentModule.GetAssociatedClass(objectType); if(scope == null) Error(node, "unimplemented primitive type classes."); } } else if(baseRefType.IsStructure()) { canStatic = false; canNoStatic = true; scope = (Scope)baseRefType; } else if(baseRefType.IsPrimitive()) { canStatic = false; canNoStatic = true; scope = currentModule.GetAssociatedClass(baseRefType); if(scope == null) Error(node, "unimplemented primitive type classes."); } else if(baseRefType.IsVector()) { canStatic = false; canNoStatic = true; scope = currentModule.GetAssociatedClass(baseRefType); if(scope == null) Error(node, "unimplemented vector type classes."); } else if(baseRefType.IsPlaceHolderType()) { canStatic = false; canNoStatic = true; scope = new PseudoScope((PlaceHolderType)baseRefType); } else { Error(node, "expected reference, namespace, struct, class, primitive, vector."); } // Check vectorial swizzle. IChelaType coercionType = node.GetCoercionType(); if(coercionType.IsVector()) { VectorType vectorType = (VectorType)coercionType; int minSize = 0; int mask = 0; string fieldName = node.GetName(); if(fieldName.Length <= 4) { // It can be a vectorial swizzle bool isSwizzle = true; for(int i = 0; i < fieldName.Length; ++i) { switch(fieldName[i]) { case 'x': case 'r': case 's': mask |= 0<<(2*i); if(minSize < 1) minSize = 1; break; case 'y': case 'g': case 't': mask |= 1<<(2*i); if(minSize < 2) minSize = 2; break; case 'z': case 'b': case 'p': mask |= 2<<(2*i); if(minSize < 3) minSize = 3; break; case 'w': case 'a': case 'q': mask |= 3<<(2*i); if(minSize < 4) minSize = 4; break; default: i = fieldName.Length + 1; isSwizzle = false; break; } } // Swizzle found. if(isSwizzle) { // Check the validity. if(minSize > vectorType.GetNumComponents()) Error(node, "accessing inexistent elements in the vector."); // Store the base variable. Variable baseVar = baseReference.GetNodeValue() as Variable; // Return the swizzle. IChelaType swizzleType = VectorType.Create(vectorType.GetPrimitiveType(), fieldName.Length); SwizzleVariable swizzleVar = new SwizzleVariable(swizzleType, baseVar, (byte)mask, fieldName.Length); node.SetNodeValue(swizzleVar); node.SetNodeType(ReferenceType.Create(swizzleType)); return node; } } } // Find the scope member. ScopeMember member = scope.FindMemberRecursive(node.GetName()); if(member == null) { // Check attribute name. if(node.IsAttributeName()) member = scope.FindMemberRecursive(node.GetName() + "Attribute"); if(member == null) Error(node, "couldn't find member '" + node.GetName() + "' in '" + scope.GetFullName() + "'."); } // Check the accesiblity. CheckMemberVisibility(node, member); // Return it. IChelaType type = null; if(member.IsNamespace()) { type = ChelaType.GetNamespaceType(); } else if(member.IsType()) { type = MetaType.Create((IChelaType)member); } else if(member.IsTypeName()) { // Read the type name. TypeNameMember typeName = (TypeNameMember)member; type = typeName.GetActualType(); // Create an incomplete type if necessary. if(type == null) type = new IncompleteType(typeName); type = MetaType.Create(type); } else if(member.IsFunctionGroup()) { FunctionGroup fgroup = (FunctionGroup)member; FunctionGroupSelector selector = new FunctionGroupSelector(fgroup); selector.SuppressVirtual = suppressVirtual; selector.ImplicitThis = implicitThis; member = selector; if(canNoStatic && canStatic) type = ChelaType.GetAnyFunctionGroupType(); else if(canStatic) type = ChelaType.GetStaticFunctionGroupType(); else type = ChelaType.GetFunctionGroupType(); } else if(member.IsFunction()) { Function function = (Function)member; type = function.GetFunctionType(); // Check the static flag. if(!canNoStatic && (function.GetFlags() & MemberFlags.InstanceMask) != MemberFlags.Static) { Error(node, "expected a static function."); } else if(function.IsMethod()) { Method method = (Method)function; node.SetSlot(method.GetVSlot()); } } else { Variable variable = (Variable)member; IChelaType variableType = variable.GetVariableType(); if(variableType.IsPassedByReference()) variableType = ReferenceType.Create(variableType); // Required for nested access. type = ReferenceType.Create(variableType); // Check the static flag. if(!canNoStatic && !variable.IsStatic()) { Error(node, "expected a static variable."); } else if(variable.IsField()) { // Use the slot. FieldVariable field = (FieldVariable) variable; node.SetSlot(field.GetSlot()); } else if(variable.IsProperty() && !variable.IsStatic() && suppressVirtual) { // Wrap the property in a direct property slot. member = new DirectPropertySlot((PropertyVariable)variable); } // Store the implicit this property. if(!variable.IsStatic()) node.ImplicitSelf = implicitThis; } // Set the value. node.SetNodeValue(member); // Set the type. node.SetNodeType(type); return node; }
public void SetGenericScope(PseudoScope genericScope) { this.genericScope = genericScope; }
public override AstNode Visit(DelegateDefinition node) { // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if(genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), GenericPrototype.Empty); if(old != null) Error(node, "trying to redefine a delegate."); // Create the structure MemberFlags flags = node.GetFlags(); // TODO: Check the flags. Class building = new Class(node.GetName(), flags, currentContainer); building.SetGenericPrototype(genProto); building.Position = node.GetPosition(); node.SetStructure(building); // Add into the current scope. if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddType(building); } else if(currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; parent.AddType(building); } else { Error(node, "unexpected place for a delegate."); } // Register the compute binding delegate. if(building.GetFullName() == "Chela.Compute.ComputeBinding") currentModule.RegisterComputeBindingDelegate(building); return node; }
public override AstNode Visit(InterfaceDefinition node) { // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if(genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), genProto); if(old != null) Error(node, "trying to redefine a class."); // Create the structure Interface iface = new Interface(node.GetName(), node.GetFlags(), currentContainer); iface.SetGenericPrototype(genProto); node.SetStructure(iface); iface.Position = node.GetPosition(); // Register type maps. string fullName = iface.GetFullName(); IChelaType alias; if(typeMaps.TryGetValue(fullName, out alias)) currentModule.RegisterTypeMap(alias, ReferenceType.Create(iface)); // Register some important interfaces. if(fullName == "Chela.Lang.NumberConstraint") currentModule.RegisterNumberConstraint(iface); else if(fullName == "Chela.Lang.IntegerConstraint") currentModule.RegisterIntegerConstraint(iface); else if(fullName == "Chela.Lang.FloatingPointConstraint") currentModule.RegisterFloatingPointConstraint(iface); else if(fullName == "Chela.Collections.IEnumerable") currentModule.RegisterEnumerableIface(iface); else if(fullName == "Chela.Collections.IEnumerator") currentModule.RegisterEnumeratorIface(iface); else if(fullName.StartsWith("Chela.Collections.Generic.IEnumerable<")) currentModule.RegisterEnumerableGIface(iface); else if(fullName.StartsWith("Chela.Collections.Generic.IEnumerator<")) currentModule.RegisterEnumeratorGIface(iface); // Use the prototype scope. if(protoScope != null) PushScope(protoScope); // Add into the current scope. if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddType(iface); } else if(currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; parent.AddType(iface); } else { Error(node, "unexpected place for a class."); } // Push the interface unsafe. if(iface.IsUnsafe()) PushUnsafe(); // Update the scope. PushScope(iface); // Visit the building children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); // Restore the generic scope. if(protoScope != null) PopScope(); // Pop the interface unsafe. if(iface.IsUnsafe()) PopUnsafe(); return node; }
public override AstNode Visit(ClassDefinition node) { // Check the partial flag. bool isPartial = (node.GetFlags() & MemberFlags.ImplFlagMask) == MemberFlags.Partial; // Add the parent static flag. if(currentContainer.IsStatic()) { MemberFlags oldInstance = node.GetFlags() & MemberFlags.InstanceMask; if(oldInstance == MemberFlags.Static || oldInstance == MemberFlags.Instanced) { MemberFlags flags = node.GetFlags() & ~MemberFlags.InstanceMask; node.SetFlags(flags | MemberFlags.Static); } else Error(node, "static class member cannot be {0}.", oldInstance.ToString().ToLower()); } // Static classes are automatically sealed. if((node.GetFlags() & MemberFlags.InstanceMask) == MemberFlags.Static) { MemberFlags flags = node.GetFlags() & ~MemberFlags.InheritanceMask; node.SetFlags(flags | MemberFlags.Sealed); } // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if(genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), genProto); if(old != null && (!isPartial || !old.IsClass())) Error(node, "trying to redefine a class."); // Create the structure Class clazz = (Class)old; if(clazz != null) { if(!clazz.IsPartial()) Error(node, "incompatible partial class definitions."); } else { clazz = new Class(node.GetName(), node.GetFlags(), currentContainer); clazz.Position = node.GetPosition(); clazz.SetGenericPrototype(genProto); } node.SetStructure(clazz); // Use the prototype scope. if(protoScope != null) PushScope(protoScope); // Register type maps. string fullName = clazz.GetFullName(); IChelaType alias; if(typeMaps.TryGetValue(fullName, out alias)) currentModule.RegisterTypeMap(alias, clazz); // Register type association. IChelaType assoc; if(assocClasses.TryGetValue(fullName, out assoc)) currentModule.RegisterAssociatedClass(assoc, clazz); // Array base class is special. if(fullName == "Chela.Lang.Array") currentModule.RegisterArrayClass(clazz); else if(fullName == "Chela.Lang.Attribute") currentModule.RegisterAttributeClass(clazz); else if(fullName == "Chela.Lang.ValueType") currentModule.RegisterValueTypeClass(clazz); else if(fullName == "Chela.Lang.Enum") currentModule.RegisterEnumClass(clazz); else if(fullName == "Chela.Lang.Type") currentModule.RegisterTypeClass(clazz); else if(fullName == "Chela.Lang.Delegate") currentModule.RegisterDelegateClass(clazz); else if(fullName == "Chela.Compute.StreamHolder") currentModule.RegisterStreamHolderClass(clazz); else if(fullName == "Chela.Compute.StreamHolder1D") currentModule.RegisterStreamHolder1DClass(clazz); else if(fullName == "Chela.Compute.StreamHolder2D") currentModule.RegisterStreamHolder2DClass(clazz); else if(fullName == "Chela.Compute.StreamHolder3D") currentModule.RegisterStreamHolder3DClass(clazz); else if(fullName == "Chela.Compute.UniformHolder") currentModule.RegisterUniformHolderClass(clazz); // Add into the current scope. if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; if(old == null) space.AddType(clazz); } else if(currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; if(old == null) parent.AddType(clazz); } else { Error(node, "unexpected place for a class."); } // Push the class unsafe. if(clazz.IsUnsafe()) PushUnsafe(); // Update the scope. PushScope(clazz); // Visit the building children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); // Restore the scope. if(protoScope != null) PopScope(); // Pop the class unsafe. if(clazz.IsUnsafe()) PopUnsafe(); return node; }
public override AstNode Visit(StructDefinition node) { // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if(genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), genProto); if(old != null) Error(node, "trying to redefine a struct."); // Create the structure Structure building = new Structure(node.GetName(), node.GetFlags(), currentContainer); building.SetGenericPrototype(genProto); node.SetStructure(building); building.Position = node.GetPosition(); // Use the prototype scope. if(protoScope != null) PushScope(protoScope); // Register type association. string fullName = building.GetFullName(); IChelaType assoc; if(assocClasses.TryGetValue(fullName, out assoc)) currentModule.RegisterAssociatedClass(assoc, building); // Add into the current scope. if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddType(building); } else if(currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; parent.AddType(building); } else { Error(node, "unexpected place for a structure."); } // Push the building unsafe. if(building.IsUnsafe()) PushUnsafe(); // Update the scope. PushScope(building); // Visit the building children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); // Pop the building unsafe. if(building.IsUnsafe()) PopUnsafe(); // Restore the prototype scope. if(protoScope != null) PopScope(); return node; }
public override AstNode Visit(AliasDeclaration node) { PseudoScope scope = new PseudoScope(currentScope); // Store it in the node. node.SetScope(scope); // Change the ast layout to reflect the new scope hierarchy. node.SetChildren(node.GetNext()); node.SetNext(null); // Update the scope. PushScope(node.GetScope()); // Visit his children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); return node; }
public override AstNode Visit(FunctionPrototype node) { MemberFlags callingConvention = node.GetFlags() & MemberFlags.LanguageMask; bool isCdecl = callingConvention == MemberFlags.Cdecl; bool isUnsafe = (node.GetFlags() & MemberFlags.SecurityMask) == MemberFlags.Unsafe; // Use the unsafe scope. if(isUnsafe) PushUnsafe(); // Generate a name for explicit contracts. if(node.GetNameExpression() != null) node.SetName(GenSym()); // Find an existing group. ScopeMember oldGroup = currentContainer.FindMember(node.GetName()); if(oldGroup != null && (oldGroup.IsType() || !oldGroup.IsFunctionGroup())) { if(oldGroup.IsFunction() && isCdecl) { // TODO: Add additional checks. Function oldDefinition = (Function)oldGroup; node.SetFunction(oldDefinition); node.SetNodeType(oldDefinition.GetFunctionType()); oldGroup = null; return node; } else Error(node, "cannot override something without a function group."); } FunctionGroup functionGroup = null; if(oldGroup != null) // Cast the group member. functionGroup = (FunctionGroup)oldGroup; // Make sure the destructor name is correct. if(node.GetDestructorName() != null) { // Get the building scope. Scope buildingScope = currentScope; while(buildingScope != null && (buildingScope.IsFunction() || buildingScope.IsPseudoScope() || buildingScope.IsLexicalScope())) buildingScope = buildingScope.GetParentScope(); // Make sure we are in a class. if(buildingScope == null || !buildingScope.IsClass()) Error(node, "only classes can have finalizers."); // Make sure the destructor and class name are the same. if(node.GetDestructorName() != buildingScope.GetName()) Error(node, "finalizers must have the same name as their class."); } // Read the instance flag. MemberFlags instanceFlags = node.GetFlags() & MemberFlags.InstanceMask; // Don't allow overloading with cdecl. if(isCdecl && functionGroup != null) Error(node, "overloading and cdecl are incompatible."); // Make sure static constructor doesn't have modifiers. if(instanceFlags == MemberFlags.StaticConstructor && node.GetFlags() != MemberFlags.StaticConstructor) Error(node, "static constructors cannot have modifiers."); // Static constructors cannot have paraemeters. if(instanceFlags == MemberFlags.StaticConstructor && node.GetArguments() != null) Error(node, "static constructors cannot have parameters."); // Add the this argument. if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { // Cast the scope. Structure building = (Structure)currentContainer; // Add the this argument. if(instanceFlags != MemberFlags.Static && instanceFlags != MemberFlags.StaticConstructor) { // Instance the building. building = building.GetSelfInstance(); // Use the structure type. TypeNode thisType = new TypeNode(TypeKind.Reference, node.GetPosition()); thisType.SetOtherType(building); // Create the this argument. FunctionArgument thisArg = new FunctionArgument(thisType, "this", node.GetPosition()); // Add to the begin of the argument list. thisArg.SetNext(node.GetArguments()); node.SetArguments(thisArg); } } // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = null; PseudoScope protoScope = null; if(genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Create the placeholders scope. genProto = genericSign.GetPrototype(); protoScope = new PseudoScope(currentScope, genProto); node.SetScope(protoScope); } // Use the prototype scope. if(protoScope != null) PushScope(protoScope); // Visit the arguments. VisitList(node.GetArguments()); // Visit the return type. Expression returnTypeExpr = node.GetReturnType(); IChelaType returnType; if(returnTypeExpr != null) { // Don't allow the same name as the container. if((currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) && node.GetName() == currentContainer.GetName()) Error(node, "constructors cannot have a return type."); returnTypeExpr.Accept(this); returnType = returnTypeExpr.GetNodeType(); returnType = ExtractActualType(returnTypeExpr, returnType); // Use references for class/interface. if(returnType.IsPassedByReference()) returnType = ReferenceType.Create(returnType); } else if(node.GetDestructorName() != null) { returnType = ChelaType.GetVoidType(); } else { returnType = ChelaType.GetVoidType(); if(!currentContainer.IsStructure() && !currentContainer.IsClass()) Error(node, "only classes and structures can have constructors."); if(node.GetName() != currentContainer.GetName()) Error(node, "constructors must have the same name as their parent."); } // Restore the prototype scope. if(protoScope != null) PopScope(); // Create his function type. List<IChelaType> arguments = new List<IChelaType> (); bool variableArgs = false; // Add the argument types. AstNode argNode = node.GetArguments(); while(argNode != null) { // Cast the argument node. FunctionArgument funArg = (FunctionArgument)argNode; // Store the argument type. arguments.Add(funArg.GetNodeType()); // Set the variable argument flags. variableArgs = funArg.IsParams(); // Check the next argument. argNode = argNode.GetNext(); } // Set the function type. FunctionType type = FunctionType.Create(returnType, arguments, variableArgs, callingConvention); node.SetNodeType(type); // Check the function safetyness. if(type.IsUnsafe()) UnsafeError(node, "safe function with unsafe type."); // Avoid collisions. if(functionGroup != null) { Function ambiguos = functionGroup.Find(type, instanceFlags == MemberFlags.Static); if(ambiguos != null) Error(node, "adding ambiguous overload for " + ambiguos.GetFullName()); } // Create and add the method into his scope. Function function = null; if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { // Cast the scope. Structure building = (Structure) currentContainer; // Create the function according to his instance type. if(instanceFlags == MemberFlags.Static || instanceFlags == MemberFlags.StaticConstructor) { function = new Function(node.GetName(), node.GetFlags(), currentContainer); } else { Method method = new Method(node.GetName(), node.GetFlags(), currentContainer); function = method; // Check the constructor initializer. ConstructorInitializer ctorInit = node.GetConstructorInitializer(); if(ctorInit == null || ctorInit.IsBaseCall()) method.SetCtorLeaf(true); } // Set the function position. function.Position = node.GetPosition(); // Set the function type. function.SetFunctionType(type); // Add the function. try { building.AddFunction(node.GetName(), function); } catch(ModuleException error) { Error(node, error.Message); } } else if(currentContainer.IsNamespace()) { // Create the function. function = new Function(node.GetName(), node.GetFlags(), currentContainer); function.SetFunctionType(type); // Set the function position. function.Position = node.GetPosition(); // Add the method into his namespace. Namespace space = (Namespace) currentContainer; // Create the function group. if(functionGroup == null && !isCdecl) { functionGroup = new FunctionGroup(node.GetName(), currentContainer); oldGroup = functionGroup; space.AddMember(functionGroup); } // Add the function into the function group or the namespace. if(!isCdecl) functionGroup.Insert(function); else space.AddMember(function); } else { Error(node, "a function cannot be added here."); } // Store the generic prototype. if(genProto != null) function.SetGenericPrototype(genProto); // Set the node function. node.SetFunction(function); // Check for main function. if(function.IsStatic() && function.GetName() == "Main") CheckMainCandidate(node, function); // Create kernel entry point. if(function.IsKernel()) CreateKernelEntryPoint(node, function); // Restore the safety scope. if(isUnsafe) PopUnsafe(); return node; }