public static AssocArrayType Resolve(ArrayDecl ad, ResolverContextStack ctxt)
        {
            var valueTypes = Resolve(ad.ValueType, ctxt);

            ctxt.CheckForSingleResult(valueTypes, ad);

            AbstractType valueType        = null;
            AbstractType keyType          = null;
            int          fixedArrayLength = -1;

            if (valueTypes == null || valueTypes.Length == 0)
            {
                return(null);
            }
            valueType = valueTypes[0];

            ISymbolValue val;

            keyType = ResolveKey(ad, out fixedArrayLength, out val, ctxt);


            if (keyType == null || (keyType is PrimitiveType && ((PrimitiveType)keyType).TypeToken == DTokens.Int))
            {
                return(fixedArrayLength == -1 ?
                       new ArrayType(valueType, ad) :
                       new ArrayType(valueType, fixedArrayLength, ad));
            }

            return(new AssocArrayType(valueType, keyType, ad));
        }
Example #2
0
        private DSDomain ArrayDeclTransfer(ArrayDecl arrayDecl, DSDomain domain)
        {
            var ident = new Identifier(arrayDecl.Name, VarType.Array, arrayDecl.Id);

            var newDomain = CopyDomain(domain);

            newDomain[ident] = DSSign.Zero.Singleton().ToHashSet();
            return(newDomain);
        }
        public override IAstNode VisitArrayDecl(MicroCParser.ArrayDeclContext context)
        {
            var label     = ++_label;
            var name      = context.IDENT().GetText();
            var size      = int.Parse(context.NUMBER().GetText());
            var id        = _symbolTable.InsertSymbol(name, VarType.Array, size);
            var arrayDecl = new ArrayDecl(name, size);

            arrayDecl.Label = label;
            arrayDecl.Id    = id;
            return(arrayDecl);
        }
Example #4
0
        private IADomain ArrayDeclTransfer(ArrayDecl arrayDecl, IADomain domain)
        {
            var newDomain = CopyDomain(domain);

            if (domain.IsBottom())
            {
                return(newDomain);
            }

            var ident = new Identifier(arrayDecl.Name, VarType.Array, arrayDecl.Id);

            newDomain[ident] = new Interval(new ExtendedZ(0), new ExtendedZ(0)).ToIntervalK(_program);

            return(newDomain);
        }
Example #5
0
        public static AbstractType Resolve(ArrayDecl ad, ResolutionContext ctxt)
        {
            var valueTypes = Resolve(ad.ValueType, ctxt);

            ctxt.CheckForSingleResult(valueTypes, ad);

            AbstractType valueType        = null;
            AbstractType keyType          = null;
            int          fixedArrayLength = -1;

            if (valueTypes != null && valueTypes.Length != 0)
            {
                valueType = valueTypes[0];
            }

            ISymbolValue val;

            keyType = ResolveKey(ad, out fixedArrayLength, out val, ctxt);

            if (keyType == null || (keyType is PrimitiveType &&
                                    ((PrimitiveType)keyType).TypeToken == DTokens.Int))
            {
                if (fixedArrayLength >= 0)
                {
                    // D Magic: One might access tuple items directly in the pseudo array declaration - so stuff like Tup[0] i; becomes e.g. int i;
                    var dtup = DResolver.StripMemberSymbols(valueType) as DTuple;
                    if (dtup == null)
                    {
                        return(new ArrayType(valueType, fixedArrayLength, ad));
                    }

                    if (dtup.Items != null && fixedArrayLength < dtup.Items.Length)
                    {
                        return(AbstractType.Get(dtup.Items [fixedArrayLength]));
                    }
                    else
                    {
                        ctxt.LogError(ad, "TypeTuple only consists of " + (dtup.Items != null ? dtup.Items.Length : 0) + " items. Can't access item at index " + fixedArrayLength);
                        return(null);
                    }
                }
                return(new ArrayType(valueType, ad));
            }

            return(new AssocArrayType(valueType, keyType, ad));
        }
Example #6
0
        public ITypeDeclaration VisitArrayAccessSymbol(ArrayAccessSymbol t)
        {
            var ad = new ArrayDecl {
                ValueType = AcceptType(t.Base)
            };

            if (t.DeclarationOrExpressionBase is IExpression)
            {
                ad.KeyExpression = t.DeclarationOrExpressionBase as IExpression;
            }
            else
            {
                ad.KeyType = t.DeclarationOrExpressionBase as ITypeDeclaration;
            }

            return(ad);
        }
