2 * PARSE2.C - Misc parser support, including declarator handling
4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
10 static int FinishDecl(Parse *p, int t, Declaration *d, Type *type);
13 * XXX handle scope overrides
16 ParseScopeQual(Parse *p, int t, Scope *scope)
19 scope->s_AlignOverride = 0;
21 while (t & TOKF_SCOPE_QUAL) {
22 scope->s_Flags |= 1 << (t & TOKF_SCOPE_MASK);
24 t = LexToken(&p->p_Token);
25 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
26 t = SimpleIntToken(&p->p_Token,
27 &scope->s_AlignOverride);
28 t = LexSkipToken(&p->p_Token, TOK_INTEGER);
29 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
31 t = LexToken(&p->p_Token);
38 * XXX handle illegal storage qualifier combinations & overrides
41 ParseStorageQual(Parse *p, int t, int *pmask)
45 while (t & TOKF_STOR_QUAL) {
46 mask |= 1 << (t & TOKF_STOR_MASK);
47 t = LexToken(&p->p_Token);
54 * declaration: type decl(idReq) [= exp]
56 * Note: we only handle the procedural reference portion of a procedure
57 * definition here. We do not handle the procedure body. See
58 * ParseDeclarationStmt(). We also handle aliases here.
60 * idRequired may be 0, 1, or 2.
62 * 0: No identifier is required
63 * 1: An identifier is required
64 * 2: An identifier is required, a dotted identifier sequence is
65 * optional, and global scope is implied if only a single
69 ParseDeclaration(Parse *p, int t, Declaration **pd, int idRequired, int dop, Scope *scope)
81 Scope tscope = *scope;
84 * Handle alias declarations.
88 t = LexToken(&p->p_Token);
92 * Handle procedure-related special cases
96 t = LexToken(&p->p_Token);
97 tscope.s_Flags |= SCOPE_CAST;
101 t = LexToken(&p->p_Token);
102 if (t != TOK_DSTRING) {
103 t = LexError(&p->p_Token,
104 TOK_ERR_EXPECTED_QUOTED_OPERATOR);
107 * Add the operator to the operator hash. Don't
108 * hash the quotes, just the contents of the quotes.
110 opid = StrTableAlloc(p->p_Token.t_Ptr + 1,
111 p->p_Token.t_Len - 2, 0);
112 t = LexToken(&p->p_Token);
117 t = LexToken(&p->p_Token);
119 if (tscope.s_Flags & SCOPE_GLOBAL)
120 rqflags |= SF_GMETHOD;
122 rqflags |= SF_METHOD;
127 * Allow the LVALUE scope to be specified after the operator
128 * (to make operator declarations using lvalue look nicer).
130 * 'lvalue' is also a storage qualifier, and requires outer scoping.
131 * e.g. if you have something like 'lvalue const int *x', lvalue
132 * applies to the declaration itself, the pointer, whereas const
133 * applies to what is being pointed to.
135 if (t == TOK_LVALUE) {
136 tscope.s_Flags |= SCOPE_LVALUE;
137 t = LexToken(&p->p_Token);
139 if (tscope.s_Flags & SCOPE_LVALUE)
140 rqflags |= SF_LVALUE;
144 * Parse storage qualifiers and the base type
146 t = ParseStorageQual(p, t, &sqflags);
147 t = ParseType(p, t, &type, sqflags);
150 * Parse the declarators and identifier(s). Deal with implied global
151 * scope, and adjust 'dop' properly.
154 SemGroup *sg = p->p_CurSemGroup;
155 t = ParseDeclType(p, t, &type, &sg,
156 tscope.s_Flags & SCOPE_CLANG,
157 rqflags, &id, idRequired);
158 if (idRequired == 2 && sg == p->p_CurSemGroup)
159 tscope.s_Flags |= SCOPE_GLOBAL;
160 if ((tscope.s_Flags & SCOPE_GLOBAL) && (dop & DOPF_STORAGE))
161 dop = DOP_GLOBAL_STORAGE;
164 d = AllocDeclaration(sg, dop, &tscope);
165 t = FinishDecl(p, t, d, type);
171 * Make sure procedural keywords are only used with procedures,
172 * and hash the operator id (if any).
175 if (d->d_Op != DOP_PROC && (isCast || isOper || isMeth)) {
176 t = LexError(&p->p_Token,
177 TOK_ERR_OPERATOR_NOT_PROCEDURE);
185 * If this is a method procedure we have to add an argument called
186 * 'this' that represents an lvalue of the class the procedure resides
187 * in. XXX not needed any more.
194 * Handle any assigned expression
199 t = LexToken(&p->p_Token);
200 t = ParseExp(p, t, &d->d_AliasDecl.ed_AssExp);
203 t = LexToken(&p->p_Token);
204 t = ParseExp(p, t, &d->d_TypedefDecl.ed_AssExp);
206 case DOP_ARGS_STORAGE:
207 case DOP_STACK_STORAGE:
208 case DOP_GLOBAL_STORAGE:
209 case DOP_GROUP_STORAGE:
210 t = LexToken(&p->p_Token);
211 t = ParseExp(p, t, &d->d_StorDecl.ed_AssExp);
214 } else if (isAlias) {
216 * Assignment is required for aliases
218 t = LexError(&p->p_Token, TOK_ERR_SYNTAX);
220 if (t & TOKF_ERROR) {
222 FreeDeclaration(p, d);
230 * note: HashDecl() eats our reference on id.
232 if (HashDecl(d, id) > 0 &&
233 !(d->d_Op == DOP_PROC &&
234 d->d_ProcDecl.ed_OperId != NULL))
236 t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ID);
246 * ( declaration [, declaration]* )
249 ParseDeclarationList(Parse *p, int t, int scopeFlags, int idRequired, int dop)
251 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
252 if (t != TOK_CPAREN) {
257 if (p->p_CurSemGroup->sg_Flags & SGF_PROCARGS) {
258 t = LexSkipToken(&p->p_Token, TOK_DOT);
259 t = LexSkipToken(&p->p_Token, TOK_DOT);
260 t = LexSkipToken(&p->p_Token, TOK_DOT);
261 p->p_CurSemGroup->sg_Flags |= SGF_VARARGS;
263 t = LexError(&p->p_Token,
268 t = ParseScopeQual(p, t, &scope);
269 scope.s_Flags |= scopeFlags;
270 t = ParseDeclaration(p, t, NULL,
271 idRequired, dop, &scope);
274 t = LexToken(&p->p_Token);
277 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
284 * ( declaration [, declaration]* )
287 ParseType(Parse *p, int t, Type **ptype, int sqflags)
291 if (t == TOK_STORAGE) {
294 t = LexToken(&p->p_Token);
295 t = LexSkipToken(&p->p_Token, TOK_OPAREN);
296 t = SimpleIntToken(&p->p_Token, &bytes);
297 t = LexSkipToken(&p->p_Token, TOK_INTEGER);
298 t = LexSkipToken(&p->p_Token, TOK_CPAREN);
299 *ptype = AllocStorageType(bytes);
301 *ptype = TypeToQualType(*ptype,
303 (*ptype)->ty_SQFlags|sqflags,
309 if (t == TOK_OPAREN) {
311 * parse a compound type.
313 p->p_CurSemGroup = AllocSemGroup(p, p->p_CurSemGroup, NULL);
314 t = ParseDeclarationList(p, t, 0, 0, DOP_GROUP_STORAGE);
315 if ((t & TOKF_ERROR) == 0) {
316 *ptype = AllocCompoundType(p->p_CurSemGroup);
318 *ptype = TypeToQualType(*ptype, NULL,
319 (*ptype)->ty_SQFlags |
324 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_CPAREN);
325 /* mark semgroup for free after pop */
327 p->p_CurSemGroup = p->p_CurSemGroup->sg_Parent;
328 } else if (t & TOKF_ID) {
330 * parse a normal type, which is a semantic identifier path
337 t = ParseDotIdAry(p, t, &ary, &count, <);
338 if (lt != TOK_CLASSID)
339 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_CLASSID);
340 if ((t & TOKF_ERROR) == 0) {
341 *ptype = AllocUnresolvedType(
342 p->p_Import->st_ImportStmt.es_SemGroup,
347 /* XXX cleanup memory */
349 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_TYPE);
351 if ((t & TOKF_ERROR) == 0) {
353 *ptype = TypeToQualType(*ptype, NULL,
354 (*ptype)->ty_SQFlags | sqflags,
362 * ParseDotIdAry() - parse a sequence of dot-separated identifiers.
365 ParseDotIdAry(Parse *p, int t, string_t **pary, int *pcount, int *ltp)
372 * First token must be an identifier
374 if ((t & TOKF_ID) == 0)
375 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_ID);
378 * First count the number of identifiers.
384 while ((t & TOKF_ERROR) == 0) {
385 ++count; /* count ID */
387 t = LexToken(&p->p_Token); /* skip id */
390 t = LexToken(&p->p_Token); /* skip dot */
391 if ((t & TOKF_ID) == 0)
392 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_ID);
396 * If no error occured, allocate the array and load it with the
399 if ((t & TOKF_ERROR) == 0) {
404 ary = zalloc(sizeof(string_t) * (count + 1));
405 for (i = 0; i < count; ++i) {
406 ary[i] = StrTableToken(&p->p_Token);
407 t = LexToken(&p->p_Token); /* skip id */
409 t = LexToken(&p->p_Token); /* skip dot */
421 DupDotIdAry(string_t *ary)
426 for (i = 0; ary[i]; ++i)
428 nary = zalloc(sizeof(string_t) * (i + 1));
429 for (i = 0; ary[i]; ++i)
430 nary[i] = StrTableDup(ary[i]);
435 FreeDotIdAry(string_t *ary)
439 for (i = 0; ary[i]; ++i)
440 RelStrTable(&ary[i]);
441 zfree(ary, sizeof(string_t) * (i + 1));
445 * ParseDeclType() - Parse declarators for declaration given base type
447 * Parse the declarators for the specified base type, returning an
448 * appropriate qualified type. If an identifier is part of the
449 * declarator sequence the identifier will be returned. If idRequired
450 * is 1, an identifier is required. If idRequired is 2, multiple
451 * dot-separated identifiers are allowed (and the last is returned),
452 * and psg will be set to the SemGroup representing the class they
453 * reference. For example, 'int FILE.setMode(int mode) { .. }'
454 * will set *psg to FILE's SemGroup. This eventually goes into
455 * d_MyGroup, while d_OrigSemGroup retains the original semgroup.
457 * Note that multi-identifiers have library scope only and must already
458 * exist (not be forward referenced).
460 * declaration: type decl
462 * decl: [ declarator ]*
465 * id[.id]* identifier(s) (if not already specified)
466 * ( declaration_list) procedure-returning
469 * [ storage_qual ]* qualified with
471 * NOTE! Types are built up from left-to-right prior to the identifier or
472 * procedure args, then right-to-left. For example:
474 * const char * const a[2][10] - an array 2 of an array 10 of
475 * a constant pointer to a constant
478 * int func * (int, int) - a pointer to a procedure taking
479 * two arguments and returning an int.
481 * NOTE! Certain storage qualifiers in an underlying type will migrate to
484 * NOTE! scopeFlags propogates SCOPE_CLANG, which effects pointers
485 * (XXX and should effect alignment too??)
488 ParseDeclType(Parse *p, int t, Type **ptype, SemGroup **psg,
489 int scopeFlags, int rqflags, string_t *id,
493 if (t == TOK_OPAREN) {
495 * parse procedure argument-type, which is a compound
496 * type. Note that we leave our semantic linkages
497 * intact to simplify the type resolver (see
498 * resolve.c), but set the DOP to something we can
499 * recognize later. The nesting level will be fixed
502 p->p_CurSemGroup = AllocSemGroup(p,
505 p->p_CurSemGroup->sg_Flags |= SGF_PROCARGS;
506 t = ParseDeclarationList(p, t, scopeFlags,
507 0, DOP_ARGS_STORAGE);
509 t = ParseDeclType(p, t, ptype,
510 NULL, scopeFlags, 0, id,
511 idRequired > 1 ? 1 : idRequired);
512 *ptype = TypeToProcType(*ptype,
513 AllocArgsType(p->p_CurSemGroup));
514 p->p_CurSemGroup = p->p_CurSemGroup->sg_Parent;
517 * anything after proc args must be parsed as if
518 * we had specified an identifier.
521 *id = StrTableAlloc("_dummy_", 7, 0);
522 } else if (t == TOK_AT) {
524 * A reference type (bound via a superclass)
526 t = LexToken(&p->p_Token);
528 t = ParseDeclType(p, t, ptype,
529 psg, scopeFlags, 0, id,
532 *ptype = TypeToRefType(*ptype);
533 } else if (t == TOK_OPER && p->p_Token.t_Ptr[0] == '*') {
535 * We have to deal with pointer-to declarators.
536 * Regenerate the token using only the first character
539 t = LexRedactToken(&p->p_Token, 1);
540 t = LexToken(&p->p_Token);
542 t = ParseDeclType(p, t, ptype,
543 psg, scopeFlags, 0, id,
546 if (scopeFlags & SCOPE_CLANG)
547 *ptype = TypeToCPtrType(*ptype);
549 *ptype = TypeToPtrType(*ptype);
550 } else if (t == TOK_OBRACKET) {
556 t = LexToken(&p->p_Token);
557 t = ParseExp(p, t, &exp);
558 t = LexSkipToken(&p->p_Token, TOK_CBRACKET);
560 t = ParseDeclType(p, t, ptype,
561 psg, scopeFlags, 0, id,
564 *ptype = TypeToAryType(*ptype, exp, *psg);
565 } else if (t & TOKF_SCOPE_QUAL) {
566 t = LexError(&p->p_Token, TOK_ERR_SYNTAX);
567 } else if (t & TOKF_STOR_QUAL) {
570 t = ParseStorageQual(p, t, &sqflags);
572 t = ParseDeclType(p, t, ptype,
573 psg, scopeFlags, 0, id,
576 *ptype = TypeToQualType(*ptype,
578 (*ptype)->ty_SQFlags | sqflags,
580 } else if (t & TOKF_ID) {
581 if (*id) /* terminator */
583 *id = StrTableToken(&p->p_Token);
584 t = LexToken(&p->p_Token);
585 if (idRequired < 2 && t == TOK_DOT) {
586 t = LexError(&p->p_Token,
587 TOK_ERR_NO_DOTTED_ID_HERE);
589 while (t == TOK_DOT) {
591 * Lookup *id based on the current psg. This
592 * is about the only FindDeclPath() call that
593 * occurs during parse time. All the rest
594 * occur at resolve time. There is no
595 * skip-back SemGroup at parse time (i.e.
596 * first arg is NULL).
598 * At the moment we only allow private scope.
599 * This is because we need pre-resolution
600 * structural linkages to stay within their
601 * import paradigm, allowing us to save and
602 * restore/relocate the associated memory pool
603 * as an intermediate pre-parsed file format.
604 * It also allows us to resolve things
605 * incrementally and save/restore after those
608 * At some future date I intend to allow
609 * library scope, (SCOPE_PRIVATE|SCOPE_LIBRARY),
610 * which will necessitate saving and restoring
611 * dependant files as a single entity.
615 int vis = SCOPE_LIBRARY|SCOPE_PRIVATE;
616 int eno = TOK_ERR_PARSE_CLASS_NOT_FOUND;
617 string_t ary[] = { *id, NULL };
619 d = FindDeclPath(NULL, NULL, *psg,
620 NULL, ary, 0, &vis, -1,
626 d->d_ClassDecl.ed_SemGroup;
630 d->d_ImportDecl.ed_SemGroup;
633 t = LexError(&p->p_Token,
634 TOK_ERR_PARSE_ID_NOT_CLASS);
638 t = LexError(&p->p_Token, eno);
644 * Retrieve the next identifier
646 t = LexToken(&p->p_Token);
647 if ((t & TOKF_ID) == 0) {
648 t = LexError(&p->p_Token,
649 TOK_ERR_EXPECTED_ID);
652 ReplaceStrTable(id, StrTableToken(&p->p_Token));
653 t = LexToken(&p->p_Token);
662 break; /* terminator */
664 t = LexError(&p->p_Token, TOK_ERR_EXPECTED_DECLARATOR);
671 * A Method procedure silently passes the lvalue object as the first
672 * argument to the procedure. A global method procedure silently
673 * passes the type of the object as the first argument to the
674 * procedure (as a typedef). The argument is called this. If the
675 * procedure declares a 'this' argument for the first argument, we
676 * assume that the programmer has constructed this special argument
677 * manually (which the programmer must do if he wants an lvalue
678 * pointer or reference to the class).
680 if (rqflags & (SF_METHOD|SF_GMETHOD)) {
688 dassert_parse(p, 0, type->ty_Op == TY_PROC);
690 nd = getHead(&type->ty_ProcType.et_ArgsType->
691 ty_ArgsType.et_SemGroup->sg_DeclList);
692 if (nd && nd->d_Id != String_This)
695 * XXX should really use TypeToProcType() or write a
696 * ProcTypeToMethodProcType() call.
700 if (st->st_Op != ST_Class) {
702 "Method calls must be placed in a class\n");
703 dassert_parse(p, 0, st->st_Op == ST_Class);
706 ctype = AllocClassType(&sg->sg_ClassList,
707 st->st_ClassStmt.es_Super,
711 if (rqflags & SF_METHOD) {
712 type = TypeToQualType(type,
714 type->ty_SQFlags | SF_METHOD,
717 dassert(rqflags & SF_GMETHOD);
718 type = TypeToQualType(type,
720 type->ty_SQFlags | SF_GMETHOD,
724 Scope tscope = INIT_SCOPE(SCOPE_ALL_VISIBLE);
726 sg = type->ty_ProcType.et_ArgsType->
727 ty_ArgsType.et_SemGroup;
728 if (rqflags & SF_METHOD) {
729 nd = AllocDeclaration(sg,
732 nd->d_StorDecl.ed_Type =
733 TypeToQualType(ctype, NULL,
737 nd->d_ScopeFlags |= SCOPE_LVALUE;
739 nd = AllocDeclaration(sg, DOP_TYPEDEF, &tscope);
740 nd->d_TypedefDecl.ed_Type = ctype;
742 HashDecl(nd, StrTableDup(String_This));
743 removeNode(&nd->d_Node);
744 addHead(&sg->sg_DeclList, &nd->d_Node);
747 rqflags &= ~(SF_METHOD | SF_GMETHOD);
751 if (type->ty_Op == TY_PROC) {
752 type = type->ty_ProcType.et_RetType;
753 (*ptype)->ty_ProcType.et_RetType =
756 type->ty_SQFlags | rqflags,
759 *ptype = TypeToQualType(type,
761 type->ty_SQFlags | rqflags,
769 FinishDecl(Parse *p, int t, Declaration *d, Type *type)
772 * Install the type and adjust the declaration accordingly.
774 if (d->d_Op == DOP_ALIAS) {
775 d->d_StorDecl.ed_Type = type;
776 } else if (d->d_Op == DOP_TYPEDEF) {
777 if (type->ty_Op == TY_PROC)
778 t = LexError(&p->p_Token, TOK_ERR_ILLEGAL_TYPEDEF);
780 d->d_TypedefDecl.ed_Type = type;
781 } else if (type->ty_Op == TY_PROC) {
783 d->d_ProcDecl.ed_Type = type;
785 dassert_decl(d, d->d_Op & DOPF_STORAGE);
786 d->d_StorDecl.ed_Type = type;
790 * Install d_ImportSemGroup.
792 d->d_ImportSemGroup = p->p_Import->st_ImportStmt.es_SemGroup;