Beispiel #1
0
        /// <summary>
        /// Parses a type declarator
        /// </summary>
        /// <returns>A dummy node that contains the return type, the variable name and possible parameters of a function declaration</returns>
        DNode Declarator(ITypeDeclaration basicType,bool IsParam, INode parent)
        {
            DNode ret = new DVariable() { Type=basicType, Location = la.Location, Parent = parent };
            ApplyAttributes (ret);

            while (IsBasicType2())
            {
                if (ret.Type == null)
                    ret.Type = BasicType2();
                else {
                    var ttd = BasicType2();
                    if(ttd!=null)
                        ttd.InnerDeclaration = ret.Type;
                    ret.Type = ttd;
                }
            }

            if (laKind != (OpenParenthesis))
            {
                // On external function declarations, no parameter names are required.
                // extern void Cfoo(HANDLE,char**);
                if (IsParam && laKind != (Identifier))
                {
                    if ((!(ret.Type is DTokenDeclaration) ||
                        (ret.Type as DTokenDeclaration).Token != DTokens.Incomplete) && IsEOF)
                        ret.NameHash = DTokens.IncompleteIdHash;
                    return ret;
                }

                if (Expect(Identifier))
                {
                    ret.Name = t.Value;
                    ret.NameLocation = t.Location;

                    // enum asdf(...) = ...;
                    if (laKind == OpenParenthesis && OverPeekBrackets(DTokens.OpenParenthesis, true) &&
                        Lexer.CurrentPeekToken.Kind == Assign)
                    {
                        var eponymousTemplateDecl = new EponymousTemplate ();
                        eponymousTemplateDecl.AssignFrom (ret);
                        ret = eponymousTemplateDecl;

                        TemplateParameterList (eponymousTemplateDecl);

                        return ret;
                    }
                }
                else
                {
                    if (IsEOF)
                    {
                        ret.NameHash = DTokens.IncompleteIdHash;
                        return ret;
                    }

                    return null;
                    // Code error! - to prevent infinite declaration loops, step one token forward anyway!
                    if(laKind != CloseCurlyBrace && laKind != CloseParenthesis)
                        Step();
                    return null;
                }
            }
            else
                OldCStyleFunctionPointer(ret, IsParam);

            if (IsDeclaratorSuffix || IsFunctionAttribute)
            {
                var dm = new DMethod { Parent = parent, Parameters = null };
                dm.AssignFrom(ret);

                DeclaratorSuffixes(dm);

                if (dm.Parameters != null)
                    ret = dm;
            }

            return ret;
        }
Beispiel #2
0
        /// <summary>
        /// Parses a type declarator
        /// </summary>
        /// <returns>A dummy node that contains the return type, the variable name and possible parameters of a function declaration</returns>
        DNode Declarator(ITypeDeclaration basicType,bool IsParam)
        {
            DNode ret = new DVariable() { Type=basicType, Location = la.Location };
            LastParsedObject = ret;
            ITypeDeclaration ttd = null;

            while (IsBasicType2())
            {
                if (ret.Type == null)
                    ret.Type = BasicType2();
                else {
                    ttd = BasicType2();
                    if(ttd!=null)
                        ttd.InnerDeclaration = ret.Type;
                    ret.Type = ttd;
                }
            }
            /*
             * Add some syntax possibilities here
             * like
             * int (x);
             * int(*foo);
             */
            #region This way of declaring function pointers is deprecated
            if (laKind == (OpenParenthesis))
            {
                Step();
                //SynErr(OpenParenthesis,"C-style function pointers are deprecated. Use the function() syntax instead."); // Only deprecated in D2
                var cd = new DelegateDeclaration() as ITypeDeclaration;
                LastParsedObject = cd;
                ret.Type = cd;
                var deleg = cd as DelegateDeclaration;

                /*
                 * Parse all basictype2's that are following the initial '('
                 */
                while (IsBasicType2())
                {
                    ttd = BasicType2();

                    if (deleg.ReturnType == null)
                        deleg.ReturnType = ttd;
                    else
                    {
                        if(ttd!=null)
                            ttd.InnerDeclaration = deleg.ReturnType;
                        deleg.ReturnType = ttd;
                    }
                }

                /*
                 * Here can be an identifier with some optional DeclaratorSuffixes
                 */
                if (laKind != (CloseParenthesis))
                {
                    if (IsParam && laKind != (Identifier))
                    {
                        /* If this Declarator is a parameter of a function, don't expect anything here
                         * except a '*' that means that here's an anonymous function pointer
                         */
                        if (t.Kind != (Times))
                            SynErr(Times);
                    }
                    else
                    {
                        if(Expect(Identifier))
                            ret.Name = t.Value;

                        /*
                         * Just here suffixes can follow!
                         */
                        if (laKind != (CloseParenthesis))
                        {
                            ITemplateParameter[] _unused2 = null;
                            List<INode> _unused = null;
                            List<DAttribute> _unused3 = new List<DAttribute>();
                            ttd = DeclaratorSuffixes(out _unused2, out _unused, _unused3);

                            if (ttd != null)
                            {
                                ttd.InnerDeclaration = cd;
                                cd = ttd;
                            }
                        }
                    }
                }
                ret.Type = cd;
                Expect(CloseParenthesis);
            }
            #endregion
            else
            {
                // On external function declarations, no parameter names are required.
                // extern void Cfoo(HANDLE,char**);
                if (IsParam && laKind != (Identifier))
                {
                    if(ret.Type!=null)
                        ExpectingIdentifier = true;
                    return ret;
                }

                if (Expect(Identifier))
                {
                    ret.Name = t.Value;
                    ret.NameLocation = t.Location;
                }
                else
                {
                    // Code error! - to prevent infinite declaration loops, step one token forward anyway!
                    Step();
                    return ret;
                }
            }

            if (IsDeclaratorSuffix || MemberFunctionAttribute[laKind])
            {
                var dm = new DMethod();
                LastParsedObject = dm;

                // DeclaratorSuffixes
                List<INode> _Parameters;
                ttd = DeclaratorSuffixes(out (ret as DNode).TemplateParameters, out _Parameters, ret.Attributes);
                if (ttd != null)
                {
                    ttd.InnerDeclaration = ret.Type;
                    ret.Type = ttd;
                }

                if (_Parameters == null)
                    LastParsedObject = ret;

                if (_Parameters != null)
                {
                    dm.AssignFrom(ret);
                    dm.Parameters = _Parameters;
                    foreach (var pp in dm.Parameters)
                        pp.Parent = dm;
                    return dm;
                }
            }

            return ret;
        }