Example #7
0
        protected override ILattice <IADomain> TransferFunctions(int label)
        {
            var block     = GetBlock(label);
            var domain    = _analysisCircle[label].GetDomain();
            var newDomain = block switch
            {
                IntDecl intDecl => IntDeclTransfer(intDecl, domain),
                ArrayDecl arrayDecl => ArrayDeclTransfer(arrayDecl, domain),
                RecordDecl recordDecl => RecDeclTransfer(recordDecl, domain),
                AssignStmt assignStmt => AssignTransfer(assignStmt, domain),
                RecAssignStmt recAssignStmt => RecAssignTransfer(recAssignStmt, domain),
                IfStmt ifStmt => IdTransfer(ifStmt, domain),
                IfElseStmt ifElseStmt => IdTransfer(ifElseStmt, domain),
                WhileStmt whileStmt => IdTransfer(whileStmt, domain),
                WriteStmt writeStmt => IdTransfer(writeStmt, domain),
                ReadStmt readStmt => ReadTransfer(readStmt, domain),
                _ => Bottom().GetDomain(),
            };

            return(new IALattice(newDomain));
        }
Example #8
0
        public static AbstractType ResolveKey(ArrayDecl ad, out int fixedArrayLength, out ISymbolValue keyVal, ResolutionContext ctxt)
        {
            keyVal           = null;
            fixedArrayLength = -1;
            AbstractType keyType = null;

            if (ad.KeyExpression != null)
            {
                //TODO: Template instance expressions?
                var id_x = ad.KeyExpression as IdentifierExpression;
                if (id_x != null && id_x.IsIdentifier)
                {
                    var id = new IdentifierDeclaration((string)id_x.Value)
                    {
                        Location    = id_x.Location,
                        EndLocation = id_x.EndLocation
                    };

                    keyType = TypeDeclarationResolver.ResolveSingle(id, ctxt);

                    if (keyType != null)
                    {
                        var tt = DResolver.StripAliasSymbol(keyType) as MemberSymbol;

                        if (tt == null ||
                            !(tt.Definition is DVariable) ||
                            ((DVariable)tt.Definition).Initializer == null)
                        {
                            return(keyType);
                        }
                    }
                }

                try
                {
                    keyVal = Evaluation.EvaluateValue(ad.KeyExpression, ctxt);

                    if (keyVal != null)
                    {
                        // Take the value's type as array key type
                        keyType = keyVal.RepresentedType;

                        // It should be mostly a number only that points out how large the final array should be
                        var pv = Evaluation.GetVariableContents(keyVal, new StandardValueProvider(ctxt)) as PrimitiveValue;
                        if (pv != null)
                        {
                            fixedArrayLength = System.Convert.ToInt32(pv.Value);

                            if (fixedArrayLength < 0)
                            {
                                ctxt.LogError(ad, "Invalid array size: Length value must be greater than 0");
                            }
                        }
                        //TODO Is there any other type of value allowed?
                    }
                }
                catch { }
            }
            else
            {
                var t = Resolve(ad.KeyType, ctxt);
                ctxt.CheckForSingleResult(t, ad.KeyType);

                if (t != null && t.Length != 0)
                {
                    return(t[0]);
                }
            }

            return(keyType);
        }
Example #9
0
		/// <summary>
		/// Note:
		/// http://www.digitalmars.com/d/2.0/declaration.html#DeclaratorSuffix
		/// The definition of a sequence of declarator suffixes is buggy here! Theoretically template parameters can be declared without a surrounding ( and )!
		/// Also, more than one parameter sequences are possible!
		/// 
		/// TemplateParameterList[opt] Parameters MemberFunctionAttributes[opt]
		/// </summary>
		void DeclaratorSuffixes(DNode dn)
		{
			FunctionAttributes(ref dn.Attributes);

			while (laKind == (OpenSquareBracket))
			{
				Step();
				var ad = new ArrayDecl() { Location=t.Location };
				LastParsedObject = ad;
				ad.InnerDeclaration = dn.Type;
				if (laKind != (CloseSquareBracket))
				{
					ad.ClampsEmpty = false;
					ITypeDeclaration keyType=null;
					Lexer.PushLookAheadBackup();
					if (!IsAssignExpression())
					{
						var weakType = AllowWeakTypeParsing;
						AllowWeakTypeParsing = true;
						
						keyType= ad.KeyType = Type();

						AllowWeakTypeParsing = weakType;
					}
					if (keyType == null || laKind != CloseSquareBracket)
					{
						Lexer.RestoreLookAheadBackup();
						keyType = ad.KeyType = null;
						ad.KeyExpression = AssignExpression();
					}
					else
						Lexer.PopLookAheadBackup();
				}
				Expect(CloseSquareBracket);
				ad.EndLocation = t.EndLocation;
				dn.Type = ad;
			}

			if (laKind == (OpenParenthesis))
			{
				if (IsTemplateParameterList())
				{
					TemplateParameterList(dn);
				}
				var dm = dn as DMethod;
				if(dm != null)
					dm.Parameters = Parameters(dm);
			}

			FunctionAttributes(ref dn.Attributes);
		}
