summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/src/brace_cleanup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.74.0/src/brace_cleanup.cpp')
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.74.0/src/brace_cleanup.cpp1498
1 files changed, 0 insertions, 1498 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/src/brace_cleanup.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/src/brace_cleanup.cpp
deleted file mode 100644
index 0810c04c..00000000
--- a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/src/brace_cleanup.cpp
+++ /dev/null
@@ -1,1498 +0,0 @@
-/**
- * @file brace_cleanup.cpp
- * Determines the brace level and paren level.
- * Inserts virtual braces as needed.
- * Handles all that preprocessor stuff.
- *
- * @author Ben Gardner
- * @license GPL v2+
- */
-
-#include "brace_cleanup.h"
-
-#include "flag_parens.h"
-#include "frame_list.h"
-#include "keywords.h"
-#include "lang_pawn.h"
-#include "prototypes.h"
-
-#include <stdexcept> // to get std::invalid_argument
-
-constexpr static auto LCURRENT = LBC;
-
-using namespace uncrustify;
-
-using std::invalid_argument;
-using std::string;
-using std::to_string;
-using std::stringstream;
-
-
-/*
- * abbreviations used:
- * - sparen = tbd
- * - PS = Parenthesis Stack
- * - pse = Parenthesis Stack
- */
-
-
-struct BraceState
-{
- std::vector<ParseFrame> frames = {};
- c_token_t in_preproc = CT_NONE;
- int pp_level = 0;
- bool consumed = false;
-};
-
-/**
- * Called when a statement was just closed and the pse_tos was just
- * decremented.
- *
- * - if the TOS is now VBRACE, insert a CT_VBRACE_CLOSE and recurse.
- * - if the TOS is a complex statement, call handle_complex_close()
- *
- * @retval true done with this chunk
- * @retval false keep processing
- */
-static bool close_statement(ParseFrame &frm, chunk_t *pc, const BraceState &braceState);
-
-
-static size_t preproc_start(BraceState &braceState, ParseFrame &frm, chunk_t *pc);
-
-
-static void print_stack(log_sev_t logsev, const char *str, const ParseFrame &frm);
-
-
-/**
- * pc is a CT_WHILE.
- * Scan backwards to see if we find a brace/vbrace with the parent set to CT_DO
- */
-static bool maybe_while_of_do(chunk_t *pc);
-
-
-/**
- * @param after determines: true - insert_vbrace_close_after(pc, frm)
- * false - insert_vbrace_open_before(pc, frm)
- */
-static chunk_t *insert_vbrace(chunk_t *pc, bool after, const ParseFrame &frm);
-
-#define insert_vbrace_close_after(pc, frm) insert_vbrace(pc, true, frm)
-#define insert_vbrace_open_before(pc, frm) insert_vbrace(pc, false, frm)
-
-static void parse_cleanup(BraceState &braceState, ParseFrame &frm, chunk_t *pc);
-
-
-/**
- * Checks the progression of complex statements.
- * - checks for else after if
- * - checks for if after else
- * - checks for while after do
- * - checks for open brace in BRACE2 and BRACE_DO stages, inserts open VBRACE
- * - checks for open paren in PAREN1 and BRACE2 stages, complains
- *
- * @param frm The parse frame
- * @param pc The current chunk
- *
- * @return true - done with this chunk, false - keep processing
- */
-static bool check_complex_statements(ParseFrame &frm, chunk_t *pc, const BraceState &braceState);
-
-
-/**
- * Handles a close paren or brace - just progress the stage, if the end
- * of the statement is hit, call close_statement()
- *
- * @param frm The parse frame
- * @param pc The current chunk
- *
- * @return true - done with this chunk, false - keep processing
- */
-static bool handle_complex_close(ParseFrame &frm, chunk_t *pc, const BraceState &braceState);
-
-
-//! We're on a 'namespace' skip the word and then set the parent of the braces.
-static void mark_namespace(chunk_t *pns);
-
-
-static size_t preproc_start(BraceState &braceState, ParseFrame &frm, chunk_t *pc)
-{
- LOG_FUNC_ENTRY();
- const size_t pp_level = braceState.pp_level;
-
- chunk_t *next = chunk_get_next_ncnnl(pc);
-
- if (next == nullptr)
- {
- return(pp_level);
- }
- // Get the type of preprocessor and handle it
- braceState.in_preproc = next->type;
-
- // If we are not in a define, check for #if, #else, #endif, etc
- if (braceState.in_preproc != CT_PP_DEFINE)
- {
- int pp_indent = fl_check(braceState.frames, frm, braceState.pp_level, pc);
- return(pp_indent);
- }
- // else push the frame stack
- fl_push(braceState.frames, frm);
-
- // a preproc body starts a new, blank frame
- frm = {};
- frm.level = 1;
- frm.brace_level = 1;
-
- // TODO: not sure about the next 3 lines
- frm.push(nullptr);
- frm.top().type = CT_PP_DEFINE;
-
- return(pp_level);
-}
-
-
-static void print_stack(log_sev_t logsev, const char *str,
- const ParseFrame &frm)
-{
- LOG_FUNC_ENTRY();
-
- if (!log_sev_on(logsev))
- {
- return;
- }
- log_fmt(logsev, "%s(%d): str is '%s'", __func__, __LINE__, str);
-
- for (size_t idx = 1; idx < frm.size(); idx++)
- {
- if (frm.at(idx).stage != brace_stage_e::NONE)
- {
- LOG_FMT(logsev, " [%s - %u]", get_token_name(frm.at(idx).type),
- (unsigned int)frm.at(idx).stage);
- }
- else
- {
- LOG_FMT(logsev, " [%s]", get_token_name(frm.at(idx).type));
- }
- }
-
- log_fmt(logsev, "\n");
-}
-
-
-//TODO: This can be cleaned up and simplified - we can look both forward and backward!
-void brace_cleanup(void)
-{
- LOG_FUNC_ENTRY();
-
- BraceState braceState;
- ParseFrame frm{};
- chunk_t *pc = chunk_get_head();
-
- while (pc != nullptr)
- {
- LOG_FMT(LTOK, "%s(%d): orig_line is %zu, orig_col is %zu, text() is '%s'\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
-
- // Check for leaving a #define body
- if ( braceState.in_preproc != CT_NONE
- && !pc->flags.test(PCF_IN_PREPROC))
- {
- if (braceState.in_preproc == CT_PP_DEFINE)
- {
- // out of the #define body, restore the frame
- fl_pop(braceState.frames, frm);
- }
- braceState.in_preproc = CT_NONE;
- }
- // Check for a preprocessor start
- size_t pp_level;
-
- if (chunk_is_token(pc, CT_PREPROC))
- {
- pp_level = preproc_start(braceState, frm, pc);
- }
- else
- {
- pp_level = braceState.pp_level;
- }
- LOG_FMT(LTOK, "%s(%d): pp_level is %zu\n",
- __func__, __LINE__, pp_level);
-
- // Do before assigning stuff from the frame
- if ( language_is_set(LANG_PAWN)
- && frm.top().type == CT_VBRACE_OPEN
- && chunk_is_token(pc, CT_NEWLINE))
- {
- pc = pawn_check_vsemicolon(pc);
-
- if (pc == nullptr)
- {
- return;
- }
- }
-
- // Issue #1813
- if (chunk_is_token(pc, CT_NAMESPACE))
- {
- mark_namespace(pc);
- }
- // Assume the level won't change
- pc->level = frm.level;
- pc->brace_level = frm.brace_level;
- pc->pp_level = pp_level;
-
- /*
- * #define bodies get the full formatting treatment
- * Also need to pass in the initial '#' to close out any virtual braces.
- */
- if ( !chunk_is_comment(pc)
- && !chunk_is_newline(pc)
- && !chunk_is_token(pc, CT_ATTRIBUTE)
- && !chunk_is_token(pc, CT_IGNORED) // Issue #2279
- && ( braceState.in_preproc == CT_PP_DEFINE
- || braceState.in_preproc == CT_NONE))
- {
- braceState.consumed = false;
- parse_cleanup(braceState, frm, pc);
- print_stack(LBCSAFTER, (chunk_is_token(pc, CT_VBRACE_CLOSE)) ? "Virt-}\n" : pc->str.c_str(), frm);
- }
- pc = chunk_get_next(pc);
- }
-// pc = chunk_get_head();
-//
-// while (pc != nullptr)
-// {
-// LOG_FMT(LTOK, "%s(%d): orig_line is %zu, orig_col is %zu, text() is '%s'\n",
-// __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
-//
-// // look for template
-// if (chunk_is_token(pc, CT_TEMPLATE)) // Issue #3309
-// {
-// chunk_t *template_end = chunk_get_next_type(pc, CT_SEMICOLON, pc->level);
-//
-// // look for a parameter pack
-// while (pc != nullptr)
-// {
-// LOG_FMT(LTOK, "%s(%d): orig_line is %zu, orig_col is %zu, text() is '%s'\n",
-// __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
-//
-// if (chunk_is_token(pc, CT_PARAMETER_PACK))
-// {
-// chunk_t *parameter_pack = pc;
-//
-// // look for a token with the same text
-// while (pc != nullptr)
-// {
-// LOG_FMT(LTOK, "%s(%d): orig_line is %zu, orig_col is %zu, text() is '%s'\n",
-// __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
-// pc = chunk_get_next(pc);
-//
-// if (pc == template_end)
-// {
-// break;
-// }
-//
-// if (strcmp(pc->text(), parameter_pack->text()) == 0)
-// {
-// set_chunk_type(pc, CT_PARAMETER_PACK);
-// }
-// }
-// }
-// pc = chunk_get_next(pc);
-//
-// if (pc == template_end)
-// {
-// break;
-// }
-// }
-// }
-// pc = chunk_get_next(pc);
-// }
-} // brace_cleanup
-
-
-static bool maybe_while_of_do(chunk_t *pc)
-{
- LOG_FUNC_ENTRY();
-
- chunk_t *prev = chunk_get_prev_ncnnl(pc);
-
- if ( prev == nullptr
- || !prev->flags.test(PCF_IN_PREPROC))
- {
- return(false);
- }
-
- // Find the chunk before the preprocessor
- while ( prev != nullptr
- && prev->flags.test(PCF_IN_PREPROC))
- {
- prev = chunk_get_prev_ncnnl(prev);
- }
-
- if ( ( chunk_is_token(prev, CT_VBRACE_CLOSE)
- || chunk_is_token(prev, CT_BRACE_CLOSE))
- && get_chunk_parent_type(prev) == CT_DO)
- {
- return(true);
- }
- return(false);
-}
-
-
-/**
- * At the heart of this algorithm are two stacks.
- * There is the Paren Stack (PS) and the Frame stack.
- *
- * The PS (pse in the code) keeps track of braces, parens,
- * if/else/switch/do/while/etc items -- anything that is nestable.
- * Complex statements go through stages.
- * Take this simple if statement as an example:
- * if ( x ) { x--; }
- *
- * The stack would change like so: 'token' stack afterwards
- * 'if' [IF - 1]
- * '(' [IF - 1] [PAREN OPEN]
- * 'x' [IF - 1] [PAREN OPEN]
- * ')' [IF - 2] <- note that the state was incremented
- * '{' [IF - 2] [BRACE OPEN]
- * 'x' [IF - 2] [BRACE OPEN]
- * '--' [IF - 2] [BRACE OPEN]
- * ';' [IF - 2] [BRACE OPEN]
- * '}' [IF - 3]
- * <- lack of else kills the IF, closes statement
- *
- * Virtual braces example:
- * if ( x ) x--; else x++;
- *
- * 'if' [IF - 1]
- * '(' [IF - 1] [PAREN OPEN]
- * 'x' [IF - 1] [PAREN OPEN]
- * ')' [IF - 2]
- * 'x' [IF - 2] [VBRACE OPEN] <- VBrace open inserted before because '{' was not next
- * '--' [IF - 2] [VBRACE OPEN]
- * ';' [IF - 3] <- VBrace close inserted after semicolon
- * 'else' [ELSE - 0] <- IF changed into ELSE
- * 'x' [ELSE - 0] [VBRACE OPEN] <- lack of '{' -> VBrace
- * '++' [ELSE - 0] [VBRACE OPEN]
- * ';' [ELSE - 0] <- VBrace close inserted after semicolon
- * <- ELSE removed after statement close
- *
- * The pse stack is kept on a frame stack.
- * The frame stack is need for languages that support preprocessors (C, C++, C#)
- * that can arbitrarily change code flow. It also isolates #define macros so
- * that they are indented independently and do not affect the rest of the program.
- *
- * When an #if is hit, a copy of the current frame is push on the frame stack.
- * When an #else/#elif is hit, a copy of the current stack is pushed under the
- * #if frame and the original (pre-#if) frame is copied to the current frame.
- * When #endif is hit, the top frame is popped.
- * This has the following effects:
- * - a simple #if / #endif does not affect program flow
- * - #if / #else /#endif - continues from the #if clause
- *
- * When a #define is entered, the current frame is pushed and cleared.
- * When a #define is exited, the frame is popped.
- */
-static void parse_cleanup(BraceState &braceState, ParseFrame &frm, chunk_t *pc)
-{
- LOG_FUNC_ENTRY();
-
- LOG_FMT(LTOK, "%s(%d): orig_line is %zu, orig_col is %zu, type is %s, tos is %zu, TOS.type is %s, TOS.stage is %s, ",
- __func__, __LINE__, pc->orig_line, pc->orig_col, get_token_name(pc->type),
- frm.size() - 1, get_token_name(frm.top().type),
- get_brace_stage_name(frm.top().stage));
- log_pcf_flags(LTOK, pc->flags);
-
- // Mark statement starts
- LOG_FMT(LTOK, "%s(%d): orig_line is %zu, type is %s, text() is '%s'\n",
- __func__, __LINE__, pc->orig_line, get_token_name(pc->type), pc->text());
- LOG_FMT(LTOK, "%s(%d): frm.stmt_count is %zu, frm.expr_count is %zu\n",
- __func__, __LINE__, frm.stmt_count, frm.expr_count);
-
- if ( ( frm.stmt_count == 0
- || frm.expr_count == 0)
- && !chunk_is_semicolon(pc)
- && chunk_is_not_token(pc, CT_BRACE_CLOSE)
- && chunk_is_not_token(pc, CT_VBRACE_CLOSE)
- && !chunk_is_str(pc, ")", 1)
- && !chunk_is_str(pc, "]", 1))
- {
- chunk_flags_set(pc, PCF_EXPR_START | ((frm.stmt_count == 0) ? PCF_STMT_START : PCF_NONE));
- LOG_FMT(LSTMT, "%s(%d): orig_line is %zu, 1.marked '%s' as %s, start stmt_count is %zu, expr_count is %zu\n",
- __func__, __LINE__, pc->orig_line, pc->text(),
- pc->flags.test(PCF_STMT_START) ? "stmt" : "expr", frm.stmt_count,
- frm.expr_count);
- }
- frm.stmt_count++;
- frm.expr_count++;
- LOG_FMT(LTOK, "%s(%d): frm.stmt_count is %zu, frm.expr_count is %zu\n",
- __func__, __LINE__, frm.stmt_count, frm.expr_count);
-
- if (frm.sparen_count > 0)
- {
- chunk_flags_set(pc, PCF_IN_SPAREN);
-
- // Mark everything in the for statement
- for (int tmp = static_cast<int>(frm.size()) - 2; tmp >= 0; tmp--)
- {
- if (frm.at(tmp).type == CT_FOR)
- {
- chunk_flags_set(pc, PCF_IN_FOR);
- break;
- }
- }
-
- // Mark the parent on semicolons in for() statements
- if ( chunk_is_token(pc, CT_SEMICOLON)
- && frm.size() > 2
- && frm.prev().type == CT_FOR)
- {
- set_chunk_parent(pc, CT_FOR);
- }
- }
-
- // Check the progression of complex statements
- if ( frm.top().stage != brace_stage_e::NONE
- && !chunk_is_token(pc, CT_AUTORELEASEPOOL)
- && check_complex_statements(frm, pc, braceState))
- {
- return;
- }
-
- /*
- * Check for a virtual brace statement close due to a semicolon.
- * The virtual brace will get handled the next time through.
- * The semicolon isn't handled at all.
- * TODO: may need to float VBRACE past comments until newline?
- */
- if (frm.top().type == CT_VBRACE_OPEN)
- {
- if (chunk_is_semicolon(pc))
- {
- braceState.consumed = true;
- close_statement(frm, pc, braceState);
- }
- else if ( language_is_set(LANG_PAWN)
- && chunk_is_token(pc, CT_BRACE_CLOSE))
- {
- close_statement(frm, pc, braceState);
- }
- else if ( language_is_set(LANG_D)
- && chunk_is_token(pc, CT_BRACE_CLOSE))
- {
- close_statement(frm, pc, braceState);
- }
- }
-
- // Handle close parenthesis, vbrace, brace, and square
- if ( chunk_is_token(pc, CT_PAREN_CLOSE)
- || chunk_is_token(pc, CT_BRACE_CLOSE)
- || chunk_is_token(pc, CT_VBRACE_CLOSE)
- || chunk_is_token(pc, CT_ANGLE_CLOSE)
- || chunk_is_token(pc, CT_MACRO_CLOSE)
- || chunk_is_token(pc, CT_SQUARE_CLOSE))
- {
- // Change CT_PAREN_CLOSE into CT_SPAREN_CLOSE or CT_FPAREN_CLOSE
- if ( chunk_is_token(pc, CT_PAREN_CLOSE)
- && ( (frm.top().type == CT_FPAREN_OPEN)
- || (frm.top().type == CT_SPAREN_OPEN)))
- {
- // TODO: fix enum hack
- set_chunk_type(pc, static_cast<c_token_t>(frm.top().type + 1));
-
- if (chunk_is_token(pc, CT_SPAREN_CLOSE))
- {
- frm.sparen_count--;
- chunk_flags_clr(pc, PCF_IN_SPAREN);
- }
- }
-
- // Make sure the open / close match
- if (chunk_is_not_token(pc, (c_token_t)(frm.top().type + 1)))
- {
- LOG_FMT(LWARN, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- paren_stack_entry_t AA = frm.top(); // Issue #3055
-
- if (AA.type != CT_EOF)
- {
- LOG_FMT(LWARN, "%s(%d): (frm.top().type + 1) is %s\n",
- __func__, __LINE__, get_token_name((c_token_t)(frm.top().type + 1)));
- }
-
- if (pc->flags.test(PCF_IN_PREPROC)) // Issue #3113
- {
- // do nothing
- }
- else
- {
- if ( frm.top().type != CT_EOF
- && frm.top().type != CT_PP_DEFINE)
- {
- LOG_FMT(LWARN, "%s(%d): File: %s, orig_line is %zu, orig_col is %zu, Error: Unexpected '%s' for '%s', which was on line %zu\n",
- __func__, __LINE__, cpd.filename.c_str(), pc->orig_line, pc->orig_col,
- pc->text(), get_token_name(frm.top().pc->type),
- frm.top().pc->orig_line);
- print_stack(LBCSPOP, "=Error ", frm);
- cpd.error_count++;
- exit(EXIT_FAILURE);
- }
- }
- }
- else
- {
- braceState.consumed = true;
-
- // Copy the parent, update the parenthesis/brace levels
- set_chunk_parent(pc, frm.top().parent);
- frm.level--;
-
- if ( chunk_is_token(pc, CT_BRACE_CLOSE)
- || chunk_is_token(pc, CT_VBRACE_CLOSE)
- || chunk_is_token(pc, CT_MACRO_CLOSE))
- {
- frm.brace_level--;
- LOG_FMT(LBCSPOP, "%s(%d): frm.brace_level decreased to %zu",
- __func__, __LINE__, frm.brace_level);
- log_pcf_flags(LBCSPOP, pc->flags);
- }
- pc->level = frm.level;
- pc->brace_level = frm.brace_level;
-
- // Pop the entry
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-Close ", frm);
-
- if ( frm.top().stage == brace_stage_e::NONE
- && ( chunk_is_token(pc, CT_VBRACE_CLOSE)
- || chunk_is_token(pc, CT_BRACE_CLOSE)
- || chunk_is_token(pc, CT_SEMICOLON))
- && chunk_is_token(frm.top().pc, CT_VBRACE_OPEN))
- {
- // frames for functions are not created as they are for an if
- // this here is a hackish solution to close a vbrace of a block that
- // contains the function
- frm.push(nullptr); // <- dummy frame for the function
- frm.top().stage = brace_stage_e::BRACE2;
- }
-
- // See if we are in a complex statement
- if (frm.top().stage != brace_stage_e::NONE)
- {
- handle_complex_close(frm, pc, braceState);
- }
- }
- }
-
- /*
- * In this state, we expect a semicolon, but we'll also hit the closing
- * sparen, so we need to check braceState.consumed to see if the close sparen
- * was aleady handled.
- */
- if (frm.top().stage == brace_stage_e::WOD_SEMI)
- {
- if (braceState.consumed)
- {
- /*
- * If consumed, then we are on the close sparen.
- * PAWN: Check the next chunk for a semicolon. If it isn't, then
- * add a virtual semicolon, which will get handled on the next pass.
- */
- if (language_is_set(LANG_PAWN))
- {
- chunk_t *tmp = chunk_get_next_ncnnl(pc);
-
- if ( chunk_is_not_token(tmp, CT_SEMICOLON)
- && chunk_is_not_token(tmp, CT_VSEMICOLON))
- {
- pawn_add_vsemi_after(pc);
- }
- }
- }
- else
- {
- // Complain if this ISN'T a semicolon, but close out WHILE_OF_DO anyway
- if ( chunk_is_token(pc, CT_SEMICOLON)
- || chunk_is_token(pc, CT_VSEMICOLON))
- {
- braceState.consumed = true;
- set_chunk_parent(pc, CT_WHILE_OF_DO);
- }
- else
- {
- LOG_FMT(LWARN, "%s: %s(%d): %zu: Error: Expected a semicolon for WHILE_OF_DO, but got '%s'\n",
- cpd.filename.c_str(), __func__, __LINE__, pc->orig_line,
- get_token_name(pc->type));
- cpd.error_count++;
- }
- handle_complex_close(frm, pc, braceState);
- }
- }
- // Get the parent type for brace and parenthesis open
- c_token_t parent = get_chunk_parent_type(pc);
-
- if ( chunk_is_token(pc, CT_PAREN_OPEN)
- || chunk_is_token(pc, CT_FPAREN_OPEN)
- || chunk_is_token(pc, CT_SPAREN_OPEN)
- || chunk_is_token(pc, CT_BRACE_OPEN))
- {
- chunk_t *prev = chunk_get_prev_ncnnl(pc);
-
- if (prev != nullptr)
- {
- if ( chunk_is_token(pc, CT_PAREN_OPEN)
- || chunk_is_token(pc, CT_FPAREN_OPEN)
- || chunk_is_token(pc, CT_SPAREN_OPEN))
- {
- // Set the parent for parenthesis and change parenthesis type
- if ( chunk_is_token(prev, CT_IF)
- || chunk_is_token(prev, CT_CONSTEXPR)
- || chunk_is_token(prev, CT_ELSEIF)
- || chunk_is_token(prev, CT_WHILE)
- || chunk_is_token(prev, CT_WHILE_OF_DO)
- || chunk_is_token(prev, CT_DO)
- || chunk_is_token(prev, CT_FOR)
- || chunk_is_token(prev, CT_SWITCH)
- || chunk_is_token(prev, CT_CATCH)
- || chunk_is_token(prev, CT_SYNCHRONIZED)
- || chunk_is_token(prev, CT_D_VERSION)
- || chunk_is_token(prev, CT_D_VERSION_IF)
- || chunk_is_token(prev, CT_D_SCOPE)
- || chunk_is_token(prev, CT_D_SCOPE_IF))
- {
- set_chunk_type(pc, CT_SPAREN_OPEN);
- parent = frm.top().type;
- frm.sparen_count++;
- }
- else if (chunk_is_token(prev, CT_FUNCTION))
- {
- set_chunk_type(pc, CT_FPAREN_OPEN);
- parent = CT_FUNCTION;
- }
- // NS_ENUM and NS_OPTIONS are followed by a (type, name) pair
- else if ( chunk_is_token(prev, CT_ENUM)
- && language_is_set(LANG_OC))
- {
- // Treat both as CT_ENUM since the syntax is identical
- set_chunk_type(pc, CT_FPAREN_OPEN);
- parent = CT_ENUM;
- }
- else if (chunk_is_token(prev, CT_DECLSPEC)) // Issue 1289
- {
- parent = CT_DECLSPEC;
- }
- // else: no need to set parent
- }
- else // must be CT_BRACE_OPEN
- {
- // Set the parent for open braces
- if (frm.top().stage != brace_stage_e::NONE)
- {
- parent = frm.top().type;
- }
- else if ( chunk_is_token(prev, CT_ASSIGN)
- && (prev->str[0] == '='))
- {
- parent = CT_ASSIGN;
- }
- else if ( chunk_is_token(prev, CT_RETURN)
- && language_is_set(LANG_CPP))
- {
- parent = CT_RETURN;
- }
- // Carry through CT_ENUM parent in NS_ENUM (type, name) {
- // for the vim editor }
- else if ( chunk_is_token(prev, CT_FPAREN_CLOSE)
- && language_is_set(LANG_OC)
- && get_chunk_parent_type(prev) == CT_ENUM)
- {
- parent = CT_ENUM;
- }
- else if (chunk_is_token(prev, CT_FPAREN_CLOSE))
- {
- parent = CT_FUNCTION;
- }
- // else: no need to set parent
- }
- }
- }
-
- /*
- * Adjust the level for opens & create a stack entry
- * Note that CT_VBRACE_OPEN has already been handled.
- */
- if ( chunk_is_token(pc, CT_BRACE_OPEN)
- || chunk_is_token(pc, CT_PAREN_OPEN)
- || chunk_is_token(pc, CT_FPAREN_OPEN)
- || chunk_is_token(pc, CT_SPAREN_OPEN)
- || chunk_is_token(pc, CT_ANGLE_OPEN)
- || chunk_is_token(pc, CT_MACRO_OPEN)
- || chunk_is_token(pc, CT_SQUARE_OPEN))
- {
- frm.level++;
-
- if ( chunk_is_token(pc, CT_BRACE_OPEN)
- || chunk_is_token(pc, CT_MACRO_OPEN))
- {
- // Issue #1813
- bool single = false;
-
- if (get_chunk_parent_type(pc) == CT_NAMESPACE)
- {
- LOG_FMT(LBCSPOP, "%s(%d): parent_type is NAMESPACE\n",
- __func__, __LINE__);
- chunk_t *tmp = frm.top().pc;
-
- if ( tmp != nullptr
- && get_chunk_parent_type(tmp) == CT_NAMESPACE)
- {
- LOG_FMT(LBCSPOP, "%s(%d): tmp->parent_type is NAMESPACE\n",
- __func__, __LINE__);
-
- log_rule_B("indent_namespace");
- log_rule_B("indent_namespace_single_indent");
-
- if ( options::indent_namespace()
- && options::indent_namespace_single_indent())
- {
- LOG_FMT(LBCSPOP, "%s(%d): Options are SINGLE\n",
- __func__, __LINE__);
- single = true;
- }
- }
- }
- LOG_FMT(LBCSPOP, "%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->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type), get_token_name(get_chunk_parent_type(pc)));
-
- if (!single)
- {
- frm.brace_level++;
- LOG_FMT(LBCSPOP, "%s(%d): frm.brace_level increased to %zu\n",
- __func__, __LINE__, frm.brace_level);
- }
- }
- frm.push(pc, __func__, __LINE__);
- frm.top().parent = parent;
- // set parent type
- set_chunk_parent(pc, parent);
- }
- // Issue #2281
-
- if ( chunk_is_token(pc, CT_BRACE_OPEN)
- && pc->parent_type == CT_SWITCH)
- {
- size_t idx = frm.size();
- LOG_FMT(LBCSPOP, "%s(%d): idx is %zu\n",
- __func__, __LINE__, idx);
- chunk_t *saved = frm.at(idx - 2).pc;
-
- if (saved != nullptr)
- {
- // set parent member
- chunk_set_parent(pc, saved);
- }
- }
-
- if ( chunk_is_token(pc, CT_CASE)
- || chunk_is_token(pc, CT_DEFAULT))
- {
- chunk_t *prev = chunk_get_prev_ncnnl(pc); // Issue #3176
-
- if ( chunk_is_token(pc, CT_CASE)
- || ( chunk_is_token(pc, CT_DEFAULT)
- && chunk_is_not_token(prev, CT_ASSIGN)))
- {
- // it is a CT_DEFAULT from a switch
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, pc->orig_col is %zu\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col);
- set_chunk_parent(pc, CT_SWITCH);
- size_t idx = frm.size();
- LOG_FMT(LBCSPOP, "%s(%d): idx is %zu\n",
- __func__, __LINE__, idx);
- chunk_t *saved = frm.at(idx - 2).pc;
-
- if (saved != nullptr)
- {
- // set parent member
- chunk_set_parent(pc, saved);
- }
- }
- }
-
- if (chunk_is_token(pc, CT_BREAK))
- {
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, pc->orig_col is %zu\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col);
- size_t idx = frm.size();
- LOG_FMT(LBCSPOP, "%s(%d): idx is %zu\n",
- __func__, __LINE__, idx);
- chunk_t *saved = frm.at(idx - 2).pc;
-
- if (saved != nullptr)
- {
- // set parent member
- chunk_set_parent(pc, saved);
- }
- }
- const pattern_class_e patcls = get_token_pattern_class(pc->type);
-
- /*
- * Create a stack entry for complex statements:
- * if, elseif, switch, for, while, synchronized, using, lock, with,
- * version, CT_D_SCOPE_IF
- */
- if (patcls == pattern_class_e::BRACED)
- {
- frm.push(pc, __func__, __LINE__, (chunk_is_token(pc, CT_DO) ? brace_stage_e::BRACE_DO
- : brace_stage_e::BRACE2));
- // "+ComplexBraced"
- }
- else if (patcls == pattern_class_e::PBRACED)
- {
- brace_stage_e bs = brace_stage_e::PAREN1;
-
- if ( chunk_is_token(pc, CT_WHILE)
- && maybe_while_of_do(pc))
- {
- set_chunk_type(pc, CT_WHILE_OF_DO);
- bs = brace_stage_e::WOD_PAREN;
- }
- frm.push(pc, __func__, __LINE__, bs);
- // "+ComplexParenBraced"
- }
- else if (patcls == pattern_class_e::OPBRACED)
- {
- frm.push(pc, __func__, __LINE__, brace_stage_e::OP_PAREN1);
- // "+ComplexOpParenBraced");
- }
- else if (patcls == pattern_class_e::ELSE)
- {
- frm.push(pc, __func__, __LINE__, brace_stage_e::ELSEIF);
- // "+ComplexElse");
- }
-
- /*
- * Mark simple statement/expression starts
- * - after { or }
- * - after ';', but not if the paren stack top is a paren
- * - after '(' that has a parent type of CT_FOR
- */
- if ( chunk_is_token(pc, CT_SQUARE_OPEN)
- || ( chunk_is_token(pc, CT_BRACE_OPEN)
- && get_chunk_parent_type(pc) != CT_ASSIGN)
- || chunk_is_token(pc, CT_BRACE_CLOSE)
- || chunk_is_token(pc, CT_VBRACE_CLOSE)
- || ( chunk_is_token(pc, CT_SPAREN_OPEN)
- && get_chunk_parent_type(pc) == CT_FOR)
- || chunk_is_token(pc, CT_COLON)
- || chunk_is_token(pc, CT_OC_END)
- || ( chunk_is_semicolon(pc)
- && frm.top().type != CT_PAREN_OPEN
- && frm.top().type != CT_FPAREN_OPEN
- && frm.top().type != CT_SPAREN_OPEN)
- || chunk_is_token(pc, CT_MACRO)) // Issue #2742
- {
- LOG_FMT(LSTMT, "%s(%d): orig_line is %zu, reset1 stmt on '%s'\n",
- __func__, __LINE__, pc->orig_line, pc->text());
- frm.stmt_count = 0;
- frm.expr_count = 0;
- LOG_FMT(LTOK, "%s(%d): frm.stmt_count is %zu, frm.expr_count is %zu\n",
- __func__, __LINE__, frm.stmt_count, frm.expr_count);
- }
- // Mark expression starts
- LOG_FMT(LSTMT, "%s(%d): Mark expression starts: orig_line is %zu, orig_col is %zu, text() is '%s'\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
- chunk_t *tmp = chunk_get_next_ncnnl(pc);
-
- if ( chunk_is_token(pc, CT_ARITH)
- || chunk_is_token(pc, CT_SHIFT)
- || chunk_is_token(pc, CT_ASSIGN)
- || chunk_is_token(pc, CT_CASE)
- || chunk_is_token(pc, CT_COMPARE)
- || ( chunk_is_token(pc, CT_STAR)
- && chunk_is_not_token(tmp, CT_STAR))
- || chunk_is_token(pc, CT_BOOL)
- || chunk_is_token(pc, CT_MINUS)
- || chunk_is_token(pc, CT_PLUS)
- || chunk_is_token(pc, CT_CARET)
- || chunk_is_token(pc, CT_ANGLE_OPEN)
- || chunk_is_token(pc, CT_ANGLE_CLOSE)
- || chunk_is_token(pc, CT_RETURN)
- || chunk_is_token(pc, CT_THROW)
- || chunk_is_token(pc, CT_GOTO)
- || chunk_is_token(pc, CT_CONTINUE)
- || chunk_is_token(pc, CT_PAREN_OPEN)
- || chunk_is_token(pc, CT_FPAREN_OPEN)
- || chunk_is_token(pc, CT_SPAREN_OPEN)
- || chunk_is_token(pc, CT_BRACE_OPEN)
- || chunk_is_semicolon(pc)
- || chunk_is_token(pc, CT_COMMA)
- || chunk_is_token(pc, CT_NOT)
- || chunk_is_token(pc, CT_INV)
- || chunk_is_token(pc, CT_COLON)
- || chunk_is_token(pc, CT_QUESTION))
- {
- frm.expr_count = 0;
- LOG_FMT(LSTMT, "%s(%d): orig_line is %zu, orig_col is %zu, reset expr on '%s'\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
- }
-} // parse_cleanup
-
-
-static bool check_complex_statements(ParseFrame &frm, chunk_t *pc, const BraceState &braceState)
-{
- LOG_FUNC_ENTRY();
-
- brace_stage_e atest = frm.top().stage;
-
- LOG_FMT(LBCSPOP, "%s(%d): atest is %s\n",
- __func__, __LINE__, get_brace_stage_name(atest));
-
- // Turn an optional parenthesis into either a real parenthesis or a brace
- if (frm.top().stage == brace_stage_e::OP_PAREN1)
- {
- frm.top().stage = (chunk_is_not_token(pc, CT_PAREN_OPEN))
- ? brace_stage_e::BRACE2
- : brace_stage_e::PAREN1;
- LOG_FMT(LBCSPOP, "%s(%d): frm.top().stage is now %s\n",
- __func__, __LINE__, get_brace_stage_name(frm.top().stage));
- }
-
- // Check for CT_ELSE after CT_IF
- while (frm.top().stage == brace_stage_e::ELSE)
- {
- if (chunk_is_token(pc, CT_ELSE))
- {
- // Replace CT_IF with CT_ELSE on the stack & we are done
- frm.top().type = CT_ELSE;
- frm.top().stage = brace_stage_e::ELSEIF;
- print_stack(LBCSSWAP, "=Swap ", frm);
-
- return(true);
- }
- // Remove the CT_IF and close the statement
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-IF-CCS ", frm);
-
- if (close_statement(frm, pc, braceState))
- {
- return(true);
- }
- }
-
- // Check for CT_IF after CT_ELSE
- if (frm.top().stage == brace_stage_e::ELSEIF)
- {
- log_rule_B("indent_else_if");
-
- if ( chunk_is_token(pc, CT_IF)
- && ( !options::indent_else_if()
- || !chunk_is_newline(chunk_get_prev_nc(pc))))
- {
- // Replace CT_ELSE with CT_IF
- set_chunk_type(pc, CT_ELSEIF);
- frm.top().type = CT_ELSEIF;
- frm.top().stage = brace_stage_e::PAREN1;
- return(true);
- }
- // Jump to the 'expecting brace' stage
- frm.top().stage = brace_stage_e::BRACE2;
- }
-
- // Check for CT_CATCH or CT_FINALLY after CT_TRY or CT_CATCH
- while (frm.top().stage == brace_stage_e::CATCH)
- {
- if ( chunk_is_token(pc, CT_CATCH)
- || chunk_is_token(pc, CT_FINALLY))
- {
- // Replace CT_TRY with CT_CATCH or CT_FINALLY on the stack & we are done
- frm.top().type = pc->type;
-
- if (language_is_set(LANG_CS))
- {
- frm.top().stage = (chunk_is_token(pc, CT_CATCH)) ? brace_stage_e::CATCH_WHEN : brace_stage_e::BRACE2;
- }
- else
- {
- // historically this used OP_PAREN1; however, to my knowledge the expression after a catch clause
- // is only optional for C# which has been handled above; therefore, this should now always expect
- // a parenthetical expression after the catch keyword and brace after the finally keyword
- frm.top().stage = (chunk_is_token(pc, CT_CATCH)) ? brace_stage_e::PAREN1 : brace_stage_e::BRACE2;
- }
- print_stack(LBCSSWAP, "=Swap ", frm);
-
- return(true);
- }
- // Remove the CT_TRY and close the statement
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-TRY-CCS ", frm);
-
- if (close_statement(frm, pc, braceState))
- {
- return(true);
- }
- }
-
- // Check for optional parenthesis and optional CT_WHEN after CT_CATCH
- if (frm.top().stage == brace_stage_e::CATCH_WHEN)
- {
- if (chunk_is_token(pc, CT_PAREN_OPEN)) // this is for the paren after "catch"
- {
- // Replace CT_PAREN_OPEN with CT_SPAREN_OPEN
- set_chunk_type(pc, CT_SPAREN_OPEN);
- frm.top().type = pc->type;
- frm.top().stage = brace_stage_e::PAREN1;
-
- return(false);
- }
-
- if (chunk_is_token(pc, CT_WHEN))
- {
- frm.top().type = pc->type;
- frm.top().stage = brace_stage_e::OP_PAREN1;
-
- return(true);
- }
-
- if (chunk_is_token(pc, CT_BRACE_OPEN))
- {
- frm.top().stage = brace_stage_e::BRACE2;
-
- return(false);
- }
- }
-
- // Check for CT_WHILE after the CT_DO
- if (frm.top().stage == brace_stage_e::WHILE)
- {
- if (chunk_is_token(pc, CT_WHILE))
- {
- set_chunk_type(pc, CT_WHILE_OF_DO);
- frm.top().type = CT_WHILE_OF_DO; //CT_WHILE;
- frm.top().stage = brace_stage_e::WOD_PAREN;
-
- return(true);
- }
- LOG_FMT(LWARN, "%s(%d): %s, orig_line is %zu, Error: Expected 'while', got '%s'\n",
- __func__, __LINE__, cpd.filename.c_str(), pc->orig_line,
- pc->text());
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-Error ", frm);
- cpd.error_count++;
- }
- // Insert a CT_VBRACE_OPEN, if needed
- // but not in a preprocessor
- atest = frm.top().stage;
-
- if ( chunk_is_not_token(pc, CT_BRACE_OPEN)
- && !pc->flags.test(PCF_IN_PREPROC)
- && ( (frm.top().stage == brace_stage_e::BRACE2)
- || (frm.top().stage == brace_stage_e::BRACE_DO)))
- {
- log_rule_B("indent_using_block");
-
- if ( language_is_set(LANG_CS)
- && chunk_is_token(pc, CT_USING_STMT)
- && (!options::indent_using_block()))
- {
- // don't indent the using block
- }
- else
- {
- const c_token_t parent = frm.top().type;
-
- chunk_t *vbrace = insert_vbrace_open_before(pc, frm);
- set_chunk_parent(vbrace, parent);
-
- frm.level++;
- frm.brace_level++;
- LOG_FMT(LBCSPOP, "%s(%d): frm.brace_level increased to %zu\n",
- __func__, __LINE__, frm.brace_level);
- log_pcf_flags(LBCSPOP, pc->flags);
-
- frm.push(vbrace, __func__, __LINE__, brace_stage_e::NONE);
- // "+VBrace");
-
- frm.top().parent = parent;
-
- // update the level of pc
- pc->level = frm.level;
- pc->brace_level = frm.brace_level;
-
- // Mark as a start of a statement
- frm.stmt_count = 0;
- frm.expr_count = 0;
- LOG_FMT(LTOK, "%s(%d): frm.stmt_count is %zu, frm.expr_count is %zu\n",
- __func__, __LINE__, frm.stmt_count, frm.expr_count);
- chunk_flags_set(pc, PCF_STMT_START | PCF_EXPR_START);
- frm.stmt_count = 1;
- frm.expr_count = 1;
- LOG_FMT(LSTMT, "%s(%d): orig_line is %zu, 2.marked '%s' as stmt start\n",
- __func__, __LINE__, pc->orig_line, pc->text());
- }
- }
-
- // Check for "constexpr" after CT_IF or CT_ELSEIF
- if ( frm.top().stage == brace_stage_e::PAREN1
- && ( frm.top().type == CT_IF
- || frm.top().type == CT_ELSEIF)
- && chunk_is_token(pc, CT_CONSTEXPR))
- {
- return(false);
- }
-
- // Verify open parenthesis in complex statement
- if ( chunk_is_not_token(pc, CT_PAREN_OPEN)
- && ( (frm.top().stage == brace_stage_e::PAREN1)
- || (frm.top().stage == brace_stage_e::WOD_PAREN)))
- {
- LOG_FMT(LWARN, "%s(%d): %s, orig_line is %zu, Error: Expected '(', got '%s' for '%s'\n",
- __func__, __LINE__, cpd.filename.c_str(), pc->orig_line, pc->text(),
- get_token_name(frm.top().type));
-
- // Throw out the complex statement
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-Error ", frm);
- cpd.error_count++;
- }
- return(false);
-} // check_complex_statements
-
-
-static bool handle_complex_close(ParseFrame &frm, chunk_t *pc, const BraceState &braceState)
-{
- LOG_FUNC_ENTRY();
-
- if (frm.top().stage == brace_stage_e::PAREN1)
- {
- if ( pc->next != nullptr
- && pc->next->type == CT_WHEN)
- {
- frm.top().type = pc->type;
- frm.top().stage = brace_stage_e::CATCH_WHEN;
-
- return(true);
- }
- // PAREN1 always => BRACE2
- frm.top().stage = brace_stage_e::BRACE2;
- }
- else if (frm.top().stage == brace_stage_e::BRACE2)
- {
- // BRACE2: IF => ELSE, anything else => close
- if ( (frm.top().type == CT_IF)
- || (frm.top().type == CT_ELSEIF))
- {
- frm.top().stage = brace_stage_e::ELSE;
-
- // If the next chunk isn't CT_ELSE, close the statement
- chunk_t *next = chunk_get_next_ncnnl(pc);
-
- if ( next == nullptr
- || chunk_is_not_token(next, CT_ELSE))
- {
- LOG_FMT(LBCSPOP, "%s(%d): no CT_ELSE, pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-IF-HCS ", frm);
-
- return(close_statement(frm, pc, braceState));
- }
- }
- else if ( (frm.top().type == CT_TRY)
- || (frm.top().type == CT_CATCH))
- {
- frm.top().stage = brace_stage_e::CATCH;
-
- // If the next chunk isn't CT_CATCH or CT_FINALLY, close the statement
- chunk_t *next = chunk_get_next_ncnnl(pc);
-
- if ( chunk_is_not_token(next, CT_CATCH)
- && chunk_is_not_token(next, CT_FINALLY))
- {
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-TRY-HCS ", frm);
-
- return(close_statement(frm, pc, braceState));
- }
- }
- else
- {
- LOG_FMT(LNOTE, "%s(%d): close_statement on %s brace_stage_e::BRACE2\n",
- __func__, __LINE__, get_token_name(frm.top().type));
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-HCC B2 ", frm);
-
- return(close_statement(frm, pc, braceState));
- }
- }
- else if (frm.top().stage == brace_stage_e::BRACE_DO)
- {
- frm.top().stage = brace_stage_e::WHILE;
- }
- else if (frm.top().stage == brace_stage_e::WOD_PAREN)
- {
- LOG_FMT(LNOTE, "%s(%d): close_statement on %s brace_stage_e::WOD_PAREN\n",
- __func__, __LINE__, get_token_name(frm.top().type));
- frm.top().stage = brace_stage_e::WOD_SEMI;
- print_stack(LBCSPOP, "-HCC WoDP ", frm);
- }
- else if (frm.top().stage == brace_stage_e::WOD_SEMI)
- {
- LOG_FMT(LNOTE, "%s(%d): close_statement on %s brace_stage_e::WOD_SEMI\n",
- __func__, __LINE__, get_token_name(frm.top().type));
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
- print_stack(LBCSPOP, "-HCC WoDS ", frm);
-
- return(close_statement(frm, pc, braceState));
- }
- else
- {
- // PROBLEM
- LOG_FMT(LWARN, "%s(%d): %s:%zu Error: TOS.type='%s' TOS.stage=%u\n",
- __func__, __LINE__, cpd.filename.c_str(), pc->orig_line,
- get_token_name(frm.top().type),
- (unsigned int)frm.top().stage);
- cpd.error_count++;
- }
- return(false);
-} // handle_complex_close
-
-
-static void mark_namespace(chunk_t *pns)
-{
- LOG_FUNC_ENTRY();
- // Issue #1813
- chunk_t *br_close;
- bool is_using = false;
-
- chunk_t *pc = chunk_get_prev_ncnnl(pns);
-
- if (chunk_is_token(pc, CT_USING))
- {
- is_using = true;
- set_chunk_parent(pns, CT_USING);
- }
- pc = chunk_get_next_ncnnl(pns);
-
- while (pc != nullptr)
- {
- set_chunk_parent(pc, CT_NAMESPACE);
-
- if (chunk_is_not_token(pc, CT_BRACE_OPEN))
- {
- if (chunk_is_token(pc, CT_SEMICOLON))
- {
- if (is_using)
- {
- set_chunk_parent(pc, CT_USING);
- }
- return;
- }
- pc = chunk_get_next_ncnnl(pc);
- continue;
- }
- log_rule_B("indent_namespace_limit");
-
- if ( (options::indent_namespace_limit() > 0)
- && ((br_close = chunk_skip_to_match(pc)) != nullptr))
- {
- // br_close->orig_line is always >= pc->orig_line;
- size_t numberOfLines = br_close->orig_line - pc->orig_line - 1; // Issue #2345
- LOG_FMT(LTOK, "%s(%d): br_close->orig_line is %zu, pc->orig_line is %zu\n",
- __func__, __LINE__, br_close->orig_line, pc->orig_line);
- LOG_FMT(LTOK, "%s(%d): numberOfLines is %zu, indent_namespace_limit() is %d\n",
- __func__, __LINE__, numberOfLines, options::indent_namespace_limit());
-
- log_rule_B("indent_namespace_limit");
-
- if (numberOfLines > options::indent_namespace_limit())
- {
- LOG_FMT(LTOK, "%s(%d): PCF_LONG_BLOCK is set\n", __func__, __LINE__);
- chunk_flags_set(pc, PCF_LONG_BLOCK);
- chunk_flags_set(br_close, PCF_LONG_BLOCK);
- }
- }
- flag_parens(pc, PCF_IN_NAMESPACE, CT_NONE, CT_NAMESPACE, false);
- return;
- }
-} // mark_namespace
-
-
-static chunk_t *insert_vbrace(chunk_t *pc, bool after, const ParseFrame &frm)
-{
- LOG_FUNC_ENTRY();
-
- chunk_t chunk;
-
- set_chunk_parent(&chunk, frm.top().type);
- chunk.orig_line = pc->orig_line;
- chunk.level = frm.level;
- chunk.pp_level = frm.pp_level;
- chunk.brace_level = frm.brace_level;
- chunk.flags = pc->flags & PCF_COPY_FLAGS;
- chunk.str = "";
-
- if (after)
- {
- chunk.orig_col = pc->orig_col;
- set_chunk_type(&chunk, CT_VBRACE_CLOSE);
- return(chunk_add_after(&chunk, pc));
- }
- chunk_t *ref = chunk_get_prev(pc);
-
- if (ref == nullptr)
- {
- return(nullptr);
- }
-
- if (!ref->flags.test(PCF_IN_PREPROC))
- {
- chunk.flags &= ~PCF_IN_PREPROC;
- }
- bool ref_is_comment = chunk_is_comment(ref); // Issue #3351
-
- while ( chunk_is_newline(ref)
- || chunk_is_comment(ref))
- {
- ref->level++;
- ref->brace_level++;
- ref = chunk_get_prev(ref);
- }
-
- if (ref == nullptr)
- {
- return(nullptr);
- }
-
- // Don't back into a preprocessor
- if ( !pc->flags.test(PCF_IN_PREPROC)
- && ref->flags.test(PCF_IN_PREPROC))
- {
- if (chunk_is_token(ref, CT_PREPROC_BODY))
- {
- while ( ref != nullptr
- && ref->flags.test(PCF_IN_PREPROC))
- {
- ref = chunk_get_prev(ref);
- }
- }
- else
- {
- ref = chunk_get_next(ref);
-
- if (chunk_is_token(ref, CT_COMMENT)) // Issue #3034
- {
- ref = chunk_get_next_nc(ref);
- }
- }
- }
-
- if (ref_is_comment) // Issue #3351
- {
- ref = chunk_get_next(ref);
- }
-
- if (ref == nullptr)
- {
- return(nullptr);
- }
- chunk.orig_line = ref->orig_line;
- chunk.orig_col = ref->orig_col;
- chunk.column = ref->column + ref->len() + 1;
- chunk.pp_level = ref->pp_level; // Issue #3055
- set_chunk_type(&chunk, CT_VBRACE_OPEN);
-
- return(chunk_add_after(&chunk, ref));
-} // insert_vbrace
-
-
-bool close_statement(ParseFrame &frm, chunk_t *pc, const BraceState &braceState)
-{
- LOG_FUNC_ENTRY();
-
- if (pc == nullptr)
- {
- throw invalid_argument(string(__func__) + ":" + to_string(__LINE__)
- + "args cannot be nullptr");
- }
- LOG_FMT(LTOK, "%s(%d): orig_line is %zu, type is %s, '%s' type is %s, stage is %u\n",
- __func__, __LINE__, pc->orig_line,
- get_token_name(pc->type), pc->text(),
- get_token_name(frm.top().type),
- (unsigned int)frm.top().stage);
-
- if (braceState.consumed)
- {
- frm.stmt_count = 0;
- frm.expr_count = 0;
- LOG_FMT(LSTMT, "%s(%d): orig_line is %zu> reset2 stmt on '%s'\n",
- __func__, __LINE__, pc->orig_line, pc->text());
- }
- /*
- * Insert a CT_VBRACE_CLOSE, if needed:
- * If we are in a virtual brace and we are not ON a CT_VBRACE_CLOSE add one
- */
- chunk_t *vbc = pc;
-
- if (frm.top().type == CT_VBRACE_OPEN)
- {
- // If the current token has already been consumed, then add after it
- if (braceState.consumed)
- {
- insert_vbrace_close_after(pc, frm);
- }
- else
- {
- // otherwise, add before it and consume the vbrace
- vbc = chunk_get_prev_ncnnl(pc);
-
- frm.level--;
- frm.brace_level--;
- vbc = insert_vbrace_close_after(vbc, frm);
- set_chunk_parent(vbc, frm.top().parent);
-
- LOG_FMT(LBCSPOP, "%s(%d): frm.brace_level decreased to %zu\n",
- __func__, __LINE__, frm.brace_level);
- log_pcf_flags(LBCSPOP, pc->flags);
- LOG_FMT(LBCSPOP, "%s(%d): pc->orig_line is %zu, orig_col is %zu, text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__);
-
- // Update the token level
- pc->level = frm.level;
- pc->brace_level = frm.brace_level;
-
- print_stack(LBCSPOP, "-CS VB ", frm);
-
- // And repeat the close
- close_statement(frm, pc, braceState);
- return(true);
- }
- }
-
- // See if we are done with a complex statement
- if (frm.top().stage != brace_stage_e::NONE)
- {
- if (handle_complex_close(frm, vbc, braceState))
- {
- return(true);
- }
- }
- return(false);
-} // close_statement