Beispiel #3
0
        /// <summary>
        /// Parses a type declarator
        /// </summary>
        /// <returns>A dummy node that contains the return type, the variable name and possible parameters of a function declaration</returns>
        DNode Declarator(ITypeDeclaration basicType,bool IsParam, INode parent)
        {
            DNode ret = new DVariable() { Type=basicType, Location = la.Location, Parent = parent };
            ApplyAttributes (ret);
            LastParsedObject = ret;

            while (IsBasicType2())
            {
                if (ret.Type == null)
                    ret.Type = BasicType2();
                else {
                    var ttd = BasicType2();
                    if(ttd!=null)
                        ttd.InnerDeclaration = ret.Type;
                    ret.Type = ttd;
                }
            }

            // Only return no variable if the BasicType2 wasn't parsed properly to ensure good code completion
            if (IsEOF && ret != LastParsedObject)
                return null;

            if (laKind != (OpenParenthesis))
            {
                // On external function declarations, no parameter names are required.
                // extern void Cfoo(HANDLE,char**);
                if (IsParam && laKind != (Identifier))
                {
                    if(ret.Type!=null && IsEOF)
                        ExpectingNodeName = true;
                    return ret;
                }

                if (Expect(Identifier))
                {
                    ret.Name = t.Value;
                    ret.NameLocation = t.Location;

                    if (laKind == OpenParenthesis && ret.Type == null) {
                        OverPeekBrackets (DTokens.OpenParenthesis, true);

                        var k = Lexer.LastToken.Kind;
                        if (k == DTokens.Alias || k == DTokens.Enum) {
                            if (ret.Attributes == null)
                                ret.Attributes = new List<DAttribute> ();
                            ret.Attributes.Add (new Modifier (k));
                        }

                        // enum asdf(...) = ...;
                        if (Lexer.CurrentPeekToken.Kind == Assign) {
                            var eponymousTemplateDecl = new EponymousTemplate ();
                            eponymousTemplateDecl.AssignFrom (ret);
                            ret = eponymousTemplateDecl;

                            TemplateParameterList (eponymousTemplateDecl);

                            return ret;
                        }
                    }
                }
                else
                {
                    if (IsEOF || IsParam)
                    {
                        ExpectingNodeName = true;
                        return ret;
                    }

                    return null;
                    // Code error! - to prevent infinite declaration loops, step one token forward anyway!
                    if(laKind != CloseCurlyBrace && laKind != CloseParenthesis)
                        Step();
                    return null;
                }
            }
            else
                OldCStyleFunctionPointer(ret, IsParam);

            if (IsDeclaratorSuffix || IsFunctionAttribute)
            {
                var dm = new DMethod { Parent = parent, Parameters = null };
                dm.AssignFrom(ret);
                LastParsedObject = dm;

                DeclaratorSuffixes(dm);

                if (dm.Parameters != null)
                    ret = dm;
                else
                    LastParsedObject = ret;
            }

            return ret;
        }
Beispiel #4
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(ref DNode dn)
		{
			FunctionAttributes(ref dn.Attributes);

			while (laKind == (OpenSquareBracket))
			{
				Step();
				var ad = new ArrayDecl() { Location=t.Location,InnerDeclaration = dn.Type };

				if (laKind != (CloseSquareBracket))
				{
					ITypeDeclaration keyType=null;
					Lexer.PushLookAheadBackup();
					if (!IsAssignExpression())
					{
						var weakType = AllowWeakTypeParsing;
						AllowWeakTypeParsing = true;
						
						keyType= ad.KeyType = Type(dn.Parent as IBlockNode);

						AllowWeakTypeParsing = weakType;
					}
					if (keyType == null || laKind != CloseSquareBracket)
					{
						Lexer.RestoreLookAheadBackup();
						keyType = ad.KeyType = null;
						ad.KeyExpression = AssignExpression(dn.Parent as IBlockNode);
					}
					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 = new DMethod();
					dm.AssignFrom(dn);
					dn = dm;
				}

				Parameters(dm);
			}

			FunctionAttributes(ref dn.Attributes);
		}