Esempio n. 1
0
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;
}
Esempio n. 2
0
/*  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";
}
Esempio n. 3
0
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());
				}
			}
		}
	}
}
Esempio n. 4
0
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_);
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
    }

}
Esempio n. 7
0
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;
}