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 ); }
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 ); } }
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 ); }
static void Jump( LABEL_INDEX label ) { TREEPTR tree; if( ! DeadCode ) { tree = LeafNode( OPR_JUMP ); tree->op.label_index = label; AddStmt( tree ); DeadCode = 1; } }
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; } }
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; }
/* ================ 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; }
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; }
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 ); }
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 ); }
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); }
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 ); }
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 ); } }
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; }
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; }
//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
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 ); }
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; } }
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