Type* GlobalEntry::typeCheck(){ SymTab* st = this->symTab(); for(SymTab::iterator i = st->begin(); i != st->end(); ++i){ (*i)->typeCheck(); } //Loops over all Rules for(unsigned int x = 0; x < rules_.size();++x){ rules_[x]->typeCheck(); } return NULL; }
/* generate declarations for global variables used in the program */ void generateDecls( const SymTab &curSymTab ) { for ( SymTab::const_iterator curSym = curSymTab.begin( ); curSym != curSymTab.end( ); ++curSym ) { if ( curSym -> second.isReg( ) == true || curSym -> second.Type( ) == FUNC || curSym -> second.isLocal( ) ) continue; curSym -> second.declare( curSym -> first ); } cout << "\n\n"; }
void EventEntry::memAlloc(MemoryMgr &mm){ memory_mgr_ = MemoryMgr(); //cout << "Event memAlloc" << endl; SymTab* st = this->symTab(); if(st!=NULL){ for(SymTab::iterator i = st->begin(); i != st->end();++i){ if((*i)->kind()==SymTabEntry::Kind::VARIABLE_KIND){ VariableEntry* ve = (VariableEntry*) (*i); if(ve->varKind()==VariableEntry::VarKind::PARAM_VAR){ ve->offSet(memory_mgr_.getNextAddress()); } } } } }
void GlobalEntry::memAlloc(MemoryMgr &mm){ memory_mgr_ = mm; parse_label_ = new Label(Label::LabelType::PARSE_START); end_label_ = new Label(Label::LabelType::END_PROGRAM); //Loops over all declarations SymTab* st = this->symTab(); for(SymTab::iterator i = st->begin(); i != st->end(); ++i){ (*i)->memAlloc(mm); } //Technically this happens between the two of them, but all registers should be free at this point in_reg_ = mm.getNextRegister(true); mm.addRegister(in_reg_); comp_reg_ = mm.getNextRegister(true); mm.addRegister(comp_reg_); mm.freeRegister(comp_reg_); //Loops over all Rules for(unsigned int x = 0; x < rules_.size();++x){ MemoryMgr mm_r; mm_r.addRegister(in_reg_); rules_[x]->memAlloc(mm_r); mm_r.freeRegister(in_reg_); if(rules_[x]->pat()->kind() == BasePatNode::PatNodeKind::PRIMITIVE){ PrimitivePatNode* pn = (PrimitivePatNode*)((PatNode*)rules_[x]->pat())->pat1(); EventEntry* ee = pn->event(); if(ee->name().length() == 1){ rule_names_.push_back(ee->name()); rule_labels_.push_back(rules_[x]->startLabel()); rule_return_labels_.push_back(rules_[x]->returnLabel()); } if(ee->name() == "any"){ any_labels_.push_back(rules_[x]->startLabel()); any_return_labels_.push_back(rules_[x]->returnLabel()); } } } mm.freeRegister(in_reg_); }
Type* EventEntry::typeCheck(){ vector<Type*>* arg_types = new vector<Type*>(); SymTab* st = this->symTab(); if(st!=NULL){ for(SymTab::iterator i = st->begin(); i != st->end();++i){ if((*i)->kind()==SymTabEntry::Kind::VARIABLE_KIND){ VariableEntry* ve = (VariableEntry*) (*i); if(ve->varKind()==VariableEntry::VarKind::PARAM_VAR){ arg_types->push_back(ve->type()); } } } } type()->argTypes(arg_types); return NULL; }
void Doxygen::annotate(SgProject *n) { typedef map<string, map<SgDeclarationStatement *, list<DoxygenComment *> *> > SymTab; /* The first pass finds declarations in the AST, adds them to a * rudimentary symbol table and attaches any doxygen comments situated next * to the declaration. The advantage of building our own symbol table * is that we do not need to know the exact type of overloaded functions. * This comes in handy when doing inexact matches (3rd pass). */ SymTab symTab; list<DoxygenComment *> commentList; PureDocumentationFileListAttribute *attr = new PureDocumentationFileListAttribute(); //Find declarations in the AST with doxygen comments attached. This will not find the //detached comments in a separate .docs file. class CollectDeclarations : public AstSimpleProcessing { public: SymTab *symTab; virtual void visit(SgNode *n) { SgDeclarationStatement *st = isSgDeclarationStatement(n); if (!st) { return; } if (!isRecognizedDeclaration(st)) { return; } string proto = getProtoName(st); SgDeclarationStatement *dxSt = getDoxygenAttachedDeclaration(st); if ((*symTab)[proto].count(dxSt) == 0) { DoxygenCommentListAttribute *attr = new DoxygenCommentListAttribute(); // King84 (2010.08.03) : This seems to be called with the same node multiple times. // From what I can tell, this is because a single function has been documented multiple times. // At the moment this function is AssemblerX86::AssemblerX86() from src/frontend/Disassemblers/AssemblerX86.h // For now, we will print out a warning and use the new documentation (instead of addNewAttribute we use setAttribute). if (dxSt->attributeExists("DoxygenCommentList")) { std::cerr << "Warning: Multiple Doxygen comments found for function " << dxSt->get_mangled_name().getString() << " at file " << dxSt->get_file_info()->get_filenameString() << ":" << dxSt->get_file_info()->get_line() << "," << dxSt->get_file_info()->get_col() << ". Picking the last." << std::endl; } dxSt->setAttribute("DoxygenCommentList", attr); // dxSt->addNewAttribute("DoxygenCommentList", attr); (*symTab)[proto][dxSt] = &(attr->commentList); } list<DoxygenComment *> *commentList = (*symTab)[proto][dxSt]; AttachedPreprocessingInfoType *info = st->getAttachedPreprocessingInfo(); if (info) { for (AttachedPreprocessingInfoType::iterator i = info->begin(); i != info->end(); ++i) { PreprocessingInfo *pi = *i; if (pi->getRelativePosition() == PreprocessingInfo::before && DoxygenComment::isDoxygenComment(pi)) { commentList->push_back(new DoxygenComment(st, pi)); } } } } }; //Find the detached comments in .docs files class FindDetachedComments : public AstSimpleProcessing { public: list<DoxygenComment *> *commentList; map<string, DoxygenFile *> *docsList; virtual void visit(SgNode *n) { SgVariableDeclaration *vd = isSgVariableDeclaration(n); if (!vd) { return; } if (isRecognizedDeclaration(vd)) { return; } AttachedPreprocessingInfoType *info = vd->getAttachedPreprocessingInfo(); if (info) { DoxygenFile *f = new DoxygenFile(vd); DoxygenGroup *currentGroup = 0; DoxygenComment *groupComment = 0; (*docsList)[vd->get_file_info()->get_filenameString()] = f; for (AttachedPreprocessingInfoType::iterator i = info->begin(); i != info->end(); ++i) { PreprocessingInfo *pi = *i; //printf("pass %d: processing comment %s\n", inexact ? 3 : 2, pi->getString().c_str()); //printf("processing comment %s\n", pi->getString().c_str()); if (DoxygenComment::isDoxygenComment(pi)) { DoxygenComment *comm = new DoxygenComment(vd, pi); comm->originalFile = f; if (comm->entry.type() == DoxygenEntry::None) { if (comm->entry.hasName()) { // this is a group //printf("name = '%s'\n", comm->entry.name().c_str()); if (currentGroup) { currentGroup->comment = comm; } else { groupComment = comm; } } else { delete comm; continue; } } commentList->push_back(comm); #if 0 pair<SymTab::iterator, SymTab::iterator> bounds = symTab->equal_range(DoxygenClass::getProtoName(comm->entry.prototype)); for (SymTab::iterator i = bounds.first; i != bounds.second; ) { if (inexact || comm->entry.prototype == getQualifiedPrototype((*i).second)) { DoxygenCommentListAttribute *attr = dynamic_cast<DoxygenCommentListAttribute *>((*i).second->attribute()["DoxygenCommentList"]); ROSE_ASSERT(attr); printf("attaching to node %s\n", (*i).second->unparseToString().c_str()); attr->commentList.push_back(comm); SymTab::iterator ii = i; ++i; symTab->erase(ii); } else { ++i; } } #endif } else if (isGroupStart(pi)) { if (currentGroup) { puts("Group already open!"); } //puts("opening group"); currentGroup = new DoxygenGroup(); currentGroup->groupStart = *i; currentGroup->comment = groupComment; groupComment = 0; } else if (isGroupEnd(pi)) { //puts("closing group"); if (!currentGroup) { puts("Group-end encountered without group begin!"); } else { currentGroup->groupEnd = *i; if (currentGroup->comment) { f->groups[currentGroup->comment->entry.name()] = currentGroup; } else { puts("Group wasn't given a name!"); } currentGroup = 0; } } } } } }; //Attach the PureDocumentationFileListAttribute to the SgProject for later access n->addNewAttribute("PureDocumentationFileList", attr); //Find doxygen comments attached to the interface documented CollectDeclarations cd; cd.symTab = &symTab; cd.traverse(n, preorder); //Find doxygen comments detached from the interface documented. FindDetachedComments fdc; fdc.commentList = &commentList; fdc.docsList = &(attr->docsList); fdc.traverse(n, preorder); bool inexact = false; bool innerFound = false; /* The first pass finds declarations in the AST, adds them to a * rudimentary symbol table and attaches any doxygen comments situated next * to the declaration. The advantage of building our own symbol table * is that we do not need to know the exact type of overloaded functions. * This comes in handy when doing inexact matches (3rd pass). */ /* The following loop executes exactly two times, during which inexact is first false then true. If inexact is true then matches are based on function name only. */ do { for (list<DoxygenComment *>::iterator i = commentList.begin(); i != commentList.end(); ) { DoxygenComment *comm = *i; if (!comm->entry.hasPrototype()) { list<DoxygenComment *>::iterator ii = i; ++i; commentList.erase(ii); continue; } //SymTab::mapped_type *protos = &(symTab[DoxygenEntry::getProtoName(comm->entry.prototype())]); //AS(09/24/07) Make the lookup in the symbol table explicit SymTab::mapped_type *protos; SymTab::iterator symTabLookup = symTab.find(DoxygenEntry::getProtoName(comm->entry.prototype())); if (symTabLookup != symTab.end()) protos = &(symTabLookup->second); else { std::cout << "creating new symTab for : " << comm->originalComment->getString() << " \n"; protos = new SymTab::mapped_type(); } //pair<SymTab::iterator, SymTab::iterator> bounds = symTab.equal_range(DoxygenEntry::getProtoName(comm->entry.prototype())); int lowestDist = INT_MAX; SymTab::mapped_type::iterator lowestCommentList; for (SymTab::mapped_type::iterator j = protos->begin(); j != protos->end(); ) { string s1 = removeWhitespace(comm->entry.prototype()); string s2 = removeWhitespace(getQualifiedPrototype((*j).first)); //printf("s1 = \"%s\"\ns2 = \"%s\"\n", s1.c_str(), s2.c_str()); if (inexact) { int dist = lDistance(s1, s2); if (dist < lowestDist) { lowestDist = dist; lowestCommentList = j; } ++j; } else if (s1 == s2) { (*j).second->push_back(comm); SymTab::mapped_type::iterator jj = j; ++j; protos->erase(jj); innerFound = true; break; } else { ++j; } } if (lowestDist != INT_MAX) { (*lowestCommentList).second->push_back(comm); protos->erase(lowestCommentList); innerFound = true; } if (innerFound) { list<DoxygenComment *>::iterator ii = i; ++i; commentList.erase(ii); innerFound = false; } else { ++i; } } inexact = !inexact; } while (inexact); #if 0 //Print out the current symbol table for( SymTab::iterator iItr = symTab.begin(); iItr != symTab.end(); ++iItr ) { std::cout << "first loop" << std::endl; SymTab::mapped_type::iterator jItr = iItr->second.begin(); for(; jItr != iItr->second.end(); ++jItr) { std::cout << "second loop" << std::endl; for(std::list<DoxygenComment*>::iterator kItr = (*jItr).second->begin(); kItr != (*jItr).second->end(); ++kItr) { std::cout << "third loop" << std::endl; std::cout << "symTab: " << (*kItr)->originalComment->getString() << std::endl; } } } #endif /* any remaining comments in the list do not correspond to an existing symbol */ for (list<DoxygenComment *>::iterator i = commentList.begin(); i != commentList.end(); ++i) { printf("%s:%d: warning: comment does not match a symbol\n\tprototype is: %s\n", (*i)->originalNode->get_file_info()->get_filenameString().c_str(), (*i)->originalComment->getLineNumber(), (*i)->entry.prototype().c_str()); delete *i; } }
CodeBlock* GlobalEntry::codeGen(){ CodeBlock* main_block = new CodeBlock(); //--------------Init stack and base pointers-------------- ICode set_stack(ICode::ICodeType::MOVI,new Value(0,Type::TypeTag::UINT),&MemoryMgr::stackPointerRegister()); ICode set_base(ICode::ICodeType::MOVI,new Value(0,Type::TypeTag::UINT),&MemoryMgr::basePointerRegister()); main_block->append(set_stack); main_block->append(set_base); //----------------------Declarations---------------------- //Loops over all declarations SymTab* st = this->symTab(); //Separates FunctionEntries from the other types vector<CodeBlock*> function_blocks; vector<CodeBlock*> other_blocks; for(SymTab::iterator i = st->begin(); i != st->end(); ++i){ CodeBlock* cb = (*i)->codeGen(); if((*i)->kind() == SymTabEntry::Kind::FUNCTION_KIND){ function_blocks.push_back(cb); } else { other_blocks.push_back(cb); } } for(unsigned int x = 0; x < other_blocks.size();++x){ main_block->append(other_blocks[x]); } ICode jmp_start(ICode::ICodeType::JMP,parse_label_); main_block->append(jmp_start); for(unsigned int x = 0; x < function_blocks.size();++x){ main_block->append(function_blocks[x]); } //---------------------Event Matching--------------------- // Reads in character CodeBlock* input_block = new CodeBlock(); ICode read_in(ICode::ICodeType::IN,&in_reg_); //If negative, then reached end of file ICode* check_neg = new ICode(ICode::ICodeType::GT,new Value(0,Type::TypeTag::INT),&in_reg_); ICode end_jmp(ICode::ICodeType::JMPC,check_neg,end_label_); input_block->append(read_in); input_block->append(end_jmp); input_block->setStartLabel(parse_label_); CodeBlock* rule_block; // Named rules for(unsigned int i = 0; i < rule_names_.size(); ++i){ rule_block = new CodeBlock(); // Moves the string constant to the register ICode mov_string(ICode::ICodeType::MOVI,new Value((int)(rule_names_[i].at(0)),Type::TypeTag::INT),&comp_reg_); // Comparison ICode* compare = new ICode(ICode::ICodeType::EQ,&comp_reg_,&in_reg_); //Conditionally jumps ICode jmpc(ICode::ICodeType::JMPC,compare,rule_labels_[i]); rule_block->append(mov_string); rule_block->append(jmpc); rule_block->setEndLabel(rule_return_labels_[i]); input_block->append(rule_block); } // "Any" rules for(unsigned int i = 0; i < any_labels_.size(); ++i){ rule_block = new CodeBlock(); //Jumps to any rule body ICode jmp(ICode::ICodeType::JMP,any_labels_[i]); rule_block->append(jmp); rule_block->setEndLabel(any_return_labels_[i]); input_block->append(rule_block); } input_block->append(jmp_start); main_block->append(input_block); //------------------------Rules------------------------ //Loops over all Rules for(unsigned int x = 0; x < rules_.size();++x){ main_block->append(rules_[x]->codeGen()); } //---------------------End program--------------------- //Do the end jump here CodeBlock* end_block = new CodeBlock(); ICode print_end(ICode::ICodeType::PRTS,new Value("PROGRAM END\\n")); end_block->setStartLabel(end_label_); end_block->append(print_end); main_block->append(end_block); return main_block; }