Esempio n. 1
0
/* If we have an enum-valued group attribute, then we need to do
extra work to find the containing enum type
*/
static Symbol*
locateenumtype(Symbol* refsym, Symbol* parent, NCConstant* con)
{
    Symbol* match = NULL;
    List* grpmatches;

    /* Locate all possible matching enum constant definitions */
    List* candidates = findecmatches(refsym->name);
    if(candidates == NULL) {
	semerror(con->lineno,"Undefined enum or enum constant reference: %s",refsym->name);
	return NULL;
    }
    /* One hopes that 99% of the time, the match is unique */
    if(listlength(candidates) == 1) {
	match = listget(candidates,0);
	goto done;
    }
    /* If this ref has a specified group prefix, then find that group
       and search only within it for matches to the candidates */
    if(refsym->is_prefixed && refsym->prefix != NULL) {
	parent = lookupgroup(refsym->prefix);
	if(parent == NULL) {
	    semerror(con->lineno,"Undefined group reference: ",fullname(refsym));
	    goto done;
	}
	/* Search this group only for matches */
	grpmatches = ecsearchgrp(parent,candidates);
	switch (listlength(grpmatches)) {
	case 0:
	    semerror(con->lineno,"Undefined enum or enum constant reference: ",refsym->name);
	    listfree(grpmatches);
	    goto done;
	case 1:
	    break;
	default:
	    semerror(con->lineno,"Ambiguous enum constant reference: %s", fullname(refsym));
	}
	match = listget(grpmatches,0);
	listfree(grpmatches);
	goto done;
    }
    /* Sigh, we have to search up the tree to see if any of our candidates are there */
    assert(parent == NULL || parent->objectclass == NC_GRP);
    while(parent != NULL && match == NULL) {
	grpmatches = ecsearchgrp(parent,candidates);
	switch (listlength(grpmatches)) {
	case 0: break;
	case 1: match = listget(grpmatches,0); break;
	default:
	    semerror(con->lineno,"Ambiguous enum constant reference: %s", fullname(refsym));
	    match = listget(grpmatches,0);
	    break;
	}
	listfree(grpmatches);
    }
    if(match != NULL) goto done;
    /* Not unique and not in the parent tree, so complains and pick the first candidate */
    semerror(con->lineno,"Ambiguous enum constant reference: %s", fullname(refsym));
    match = (Symbol*)listget(candidates,0);
done:
    listfree(candidates);
    return match;
}
Esempio n. 2
0
Symbol*
locate(Symbol* refsym)
{
    Symbol* sym = NULL;
    switch (refsym->objectclass) {
    case NC_DIM:
	if(refsym->is_prefixed) {
	    /* locate exact dimension specified*/
	    sym = lookup(NC_DIM,refsym);
	} else { /* Search for matching dimension in all parent groups*/
	    Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/
	    while(parent != NULL) {
		/* search this parent for matching name and type*/
		sym = lookupingroup(NC_DIM,refsym->name,parent);
		if(sym != NULL) break;
		parent = parent->container;
	    }
	}		
	break;
    case NC_TYPE:
	if(refsym->is_prefixed) {
	    /* locate exact type specified*/
	    sym = lookup(NC_TYPE,refsym);
	} else {
	    Symbol* parent;
	    int i; /* Search for matching type in all groups (except...)*/
	    /* Short circuit test for primitive types*/
	    for(i=NC_NAT;i<=NC_STRING;i++) {
		Symbol* prim = basetypefor(i);
		if(prim == NULL) continue;
	        if(strcmp(refsym->name,prim->name)==0) {
		    sym = prim;
		    break;
		}
	    }
	    if(sym == NULL) {
	        /* Added 5/26/09: look in parent hierarchy first */
	        parent = lookupgroup(refsym->prefix);/*get group for refsym*/
	        while(parent != NULL) {
		    /* search this parent for matching name and type*/
		    sym = lookupingroup(NC_TYPE,refsym->name,parent);
		    if(sym != NULL) break;
		    parent = parent->container;
		}
	    }
	    if(sym == NULL) {
	        sym = uniquetreelocate(refsym,rootgroup); /* want unique */
	    }
	}		
	break;
    case NC_VAR:
	if(refsym->is_prefixed) {
	    /* locate exact variable specified*/
	    sym = lookup(NC_VAR,refsym);
	} else {
	    Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/
   	    /* search this parent for matching name and type*/
	    sym = lookupingroup(NC_VAR,refsym->name,parent);
	}		
        break;
    case NC_GRP:
	if(refsym->is_prefixed) {
	    /* locate exact group specified*/
	    sym = lookup(NC_GRP,refsym);
	} else {
	    Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/
   	    /* search this parent for matching name and type*/
	    sym = lookupingroup(NC_GRP,refsym->name,parent);
	}		
	break;

    default: PANIC1("locate: bad refsym type: %d",refsym->objectclass);
    }
    if(debug > 1) {
	char* ncname;
	if(refsym->objectclass == NC_TYPE)
	    ncname = ncclassname(refsym->subclass);
	else
	    ncname = ncclassname(refsym->objectclass);
	fdebug("locate: %s: %s -> %s\n",
		ncname,fullname(refsym),(sym?fullname(sym):"NULL"));
    }   
    return sym;
}