Beispiel #1
0
static int EndTry( void )
{
    int         parent_scope;
    TREEPTR     expr;
    TREEPTR     func;
    TREEPTR     tree;
    TYPEPTR     typ;
    int         expr_type;

    DropBreakLabel();           /* _leave jumps to this label */
    parent_scope = BlockStack->parent_index;
    tree = LeafNode( OPR_TRY );
    tree->op.st.try_index = BlockStack->try_index;
    tree->op.st.parent_scope = parent_scope;
    AddStmt( tree );
    if( (CurToken == T__EXCEPT) || (CurToken == T___EXCEPT) ) {
        NextToken();
        BlockStack->block_type = T__EXCEPT;
        BlockStack->break_label = NextLabel();
        Jump( BlockStack->break_label );
        DeadCode = 0;
        tree = LeafNode( OPR_EXCEPT );
        tree->op.st.try_sym_handle = DummyTrySymbol();
        tree->op.st.parent_scope = parent_scope;
        AddStmt( tree );
        CompFlags.exception_filter_expr = 1;
        expr = RValue( BracketExpr() );
        CompFlags.exception_filter_expr = 0;
        CompFlags.exception_handler = 1;
        typ = TypeOf( expr );
        expr_type = DataTypeOf( typ );
        if( expr_type != TYPE_VOID ) {
            if( expr_type > TYPE_ULONG ) {
                CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
            }
        }
        func = VarLeaf( SymGetPtr( SymExcept ), SymExcept );
        func->op.opr = OPR_FUNCNAME;
        expr = ExprNode( NULL, OPR_PARM, expr );
        expr->expr_type = typ;
        expr->op.result_type = typ;
        tree = ExprNode( func, OPR_CALL, expr );
        tree->expr_type = GetType( TYPE_VOID );
        AddStmt( tree );
        return( 1 );
    } else if( (CurToken == T__FINALLY) || (CurToken == T___FINALLY) ) {
        CompFlags.in_finally_block = 1;
        NextToken();
        BlockStack->block_type = T__FINALLY;
        DeadCode = 0;
        tree = LeafNode( OPR_FINALLY );
        tree->op.st.try_sym_handle = DummyTrySymbol();
        tree->op.st.parent_scope = parent_scope;
        AddStmt( tree );
        return( 1 );
    }
    return( 0 );
}
Beispiel #2
0
static void AddCaseLabel( unsigned long value )
{
    CASEPTR         ce, prev_ce, new_ce;
    unsigned long   old_value, converted_value;
    TREEPTR         tree;
    char            buffer[12];

    prev_ce = NULL;
#if 0
    leaf.u.ulong_konst = value;
    leaf.data_type = SwitchStack->case_type;
    SetLeafType( &leaf, 1 );
//      converted_value = value & SwitchStack->case_mask;
    converted_value = leaf.u.ulong_konst;
#else
    converted_value = value;
#endif
    old_value = converted_value + 1;  /* make old_value different */
    for( ce = SwitchStack->case_list; ce; ce = ce->next_case ) {
        old_value = ce->value;
        if( old_value >= converted_value ) break;
        prev_ce = ce;
    }
    if( converted_value == old_value ) {   /* duplicate case value found */
        sprintf( buffer, SwitchStack->case_format, value );
        CErr2p( ERR_DUPLICATE_CASE_VALUE, buffer );
    } else {
        new_ce = (CASEPTR)CMemAlloc( sizeof( CASEDEFN ) );
        new_ce->value = converted_value;
        if( prev_ce == NULL ) {
            new_ce->next_case = SwitchStack->case_list;
            SwitchStack->case_list = new_ce;
        } else {
            prev_ce->next_case = new_ce;
            new_ce->next_case = ce;
        }
        /* Check if the previous statement was a 'case'. If so, reuse the label, as generating
         * too many labels seriously slows down code generation.
         */
        if( prev_ce && LastStmt->op.opr == OPR_STMT && LastStmt->right->op.opr == OPR_CASE ) {
            new_ce->label = SwitchStack->last_case_label;
            new_ce->gen_label = FALSE;
        } else {
            new_ce->label = NextLabel();
            new_ce->gen_label = TRUE;
        }
        SwitchStack->number_of_cases++;
        if( converted_value < SwitchStack->low_value ) {
            SwitchStack->low_value = converted_value;
        }
        if( converted_value > SwitchStack->high_value ) {
            SwitchStack->high_value = converted_value;
        }
        SwitchStack->last_case_label = new_ce->label;
        tree = LeafNode( OPR_CASE );
        tree->op.case_info = new_ce;
        AddStmt( tree );
    }
}
Beispiel #3
0
static void DropLabel( LABEL_INDEX label )
{
    TREEPTR     tree;

    CompFlags.label_dropped = 1;
    DeadCode = 0;
    tree = LeafNode( OPR_LABEL );
    tree->op.label_index = label;
    AddStmt( tree );
}
Beispiel #4
0
static void Jump( LABEL_INDEX label )
{
    TREEPTR     tree;

    if( ! DeadCode ) {
        tree = LeafNode( OPR_JUMP );
        tree->op.label_index = label;
        AddStmt( tree );
        DeadCode = 1;
    }
}
Beispiel #5
0
static void SetFuncReturnNode( TREEPTR tree )
{
    TYPEPTR     typ;

    typ = CurFunc->sym_type->object;
    tree->expr_type = typ;
    SKIP_TYPEDEFS( typ );
    if( typ->decl_type == TYPE_STRUCT || typ->decl_type == TYPE_UNION ) {
        tree->right = LeafNode( OPR_NOP );      // place holder
        tree->right->expr_type = NULL;
    }
}
Beispiel #6
0
static void UnWindTry( int try_scope )
{
#ifdef __SEH__
    TREEPTR     tree;

    tree = LeafNode( OPR_UNWIND );
    tree->op.st.try_index = try_scope;
    AddStmt( tree );
#else
    try_scope = try_scope;
#endif
}
NS_IMETHODIMP
nsLoggingSink::AddLeaf(const nsIParserNode& aNode) {
  LeafNode(aNode);

  nsresult theResult=NS_OK;

  //then proxy the call to the real sink if you have one.
  if(mSink) {
    theResult=mSink->AddLeaf(aNode);
  }
  
  return theResult;

} 
Beispiel #8
0
/*
================
BuildTree_r
================
*/
node_t *BuildTree_r (node_t *node, bspbrush_t *brushes)
{
	node_t		*newnode;
	side_t		*bestside;
	int			i;
	bspbrush_t	*children[2];

	if (numthreads == 1)
		c_nodes++;

	if (drawflag)
		DrawBrushList (brushes, node);

	// find the best plane to use as a splitter
	bestside = SelectSplitSide (brushes, node);
	if (!bestside)
	{
		// leaf node
		node->side = NULL;
		node->planenum = -1;
		LeafNode (node, brushes);
		return node;
	}

	// this is a splitplane node
	node->side = bestside;
	node->planenum = bestside->planenum & ~1;	// always use front facing

	SplitBrushList (brushes, node, &children[0], &children[1]);
	FreeBrushList (brushes);

	// allocate children before recursing
	for (i=0 ; i<2 ; i++)
	{
		newnode = AllocNode ();
		newnode->parent = node;
		node->children[i] = newnode;
	}

	SplitBrush (node->volume, node->planenum, &node->children[0]->volume,
		&node->children[1]->volume);

	// recursively process children
	for (i=0 ; i<2 ; i++)
	{
		node->children[i] = BuildTree_r (node->children[i], children[i]);
	}

	return node;
}
Beispiel #9
0
static node_t *BuildTree_r (node_t *node, bspbrush_t *brushes)
{
	node_t *newnode;
	side_t *bestside;
	int i;
	bspbrush_t *children[2];

	if (threadstate.numthreads == 1)
		c_nodes++;

	/* find the best plane to use as a splitter */
	bestside = SelectSplitSide(brushes, node->volume);
	if (!bestside) {
		/* leaf node */
		LeafNode(node, brushes);
		Verb_Printf(VERB_DUMP, "BuildTree_r: Created a leaf node.\n");
		return node;
	}
	/* make sure the selected plane hasn't been used before. */
	CheckPlaneAgainstParents(bestside->planenum, node);

	Verb_Printf(VERB_DUMP, "BuildTree_r: splitting along plane %i\n", (int)bestside->planenum);

	/* this is a splitplane node */
	node->side = bestside;
	node->planenum = bestside->planenum & ~1;	/* always use front facing */

	SplitBrushList(brushes, node->planenum, &children[0], &children[1]);
	FreeBrushList(brushes);

	/* allocate children before recursing */
	for (i = 0; i < 2; i++) {
		newnode = AllocNode();
		newnode->parent = node;
		node->children[i] = newnode;
	}

	SplitBrush(node->volume, node->planenum, &node->children[0]->volume,
		&node->children[1]->volume);

	/* recursively process children */
	for (i = 0; i < 2; i++) {
		node->children[i] = BuildTree_r(node->children[i], children[i]);
	}

	return node;
}
Beispiel #10
0
static void ForStmt( void )
{
    bool    parsed_semi_colon = FALSE;

    NextToken();
    MustRecog( T_LEFT_PAREN );
    if( CompFlags.c99_extensions ) {
        PushBlock();    // 'for' opens new scope
    }
    if( CurToken != T_SEMI_COLON ) {
        if( CompFlags.c99_extensions ) {
            TREEPTR     tree;

            tree = LeafNode( OPR_NEWBLOCK );
            AddStmt( tree );
            BlockStack->gen_endblock = TRUE;
            if( !LoopDecl( &BlockStack->sym_list ) ) {
                ChkStmtExpr();      // no declarator, try init_expr
            } else {
                parsed_semi_colon = TRUE;   // LoopDecl ate it up
            }
            tree->op.sym_handle = BlockStack->sym_list;
        } else {
            ChkStmtExpr();          // init_expr
        }
    }
    if( !parsed_semi_colon ) {
        MustRecog( T_SEMI_COLON );
    }
    NewLoop();
    BlockStack->block_type = T_FOR;
    if( CurToken != T_SEMI_COLON ) {
        BlockStack->break_label = NextLabel();
        if( !JumpFalse( Expr(), BlockStack->break_label ) ) {
            BlockStack->break_label = 0;        /* 09-sep-92 */
        }
    }
    MustRecog( T_SEMI_COLON );
    BlockStack->inc_var = NULL;
    if( CurToken != T_RIGHT_PAREN ) {
        BlockStack->inc_var = Expr();                   // save this
        if( CompFlags.meaningless_stmt == 1 ) {
            ChkUseful();
        }
    }
    MustRecog( T_RIGHT_PAREN );
}
Beispiel #11
0
static void PopBlock( void )
{
    BLOCKPTR    block;
    TREEPTR     tree;

    if( BlockStack->gen_endblock ) {
        tree = LeafNode( OPR_ENDBLOCK );
        tree->op.sym_handle = BlockStack->sym_list;
        AddStmt( tree );
    }
    if( BlockStack->sym_list != 0 ) {
        AddSymList( BlockStack->sym_list );
    }
    block = BlockStack;
    LoopStack = block->prev_loop;
    BlockStack = block->prev_block;
    CMemFree( block );
}
Beispiel #12
0
void SphericalQuadTree::_buildTree(const int nodeid, 
		const Vector3d &p0, const int i0, const Vector3d &p1, const int i1, const Vector3d &p2, const int i2, 
		const int level, const int maxlevel)
{
	if (level>=maxlevel){
		m_leaves[nodeid] = LeafNode(i0, i1, i2);
		return;
	}
	Vector3d n[4];
	short int t[4]; 
	//allocate nodes or leaves
	if (level<maxlevel-1){
		NoneLeafNode _tt;
		t[0] = m_nodes.size(); m_nodes.push_back(_tt);
		t[1] = m_nodes.size(); m_nodes.push_back(_tt);
		t[2] = m_nodes.size(); m_nodes.push_back(_tt);
		t[3] = m_nodes.size(); m_nodes.push_back(_tt);
	}
	else{
		LeafNode _tt;
		t[0] = m_leaves.size(); m_leaves.push_back(_tt);
		t[1] = m_leaves.size(); m_leaves.push_back(_tt);
		t[2] = m_leaves.size(); m_leaves.push_back(_tt);
		t[3] = m_leaves.size(); m_leaves.push_back(_tt);
	}
	//construct the information for node itself
	const Vector3d q0 = midpoint_slerp(p0, p1);
	const Vector3d q1 = midpoint_slerp(p1, p2);
	const Vector3d q2 = midpoint_slerp(p2, p0);
	const int j0 = _getVertexIndex(q0);
	const int j1 = _getVertexIndex(q1);
	const int j2 = _getVertexIndex(q2);
	n[0] = tri_norm(p0, q0, q2);
	n[1] = tri_norm(q0, p1, q1);
	n[2] = tri_norm(q0, q1, q2);
	n[3] = tri_norm(q2, q1, p2);
	m_nodes[nodeid] = NoneLeafNode(n, t);
	//build child nodes
	const int level1 = level+1;
	_buildTree(t[0], p0, i0, q0, j0, q2, j2, level1, maxlevel); 
	_buildTree(t[1], q0, j0, p1, i1, q1, j1, level1, maxlevel); 
	_buildTree(t[2], q0, j0, q1, j1, q2, j2, level1, maxlevel); 
	_buildTree(t[3], q2, j2, q1, j1, p2, i2, level1, maxlevel); 
}
Beispiel #13
0
static void TryStmt( void )
{
    TREEPTR     tree;

    MarkTryVolatile( CurFunc->u.func.parms );
    MarkTryVolatile( CurFunc->u.func.locals );
    CurFuncNode->op.func.flags |=  FUNC_USES_SEH;
    CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
    CurToken = T__TRY;
    StartNewBlock();
    NextToken();
    BlockStack->parent_index = TryScope;
    ++TryCount;
    BlockStack->try_index = TryCount;
    TryScope = TryCount;
    tree = LeafNode( OPR_TRY );
    tree->op.st.try_index = 0;
    tree->op.st.parent_scope = TryCount;
    AddStmt( tree );
}
Beispiel #14
0
void AsmSysMakeInlineAsmFunc( bool too_many_bytes )
/*************************************************/
{
    int                 code_length;
    SYM_HANDLE          sym_handle;
    TREEPTR             tree;
    bool                uses_auto;
    char                name[8];

    /* unused parameters */ (void)too_many_bytes;

    code_length = AsmCodeAddress;
    if( code_length != 0 ) {
        sprintf( name, "F.%d", AsmFuncNum );
        ++AsmFuncNum;
        CreateAux( name );
        CurrInfo = (aux_info *)CMemAlloc( sizeof( aux_info ) );
        *CurrInfo = WatcallInfo;
        CurrInfo->use = 1;
        CurrInfo->save = AsmRegsSaved;  // indicate no registers saved
        uses_auto = InsertFixups( AsmCodeBuffer, code_length, &CurrInfo->code );
        if( uses_auto ) {
            /*
               We want to force the calling routine to set up a [E]BP frame
               for the use of this pragma. This is done by saying the pragma
               modifies the [E]SP register. A kludge, but it works.
            */
            HW_CTurnOff( CurrInfo->save, HW_SP );
        }
        CurrEntry->info = CurrInfo;
        CurrEntry->next = AuxList;
        AuxList = CurrEntry;
        CurrEntry = NULL;
        sym_handle = MakeFunction( name, FuncNode( GetType( TYPE_VOID ), FLAG_NONE, NULL ) );
        tree = LeafNode( OPR_FUNCNAME );
        tree->op.u2.sym_handle = sym_handle;
        tree = ExprNode( tree, OPR_CALL, NULL );
        tree->u.expr_type = GetType( TYPE_VOID );
        AddStmt( tree );
    }
}
Beispiel #15
0
static void LeftBrace( void )
{
    TREEPTR     tree;

    /*
        <storage> <type> function( <parms> )
        {   <- this is SymLevel == 1
        (weird code is for SymLevel > 1 )
    */
    // DeclList might generate some quads to do some initializers
    // if that happens, we want them output after the OPR_NEWBLOCK node
    StartNewBlock();
    NextToken();
    ++SymLevel;
    tree = LeafNode( OPR_NEWBLOCK );
    AddStmt( tree );
    BlockStack->sym_list = 0;
    BlockStack->gen_endblock = TRUE;
    DeclList( &BlockStack->sym_list );
    tree->op.sym_handle = BlockStack->sym_list;
}
Beispiel #16
0
void GenFunctionNode( SYM_HANDLE sym_handle )
{
    TREEPTR     tree;
    SYMPTR      sym;

    tree = LeafNode( OPR_FUNCTION );
    sym = SymGetPtr( sym_handle );
    tree->op.func.sym_handle = sym_handle;
    tree->op.func.flags = FUNC_NONE;
    if( ( Toggles & TOGGLE_INLINE ) | ( sym->attrib & FLAG_INLINE ) ) {
        if( !sym->naked ) {
            if( strcmp( sym->name, "main" ) != 0 ) {
                tree->op.func.flags |= FUNC_OK_TO_INLINE;
            }
        }
    }
    tree->op.flags = OpFlags( sym->attrib );
    tree->expr_type = sym->sym_type->object;    // function return type
    AddStmt( tree );
    // Evil, evil globals! But we need this for later lookups in cgen.c
    sym->u.func.start_of_func = LastStmt;
    CurFuncNode = tree;
    NodeCount = 0;
}
Beispiel #17
0
//thread function, gets nodes from the nodelist and processes them
void BuildTreeThread( int threadid ) {
	node_t *newnode, *node;
	side_t *bestside;
	int i, totalmem;
	bspbrush_t *brushes;

	for ( node = NextNodeFromList(); node; )
	{
		//if the nodelist isn't empty try to add another thread
		//if (NodeListSize() > 10) AddThread(BuildTreeThread);
		//display the number of nodes processed so far
		if ( numthreads == 1 ) {
			IncreaseNodeCounter();
		}

		brushes = node->brushlist;

		if ( numthreads == 1 ) {
			totalmem = WindingMemory() + c_nodememory + c_brushmemory;
			if ( totalmem > c_peak_totalbspmemory ) {
				c_peak_totalbspmemory = totalmem;
			} //end if
			c_nodes++;
		} //endif

		if ( drawflag ) {
			DrawBrushList( brushes, node );
		} //end if

		if ( cancelconversion ) {
			bestside = NULL;
		} //end if
		else
		{
			// find the best plane to use as a splitter
			bestside = SelectSplitSide( brushes, node );
		} //end else
		  //if there's no split side left
		if ( !bestside ) {
			//create a leaf out of the node
			LeafNode( node, brushes );
			if ( node->contents & CONTENTS_SOLID ) {
				c_solidleafnodes++;
			}

			if ( create_aas ) {
				//free up memory!!!
				FreeBrushList( node->brushlist );
				node->brushlist = NULL;
			} //end if
			  //free the node volume brush (it is not used anymore)
			if ( node->volume ) {
				FreeBrush( node->volume );
				node->volume = NULL;
			} //end if
			node = NextNodeFromList();
			continue;
		} //end if

		// this is a splitplane node
		node->side = bestside;
		node->planenum = bestside->planenum & ~1;   //always use front facing

		//allocate children
		for ( i = 0; i < 2; i++ )
		{
			newnode = AllocNode();
			newnode->parent = node;
			node->children[i] = newnode;
		} //end for

		//split the brush list in two for both children
		SplitBrushList( brushes, node, &node->children[0]->brushlist, &node->children[1]->brushlist );

		CheckBrushLists( node->children[0]->brushlist, node->children[1]->brushlist );
		//free the old brush list
		FreeBrushList( brushes );
		node->brushlist = NULL;

		//split the volume brush of the node for the children
		SplitBrush( node->volume, node->planenum, &node->children[0]->volume,
					&node->children[1]->volume );

		if ( !node->children[0]->volume || !node->children[1]->volume ) {
			Error( "child without volume brush" );
		} //end if

		//free the volume brush
		if ( node->volume ) {
			FreeBrush( node->volume );
			node->volume = NULL;
		} //end if

		//add both children to the node list
		//AddNodeToList(node->children[0]);
		AddNodeToList( node->children[1] );
		node = node->children[0];
	} //end while
	RemoveThread( threadid );
} //end of the function BuildTreeThread
Beispiel #18
0
static void EndOfStmt( void )
{
    do {
        switch( BlockStack->block_type ) {
        case T_LEFT_BRACE:
            EndBlock();
            break;
        case T_IF:
            if( CurToken == T_ELSE ) {
                ElseStmt();
                return;
            }
            DropBreakLabel();
            break;
        case T_ELSE:
            DropBreakLabel();
            break;
        case T_WHILE:
            DropContinueLabel();
            Jump( BlockStack->top_label );
            --LoopDepth;
            DropBreakLabel();
            break;
        case T_FOR:
            EndForStmt();
            --LoopDepth;
            DropBreakLabel();
            if( CompFlags.c99_extensions ) {
                EndBlock();     /* Terminate the scope introduced by 'for' */
                PopBlock();
            }
            break;
        case T_DO:
            DropContinueLabel();
            MustRecog( T_WHILE );
            SrcLoc = TokenLoc;
            JumpTrue( BracketExpr(), BlockStack->top_label );
            MustRecog( T_SEMI_COLON );
            SrcLoc = TokenLoc;
            --LoopDepth;
            DropBreakLabel();
            break;
        case T_SWITCH:
            EndSwitch();
            DropBreakLabel();
            break;
#ifdef __SEH__
        case T__TRY:
        case T___TRY:
            if( EndTry() )
                return;
            break;
        case T__EXCEPT:
        case T___EXCEPT:
            DropBreakLabel();
            TryScope = BlockStack->parent_index;
            CompFlags.exception_handler = 0;
            break;
        case T__FINALLY:
        case T___FINALLY:
            AddStmt( LeafNode( OPR_END_FINALLY ) );
            CompFlags.in_finally_block = 0;
            TryScope = BlockStack->parent_index;
            break;
#endif
        }
        PopBlock();
        if( BlockStack == NULL ) break;
    } while( BlockStack->block_type != T_LEFT_BRACE );
}
Beispiel #19
0
void Statement( void )
{
    LABEL_INDEX         end_of_func_label;
    SYM_HANDLE          func_result;
    TREEPTR             tree;
    bool                return_at_outer_level;
    bool                skip_to_next_token;
    bool                declaration_allowed;
    struct return_info  return_info;
    SYM_ENTRY           sym;

#ifndef NDEBUG
    if( DebugFlag >= 1 ) {
        printf( "***** line %u, func=%s\n", TokenLoc.line, CurFunc->name );
        PrintStats();
    }
#endif
    ++FuncCount;
    return_info.with = RETURN_WITH_NONE; /* indicate no return statements */
    return_info.with_expr = FALSE;
    CompFlags.label_dropped = 0;
    CompFlags.addr_of_auto_taken = 0;           /* 23-oct-91 */
    end_of_func_label = 0;
    return_at_outer_level = FALSE;              /* 28-feb-92 */
    declaration_allowed   = FALSE;
    DeadCode = 0;
    LoopDepth = 0;
    LabelIndex = 0;
    BlockStack = NULL;
    LoopStack = NULL;
    SwitchStack = NULL;
#ifdef __SEH__
    TryCount = -1;
    TryScope = -1;
#endif
    StartNewBlock();
    NextToken();                        // skip over {
    ++SymLevel;
    tree = LeafNode( OPR_LABELCOUNT );
    AddStmt( tree );
    if( GrabLabels() == 0 ) {                           /* 29-nov-94 */
        GetLocalVarDecls();
    }
    func_result = MakeNewSym( &sym, 'R', CurFunc->sym_type->object, SC_AUTO );
    sym.flags |= SYM_FUNC_RETURN_VAR;   /* 25-oct-91 */
    SymReplace( &sym, func_result );
    for( ;; ) {
        CompFlags.pending_dead_code = 0;
        if( GrabLabels() == 0 && declaration_allowed && IsDeclarator( CurToken ) ) {
            GetLocalVarDecls();
        }
        if( CompFlags.c99_extensions ) {
            declaration_allowed = TRUE;
        }
        skip_to_next_token = FALSE;
        switch( CurToken ) {
        case T_IF:
            StartNewBlock();
            NextToken();
            BlockStack->break_label = NextLabel();
            JumpFalse( BracketExpr(), BlockStack->break_label );
            /* 23-dec-88, only issue msg if ';' is on same line as 'if' */
            if( CurToken == T_SEMI_COLON  &&  SrcLoc.line == TokenLoc.line && SrcLoc.fno == TokenLoc.fno ) {
                SetErrLoc( &TokenLoc );
                NextToken();    /* look ahead for else keyword */
                if( CurToken != T_ELSE ) {              /* 02-apr-91 */
                    ChkUseful();                        /* 08-dec-88 */
                }
                InitErrLoc();
                break;
            }
            declaration_allowed = FALSE;
            continue;
        case T_WHILE:
            NewLoop();
            NextToken();
            BlockStack->break_label = NextLabel();
            if( !JumpFalse( BracketExpr(), BlockStack->break_label ) ) {
                BlockStack->break_label = 0;            /* 09-sep-92 */
            }
            if( CurToken == T_SEMI_COLON ) {            /* 08-dec-88 */
                if( ! CompFlags.useful_side_effect ) {
                    CWarn1( WARN_MEANINGLESS, ERR_MEANINGLESS );
                }
            }
            declaration_allowed = FALSE;
            continue;
        case T_DO:
            NewLoop();
            NextToken();
            if( CurToken == T_RIGHT_BRACE ) {
                CErr1( ERR_STMT_REQUIRED_AFTER_DO );
                break;
            }
            declaration_allowed = FALSE;
            continue;
        case T_FOR:
            ForStmt();
            declaration_allowed = FALSE;
            continue;
        case T_SWITCH:
            SwitchStmt();
            DeadCode = 1;
            declaration_allowed = FALSE;
            continue;
        case T_CASE:
            DeadCode = 0;
            CaseStmt();
            declaration_allowed = FALSE;
            continue;
        case T_DEFAULT:
            DefaultStmt();
            declaration_allowed = FALSE;
            continue;
        case T_BREAK:
            BreakStmt();
            DeadCode = 1;
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
        case T_CONTINUE:
            ContinueStmt();
            DeadCode = 1;
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
#ifdef __SEH__
        case T__LEAVE:
        case T___LEAVE:
            LeaveStmt();
            DeadCode = 1;
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
#endif
        case T_RETURN:
            ReturnStmt( func_result, &return_info );
            if( BlockStack->prev_block == NULL ) {      /* 28-feb-92 */
                return_at_outer_level = TRUE;
            }
            MustRecog( T_SEMI_COLON );
            if( SymLevel != 1  ||  CurToken != T_RIGHT_BRACE  ||
                    BlockStack->block_type != T_LEFT_BRACE ) {
                if( end_of_func_label == 0 ) {
                    end_of_func_label = NextLabel();
                }
                Jump( end_of_func_label );
            }
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
        case T_GOTO:
            GotoStmt();
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
        case T_SEMI_COLON:
            NextToken();
            if( BlockStack->block_type != T_LEFT_BRACE ) {
                if( CurToken == T_ELSE ) {
                    declaration_allowed = FALSE;
                }
                break;
            }
            continue;
        case T_LEFT_BRACE:
            LeftBrace();
            continue;
        case T_RIGHT_BRACE:
            if( BlockStack->block_type != T_LEFT_BRACE ) {
                CErr1( ERR_MISPLACED_RIGHT_BRACE );
            }
            if( BlockStack->prev_block == NULL ) {
                skip_to_next_token = TRUE;
            } else {
                NextToken();
            }
            break;
        case T_EXTERN:
        case T_STATIC:
        case T_AUTO:
        case T_REGISTER:
        case T_VOID:
        case T_CHAR:
        case T_SHORT:
        case T_INT:
        case T_LONG:
        case T_FLOAT:
        case T_DOUBLE:
        case T_SIGNED:
        case T_UNSIGNED:
            if( CompFlags.c99_extensions )
                CErr1( ERR_UNEXPECTED_DECLARATION );
            else
                CErr1( ERR_MISSING_RIGHT_BRACE );
            break;
        case T_EOF:
            CErr1( ERR_MISSING_RIGHT_BRACE );
            break;
#ifdef __SEH__
        case T__TRY:
        case T___TRY:
            TryStmt();
            continue;
#endif
        case T___ASM:
            AsmStmt();
            continue;
        default:
            if( DeadCode == 1 ) {
                DeadMsg();
            }
            StmtExpr();
            if( BlockStack->block_type != T_LEFT_BRACE ) break;
            continue;
        }
        EndOfStmt();
        if( BlockStack == NULL ) break;
        if( skip_to_next_token ) {
            NextToken();
        }
    }
    /* C99 has special semantics for return value of main() */
    if( CompFlags.c99_extensions && !strcmp( CurFunc->name, "main" ) ) {
        if( !return_at_outer_level ) {
            FixupC99MainReturn( func_result, &return_info );
            return_at_outer_level = TRUE;
        }
    }
    if( !return_info.with_expr ) {   /* no return values present */
        if( !DeadCode && !CurFunc->naked ) {
            ChkRetValue();
        }
    } else if( ! return_at_outer_level ) {              /* 28-feb-92 */
        if( ! DeadCode && !CurFunc->naked ) {
            CWarn( WARN_MISSING_RETURN_VALUE,
                   ERR_MISSING_RETURN_VALUE, CurFunc->name );
        }
    }
    if( end_of_func_label != 0 ) {
        DropLabel( end_of_func_label );
    }
    DeadCode = 0;
    tree->op.label_count = LabelIndex;
    tree = LeafNode( OPR_FUNCEND );
    if( !return_info.with_expr ) {
        tree->expr_type = NULL;
        tree->op.sym_handle = 0;
    } else {
        tree->op.sym_handle = func_result;
        SetFuncReturnNode( tree );
    }
    AddStmt( tree );
    AddSymList( CurFunc->u.func.locals );
    SrcLoc = TokenLoc;
    FreeLabels();
    if( skip_to_next_token ) {
        NextToken();
    }
    if( CompFlags.generate_prototypes ) {
        if( DefFile == NULL ) {
            OpenDefFile();
        }
        if( DefFile != NULL && CurFunc->stg_class == SC_NULL ) {
            /* function exported */
            DumpFuncDefn();
        }
    }

    if( Toggles & TOGGLE_INLINE ) {
        if( Inline_Threshold < NodeCount ) {
            CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
        }
    }
    if( VarParm( CurFunc ) ) {
        CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
    }
    NodeCount = 0;
    if( CompFlags.addr_of_auto_taken ) {                /* 23-oct-91 */
        CurFunc->flags &= ~ SYM_OK_TO_RECURSE;
    }
}
Beispiel #20
0
node_t *BuildTree_r( node_t *node, bspbrush_t *brushes ) {
	node_t      *newnode;
	side_t      *bestside;
	int i, totalmem;
	bspbrush_t  *children[2];

	qprintf( "\r%6d", numrecurse );
	numrecurse++;

	if ( numthreads == 1 ) {
		totalmem = WindingMemory() + c_nodememory + c_brushmemory;
		if ( totalmem > c_peak_totalbspmemory ) {
			c_peak_totalbspmemory = totalmem;
		}
		c_nodes++;
	} //endif

	if ( drawflag ) {
		DrawBrushList( brushes, node );
	}

	// find the best plane to use as a splitter
	bestside = SelectSplitSide( brushes, node );
	if ( !bestside ) {
		// leaf node
		node->side = NULL;
		node->planenum = -1;
		LeafNode( node, brushes );
		if ( node->contents & CONTENTS_SOLID ) {
			c_solidleafnodes++;
		}
		if ( create_aas ) {
			//free up memory!!!
			FreeBrushList( node->brushlist );
			node->brushlist = NULL;
			//free the node volume brush
			if ( node->volume ) {
				FreeBrush( node->volume );
				node->volume = NULL;
			} //end if
		} //end if
		return node;
	} //end if

	// this is a splitplane node
	node->side = bestside;
	node->planenum = bestside->planenum & ~1;   // always use front facing

	//split the brush list in two for both children
	SplitBrushList( brushes, node, &children[0], &children[1] );
	//free the old brush list
	FreeBrushList( brushes );

	// allocate children before recursing
	for ( i = 0; i < 2; i++ )
	{
		newnode = AllocNode();
		newnode->parent = node;
		node->children[i] = newnode;
	} //end for

	//split the volume brush of the node for the children
	SplitBrush( node->volume, node->planenum, &node->children[0]->volume,
				&node->children[1]->volume );

	if ( create_aas ) {
		//free the volume brush
		if ( node->volume ) {
			FreeBrush( node->volume );
			node->volume = NULL;
		} //end if
	} //end if
	  // recursively process children
	for ( i = 0; i < 2; i++ )
	{
		node->children[i] = BuildTree_r( node->children[i], children[i] );
	} //end for

	return node;
} //end of the function BuildTree_r