示例#1
0
        internal TypeSyntax(NamespaceSyntax pNamespace, string pValue, List <TypeSyntax> pGenericArgs)
        {
            Namespace        = pNamespace;
            Value            = pValue;
            GenericArguments = pGenericArgs;

            SmallTypeCache.TryGetPrimitive(Value, out _type);//Get primitive types
        }
示例#2
0
 public static TypeSyntax Type(NamespaceSyntax pNamespace, string pValue, List <TypeSyntax> pGenericArgs)
 {
     return(new TypeSyntax(pNamespace, pValue, pGenericArgs));
 }
        public override LLVMValueRef Emit(EmittingContext pContext)
        {
            pContext.EmitDebugLocation(this);

            NamespaceSyntax  ns     = null;
            IdentifierSyntax access = Identifier;

            if (Identifier.SyntaxType == SyntaxType.Namespace)
            {
                ns     = (NamespaceSyntax)Identifier;
                access = Value;
            }

            //Check if this is a "static" method
            if (!pContext.Cache.IsTypeDefined(ns, access.Value) || Value.SyntaxType == SyntaxType.MethodCall)
            {
                LLVMValueRef value;
                if (Identifier.SyntaxType == SyntaxType.Namespace)
                {
                    value = Value.Emit(pContext);
                    //Terminal nodes are fully emitted in their child most node
                    if (IsTerminalNode(Value))
                    {
                        value = AccessStack <MemberAccess> .BuildGetElementPtr(pContext, value);
                    }
                }
                else
                {
                    LLVMValueRef identifier = Identifier.Emit(pContext);

                    //For every method call we need to stop and allocate a new variable
                    //This is because our method call is going to return a value, but we need a pointer.
                    //To solve this we allocate a temporary variable, store the value, and continue
                    if (Identifier.SyntaxType == SyntaxType.MethodCall)
                    {
                        var tempVar = pContext.AllocateVariable("memberaccess_temp", Identifier.Type);
                        LLVM.BuildStore(pContext.Builder, identifier, tempVar);
                        identifier = tempVar;
                        pContext.AccessStack.Clear();
                    }

                    //Store the index we pushed at.
                    //We will later pop only if that index still exists
                    //This allows things like MethodCalls to wipe the stack (because the arguments aren't in the same stack) while still properly popping values
                    var index = pContext.AccessStack.Push(new MemberAccess(identifier, Identifier.Type));

                    value = Value.Emit(pContext);
                    //Terminal nodes are fully emitted in their child most node
                    if (IsTerminalNode(Value))
                    {
                        value = AccessStack <MemberAccess> .BuildGetElementPtr(pContext, value);
                    }

                    pContext.AccessStack.PopFrom(index);
                }

                return(value);
            }
            else
            {
                //Only this way while fields are allow to be accessed
                if (access.Type.IsEnum)
                {
                    int i = 0;
                    if (access.SyntaxType == SyntaxType.MemberAccess)
                    {
                        i = access.Type.GetEnumValue(((MemberAccessSyntax)access).Value.Value);
                    }
                    else
                    {
                        i = access.Type.GetEnumValue(Value.Value);
                    }
                    return(pContext.GetInt(i));
                }

                throw new NotSupportedException("Only static fields on Enums are supported");
            }
        }