Example #10
0
		ITypeDeclaration BasicType2()
		{
			// *
			if (laKind == (Times))
			{
				Step();
				return new PointerDecl() { Location=t.Location, EndLocation=t.EndLocation };
			}

			// [ ... ]
			else if (laKind == (OpenSquareBracket))
			{
				var startLoc = la.Location;
				Step();
				// [ ]
				if (laKind == (CloseSquareBracket)) 
				{ 
					Step();
					return new ArrayDecl() { Location=startLoc, EndLocation=t.EndLocation }; 
				}

				ITypeDeclaration cd = null;

				// [ Type ]
				Lexer.PushLookAheadBackup();
				bool weaktype = AllowWeakTypeParsing;
				AllowWeakTypeParsing = true;

				var keyType = Type();

				AllowWeakTypeParsing = weaktype;

				if (keyType != null && laKind == CloseSquareBracket && !(keyType is IdentifierDeclaration))
				{
					//HACK: Both new int[size_t] as well as new int[someConstNumber] are legal. So better treat them as expressions.
					cd = new ArrayDecl() { KeyType = keyType, ClampsEmpty = false, Location = startLoc };
					Lexer.PopLookAheadBackup();
				}
				else
				{
					Lexer.RestoreLookAheadBackup();

					var fromExpression = AssignExpression();

					// [ AssignExpression .. AssignExpression ]
					if (laKind == DoubleDot)
					{
						Step();
						cd = new ArrayDecl() {
							Location=startLoc,
							ClampsEmpty=false,
							KeyType=null,
							KeyExpression= new PostfixExpression_Slice() { 
								FromExpression=fromExpression,
								ToExpression=AssignExpression()}};
					}
					else
						cd = new ArrayDecl() { KeyType=null, KeyExpression=fromExpression,ClampsEmpty=false,Location=startLoc };
				}

				if ((AllowWeakTypeParsing && laKind != CloseSquareBracket) || IsEOF)
					return null;

				Expect(CloseSquareBracket);
				if(cd!=null)
					cd.EndLocation = t.EndLocation;
				return cd;
			}

			// delegate | function
			else if (laKind == (Delegate) || laKind == (Function))
			{
				Step();
				var dd = new DelegateDeclaration() { Location=t.Location};
				dd.IsFunction = t.Kind == Function;

				var lpo = LastParsedObject;

				if (AllowWeakTypeParsing && laKind != OpenParenthesis)
					return null;

				dd.Parameters = Parameters(null);

				if (!IsEOF)
					LastParsedObject = lpo;

				var attributes = new List<DAttribute>();
				FunctionAttributes(ref attributes);
				dd.Modifiers= attributes.Count > 0 ? attributes.ToArray() : null;

				dd.EndLocation = t.EndLocation;
				return dd;
			}
			else
				SynErr(Identifier);
			return null;
		}
