/src/combine.cpp
C++ | 6211 lines | 4734 code | 653 blank | 824 comment | 1959 complexity | 8b08d7a3f9f4571f94efa23d9bc9df84 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /**
- * @file combine.cpp
- * Labels the chunks as needed.
- *
- * @author Ben Gardner
- * @author Guy Maurel since version 0.62 for uncrustify4Qt
- * October 2015, 2016
- * @license GPL v2+
- */
- #include "combine.h"
- #include "uncrustify_types.h"
- #include "chunk_list.h"
- #include "ChunkStack.h"
- #include "uncrustify.h"
- #include "lang_pawn.h"
- #include "newlines.h"
- #include "prototypes.h"
- #include "tokenize_cleanup.h"
- #include <cstdio>
- #include <cstdlib>
- #include "unc_ctype.h"
- #include <cassert>
- /**
- * Flags everything from the open paren to the close paren.
- *
- * @param po Pointer to the open parenthesis
- * @return The token after the close paren
- */
- static chunk_t *flag_parens(chunk_t *po, UINT64 flags, c_token_t opentype, c_token_t parenttype, bool parent_all);
- /**
- * Mark the parens and colons in:
- * asm volatile ( "xx" : "xx" (l), "yy"(h) : ... );
- *
- * @param pc the CT_ASM item
- */
- static void flag_asm(chunk_t *pc);
- /**
- * Scan backwards to see if we might be on a type declaration
- */
- static bool chunk_ends_type(chunk_t *start);
- /**
- * skip to the final word/type in a :: chain
- * pc is either a word or a ::
- */
- static chunk_t *skip_dc_member(chunk_t *start);
- /**
- * Skips to the start of the next statement.
- */
- static chunk_t *skip_to_next_statement(chunk_t *pc);
- /**
- * Skips everything until a comma or semicolon at the same level.
- * Returns the semicolon, comma, or close brace/paren or NULL.
- */
- static chunk_t *skip_expression(chunk_t *start);
- /**
- * Skips the D 'align()' statement and the colon, if present.
- * align(2) int foo; -- returns 'int'
- * align(4): -- returns 'int'
- * int bar;
- */
- static chunk_t *skip_align(chunk_t *start);
- /**
- * Combines two tokens into {{ and }} if inside parens and nothing is between
- * either pair.
- */
- static void check_double_brace_init(chunk_t *bo1);
- /**
- * Simply change any STAR to PTR_TYPE and WORD to TYPE
- *
- * @param start points to the open paren
- */
- static void fix_fcn_def_params(chunk_t *pc);
- /**
- * We are on a typedef.
- * If the next word is not enum/union/struct, then the last word before the
- * next ',' or ';' or '__attribute__' is a type.
- *
- * typedef [type...] [*] type [, [*]type] ;
- * typedef <return type>([*]func)();
- * typedef <return type>([*]func)(params);
- * typedef <return type>(__stdcall *func)(); Bug # 633 MS-specific extension
- * include the config-file "test/config/MS-calling_conventions.cfg"
- * typedef <return type>func(params);
- * typedef <enum/struct/union> [type] [*] type [, [*]type] ;
- * typedef <enum/struct/union> [type] { ... } [*] type [, [*]type] ;
- */
- static void fix_typedef(chunk_t *pc);
- /**
- * We are on an enum/struct/union tag that is NOT inside a typedef.
- * If there is a {...} and words before the ';', then they are variables.
- *
- * tag { ... } [*] word [, [*]word] ;
- * tag [word/type] { ... } [*] word [, [*]word] ;
- * enum [word/type [: int_type]] { ... } [*] word [, [*]word] ;
- * tag [word/type] [word]; -- this gets caught later.
- * fcn(tag [word/type] [word])
- * a = (tag [word/type] [*])&b;
- *
- * REVISIT: should this be consolidated with the typedef code?
- */
- static void fix_enum_struct_union(chunk_t *pc);
- /**
- * Checks to see if the current paren is part of a cast.
- * We already verified that this doesn't follow function, TYPE, IF, FOR,
- * SWITCH, or WHILE and is followed by WORD, TYPE, STRUCT, ENUM, or UNION.
- *
- * @param start Pointer to the open paren
- */
- static void fix_casts(chunk_t *pc);
- /**
- * CT_TYPE_CAST follows this pattern:
- * dynamic_cast<...>(...)
- *
- * Mark everything between the <> as a type and set the paren parent
- */
- static void fix_type_cast(chunk_t *pc);
- /**
- * We are on the start of a sequence that could be a var def
- * - FPAREN_OPEN (parent == CT_FOR)
- * - BRACE_OPEN
- * - SEMICOLON
- */
- static chunk_t *fix_var_def(chunk_t *pc);
- /**
- * We are on a function word. we need to:
- * - find out if this is a call or prototype or implementation
- * - mark return type
- * - mark parameter types
- * - mark brace pair
- *
- * REVISIT:
- * This whole function is a mess.
- * It needs to be reworked to eliminate duplicate logic and determine the
- * function type more directly.
- * 1. Skip to the close paren and see what is after.
- * a. semicolon - function call or function proto
- * b. open brace - function call (ie, list_for_each) or function def
- * c. open paren - function type or chained function call
- * d. qualifier - function def or proto, continue to semicolon or open brace
- * 2. Examine the 'parameters' to see if it can be a proto/def
- * 3. Examine what is before the function name to see if it is a proto or call
- * Constructor/destructor detection should have already been done when the
- * 'class' token was encountered (see mark_class_ctor).
- */
- static void mark_function(chunk_t *pc);
- /**
- * Checks to see if a series of chunks could be a C++ parameter
- * FOO foo(5, &val);
- *
- * WORD means CT_WORD or CT_TYPE
- *
- * "WORD WORD" ==> true
- * "QUALIFIER ??" ==> true
- * "TYPE" ==> true
- * "WORD" ==> true
- * "WORD.WORD" ==> true
- * "WORD::WORD" ==> true
- * "WORD * WORD" ==> true
- * "WORD & WORD" ==> true
- * "NUMBER" ==> false
- * "STRING" ==> false
- * "OPEN PAREN" ==> false
- *
- * @param start the first chunk to look at
- * @param end the chunk after the last one to look at
- */
- static bool can_be_full_param(chunk_t *start, chunk_t *end);
- /**
- * Changes the return type to type and set the parent.
- *
- * @param pc the last chunk of the return type
- * @param parent_type CT_NONE (no change) or the new parent type
- */
- static void mark_function_return_type(chunk_t *fname, chunk_t *pc, c_token_t parent_type);
- /**
- * Process a function type that is not in a typedef.
- * pc points to the first close paren.
- *
- * void (*func)(params);
- * const char * (*func)(params);
- * const char * (^func)(params); -- Objective C
- *
- * @param pc Points to the first closing paren
- * @return whether a function type was processed
- */
- static bool mark_function_type(chunk_t *pc);
- /**
- * Examines the stuff between braces { }.
- * There should only be variable definitions and methods.
- * Skip the methods, as they will get handled elsewhere.
- */
- static void mark_struct_union_body(chunk_t *start);
- /**
- * We are on the first word of a variable definition.
- * Mark all the variable names with PCF_VAR_1ST and PCF_VAR_DEF as appropriate.
- * Also mark any '*' encountered as a CT_PTR_TYPE.
- * Skip over []. Go until a ';' is hit.
- *
- * Example input:
- * int a = 3, b, c = 2; ## called with 'a'
- * foo_t f = {1, 2, 3}, g = {5, 6, 7}; ## called with 'f'
- * struct {...} *a, *b; ## called with 'a' or '*'
- * myclass a(4);
- */
- static chunk_t *mark_variable_definition(chunk_t *start);
- /**
- * Marks statement starts in a macro body.
- * REVISIT: this may already be done
- */
- static void mark_define_expressions(void);
- static void process_returns(void);
- /**
- * Processes a return statement, labeling the parens and marking the parent.
- * May remove or add parens around the return statement
- *
- * @param pc Pointer to the return chunk
- */
- static chunk_t *process_return(chunk_t *pc);
- /**
- * We're on a 'class' or 'struct'.
- * Scan for CT_FUNCTION with a string that matches pclass->str
- */
- static void mark_class_ctor(chunk_t *pclass);
- /**
- * We're on a 'namespace' skip the word and then set the parent of the braces.
- */
- static void mark_namespace(chunk_t *pns);
- static void mark_cpp_constructor(chunk_t *pc);
- /**
- * Just hit an assign. Go backwards until we hit an open brace/paren/square or
- * semicolon (TODO: other limiter?) and mark as a LValue.
- */
- static void mark_lvalue(chunk_t *pc);
- /**
- * We are on a word followed by a angle open which is part of a template.
- * If the angle close is followed by a open paren, then we are on a template
- * function def or a template function call:
- * Vector2<float>(...) [: ...[, ...]] { ... }
- * Or we could be on a variable def if it's followed by a word:
- * Renderer<rgb32> rend;
- */
- static void mark_template_func(chunk_t *pc, chunk_t *pc_next);
- /**
- * Just mark every CT_WORD until a semicolon as CT_SQL_WORD.
- * Adjust the levels if pc is CT_SQL_BEGIN
- */
- static void mark_exec_sql(chunk_t *pc);
- /**
- * Process an ObjC 'class'
- * pc is the chunk after '@implementation' or '@interface' or '@protocol'.
- * Change colons, etc. Processes stuff until '@end'.
- * Skips anything in braces.
- */
- static void handle_oc_class(chunk_t *pc);
- /**
- * Mark Objective-C blocks (aka lambdas or closures)
- * The syntax and usage is exactly like C function pointers
- * but instead of an asterisk they have a caret as pointer symbol.
- * Although it may look expensive this functions is only triggered
- * on appearance of an OC_BLOCK_CARET for LANG_OC.
- * repeat(10, ^{ putc('0'+d); });
- * typedef void (^workBlk_t)(void);
- *
- * @param pc points to the '^'
- */
- static void handle_oc_block_literal(chunk_t *pc);
- /**
- * Mark Objective-C block types.
- * The syntax and usage is exactly like C function pointers
- * but instead of an asterisk they have a caret as pointer symbol.
- * typedef void (^workBlk_t)(void);
- * const char * (^workVar)(void);
- * -(void)Foo:(void(^)())blk { }
- *
- * This is triggered when the sequence '(' '^' is found.
- *
- * @param pc points to the '^'
- */
- static void handle_oc_block_type(chunk_t *pc);
- /**
- * Process an ObjC message spec/dec
- *
- * Specs:
- * -(void) foo ARGS;
- *
- * Decl:
- * -(void) foo ARGS { }
- *
- * LABEL : (ARGTYPE) ARGNAME
- *
- * ARGS is ': (ARGTYPE) ARGNAME [MOREARGS...]'
- * MOREARGS is ' [ LABEL] : (ARGTYPE) ARGNAME '
- * -(void) foo: (int) arg: { }
- * -(void) foo: (int) arg: { }
- * -(void) insertObject:(id)anObject atIndex:(int)index
- */
- static void handle_oc_message_decl(chunk_t *pc);
- /**
- * Process an ObjC message send statement:
- * [ class func: val1 name2: val2 name3: val3] ; // named params
- * [ class func: val1 : val2 : val3] ; // unnamed params
- * [ class <proto> self method ] ; // with protocol
- * [[NSMutableString alloc] initWithString: @"" ] // class from msg
- * [func(a,b,c) lastObject ] // class from func
- *
- * Mainly find the matching ']' and ';' and mark the colons.
- *
- * @param os points to the open square '['
- */
- static void handle_oc_message_send(chunk_t *pc);
- /**
- * Process @Property values and re-arrange them if necessary
- */
- static void handle_oc_property_decl(chunk_t *pc);
- /**
- * Process a type that is enclosed in parens in message decls.
- * TODO: handle block types, which get special formatting
- *
- * @param pc points to the open paren
- * @return the chunk after the type
- */
- static chunk_t *handle_oc_md_type(chunk_t *paren_open, c_token_t ptype, UINT64 flags, bool &did_it);
- /**
- * Process an C# [] thingy:
- * [assembly: xxx]
- * [AttributeUsage()]
- * [@X]
- *
- * Set the next chunk to a statement start after the close ']'
- *
- * @param os points to the open square '['
- */
- static void handle_cs_square_stmt(chunk_t *pc);
- /**
- * We are on a brace open that is preceded by a word or square close.
- * Set the brace parent to CT_CS_PROPERTY and find the first item in the
- * property and set its parent, too.
- */
- static void handle_cs_property(chunk_t *pc);
- /**
- * We hit a ']' followed by a WORD. This may be a multidimensional array type.
- * Example: int[,,] x;
- * If there is nothing but commas between the open and close, then mark it.
- */
- static void handle_cs_array_type(chunk_t *pc);
- /**
- * We are on the C++ 'template' keyword.
- * What follows should be the following:
- *
- * template <class identifier> function_declaration;
- * template <typename identifier> function_declaration;
- * template <class identifier> class class_declaration;
- * template <typename identifier> class class_declaration;
- *
- * Change the 'class' inside the <> to CT_TYPE.
- * Set the parent to the class after the <> to CT_TEMPLATE.
- * Set the parent of the semicolon to CT_TEMPLATE.
- */
- static void handle_cpp_template(chunk_t *pc);
- /**
- * Verify and then mark C++ lambda expressions.
- * The expected format is '[...](...){...}' or '[...](...) -> type {...}'
- * sq_o is '[' CT_SQUARE_OPEN or '[]' CT_TSQUARE
- * Split the '[]' so we can control the space
- */
- static void handle_cpp_lambda(chunk_t *pc);
- /**
- * We are on the D 'template' keyword.
- * What follows should be the following:
- *
- * template NAME ( TYPELIST ) { BODY }
- *
- * Set the parent of NAME to template, change NAME to CT_TYPE.
- * Set the parent of the parens and braces to CT_TEMPLATE.
- * Scan the body for each type in TYPELIST and change the type to CT_TYPE.
- */
- static void handle_d_template(chunk_t *pc);
- /**
- * A func wrap chunk and what follows should be treated as a function name.
- * Create new text for the chunk and call it a CT_FUNCTION.
- *
- * A type wrap chunk and what follows should be treated as a simple type.
- * Create new text for the chunk and call it a CT_TYPE.
- */
- static void handle_wrap(chunk_t *pc);
- /**
- * A proto wrap chunk and what follows should be treated as a function proto.
- *
- * RETTYPE PROTO_WRAP( NAME, PARAMS ); or RETTYPE PROTO_WRAP( NAME, (PARAMS) );
- * RETTYPE gets changed with make_type().
- * PROTO_WRAP is marked as CT_FUNC_PROTO or CT_FUNC_DEF.
- * NAME is marked as CT_WORD.
- * PARAMS is all marked as prototype parameters.
- */
- static void handle_proto_wrap(chunk_t *pc);
- static bool is_oc_block(chunk_t *pc);
- /**
- * Java assert statements are: "assert EXP1 [: EXP2] ;"
- * Mark the parent of the colon and semicolon
- */
- static void handle_java_assert(chunk_t *pc);
- /**
- * Parse off the types in the D template args, adds to cs
- * returns the close_paren
- */
- static chunk_t *get_d_template_types(ChunkStack &cs, chunk_t *open_paren);
- static bool chunkstack_match(ChunkStack &cs, chunk_t *pc);
- enum PLBfound
- {
- FOUND_ANGLE_CLOSE = 0, // '>' found
- NO_PROTOCOL_FOUND = 1, // no protocol found,
- FOUND_ANGLE_OPEN = 2 // '<' found
- };
- void make_type(chunk_t *pc)
- {
- LOG_FUNC_ENTRY();
- if (pc != NULL)
- {
- if (pc->type == CT_WORD)
- {
- set_chunk_type(pc, CT_TYPE);
- }
- else if (chunk_is_star(pc) || chunk_is_msref(pc))
- {
- set_chunk_type(pc, CT_PTR_TYPE);
- }
- else if (chunk_is_addr(pc))
- {
- set_chunk_type(pc, CT_BYREF);
- }
- }
- }
- void flag_series(chunk_t *start, chunk_t *end, UINT64 set_flags, UINT64 clr_flags, chunk_nav_t nav)
- {
- LOG_FUNC_ENTRY();
- while (start && (start != end))
- {
- chunk_flags_upd(start, clr_flags, set_flags);
- start = chunk_get_next(start, nav);
- }
- if (end)
- {
- chunk_flags_upd(end, clr_flags, set_flags);
- }
- }
- static chunk_t *flag_parens(chunk_t *po, UINT64 flags, c_token_t opentype,
- c_token_t parenttype, bool parent_all)
- {
- LOG_FUNC_ENTRY();
- chunk_t *paren_close;
- paren_close = chunk_skip_to_match(po, CNAV_PREPROC);
- if (paren_close == NULL)
- {
- LOG_FMT(LERR, "flag_parens: no match for [%s] at [%zu:%zu]",
- po->text(), po->orig_line, po->orig_col);
- log_func_stack_inline(LERR);
- cpd.error_count++;
- return(NULL);
- }
- LOG_FMT(LFLPAREN, "flag_parens: %zu:%zu [%s] and %zu:%zu [%s] type=%s ptype=%s",
- po->orig_line, po->orig_col, po->text(),
- paren_close->orig_line, paren_close->orig_col, paren_close->text(),
- get_token_name(opentype), get_token_name(parenttype));
- //log_func_stack_inline(LSETTYP);
- log_func_stack_inline(LFLPAREN);
- if (po != paren_close)
- {
- if ((flags != 0) ||
- (parent_all && (parenttype != CT_NONE)))
- {
- chunk_t *pc;
- for (pc = chunk_get_next(po, CNAV_PREPROC);
- pc != paren_close;
- pc = chunk_get_next(pc, CNAV_PREPROC))
- {
- chunk_flags_set(pc, flags);
- if (parent_all)
- {
- set_chunk_parent(pc, parenttype);
- }
- }
- }
- if (opentype != CT_NONE)
- {
- set_chunk_type(po, opentype);
- set_chunk_type(paren_close, (c_token_t)(opentype + 1));
- }
- if (parenttype != CT_NONE)
- {
- set_chunk_parent(po, parenttype);
- set_chunk_parent(paren_close, parenttype);
- }
- }
- return(chunk_get_next_ncnl(paren_close, CNAV_PREPROC));
- } // flag_parens
- /**
- * Sets the parent of the open paren/brace/square/angle and the closing.
- * Note - it is assumed that pc really does point to an open item and the
- * close must be open + 1.
- *
- * @param start The open paren
- * @param parent The type to assign as the parent
- * @return The chunk after the close paren
- */
- chunk_t *set_paren_parent(chunk_t *start, c_token_t parent)
- {
- LOG_FUNC_ENTRY();
- chunk_t *end;
- end = chunk_skip_to_match(start, CNAV_PREPROC);
- if (end != NULL)
- {
- LOG_FMT(LFLPAREN, "set_paren_parent: %zu:%zu [%s] and %zu:%zu [%s] type=%s ptype=%s",
- start->orig_line, start->orig_col, start->text(),
- end->orig_line, end->orig_col, end->text(),
- get_token_name(start->type), get_token_name(parent));
- log_func_stack_inline(LFLPAREN);
- set_chunk_parent(start, parent);
- set_chunk_parent(end, parent);
- }
- return(chunk_get_next_ncnl(end, CNAV_PREPROC));
- }
- static void flag_asm(chunk_t *pc)
- {
- LOG_FUNC_ENTRY();
- chunk_t *tmp = chunk_get_next_ncnl(pc, CNAV_PREPROC);
- if (!chunk_is_token(tmp, CT_QUALIFIER))
- {
- return;
- }
- chunk_t *po = chunk_get_next_ncnl(tmp, CNAV_PREPROC);
- if (!chunk_is_paren_open(po))
- {
- return;
- }
- chunk_t *end = chunk_skip_to_match(po, CNAV_PREPROC);
- if (!end)
- {
- return;
- }
- set_chunk_parent(po, CT_ASM);
- set_chunk_parent(end, CT_ASM);
- for (tmp = chunk_get_next_ncnl(po, CNAV_PREPROC);
- tmp != end;
- tmp = chunk_get_next_ncnl(tmp, CNAV_PREPROC))
- {
- if (tmp->type == CT_COLON)
- {
- set_chunk_type(tmp, CT_ASM_COLON);
- }
- else if (tmp->type == CT_DC_MEMBER)
- {
- /* if there is a string on both sides, then this is two ASM_COLONs */
- if (chunk_is_token(chunk_get_next_ncnl(tmp, CNAV_PREPROC), CT_STRING) &&
- chunk_is_token(chunk_get_prev_ncnl(tmp, CNAV_PREPROC), CT_STRING))
- {
- chunk_t nc;
- nc = *tmp;
- tmp->str.resize(1);
- tmp->orig_col_end = tmp->orig_col + 1;
- set_chunk_type(tmp, CT_ASM_COLON);
- nc.type = tmp->type;
- nc.str.pop_front();
- nc.orig_col++;
- nc.column++;
- chunk_add_after(&nc, tmp);
- }
- }
- }
- tmp = chunk_get_next_ncnl(end, CNAV_PREPROC);
- if (chunk_is_token(tmp, CT_SEMICOLON))
- {
- set_chunk_parent(tmp, CT_ASM);
- }
- } // flag_asm
- static bool chunk_ends_type(chunk_t *start)
- {
- LOG_FUNC_ENTRY();
- chunk_t *pc = start;
- bool ret = false;
- size_t cnt = 0;
- bool last_lval = false;
- for (/* nada */; pc != NULL; pc = chunk_get_prev_ncnl(pc))
- {
- LOG_FMT(LFTYPE, "%s: [%s] %s flags %" PRIx64 " on line %zu, col %zu\n",
- __func__, get_token_name(pc->type), pc->text(),
- pc->flags, pc->orig_line, pc->orig_col);
- if ((pc->type == CT_WORD) ||
- (pc->type == CT_TYPE) ||
- (pc->type == CT_PTR_TYPE) ||
- (pc->type == CT_STRUCT) ||
- (pc->type == CT_DC_MEMBER) ||
- (pc->type == CT_QUALIFIER))
- {
- cnt++;
- last_lval = (pc->flags & PCF_LVALUE) != 0; // forcing value to bool
- continue;
- }
- if ((chunk_is_semicolon(pc) && ((pc->flags & PCF_IN_FOR) == 0)) ||
- (pc->type == CT_TYPEDEF) ||
- (pc->type == CT_BRACE_OPEN) ||
- (pc->type == CT_BRACE_CLOSE) ||
- chunk_is_forin(pc) ||
- ((pc->type == CT_SPAREN_OPEN) && last_lval))
- {
- ret = cnt > 0;
- }
- break;
- }
- if (pc == NULL)
- {
- /* first token */
- ret = true;
- }
- LOG_FMT(LFTYPE, "%s verdict: %s\n", __func__, ret ? "yes" : "no");
- return(ret);
- } // chunk_ends_type
- static chunk_t *skip_dc_member(chunk_t *start)
- {
- LOG_FUNC_ENTRY();
- if (!start)
- {
- return(NULL);
- }
- chunk_t *pc = start;
- chunk_t *next = (pc->type == CT_DC_MEMBER) ? pc : chunk_get_next_ncnl(pc);
- while (next && (next->type == CT_DC_MEMBER))
- {
- pc = chunk_get_next_ncnl(next);
- next = chunk_get_next_ncnl(pc);
- }
- return(pc);
- }
- /**
- * This is called on every chunk.
- * First on all non-preprocessor chunks and then on each preprocessor chunk.
- * It does all the detection and classifying.
- * This is only called by fix_symbols.
- * The three parameters never get the value NULL.
- * it is not necessary to test.
- */
- void do_symbol_check(chunk_t *prev, chunk_t *pc, chunk_t *next)
- {
- LOG_FUNC_ENTRY();
- chunk_t *tmp;
- #ifdef DEBUG
- LOG_FMT(LGUY, "(%d) ", __LINE__);
- #endif
- if (pc->type == CT_NEWLINE)
- {
- LOG_FMT(LGUY, "%s: %zu:%zu CT_NEWLINE\n", __func__, pc->orig_line, pc->orig_col);
- }
- else if (pc->type == CT_VBRACE_OPEN)
- {
- LOG_FMT(LGUY, "%s: %zu:%zu CT_VBRACE_OPEN\n", __func__, pc->orig_line, pc->orig_col);
- }
- else if (pc->type == CT_VBRACE_CLOSE)
- {
- LOG_FMT(LGUY, "%s: %zu:%zu CT_VBRACE_CLOSE\n", __func__, pc->orig_line, pc->orig_col);
- }
- else
- {
- LOG_FMT(LGUY, "%s: %zu:%zu %s:%s\n",
- __func__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- }
- // LOG_FMT(LSYS, " %3d > ['%s' %s] ['%s' %s] ['%s' %s]\n",
- // pc->orig_line,
- // prev->text(), get_token_name(prev->type),
- // pc->text(), get_token_name(pc->type),
- // next->text(), get_token_name(next->type));
- if (pc->type == CT_OC_AT)
- {
- if ((next->type == CT_PAREN_OPEN) ||
- (next->type == CT_BRACE_OPEN) ||
- (next->type == CT_SQUARE_OPEN))
- {
- flag_parens(next, PCF_OC_BOXED, next->type, CT_OC_AT, false);
- }
- else
- {
- set_chunk_parent(next, CT_OC_AT);
- }
- }
- /* D stuff */
- if ((cpd.lang_flags & LANG_D) &&
- (pc->type == CT_QUALIFIER) &&
- chunk_is_str(pc, "const", 5) &&
- (next->type == CT_PAREN_OPEN))
- {
- set_chunk_type(pc, CT_D_CAST);
- set_paren_parent(next, pc->type);
- }
- if ((next->type == CT_PAREN_OPEN) &&
- ((pc->type == CT_D_CAST) ||
- (pc->type == CT_DELEGATE) ||
- (pc->type == CT_ALIGN)))
- {
- /* mark the parenthesis parent */
- tmp = set_paren_parent(next, pc->type);
- /* For a D cast - convert the next item */
- if ((pc->type == CT_D_CAST) && (tmp != NULL))
- {
- if (tmp->type == CT_STAR)
- {
- set_chunk_type(tmp, CT_DEREF);
- }
- else if (tmp->type == CT_AMP)
- {
- set_chunk_type(tmp, CT_ADDR);
- }
- else if (tmp->type == CT_MINUS)
- {
- set_chunk_type(tmp, CT_NEG);
- }
- else if (tmp->type == CT_PLUS)
- {
- set_chunk_type(tmp, CT_POS);
- }
- }
- /* For a delegate, mark previous words as types and the item after the
- * close paren as a variable def
- */
- if (pc->type == CT_DELEGATE)
- {
- if (tmp != NULL)
- {
- set_chunk_parent(tmp, CT_DELEGATE);
- if (tmp->level == tmp->brace_level)
- {
- chunk_flags_set(tmp, PCF_VAR_1ST_DEF);
- }
- }
- for (tmp = chunk_get_prev_ncnl(pc); tmp != NULL; tmp = chunk_get_prev_ncnl(tmp))
- {
- if (chunk_is_semicolon(tmp) ||
- (tmp->type == CT_BRACE_OPEN) ||
- (tmp->type == CT_VBRACE_OPEN))
- {
- break;
- }
- make_type(tmp);
- }
- }
- if ((pc->type == CT_ALIGN) && (tmp != NULL))
- {
- if (tmp->type == CT_BRACE_OPEN)
- {
- set_paren_parent(tmp, pc->type);
- }
- else if (tmp->type == CT_COLON)
- {
- set_chunk_parent(tmp, pc->type);
- }
- }
- } /* paren open + cast/align/delegate */
- if (pc->type == CT_INVARIANT)
- {
- if (next->type == CT_PAREN_OPEN)
- {
- set_chunk_parent(next, pc->type);
- tmp = chunk_get_next(next);
- while (tmp != NULL)
- {
- if (tmp->type == CT_PAREN_CLOSE)
- {
- set_chunk_parent(tmp, pc->type);
- break;
- }
- make_type(tmp);
- tmp = chunk_get_next(tmp);
- }
- }
- else
- {
- set_chunk_type(pc, CT_QUALIFIER);
- }
- }
- if ((prev->type == CT_BRACE_OPEN) &&
- (prev->parent_type != CT_CS_PROPERTY) &&
- ((pc->type == CT_GETSET) || (pc->type == CT_GETSET_EMPTY)))
- {
- flag_parens(prev, 0, CT_NONE, CT_GETSET, false);
- }
- if (pc->type == CT_ASM)
- {
- flag_asm(pc);
- }
- /* Objective C stuff */
- if (cpd.lang_flags & LANG_OC)
- {
- /* Check for message declarations */
- if (pc->flags & PCF_STMT_START)
- {
- if ((chunk_is_str(pc, "-", 1) || chunk_is_str(pc, "+", 1)) &&
- chunk_is_str(next, "(", 1))
- {
- handle_oc_message_decl(pc);
- }
- }
- if (pc->flags & PCF_EXPR_START)
- {
- if (pc->type == CT_SQUARE_OPEN)
- {
- handle_oc_message_send(pc);
- }
- if (pc->type == CT_CARET)
- {
- handle_oc_block_literal(pc);
- }
- }
- if (pc->type == CT_OC_PROPERTY)
- {
- handle_oc_property_decl(pc);
- }
- }
- /* C# stuff */
- if (cpd.lang_flags & LANG_CS)
- {
- /* '[assembly: xxx]' stuff */
- if ((pc->flags & PCF_EXPR_START) &&
- (pc->type == CT_SQUARE_OPEN))
- {
- handle_cs_square_stmt(pc);
- }
- if ((next->type == CT_BRACE_OPEN) &&
- (next->parent_type == CT_NONE) &&
- ((pc->type == CT_SQUARE_CLOSE) ||
- (pc->type == CT_ANGLE_CLOSE) ||
- (pc->type == CT_WORD)))
- {
- handle_cs_property(next);
- }
- if ((pc->type == CT_SQUARE_CLOSE) &&
- (next->type == CT_WORD))
- {
- handle_cs_array_type(pc);
- }
- if ((((pc->type == CT_LAMBDA) || (pc->type == CT_DELEGATE))) && (next->type == CT_BRACE_OPEN))
- {
- set_paren_parent(next, pc->type);
- }
- if ((pc->type == CT_WHEN) && (pc->next->type != CT_SPAREN_OPEN))
- {
- set_chunk_type(pc, CT_WORD);
- }
- }
- if (pc->type == CT_NEW)
- {
- chunk_t *ts = NULL;
- tmp = next;
- if (tmp->type == CT_TSQUARE)
- {
- ts = tmp;
- tmp = chunk_get_next_ncnl(tmp);
- }
- if (tmp && (tmp->type == CT_BRACE_OPEN))
- {
- set_paren_parent(tmp, pc->type);
- if (ts)
- {
- ts->parent_type = pc->type;
- }
- }
- }
- /* C++11 Lambda stuff */
- if ((cpd.lang_flags & LANG_CPP) &&
- ((pc->type == CT_SQUARE_OPEN) || (pc->type == CT_TSQUARE)))
- {
- handle_cpp_lambda(pc);
- }
- /* FIXME: which language does this apply to? */
- if ((pc->type == CT_ASSIGN) && (next->type == CT_SQUARE_OPEN))
- {
- set_paren_parent(next, CT_ASSIGN);
- /* Mark one-liner assignment */
- tmp = next;
- while ((tmp = chunk_get_next_nc(tmp)) != NULL)
- {
- if (chunk_is_newline(tmp))
- {
- break;
- }
- if ((tmp->type == CT_SQUARE_CLOSE) && (next->level == tmp->level))
- {
- chunk_flags_set(tmp, PCF_ONE_LINER);
- chunk_flags_set(next, PCF_ONE_LINER);
- break;
- }
- }
- }
- if (pc->type == CT_ASSERT)
- {
- handle_java_assert(pc);
- }
- if (pc->type == CT_ANNOTATION)
- {
- tmp = chunk_get_next_ncnl(pc);
- if (chunk_is_paren_open(tmp))
- {
- set_paren_parent(tmp, CT_ANNOTATION);
- }
- }
- /* A [] in C# and D only follows a type */
- if ((pc->type == CT_TSQUARE) &&
- (cpd.lang_flags & (LANG_D | LANG_CS | LANG_VALA)))
- {
- if (prev->type == CT_WORD)
- {
- set_chunk_type(prev, CT_TYPE);
- }
- if (next->type == CT_WORD)
- {
- chunk_flags_set(next, PCF_VAR_1ST_DEF);
- }
- }
- if ((pc->type == CT_SQL_EXEC) ||
- (pc->type == CT_SQL_BEGIN) ||
- (pc->type == CT_SQL_END))
- {
- mark_exec_sql(pc);
- }
- if (pc->type == CT_PROTO_WRAP)
- {
- handle_proto_wrap(pc);
- }
- /* Handle the typedef */
- if (pc->type == CT_TYPEDEF)
- {
- fix_typedef(pc);
- }
- if ((pc->type == CT_ENUM) ||
- (pc->type == CT_STRUCT) ||
- (pc->type == CT_UNION))
- {
- if (prev->type != CT_TYPEDEF)
- {
- fix_enum_struct_union(pc);
- }
- }
- if (pc->type == CT_EXTERN)
- {
- if (chunk_is_paren_open(next))
- {
- tmp = flag_parens(next, 0, CT_NONE, CT_EXTERN, true);
- if (tmp && (tmp->type == CT_BRACE_OPEN))
- {
- set_paren_parent(tmp, CT_EXTERN);
- }
- }
- else
- {
- /* next likely is a string (see tokenize_cleanup.cpp) */
- set_chunk_parent(next, CT_EXTERN);
- tmp = chunk_get_next_ncnl(next);
- if (tmp && (tmp->type == CT_BRACE_OPEN))
- {
- set_paren_parent(tmp, CT_EXTERN);
- }
- }
- }
- if (pc->type == CT_TEMPLATE)
- {
- if (cpd.lang_flags & LANG_D)
- {
- handle_d_template(pc);
- }
- else
- {
- handle_cpp_template(pc);
- }
- }
- if ((pc->type == CT_WORD) &&
- (next->type == CT_ANGLE_OPEN) &&
- (next->parent_type == CT_TEMPLATE))
- {
- mark_template_func(pc, next);
- }
- if ((pc->type == CT_SQUARE_CLOSE) &&
- (next->type == CT_PAREN_OPEN))
- {
- flag_parens(next, 0, CT_FPAREN_OPEN, CT_NONE, false);
- }
- if (pc->type == CT_TYPE_CAST)
- {
- fix_type_cast(pc);
- }
- if ((pc->parent_type == CT_ASSIGN) &&
- ((pc->type == CT_BRACE_OPEN) ||
- (pc->type == CT_SQUARE_OPEN)))
- {
- /* Mark everything in here as in assign */
- flag_parens(pc, PCF_IN_ARRAY_ASSIGN, pc->type, CT_NONE, false);
- }
- if (pc->type == CT_D_TEMPLATE)
- {
- set_paren_parent(next, pc->type);
- }
- /**
- * A word before an open paren is a function call or definition.
- * CT_WORD => CT_FUNC_CALL or CT_FUNC_DEF
- */
- if (next->type == CT_PAREN_OPEN)
- {
- tmp = chunk_get_next_ncnl(next);
- if ((cpd.lang_flags & LANG_OC) && chunk_is_token(tmp, CT_CARET))
- {
- handle_oc_block_type(tmp);
- // This is the case where a block literal is passed as the first argument of a C-style method invocation.
- if ((tmp->type == CT_OC_BLOCK_CARET) && (pc->type == CT_WORD))
- {
- set_chunk_type(pc, CT_FUNC_CALL);
- }
- }
- else if ((pc->type == CT_WORD) || (pc->type == CT_OPERATOR_VAL))
- {
- set_chunk_type(pc, CT_FUNCTION);
- }
- else if (pc->type == CT_TYPE)
- {
- /**
- * If we are on a type, then we are either on a C++ style cast, a
- * function or we are on a function type.
- * The only way to tell for sure is to find the close paren and see
- * if it is followed by an open paren.
- * "int(5.6)"
- * "int()"
- * "int(foo)(void)"
- *
- * FIXME: this check can be done better...
- */
- tmp = chunk_get_next_type(next, CT_PAREN_CLOSE, next->level);
- tmp = chunk_get_next(tmp);
- if ((tmp != NULL) && (tmp->type == CT_PAREN_OPEN))
- {
- /* we have "TYPE(...)(" */
- set_chunk_type(pc, CT_FUNCTION);
- }
- else
- {
- if ((pc->parent_type == CT_NONE) &&
- ((pc->flags & PCF_IN_TYPEDEF) == 0))
- {
- tmp = chunk_get_next_ncnl(next);
- if ((tmp != NULL) && (tmp->type == CT_PAREN_CLOSE))
- {
- /* we have TYPE() */
- set_chunk_type(pc, CT_FUNCTION);
- }
- else
- {
- /* we have TYPE(...) */
- set_chunk_type(pc, CT_CPP_CAST);
- set_paren_parent(next, CT_CPP_CAST);
- }
- }
- }
- }
- else if (pc->type == CT_ATTRIBUTE)
- {
- flag_parens(next, 0, CT_FPAREN_OPEN, CT_ATTRIBUTE, false);
- }
- }
- if (cpd.lang_flags & LANG_PAWN)
- {
- if ((pc->type == CT_FUNCTION) && (pc->brace_level > 0))
- {
- set_chunk_type(pc, CT_FUNC_CALL);
- }
- if ((pc->type == CT_STATE) &&
- (next->type == CT_PAREN_OPEN))
- {
- set_paren_parent(next, pc->type);
- }
- }
- else
- {
- if ((pc->type == CT_FUNCTION) &&
- ((pc->parent_type == CT_OC_BLOCK_EXPR) || !is_oc_block(pc)))
- {
- mark_function(pc);
- }
- }
- /* Detect C99 member stuff */
- if ((pc->type == CT_MEMBER) &&
- ((prev->type == CT_COMMA) ||
- (prev->type == CT_BRACE_OPEN)))
- {
- set_chunk_type(pc, CT_C99_MEMBER);
- set_chunk_parent(next, CT_C99_MEMBER);
- }
- /* Mark function parens and braces */
- if ((pc->type == CT_FUNC_DEF) ||
- (pc->type == CT_FUNC_CALL) ||
- (pc->type == CT_FUNC_CALL_USER) ||
- (pc->type == CT_FUNC_PROTO))
- {
- tmp = next;
- if (tmp->type == CT_SQUARE_OPEN)
- {
- tmp = set_paren_parent(tmp, pc->type);
- }
- else if ((tmp->type == CT_TSQUARE) ||
- (tmp->parent_type == CT_OPERATOR))
- {
- tmp = chunk_get_next_ncnl(tmp);
- }
- if (tmp != NULL)
- {
- if (chunk_is_paren_open(tmp))
- {
- tmp = flag_parens(tmp, 0, CT_FPAREN_OPEN, pc->type, false);
- if (tmp != NULL)
- {
- if (tmp->type == CT_BRACE_OPEN)
- {
- if ((tmp->parent_type != CT_DOUBLE_BRACE) &&
- ((pc->flags & PCF_IN_CONST_ARGS) == 0))
- {
- set_paren_parent(tmp, pc->type);
- }
- }
- else if (chunk_is_semicolon(tmp) && (pc->type == CT_FUNC_PROTO))
- {
- set_chunk_parent(tmp, pc->type);
- }
- }
- }
- }
- }
- /* Mark the parameters in catch() */
- if ((pc->type == CT_CATCH) && (next->type == CT_SPAREN_OPEN))
- {
- fix_fcn_def_params(next);
- }
- if ((pc->type == CT_THROW) && (prev->type == CT_FPAREN_CLOSE))
- {
- set_chunk_parent(pc, prev->parent_type);
- if (next->type == CT_PAREN_OPEN)
- {
- set_paren_parent(next, CT_THROW);
- }
- }
- /* Mark the braces in: "for_each_entry(xxx) { }" */
- if ((pc->type == CT_BRACE_OPEN) &&
- (pc->parent_type != CT_DOUBLE_BRACE) &&
- (prev->type == CT_FPAREN_CLOSE) &&
- ((prev->parent_type == CT_FUNC_CALL) ||
- (prev->parent_type == CT_FUNC_CALL_USER)) &&
- ((pc->flags & PCF_IN_CONST_ARGS) == 0))
- {
- set_paren_parent(pc, CT_FUNC_CALL);
- }
- /* Check for a close paren followed by an open paren, which means that
- * we are on a function type declaration (C/C++ only?).
- * Note that typedefs are already taken care of.
- */
- if (((pc->flags & (PCF_IN_TYPEDEF | PCF_IN_TEMPLATE)) == 0) &&
- (pc->parent_type != CT_CPP_CAST) &&
- (pc->parent_type != CT_C_CAST) &&
- ((pc->flags & PCF_IN_PREPROC) == 0) &&
- (!is_oc_block(pc)) &&
- (pc->parent_type != CT_OC_MSG_DECL) &&
- (pc->parent_type != CT_OC_MSG_SPEC) &&
- chunk_is_str(pc, ")", 1) &&
- chunk_is_str(next, "(", 1))
- {
- if (cpd.lang_flags & LANG_D)
- {
- flag_parens(next, 0, CT_FPAREN_OPEN, CT_FUNC_CALL, false);
- }
- else
- {
- mark_function_type(pc);
- }
- }
- if (((pc->type == CT_CLASS) ||
- (pc->type == CT_STRUCT)) &&
- (pc->level == pc->brace_level))
- {
- if ((pc->type != CT_STRUCT) || ((cpd.lang_flags & LANG_C) == 0))
- {
- mark_class_ctor(pc);
- }
- }
- if (pc->type == CT_OC_CLASS)
- {
- handle_oc_class(pc);
- }
- if (pc->type == CT_NAMESPACE)
- {
- mark_namespace(pc);
- }
- /*TODO: Check for stuff that can only occur at the start of an statement */
- if ((cpd.lang_flags & LANG_D) == 0)
- {
- /**
- * Check a paren pair to see if it is a cast.
- * Note that SPAREN and FPAREN have already been marked.
- */
- if ((pc->type == CT_PAREN_OPEN) &&
- ((pc->parent_type == CT_NONE) ||
- (pc->parent_type == CT_OC_MSG) ||
- (pc->parent_type == CT_OC_BLOCK_EXPR)) &&
- ((next->type == CT_WORD) ||
- (next->type == CT_TYPE) ||
- (next->type == CT_STRUCT) ||
- (next->type == CT_QUALIFIER) ||
- (next->type == CT_MEMBER) ||
- (next->type == CT_DC_MEMBER) ||
- (next->type == CT_ENUM) ||
- (next->type == CT_UNION)) &&
- (prev->type != CT_SIZEOF) &&
- (prev->parent_type != CT_OPERATOR) &&
- ((pc->flags & PCF_IN_TYPEDEF) == 0) &&
- ((pc->flags & PCF_IN_FCN_DEF) == 0)) // issue # 222
- {
- fix_casts(pc);
- }
- }
- /* Check for stuff that can only occur at the start of an expression */
- if (pc->flags & PCF_EXPR_START)
- {
- /* Change STAR, MINUS, and PLUS in the easy cases */
- if (pc->type == CT_STAR)
- {
- // issue #596
- // [0x100062020:IN_SPAREN,IN_FOR,STMT_START,EXPR_START,PUNCTUATOR]
- // prev->type is CT_COLON ==> CT_DEREF
- if (prev->type == CT_ANGLE_CLOSE)
- {
- set_chunk_type(pc, CT_PTR_TYPE);
- }
- else if (prev->type == CT_COLON)
- {
- set_chunk_type(pc, CT_DEREF);
- }
- else
- {
- set_chunk_type(pc, CT_DEREF);
- }
- }
- if ((cpd.lang_flags & LANG_CPP) && (pc->type == CT_CARET) && (prev->type == CT_ANGLE_CLOSE))
- {
- set_chunk_type(pc, CT_PTR_TYPE);
- }
- if (pc->type == CT_MINUS)
- {
- set_chunk_type(pc, CT_NEG);
- }
- if (pc->type == CT_PLUS)
- {
- set_chunk_type(pc, CT_POS);
- }
- if (pc->type == CT_INCDEC_AFTER)
- {
- set_chunk_type(pc, CT_INCDEC_BEFORE);
- //fprintf(stderr, "%s: %d> changed INCDEC_AFTER to INCDEC_BEFORE\n", __func__, pc->orig_line);
- }
- if (pc->type == CT_AMP)
- {
- //fprintf(stderr, "Changed AMP to ADDR on line %d\n", pc->orig_line);
- set_chunk_type(pc, CT_ADDR);
- }
- if (pc->type == CT_CARET)
- {
- if (cpd.lang_flags & LANG_OC)
- {
- /* This is likely the start of a block literal */
- handle_oc_block_literal(pc);
- }
- }
- }
- /* Detect a variable definition that starts with struct/enum/union/class */
- if (((pc->flags & PCF_IN_TYPEDEF) == 0) &&
- (prev->parent_type != CT_CPP_CAST) &&
- ((prev->flags & PCF_IN_FCN_DEF) == 0) &&
- ((pc->type == CT_STRUCT) ||
- (pc->type == CT_UNION) ||
- (pc->type == CT_CLASS) ||
- (pc->type == CT_ENUM)))
- {
- tmp = skip_dc_member(next);
- if (tmp && ((tmp->type == CT_TYPE) || (tmp->type == CT_WORD)))
- {
- set_chunk_parent(tmp, pc->type);
- set_chunk_type(tmp, CT_TYPE);
- tmp = chunk_get_next_ncnl(tmp);
- }
- if ((tmp != NULL) && (tmp->type == CT_BRACE_OPEN))
- {
- tmp = chunk_skip_to_match(tmp);
- tmp = chunk_get_next_ncnl(tmp);
- }
- if ((tmp != NULL) && (chunk_is_ptr_operator(tmp) || (tmp->type == CT_WORD)))
- {
- mark_variable_definition(tmp);
- }
- }
- /**
- * Change the paren pair after a function/macrofunc.
- * CT_PAREN_OPEN => CT_FPAREN_OPEN
- */
- if (pc->type == CT_MACRO_FUNC)
- {
- flag_parens(next, PCF_IN_FCN_CALL, CT_FPAREN_OPEN, CT_MACRO_FUNC, false);
- }
- if ((pc->type == CT_MACRO_OPEN) ||
- (pc->type == CT_MACRO_ELSE) ||
- (pc->type == CT_MACRO_CLOSE))
- {
- if (next->type == CT_PAREN_OPEN)
- {
- flag_parens(next, 0, CT_FPAREN_OPEN, pc->type, false);
- }
- }
- if ((pc->type == CT_DELETE) && (next->type == CT_TSQUARE))
- {
- set_chunk_parent(next, CT_DELETE);
- }
- /* Change CT_STAR to CT_PTR_TYPE or CT_ARITH or CT_DEREF */
- if (pc->type == CT_STAR || ((cpd.lang_flags & LANG_CPP) && (pc->type == CT_CARET)))
- {
- if (chunk_is_paren_close(next) || (next->type == CT_COMMA))
- {
- set_chunk_type(pc, CT_PTR_TYPE);
- }
- else if ((cpd.lang_flags & LANG_OC) && (next->type == CT_STAR))
- {
- /* Change pointer-to-pointer types in OC_MSG_DECLs
- * from ARITH <===> DEREF to PTR_TYPE <===> PTR_TYPE */
- set_chunk_type(pc, CT_PTR_TYPE);
- set_chunk_parent(pc, prev->parent_type);
- set_chunk_type(next, CT_PTR_TYPE);
- set_chunk_parent(next, pc->parent_type);
- }
- else if ((pc->type == CT_STAR) && ((prev->type == CT_SIZEOF) || (prev->type == CT_DELETE)))
- {
- set_chunk_type(pc, CT_DEREF);
- }
- else if (((prev->type == CT_WORD) && chunk_ends_type(prev)) ||
- (prev->type == CT_DC_MEMBER) || (prev->type == CT_PTR_TYPE))
- {
- set_chunk_type(pc, CT_PTR_TYPE);
- }
- else if ((next->type == CT_SQUARE_OPEN) &&
- !(cpd.lang_flags & LANG_OC)) // issue # 408
- {
- set_chunk_type(pc, CT_PTR_TYPE);
- }
- else if (pc->type == CT_STAR)
- {
- /* most PCF_PUNCTUATOR chunks except a paren close would make this
- * a deref. A paren close may end a cast or may be part of a macro fcn.
- */
- if (prev->type == CT_TYPE)
- {
- set_chunk_type(pc, CT_PTR_TYPE);
- }
- else
- {
- set_chunk_type(pc,
- ((prev->flags & PCF_PUNCTUATOR) &&
- (!chunk_is_paren_close(prev) ||
- (prev->parent_type == CT_MACRO_FUNC)) &&
- (prev->type != CT_SQUARE_CLOSE) &&
- (prev->type != CT_DC_MEMBER)) ? CT_DEREF : CT_ARITH);
- }
- }
- }
- if (pc->type == CT_AMP)
- {
- if (prev->type == CT_DELETE)
- {
- set_chunk_type(pc, CT_ADDR);
- }
- else if (prev->type == CT_TYPE)
- {
- set_chunk_type(pc, CT_BYREF);
- }
- else if ((next->type == CT_FPAREN_CLOSE) ||
- (next->type == CT_COMMA))
- {
- // fix the bug #654
- // connect(&mapper, SIGNAL(mapped(QString &)), this, SLOT(onSomeEvent(QString &)));
- set_chunk_type(pc, CT_BYREF);
- }
- else
- {
- set_chunk_type(pc, CT_ARITH);
- if (prev->type == CT_WORD)
- {
- tmp = chunk_get_prev_ncnl(prev);
- if ((tmp != NULL) &&
- (chunk_is_semicolon(tmp) ||
- (tmp->type == CT_BRACE_OPEN) ||
- (tmp->type == CT_QUALIFIER)))
- {
- set_chunk_type(prev, CT_TYPE);
- set_chunk_type(pc, CT_ADDR);
- chunk_flags_set(next, PCF_VAR_1ST);
- }
- }
- }
- }
- if ((pc->type == CT_MINUS) ||
- (pc->type == CT_PLUS))
- {
- if ((prev->type == CT_POS) || (prev->type == CT_NEG))
- {
- set_chunk_type(pc, (pc->type == CT_MINUS) ? CT_NEG : CT_POS);
- }
- else if (prev->type == CT_OC_CLASS)
- {
- set_chunk_type(pc, (pc->type == CT_MINUS) ? CT_NEG : CT_POS);
- }
- else
- {
- set_chunk_type(pc, CT_ARITH);
- }
- }
- /**
- * Bug # 634
- * Check for extern "C" NSString* i;
- * NSString is a type
- * change CT_WORD => CT_TYPE for pc
- * change CT_STAR => CT_PTR_TYPE for pc-next
- */
- if (pc->type == CT_WORD) // here NSString
- {
- if (pc->next != NULL) // here *
- {
- if (pc->next->type == CT_STAR) // here *
- {
- if (pc->prev != NULL)
- {
- if (pc->prev->type == CT_STRING)
- {
- if (unc_text::compare(pc->prev->text(), "\"C\"") == 0)
- {
- if (pc->prev->prev->type == CT_EXTERN)
- {
- // change CT_WORD => CT_TYPE
- set_chunk_type(pc, CT_TYPE);
- // change CT_STAR => CT_PTR_TYPE
- set_chunk_type(pc->next, CT_PTR_TYPE);
- }
- }
- }
- }
- // Issue #322 STDMETHOD(GetValues)(BSTR bsName, REFDATA** pData);
- if ((pc->next->next) && (pc->next->next->type == CT_STAR))
- {
- // change CT_STAR => CT_PTR_TYPE
- set_chunk_type(pc->next, CT_PTR_TYPE);
- set_chunk_type(pc->next->next, CT_PTR_TYPE);
- }
- // Issue #222 whatever3 *(func_ptr)( whatever4 *foo2, ...
- if ((pc->next->next) &&
- (pc->next->next->type == CT_WORD) &&
- (pc->flags & PCF_IN_FCN_DEF))
- {
- set_chunk_type(pc->next, CT_PTR_TYPE);
- }
- }
- }
- }
- /**
- * Bug # 634
- * Check for __attribute__((visibility ("default"))) NSString* i;
- * NSString is a type
- * change CT_WORD => CT_TYPE for pc
- * change CT_STAR => CT_PTR_TYPE for pc-next
- */
- if (pc->type == CT_WORD) // here NSString
- {
- if (pc->next != NULL) // here *
- {
- if (pc->next->type == CT_STAR) // here *
- {
- tmp = pc;
- while ((tmp != NULL))
- {
- if (tmp->type == CT_ATTRIBUTE)
- {
- LOG_FMT(LGUY, "ATTRIBUTE found %s:%s\n",
- get_token_name(tmp->type), tmp->text());
- LOG_FMT(LGUY, "for token %s:%s\n", get_token_name(pc->type), pc->text());
- // change CT_WORD => CT_TYPE
- set_chunk_type(pc, CT_TYPE);
- // change CT_STAR => CT_PTR_TYPE
- set_chunk_type(pc->next, CT_PTR_TYPE);
- }
- if (tmp->flags & PCF_STMT_START)
- {
- // we are at beginnig of the line
- break;
- }
- tmp = chunk_get_prev(tmp);
- }
- }
- }
- }
- } // do_symbol_check
- static void check_double_brace_init(chunk_t *bo1)
- {
- LOG_FUNC_ENTRY();
- LOG_FMT(LJDBI, "%s: %zu:%zu", __func__, bo1->orig_line, bo1->orig_col);
- chunk_t *pc = chunk_get_prev_ncnl(bo1);
- if (chunk_is_paren_close(pc))
- {
- chunk_t *bo2 = chunk_get_next(bo1);
- if (chunk_is_token(bo2, CT_BRACE_OPEN))
- {
- /* found a potential double brace */
- chunk_t *bc2 = chunk_skip_to_match(bo2);
- chunk_t *bc1 = chunk_get_next(bc2);
- if (chunk_is_token(bc1, CT_BRACE_CLOSE))
- {
- LOG_FMT(LJDBI, " - end %zu:%zu\n", bc2->orig_line, bc2->orig_col);
- /* delete bo2 and bc1 */
- bo1->str += bo2->str;
- bo1->orig_col_end = bo2->orig_col_end;
- chunk_del(bo2);
- set_chunk_parent(bo1, CT_DOUBLE_BRACE);
- bc2->str += bc1->str;
- bc2->orig_col_end = bc1->orig_col_end;
- chunk_del(bc1);
- set_chunk_parent(bc2, CT_DOUBLE_BRACE);
- return;
- }
- }
- }
- LOG_FMT(LJDBI, " - no\n");
- }
- void fix_symbols(void)
- {
- LOG_FUNC_ENTRY();
- chunk_t *pc;
- chunk_t dummy;
- cpd.unc_stage = US_FIX_SYMBOLS;
- mark_define_expressions();
- bool is_java = (cpd.lang_flags & LANG_JAVA) != 0; // forcing value to bool
- for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next_ncnl(pc))
- {
- if ((pc->type == CT_FUNC_WRAP) ||
- (pc->type == CT_TYPE_WRAP))
- {
- handle_wrap(pc);
- }
- if (pc->type == CT_ASSIGN)
- {
- mark_lvalue(pc);
- }
- if (is_java && (pc->type == CT_BRACE_OPEN))
- {
- check_double_brace_init(pc);
- }
- }
- pc = chunk_get_head();
- if (chunk_is_newline(pc) || chunk_is_comment(pc))
- {
- pc = chunk_get_next_ncnl(pc);
- }
- while (pc != NULL)
- {
- chunk_t *prev = chunk_get_prev_ncnl(pc, CNAV_PREPROC);
- if (prev == NULL)
- {
- prev = &dummy;
- }
- chunk_t *next = chunk_get_next_ncnl(pc, CNAV_PREPROC);
- if (next == NULL)
- {
- next = &dummy;
- }
- do_symbol_check(prev, pc, next);
- pc = chunk_get_next_ncnl(pc);
- }
- pawn_add_virtual_semicolons();
- process_returns();
- /**
- * 2nd pass - handle variable definitions
- * REVISIT: We need function params marked to do this (?)
- */
- pc = chunk_get_head();
- int square_level = -1;
- while (pc != NULL)
- {
- /* Can't have a variable definition inside [ ] */
- if (square_level < 0)
- {
- if (pc->type == CT_SQUARE_OPEN)
- {
- square_level = pc->level;
- }
- }
- else
- {
- if (pc->level <= (size_t)square_level)
- {
- square_level = -1;
- }
- }
- /**
- * A variable definition is possible after at the start of a statement
- * that starts with: QUALIFIER, TYPE, or WORD
- */
- if ((square_level < 0) &&
- (pc->flags & PCF_STMT_START) &&
- ((pc->type == CT_QUALIFIER) ||
- (pc->type == CT_TYPE) ||
- (pc->type == CT_TYPENAME) ||
- (pc->type == CT_WORD)) &&
- (pc->parent_type != CT_ENUM) &&
- ((pc->flags & PCF_IN_ENUM) == 0))
- {
- pc = fix_var_def(pc);
- }
- else
- {
- pc = chunk_get_next_ncnl(pc);
- }
- }
- } // fix_symbols
- static void mark_lvalue(chunk_t …
Large files files are truncated, but you can click here to view the full file