public override AstNode Visit(AddressOfOperation node) { // Begin the node. builder.BeginNode(node); // Functions are statically handler. if(node.IsFunction()) { builder.CreateLoadFunctionAddr((Function)node.GetNodeValue()); return builder.EndNode(); } // Get the reference expression. Expression reference = node.GetReference(); // Visit it. reference.Accept(this); // Get the reference variable. Variable variable = (Variable) reference.GetNodeValue(); if(variable.IsLocal()) { LocalVariable local = (LocalVariable) variable; if(local.IsPseudoLocal) { builder.CreateLoadArg(0); builder.CreateLoadFieldAddr((FieldVariable)local.ActualVariable); } else { builder.CreateLoadLocalAddr(local); } } else if(variable.IsField()) { FieldVariable field = (FieldVariable) variable; if(field.IsStatic()) builder.CreateLoadGlobalAddr(field); else builder.CreateLoadFieldAddr(field); } else if(variable.IsArraySlot()) { ArraySlot slot = (ArraySlot)variable; builder.CreateLoadArraySlotAddr(slot.GetArrayType()); } else if(variable.IsPointedSlot()) { // Do nothing. } else if(variable.IsReferencedSlot()) { builder.CreateBitCast(node.GetNodeType()); } else if(variable.IsProperty()) { Error(node, "cannot use address-of operator for properties."); } return builder.EndNode(); }
public override AstNode Visit(AddressOfOperation node) { UnsafeError(node, "cannot use address-of operator under safe contexts."); // Evaluate the base reference. Expression reference = node.GetReference(); reference.Accept(this); // Get the reference type. IChelaType refType = reference.GetNodeType(); if(!refType.IsReference() && !refType.IsFunctionGroup()) Error(node, "expected a reference/function."); // Handle function groups. if(refType.IsFunctionGroup()) { // Only accept groups with only one function. FunctionGroupSelector selector = (FunctionGroupSelector)reference.GetNodeValue(); FunctionGroup fgroup = selector.GetFunctionGroup(); if(fgroup.GetFunctionCount() != 1) Error(node, "cannot get the address of a function grop."); // Extract the single function in the group. Function function = null; foreach(FunctionGroupName name in fgroup.GetFunctions()) function = name.GetFunction(); // Make sure its static. if(!function.IsStatic()) Error(node, "cannot get the addres of a no-static function."); // Store it in the node. node.SetNodeValue(function); node.SetIsFunction(true); // Set the node type. node.SetNodeType(PointerType.Create(function.GetFunctionType())); return node; } node.SetCoercionType(refType); // De-Reference. refType = DeReferenceType(refType); if(refType.IsReference() || refType.IsPassedByReference()) Error(node, "cannot use address of operator for managed objects."); // Create the pointer type. IChelaType pointerType = PointerType.Create(refType); node.SetNodeType(pointerType); return node; }