Example #11
0
            //INode typeNode;
            //IEnumerable<IAbstractSyntaxTree> moduleCache;

            public DDebugSymbolWrapper(DebugScopedSymbol sym, DDebugSupport support) : base(sym)
            {
                this.supp = support;
                try
                {
                    /*var ci=CoreManager.DebugManagement.Engine.Symbols.GetPointerTarget(sym.Offset);
                     * object mo = null;
                     * IntPtr moPtr = new IntPtr();
                     * var raw = CoreManager.DebugManagement.Engine.Memory.ReadVirtual(ci, 4);
                     * Marshal.StructureToPtr(raw, moPtr, false);
                     * mo = Marshal.PtrToStructure(moPtr, typeof(DObject));*/
                }
                catch { }

                // Search currently scoped module
                string file = "";
                uint   line = 0;

                CoreManager.DebugManagement.Engine.Symbols.GetLineByOffset(CoreManager.DebugManagement.Engine.CurrentInstructionOffset, out file, out line);
                codeLine = (int)line;

                if (string.IsNullOrWhiteSpace(file))
                {
                    return;
                }

                // If file name found, get syntax tree, as far as possible
                DProject ownerPrj = null;

                module = DLanguageBinding.GetFileSyntaxTree(file, out ownerPrj);



                // If syntax tree built, search the variable location
                if (module != null)
                {
                    IStatement stmt  = null;
                    var        block = DResolver.SearchBlockAt(module, new CodeLocation(0, codeLine), out stmt);

                    var ctxt = ResolutionContext.Create(null, null, block);

                    var res = TypeDeclarationResolver.ResolveIdentifier(Symbol.Name, ctxt, null);

                    if (res != null && res.Length > 0 && res[0] is DSymbol)
                    {
                        variableNode = ((DSymbol)res[0]).Definition;
                        //moduleCache = DCodeCompletionSupport.Instance.EnumAvailableModules(ownerPrj);
                    }
                }



                // Set type string
                _typeString = base.TypeString;
                if (variableNode != null)
                {
                    var t = variableNode.Type;
                    if (t != null)
                    {
                        _typeString = t.ToString();
                    }
                }



                // Set value string
                if (_typeString.StartsWith("class "))
                {
                    _valueString = base.ValueString;

                    //CodeInjection.WriteObjectVariable(supp.hProcess, supp.varAddr, (uint)sym.Offset);

                    //_valueString = CodeInjection.EvaluateObjectString(supp.hProcess, supp.toStringFunc, supp.varAddr, (uint)sym.Offset);

                    /*
                     * var th = CodeInjection.BeginExecuteMethod(supp.hProcess, supp.toStringFunc);
                     *
                     * CoreManager.DebugManagement.Engine.Execute("~2 g");
                     * CoreManager.DebugManagement.Engine.WaitForEvent();
                     *
                     * CodeInjection.WaitForExecutionEnd(th);
                     */
                    //_valueString = CodeInjection.ReadDString(supp.hProcess, supp.varAddr);
                }
                else
                {
                    _valueString = base.ValueString;

                    if (variableNode != null)
                    {
                        ITypeDeclaration curValueType = variableNode.Type;
                        if (curValueType != null)
                        {
                            if (!IsBasicType(curValueType))
                            {
                                if (TypeString == "string")                                 //TODO: Replace this by searching the alias definition in the cache
                                {
                                    curValueType = new ArrayDecl()
                                    {
                                        InnerDeclaration = new DTokenDeclaration(DTokens.Char)
                                    }
                                }
                                ;
                                else if (TypeString == "wstring")
                                {
                                    curValueType = new ArrayDecl()
                                    {
                                        InnerDeclaration = new DTokenDeclaration(DTokens.Wchar)
                                    }
                                }
                                ;
                                else if (TypeString == "dstring")
                                {
                                    curValueType = new ArrayDecl()
                                    {
                                        InnerDeclaration = new DTokenDeclaration(DTokens.Dchar)
                                    }
                                }
                                ;

                                if (IsArray(curValueType))
                                {
                                    var clampDecl = curValueType as ArrayDecl;
                                    var valueType = clampDecl.InnerDeclaration;

                                    if (valueType is DTokenDeclaration)
                                    {
                                        bool IsString = false;
                                        uint elsz     = 0;
                                        var  realType = DetermineArrayType((valueType as DTokenDeclaration).Token, out elsz, out IsString);

                                        var arr = CoreManager.DebugManagement.Engine.Symbols.ReadArray(sym.Offset, realType, elsz);

                                        if (arr != null)
                                        {
                                            _valueString = BuildArrayContentString(arr, IsString);
                                        }
                                    }
                                }

                                else
                                {
                                    //TODO: call an object's toString method somehow to obtain its representing string manually
                                }
                            }
                        }
                    }
                }
            }
        bool HandleDecl(TemplateTypeParameter parameterRef, ArrayDecl arrayDeclToCheckAgainst, AssocArrayType argumentArrayType)
        {
            if (argumentArrayType == null)
            {
                return(false);
            }

            // Handle key type
            var at = argumentArrayType as ArrayType;

            if ((arrayDeclToCheckAgainst.ClampsEmpty == (at == null)) &&
                (at == null || !at.IsStaticArray || arrayDeclToCheckAgainst.KeyExpression == null))
            {
                return(false);
            }
            bool result;

            if (arrayDeclToCheckAgainst.KeyExpression != null)
            {
                // Remove all surrounding parentheses from the expression
                var x_param = arrayDeclToCheckAgainst.KeyExpression;

                while (x_param is SurroundingParenthesesExpression)
                {
                    x_param = ((SurroundingParenthesesExpression)x_param).Expression;
                }

                var ad_Argument = argumentArrayType.DeclarationOrExpressionBase as ArrayDecl;

                /*
                 * This might be critical:
                 * the [n] part in class myClass(T:char[n], int n) {}
                 * will be seen as an identifier expression, not as an identifier declaration.
                 * So in the case the parameter expression is an identifier,
                 * test if it's part of the parameter list
                 */
                var id = x_param as IdentifierExpression;
                if (id != null && id.IsIdentifier && Contains(id.ValueStringHash))
                {
                    // If an expression (the usual case) has been passed as argument, evaluate its value, otherwise is its type already resolved.
                    ISemantic finalArg = null;

                    if (ad_Argument != null && ad_Argument.KeyExpression != null)
                    {
                        ISymbolValue val = null;
                        int          len = -1;
                        finalArg = TypeDeclarationResolver.ResolveKey(ad_Argument, out len, out val, ctxt);
                        if (val != null)
                        {
                            finalArg = val;
                        }
                    }
                    else
                    {
                        finalArg = argumentArrayType.KeyType;
                    }

                    //TODO: Do a type convertability check between the param type and the given argument's type.
                    // The affected parameter must also be a value parameter then, if an expression was given.

                    // and handle it as if it was an identifier declaration..
                    result = Set(parameterRef, finalArg, id.ValueStringHash);
                }
                else if (ad_Argument != null && ad_Argument.KeyExpression != null)
                {
                    // Just test for equality of the argument and parameter expression, e.g. if both param and arg are 123, the result will be true.
                    result = SymbolValueComparer.IsEqual(arrayDeclToCheckAgainst.KeyExpression, ad_Argument.KeyExpression, new StandardValueProvider(ctxt));
                }
                else
                {
                    result = false;
                }

                if (!result)
                {
                    return(false);
                }
            }
            else if (arrayDeclToCheckAgainst.KeyType != null)
            {
                // If the array we're passing to the decl check that is static (i.e. has a constant number as key 'type'),
                // pass that number instead of type 'int' to the check.
                if (argumentArrayType != null && at != null && at.IsStaticArray)
                {
                    result = HandleDecl(parameterRef, arrayDeclToCheckAgainst.KeyType,
                                        new PrimitiveValue(D_Parser.Parser.DTokens.Int, (decimal)at.FixedLength, null));
                }
                else
                {
                    result = HandleDecl(parameterRef, arrayDeclToCheckAgainst.KeyType, argumentArrayType.KeyType);
                }

                if (!result)
                {
                    return(false);
                }
            }

            // Handle inner type
            return(HandleDecl(parameterRef, arrayDeclToCheckAgainst.InnerDeclaration, argumentArrayType.Base));
        }
 public ulong Visit(ArrayDecl arrayDecl)
 {
     return(1001551);
 }
        public ObjectValue Resolve(ulong offset, string symbolname, string typename, string val, DEW.DebugScopedSymbol parentsymbol)
        {
            DModule module;
            int     codeLine;
            INode   variableNode = null;

            // Search currently scoped module
            string file = "";
            uint   line = 0;

            Engine.Symbols.GetLineByOffset(Engine.CurrentInstructionOffset, out file, out line);
            codeLine = (int)line;

            if (string.IsNullOrWhiteSpace(file))
            {
                return(null);
            }

            AbstractDProject dproj = null;

            module = GetFileSyntaxTree(file, out dproj);

            // If syntax tree built, search the variable location
            if (module != null)
            {
                var ed   = Resolver.DResolverWrapper.CreateEditorData(IdeApp.Workbench.ActiveDocument);
                var ctxt = ResolutionContext.Create(ed, false);

                CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () =>
                {
                    var loc = new CodeLocation(0, codeLine);
                    ctxt.Push(DResolver.SearchBlockAt(module, loc), loc);

                    AbstractType[] res;
                    if (parentsymbol != null)
                    {
                        var parentres = ResolveParentSymbol(parentsymbol, ctxt);
                        res           = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(symbolname, parentres, ctxt, null);
                    }
                    else
                    {
                        res = TypeDeclarationResolver.ResolveIdentifier(symbolname, ctxt, null);
                    }

                    if (res != null && res.Length > 0 && res[0] is DSymbol)
                    {
                        variableNode = (res[0] as DSymbol).Definition;
                    }
                });
            }

            // Set type string
            string _typeString = typename;

            if (variableNode != null)
            {
                var t = variableNode.Type;
                if (t != null)
                {
                    _typeString = t.ToString();
                }
            }

            // Set value string
            string _valueString = val;

            ObjectValueFlags flags = ObjectValueFlags.Variable;

            if (variableNode != null)
            {
                ITypeDeclaration curValueType = variableNode.Type;
                if (curValueType != null)
                {
                    if (!IsBasicType(curValueType))
                    {
                        if (_typeString == "string")                         //TODO: Replace this by searching the alias definition in the cache
                        {
                            curValueType = new ArrayDecl()
                            {
                                InnerDeclaration = new DTokenDeclaration(DTokens.Char)
                            }
                        }
                        ;
                        else if (_typeString == "wstring")
                        {
                            curValueType = new ArrayDecl()
                            {
                                InnerDeclaration = new DTokenDeclaration(DTokens.Wchar)
                            }
                        }
                        ;
                        else if (_typeString == "dstring")
                        {
                            curValueType = new ArrayDecl()
                            {
                                InnerDeclaration = new DTokenDeclaration(DTokens.Dchar)
                            }
                        }
                        ;

                        if (IsArray(curValueType))
                        {
                            flags = ObjectValueFlags.Array;

                            var clampDecl = curValueType as ArrayDecl;
                            var valueType = clampDecl.InnerDeclaration;

                            if (valueType is DTokenDeclaration)
                            {
                                bool IsString = false;
                                uint elsz     = 0;
                                var  realType = DetermineArrayType((valueType as DTokenDeclaration).Token, out elsz, out IsString);

                                var arr = Engine.Symbols.ReadArray(offset, realType, elsz);

                                if (arr != null)
                                {
                                    _valueString = BuildArrayContentString(arr, IsString);
                                }
                            }
                        }
                        else
                        {
                            flags = ObjectValueFlags.Object;
                        }
                    }
                }
            }

            return(ObjectValue.CreatePrimitive(ObjectValueSource, new ObjectPath(symbolname), _typeString, new EvaluationResult(_valueString), flags));
        }
		bool HandleDecl(TemplateTypeParameter parameterRef,ArrayDecl arrayDeclToCheckAgainst, AssocArrayType argumentArrayType)
		{
			if (argumentArrayType == null)
				return false;

			// Handle key type
			if((arrayDeclToCheckAgainst.KeyType != null || arrayDeclToCheckAgainst.KeyExpression!=null) && argumentArrayType.KeyType == null)
				return false;
			bool result = false;

			if (arrayDeclToCheckAgainst.KeyExpression != null)
			{
				// Remove all surrounding parentheses from the expression
				var x_param = arrayDeclToCheckAgainst.KeyExpression;

				while(x_param is SurroundingParenthesesExpression)
					x_param = ((SurroundingParenthesesExpression)x_param).Expression;

				var ad_Argument = argumentArrayType.DeclarationOrExpressionBase as ArrayDecl;

				/*
				 * This might be critical:
				 * the [n] part in class myClass(T:char[n], int n) {}
				 * will be seen as an identifier expression, not as an identifier declaration.
				 * So in the case the parameter expression is an identifier,
				 * test if it's part of the parameter list
				 */
				var id = x_param as IdentifierExpression;
				if(id!=null && id.IsIdentifier && Contains(id.ValueStringHash))
				{
					// If an expression (the usual case) has been passed as argument, evaluate its value, otherwise is its type already resolved.
					ISemantic finalArg = null;

					if (ad_Argument != null && ad_Argument.KeyExpression != null)
					{
						ISymbolValue val = null;
						int len = -1;
						finalArg = TypeDeclarationResolver.ResolveKey(ad_Argument, out len, out val, ctxt);
						if (val != null)
							finalArg = val;
					}
					else
						finalArg = argumentArrayType.KeyType;

					//TODO: Do a type convertability check between the param type and the given argument's type.
					// The affected parameter must also be a value parameter then, if an expression was given.

					// and handle it as if it was an identifier declaration..
					result = Set(parameterRef, finalArg, id.ValueStringHash); 
				}
				else if (ad_Argument != null && ad_Argument.KeyExpression != null)
				{
					// Just test for equality of the argument and parameter expression, e.g. if both param and arg are 123, the result will be true.
					result = SymbolValueComparer.IsEqual(arrayDeclToCheckAgainst.KeyExpression, ad_Argument.KeyExpression, new StandardValueProvider(ctxt));
				}
			}
			else if (arrayDeclToCheckAgainst.KeyType != null)
			{
				// If the array we're passing to the decl check that is static (i.e. has a constant number as key 'type'),
				// pass that number instead of type 'int' to the check.
				var at = argumentArrayType as ArrayType;
				if (argumentArrayType != null && at != null && at.IsStaticArray)
					result = HandleDecl(parameterRef, arrayDeclToCheckAgainst.KeyType,
						new PrimitiveValue(DSharp.Parser.DTokens.Int, (decimal)at.FixedLength, null)); 
				else
					result = HandleDecl(parameterRef, arrayDeclToCheckAgainst.KeyType, argumentArrayType.KeyType);
			}

			// Handle inner type
			return result && HandleDecl(parameterRef,arrayDeclToCheckAgainst.InnerDeclaration, argumentArrayType.Base);
		}
            public static void AddArrayProperties(ResolveResult rr, ICompletionDataGenerator cdg, ArrayDecl ArrayDecl = null)
            {
                CreateArtificialProperties(ArrayProps, cdg, ArrayDecl);

                cdg.Add(new DVariable
                {
                    Name        = "ptr",
                    Description = "Returns pointer to the array",
                    Type        = new PointerDecl(ArrayDecl == null ? new DTokenDeclaration(DTokens.Void) : ArrayDecl.ValueType)
                });
            }
            public static void AddAssocArrayProperties(ResolveResult rr, ICompletionDataGenerator cdg, ArrayDecl ad)
            {
                var ll = new List <INode>();

                ll.Add(new DVariable()
                {
                    Name        = "sizeof",
                    Description = "Returns the size of the reference to the associative array; it is typically 8.",
                    Type        = new IdentifierDeclaration("size_t"),
                    Initializer = new IdentifierExpression(8, LiteralFormat.Scalar)
                });

                /*ll.Add(new DVariable() {
                 *      Name="length",
                 *      Description="Returns number of values in the associative array. Unlike for dynamic arrays, it is read-only.",
                 *      Type=new IdentifierDeclaration("size_t")
                 * });*/

                if (ad != null)
                {
                    ll.Add(new DVariable()
                    {
                        Name        = "keys",
                        Description = "Returns dynamic array, the elements of which are the keys in the associative array.",
                        Type        = new ArrayDecl()
                        {
                            ValueType = ad.KeyType
                        }
                    });

                    ll.Add(new DVariable()
                    {
                        Name        = "values",
                        Description = "Returns dynamic array, the elements of which are the values in the associative array.",
                        Type        = new ArrayDecl()
                        {
                            ValueType = ad.ValueType
                        }
                    });

                    ll.Add(new DVariable()
                    {
                        Name        = "rehash",
                        Description = "Reorganizes the associative array in place so that lookups are more efficient. rehash is effective when, for example, the program is done loading up a symbol table and now needs fast lookups in it. Returns a reference to the reorganized array.",
                        Type        = ad
                    });

                    ll.Add(new DVariable()
                    {
                        Name        = "byKey",
                        Description = "Returns a delegate suitable for use as an Aggregate to a ForeachStatement which will iterate over the keys of the associative array.",
                        Type        = new DelegateDeclaration()
                        {
                            ReturnType = new ArrayDecl()
                            {
                                ValueType = ad.KeyType
                            }
                        }
                    });

                    ll.Add(new DVariable()
                    {
                        Name        = "byValue",
                        Description = "Returns a delegate suitable for use as an Aggregate to a ForeachStatement which will iterate over the values of the associative array.",
                        Type        = new DelegateDeclaration()
                        {
                            ReturnType = new ArrayDecl()
                            {
                                ValueType = ad.ValueType
                            }
                        }
                    });

                    ll.Add(new DMethod()
                    {
                        Name        = "get",
                        Description = "Looks up key; if it exists returns corresponding value else evaluates and returns defaultValue.",
                        Type        = ad.ValueType,
                        Parameters  = new List <INode> {
                            new DVariable()
                            {
                                Name = "key",
                                Type = ad.KeyType
                            },
                            new DVariable()
                            {
                                Name       = "defaultValue",
                                Type       = ad.ValueType,
                                Attributes = new List <DAttribute> {
                                    new DAttribute(DTokens.Lazy)
                                }
                            }
                        }
                    });
                }

                foreach (var prop in ll)
                {
                    cdg.Add(prop);
                }
            }
		public static AbstractType ResolveKey(ArrayDecl ad, out int fixedArrayLength, out ISymbolValue keyVal, ResolutionContext ctxt)
		{
			keyVal = null;
			fixedArrayLength = -1;
			AbstractType keyType = null;

			if (ad.KeyExpression != null)
			{
				//TODO: Template instance expressions?
				var id_x = ad.KeyExpression as IdentifierExpression;
				if (id_x != null && id_x.IsIdentifier)
				{
					var id = new IdentifierDeclaration((string)id_x.Value)
					{
						Location = id_x.Location,
						EndLocation = id_x.EndLocation
					};

					keyType = TypeDeclarationResolver.ResolveSingle(id, ctxt);

					if (keyType != null)
					{
						var tt = DResolver.StripAliasSymbol(keyType) as MemberSymbol;

						if (tt == null ||
							!(tt.Definition is DVariable) ||
							((DVariable)tt.Definition).Initializer == null)
							return keyType;
					}
				}

				try
				{
					keyVal = Evaluation.EvaluateValue(ad.KeyExpression, ctxt);

					if (keyVal != null)
					{
						// Take the value's type as array key type
						keyType = keyVal.RepresentedType;

						// It should be mostly a number only that points out how large the final array should be
						var pv = Evaluation.GetVariableContents(keyVal, new StandardValueProvider(ctxt)) as PrimitiveValue;
						if (pv != null)
						{
							fixedArrayLength = System.Convert.ToInt32(pv.Value);

							if (fixedArrayLength < 0)
								ctxt.LogError(ad, "Invalid array size: Length value must be greater than 0");
						}
						//TODO Is there any other type of value allowed?
					}
				}
				catch { }
			}
			else
			{
				var t = Resolve(ad.KeyType, ctxt);
				ctxt.CheckForSingleResult(t, ad.KeyType);

				if (t != null && t.Length != 0)
					return t[0];
			}

			return keyType;
		}
		public virtual void Visit(ArrayDecl td)
		{
			VisitInner(td);

			if (td.KeyType != null)
				td.KeyType.Accept(this);

			if (td.KeyExpression != null)
				td.KeyExpression.Accept(this);

			// ValueType == InnerDeclaration
		}
		public static AbstractType Resolve(ArrayDecl ad, ResolutionContext ctxt)
		{
			var valueTypes = Resolve(ad.ValueType, ctxt);

			ctxt.CheckForSingleResult(valueTypes, ad);

			AbstractType valueType = null;
			AbstractType keyType = null;
			int fixedArrayLength = -1;

			if (valueTypes != null && valueTypes.Length != 0)
				valueType = valueTypes[0];

			ISymbolValue val;
			keyType = ResolveKey(ad, out fixedArrayLength, out val, ctxt);

			if (keyType == null || (keyType is PrimitiveType &&
			    ((PrimitiveType)keyType).TypeToken == DTokens.Int)) {

				if (fixedArrayLength >= 0) {
					// D Magic: One might access tuple items directly in the pseudo array declaration - so stuff like Tup[0] i; becomes e.g. int i;
					var dtup = DResolver.StripMemberSymbols (valueType) as DTuple;
					if (dtup == null)
						return new ArrayType (valueType, fixedArrayLength, ad);

					if (fixedArrayLength < dtup.Items.Length)
						return AbstractType.Get(dtup.Items [fixedArrayLength]);
					else {
						ctxt.LogError (ad, "TypeTuple only consists of " + dtup.Items.Length + " items. Can't access item at index " + fixedArrayLength);
						return null;
					}
				}
				return new ArrayType (valueType, ad);
			}

			return new AssocArrayType(valueType, keyType, ad);
		}