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 + -
显示快捷键?