SNode SNode::multiplyStmtList() const {
  ENTERMETHOD();
  CHECKNODETYPE(*this,NT_STMTLIST);
  const SNodeArray &a = getChildArray();
  SNodeArray        newChildArray(a.getTree(),a.size());
  for(size_t i = 0; i < a.size(); i++) {
    newChildArray.add(a[i].multiplyParentheses());
  }
  SNode result = stmtList(newChildArray);
  RETURNNODE( result );
}
Пример #2
0
  void program () {

    std::cout << "\nIn program\n" ;
    match (scanner::BeginSym);

    stmtList ();

    match (scanner::EndSym);

    std::cout << "\nEnd program\n";

  }
Пример #3
0
  void stmtList () {
    std::cout << "\nIn stmtList\n" ;
    statement ();

    nextToken = getNextToken();

    switch (nextToken) {

      case (scanner::Id) :
      case (scanner::ReadSym) :
      case (scanner::WriteSym) :

        stmtList();
        break;

    }

    std::cout << "\nEnd stmtList\n";

  }
Пример #4
0
	clang::StmtResult InsiemeSema::ActOnCompoundStmt(clang::SourceLocation L, clang::SourceLocation R, llvm::ArrayRef<clang::Stmt*> Elts, bool isStmtExpr) {
		// we parse the original code segment, within the original locations
		StmtResult&& ret = Sema::ActOnCompoundStmt(L, R, std::move(Elts), isStmtExpr);
		clang::CompoundStmt* CS = cast<clang::CompoundStmt>(ret.get());
		
		// This is still buggy as of Clang 3.6.2:
		// when pragmas are just after the beginning of a compound stmt, example:
		// {
		// 		#pragma xxx
		// 		...
		// }
		// the location of the opening bracket is wrong because of a bug in the clang parser.
		//
		// We solve the problem by searching for the bracket in the input stream and overwrite
		// the value of L (which contains the wrong location) with the correct value.

		enum { MacroIDBit = 1U << 31 }; // from clang/Basic/SourceLocation.h for use with cpp classes
		{
			SourceLocation&& leftBracketLoc = SourceMgr.getImmediateSpellingLoc(L);
			std::pair<FileID, unsigned>&& locInfo = SourceMgr.getDecomposedLoc(leftBracketLoc);
			llvm::StringRef&& buffer = SourceMgr.getBufferData(locInfo.first);
			const char* strData = buffer.begin() + locInfo.second;
			char const* lBracePos = strbchr(strData, buffer.begin(), '{');

			// We know the location of the left bracket, we overwrite the value of L with the correct location
			// but only if the location is valid as in getFileLocWithOffset() in SourceLocation
			if((((leftBracketLoc.getRawEncoding() & ~MacroIDBit) + (lBracePos - strData)) & MacroIDBit) == 0) {
				L = leftBracketLoc.getLocWithOffset(lBracePos - strData);
			}
		}

		// For the right bracket, we start at the final statement in the compound 
		//   (or its start if it is empty) and search forward until we find the first "}"
		// Otherwise, cases such as this:
		//
		// {
		//    bla();
		// }
		// #pragma test expect_ir(R"( {} )")
		//
		// will be broken

		{
			SourceLocation rightBracketLoc;
			if(CS->size() == 0) {
				rightBracketLoc = SourceMgr.getImmediateSpellingLoc(L);
			} else {
				rightBracketLoc = SourceMgr.getImmediateSpellingLoc(CS->body_back()->getLocEnd());
			}
			std::pair<FileID, unsigned>&& locInfo = SourceMgr.getDecomposedLoc(rightBracketLoc);
			llvm::StringRef buffer = SourceMgr.getBufferData(locInfo.first);
			const char* strData = buffer.begin() + locInfo.second;
			char const* rBracePos = strchr(strData, '}');

			// We know the location of the right bracket, we overwrite the value of R with the correct location
			if((((rightBracketLoc.getRawEncoding() & ~MacroIDBit) + (rBracePos - strData)) & MacroIDBit) == 0) {
				R = rightBracketLoc.getLocWithOffset(rBracePos - strData);
			}
		}
		
		// the source range we inspect is defined by the new source locations,
		// this fix the problem with boundaries jumping to the beginning of the file in
		// the macro expansions:
		//
		//	#define F(x) { }
		//
		//		...
		//
		//		F(r)    // <-this statement will jum to the macro location
		//
		PragmaList matched;
		SourceRange SR(L, R);

		// for each of the pragmas in the range between brackets
		for(PragmaFilter&& filter = PragmaFilter(SR, SourceMgr, pimpl->pending_pragma); *filter; ++filter) {
			PragmaPtr P = *filter;

			unsigned int pragmaStart = utils::Line(P->getStartLocation(), SourceMgr);
			unsigned int pragmaEnd = utils::Line(P->getEndLocation(), SourceMgr);

			bool found = false;
			// problem with first pragma, compound start is delayed until fist usable line (first stmt)
			if(CS->size() > 0) {
				for(clang::CompoundStmt::body_iterator it = CS->body_begin(); it != CS->body_end(); ++it) {
					unsigned int stmtStart = (Line((*it)->getLocStart(), SourceMgr));

					if((pragmaEnd <= stmtStart)) {
						// ACHTUNG: if the node is a nullStmt, and is not at the end of the compound (in
						// which case is most probably ours) we can not trust it. semantics wont change,
						// we move one more. (BUG: nullStmt followed by pragmas, the source begin is
						// postponed until next stmt) this makes pragmas to be attached to a previous
						// stmt
						if(!llvm::isa<clang::NullStmt>(*it)) {
							// this pragma is attached to the current stmt
							P->setStatement(*it);
							matched.push_back(P);
							found = true;
							break;
						}
					}
				}
			}
			if(!found && pragmaStart <= utils::Line(R, SourceMgr)) {
				// this is a de-attached pragma (barrier i.e.) at the end of the compound
				// we need to create a fake NullStmt ( ; ) to attach this
				Stmt** stmts = new Stmt*[CS->size() + 1];

				ArrayRef<clang::Stmt*> stmtList(stmts, CS->size() + 1);

				clang::CompoundStmt* newCS =
				    new(Context) clang::CompoundStmt(Context, stmtList, CS->getSourceRange().getBegin(), CS->getSourceRange().getEnd());

				std::copy(CS->body_begin(), CS->body_end(), newCS->body_begin());
				std::for_each(CS->body_begin(), CS->body_end(), [&](Stmt*& curr) { this->Context.Deallocate(curr); });
				newCS->setLastStmt(new(Context) NullStmt(SourceLocation()));

				P->setStatement(*newCS->body_rbegin());
				matched.push_back(P);

				// transfer the ownership of the statement
				clang::CompoundStmt* oldStmt = ret.getAs<clang::CompoundStmt>();
				oldStmt->setStmts(Context, NULL, 0);
				ret = newCS;
				CS = newCS;

				// destroy the old compound stmt
				Context.Deallocate(oldStmt);
				delete[] stmts;
			}
		}
		// remove matched pragmas
		EraseMatchedPragmas(pimpl->pending_pragma, matched);

		return std::move(ret);
	}