private void ParseTypedef(LinkedListStream <IBaseToken> stream) { CppToken typedefToken = stream.Peek <CppToken>(); Debug.Assert(typedefToken.Kind == CppTokenKind.ReservedKeyword && "typedef".Equals(typedefToken.Value)); stream.Next(); var reservedKeywordResult = Search(stream, SearchMode.Current, CppTokenKind.ReservedKeyword); if (reservedKeywordResult != null) { var reservedKeywordToken = reservedKeywordResult.Token; string keyword = reservedKeywordToken.Value; switch (keyword) { case "union": case "struct": ParseStruct(stream); return; case "enum": ParseEnum(stream, reservedKeywordToken.Position); return; } } // Normal typedef CppEntityKind kind = CppEntityKind.Typedef; var semicolonResult = Search(stream, SearchMode.Forward, CppTokenKind.Semicolon); if (semicolonResult != null) { stream.Seek(semicolonResult.Node); stream.Next(); SearchResult <CppToken> identResult = null; var prevResult = Search(semicolonResult, SearchMode.Prev, CppTokenKind.RightParen, CppTokenKind.IdentLiteral); if (prevResult != null) { if (prevResult.Token.Kind == CppTokenKind.RightParen) { // Function typedef var leftParenResult = Search(prevResult, SearchMode.Backward, CppTokenKind.LeftParen); if (leftParenResult != null) { var rightParentResult = Search(leftParenResult, SearchMode.Prev, CppTokenKind.RightParen); if (rightParentResult != null) { leftParenResult = Search(rightParentResult, SearchMode.Backward, CppTokenKind.LeftParen); if (leftParenResult != null) { identResult = Search(leftParenResult, SearchMode.Next, CppTokenKind.IdentLiteral); kind = CppEntityKind.FunctionTypedef; } } else { // Typedef on define // #define MY_TYPEDEF(name) // typedef MY_TYPEDEF(my_typedef); //Debug.WriteLine("Right paren not found!"); } } } else { // Type typedef Debug.Assert(prevResult.Token.Kind == CppTokenKind.IdentLiteral); identResult = prevResult; } } if (identResult != null) { var identToken = identResult.Token; string typedefIdent = identToken.Value; CppEntity typedefEntity = new CppEntity(kind, identToken, typedefIdent) { DocumentationNode = FindDocumentationNode(identResult.Node, 1), }; var typedefNode = new CppNode(Top, typedefEntity); Add(typedefNode); SymbolCache.AddSource(Tag, typedefIdent, new SourceSymbol(SourceSymbolKind.CppType, identToken.Range)); } } }
private bool ParseFunction(LinkedListStream <IBaseToken> stream) { var functionIdentNode = stream.CurrentNode; CppToken functionIdentToken = functionIdentNode.Value as CppToken; Debug.Assert(functionIdentToken.Kind == CppTokenKind.IdentLiteral); var functionName = functionIdentToken.Value; CppTokenKind[] funcCallKinds = { CppTokenKind.EqOp, CppTokenKind.Comma, CppTokenKind.LeftParen, CppTokenKind.AddOp, CppTokenKind.AddAssign, CppTokenKind.SubOp, CppTokenKind.SubAssign, CppTokenKind.DivOp, CppTokenKind.DivAssign, CppTokenKind.MulAssign, CppTokenKind.XorOp, CppTokenKind.XorAssign, CppTokenKind.LeftShiftOp, CppTokenKind.LeftShiftAssign, CppTokenKind.RightShiftOp, CppTokenKind.RightShiftAssign, }; var funcCallResult = Search(stream, SearchMode.Prev, funcCallKinds); CppEntityKind kind = CppEntityKind.FunctionCall; // Skip ident stream.Next(); // Skip parameters CppToken openParenToken = stream.Peek <CppToken>(); Debug.Assert(openParenToken.Kind == CppTokenKind.LeftParen); stream.Next(); var closeParenResult = Search(stream, SearchMode.Forward, CppTokenKind.RightParen); if (closeParenResult == null) { AddError(openParenToken.Position, $"Unterminated function '{functionName}'", "Function", functionName); return(true); } stream.Seek(closeParenResult.Node); stream.Next(); if (funcCallResult == null) { var endingTokenResult = Search(stream, SearchMode.Current, CppTokenKind.Semicolon, CppTokenKind.LeftBrace); if (endingTokenResult != null) { stream.Next(); if (endingTokenResult.Token.Kind == CppTokenKind.LeftBrace) { kind = CppEntityKind.FunctionBody; if (Configuration.SkipFunctionBlocks) { return(true); } } else { kind = CppEntityKind.FunctionDefinition; } } } CppEntity functionEntity = new CppEntity(kind, functionIdentToken, functionName) { DocumentationNode = FindDocumentationNode(functionIdentNode, 1), }; CppNode functionNode = new CppNode(Top, functionEntity); Add(functionNode); if (kind == CppEntityKind.FunctionDefinition) { SymbolCache.AddSource(Tag, functionName, new SourceSymbol(SourceSymbolKind.CppFunctionDefinition, functionIdentToken.Range, functionNode)); } else if (kind == CppEntityKind.FunctionBody) { SymbolCache.AddSource(Tag, functionName, new SourceSymbol(SourceSymbolKind.CppFunctionBody, functionIdentToken.Range, functionNode)); } else if (Configuration.FunctionCallSymbolsEnabled) { SymbolCache.AddReference(Tag, functionName, new ReferenceSymbol(ReferenceSymbolKind.CppFunction, functionIdentToken.Range, functionNode)); } return(true); }
private void ParseEnumValues(LinkedListStream <IBaseToken> stream, CppNode rootNode) { CppToken leftBraceToken = stream.Peek <CppToken>(); Debug.Assert(leftBraceToken.Kind == CppTokenKind.LeftBrace); stream.Next(); while (!stream.IsEOF) { var rightBraceResult = Search(stream, SearchMode.Current, CppTokenKind.RightBrace); if (rightBraceResult != null) { // Enum complete stream.Next(); break; } var identResult = Search(stream, SearchMode.Current, CppTokenKind.IdentLiteral); if (identResult != null) { stream.Seek(identResult.Node); // Enum value var enumValueToken = identResult.Token; string enumValueName = enumValueToken.Value; stream.Next(); CppEntity enumValueEntity = new CppEntity(CppEntityKind.EnumValue, enumValueToken, enumValueName) { DocumentationNode = FindDocumentationNode(identResult.Node, 1), }; CppNode enumValueNode = new CppNode(rootNode, enumValueEntity); rootNode.AddChild(enumValueNode); SymbolCache.AddSource(Tag, enumValueName, new SourceSymbol(SourceSymbolKind.CppMember, enumValueToken.Range, enumValueNode)); var equalsResult = Search(stream, SearchMode.Current, CppTokenKind.EqOp); if (equalsResult != null) { stream.Next(); // Skip until comma or right brace var tmpResult = Search(stream, SearchMode.Forward, CppTokenKind.Comma, CppTokenKind.RightBrace); if (tmpResult != null) { stream.Seek(tmpResult.Node); } else { AddError(equalsResult.Token.Position, $"Expect assignment token, but got token '{stream.Peek()}' for enum member '{enumValueName}'", "Enum", enumValueName); break; } } var commaOrRightBraceResult = Search(stream, SearchMode.Current, CppTokenKind.Comma, CppTokenKind.RightBrace); if (commaOrRightBraceResult != null) { stream.Seek(commaOrRightBraceResult.Node); if (commaOrRightBraceResult.Token.Kind == CppTokenKind.Comma) { stream.Next(); } continue; } else { var tok = stream.Peek <CppToken>(); if (tok != null) { AddError(tok.Position, $"Unexpected token '{tok.Kind}'", "EnumValue"); } break; } } stream.Next(); } }