Logo Search packages:      
Sourcecode: uncrustify version File versions

static void mark_function ( chunk_t pc  )  [static]

We are on a function word. we need to:

  • find out if this is a call or prototype or implementation
  • mark return type
  • mark parameter types
  • mark brace pair

This part detects either chained function calls or a function definition. MYTYPE (*func)(void); mWriter( "class Clst_"c )( somestr.getText() )( " : Cluster {"c ).newline;

For it to be a function variable def, there must be a '*' followed by a single word.

Otherwise, it must be chained function calls.

Definition at line 1636 of file combine.cpp.

References chunk_t::brace_level, chunk_get_next_ncnl(), chunk_get_next_ncnlnp(), chunk_get_next_type(), chunk_get_prev_ncnl(), chunk_get_prev_ncnlnp(), fix_fcn_def_params(), flag_parens(), chunk_t::flags, chunk_t::len, chunk_t::level, chunk_t::orig_col, chunk_t::orig_line, chunk_t::parent_type, chunk_t::str, and chunk_t::type.

Referenced by fix_symbols(), and mark_template_func().

{
   chunk_t *prev;
   chunk_t *next;
   chunk_t *tmp;
   chunk_t *paren_close;

   prev = chunk_get_prev_ncnlnp(pc);
   next = chunk_get_next_ncnlnp(pc);

   LOG_FMT(LFCN, "%s: %d] %.*s[%s] - level=%d/%d\n", __func__,
           pc->orig_line, pc->len, pc->str,
           get_token_name(pc->type), pc->level, pc->brace_level);
   LOG_FMT(LFCN, "%s: next=%.*s[%s] - level=%d\n", __func__,
           next->len, next->str, get_token_name(next->type), next->level);

   if (pc->flags & PCF_IN_CONST_ARGS)
   {
      pc->type = CT_FUNC_CTOR_VAR;
      flag_parens(next, 0, CT_FPAREN_OPEN, pc->type, true);
      return;
   }

   /* Skip over any template madness */
   if (next->type == CT_ANGLE_OPEN)
   {
      next = chunk_get_next_type(next, CT_ANGLE_CLOSE, next->level);
      if (next != NULL)
      {
         next = chunk_get_next_ncnl(next);
      }
   }

   /* Find the close paren */
   paren_close = chunk_get_next_str(pc, ")", 1, pc->level);

   /**
    * This part detects either chained function calls or a function definition.
    * MYTYPE (*func)(void);
    * mWriter( "class Clst_"c )( somestr.getText() )( " : Cluster {"c ).newline;
    *
    * For it to be a function variable def, there must be a '*' followed by a
    * single word.
    *
    * Otherwise, it must be chained function calls.
    */
   tmp = chunk_get_next_ncnl(paren_close);
   if (chunk_is_str(tmp, "(", 1))
   {
      chunk_t *tmp1, *tmp2, *tmp3;

      tmp1 = next;
      do
      {
         tmp1 = chunk_get_next_ncnl(tmp1);
      } while ((tmp1 != NULL) &&
               ((tmp1->type == CT_WORD) ||
                (tmp1->type == CT_DC_MEMBER)));

      tmp2 = chunk_get_next_ncnl(tmp1);
      tmp3 = chunk_get_next_ncnl(tmp2);

      if (chunk_is_str(tmp3, ")", 1) &&
          chunk_is_star(tmp1) &&
          (tmp2->type == CT_WORD))
      {
         LOG_FMT(LFCN, "%s: [%d/%d] function variable [%.*s], changing [%.*s] into a type\n",
                 __func__, pc->orig_line, pc->orig_col, tmp2->len, tmp2->str, pc->len, pc->str);

         pc->type     = CT_TYPE;
         pc->flags   &= ~PCF_VAR_1ST_DEF;
         tmp2->flags |= PCF_VAR_1ST_DEF;
         flag_parens(tmp, 0, CT_FPAREN_OPEN, CT_FUNC_PROTO, false);
         return;
      }

      LOG_FMT(LFCN, "%s: chained function calls? [%d.%d] [%.*s]\n",
              __func__, pc->orig_line, pc->orig_col, pc->len, pc->str);
   }

   /* Assume it is a function call if not already labeled */
   if (pc->type == CT_FUNCTION)
   {
      pc->type = CT_FUNC_CALL;
   }

   /* Check for C++ function def */
   if ((pc->type == CT_FUNC_CLASS) ||
       ((prev != NULL) && ((prev->type == CT_DC_MEMBER) ||
                           (prev->type == CT_INV))))
   {
      chunk_t *destr = NULL;
      if (prev->type == CT_INV)
      {
         /* TODO: do we care that this is the destructor? */
         destr = prev;
         prev  = chunk_get_prev_ncnlnp(prev);
      }

      if ((prev != NULL) && (prev->type == CT_DC_MEMBER))
      {
         prev = chunk_get_prev_ncnlnp(prev);
         if ((prev != NULL) && (prev->type == CT_WORD))
         {
            if ((pc->len == prev->len) && (memcmp(pc->str, prev->str, pc->len) == 0))
            {
               pc->type = CT_FUNC_CLASS;
               if (destr != NULL)
               {
                  destr->type = CT_DESTRUCTOR;
               }
               LOG_FMT(LFCN, "FOUND %sSTRUCTOR for %.*s[%s] ",
                       (destr != NULL) ? "DE" : "CON",
                       prev->len, prev->str, get_token_name(prev->type));

               mark_cpp_constructor(pc);
               return;
            }
            else
            {
               /* Point to the item previous to the class name */
               prev = chunk_get_prev_ncnlnp(prev);
            }
         }
      }
   }

   if ((pc->type == CT_FUNC_CALL) &&
       (pc->level == pc->brace_level))
   {
      while ((prev != NULL) &&
             ((prev->type == CT_TYPE) ||
              (prev->type == CT_WORD) ||
              (prev->type == CT_DC_MEMBER) ||
              (prev->type == CT_OPERATOR) ||
              (prev->type == CT_TSQUARE) ||
              chunk_is_addr(prev) ||
              chunk_is_star(prev)))
      {
         LOG_FMT(LFCN, "FCN_DEF due to %.*s[%s] ",
                 prev->len, prev->str, get_token_name(prev->type));

         pc->type = CT_FUNC_DEF;
         make_type(prev);
         prev = chunk_get_prev_ncnlnp(prev);
      }
      LOG_FMT(LFCN, "\n");
   }

   if (pc->type != CT_FUNC_DEF)
   {
      LOG_FMT(LFCN, "Detected [%s] %.*s on line %d col %d\n",
              get_token_name(pc->type),
              pc->len, pc->str, pc->orig_line, pc->orig_col);

      flag_parens(next, PCF_IN_FCN_CALL, CT_FPAREN_OPEN, CT_NONE, false);
      return;
   }

   flag_parens(next, PCF_IN_FCN_DEF, CT_FPAREN_OPEN, CT_NONE, false);

   /* See if this is a prototype or implementation */
   paren_close = chunk_get_next_type(pc, CT_FPAREN_CLOSE, pc->level);

   /* Scan tokens until we hit a brace open (def) or semicolon (proto) */
   tmp = paren_close;
   while (((tmp = chunk_get_next_ncnl(tmp)) != NULL) &&
          (tmp->level >= pc->level))
   {
      /* Only care about brace or semi on the same level */
      if (tmp->level == pc->level)
      {
         if (tmp->type == CT_BRACE_OPEN)
         {
            /* its a function def for sure */
            break;
         }
         else if (chunk_is_semicolon(tmp))
         {
            /* Set the parent for the semi for later */
            tmp->parent_type = CT_FUNC_PROTO;
            pc->type         = CT_FUNC_PROTO;
            break;
         }
         else if (pc->type == CT_COMMA)
         {
            pc->type = CT_FUNC_CTOR_VAR;
            break;
         }
         else if (chunk_is_str(tmp, ":", 1))
         {
            /* mark constuctor colon (?) */
            tmp->type = CT_CLASS_COLON;
         }
      }
   }

   if ((cpd.lang_flags & LANG_CPP) &&
       (pc->type == CT_FUNC_PROTO) &&
       (pc->parent_type != CT_OPERATOR))
   {
      prev = chunk_get_prev_ncnl(pc);
      if (!chunk_is_str(prev, "*", 1) && !chunk_is_str(prev, "&", 1))
      {
         int lvl = 1;
         lvl += (pc->flags & PCF_IN_CLASS) ? 1 : 0;
         lvl += (pc->flags & PCF_IN_NAMESPACE) ? 1 : 0;

         if ((pc->level == pc->brace_level) && (pc->level == lvl))
         {
            pc->type = CT_FUNC_CTOR_VAR;
         }
      }
   }

   if (pc->type == CT_FUNC_CTOR_VAR)
   {
      pc->flags |= PCF_VAR_1ST_DEF;

      LOG_FMT(LFCN, "Detected [%s] %.*s on line %d col %d\n",
              get_token_name(pc->type),
              pc->len, pc->str, pc->orig_line, pc->orig_col);
      return;
   }

   /* Mark parameters */
   fix_fcn_def_params(next);

   /* Step backwards from pc and mark the parent of the return type */
   tmp = pc;
   while ((tmp = chunk_get_prev_ncnl(tmp)) != NULL)
   {
      if (!chunk_is_type(tmp))
      {
         break;
      }
      tmp->parent_type = pc->type;
   }

   /* Find the brace pair */
   if (pc->type == CT_FUNC_DEF)
   {
      bool on_first = true;
      tmp = chunk_get_next_ncnl(paren_close);
      while ((tmp != NULL) && (tmp->type != CT_BRACE_OPEN))
      {
         tmp->parent_type = CT_FUNC_DEF;
         if (chunk_is_semicolon(tmp))
         {
            on_first = true;
         }
         else
         {
            tmp->flags |= PCF_OLD_FCN_PARAMS;
            on_first    = false;
         }
         tmp = chunk_get_next_ncnl(tmp);
      }
      if ((tmp != NULL) && (tmp->type == CT_BRACE_OPEN))
      {
         tmp->parent_type = CT_FUNC_DEF;
         tmp = chunk_skip_to_match(tmp);
         if (tmp != NULL)
         {
            tmp->parent_type = CT_FUNC_DEF;
         }
      }
   }
}


Generated by  Doxygen 1.6.0   Back to index