parameters: (typenames, clean_lines, nesting_state, linenum, column)
return_statement: return False
docstring: Check if the token ending on (linenum, column) is a type.
  
    Assumes that text to the right of the column is "&&" or a function
    name.
  
    Args:
      typenames: set of type names from template-argument-list.
      clean_lines: A CleansedLines instance containing the file.
      nesting_state: A NestingState instance which maintains information about
                     the current stack of nested blocks being parsed.
      linenum: the number of the line to check.
      column: end column of the token to check.
    Returns:
      True if this token is a type, False if we are not sure.
docstring_summary: Check if the token ending on (linenum, column) is a type.
docstring_tokens: Check if the token ending on ( linenum column ) is a type .
function: def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
    """Check if the token ending on (linenum, column) is a type.
  
    Assumes that text to the right of the column is "&&" or a function
    name.
  
    Args:
      typenames: set of type names from template-argument-list.
      clean_lines: A CleansedLines instance containing the file.
      nesting_state: A NestingState instance which maintains information about
                     the current stack of nested blocks being parsed.
      linenum: the number of the line to check.
      column: end column of the token to check.
    Returns:
      True if this token is a type, False if we are not sure.
    """
    prefix = clean_lines.elided[linenum][0:column]
  
    # Get one word to the left.  If we failed to do so, this is most
    # likely not a type, since it's unlikely that the type name and "&&"
    # would be split across multiple lines.
    match = Match(r'^(.*)(\b\w+|[>*)&])\s*$', prefix)
    if not match:
      return False
  
    # Check text following the token.  If it's "&&>" or "&&," or "&&...", it's
    # most likely a rvalue reference used inside a template.
    suffix = clean_lines.elided[linenum][column:]
    if Match(r'&&\s*(?:[>,]|\.\.\.)', suffix):
      return True
  
    # Check for known types and end of templates:
    #   int&& variable
    #   vector<int>&& variable
    #
    # Because this function is called recursively, we also need to
    # recognize pointer and reference types:
    #   int* Function()
    #   int& Function()
    if (match.group(2) in typenames or
        match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool',
                           'short', 'int', 'long', 'signed', 'unsigned',
                           'float', 'double', 'void', 'auto', '>', '*', '&']):
      return True
  
    # If we see a close parenthesis, look for decltype on the other side.
    # decltype would unambiguously identify a type, anything else is
    # probably a parenthesized expression and not a type.
    if match.group(2) == ')':
      return IsDecltype(
          clean_lines, linenum, len(match.group(1)) + len(match.group(2)) - 1)
  
    # Check for casts and cv-qualifiers.
    #   match.group(1)  remainder
    #   --------------  ---------
    #   const_cast<     type&&
    #   const           type&&
    #   type            const&&
    if Search(r'\b(?:const_cast\s*<|static_cast\s*<|dynamic_cast\s*<|'
              r'reinterpret_cast\s*<|\w+\s)\s*$',
              match.group(1)):
      return True
  
    # Look for a preceding symbol that might help differentiate the context.
    # These are the cases that would be ambiguous:
    #   match.group(1)  remainder
    #   --------------  ---------
    #   Call         (   expression &&
    #   Declaration  (   type&&
    #   sizeof       (   type&&
    #   if           (   expression &&
    #   while        (   expression &&
    #   for          (   type&&
    #   for(         ;   expression &&
    #   statement    ;   type&&
    #   block        {   type&&
    #   constructor  {   expression &&
    start = linenum
    line = match.group(1)
    match_symbol = None
    while start >= 0:
      # We want to skip over identifiers and commas to get to a symbol.
      # Commas are skipped so that we can find the opening parenthesis
      # for function parameter lists.
      match_symbol = Match(r'^(.*)([^\w\s,])[\w\s,]*$', line)
      if match_symbol:
        break
      start -= 1
      line = clean_lines.elided[start]
  
    if not match_symbol:
      # Probably the first statement in the file is an rvalue reference
      return True
  
    if match_symbol.group(2) == '}':
      # Found closing brace, probably an indicate of this:
      #   block{} type&&
      return True
  
    if match_symbol.group(2) == ';':
      # Found semicolon, probably one of these:
      #   for(; expression &&
      #   statement; type&&
  
      # Look for the previous 'for(' in the previous lines.
      before_text = match_symbol.group(1)
      for i in xrange(start - 1, max(start - 6, 0), -1):
        before_text = clean_lines.elided[i] + before_text
      if Search(r'for\s*\([^{};]*$', before_text):
        # This is the condition inside a for-loop
        return False
  
      # Did not find a for-init-statement before this semicolon, so this
      # is probably a new statement and not a condition.
      return True
  
    if match_symbol.group(2) == '{':
      # Found opening brace, probably one of these:
      #   block{ type&& = ... ; }
      #   constructor{ expression && expression }
  
      # Look for a closing brace or a semicolon.  If we see a semicolon
      # first, this is probably a rvalue reference.
      line = clean_lines.elided[start][0:len(match_symbol.group(1)) + 1]
      end = start
      depth = 1
      while True:
        for ch in line:
          if ch == ';':
            return True
          elif ch == '{':
            depth += 1
          elif ch == '}':
            depth -= 1
            if depth == 0:
              return False
        end += 1
        if end >= clean_lines.NumLines():
          break
        line = clean_lines.elided[end]
      # Incomplete program?
      return False
  
    if match_symbol.group(2) == '(':
      # Opening parenthesis.  Need to check what's to the left of the
      # parenthesis.  Look back one extra line for additional context.
      before_text = match_symbol.group(1)
      if linenum > 1:
        before_text = clean_lines.elided[linenum - 1] + before_text
      before_text = match_symbol.group(1)
  
      # Patterns that are likely to be types:
      #   [](type&&
      #   for (type&&
      #   sizeof(type&&
      #   operator=(type&&
      #
      if Search(r'(?:\]|\bfor|\bsizeof|\boperator\s*\S+\s*)\s*$', before_text):
        return True
  
      # Patterns that are likely to be expressions:
      #   if (expression &&
      #   while (expression &&
      #   : initializer(expression &&
      #   , initializer(expression &&
      #   ( FunctionCall(expression &&
      #   + FunctionCall(expression &&
      #   + (expression &&
      #
      # The last '+' represents operators such as '+' and '-'.
      if Search(r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$', before_text):
        return False
  
      # Something else.  Check that tokens to the left look like
      #   return_type function_name
      match_func = Match(r'^(.*\S.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$',
                         match_symbol.group(1))
      if match_func:
        # Check for constructors, which don't have return types.
        if Search(r'\b(?:explicit|inline)$', match_func.group(1)):
          return True
        implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix)
        if (implicit_constructor and
            implicit_constructor.group(1) == implicit_constructor.group(2)):
          return True
        return IsRValueType(typenames, clean_lines, nesting_state, linenum,
                            len(match_func.group(1)))
  
      # Nothing before the function name.  If this is inside a block scope,
      # this is probably a function call.
      return not (nesting_state.previous_stack_top and
                  nesting_state.previous_stack_top.IsBlockInfo())
  
    if match_symbol.group(2) == '>':
      # Possibly a closing bracket, check that what's on the other side
      # looks like the start of a template.
      return IsTemplateParameterList(
          clean_lines, start, len(match_symbol.group(1)))
  
    # Some other symbol, usually something like "a=b&&c".  This is most
    # likely not a type.
    return False
