idlscope.cc

来自「编译工具」· CC 代码 · 共 1,370 行 · 第 1/3 页

CC
1,370
字号
}voidScope::appendEntry(Entry* e){  if (entries_) last_->next_ = e;  else entries_ = e;  last_ = e;}voidScope::startScope(Scope* s){  assert(s->parent() == current_);  current_ = s;}voidScope::endScope(){  assert(current_ != 0);  current_ = current_->parent();  assert(current_ != 0);}// Scope creation functionsScope*Scope::newModuleScope(const char* identifier, const char* file, int line){  // Only the global scope and modules can contain modules. The  // grammar enforces this  assert(kind() == S_GLOBAL || kind() == S_MODULE);  // If there is already a module entry for this name, return it  Entry* e = find(identifier);  if (e && e->kind() == Entry::E_MODULE)    return e->scope();  // If there was an entry but it wasn't a module, carry on anyway,  // since addModule() will report the error  return new Scope(this, identifier, S_MODULE, 0, file, line);}Scope*Scope::newInterfaceScope(const char* identifier, const char* file, int line){  assert(kind() == S_GLOBAL || kind() == S_MODULE);  return new Scope(this, identifier, S_INTERFACE, 1, file, line);}Scope*Scope::newStructScope(const char* identifier, const char* file, int line){  assert(kind() != S_OPERATION);  return new Scope(this, identifier, S_STRUCT, 0, file, line);}Scope*Scope::newExceptionScope(const char* identifier, const char* file, int line){  assert(kind() != S_OPERATION);  return new Scope(this, identifier, S_EXCEPTION, 0, file, line);}Scope*Scope::newUnionScope(const char* identifier, const char* file, int line){  assert(kind() != S_OPERATION);  return new Scope(this, identifier, S_UNION, 0, file, line);}Scope*Scope::newOperationScope(const char* file, int line){  assert(kind() == S_INTERFACE || kind() == S_VALUE);  return new Scope(this, S_OPERATION, 0, file, line);}Scope*Scope::newValueScope(const char* identifier, const char* file, int line){  assert(kind() == S_GLOBAL || kind() == S_MODULE);  return new Scope(this, identifier, S_VALUE, 1, file, line);}// Searching functionsScope::Entry*Scope::find(const char* identifier) const{  Entry* e;  if (identifier[0] == '_') ++identifier;  for (e = entries_; e; e = e->next()) {    if (!(strcmp(identifier, e->identifier())))      return e;  }  return 0;}Scope::Entry*Scope::iFind(const char* identifier) const{  Entry* e;  if (identifier[0] == '_') ++identifier;  for (e = entries_; e; e = e->next()) {    if (Config::caseSensitive) {      if (!(strcmp(identifier, e->identifier())))	return e;    }    else {      if (!(strcasecmp(identifier, e->identifier())))	return e;    }  }  return 0;}Scope::EntryList*Scope::findWithInheritance(const char* identifier) const{  const Entry* e;  EntryList*   el = 0;  EntryList*   in_el;  if (identifier[0] == '_') ++identifier;  if ((e = find(identifier))) {    switch (e->kind()) {    case Entry::E_MODULE:    case Entry::E_DECL:    case Entry::E_CALLABLE:    case Entry::E_INHERITED:    case Entry::E_INSTANCE:      el = new EntryList(e);      return el;    case Entry::E_USE:    case Entry::E_PARENT:      break;    }  }  // Not found locally -- try inherited scopes  for (InheritSpec* is = inherited_; is; is = is->next()) {    if (!is->scope()) continue; // Skip broken entries from earlier errors    in_el = is->scope()->findWithInheritance(identifier);    if (el)      el->merge(in_el);    else      el = in_el;  }  for (ValueInheritSpec* vis = valueInherited_; vis; vis = vis->next()) {    if (!vis->scope()) continue; // Skip broken entries from earlier errors    in_el = vis->scope()->findWithInheritance(identifier);    if (el)      el->merge(in_el);    else      el = in_el;  }  return el;}Scope::EntryList*Scope::iFindWithInheritance(const char* identifier) const{  const Entry* e;  EntryList*   el = 0;  EntryList*   in_el;  if (identifier[0] == '_') ++identifier;  if ((e = iFind(identifier))) {    switch (e->kind()) {    case Entry::E_MODULE:    case Entry::E_DECL:    case Entry::E_CALLABLE:    case Entry::E_INHERITED:    case Entry::E_INSTANCE:      el = new EntryList(e);      return el;    case Entry::E_USE:    case Entry::E_PARENT:      break;    }  }  // Not found locally -- try inherited scopes  for (InheritSpec* is = inherited_; is; is = is->next()) {    if (!is->scope()) continue; // Skip broken entries from earlier errors    in_el = is->scope()->iFindWithInheritance(identifier);    if (el)      el->merge(in_el);    else      el = in_el;  }  for (ValueInheritSpec* vis = valueInherited_; vis; vis = vis->next()) {    if (!vis->scope()) continue; // Skip broken entries from earlier errors    in_el = vis->scope()->iFindWithInheritance(identifier);    if (el)      el->merge(in_el);    else      el = in_el;  }  return el;}const Scope::Entry*Scope::findScopedName(const ScopedName* sn, const char* file, int line) const{  const Scope* s;  // Start at relevant Scope  if (sn->absolute())    s = global();  else    s = this;  // Find entry for each name component  const Entry*          e = 0;  EntryList*            el;  ScopedName::Fragment* f = sn->scopeList();  const char*           fid;  IDL_Boolean top_component = 1;  while (f) {    fid = f->identifier();    if (fid[0] == '_') fid++;    do {      el = s->iFindWithInheritance(fid);      e = 0;      if (el) {	e = el->head();	if (el->tail()) {	  // Error -- ambiguous	  if (file) {	    char* ssn = sn->toString();	    IdlError(file, line, "Ambiguous name '%s':", ssn);	    delete [] ssn;	    for (; el; el = el->tail()) {	      char* ssn = el->head()->container()->scopedName()->toString();	      IdlErrorCont(el->head()->file(), el->head()->line(),			   "('%s' defined in '%s')",			   el->head()->identifier(), ssn);	      delete [] ssn;	    }	  }	  delete el;	  return 0;	}	delete el;	break;      }    } while (top_component && (s = s->parent()));    top_component = 0;    if (!e) {      if (file) {	char* ssn = sn->toString();	IdlError(file, line, "Error in look-up of '%s': '%s' not found",		 ssn, fid);	delete [] ssn;      }      return 0;    }    if (strcmp(fid, e->identifier())) {      // Case clash      if (file) {	char* ssn = sn->toString();	IdlError(file, line, "Error in look-up of '%s': '%s' differs in case",		 ssn, fid);	delete [] ssn;	ssn = e->scopedName()->toString();	IdlErrorCont(e->file(), e->line(), "from '%s' declared here", ssn);	delete [] ssn;      }      return 0;    }    f = f->next();    if (f) { // More name fragments: check that current entry forms a scope      s = e->scope();      if (!s) {	if (file) {	  char* ssn = sn->toString();	  IdlError(file, line,		   "Error in look-up of '%s': '%s' does not form a scope",		   ssn, e->identifier());	  IdlErrorCont(e->file(), e->line(), "('%s' defined here)",		       e->identifier());	  delete [] ssn;	}	return 0;      }    }  }  return e;}const Scope::Entry*Scope::findForUse(const ScopedName* sn, const char* file, int line){  const Entry* e = findScopedName(sn, file, line);  addUse(sn, file, line);  return e;}static ScopedName*findRelativeScope(const ScopedName::Fragment* from,		  const ScopedName::Fragment* to,		  const Scope* fromScope,		  const Scope::Entry* target){  ScopedName* result = 0;  if (!to)    return 0;  if (from && !strcmp(from->identifier(), to->identifier())) {    // Top name components match -- recursively try next components    result = findRelativeScope(from->next(), to->next(), fromScope, target);  }  if (!result) {    ScopedName*         test = new ScopedName(to, 0);    const Scope::Entry* find = fromScope->findScopedName(test);    if (find == target)      result = test;    else      delete test;  }  return result;}ScopedName*Scope::relativeScopedName(const ScopedName* from, const ScopedName* to){  if (!global_) {    // Haven't parsed any IDL yet!    return 0;  }  if ((from && !from->absolute()) || !to->absolute())    return 0;  const Scope* fromScope;  if (from) {    const Entry* fromEntry = global_->findScopedName(from);    if (!fromEntry) return 0;    fromScope = fromEntry->scope();  }  else    fromScope = global_;  const Entry* toEntry = global_->findScopedName(to);  if (!toEntry) return 0;  ScopedName* result = findRelativeScope(from ? from->scopeList() : 0,					 to->scopeList(), fromScope, toEntry);  if (!result)    result = new ScopedName(to);  return result;}// Entry adding functionsvoidScope::addUse(const ScopedName* sn, const char* file, int line){  if (!sn->absolute()) {    const char* id = sn->scopeList()->identifier();    if (id[0] == '_') ++id;    const Entry* clash = iFind(id);    if (clash) {      if (strcmp(id, clash->identifier())) {	char* ssn = sn->toString();	IdlError(file, line, "Use of '%s' clashes with identifier '%s'",		 ssn, clash->identifier());	IdlErrorCont(clash->file(), clash->line(), "('%s' declared here)",		     clash->identifier());	delete [] ssn;      }      // Else the identifier is being used in the same scope that it was      // declared, so don't mark it as used.    }    else {      Entry* ue = new Entry(this, Entry::E_USE, id, 0, 0, 0, 0, file, line);      appendEntry(ue);      if (parent_ && parent_->nestedUse()) parent_->addUse(sn, file, line);    }  }}voidScope::addModule(const char* identifier, Scope* scope, Decl* decl,	  const char* file, int line){  if (*identifier == '_')    ++identifier;  else    keywordClash(identifier, file, line);  Entry* clash = iFind(identifier);  if (clash) {    switch (clash->kind()) {    case Entry::E_MODULE:      {	if (!strcmp(identifier, clash->identifier())) {	  return; // Reopening the module	}	IdlError(file, line,		 "Declaration of module '%s' clashes with declaration "		 "of module '%s'", identifier, clash->identifier());	IdlErrorCont(clash->file(), clash->line(),		     "(module '%s' declared here)", clash->identifier());

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?