summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine.cpp')
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine.cpp4044
1 files changed, 0 insertions, 4044 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine.cpp
deleted file mode 100644
index a033be49..00000000
--- a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine.cpp
+++ /dev/null
@@ -1,4044 +0,0 @@
-/**
- * @file combine.cpp
- * Labels the chunks as needed.
- *
- * @author Ben Gardner
- * @author Guy Maurel
- * @license GPL v2+
- */
-
-#include "combine.h"
-
-#include "combine_fix_mark.h"
-#include "combine_skip.h"
-#include "combine_tools.h"
-#include "EnumStructUnionParser.h"
-#include "flag_braced_init_list.h"
-#include "flag_parens.h"
-#include "lang_pawn.h"
-#include "mark_question_colon.h"
-#include "newlines.h"
-#include "prototypes.h"
-#include "tokenize_cleanup.h"
-#include "unc_tools.h"
-
-#include <limits>
-
-constexpr static auto LCURRENT = LCOMBINE;
-
-using namespace std;
-using namespace uncrustify;
-
-
-/**
- * Mark the parens and colons in:
- * asm volatile ( "xx" : "xx" (l), "yy"(h) : ... );
- *
- * @param pc the CT_ASM item
- */
-static void flag_asm(Chunk *pc);
-
-
-/**
- * Combines two tokens into {{ and }} if inside parens and nothing is between
- * either pair.
- */
-static void check_double_brace_init(Chunk *bo1);
-
-
-static void process_returns_and_throws();
-
-
-/**
- * Processes a 'return' or 'throw' statement, labeling the parens and marking
- * the parent. May remove or add parens around the return/throw statement.
- *
- * @param pc Pointer to the return or throw chunk
- */
-static Chunk *process_return_or_throw(Chunk *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 *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 *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 *pc);
-
-
-/**
- * Process an ObjC message spec/dec
- *
- * Specs:
- * -(void) foo ARGS;
- *
- * Declaration:
- * -(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 *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 pc points to the open square '['
- */
-static void handle_oc_message_send(Chunk *pc);
-
-
-//! Process @Property values and re-arrange them if necessary
-static void handle_oc_property_decl(Chunk *pc);
-
-//! Process @available annotation
-static void handle_oc_available(Chunk *pc);
-
-/**
- * Process a type that is enclosed in parens in message declarations.
- * TODO: handle block types, which get special formatting
- *
- * @param pc points to the open paren
- *
- * @return the chunk after the type
- */
-static Chunk *handle_oc_md_type(Chunk *paren_open, E_Token ptype, PcfFlags flags, bool &did_it);
-
-/**
- * Process an C# [] thingy:
- * [assembly: xxx]
- * [AttributeUsage()]
- * [@X]
- *
- * Set the next chunk to a statement start after the close ']'
- *
- * @param pc points to the open square '['
- */
-static void handle_cs_square_stmt(Chunk *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 *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 *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 *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 *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 *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 *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 *pc);
-
-
-static bool is_oc_block(Chunk *pc);
-
-
-/**
- * Java assert statements are: "assert EXP1 [: EXP2] ;"
- * Mark the parent of the colon and semicolon
- */
-static void handle_java_assert(Chunk *pc);
-
-
-static void flag_asm(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
-
- Chunk *tmp = pc->GetNextNcNnl(E_Scope::PREPROC);
-
- if (tmp->IsNot(CT_QUALIFIER))
- {
- return;
- }
- Chunk *po = tmp->GetNextNcNnl(E_Scope::PREPROC);
-
- if (!po->IsParenOpen())
- {
- return;
- }
- Chunk *end = po->GetClosingParen(E_Scope::PREPROC);
-
- if (end->IsNullChunk())
- {
- return;
- }
- po->SetParentType(CT_ASM);
- end->SetParentType(CT_ASM);
-
- for ( tmp = po->GetNextNcNnl(E_Scope::PREPROC);
- tmp->IsNotNullChunk()
- && tmp != end;
- tmp = tmp->GetNextNcNnl(E_Scope::PREPROC))
- {
- if (tmp->Is(CT_COLON))
- {
- tmp->SetType(CT_ASM_COLON);
- }
- else if (tmp->Is(CT_DC_MEMBER))
- {
- // if there is a string on both sides, then this is two ASM_COLONs
- if ( tmp->GetNextNcNnl(E_Scope::PREPROC)->Is(CT_STRING)
- && tmp->GetPrevNcNnlNi(E_Scope::PREPROC)->Is(CT_STRING)) // Issue #2279
- {
- Chunk nc;
-
- nc = *tmp;
-
- tmp->Str().resize(1);
- tmp->SetOrigColEnd(tmp->GetOrigCol() + 1);
- tmp->SetType(CT_ASM_COLON);
-
- nc.SetType(tmp->GetType());
- nc.Str().pop_front();
- nc.SetOrigCol(nc.GetOrigCol() + 1);
- nc.SetColumn(nc.GetColumn() + 1);
- nc.CopyAndAddAfter(tmp);
- }
- }
- }
-
- tmp = end->GetNextNcNnl(E_Scope::PREPROC);
-
- if (tmp->IsNullChunk())
- {
- return;
- }
-
- if (tmp->Is(CT_SEMICOLON))
- {
- tmp->SetParentType(CT_ASM);
- }
-} // flag_asm
-
-
-void do_symbol_check(Chunk *prev, Chunk *pc, Chunk *next)
-{
- LOG_FUNC_ENTRY();
- LOG_FMT(LFCNR, "%s(%d): prev is '%s' %s\n",
- __func__, __LINE__,
- prev->Text(), get_token_name(prev->GetType()));
- log_pcf_flags(LFCNR, prev->GetFlags());
- LOG_FMT(LFCNR, "%s(%d): pc is '%s' %s\n",
- __func__, __LINE__,
- pc->Text(), get_token_name(pc->GetType()));
- log_pcf_flags(LFCNR, pc->GetFlags());
- LOG_FMT(LFCNR, "%s(%d): next is '%s' %s\n",
- __func__, __LINE__,
- next->Text(), get_token_name(next->GetType()));
- log_pcf_flags(LFCNR, next->GetFlags());
-
- if ( pc->Is(CT_NOEXCEPT) // Issue #3284
- && next->Is(CT_ASSIGN)) // skip over noexcept
- {
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s'\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
- pc = next;
- next = pc->GetNext();
- }
-
- // separate the uses of CT_ASSIGN sign '='
- // into CT_ASSIGN_DEFAULT_ARG, CT_ASSIGN_FUNC_PROTO
- if ( pc->Is(CT_ASSIGN)
- && pc->GetParentType() == CT_FUNC_PROTO
- && ( pc->TestFlags(PCF_IN_FCN_DEF) // Issue #2236
- || pc->TestFlags(PCF_IN_CONST_ARGS)))
- {
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s'\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
- log_pcf_flags(LFCNR, pc->GetFlags());
- pc->SetType(CT_ASSIGN_DEFAULT_ARG);
- return;
- }
-
- if ( ( prev->Is(CT_FPAREN_CLOSE)
- || ( ( prev->IsString("const")
- || prev->IsString("override"))
- && prev->GetPrev()->Is(CT_FPAREN_CLOSE)))
- && pc->Is(CT_ASSIGN)
- && ( next->Is(CT_DEFAULT)
- || next->Is(CT_DELETE)
- || next->IsString("0")))
- {
- pc->SetType(CT_ASSIGN_FUNC_PROTO);
- return; // cpp 30031
- }
-
- if (pc->Is(CT_OC_AT))
- {
- if ( next->Is(CT_PAREN_OPEN)
- || next->Is(CT_BRACE_OPEN)
- || next->Is(CT_SQUARE_OPEN))
- {
- flag_parens(next, PCF_OC_BOXED, next->GetType(), CT_OC_AT, false);
- }
- else
- {
- next->SetParentType(CT_OC_AT);
- return; // objective-c_50095
- }
- }
-
- // D stuff
- if ( language_is_set(LANG_D)
- && pc->Is(CT_QUALIFIER)
- && pc->IsString("const")
- && next->Is(CT_PAREN_OPEN))
- {
- pc->SetType(CT_D_CAST);
- set_paren_parent(next, pc->GetType());
- return; // d_40061
- }
-
- if ( next->Is(CT_PAREN_OPEN)
- && ( pc->Is(CT_D_CAST)
- || pc->Is(CT_DELEGATE)
- || pc->Is(CT_ALIGN)))
- {
- // mark the parenthesis parent
- Chunk *tmp = set_paren_parent(next, pc->GetType());
-
- // For a D cast - convert the next item
- if ( pc->Is(CT_D_CAST)
- && tmp->IsNotNullChunk())
- {
- if (tmp->Is(CT_STAR))
- {
- tmp->SetType(CT_DEREF);
- return; // d_40006
- }
- else if (tmp->Is(CT_AMP))
- {
- tmp->SetType(CT_ADDR);
- return; // d_40060
- }
- else if (tmp->Is(CT_MINUS))
- {
- tmp->SetType(CT_NEG);
- return; // d_40060
- }
- else if (tmp->Is(CT_PLUS))
- {
- tmp->SetType(CT_POS);
- return; // d_40060
- }
- }
-
- /*
- * For a delegate, mark previous words as types and the item after the
- * close paren as a variable def
- */
- if (pc->Is(CT_DELEGATE))
- {
- if (tmp->IsNotNullChunk())
- {
- tmp->SetParentType(CT_DELEGATE);
-
- if (tmp->GetLevel() == tmp->GetBraceLevel())
- {
- tmp->SetFlagBits(PCF_VAR_1ST_DEF);
- }
- }
-
- for (tmp = pc->GetPrevNcNnlNi(); tmp->IsNotNullChunk(); tmp = tmp->GetPrevNcNnlNi()) // Issue #2279
- {
- if ( tmp->IsSemicolon()
- || tmp->Is(CT_BRACE_OPEN)
- || tmp->Is(CT_VBRACE_OPEN))
- {
- break;
- }
- make_type(tmp);
- }
-
- return; // c-sharp_10160
- }
-
- if ( pc->Is(CT_ALIGN)
- && tmp->IsNotNullChunk())
- {
- if (tmp->Is(CT_BRACE_OPEN))
- {
- set_paren_parent(tmp, pc->GetType());
- return; // d_40024
- }
- else if (tmp->Is(CT_COLON))
- {
- tmp->SetParentType(pc->GetType());
- return; // d_40024
- }
- }
- } // paren open + cast/align/delegate
-
- if (pc->Is(CT_INVARIANT))
- {
- if (next->Is(CT_PAREN_OPEN))
- {
- next->SetParentType(pc->GetType());
- Chunk *tmp = next->GetNext();
-
- while (tmp->IsNotNullChunk())
- {
- if (tmp->Is(CT_PAREN_CLOSE))
- {
- tmp->SetParentType(pc->GetType());
- break;
- }
- make_type(tmp);
- tmp = tmp->GetNext();
- }
- return; // d_40100
- }
- else
- {
- pc->SetType(CT_QUALIFIER);
- return;
- }
- }
-
- if ( prev->Is(CT_BRACE_OPEN)
- && prev->GetParentType() != CT_CS_PROPERTY
- && ( pc->Is(CT_GETSET)
- || pc->Is(CT_GETSET_EMPTY)))
- {
- flag_parens(prev, PCF_NONE, CT_NONE, CT_GETSET, false);
- return;
- }
-
- if (pc->Is(CT_ASM))
- {
- flag_asm(pc);
- return;
- }
-
- // clang stuff - A new derived type is introduced to C and, by extension, Objective-C, C++, and Objective-C++
- if (language_is_set(LANG_C | LANG_CPP | LANG_OC))
- {
- if (pc->Is(CT_CARET))
- {
- if ( pc->TestFlags(PCF_EXPR_START)
- || pc->TestFlags(PCF_IN_PREPROC))
- {
- handle_oc_block_literal(pc);
- return;
- }
- }
- }
-
- // Objective C stuff
- if (language_is_set(LANG_OC))
- {
- // Check for message declarations
- if (pc->TestFlags(PCF_STMT_START))
- {
- if ( ( pc->IsString("-")
- || pc->IsString("+"))
- && next->IsString("("))
- {
- handle_oc_message_decl(pc);
- return;
- }
- }
-
- if ( pc->TestFlags(PCF_EXPR_START)
- || pc->TestFlags(PCF_IN_PREPROC))
- {
- if (pc->Is(CT_SQUARE_OPEN))
- {
- handle_oc_message_send(pc);
-
- // Only return early if the '[' was determined to be an OC MSG
- // Otherwise, it could have been a lambda capture list (ie '[&]')
- if (pc->GetParentType() == CT_OC_MSG)
- {
- return; // objective-c_50003
- }
- }
- }
-
- if (pc->Is(CT_OC_PROPERTY))
- {
- handle_oc_property_decl(pc);
- return;
- }
-
- if (pc->Is(CT_OC_AVAILABLE))
- {
- handle_oc_available(pc);
- return;
- }
- }
-
- // C# and Vala stuff
- if (language_is_set(LANG_CS | LANG_VALA))
- {
- // '[assembly: xxx]' stuff
- if ( language_is_set(LANG_CS)
- && pc->TestFlags(PCF_EXPR_START)
- && pc->Is(CT_SQUARE_OPEN))
- {
- handle_cs_square_stmt(pc);
- return;
- }
-
- if ( language_is_set(LANG_CS)
- && next->Is(CT_BRACE_OPEN)
- && next->GetParentType() == CT_NONE
- && ( pc->Is(CT_SQUARE_CLOSE)
- || pc->Is(CT_ANGLE_CLOSE)
- || pc->Is(CT_WORD)))
- {
- handle_cs_property(next);
- return;
- }
-
- if ( pc->Is(CT_SQUARE_CLOSE)
- && next->Is(CT_WORD))
- {
- handle_cs_array_type(pc);
- return;
- }
-
- if ( ( pc->Is(CT_LAMBDA)
- || pc->Is(CT_DELEGATE))
- && next->Is(CT_BRACE_OPEN))
- {
- set_paren_parent(next, pc->GetType());
- return;
- }
-
- if ( language_is_set(LANG_CS)
- && pc->Is(CT_WHEN)
- && pc->GetNext()->IsNotNullChunk()
- && pc->GetNext()->IsNot(CT_SPAREN_OPEN))
- {
- pc->SetType(CT_WORD);
- return;
- }
- }
-
- if ( language_is_set(LANG_JAVA)
- && pc->Is(CT_LAMBDA)
- && next->Is(CT_BRACE_OPEN))
- {
- set_paren_parent(next, pc->GetType());
- return;
- }
-
- if (pc->Is(CT_NEW))
- {
- Chunk *ts = Chunk::NullChunkPtr;
- Chunk *tmp = next;
-
- if (tmp->Is(CT_TSQUARE))
- {
- ts = tmp;
- tmp = tmp->GetNextNcNnl();
- }
-
- if ( tmp->Is(CT_BRACE_OPEN)
- || tmp->Is(CT_PAREN_OPEN))
- {
- set_paren_parent(tmp, pc->GetType());
-
- if (ts->IsNotNullChunk())
- {
- ts->SetParentType(pc->GetType());
- }
- }
- return;
- }
-
- // C++11 Lambda stuff
- if ( language_is_set(LANG_CPP)
- && ( pc->Is(CT_SQUARE_OPEN)
- || pc->Is(CT_TSQUARE)))
- {
- handle_cpp_lambda(pc);
- }
-
- // FIXME: which language does this apply to?
- // Issue #2432
- if (!language_is_set(LANG_OC))
- {
- if ( pc->Is(CT_ASSIGN)
- && next->Is(CT_SQUARE_OPEN))
- {
- set_paren_parent(next, CT_ASSIGN);
-
- // Mark one-liner assignment
- Chunk *tmp = next;
-
- while ((tmp = tmp->GetNextNc())->IsNotNullChunk())
- {
- if (tmp->IsNewline())
- {
- break;
- }
-
- if ( tmp->Is(CT_SQUARE_CLOSE)
- && next->GetLevel() == tmp->GetLevel())
- {
- tmp->SetFlagBits(PCF_ONE_LINER);
- next->SetFlagBits(PCF_ONE_LINER);
- break;
- }
- }
- return;
- }
- }
-
- if (pc->Is(CT_ASSERT))
- {
- handle_java_assert(pc);
- return;
- }
-
- if (pc->Is(CT_ANNOTATION))
- {
- Chunk *tmp = pc->GetNextNcNnl();
-
- if (tmp->IsParenOpen())
- {
- set_paren_parent(tmp, CT_ANNOTATION);
- }
- return;
- }
-
- if ( pc->Is(CT_SIZEOF)
- && language_is_set(LANG_ALLC))
- {
- Chunk *tmp = pc->GetNextNcNnl();
-
- if (tmp->Is(CT_ELLIPSIS))
- {
- tmp->SetParentType(CT_SIZEOF);
- }
- return;
- }
-
- if ( pc->Is(CT_DECLTYPE)
- && pc->GetParentType() != CT_FUNC_DEF)
- {
- Chunk *tmp = pc->GetNextNcNnl();
-
- if (tmp->IsParenOpen())
- {
- // decltype may be followed by a braced-init-list
- tmp = set_paren_parent(tmp, CT_DECLTYPE);
-
- if (tmp->IsBraceOpen() && !pc->TestFlags(PCF_IN_LAMBDA))
- {
- tmp = set_paren_parent(tmp, CT_BRACED_INIT_LIST);
-
- if (tmp->IsNotNullChunk())
- {
- tmp->ResetFlagBits(PCF_EXPR_START | PCF_STMT_START);
- }
- }
- else
- {
- if (tmp->Is(CT_WORD))
- {
- tmp->SetFlagBits(PCF_VAR_1ST_DEF);
- }
- }
- }
- return;
- }
-
- // A [] in C#, D and Vala only follows a type
- if ( pc->Is(CT_TSQUARE)
- && language_is_set(LANG_D | LANG_CS | LANG_VALA))
- {
- if (prev->Is(CT_WORD))
- {
- prev->SetType(CT_TYPE);
- }
-
- if (next->Is(CT_WORD))
- {
- next->SetFlagBits(PCF_VAR_1ST_DEF);
- }
- return;
- }
-
- if ( pc->Is(CT_SQL_EXEC)
- || pc->Is(CT_SQL_BEGIN)
- || pc->Is(CT_SQL_END))
- {
- mark_exec_sql(pc);
- return;
- }
-
- if (pc->Is(CT_PROTO_WRAP))
- {
- handle_proto_wrap(pc);
- return;
- }
-
- // Handle the typedef
- if (pc->Is(CT_TYPEDEF))
- {
- fix_typedef(pc);
- return;
- }
-
- if ( pc->IsClassEnumStructOrUnion()
- && prev->IsNot(CT_TYPEDEF))
- {
- // Issue #3811
- // Sometimes the enum chunk can exist in a parameter (ie. `void foo(enum EnumType param)`)
- // In this case we don't need to run the parser since we are not declaring an enum.
- if (pc->IsEnum())
- {
- const size_t level = pc->GetLevel();
- Chunk *tmp = pc;
-
- while (tmp->GetLevel() == level && tmp->IsNotNullChunk())
- {
- tmp = tmp->GetNextNcNnl();
- }
-
- if (tmp->GetLevel() < level)
- {
- return;
- }
- }
- EnumStructUnionParser parser;
- parser.parse(pc);
- return;
- }
-
- if (pc->Is(CT_EXTERN))
- {
- if (next->IsParenOpen())
- {
- Chunk *tmp = flag_parens(next, PCF_NONE, CT_NONE, CT_EXTERN, true);
-
- if (tmp->Is(CT_BRACE_OPEN))
- {
- set_paren_parent(tmp, CT_EXTERN);
- }
- }
- else
- {
- // next likely is a string (see tokenize_cleanup.cpp)
- next->SetParentType(CT_EXTERN);
- Chunk *tmp = next->GetNextNcNnl();
-
- if (tmp->Is(CT_BRACE_OPEN))
- {
- set_paren_parent(tmp, CT_EXTERN);
- }
- }
- return;
- }
-
- if (pc->Is(CT_TEMPLATE))
- {
- if (language_is_set(LANG_D))
- {
- handle_d_template(pc);
- }
- else
- {
- handle_cpp_template(pc);
- }
- return;
- }
-
- if ( pc->Is(CT_WORD)
- && next->Is(CT_ANGLE_OPEN)
- && next->GetParentType() == CT_TEMPLATE)
- {
- mark_template_func(pc, next);
- return;
- }
-
- if ( pc->Is(CT_SQUARE_CLOSE)
- && next->Is(CT_PAREN_OPEN))
- {
- flag_parens(next, PCF_NONE, CT_FPAREN_OPEN, CT_NONE, false);
- return;
- }
-
- if (pc->Is(CT_TYPE_CAST))
- {
- fix_type_cast(pc);
- return;
- }
-
- if ( pc->GetParentType() == CT_ASSIGN
- && ( pc->Is(CT_BRACE_OPEN)
- || pc->Is(CT_SQUARE_OPEN)))
- {
- // Mark everything in here as in assign
- flag_parens(pc, PCF_IN_ARRAY_ASSIGN, pc->GetType(), CT_NONE, false);
- return;
- }
-
- if (pc->Is(CT_D_TEMPLATE))
- {
- set_paren_parent(next, pc->GetType());
- return;
- }
-
- /*
- * A word before an open paren is a function call or definition.
- * CT_WORD => CT_FUNC_CALL or CT_FUNC_DEF
- */
- if (next->Is(CT_PAREN_OPEN))
- {
- Chunk *tmp = next->GetNextNcNnl();
-
- if ( language_is_set(LANG_C | LANG_CPP | LANG_OC)
- && tmp->Is(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->Is(CT_OC_BLOCK_CARET)
- || tmp->Is(CT_CARET))
- && pc->Is(CT_WORD))
- {
- LOG_FMT(LFCN, "%s(%d): (1) SET TO CT_FUNC_CALL: orig line is %zu, orig col is %zu, Text() '%s'\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
- pc->SetType(CT_FUNC_CALL);
- }
- }
- else if ( pc->Is(CT_WORD)
- || pc->Is(CT_OPERATOR_VAL))
- {
- pc->SetType(CT_FUNCTION);
- }
- else if (pc->Is(CT_FIXED))
- {
- pc->SetType(CT_FUNCTION);
- pc->SetParentType(CT_FIXED);
- }
- else if (pc->Is(CT_TYPE))
- {
- /*
- * If we are on a type, then we are either on a C++ style cast, an
- * array reference, 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...
- */
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s'\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
-
- bool is_byref_array = false;
-
- if (language_is_set(LANG_CPP))
- {
- // If the open paren is followed by an ampersand, an optional word,
- // a close parenthesis, and an open square bracket, then it is an
- // array being passed by reference, not a cast
- tmp = next->GetNextNcNnl();
-
- if (tmp->Is(CT_AMP))
- {
- auto tmp2 = tmp->GetNextNcNnl();
-
- if (tmp2->Is(CT_WORD))
- {
- tmp2 = tmp2->GetNextNcNnl();
- }
-
- if (tmp2->Is(CT_PAREN_CLOSE))
- {
- tmp2 = tmp2->GetNextNcNnl();
-
- if (tmp2->Is(CT_SQUARE_OPEN))
- {
- is_byref_array = true;
- tmp->SetType(CT_BYREF);
- }
- }
- }
- }
-
- if (!is_byref_array)
- {
- tmp = next->GetNextType(CT_PAREN_CLOSE, next->GetLevel());
-
- if (tmp->IsNotNullChunk())
- {
- tmp = tmp->GetNext();
-
- if (tmp->Is(CT_PAREN_OPEN))
- {
- pc->SetType(CT_FUNCTION);
- }
- else
- {
- if ( pc->GetParentType() == CT_NONE
- && !pc->TestFlags(PCF_IN_TYPEDEF))
- {
- tmp = next->GetNextNcNnl();
-
- if (tmp->Is(CT_PAREN_CLOSE))
- {
- // we have TYPE()
- pc->SetType(CT_FUNCTION);
- }
- else
- {
- // we have TYPE(...)
- pc->SetType(CT_CPP_CAST);
- set_paren_parent(next, CT_CPP_CAST);
- }
- }
- }
- }
- }
- }
- }
-
- if (language_is_set(LANG_PAWN))
- {
- if ( pc->Is(CT_FUNCTION)
- && pc->GetBraceLevel() > 0)
- {
- LOG_FMT(LFCN, "%s(%d): (2) SET TO CT_FUNC_CALL: orig line is %zu, orig col is %zu, Text() '%s'\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
- pc->SetType(CT_FUNC_CALL);
- }
-
- if ( pc->Is(CT_STATE)
- && next->Is(CT_PAREN_OPEN))
- {
- set_paren_parent(next, pc->GetType());
- }
- }
- else
- {
- if ( ( pc->Is(CT_FUNCTION)
- || pc->Is(CT_FUNC_DEF))
- && ( (pc->GetParentType() == CT_OC_BLOCK_EXPR)
- || !is_oc_block(pc)))
- {
- mark_function(pc);
- }
- }
-
- // Detect C99 member stuff
- if ( pc->Is(CT_MEMBER)
- && ( prev->Is(CT_COMMA)
- || prev->Is(CT_BRACE_OPEN)))
- {
- pc->SetType(CT_C99_MEMBER);
- next->SetParentType(CT_C99_MEMBER);
- return;
- }
-
- // Mark function parens and braces
- if ( pc->Is(CT_FUNC_DEF)
- || pc->Is(CT_FUNC_CALL)
- || pc->Is(CT_FUNC_CALL_USER)
- || pc->Is(CT_FUNC_PROTO))
- {
- Chunk *tmp = next;
-
- if (tmp->Is(CT_SQUARE_OPEN))
- {
- tmp = set_paren_parent(tmp, pc->GetType());
- }
- else if ( tmp->Is(CT_TSQUARE)
- || tmp->GetParentType() == CT_OPERATOR)
- {
- tmp = tmp->GetNextNcNnl();
- }
-
- if (tmp->IsNotNullChunk())
- {
- if (tmp->IsParenOpen())
- {
- tmp = flag_parens(tmp, PCF_NONE, CT_FPAREN_OPEN, pc->GetType(), false);
-
- if (tmp->IsNotNullChunk())
- {
- if (tmp->Is(CT_BRACE_OPEN))
- {
- if ( tmp->GetParentType() != CT_DOUBLE_BRACE
- && !pc->TestFlags(PCF_IN_CONST_ARGS))
- {
- set_paren_parent(tmp, pc->GetType());
- }
- }
- else if ( tmp->IsSemicolon()
- && pc->Is(CT_FUNC_PROTO))
- {
- tmp->SetParentType(pc->GetType());
- }
- }
- }
- }
- return;
- }
-
- // Mark the parameters in catch()
- if ( pc->Is(CT_CATCH)
- && next->Is(CT_SPAREN_OPEN))
- {
- fix_fcn_def_params(next);
- return;
- }
-
- if ( pc->Is(CT_THROW)
- && prev->Is(CT_FPAREN_CLOSE))
- {
- pc->SetParentType(prev->GetParentType());
-
- if (next->Is(CT_PAREN_OPEN))
- {
- set_paren_parent(next, CT_THROW);
- }
- return;
- }
-
- // Mark the braces in: "for_each_entry(xxx) { }"
- if ( pc->Is(CT_BRACE_OPEN)
- && pc->GetParentType() != CT_DOUBLE_BRACE
- && prev->Is(CT_FPAREN_CLOSE)
- && ( prev->GetParentType() == CT_FUNC_CALL
- || prev->GetParentType() == CT_FUNC_CALL_USER)
- && !pc->TestFlags(PCF_IN_CONST_ARGS))
- {
- LOG_FMT(LFCN, "%s(%d): (3) SET TO CT_FUNC_CALL: orig line is %zu, orig col is %zu, Text() '%s'\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
- set_paren_parent(pc, CT_FUNC_CALL);
- return;
- }
-
- /*
- * Check for a close parenthesis followed by an open parenthesis,
- * which means that we are on a function type declaration (C/C++ only?).
- * Note that typedefs are already taken care of.
- */
- if ( !pc->TestFlags(PCF_IN_TEMPLATE) // Issue #3252
- && pc->GetParentType() != CT_CPP_CAST
- && pc->GetParentType() != CT_C_CAST
- && !pc->TestFlags(PCF_IN_PREPROC)
- && !is_oc_block(pc)
- && pc->GetParentType() != CT_OC_MSG_DECL
- && pc->GetParentType() != CT_OC_MSG_SPEC
- && ( pc->IsString(")")
- || pc->Is(CT_FUNC_TYPE))
- && next->IsString("("))
- {
- if (language_is_set(LANG_D))
- {
- flag_parens(next, PCF_NONE, CT_FPAREN_OPEN, CT_FUNC_CALL, false);
- }
- else
- {
- mark_function_type(pc);
- }
- return;
- }
-
- if (pc->Is(CT_OC_CLASS))
- {
- handle_oc_class(pc);
- return;
- }
- // TODO: Check for stuff that can only occur at the start of an statement
-
- if (!language_is_set(LANG_D))
- {
- /*
- * Check a parenthesis pair to see if it is a cast.
- * Note that SPAREN and FPAREN have already been marked.
- */
- if ( pc->Is(CT_PAREN_OPEN)
- && ( pc->GetParentType() == CT_NONE
- || pc->GetParentType() == CT_OC_MSG
- || pc->GetParentType() == CT_OC_BLOCK_EXPR
- || pc->GetParentType() == CT_CS_SQ_STMT) // Issue # 1256
- && ( next->Is(CT_WORD)
- || next->Is(CT_TYPE)
- || next->Is(CT_STRUCT)
- || next->Is(CT_QUALIFIER)
- || next->Is(CT_MEMBER)
- || next->Is(CT_DC_MEMBER)
- || next->Is(CT_ENUM)
- || next->Is(CT_UNION))
- && prev->IsNot(CT_DECLTYPE)
- && prev->IsNot(CT_SIZEOF)
- && prev->GetParentType() != CT_SIZEOF
- && prev->GetParentType() != CT_OPERATOR
- && !pc->TestFlags(PCF_IN_TYPEDEF))
- {
- fix_casts(pc);
- return;
- }
- }
-
- if (language_is_set(LANG_CPP))
- {
- Chunk *nnext = next->GetNextNcNnl();
-
- // handle parent_type of assigns in special functions (ro5 + pure virtual)
- if ( pc->GetFlags().test_any(PCF_IN_STRUCT | PCF_IN_CLASS)
- && pc->Is(CT_ASSIGN)
- && nnext->Is(CT_SEMICOLON)
- && ( next->Is(CT_DEFAULT)
- || next->Is(CT_DELETE)
- || ( next->Is(CT_NUMBER)
- && next->IsString("0"))))
- {
- const size_t level = pc->GetLevel();
- bool found_status = false;
- Chunk *pprev = pc->GetPrev();
-
- for ( ; ( pprev->IsNotNullChunk()
- && pprev->GetLevel() >= level
- && pprev->IsNot(CT_SEMICOLON)
- && pprev->IsNot(CT_ACCESS_COLON))
- ; pprev = pprev->GetPrev())
- {
- if (pprev->GetLevel() != level)
- {
- continue;
- }
-
- if (next->Is(CT_NUMBER))
- {
- if ( pprev->Is(CT_QUALIFIER)
- && pprev->IsString("virtual"))
- {
- found_status = true;
- break;
- }
- }
- else
- {
- if ( pprev->Is(CT_FUNC_CLASS_PROTO) // ctor/dtor
- || pprev->Is(CT_FUNC_PROTO)) // normal function
- {
- found_status = true;
- break;
- }
- }
- }
-
- if (found_status)
- {
- pc->SetParentType(pprev->GetType());
- }
- }
-
- if (detect_cpp_braced_init_list(pc, next))
- {
- flag_cpp_braced_init_list(pc, next);
- }
- }
-
- // Check for stuff that can only occur at the start of an expression
- if ( pc->TestFlags(PCF_EXPR_START)
- || ( prev->TestFlags(PCF_EXPR_START)
- && pc->GetParentType() == CT_OC_AT))
- {
- // Change STAR, MINUS, and PLUS in the easy cases
- if (pc->Is(CT_STAR))
- {
- // issue #596
- // [0x100062020:IN_SPAREN,IN_FOR,STMT_START,EXPR_START,PUNCTUATOR]
- // prev->GetType() is CT_COLON ==> CT_DEREF
- if (prev->Is(CT_ANGLE_CLOSE))
- {
- pc->SetType(CT_PTR_TYPE);
- }
- else if (prev->Is(CT_COLON))
- {
- pc->SetType(CT_DEREF);
- }
- else
- {
- pc->SetType(CT_DEREF);
- }
- }
-
- if ( language_is_set(LANG_CPP)
- && pc->Is(CT_CARET)
- && prev->Is(CT_ANGLE_CLOSE))
- {
- pc->SetType(CT_PTR_TYPE);
- }
-
- if ( language_is_set(LANG_CS | LANG_VALA)
- && pc->Is(CT_QUESTION)
- && prev->Is(CT_ANGLE_CLOSE))
- {
- pc->SetType(CT_PTR_TYPE);
- }
-
- else if (pc->Is(CT_MINUS))
- {
- pc->SetType(CT_NEG);
- }
-
- else if (pc->Is(CT_PLUS))
- {
- pc->SetType(CT_POS);
- }
-
- else if (pc->Is(CT_INCDEC_AFTER))
- {
- pc->SetType(CT_INCDEC_BEFORE);
- }
-
- else if (pc->Is(CT_AMP))
- {
- if (prev->Is(CT_ANGLE_CLOSE)) // Issue #2324
- {
- pc->SetType(CT_BYREF);
- }
- else
- {
- pc->SetType(CT_ADDR);
- }
- }
-
- else if (pc->Is(CT_CARET))
- {
- if (language_is_set(LANG_C | LANG_CPP | LANG_OC))
- {
- // This is likely the start of a block literal
- handle_oc_block_literal(pc);
- }
- }
- }
-
- /*
- * Change the parenthesis pair after a function/macro-function
- * CT_PAREN_OPEN => CT_FPAREN_OPEN
- */
- if (pc->Is(CT_MACRO_FUNC))
- {
- flag_parens(next, PCF_IN_FCN_CALL, CT_FPAREN_OPEN, CT_MACRO_FUNC, false);
- }
-
- if ( pc->Is(CT_MACRO_OPEN)
- || pc->Is(CT_MACRO_ELSE)
- || pc->Is(CT_MACRO_CLOSE))
- {
- if (next->Is(CT_PAREN_OPEN))
- {
- flag_parens(next, PCF_NONE, CT_FPAREN_OPEN, pc->GetType(), false);
- }
- }
-
- if ( pc->Is(CT_DELETE)
- && next->Is(CT_TSQUARE))
- {
- next->SetParentType(CT_DELETE);
- }
-
- // Change CT_STAR to CT_PTR_TYPE or CT_ARITH or CT_DEREF
- if ( pc->Is(CT_STAR)
- || ( language_is_set(LANG_CPP)
- && pc->Is(CT_CARET)))
- {
- if ( next->IsParenClose()
- || next->Is(CT_COMMA))
- {
- pc->SetType(CT_PTR_TYPE);
- }
- else if ( language_is_set(LANG_OC)
- && next->Is(CT_STAR))
- {
- /*
- * Change pointer-to-pointer types in OC_MSG_DECLs
- * from ARITH <===> DEREF to PTR_TYPE <===> PTR_TYPE
- */
- pc->SetType(CT_PTR_TYPE);
- pc->SetParentType(prev->GetParentType());
-
- next->SetType(CT_PTR_TYPE);
- next->SetParentType(pc->GetParentType());
- }
- else if ( pc->Is(CT_STAR)
- && ( prev->Is(CT_DECLTYPE)
- || prev->Is(CT_SIZEOF)
- || prev->Is(CT_DELETE)
- || pc->GetParentType() == CT_SIZEOF))
- {
- pc->SetType(CT_DEREF);
- }
- else if ( ( prev->Is(CT_WORD)
- && chunk_ends_type(prev)
- && !prev->TestFlags(PCF_IN_FCN_CTOR)
- && !prev->TestFlags(PCF_IN_ARRAY_ASSIGN)) // Issue #3345
- || prev->Is(CT_DC_MEMBER)
- || prev->Is(CT_PTR_TYPE))
- {
- LOG_FMT(LFCNR, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n ",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType()));
- log_pcf_flags(LFCNR, pc->GetFlags());
- pc->SetType(CT_PTR_TYPE);
- }
- else if ( next->Is(CT_SQUARE_OPEN)
- && !language_is_set(LANG_OC)) // Issue #408
- {
- pc->SetType(CT_PTR_TYPE);
- }
- else if (pc->Is(CT_STAR))
- {
- // Add check for CT_DC_MEMBER CT_WORD CT_STAR sequence
- // to convert CT_WORD into CT_TYPE
- // and CT_STAR into CT_PTR_TYPE
- // look for an assign backward, function call, return to distinguish between
- // double result = Constants::PI * factor;
- // and
- // ::some::name * foo;
- if ( prev->Is(CT_WORD)
- && prev->GetPrev()->Is(CT_DC_MEMBER)
- && language_is_set(LANG_CPP))
- {
- // Issue 1402
- bool is_multiplication = false;
- Chunk *tmp = pc;
-
- while (tmp->IsNotNullChunk())
- {
- if ( tmp->Is(CT_SEMICOLON)
- || tmp->GetParentType() == CT_CLASS)
- {
- break;
- }
- else if ( tmp->Is(CT_ASSIGN)
- || tmp->Is(CT_FUNC_CALL)
- || tmp->Is(CT_RETURN))
- {
- is_multiplication = true;
- break;
- }
- tmp = tmp->GetPrevNcNnlNi(); // Issue #2279
- }
-
- if (is_multiplication)
- {
- // double result = Constants::PI * factor;
- pc->SetType(CT_ARITH);
- }
- else
- {
- // ::some::name * foo;
- prev->SetType(CT_TYPE);
- pc->SetType(CT_PTR_TYPE);
- }
- }
-
- /*
- * A star can have three meanings
- * 1. CT_DEREF = pointer dereferencing
- * 2. CT_PTR_TYPE = pointer definition
- * 3. CT_ARITH = arithmetic multiplication
- *
- * 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->Is(CT_TYPE))
- {
- pc->SetType(CT_PTR_TYPE);
- }
- else if ( pc->GetNext()->Is(CT_SEMICOLON) // Issue #2319
- || ( pc->GetNext()->Is(CT_STAR)
- && pc->GetNext()->GetNext()->Is(CT_SEMICOLON)))
- {
- // example:
- // using AbstractLinkPtr = AbstractLink*;
- // using AbstractLinkPtrPtr = AbstractLink**;
- pc->SetType(CT_PTR_TYPE);
- }
- else if ( ( pc->GetParentType() == CT_FUNC_DEF
- && ( next->IsBraceOpen()
- || pc->GetNext()->IsStar()))
- || next->Is(CT_QUALIFIER)) // Issue #2648
- {
- // example:
- // auto getComponent(Color *color) -> Component * {
- // auto getComponent(Color *color) -> Component ** {
- // auto getComponent(Color *color) -> Component * _Nonnull
- // only to help the vim command }}
- pc->SetType(CT_PTR_TYPE);
- }
- else if ( pc->GetNext()->Is(CT_SEMICOLON) // Issue #2319
- || ( pc->GetNext()->Is(CT_STAR)
- && pc->GetNext()->GetNext()->Is(CT_STAR)))
- {
- // more pointers are NOT yet possible
- fprintf(stderr, "Too many pointers: the maximum level of pointer indirection is 3 (i.e., ***p)\n");
- fprintf(stderr, "at line %zu, column %zu.\n", pc->GetOrigLine(), pc->GetOrigCol());
- fprintf(stderr, "Please make a report.\n");
- log_flush(true);
- exit(EX_SOFTWARE);
- }
- else if ( !prev->TestFlags(PCF_PUNCTUATOR)
- || prev->Is(CT_INCDEC_AFTER)
- || prev->Is(CT_SQUARE_CLOSE)
- || prev->Is(CT_DC_MEMBER)) // Issue 1402
- {
- pc->SetType(CT_ARITH);
- }
- else if ( !prev->IsParenClose()
- || prev->Is(CT_SPAREN_CLOSE)
- || prev->GetParentType() == CT_MACRO_FUNC)
- {
- pc->SetType(CT_DEREF);
- }
- else
- {
- pc->SetType(CT_ARITH);
- }
-
- if (pc->TestFlags(PCF_IN_TYPEDEF)) // Issue #1255/#633
- {
- Chunk *tmp = pc;
-
- while (tmp->IsNotNullChunk())
- {
- if ( tmp->Is(CT_SEMICOLON)
- || tmp->Is(CT_BRACE_OPEN)
- || tmp->Is(CT_SQUARE_OPEN)) // Issue #3342
- {
- break;
- }
- else if (tmp->Is(CT_TYPEDEF))
- {
- pc->SetType(CT_PTR_TYPE);
- }
- tmp = tmp->GetPrevNcNnlNi(); // Issue #2279
- }
- }
- }
- }
-
- if (pc->Is(CT_AMP))
- {
- Chunk *prevNext = prev->GetNext();
-
- if (prev->Is(CT_DELETE))
- {
- pc->SetType(CT_ADDR);
- }
- else if ( prev->Is(CT_TYPE)
- || prev->Is(CT_QUALIFIER)
- || prevNext->Is(CT_QUALIFIER))
- {
- pc->SetType(CT_BYREF);
- }
- else if ( prev->Is(CT_WORD) // Issue #3204
- && next->Is(CT_OPERATOR))
- {
- pc->SetType(CT_BYREF);
- }
- else if ( next->Is(CT_FPAREN_CLOSE)
- || next->Is(CT_COMMA))
- {
- // fix the bug #654
- // connect(&mapper, SIGNAL(mapped(QString &)), this, SLOT(onSomeEvent(QString &)));
- pc->SetType(CT_BYREF);
- }
- else if (pc->GetParentType() == CT_USING_ALIAS)
- {
- // fix the Issue # 1689
- // using reference = value_type &;
- pc->GetPrev()->SetType(CT_TYPE);
- pc->SetType(CT_BYREF);
- }
- else
- {
- // Issue # 1398
- if ( pc->TestFlags(PCF_IN_FCN_DEF)
- && prev->Is(CT_WORD)
- && pc->Is(CT_AMP)
- && next->Is(CT_WORD))
- {
- /*
- * Change CT_WORD before CT_AMP before CT_WORD to CT_TYPE
- */
- prev->SetType(CT_TYPE);
- }
- else if ( pc->TestFlags(PCF_IN_PREPROC) // Issue #3559
- && prev->IsNot(CT_WORD) // Issue #2205
- && pc->Is(CT_AMP)
- && next->Is(CT_WORD)
- && !pc->TestFlags(PCF_IN_SPAREN))
- {
- pc->SetType(CT_ADDR);
- }
- else
- {
- pc->SetType(CT_ARITH);
-
- if ( prev->Is(CT_WORD)
- && next->IsNot(CT_NUMBER)) // Issue #3407
- {
- Chunk *tmp = prev->GetPrevNcNnlNi(); // Issue #2279
-
- if (tmp->IsNotNullChunk())
- {
- if ( tmp->IsSemicolon()
- || tmp->Is(CT_BRACE_OPEN)
- || tmp->Is(CT_QUALIFIER))
- {
- pc->SetType(CT_BYREF);
- prev->SetType(CT_TYPE);
-
- if (!( next->Is(CT_OPERATOR)
- || next->Is(CT_TYPE)
- || next->Is(CT_DC_MEMBER)))
- {
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s', set PCF_VAR_1ST\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
- next->SetFlagBits(PCF_VAR_1ST);
- }
- }
- else if (tmp->Is(CT_DC_MEMBER))
- {
- // see also Issue #3967
- // Issue #2103 & Issue #3865: partial fix
- // No easy way to tell between an enum and a type with
- // a namespace qualifier. Compromise: if we're in a
- // function def or call, assume it's a ref.
- Chunk *nextNext = next->GetNext();
-
- if ( nextNext->IsNot(CT_DC_MEMBER)
- && ( pc->TestFlags(PCF_IN_FCN_CALL)
- || pc->TestFlags(PCF_IN_FCN_CTOR)
- || pc->TestFlags(PCF_IN_FCN_DEF)))
- {
- pc->SetType(CT_BYREF);
- }
- else
- {
- prev->SetType(CT_TYPE);
- }
- }
- }
- }
- }
- }
- }
-
- if ( pc->Is(CT_MINUS)
- || pc->Is(CT_PLUS))
- {
- if ( prev->Is(CT_POS)
- || prev->Is(CT_NEG)
- || prev->Is(CT_ARITH)
- || prev->Is(CT_SHIFT))
- {
- pc->SetType(pc->Is(CT_MINUS) ? CT_NEG : CT_POS);
- }
- else if (prev->Is(CT_OC_CLASS))
- {
- pc->SetType((pc->Is(CT_MINUS)) ? CT_NEG : CT_POS);
- }
- else
- {
- pc->SetType(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->Is(CT_WORD)) // here NSString
- {
- Chunk *pcNext = pc->GetNext();
- Chunk *pcPrev = pc->GetPrev();
-
- if (pcNext->Is(CT_STAR)) // here *
- {
- // compare text with "C" to find extern "C" instructions
- if (pcPrev->Is(CT_STRING))
- {
- if (UncText::compare(pcPrev->Text(), "\"C\"") == 0)
- {
- if (pcPrev->GetPrev()->Is(CT_EXTERN))
- {
- pc->SetType(CT_TYPE); // change CT_WORD => CT_TYPE
- pcNext->SetType(CT_PTR_TYPE); // change CT_STAR => CT_PTR_TYPE
- }
- }
- }
- // Issue #322 STDMETHOD(GetValues)(BSTR bsName, REFDATA** pData);
- Chunk *nnext = pcNext->GetNext();
-
- if ( nnext->Is(CT_STAR)
- && pc->TestFlags(PCF_IN_CONST_ARGS))
- {
- // change CT_STAR => CT_PTR_TYPE
- pcNext->SetType(CT_PTR_TYPE);
- nnext->SetType(CT_PTR_TYPE);
- }
-
- // Issue #222 whatever3 *(func_ptr)( whatever4 *foo2, ...
- if ( nnext->Is(CT_WORD)
- && pc->TestFlags(PCF_IN_FCN_DEF))
- {
- // look for the opening parenthesis
- // Issue 1403
- Chunk *tmp = pc->GetPrevType(CT_FPAREN_OPEN, pc->GetLevel() - 1);
-
- if ( tmp->IsNotNullChunk()
- && tmp->GetParentType() != CT_FUNC_CTOR_VAR)
- {
- pcNext->SetType(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->Is(CT_WORD)) // here NSString
- {
- Chunk *pcNext = pc->GetNext();
-
- if (pcNext->Is(CT_STAR)) // here *
- {
- Chunk *tmp = pc;
-
- while (tmp->IsNotNullChunk())
- {
- if (tmp->Is(CT_ATTRIBUTE))
- {
- LOG_FMT(LFCNR, "%s(%d): ATTRIBUTE found, type is %s, Text() '%s'\n",
- __func__, __LINE__, get_token_name(tmp->GetType()), tmp->Text());
- LOG_FMT(LFCNR, "for token, type is %s, Text() '%s'\n", get_token_name(pc->GetType()), pc->Text());
- // change CT_WORD => CT_TYPE
- pc->SetType(CT_TYPE);
- // change CT_STAR => CT_PTR_TYPE
- pcNext->SetType(CT_PTR_TYPE);
- }
-
- if (tmp->TestFlags(PCF_STMT_START))
- {
- // we are at beginning of the line
- break;
- }
- tmp = tmp->GetPrev();
- }
- }
- }
-
- /*
- * Issue # 1689
- * Check for using reference = value_type&;
- * is it a Type alias, alias template?
- */
- if (pc->Is(CT_USING))
- {
- // look for CT_ASSIGN before CT_SEMICOLON at the end of the statement
-
- bool is_preproc = pc->TestFlags(PCF_IN_PREPROC);
- auto const search_assign = [&pc, &is_preproc]()
- {
- for (Chunk *temp = pc; temp->IsNotNullChunk(); temp = temp->GetNextNcNnl())
- {
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s', type is %s\n",
- __func__, __LINE__, temp->GetOrigLine(), temp->GetOrigCol(),
- temp->Text(), get_token_name(temp->GetType()));
-
- if (temp->Is(CT_ASSIGN))
- {
- return(true);
- }
-
- if ( temp->Is(CT_SEMICOLON)
- || ( is_preproc
- && ( !temp->TestFlags(PCF_IN_PREPROC)
- || temp->Is(CT_PREPROC))))
- {
- return(false);
- }
- }
-
- return(false);
- };
-
- const bool assign_found = language_is_set(LANG_D) || search_assign();
-
- if (assign_found)
- {
- // it is a Type alias, alias template
- for (Chunk *temp = pc; temp->IsNotNullChunk(); temp = temp->GetNextNcNnl())
- {
- if (temp->GetParentType() == CT_NONE)
- {
- temp->SetParentType(CT_USING_ALIAS);
- }
-
- if ( temp->Is(CT_SEMICOLON)
- || ( is_preproc
- && ( !temp->TestFlags(PCF_IN_PREPROC)
- || temp->Is(CT_PREPROC))))
- {
- break;
- }
- }
- }
- }
-
- // Issue #548: inline T && someFunc(foo * *p, bar && q) { }
- if ( pc->Is(CT_BOOL)
- && !pc->TestFlags(PCF_IN_PREPROC)
- && pc->IsString("&&")
- && chunk_ends_type(pc->GetPrev()))
- {
- Chunk *tmp = pc->GetPrev(); // Issue #2688
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s', type is %s\n",
- __func__, __LINE__, tmp->GetOrigLine(), tmp->GetOrigCol(),
- tmp->Text(), get_token_name(tmp->GetType()));
- log_pcf_flags(LFCNR, tmp->GetFlags());
- // look for a type
-
- if (tmp->Is(CT_TYPE))
- {
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s', type is %s\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(),
- pc->Text(), get_token_name(pc->GetType()));
- log_pcf_flags(LFCNR, pc->GetFlags());
- pc->SetType(CT_BYREF);
- }
- // look next, is there a "assign" before the ";"
- Chunk *semi = pc->GetNextType(CT_SEMICOLON, pc->GetLevel()); // Issue #2688
-
- if (semi->IsNotNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s', type is %s\n",
- __func__, __LINE__, semi->GetOrigLine(), semi->GetOrigCol(),
- semi->Text(), get_token_name(semi->GetType()));
-
- for (Chunk *test_it = pc; test_it != semi; test_it = test_it->GetNext())
- {
- LOG_FMT(LFCNR, "%s(%d): test_it orig line is %zu, orig col is %zu, Text() '%s', type is %s\n",
- __func__, __LINE__, test_it->GetOrigLine(), test_it->GetOrigCol(),
- test_it->Text(), get_token_name(test_it->GetType()));
-
- if (test_it->Is(CT_ASSIGN))
- {
- // the statement is an assignment
- // && is before assign
- pc->SetType(CT_BYREF);
- break;
- }
- }
- }
- }
-
- // Issue #1704
- if ( pc->Is(CT_INCDEC_AFTER)
- && pc->TestFlags(PCF_IN_PREPROC))
- {
- Chunk *tmp_2 = pc->GetNext();
- LOG_FMT(LFCNR, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s', type is %s\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(),
- pc->Text(), get_token_name(pc->GetType()));
- log_pcf_flags(LFTYPE, pc->GetFlags());
-
- if (tmp_2->Is(CT_WORD))
- {
- pc->SetType(CT_INCDEC_BEFORE);
- }
- }
-} // do_symbol_check
-
-
-static void check_double_brace_init(Chunk *bo1)
-{
- LOG_FUNC_ENTRY();
- LOG_FMT(LJDBI, "%s(%d): orig line is %zu, orig col is %zu", __func__, __LINE__, bo1->GetOrigLine(), bo1->GetOrigCol());
- Chunk *pc = bo1->GetPrevNcNnlNi(); // Issue #2279
-
- if (pc->IsNullChunk())
- {
- return;
- }
-
- if (pc->IsParenClose())
- {
- Chunk *bo2 = bo1->GetNext();
-
- if (bo2->IsNullChunk())
- {
- return;
- }
-
- if (bo2->Is(CT_BRACE_OPEN))
- {
- // found a potential double brace
- Chunk *bc2 = bo2->GetClosingParen();
-
- if (bc2->IsNullChunk())
- {
- return;
- }
- Chunk *bc1 = bc2->GetNext();
-
- if (bc1->IsNullChunk())
- {
- return;
- }
-
- if (bc1->Is(CT_BRACE_CLOSE))
- {
- LOG_FMT(LJDBI, " - end, orig line is %zu, orig col is %zu\n", bc2->GetOrigLine(), bc2->GetOrigCol());
- // delete bo2 and bc1
- bo1->Str() += bo2->GetStr();
- bo1->SetOrigColEnd(bo2->GetOrigColEnd());
- Chunk::Delete(bo2);
- bo1->SetParentType(CT_DOUBLE_BRACE);
-
- bc2->Str() += bc1->GetStr();
- bc2->SetOrigColEnd(bc1->GetOrigColEnd());
- Chunk::Delete(bc1);
- bc2->SetParentType(CT_DOUBLE_BRACE);
- return;
- }
- }
- }
- LOG_FMT(LJDBI, " - no\n");
-} // check_double_brace_init
-
-
-void fix_symbols()
-{
- LOG_FUNC_ENTRY();
- Chunk *pc;
-
- cpd.unc_stage = unc_stage_e::FIX_SYMBOLS;
-
- mark_define_expressions();
-
- bool is_cpp = language_is_set(LANG_CPP);
- bool is_java = language_is_set(LANG_JAVA);
-
- for (pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNextNcNnl())
- {
- LOG_FMT(LFCNR, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType()));
-
- if ( pc->Is(CT_FUNC_WRAP)
- || pc->Is(CT_TYPE_WRAP))
- {
- handle_wrap(pc);
- }
-
- if (pc->Is(CT_ASSIGN))
- {
- mark_lvalue(pc);
- }
- // a brace immediately preceded by word in C++11 is an initializer list though it may also
- // by a type casting initializer list if the word is really a type; sadly uncrustify knows
- // only built-in types and knows nothing of user-defined types
- Chunk *prev = pc->GetPrevNcNnlNi(); // Issue #2279
-
- if ( is_cpp
- && pc->Is(CT_BRACE_OPEN)
- && ( prev->Is(CT_WORD)
- || prev->Is(CT_TYPE)))
- {
- mark_lvalue(pc);
- }
-
- if ( is_java
- && pc->Is(CT_BRACE_OPEN))
- {
- check_double_brace_init(pc);
- }
-
- if (pc->Is(CT_ATTRIBUTE))
- {
- Chunk *next = pc->GetNextNcNnl(E_Scope::PREPROC);
-
- if ( next->IsNotNullChunk()
- && next->Is(CT_PAREN_OPEN))
- {
- flag_parens(next, PCF_NONE, CT_FPAREN_OPEN, CT_ATTRIBUTE, false);
- }
- }
- }
-
- pc = Chunk::GetHead();
-
- if (pc->IsCommentOrNewline())
- {
- pc = pc->GetNextNcNnl();
- }
-
- while (pc->IsNotNullChunk())
- {
- if (pc->Is(CT_IGNORED))
- {
- pc = pc->GetNextNcNnl();
- continue;
- }
- LOG_FMT(LFCNR, "%s(%d): pc orig line %zu, orig col %zu, text '%s', type %s\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType()));
- Chunk *prev = pc->GetPrevNcNnlNi(E_Scope::PREPROC); // Issue #2279
-
- if (prev->Is(CT_QUALIFIER))
- {
- prev = prev->GetPrevNcNnlNi(E_Scope::PREPROC); // Issue #3513
- }
-
- if (prev->IsNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): prev is NOT defined\n", __func__, __LINE__);
- }
- else
- {
- // Issue #2279
- LOG_FMT(LFCNR, "%s(%d): prev(ni) orig line %zu, orig col %zu, text '%s', type %s\n",
- __func__, __LINE__, prev->GetOrigLine(), prev->GetOrigCol(), prev->Text(), get_token_name(prev->GetType()));
- }
- Chunk *next = pc->GetNextNcNnl(E_Scope::PREPROC);
-
- if (next->IsNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): next is NOT defined\n", __func__, __LINE__);
- }
- else
- {
- // Issue #2279
- LOG_FMT(LFCNR, "%s(%d): next orig line %zu, orig col %zu, text '%s', type %s\n",
- __func__, __LINE__, next->GetOrigLine(), next->GetOrigCol(), next->Text(), get_token_name(next->GetType()));
- }
- LOG_FMT(LFCNR, "%s(%d): do_symbol_check for '%s, %s, %s'\n",
- __func__, __LINE__, prev->Text(), pc->Text(), next->Text());
- do_symbol_check(prev, pc, next);
- pc = pc->GetNextNcNnl();
- }
- pawn_add_virtual_semicolons();
- process_returns_and_throws();
-
- /*
- * 2nd pass - handle variable definitions
- * REVISIT: We need function params marked to do this (?)
- */
- pc = Chunk::GetHead();
- int square_level = -1;
-
- while (pc->IsNotNullChunk())
- {
- char copy[1000];
- LOG_FMT(LFCNR, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s, parent type is %s\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->ElidedText(copy), get_token_name(pc->GetType()), get_token_name(pc->GetParentType()));
-
- // Can't have a variable definition inside [ ]
- if (square_level < 0)
- {
- if (pc->Is(CT_SQUARE_OPEN))
- {
- square_level = pc->GetLevel();
- }
- }
- else
- {
- if (pc->GetLevel() <= static_cast<size_t>(square_level))
- {
- square_level = -1;
- }
- }
-
- if ( pc->Is(CT_EXTERN)
- && language_is_set(LANG_ALLC))
- {
- Chunk *next = pc->GetNextNcNnl();
-
- if (next->Is(CT_STRING))
- {
- Chunk *tmp = next->GetNextNcNnl();
-
- while (tmp->IsNotNullChunk())
- {
- if ( tmp->Is(CT_TYPE)
- || tmp->Is(CT_BRACE_OPEN)
- || tmp->Is(CT_ATTRIBUTE))
- {
- break;
- }
-
- if (tmp->Is(CT_WORD))
- {
- tmp->SetFlagBits(PCF_STMT_START | PCF_EXPR_START);
- log_ruleStart("start statement/ expression", tmp);
- break;
- }
- tmp = tmp->GetNextNcNnl();
- }
- }
- }
-
- if ( pc->Is(CT_ATTRIBUTE)
- && language_is_set(LANG_ALLC))
- {
- Chunk *tmp = skip_attribute_next(pc);
-
- if (tmp->Is(CT_WORD))
- {
- tmp->SetFlagBits(PCF_STMT_START | PCF_EXPR_START);
- log_ruleStart("start statement/ expression", tmp);
- }
- }
-
- if ( pc->Is(CT_BRACE_OPEN) // Issue #2332
- && pc->GetParentType() == CT_BRACED_INIT_LIST)
- {
- LOG_FMT(LFCNR, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', look for CT_BRACE_OPEN\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
- pc = pc->GetNextType(CT_BRACE_CLOSE, pc->GetLevel());
- }
- /*
- * A variable definition is possible after at the start of a statement
- * that starts with: DC_MEMBER, QUALIFIER, TYPE, or WORD
- */
- // Issue #2279
- // Issue #2478
- LOG_FMT(LFCNR, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s, parent type is %s\n ",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->ElidedText(copy), get_token_name(pc->GetType()), get_token_name(pc->GetParentType()));
- log_pcf_flags(LFCNR, pc->GetFlags());
-
- if ( (square_level < 0)
- && pc->TestFlags(PCF_STMT_START)
- && ( pc->Is(CT_QUALIFIER)
- || pc->Is(CT_TYPE)
- || pc->Is(CT_TYPENAME)
- || pc->Is(CT_DC_MEMBER) // Issue #2478
- || ( pc->Is(CT_WORD)
- && !pc->TestFlags(PCF_IN_CONDITIONAL) // Issue #3558
-// && language_is_set(LANG_CPP)
- )
- )
- && pc->GetParentType() != CT_BIT_COLON
- && pc->GetParentType() != CT_ENUM_COLON // Issue #4040
- && pc->GetParentType() != CT_ENUM
- && !pc->TestFlags(PCF_IN_CLASS_BASE)
- && !pc->TestFlags(PCF_IN_ENUM))
- {
- pc = fix_variable_definition(pc);
- }
- else
- {
- pc = pc->GetNextNcNnl();
- }
- }
-} // fix_symbols
-
-
-static void process_returns_and_throws()
-{
- LOG_FUNC_ENTRY();
- Chunk *pc;
-
- pc = Chunk::GetHead();
-
- while (pc->IsNotNullChunk())
- {
- if ( pc->Is(CT_RETURN)
- || pc->Is(CT_THROW))
- {
- pc = process_return_or_throw(pc);
- }
- else
- {
- pc = pc->GetNext();
- }
- }
-}
-
-
-static Chunk *process_return_or_throw(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
-
- const char *nl_expr_name;
- iarf_e nl_expr_value;
- const char *mod_paren_name;
- iarf_e mod_paren_value;
-
- if (pc->Is(CT_RETURN))
- {
- nl_expr_name = "nl_return_expr";
- nl_expr_value = options::nl_return_expr();
- mod_paren_name = "mod_paren_on_return";
- mod_paren_value = options::mod_paren_on_return();
- }
- else if (pc->Is(CT_THROW))
- {
- nl_expr_name = "nl_throw_expr";
- nl_expr_value = options::nl_throw_expr();
- mod_paren_name = "mod_paren_on_throw";
- mod_paren_value = options::mod_paren_on_throw();
- }
- else // should never happen
- {
- return(pc->GetNext());
- }
- Chunk *next;
- Chunk *temp;
- Chunk *semi;
- Chunk *cpar;
- Chunk chunk;
-
- // grab next and bail if it is a semicolon
- next = pc->PpaGetNextNcNnl();
-
- if ( next->IsNullChunk()
- || next->IsSemicolon()
- || next->Is(CT_NEWLINE))
- {
- return(next);
- }
- log_rule_B(nl_expr_name);
-
- if ( nl_expr_value != IARF_IGNORE
- && !pc->TestFlags(PCF_IN_PREPROC))
- {
- newline_iarf(pc, nl_expr_value);
- }
-
- if (next->Is(CT_PAREN_OPEN))
- {
- // See if the return/throw is fully paren'd
- cpar = next->GetNextType(CT_PAREN_CLOSE, next->GetLevel());
-
- if (cpar->IsNullChunk())
- {
- return(Chunk::NullChunkPtr);
- }
- semi = cpar->PpaGetNextNcNnl();
-
- if (semi->IsNullChunk())
- {
- return(Chunk::NullChunkPtr);
- }
-
- if ( semi->Is(CT_NEWLINE)
- || semi->IsSemicolon())
- {
- log_rule_B(mod_paren_name);
-
- if (mod_paren_value == IARF_REMOVE)
- {
- LOG_FMT(LRETURN, "%s(%d): removing parens on orig line %zu\n",
- __func__, __LINE__, pc->GetOrigLine());
-
- // lower the level of everything
- for (temp = next; temp != cpar; temp = temp->GetNext())
- {
- if (temp->GetLevel() == 0)
- {
- fprintf(stderr, "%s(%d): temp->GetLevel() is ZERO, cannot be decremented, at line %zu, column %zu\n",
- __func__, __LINE__, temp->GetOrigLine(), temp->GetOrigCol());
- log_flush(true);
- exit(EX_SOFTWARE);
- }
- temp->SetLevel(temp->GetLevel() - 1);
- }
-
- // delete the parenthesis
- Chunk::Delete(next);
- Chunk::Delete(cpar);
-
- // back up following chunks
- temp = semi;
-
- while ( temp->IsNotNullChunk()
- && temp->IsNot(CT_NEWLINE))
- {
- temp->SetColumn(temp->GetColumn() - 2);
- temp->SetOrigCol(temp->GetOrigCol() - 2);
- temp->SetOrigColEnd(temp->GetOrigColEnd() - 2);
- temp = temp->GetNext();
- }
- }
- else
- {
- LOG_FMT(LRETURN, "%s(%d): keeping parens on orig line %zu\n",
- __func__, __LINE__, pc->GetOrigLine());
-
- // mark & keep them
- next->SetParentType(pc->GetType());
- cpar->SetParentType(pc->GetType());
- }
- return(semi);
- }
- }
- // We don't have a fully paren'd return/throw. Should we add some?
- log_rule_B(mod_paren_name);
-
- if (!(mod_paren_value & IARF_ADD))
- {
- return(next);
- }
-
- // Issue #1917
- // Never add parens to a braced init list; that breaks the code
- // return {args...}; // C++11 type elision; okay
- // return ({args...}); // ill-formed
- if ( language_is_set(LANG_CPP)
- && next->Is(CT_BRACE_OPEN)
- && next->GetParentType() == CT_BRACED_INIT_LIST)
- {
- LOG_FMT(LRETURN, "%s(%d): not adding parens around braced initializer"
- " on orig line %zd\n",
- __func__, __LINE__, pc->GetOrigLine());
- return(next);
- }
- // find the next semicolon on the same level
- semi = next;
-
- if (pc->TestFlags(PCF_IN_PREPROC))
- {
- while ((semi = semi->GetNext())->IsNotNullChunk())
- {
- if (!semi->TestFlags(PCF_IN_PREPROC))
- {
- break;
- }
-
- if (semi->GetLevel() < pc->GetLevel())
- {
- return(semi);
- }
-
- if ( semi->IsSemicolon()
- && pc->GetLevel() == semi->GetLevel())
- {
- break;
- }
- }
- }
- else
- {
- while ((semi = semi->GetNext())->IsNotNullChunk())
- {
- if (semi->GetLevel() < pc->GetLevel())
- {
- return(semi);
- }
-
- if ( semi->IsSemicolon()
- && pc->GetLevel() == semi->GetLevel())
- {
- break;
- }
- }
- }
-
- if (semi->IsNotNullChunk())
- {
- // add the parenthesis
- chunk.SetType(CT_PAREN_OPEN);
- chunk.SetParentType(pc->GetType());
- chunk.Str() = "(";
- chunk.SetLevel(pc->GetLevel());
- chunk.SetPpLevel(pc->GetPpLevel());
- chunk.SetBraceLevel(pc->GetBraceLevel());
- chunk.SetOrigLine(pc->GetOrigLine());
- chunk.SetOrigCol(next->GetOrigCol() - 1);
- chunk.SetFlags(pc->GetFlags() & PCF_COPY_FLAGS);
- chunk.CopyAndAddBefore(next);
-
- chunk.SetType(CT_PAREN_CLOSE);
- chunk.Str() = ")";
- chunk.SetOrigLine(semi->GetOrigLine());
- chunk.SetOrigCol(semi->GetOrigCol() - 1);
- cpar = chunk.CopyAndAddBefore(semi);
-
- LOG_FMT(LRETURN, "%s(%d): added parens on orig line %zu\n",
- __func__, __LINE__, pc->GetOrigLine());
-
- for (temp = next; temp != cpar; temp = temp->GetNext())
- {
- temp->SetLevel(temp->GetLevel() + 1);
- }
- }
- return(semi);
-} // process_return_or_throw
-
-
-static bool is_oc_block(Chunk *pc)
-{
- return( pc->GetParentType() == CT_OC_BLOCK_TYPE
- || pc->GetParentType() == CT_OC_BLOCK_EXPR
- || pc->GetParentType() == CT_OC_BLOCK_ARG
- || pc->GetParentType() == CT_OC_BLOCK
- || pc->Is(CT_OC_BLOCK_CARET)
- || pc->GetNext()->Is(CT_OC_BLOCK_CARET)
- || pc->GetPrev()->Is(CT_OC_BLOCK_CARET));
-}
-
-
-void mark_comments()
-{
- LOG_FUNC_ENTRY();
-
- cpd.unc_stage = unc_stage_e::MARK_COMMENTS;
-
- bool prev_nl = true;
- Chunk *cur = Chunk::GetHead();
-
- while (cur->IsNotNullChunk())
- {
- Chunk *next = cur->GetNextNvb();
- bool next_nl = next->IsNullChunk() || next->IsNewline();
-
- if (cur->IsComment())
- {
- if ( next_nl
- && prev_nl)
- {
- cur->SetParentType(CT_COMMENT_WHOLE);
- }
- else if (next_nl)
- {
- cur->SetParentType(CT_COMMENT_END);
- }
- else if (prev_nl)
- {
- cur->SetParentType(CT_COMMENT_START);
- }
- else
- {
- cur->SetParentType(CT_COMMENT_EMBED);
- }
- }
- prev_nl = cur->IsNewline();
- cur = next;
- }
-}
-
-
-static void handle_cpp_template(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
-
- Chunk *tmp = pc->GetNextNcNnl();
-
- if (tmp->IsNot(CT_ANGLE_OPEN))
- {
- return;
- }
- tmp->SetParentType(CT_TEMPLATE);
-
- size_t level = tmp->GetLevel();
-
- tmp = tmp->GetNext();
-
- while (tmp->IsNotNullChunk())
- {
- if ( tmp->Is(CT_CLASS)
- || tmp->Is(CT_STRUCT))
- {
- tmp->SetType(CT_TYPE);
- }
- else if ( tmp->Is(CT_ANGLE_CLOSE)
- && tmp->GetLevel() == level)
- {
- tmp->SetParentType(CT_TEMPLATE);
- break;
- }
- tmp = tmp->GetNext();
- }
-
- if (tmp->IsNotNullChunk())
- {
- tmp = tmp->GetNextNcNnl();
-
- if (tmp->Is(CT_FRIEND))
- {
- // Account for a template friend declaration
- tmp->SetParentType(CT_TEMPLATE);
-
- tmp = tmp->GetNextNcNnl();
- }
-
- if (tmp->IsClassOrStruct())
- {
- tmp->SetParentType(CT_TEMPLATE);
-
- // REVISIT: This may be a bit risky - might need to track the { };
- tmp = tmp->GetNextType(CT_SEMICOLON, tmp->GetLevel());
-
- if (tmp->IsNotNullChunk())
- {
- tmp->SetParentType(CT_TEMPLATE);
- }
- }
- }
-} // handle_cpp_template
-
-
-static void handle_cpp_lambda(Chunk *sq_o)
-{
- LOG_FUNC_ENTRY();
-
- Chunk *ret = Chunk::NullChunkPtr;
-
- // abort if type of the previous token is not contained in this whitelist
- Chunk *prev = sq_o->GetPrevNcNnlNi(); // Issue #2279
-
- if (prev->IsNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): prev is null chunk\n", __func__, __LINE__);
- }
-
- if ( prev->IsNullChunk()
- || ( prev->IsNot(CT_ASSIGN)
- && prev->IsNot(CT_COMMA)
- && prev->IsNot(CT_PAREN_OPEN) // allow Js like self invoking lambda syntax: ([](){})();
- && prev->IsNot(CT_FPAREN_OPEN)
- && prev->IsNot(CT_SQUARE_OPEN)
- && prev->IsNot(CT_BRACE_OPEN)
- && prev->IsNot(CT_SEMICOLON)
- && prev->IsNot(CT_RETURN)))
- {
- LOG_FMT(LFCNR, "%s(%d): return\n", __func__, __LINE__);
- return;
- }
- Chunk *sq_c = sq_o; // assuming '[]'
-
- if (sq_o->Is(CT_SQUARE_OPEN))
- {
- // make sure there is a ']'
- sq_c = sq_o->GetClosingParen();
-
- if (sq_c->IsNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): return\n", __func__, __LINE__);
- return;
- }
- }
- Chunk *pa_o = sq_c->GetNextNcNnl();
-
- // check to see if there is a lambda-specifier in the pa_o chunk;
- // assuming chunk is CT_EXECUTION_CONTEXT, ignore lambda-specifier
- while (pa_o->Is(CT_EXECUTION_CONTEXT))
- {
- // set pa_o to next chunk after this specifier
- pa_o = pa_o->GetNextNcNnl();
- }
-
- if (pa_o->IsNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): return\n", __func__, __LINE__);
- return;
- }
- Chunk *pa_c = Chunk::NullChunkPtr;
-
- // lambda-declarator '( params )' is optional
- if (pa_o->Is(CT_PAREN_OPEN))
- {
- // and now find the ')'
- pa_c = pa_o->GetClosingParen();
-
- if (pa_c->IsNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): return\n", __func__, __LINE__);
- return;
- }
- }
- // Check for 'mutable' keyword: '[]() mutable {}' or []() mutable -> ret {}
- Chunk *br_o = pa_c->IsNotNullChunk() ? pa_c->GetNextNcNnl() : pa_o;
-
- if (br_o->IsString("mutable"))
- {
- br_o = br_o->GetNextNcNnl();
- }
- //TODO: also check for exception and attribute between [] ... {}
-
- // skip possible arrow syntax: '-> ret'
- if (br_o->IsString("->"))
- {
- ret = br_o;
- // REVISIT: really should check the stuff we are skipping
- br_o = br_o->GetNextType(CT_BRACE_OPEN, br_o->GetLevel());
- }
-
- // skip possible CT_NOEXCEPT
- if (br_o->Is(CT_NOEXCEPT)) // Issue #3321
- {
- ret = br_o;
- // REVISIT: really should check the stuff we are skipping
- br_o = br_o->GetNextType(CT_BRACE_OPEN, br_o->GetLevel());
- }
-
- if (br_o->IsNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): br_o is null. Return\n", __func__, __LINE__);
- return;
- }
-
- if (br_o->IsNot(CT_BRACE_OPEN))
- {
- LOG_FMT(LFCNR, "%s(%d): br_o is '%s'/%s\n",
- __func__, __LINE__,
- br_o->Text(), get_token_name(br_o->GetType()));
- LOG_FMT(LFCNR, "%s(%d): return\n", __func__, __LINE__);
- return;
- }
- // and now find the '}'
- Chunk *br_c = br_o->GetClosingParen();
-
- if (br_c->IsNullChunk())
- {
- LOG_FMT(LFCNR, "%s(%d): return\n", __func__, __LINE__);
- return;
- }
-
- // This looks like a lambda expression
- if (sq_o->Is(CT_TSQUARE))
- {
- // split into two chunks
- Chunk nc;
-
- nc = *sq_o;
- sq_o->SetType(CT_SQUARE_OPEN);
- sq_o->Str().resize(1);
- /*
- * bug # 664
- *
- * The original m_origCol of CT_SQUARE_CLOSE is stored at m_origColEnd
- * of CT_TSQUARE. CT_SQUARE_CLOSE m_origCol and m_origColEnd values
- * are calculate from m_origColEnd of CT_TSQUARE.
- */
- nc.SetOrigCol(sq_o->GetOrigColEnd() - 1);
- nc.SetColumn(nc.GetOrigCol());
- nc.SetOrigColEnd(sq_o->GetOrigColEnd());
- sq_o->SetOrigColEnd(sq_o->GetOrigCol() + 1);
-
- nc.SetType(CT_SQUARE_CLOSE);
- nc.Str().pop_front();
- sq_c = nc.CopyAndAddAfter(sq_o);
- }
- sq_o->SetParentType(CT_CPP_LAMBDA);
- sq_c->SetParentType(CT_CPP_LAMBDA);
-
- if (pa_c->IsNotNullChunk())
- {
- pa_o->SetType(CT_LPAREN_OPEN); // Issue #3054
- pa_o->SetParentType(CT_CPP_LAMBDA);
- pa_o->SetParent(sq_o);
- br_o->SetParent(sq_o);
- pa_c->SetType(CT_LPAREN_CLOSE);
- pa_c->SetParentType(CT_CPP_LAMBDA);
- pa_c->SetParent(sq_o);
- br_c->SetParent(sq_o);
- }
- br_o->SetParentType(CT_CPP_LAMBDA);
- br_c->SetParentType(CT_CPP_LAMBDA);
-
- if (ret->IsNotNullChunk())
- {
- ret->SetType(CT_CPP_LAMBDA_RET);
- ret = ret->GetNextNcNnl();
-
- while (ret != br_o)
- {
- make_type(ret);
- ret = ret->GetNextNcNnl();
- }
- }
-
- if (pa_c->IsNotNullChunk())
- {
- fix_fcn_def_params(pa_o);
- }
- //handle self calling lambda paren
- Chunk *call_pa_o = br_c->GetNextNcNnl();
-
- if (call_pa_o->Is(CT_PAREN_OPEN))
- {
- Chunk *call_pa_c = call_pa_o->GetClosingParen();
-
- if (call_pa_c->IsNotNullChunk())
- {
- call_pa_o->SetType(CT_FPAREN_OPEN);
- call_pa_o->SetParentType(CT_FUNC_CALL);
- call_pa_c->SetType(CT_FPAREN_CLOSE);
- call_pa_c->SetParentType(CT_FUNC_CALL);
- }
- }
- mark_cpp_lambda(sq_o);
-} // handle_cpp_lambda
-
-
-static void handle_d_template(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
-
- Chunk *name = pc->GetNextNcNnl();
- Chunk *po = name->GetNextNcNnl();
-
- if ( name->IsNullChunk()
- || name->IsNot(CT_WORD))
- {
- // TODO: log an error, expected NAME
- return;
- }
-
- if ( po->IsNullChunk()
- || po->IsNot(CT_PAREN_OPEN))
- {
- // TODO: log an error, expected '('
- return;
- }
- name->SetType(CT_TYPE);
- name->SetParentType(CT_TEMPLATE);
- po->SetParentType(CT_TEMPLATE);
-
- ChunkStack cs;
- Chunk *tmp = get_d_template_types(cs, po);
-
- if ( tmp->IsNullChunk()
- || tmp->IsNot(CT_PAREN_CLOSE))
- {
- // TODO: log an error, expected ')'
- return;
- }
- tmp->SetParentType(CT_TEMPLATE);
-
- tmp = tmp->GetNextNcNnl();
-
- if (tmp->IsNot(CT_BRACE_OPEN))
- {
- // TODO: log an error, expected '{'
- return;
- }
- tmp->SetParentType(CT_TEMPLATE);
- po = tmp;
- tmp = tmp->GetNextNcNnl();
-
- while ( tmp->IsNotNullChunk()
- && tmp->GetLevel() > po->GetLevel())
- {
- if ( tmp->Is(CT_WORD)
- && chunkstack_match(cs, tmp))
- {
- tmp->SetType(CT_TYPE);
- }
- tmp = tmp->GetNextNcNnl();
- }
-// if (!tmp->Is(CT_BRACE_CLOSE))
-// {
-// // TODO: log an error, expected '}'
-// }
- tmp->SetParentType(CT_TEMPLATE);
-} // handle_d_template
-
-
-Chunk *skip_template_next(Chunk *ang_open)
-{
- if (ang_open->Is(CT_ANGLE_OPEN))
- {
- Chunk *pc = ang_open->GetNextType(CT_ANGLE_CLOSE, ang_open->GetLevel());
-
- if (pc->IsNullChunk())
- {
- return(Chunk::NullChunkPtr);
- }
- return(pc->GetNextNcNnl());
- }
- return(ang_open);
-}
-
-
-static void handle_oc_class(Chunk *pc)
-{
- enum class angle_state_e : unsigned int
- {
- NONE = 0,
- OPEN = 1, // '<' found
- CLOSE = 2, // '>' found
- };
-
- LOG_FUNC_ENTRY();
- Chunk *tmp;
- bool hit_scope = false;
- bool passed_name = false; // Did we pass the name of the class and now there can be only protocols, not generics
- int generic_level = 0; // level of depth of generic
- angle_state_e as = angle_state_e::NONE;
-
- LOG_FMT(LOCCLASS, "%s(%d): start [%s] [%s] line %zu\n",
- __func__, __LINE__, pc->Text(), get_token_name(pc->GetParentType()), pc->GetOrigLine());
-
- if (pc->GetParentType() == CT_OC_PROTOCOL)
- {
- tmp = pc->GetNextNcNnl();
-
- if (tmp->IsSemicolon())
- {
- tmp->SetParentType(pc->GetParentType());
- LOG_FMT(LOCCLASS, "%s(%d): bail on semicolon\n", __func__, __LINE__);
- return;
- }
- }
- tmp = pc;
-
- while ((tmp = tmp->GetNextNnl())->IsNotNullChunk())
- {
- LOG_FMT(LOCCLASS, "%s(%d): orig line is %zu, [%s]\n",
- __func__, __LINE__, tmp->GetOrigLine(), tmp->Text());
-
- if (tmp->Is(CT_OC_END))
- {
- break;
- }
-
- if (tmp->Is(CT_PAREN_OPEN))
- {
- passed_name = true;
- }
-
- if (tmp->IsString("<"))
- {
- tmp->SetType(CT_ANGLE_OPEN);
-
- if (passed_name)
- {
- tmp->SetParentType(CT_OC_PROTO_LIST);
- }
- else
- {
- tmp->SetParentType(CT_OC_GENERIC_SPEC);
- generic_level++;
- }
- as = angle_state_e::OPEN;
- }
-
- if (tmp->IsString(">"))
- {
- tmp->SetType(CT_ANGLE_CLOSE);
-
- if (passed_name)
- {
- tmp->SetParentType(CT_OC_PROTO_LIST);
- as = angle_state_e::CLOSE;
- }
- else
- {
- tmp->SetParentType(CT_OC_GENERIC_SPEC);
-
- if (generic_level == 0)
- {
- fprintf(stderr, "%s(%d): generic_level is ZERO, cannot be decremented, at line %zu, column %zu\n",
- __func__, __LINE__, tmp->GetOrigLine(), tmp->GetOrigCol());
- log_flush(true);
- exit(EX_SOFTWARE);
- }
- generic_level--;
-
- if (generic_level == 0)
- {
- as = angle_state_e::CLOSE;
- }
- }
- }
-
- if (tmp->IsString(">>"))
- {
- tmp->SetType(CT_ANGLE_CLOSE);
- tmp->SetParentType(CT_OC_GENERIC_SPEC);
- split_off_angle_close(tmp);
- generic_level -= 1;
-
- if (generic_level == 0)
- {
- as = angle_state_e::CLOSE;
- }
- }
-
- if ( tmp->Is(CT_BRACE_OPEN)
- && tmp->GetParentType() != CT_ASSIGN)
- {
- as = angle_state_e::CLOSE;
- tmp->SetParentType(CT_OC_CLASS);
- tmp = tmp->GetNextType(CT_BRACE_CLOSE, tmp->GetLevel());
-
- if ( tmp->IsNotNullChunk()
- && tmp->GetParentType() != CT_ASSIGN)
- {
- tmp->SetParentType(CT_OC_CLASS);
- }
- }
- else if (tmp->Is(CT_COLON))
- {
- if (as != angle_state_e::OPEN)
- {
- passed_name = true;
- }
- tmp->SetType(hit_scope ? CT_OC_COLON : CT_CLASS_COLON);
-
- if (tmp->Is(CT_CLASS_COLON))
- {
- tmp->SetParentType(CT_OC_CLASS);
- }
- }
- else if ( tmp->IsString("-")
- || tmp->IsString("+"))
- {
- as = angle_state_e::CLOSE;
-
- if (tmp->GetPrev()->IsNewline())
- {
- tmp->SetType(CT_OC_SCOPE);
- tmp->SetFlagBits(PCF_STMT_START);
- log_ruleStart("start statement", tmp);
- hit_scope = true;
- }
- }
-
- if (as == angle_state_e::OPEN)
- {
- if (passed_name)
- {
- tmp->SetParentType(CT_OC_PROTO_LIST);
- }
- else
- {
- tmp->SetParentType(CT_OC_GENERIC_SPEC);
- }
- }
- }
-
- if (tmp->Is(CT_BRACE_OPEN))
- {
- tmp = tmp->GetNextType(CT_BRACE_CLOSE, tmp->GetLevel());
-
- if (tmp->IsNotNullChunk())
- {
- tmp->SetParentType(CT_OC_CLASS);
- }
- }
-} // handle_oc_class
-
-
-static void handle_oc_block_literal(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
-
- Chunk *prev = pc->GetPrevNcNnlNi(); // Issue #2279
- Chunk *next = pc->GetNextNcNnl();
-
- if ( prev->IsNullChunk()
- || next->IsNullChunk())
- {
- return; // let's be paranoid
- }
- /*
- * block literal: '^ RTYPE ( ARGS ) { }'
- * RTYPE and ARGS are optional
- */
- LOG_FMT(LOCBLK, "%s(%d): block literal @ orig line is %zu, orig col is %zu\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol());
-
- Chunk *apo = Chunk::NullChunkPtr; // arg paren open
- Chunk *bbo = Chunk::NullChunkPtr; // block brace open
- Chunk *bbc; // block brace close
-
- LOG_FMT(LOCBLK, "%s(%d): + scan", __func__, __LINE__);
- Chunk *tmp;
-
- for (tmp = next; tmp->IsNotNullChunk(); tmp = tmp->GetNextNcNnl())
- {
- /* handle '< protocol >' */
- if (tmp->IsString("<"))
- {
- Chunk *ao = tmp;
- Chunk *ac = ao->GetNextString(">", 1, ao->GetLevel());
-
- if (ac->IsNotNullChunk())
- {
- ao->SetType(CT_ANGLE_OPEN);
- ao->SetParentType(CT_OC_PROTO_LIST);
- ac->SetType(CT_ANGLE_CLOSE);
- ac->SetParentType(CT_OC_PROTO_LIST);
-
- for (tmp = ao->GetNext(); tmp != ac; tmp = tmp->GetNext())
- {
- tmp->SetLevel(tmp->GetLevel() + 1);
- tmp->SetParentType(CT_OC_PROTO_LIST);
- }
-
- tmp = ac->GetNextNcNnl();
- }
- else
- {
- tmp = Chunk::NullChunkPtr;
- }
- }
- LOG_FMT(LOCBLK, " '%s'", tmp->Text());
-
- if ( tmp->GetLevel() < pc->GetLevel()
- || tmp->Is(CT_SEMICOLON))
- {
- LOG_FMT(LOCBLK, "[DONE]");
- break;
- }
-
- if (tmp->GetLevel() == pc->GetLevel())
- {
- if (tmp->IsParenOpen())
- {
- apo = tmp;
- LOG_FMT(LOCBLK, "[PAREN]");
- }
-
- if (tmp->Is(CT_BRACE_OPEN))
- {
- LOG_FMT(LOCBLK, "[BRACE]");
- bbo = tmp;
- break;
- }
- }
- }
-
- // make sure we have braces
- bbc = bbo->GetClosingParen();
-
- if ( bbo->IsNullChunk()
- || bbc->IsNullChunk())
- {
- LOG_FMT(LOCBLK, " -- no braces found\n");
- return;
- }
- LOG_FMT(LOCBLK, "\n");
-
- // we are on a block literal for sure
- pc->SetType(CT_OC_BLOCK_CARET);
- pc->SetParentType(CT_OC_BLOCK_EXPR);
-
- // handle the optional args
- Chunk *lbp; // last before paren - end of return type, if any
-
- if (apo->IsNotNullChunk())
- {
- Chunk *apc = apo->GetClosingParen(); // arg parenthesis close
-
- if (apc->IsParenClose())
- {
- LOG_FMT(LOCBLK, " -- marking parens @ apo orig line is %zu, orig col is %zu and apc orig line is %zu, orig col is %zu\n",
- apo->GetOrigLine(), apo->GetOrigCol(), apc->GetOrigLine(), apc->GetOrigCol());
- flag_parens(apo, PCF_OC_ATYPE, CT_FPAREN_OPEN, CT_OC_BLOCK_EXPR, true);
- fix_fcn_def_params(apo);
- }
- lbp = apo->GetPrevNcNnlNi(); // Issue #2279
- }
- else
- {
- lbp = bbo->GetPrevNcNnlNi(); // Issue #2279
- }
-
- // mark the return type, if any
- while (lbp != pc)
- {
- LOG_FMT(LOCBLK, " -- lbp %s[%s]\n", lbp->Text(), get_token_name(lbp->GetType()));
- make_type(lbp);
- lbp->SetFlagBits(PCF_OC_RTYPE);
- lbp->SetParentType(CT_OC_BLOCK_EXPR);
- lbp = lbp->GetPrevNcNnlNi(); // Issue #2279
- }
- // mark the braces
- bbo->SetParentType(CT_OC_BLOCK_EXPR);
- bbc->SetParentType(CT_OC_BLOCK_EXPR);
-
- // mark the OC_BLOCK
- for (Chunk *tmp1 = bbo; tmp1 != bbc; tmp1 = tmp1->GetNextNcNnl())
- {
- tmp1->SetFlagBits(PCF_OC_IN_BLOCK);
- }
-} // handle_oc_block_literal
-
-
-static void handle_oc_block_type(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
-
- if (pc->IsNullChunk())
- {
- return;
- }
-
- if (pc->TestFlags(PCF_IN_TYPEDEF))
- {
- LOG_FMT(LOCBLK, "%s(%d): skip block type @ orig line is %zu, orig col is %zu, -- in typedef\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol());
- return;
- }
- // make sure we have '( ^'
- Chunk *tpo = pc->GetPrevNcNnlNi(); // type paren open Issue #2279
-
- if (tpo->IsParenOpen())
- {
- /*
- * block type: 'RTYPE (^LABEL)(ARGS)'
- * LABEL is optional.
- */
- Chunk *tpc = tpo->GetClosingParen(); // type close paren (after '^')
- Chunk *nam = tpc->GetPrevNcNnlNi(); // name (if any) or '^' Issue #2279
- Chunk *apo = tpc->GetNextNcNnl(); // arg open paren
- Chunk *apc = apo->GetClosingParen(); // arg close paren
-
- /*
- * If this is a block literal instead of a block type, 'nam'
- * will actually be the closing bracket of the block. We run into
- * this situation if a block literal is enclosed in parentheses.
- */
- if (nam->IsBraceClose())
- {
- return(handle_oc_block_literal(pc));
- }
-
- // Check apo is '(' or else this might be a block literal. Issue 2643.
- if (!apo->IsParenOpen())
- {
- return(handle_oc_block_literal(pc));
- }
-
- if (apc->IsParenClose())
- {
- Chunk *aft = apc->GetNextNcNnl();
- E_Token pt;
-
- if (nam->IsString("^"))
- {
- nam->SetType(CT_PTR_TYPE);
- pt = CT_FUNC_TYPE;
- }
- else if ( aft->Is(CT_ASSIGN)
- || aft->Is(CT_SEMICOLON))
- {
- nam->SetType(CT_FUNC_VAR);
- pt = CT_FUNC_VAR;
- }
- else
- {
- nam->SetType(CT_FUNC_TYPE);
- pt = CT_FUNC_TYPE;
- }
- LOG_FMT(LOCBLK, "%s(%d): block type @ orig line is %zu, orig col is %zu, Text() '%s'[%s]\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), nam->Text(), get_token_name(nam->GetType()));
- pc->SetType(CT_PTR_TYPE);
- pc->SetParentType(pt); //CT_OC_BLOCK_TYPE;
- tpo->SetType(CT_TPAREN_OPEN);
- tpo->SetParentType(pt); //CT_OC_BLOCK_TYPE;
- tpc->SetType(CT_TPAREN_CLOSE);
- tpc->SetParentType(pt); //CT_OC_BLOCK_TYPE;
- apo->SetType(CT_FPAREN_OPEN);
- apo->SetParentType(CT_FUNC_PROTO);
- apc->SetType(CT_FPAREN_CLOSE);
- apc->SetParentType(CT_FUNC_PROTO);
- fix_fcn_def_params(apo);
- mark_function_return_type(nam, tpo->GetPrevNcNnlNi(), pt); // Issue #2279
- }
- }
-} // handle_oc_block_type
-
-
-static Chunk *handle_oc_md_type(Chunk *paren_open, E_Token ptype, PcfFlags flags, bool &did_it)
-{
- Chunk *paren_close;
-
- if ( !paren_open->IsParenOpen()
- || ((paren_close = paren_open->GetClosingParen())->IsNullChunk()))
- {
- did_it = false;
- return(paren_open);
- }
- did_it = true;
-
- paren_open->SetParentType(ptype);
- paren_open->SetFlagBits(flags);
- paren_close->SetParentType(ptype);
- paren_close->SetFlagBits(flags);
-
- for (Chunk *cur = paren_open->GetNextNcNnl();
- cur != paren_close;
- cur = cur->GetNextNcNnl())
- {
- LOG_FMT(LOCMSGD, " <%s|%s>", cur->Text(), get_token_name(cur->GetType()));
- cur->SetFlagBits(flags);
- make_type(cur);
- }
-
- // returning the chunk after the paren close
- return(paren_close->GetNextNcNnl());
-}
-
-
-static void handle_oc_message_decl(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
-
- bool did_it;
- //bool in_paren = false;
- //int paren_cnt = 0;
- //int arg_cnt = 0;
-
- // Figure out if this is a spec or decl
- Chunk *tmp = pc;
-
- while ((tmp = tmp->GetNext())->IsNotNullChunk())
- {
- if (tmp->GetLevel() < pc->GetLevel())
- {
- // should not happen
- return;
- }
-
- if ( tmp->Is(CT_SEMICOLON)
- || tmp->Is(CT_BRACE_OPEN))
- {
- break;
- }
- }
-
- if (tmp->IsNullChunk())
- {
- return;
- }
- E_Token pt = tmp->Is(CT_SEMICOLON) ? CT_OC_MSG_SPEC : CT_OC_MSG_DECL;
-
- pc->SetType(CT_OC_SCOPE);
- pc->SetParentType(pt);
-
- LOG_FMT(LOCMSGD, "%s(%d): %s @ orig line is %zu, orig col is %zu -",
- __func__, __LINE__, get_token_name(pt), pc->GetOrigLine(), pc->GetOrigCol());
-
- // format: -(TYPE) NAME [: (TYPE)NAME
-
- // handle the return type
- tmp = handle_oc_md_type(pc->GetNextNcNnl(), pt, PCF_OC_RTYPE, did_it);
-
- if (!did_it)
- {
- LOG_FMT(LOCMSGD, " -- missing type parens\n");
- return;
- }
-
- // expect the method name/label
- if (tmp->IsNot(CT_WORD))
- {
- LOG_FMT(LOCMSGD, " -- missing method name\n");
- return;
- } // expect the method name/label
-
- Chunk *label = tmp;
-
- tmp->SetType(pt);
- tmp->SetParentType(pt);
- pc = tmp->GetNextNcNnl();
-
- LOG_FMT(LOCMSGD, " [%s]%s", pc->Text(), get_token_name(pc->GetType()));
-
- // if we have a colon next, we have args
- if ( pc->Is(CT_COLON)
- || pc->Is(CT_OC_COLON))
- {
- pc = label;
-
- while (true)
- {
- // skip optional label
- if ( pc->Is(CT_WORD)
- || pc->Is(pt))
- {
- pc->SetParentType(pt);
- pc = pc->GetNextNcNnl();
- }
-
- // a colon must be next
- if (!pc->IsString(":"))
- {
- break;
- }
- pc->SetType(CT_OC_COLON);
- pc->SetParentType(pt);
- pc = pc->GetNextNcNnl();
-
- // next is the type in parens
- LOG_FMT(LOCMSGD, " (%s)", pc->Text());
- tmp = handle_oc_md_type(pc, pt, PCF_OC_ATYPE, did_it);
-
- if (!did_it)
- {
- LOG_FMT(LWARN, "%s(%d): orig line is %zu, orig col is %zu expected type\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol());
- break;
- }
- // attributes for a method parameter sit between the parameter type and the parameter name
- pc = skip_attribute_next(tmp);
- // we should now be on the arg name
- pc->SetFlagBits(PCF_VAR_DEF);
- LOG_FMT(LOCMSGD, " arg[%s]", pc->Text());
- pc = pc->GetNextNcNnl();
- }
- }
- LOG_FMT(LOCMSGD, " end[%s]", pc->Text());
-
- if (pc->Is(CT_BRACE_OPEN))
- {
- pc->SetParentType(pt);
- pc = pc->GetClosingParen();
-
- if (pc->IsNotNullChunk())
- {
- pc->SetParentType(pt);
- }
- }
- else if (pc->Is(CT_SEMICOLON))
- {
- pc->SetParentType(pt);
- }
- LOG_FMT(LOCMSGD, "\n");
-} // handle_oc_message_decl
-
-
-static void handle_oc_message_send(Chunk *os)
-{
- LOG_FUNC_ENTRY();
-
- Chunk *cs = os->GetNext();
-
- while ( cs->IsNotNullChunk()
- && cs->GetLevel() > os->GetLevel())
- {
- cs = cs->GetNext();
- }
-
- if ( cs->IsNullChunk()
- || cs->IsNot(CT_SQUARE_CLOSE))
- {
- return;
- }
- LOG_FMT(LOCMSG, "%s(%d): orig line is %zu, orig col is %zu\n",
- __func__, __LINE__, os->GetOrigLine(), os->GetOrigCol());
-
- Chunk *tmp = cs->GetNextNcNnl();
-
- if (tmp->IsSemicolon())
- {
- tmp->SetParentType(CT_OC_MSG);
- }
- // expect a word first thing or [...]
- tmp = os->GetNextNcNnl();
-
- if ( tmp->Is(CT_SQUARE_OPEN)
- || tmp->Is(CT_PAREN_OPEN)
- || tmp->Is(CT_OC_AT))
- {
- Chunk *tt = tmp->GetNextNcNnl();
-
- if ( tmp->Is(CT_OC_AT)
- && tt->IsNotNullChunk())
- {
- if ( tt->Is(CT_PAREN_OPEN)
- || tt->Is(CT_BRACE_OPEN)
- || tt->Is(CT_SQUARE_OPEN))
- {
- tmp = tt;
- }
- else
- {
- LOG_FMT(LOCMSG, "%s(%d): tmp orig line is %zu, orig col is %zu, expected identifier, not '%s' [%s]\n",
- __func__, __LINE__, tmp->GetOrigLine(), tmp->GetOrigCol(),
- tmp->Text(), get_token_name(tmp->GetType()));
- return;
- }
- }
- tmp = tmp->GetClosingParen();
- }
- else if ( tmp->IsNot(CT_WORD)
- && tmp->IsNot(CT_TYPE)
- && tmp->IsNot(CT_THIS)
- && tmp->IsNot(CT_STAR)
- && tmp->IsNot(CT_STRING))
- {
- LOG_FMT(LOCMSG, "%s(%d): orig line is %zu, orig col is %zu, expected identifier, not '%s' [%s]\n",
- __func__, __LINE__, tmp->GetOrigLine(), tmp->GetOrigCol(),
- tmp->Text(), get_token_name(tmp->GetType()));
- return;
- }
- else
- {
- if (tmp->IsStar()) // Issue #2722
- {
- tmp->SetType(CT_PTR_TYPE);
- tmp = tmp->GetNextNcNnl();
- }
- Chunk *tt = tmp->GetNextNcNnl();
-
- if (tt->IsParenOpen())
- {
- LOG_FMT(LFCN, "%s(%d): (18) SET TO CT_FUNC_CALL: orig line is %zu, orig col is %zu, Text() '%s'\n",
- __func__, __LINE__, tmp->GetOrigLine(), tmp->GetOrigCol(), tmp->Text());
- tmp->SetType(CT_FUNC_CALL);
- tmp = set_paren_parent(tt, CT_FUNC_CALL)->GetPrevNcNnlNi(); // Issue #2279
- }
- else
- {
- tmp->SetType(CT_OC_MSG_CLASS);
- }
- }
- os->SetParentType(CT_OC_MSG);
- os->SetFlagBits(PCF_IN_OC_MSG);
- cs->SetParentType(CT_OC_MSG);
- cs->SetFlagBits(PCF_IN_OC_MSG);
-
- // handle '< protocol >'
- tmp = tmp->GetNextNcNnl();
-
- if (tmp->IsString("<"))
- {
- Chunk *ao = tmp;
- Chunk *ac = ao->GetNextString(">", 1, ao->GetLevel());
-
- if (ac->IsNotNullChunk())
- {
- ao->SetType(CT_ANGLE_OPEN);
- ao->SetParentType(CT_OC_PROTO_LIST);
- ac->SetType(CT_ANGLE_CLOSE);
- ac->SetParentType(CT_OC_PROTO_LIST);
-
- for (tmp = ao->GetNext(); tmp != ac; tmp = tmp->GetNext())
- {
- tmp->SetLevel(tmp->GetLevel() + 1);
- tmp->SetParentType(CT_OC_PROTO_LIST);
- }
-
- tmp = ac->GetNextNcNnl();
- }
- else
- {
- tmp = Chunk::NullChunkPtr;
- }
- }
- // handle 'object.property' and 'collection[index]'
- else
- {
- while (tmp->IsNotNullChunk())
- {
- if (tmp->Is(CT_MEMBER)) // move past [object.prop1.prop2
- {
- Chunk *typ = tmp->GetNextNcNnl();
-
- if ( typ->Is(CT_WORD)
- || typ->Is(CT_TYPE))
- {
- tmp = typ->GetNextNcNnl();
- }
- else
- {
- break;
- }
- }
- else if (tmp->Is(CT_SQUARE_OPEN)) // move past [collection[index]
- {
- Chunk *tcs = tmp->GetNextNcNnl();
-
- while ( tcs->IsNotNullChunk()
- && tcs->GetLevel() > tmp->GetLevel())
- {
- tcs = tcs->GetNextNcNnl();
- }
-
- if (tcs->Is(CT_SQUARE_CLOSE))
- {
- tmp = tcs->GetNextNcNnl();
- }
- else
- {
- break;
- }
- }
- else
- {
- break;
- }
- }
- }
-
- // [(self.foo.bar) method]
- if (tmp->IsParenOpen())
- {
- tmp = tmp->GetClosingParen()->GetNextNcNnl();
- }
-
- if ( tmp->Is(CT_WORD)
- || tmp->Is(CT_ACCESS)
- || tmp->Is(CT_TYPE))
- {
- tmp->SetType(CT_OC_MSG_FUNC);
- }
- Chunk *prev = Chunk::NullChunkPtr;
-
- for (tmp = os->GetNext(); tmp != cs; tmp = tmp->GetNext())
- {
- tmp->SetFlagBits(PCF_IN_OC_MSG);
-
- if (tmp->GetLevel() == cs->GetLevel() + 1)
- {
- if ( tmp->Is(CT_COLON)
- || tmp->Is(CT_ACCESS_COLON))
- {
- tmp->SetType(CT_OC_COLON);
-
- if ( prev->Is(CT_WORD)
- || prev->Is(CT_ACCESS)
- || prev->Is(CT_TYPE))
- {
- // Might be a named param, check previous block
- Chunk *pp = prev->GetPrev();
-
- if ( pp->IsNotNullChunk()
- && pp->IsNot(CT_OC_COLON)
- && pp->IsNot(CT_ARITH)
- && pp->IsNot(CT_SHIFT)
- && pp->IsNot(CT_CARET))
- {
- prev->SetType(CT_OC_MSG_NAME);
- tmp->SetParentType(CT_OC_MSG_NAME);
- }
- }
- }
- }
- prev = tmp;
- }
-} // handle_oc_message_send
-
-
-static void handle_oc_available(Chunk *os)
-{
- os = os->GetNext();
-
- while (os->IsNotNullChunk())
- {
- E_Token origType = os->GetType();
- os->SetType(CT_OC_AVAILABLE_VALUE);
-
- if (origType == CT_PAREN_CLOSE)
- {
- break;
- }
- os = os->GetNext();
- }
-}
-
-
-static void handle_oc_property_decl(Chunk *os)
-{
- log_rule_B("mod_sort_oc_properties");
-
- if (options::mod_sort_oc_properties())
- {
- typedef std::vector<Chunk *> ChunkGroup;
-
- Chunk *next = os->GetNext();
- Chunk *open_paren = Chunk::NullChunkPtr;
-
- std::vector<ChunkGroup> class_chunks; // class
- std::vector<ChunkGroup> thread_chunks; // atomic, nonatomic
- std::vector<ChunkGroup> readwrite_chunks; // readwrite, readonly
- std::vector<ChunkGroup> ref_chunks; // retain, copy, assign, weak, strong, unsafe_unretained
- std::vector<ChunkGroup> getter_chunks; // getter
- std::vector<ChunkGroup> setter_chunks; // setter
- std::vector<ChunkGroup> nullability_chunks; // nonnull, nullable, null_unspecified, null_resettable
- std::vector<ChunkGroup> other_chunks; // any words other than above
-
- if (next->Is(CT_PAREN_OPEN))
- {
- open_paren = next;
- next = next->GetNext();
-
- /*
- * Determine location of the property attributes
- * NOTE: Did not do this in the combine.cpp do_symbol_check as
- * I was not sure what the ramifications of adding a new type
- * for each of the below types would be. It did break some items
- * when I attempted to add them so this is my hack for now.
- */
- while ( next->IsNotNullChunk()
- && next->IsNot(CT_PAREN_CLOSE))
- {
- if (next->Is(CT_OC_PROPERTY_ATTR))
- {
- if ( next->IsString("atomic")
- || next->IsString("nonatomic"))
- {
- ChunkGroup chunkGroup;
- chunkGroup.push_back(next);
- thread_chunks.push_back(chunkGroup);
- }
- else if ( next->IsString("readonly")
- || next->IsString("readwrite"))
- {
- ChunkGroup chunkGroup;
- chunkGroup.push_back(next);
- readwrite_chunks.push_back(chunkGroup);
- }
- else if ( next->IsString("assign")
- || next->IsString("retain")
- || next->IsString("copy")
- || next->IsString("strong")
- || next->IsString("weak")
- || next->IsString("unsafe_unretained"))
- {
- ChunkGroup chunkGroup;
- chunkGroup.push_back(next);
- ref_chunks.push_back(chunkGroup);
- }
- else if (next->IsString("getter"))
- {
- ChunkGroup chunkGroup;
-
- do
- {
- chunkGroup.push_back(next);
- next = next->GetNext();
- } while ( next->IsNotNullChunk()
- && next->IsNot(CT_COMMA)
- && next->IsNot(CT_PAREN_CLOSE));
-
- next = next->GetPrev();
-
- // coverity CID 160946
- if (next->IsNullChunk())
- {
- break;
- }
- getter_chunks.push_back(chunkGroup);
- }
- else if (next->IsString("setter"))
- {
- ChunkGroup chunkGroup;
-
- do
- {
- chunkGroup.push_back(next);
- next = next->GetNext();
- } while ( next->IsNotNullChunk()
- && next->IsNot(CT_COMMA)
- && next->IsNot(CT_PAREN_CLOSE));
-
- if (next->IsNotNullChunk())
- {
- next = next->GetPrev();
- }
-
- if (next->IsNullChunk())
- {
- break;
- }
- setter_chunks.push_back(chunkGroup);
- }
- else if ( next->IsString("nullable")
- || next->IsString("nonnull")
- || next->IsString("null_resettable")
- || next->IsString("null_unspecified"))
- {
- ChunkGroup chunkGroup;
- chunkGroup.push_back(next);
- nullability_chunks.push_back(chunkGroup);
- }
- else if (next->IsString("class"))
- {
- ChunkGroup chunkGroup;
- chunkGroup.push_back(next);
- class_chunks.push_back(chunkGroup);
- }
- else
- {
- ChunkGroup chunkGroup;
- chunkGroup.push_back(next);
- other_chunks.push_back(chunkGroup);
- }
- }
- else if (next->IsWord())
- {
- if (next->IsString("class"))
- {
- ChunkGroup chunkGroup;
- chunkGroup.push_back(next);
- class_chunks.push_back(chunkGroup);
- }
- else
- {
- ChunkGroup chunkGroup;
- chunkGroup.push_back(next);
- other_chunks.push_back(chunkGroup);
- }
- }
- next = next->GetNext();
- }
- log_rule_B("mod_sort_oc_property_class_weight");
- int class_w = options::mod_sort_oc_property_class_weight();
- log_rule_B("mod_sort_oc_property_thread_safe_weight");
- int thread_w = options::mod_sort_oc_property_thread_safe_weight();
- log_rule_B("mod_sort_oc_property_readwrite_weight");
- int readwrite_w = options::mod_sort_oc_property_readwrite_weight();
- log_rule_B("mod_sort_oc_property_reference_weight");
- int ref_w = options::mod_sort_oc_property_reference_weight();
- log_rule_B("mod_sort_oc_property_getter_weight");
- int getter_w = options::mod_sort_oc_property_getter_weight();
- log_rule_B("mod_sort_oc_property_setter_weight");
- int setter_w = options::mod_sort_oc_property_setter_weight();
- log_rule_B("mod_sort_oc_property_nullability_weight");
- int nullability_w = options::mod_sort_oc_property_nullability_weight();
-
- //
- std::multimap<int, std::vector<ChunkGroup> > sorted_chunk_map;
- sorted_chunk_map.insert(pair<int, std::vector<ChunkGroup> >(class_w, class_chunks));
- sorted_chunk_map.insert(pair<int, std::vector<ChunkGroup> >(thread_w, thread_chunks));
- sorted_chunk_map.insert(pair<int, std::vector<ChunkGroup> >(readwrite_w, readwrite_chunks));
- sorted_chunk_map.insert(pair<int, std::vector<ChunkGroup> >(ref_w, ref_chunks));
- sorted_chunk_map.insert(pair<int, std::vector<ChunkGroup> >(getter_w, getter_chunks));
- sorted_chunk_map.insert(pair<int, std::vector<ChunkGroup> >(setter_w, setter_chunks));
- sorted_chunk_map.insert(pair<int, std::vector<ChunkGroup> >(nullability_w, nullability_chunks));
- sorted_chunk_map.insert(pair<int, std::vector<ChunkGroup> >(std::numeric_limits<int>::min(), other_chunks));
-
- Chunk *curr_chunk = open_paren;
-
- for (multimap<int, std::vector<ChunkGroup> >::reverse_iterator it = sorted_chunk_map.rbegin(); it != sorted_chunk_map.rend(); ++it)
- {
- std::vector<ChunkGroup> chunk_groups = (*it).second;
-
- for (auto chunk_group : chunk_groups)
- {
- for (auto chunk : chunk_group)
- {
- chunk->SetOrigPrevSp(0);
-
- if (chunk != curr_chunk)
- {
- chunk->MoveAfter(curr_chunk);
- curr_chunk = chunk;
- }
- else
- {
- curr_chunk = curr_chunk->GetNext();
- }
- }
-
- // add the parenthesis
- Chunk endchunk;
- endchunk.SetType(CT_COMMA);
- endchunk.SetParentType(curr_chunk->GetParentType());
- endchunk.Str() = ",";
- endchunk.SetLevel(curr_chunk->GetLevel());
- endchunk.SetPpLevel(curr_chunk->GetPpLevel());
- endchunk.SetBraceLevel(curr_chunk->GetBraceLevel());
- endchunk.SetOrigLine(curr_chunk->GetOrigLine());
- endchunk.SetOrigCol(curr_chunk->GetOrigCol());
- endchunk.SetColumn(curr_chunk->GetOrigColEnd() + 1);
- endchunk.SetFlags(curr_chunk->GetFlags() & PCF_COPY_FLAGS);
- endchunk.CopyAndAddAfter(curr_chunk);
- curr_chunk = curr_chunk->GetNext();
- }
- }
-
- // Remove the extra comma's that we did not move
- while ( curr_chunk->IsNotNullChunk()
- && curr_chunk->IsNot(CT_PAREN_CLOSE))
- {
- Chunk *rm_chunk = curr_chunk;
- curr_chunk = curr_chunk->GetNext();
- Chunk::Delete(rm_chunk);
- }
- }
- }
- Chunk *tmp = os->GetNextNcNnl();
-
- if (tmp->IsParenOpen())
- {
- tmp = tmp->GetClosingParen()->GetNextNcNnl();
- }
- fix_variable_definition(tmp);
-} // handle_oc_property_decl
-
-
-static void handle_cs_square_stmt(Chunk *os)
-{
- LOG_FUNC_ENTRY();
-
- Chunk *cs = os->GetNext();
-
- while ( cs->IsNotNullChunk()
- && cs->GetLevel() > os->GetLevel())
- {
- cs = cs->GetNext();
- }
-
- if ( cs->IsNullChunk()
- || cs->IsNot(CT_SQUARE_CLOSE))
- {
- return;
- }
- os->SetParentType(CT_CS_SQ_STMT);
- cs->SetParentType(CT_CS_SQ_STMT);
-
- Chunk *tmp;
-
- for (tmp = os->GetNext(); tmp != cs; tmp = tmp->GetNext())
- {
- tmp->SetParentType(CT_CS_SQ_STMT);
-
- if (tmp->Is(CT_COLON))
- {
- tmp->SetType(CT_CS_SQ_COLON);
- }
- }
-
- tmp = cs->GetNextNcNnl();
-
- if (tmp->IsNotNullChunk())
- {
- tmp->SetFlagBits(PCF_STMT_START | PCF_EXPR_START);
- log_ruleStart("start statement/ expression", tmp);
- }
-} // handle_cs_square_stmt
-
-
-static void handle_cs_property(Chunk *bro)
-{
- LOG_FUNC_ENTRY();
-
- set_paren_parent(bro, CT_CS_PROPERTY);
-
- bool did_prop = false;
- Chunk *pc = bro;
-
- while ((pc = pc->GetPrevNcNnlNi())->IsNotNullChunk()) // Issue #2279
- {
- if (pc->GetLevel() == bro->GetLevel())
- {
- //prevent scanning back past 'new' in expressions like new List<int> {1,2,3}
- // Issue # 1620, UNI-24090.cs
- if (pc->Is(CT_NEW))
- {
- break;
- }
-
- if ( !did_prop
- && ( pc->Is(CT_WORD)
- || pc->Is(CT_THIS)))
- {
- pc->SetType(CT_CS_PROPERTY);
- did_prop = true;
- }
- else
- {
- pc->SetParentType(CT_CS_PROPERTY);
- make_type(pc);
- }
-
- if (pc->TestFlags(PCF_STMT_START))
- {
- break;
- }
- }
- }
-}
-
-
-static void handle_cs_array_type(Chunk *pc)
-{
- if (pc->IsNullChunk())
- {
- return;
- }
- Chunk *prev = pc->GetPrev();
-
- for ( ;
- prev->Is(CT_COMMA);
- prev = prev->GetPrev())
- {
- // empty
- }
-
- if (prev->Is(CT_SQUARE_OPEN))
- {
- while (pc != prev)
- {
- pc->SetParentType(CT_TYPE);
- pc = pc->GetPrev();
- }
- prev->SetParentType(CT_TYPE);
- }
-}
-
-
-static void handle_wrap(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
- Chunk *opp = pc->GetNext();
- Chunk *name = opp->GetNext();
- Chunk *clp = name->GetNext();
-
- log_rule_B("sp_func_call_paren");
- log_rule_B("sp_cpp_cast_paren");
- iarf_e pav = pc->Is(CT_FUNC_WRAP) ?
- options::sp_func_call_paren() :
- options::sp_cpp_cast_paren();
-
- log_rule_B("sp_inside_fparen");
- log_rule_B("sp_inside_paren_cast");
- iarf_e av = pc->Is(CT_FUNC_WRAP) ?
- options::sp_inside_fparen() :
- options::sp_inside_paren_cast();
-
- if ( clp->Is(CT_PAREN_CLOSE)
- && opp->Is(CT_PAREN_OPEN)
- && ( name->Is(CT_WORD)
- || name->Is(CT_TYPE)))
- {
- const char *psp = (pav & IARF_ADD) ? " " : "";
- const char *fsp = (av & IARF_ADD) ? " " : "";
-
- pc->Str().append(psp);
- pc->Str().append("(");
- pc->Str().append(fsp);
- pc->Str().append(name->GetStr());
- pc->Str().append(fsp);
- pc->Str().append(")");
-
- pc->SetType(pc->Is(CT_FUNC_WRAP) ? CT_FUNCTION : CT_TYPE);
-
- pc->SetOrigColEnd(pc->GetOrigCol() + pc->Len());
-
- Chunk::Delete(opp);
- Chunk::Delete(name);
- Chunk::Delete(clp);
- }
-} // handle_wrap
-
-
-static void handle_proto_wrap(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
- Chunk *opp = pc->GetNextNcNnl();
- Chunk *name = opp->GetNextNcNnl();
- Chunk *tmp = name->GetNextNcNnl()->GetNextNcNnl();
- Chunk *clp = opp->GetClosingParen();
- Chunk *cma = clp->GetNextNcNnl();
-
- if ( opp->IsNullChunk()
- || name->IsNullChunk()
- || tmp->IsNullChunk()
- || clp->IsNullChunk()
- || cma->IsNullChunk()
- || ( name->IsNot(CT_WORD)
- && name->IsNot(CT_TYPE))
- || opp->IsNot(CT_PAREN_OPEN))
- {
- return;
- }
-
- if (cma->Is(CT_SEMICOLON))
- {
- pc->SetType(CT_FUNC_PROTO);
- }
- else if (cma->Is(CT_BRACE_OPEN))
- {
- LOG_FMT(LFCN, "%s(%d): (19) SET TO CT_FUNC_DEF: orig line is %zu, orig col is %zu, Text() '%s'\n",
- __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text());
- pc->SetType(CT_FUNC_DEF);
- }
- else
- {
- return;
- }
- opp->SetParentType(pc->GetType());
- clp->SetParentType(pc->GetType());
-
- tmp->SetParentType(CT_PROTO_WRAP);
-
- if (tmp->Is(CT_PAREN_OPEN))
- {
- fix_fcn_def_params(tmp);
- }
- else
- {
- fix_fcn_def_params(opp);
- name->SetType(CT_WORD);
- }
- tmp = tmp->GetClosingParen();
-
- if (tmp->IsNotNullChunk())
- {
- tmp->SetParentType(CT_PROTO_WRAP);
- }
- // Mark return type (TODO: move to own function)
- tmp = pc;
-
- while ((tmp = tmp->GetPrevNcNnlNi())->IsNotNullChunk()) // Issue #2279
- {
- if ( !tmp->IsTypeDefinition()
- && tmp->IsNot(CT_OPERATOR)
- && tmp->IsNot(CT_WORD)
- && tmp->IsNot(CT_ADDR))
- {
- break;
- }
- tmp->SetParentType(pc->GetType());
- make_type(tmp);
- }
-} // handle_proto_wrap
-
-
-/**
- * Java assert statements are: "assert EXP1 [: EXP2] ;"
- * Mark the parent of the colon and semicolon
- */
-static void handle_java_assert(Chunk *pc)
-{
- LOG_FUNC_ENTRY();
- bool did_colon = false;
- Chunk *tmp = pc;
-
- while ((tmp = tmp->GetNext())->IsNotNullChunk())
- {
- if (tmp->GetLevel() == pc->GetLevel())
- {
- if ( !did_colon
- && tmp->Is(CT_COLON))
- {
- did_colon = true;
- tmp->SetParentType(pc->GetType());
- }
-
- if (tmp->Is(CT_SEMICOLON))
- {
- tmp->SetParentType(pc->GetType());
- break;
- }
- }
- }
-} // handle_java_assert