/** * ParamList = "(" [ ( Param [{ "," Param }] [ "," "..." ] ) | "..." | "void" ] ")" */ void parserParamList (parserCtx* ctx, ast* Node, bool inDecl) { debugEnter("ParamList"); tokenMatchPunct(ctx, punctLParen); if (!tokenIsPunct(ctx, punctRParen)) { tokenLocation voidloc = ctx->location; bool end = false; /*Either an empty prototype declaration, or the beginning of a void* parameter*/ if (tokenTryMatchKeyword(ctx, keywordVoid)) { if (!tokenIsPunct(ctx, punctRParen)) { ast* basic = astCreateLiteralIdent(voidloc, strdup("void")); ast* expr = parserDeclExpr(ctx, inDecl, symParam); ast* param = astCreateParam(voidloc, basic, expr); param->symbol = basic->symbol = symFind(ctx->scope, "void"); astAddChild(Node, param); if (!tokenTryMatchPunct(ctx, punctComma)) end = true; } else end = true; } if (!end) do { if (tokenIsPunct(ctx, punctEllipsis)) { astAddChild(Node, astCreate(astEllipsis, ctx->location)); tokenMatch(ctx); break; } else astAddChild(Node, parserParam(ctx, inDecl)); } while (tokenTryMatchPunct(ctx, punctComma)); } tokenMatchPunct(ctx, punctRParen); debugLeave(); }
STATUS symFindByNameEPICS(SYMTAB_ID symTblId, char *name, char **ppvalue, SYM_TYPE *pType) { SYMBOL_DESC symDesc; STATUS status; memset(&symDesc, 0, sizeof(SYMBOL_DESC)); symDesc.mask = SYM_FIND_BY_NAME; symDesc.name = name + (name[0] == '_'); status = symFind(sysSymTbl, &symDesc); if (!status) { *ppvalue = symDesc.value; *pType = symDesc.type; } return status; }
/** * DeclBasic = [ "const" ] <Ident> | StructUnion | Enum */ static ast* parserDeclBasic (parserCtx* ctx) { debugEnter("DeclBasic"); ast* Node; tokenLocation constloc = ctx->location; bool isConst = tokenTryMatchKeyword(ctx, keywordConst); if (tokenIsKeyword(ctx, keywordStruct) || tokenIsKeyword(ctx, keywordUnion)) Node = parserStructOrUnion(ctx); else if (tokenIsKeyword(ctx, keywordEnum)) Node = parserEnum(ctx); else { tokenLocation loc = ctx->location; sym* Symbol = symFind(ctx->scope, ctx->lexer->buffer); if (Symbol) { Node = astCreateLiteralIdent(loc, tokenDupMatch(ctx)); Node->symbol = Symbol; } else { if (tokenIsIdent(ctx)) { errorUndefType(ctx); tokenNext(ctx); } else errorExpected(ctx, "type name"); Node = astCreateInvalid(loc); } } if (isConst) { Node = astCreateConst(constloc, Node); Node->symbol = Node->r->symbol; } debugLeave(); return Node; }
/** * Name = <UnqualifiedIdent> * * If inDecl, creates a symbol, adding it to the list of declarations * if already created. */ static ast* parserName (parserCtx* ctx, bool inDecl, symTag tag) { debugEnter("Name"); ast* Node; if (tokenIsIdent(ctx)) { tokenLocation loc = ctx->location; Node = astCreateLiteralIdent(loc, tokenDupMatch(ctx)); /*Check for a collision only in this scope, will shadow any other declarations elsewhere.*/ sym* Symbol = symFind(ctx->scope, (char*) Node->literal); if (Symbol) { Node->symbol = Symbol; symChangeParent(Symbol, ctx->scope); if (Node->symbol->tag != tag && !isTypedefException(Node->symbol, tag)) errorRedeclaredSymAs(ctx, Node->symbol, tag); } else if (inDecl) Node->symbol = symCreateNamed(tag, ctx->scope, (char*) Node->literal); if (Node->symbol) { /*Can't tell whether this is a duplicate declaration or a (matching) redefinition*/ vectorPush(&Node->symbol->decls, Node); } } else { errorExpected(ctx, "name"); Node = astCreateInvalid(ctx->location); Node->literal = strdup(""); Node->symbol = symCreateNamed(tag, ctx->scope, ""); } debugLeave(); return Node; }