function_tokens: def IsRValueType ( typenames , clean_lines , nesting_state , linenum , column ) : prefix = clean_lines . elided [ linenum ] [ 0 : column ] # Get one word to the left.  If we failed to do so, this is most # likely not a type, since it's unlikely that the type name and "&&" # would be split across multiple lines. match = Match ( r'^(.*)(\b\w+|[>*)&])\s*$' , prefix ) if not match : return False # Check text following the token.  If it's "&&>" or "&&," or "&&...", it's # most likely a rvalue reference used inside a template. suffix = clean_lines . elided [ linenum ] [ column : ] if Match ( r'&&\s*(?:[>,]|\.\.\.)' , suffix ) : return True # Check for known types and end of templates: #   int&& variable #   vector<int>&& variable # # Because this function is called recursively, we also need to # recognize pointer and reference types: #   int* Function() #   int& Function() if ( match . group ( 2 ) in typenames or match . group ( 2 ) in [ 'char' , 'char16_t' , 'char32_t' , 'wchar_t' , 'bool' , 'short' , 'int' , 'long' , 'signed' , 'unsigned' , 'float' , 'double' , 'void' , 'auto' , '>' , '*' , '&' ] ) : return True # If we see a close parenthesis, look for decltype on the other side. # decltype would unambiguously identify a type, anything else is # probably a parenthesized expression and not a type. if match . group ( 2 ) == ')' : return IsDecltype ( clean_lines , linenum , len ( match . group ( 1 ) ) + len ( match . group ( 2 ) ) - 1 ) # Check for casts and cv-qualifiers. #   match.group(1)  remainder #   --------------  --------- #   const_cast<     type&& #   const           type&& #   type            const&& if Search ( r'\b(?:const_cast\s*<|static_cast\s*<|dynamic_cast\s*<|' r'reinterpret_cast\s*<|\w+\s)\s*$' , match . group ( 1 ) ) : return True # Look for a preceding symbol that might help differentiate the context. # These are the cases that would be ambiguous: #   match.group(1)  remainder #   --------------  --------- #   Call         (   expression && #   Declaration  (   type&& #   sizeof       (   type&& #   if           (   expression && #   while        (   expression && #   for          (   type&& #   for(         ;   expression && #   statement    ;   type&& #   block        {   type&& #   constructor  {   expression && start = linenum line = match . group ( 1 ) match_symbol = None while start >= 0 : # We want to skip over identifiers and commas to get to a symbol. # Commas are skipped so that we can find the opening parenthesis # for function parameter lists. match_symbol = Match ( r'^(.*)([^\w\s,])[\w\s,]*$' , line ) if match_symbol : break start -= 1 line = clean_lines . elided [ start ] if not match_symbol : # Probably the first statement in the file is an rvalue reference return True if match_symbol . group ( 2 ) == '}' : # Found closing brace, probably an indicate of this: #   block{} type&& return True if match_symbol . group ( 2 ) == ';' : # Found semicolon, probably one of these: #   for(; expression && #   statement; type&& # Look for the previous 'for(' in the previous lines. before_text = match_symbol . group ( 1 ) for i in xrange ( start - 1 , max ( start - 6 , 0 ) , - 1 ) : before_text = clean_lines . elided [ i ] + before_text if Search ( r'for\s*\([^{};]*$' , before_text ) : # This is the condition inside a for-loop return False # Did not find a for-init-statement before this semicolon, so this # is probably a new statement and not a condition. return True if match_symbol . group ( 2 ) == '{' : # Found opening brace, probably one of these: #   block{ type&& = ... ; } #   constructor{ expression && expression } # Look for a closing brace or a semicolon.  If we see a semicolon # first, this is probably a rvalue reference. line = clean_lines . elided [ start ] [ 0 : len ( match_symbol . group ( 1 ) ) + 1 ] end = start depth = 1 while True : for ch in line : if ch == ';' : return True elif ch == '{' : depth += 1 elif ch == '}' : depth -= 1 if depth == 0 : return False end += 1 if end >= clean_lines . NumLines ( ) : break line = clean_lines . elided [ end ] # Incomplete program? return False if match_symbol . group ( 2 ) == '(' : # Opening parenthesis.  Need to check what's to the left of the # parenthesis.  Look back one extra line for additional context. before_text = match_symbol . group ( 1 ) if linenum > 1 : before_text = clean_lines . elided [ linenum - 1 ] + before_text before_text = match_symbol . group ( 1 ) # Patterns that are likely to be types: #   [](type&& #   for (type&& #   sizeof(type&& #   operator=(type&& # if Search ( r'(?:\]|\bfor|\bsizeof|\boperator\s*\S+\s*)\s*$' , before_text ) : return True # Patterns that are likely to be expressions: #   if (expression && #   while (expression && #   : initializer(expression && #   , initializer(expression && #   ( FunctionCall(expression && #   + FunctionCall(expression && #   + (expression && # # The last '+' represents operators such as '+' and '-'. if Search ( r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$' , before_text ) : return False # Something else.  Check that tokens to the left look like #   return_type function_name match_func = Match ( r'^(.*\S.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$' , match_symbol . group ( 1 ) ) if match_func : # Check for constructors, which don't have return types. if Search ( r'\b(?:explicit|inline)$' , match_func . group ( 1 ) ) : return True implicit_constructor = Match ( r'\s*(\w+)\((?:const\s+)?(\w+)' , prefix ) if ( implicit_constructor and implicit_constructor . group ( 1 ) == implicit_constructor . group ( 2 ) ) : return True return IsRValueType ( typenames , clean_lines , nesting_state , linenum , len ( match_func . group ( 1 ) ) ) # Nothing before the function name.  If this is inside a block scope, # this is probably a function call. return not ( nesting_state . previous_stack_top and nesting_state . previous_stack_top . IsBlockInfo ( ) ) if match_symbol . group ( 2 ) == '>' : # Possibly a closing bracket, check that what's on the other side # looks like the start of a template. return IsTemplateParameterList ( clean_lines , start , len ( match_symbol . group ( 1 ) ) ) # Some other symbol, usually something like "a=b&&c".  This is most # likely not a type. return False