third_party/blink/tools/blinkpy/style/checkers/cpp.py
def check_for_non_standard_constructs(clean_lines, line_number, class_state,
                                      error):
    """Logs an error if we see certain non-ANSI constructs ignored by gcc-2.

    Complain about several constructs which gcc-2 accepts, but which are
    not standard C++.  Warning about these in lint is one way to ease the
    transition to new compilers.
    - put storage class first (e.g. "static const" instead of "const static").
    - "%lld" instead of %qd" in printf-type functions.
    - "%1$d" is non-standard in printf-type functions.
    - "\%" is an undefined character escape sequence.
    - text after #endif is not allowed.
    - invalid inner-style forward declaration.
    - >? and <? operators, and their >?= and <?= cousins.
    - classes with virtual methods need virtual destructors (compiler warning
        available, but not turned on yet.)

    Additionally, check for constructor/destructor style violations as it
    is very convenient to do so while checking for gcc-2 compliance.

    Args:
      clean_lines: A CleansedLines instance containing the file.
      line_number: The number of the line to check.
      class_state: A _ClassState instance which maintains information about
                   the current stack of nested class declarations being parsed.
      error: A callable to which errors are reported, which takes parameters:
             line number, error level, and message
    """
    # Work with both comments and strings removed.
    line = clean_lines.elided[line_number]

    # Track class entry and exit, and attempt to find cases within the
    # class declaration that don't meet the C++ style
    # guidelines. Tracking is very dependent on the code matching Google
    # style guidelines, but it seems to perform well enough in testing
    # to be a worthwhile addition to the checks.
    classinfo_stack = class_state.classinfo_stack
    # Look for a class declaration
    class_decl_match = match(
        r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)',
        line)
    if class_decl_match:
        classinfo_stack.append(
            _ClassInfo(class_decl_match.group(3), line_number))

    # Everything else in this function uses the top of the stack if it's
    # not empty.
    if not classinfo_stack:
        return

    classinfo = classinfo_stack[-1]

    # If the opening brace hasn't been seen look for it and also
    # parent class declarations.
    if not classinfo.seen_open_brace:
        # If the line has a ';' in it, assume it's a forward declaration or
        # a single-line class declaration, which we won't process.
        if ';' in line:
            classinfo_stack.pop()
            return
        classinfo.seen_open_brace = ('{' in line)
        # Look for a bare ':'
        if search('(^|[^:]):($|[^:])', line):
            classinfo.is_derived = True
        if not classinfo.seen_open_brace:
            return  # Everything else in this function is for after open brace

    # The class may have been declared with namespace or classname qualifiers.
    # The constructor and destructor will not have those qualifiers.
    base_classname = classinfo.name.split('::')[-1]

    # Look for single-argument constructors that aren't marked explicit.
    # Technically a valid construct, but against style.
    args = match(
        r'(?<!explicit)\s+%s\s*\(([^,()]+)\)' % re.escape(base_classname),
        line)
    if (args and args.group(1) != 'void'
            and not match(r'(const\s+)?%s\s*&' % re.escape(base_classname),
                          args.group(1).strip())):
        error(line_number, 'runtime/explicit', 5,
              'Single-argument constructors should be marked explicit.')

    # Look for methods declared virtual.
    if search(r'\bvirtual\b', line):
        classinfo.virtual_method_line_number = line_number
        # Only look for a destructor declaration on the same line. It would
        # be extremely unlikely for the destructor declaration to occupy
        # more than one line.
        if search(r'~%s\s*\(' % base_classname, line):
            classinfo.has_virtual_destructor = True

    # Look for class end.
    brace_depth = classinfo.brace_depth
    brace_depth = brace_depth + line.count('{') - line.count('}')
    if brace_depth <= 0:
        classinfo = classinfo_stack.pop()
        # Try to detect missing virtual destructor declarations.
        # For now, only warn if a non-derived class with virtual methods lacks
        # a virtual destructor. This is to make it less likely that people will
        # declare derived virtual destructors without declaring the base
        # destructor virtual.
        if ((classinfo.virtual_method_line_number is not None)
                and (not classinfo.has_virtual_destructor)
                and (not classinfo.is_derived)):  # Only warn for base classes
            error(
                classinfo.line_number, 'runtime/virtual', 4,
                'The class %s probably needs a virtual destructor due to '
                'having virtual method(s), one declared at line %d.' %
                (classinfo.name, classinfo.virtual_method_line_number))
    else:
        classinfo.brace_depth = brace_depth

    well_typed_bitfield = False
    # Look for bool <name> : 1 declarations.
    args = search(r'\bbool\s+(\S*)\s*:\s*\d+\s*;', line)
    if args:
        classinfo.bool_bitfields.append(
            '%d: %s' % (line_number, args.group(1)))
        well_typed_bitfield = True

    # Look for unsigned <name> : n declarations.
    args = search(r'\bunsigned\s+(?:int\s+)?(\S+)\s*:\s*\d+\s*;', line)
    if args:
        classinfo.unsigned_bitfields.append(
            '%d: %s' % (line_number, args.group(1)))
        well_typed_bitfield = True

    # Look for other bitfield declarations. We don't care about those in
    # size-matching structs.
    if not (well_typed_bitfield or classinfo.name.startswith('SameSizeAs')
            or classinfo.name.startswith('Expected')):
        args = match(r'\s*(\S+)\s+(\S+)\s*:\s*\d+\s*;', line)
        if args:
            error(
                line_number, 'runtime/bitfields', 4,
                'Member %s of class %s defined as a bitfield of type %s. '
                'Please declare all bitfields as unsigned.' %
                (args.group(2), classinfo.name, args.group(1)))
Logs an error if we see certain non-ANSI constructs ignored by gcc-2.

    Complain about several constructs which gcc-2 accepts, but which are
    not standard C++.  Warning about these in lint is one way to ease the
    transition to new compilers.
    - put storage class first (e.g. "static const" instead of "const static").
    - "%lld" instead of %qd" in printf-type functions.
    - "%1$d" is non-standard in printf-type functions.
    - "\%" is an undefined character escape sequence.
    - text after #endif is not allowed.
    - invalid inner-style forward declaration.
    - >? and <? operators, and their >?= and <?= cousins.
    - classes with virtual methods need virtual destructors (compiler warning
        available, but not turned on yet.)

    Additionally, check for constructor/destructor style violations as it
    is very convenient to do so while checking for gcc-2 compliance.

    Args:
      clean_lines: A CleansedLines instance containing the file.
      line_number: The number of the line to check.
      class_state: A _ClassState instance which maintains information about
                   the current stack of nested class declarations being parsed.
      error: A callable to which errors are reported, which takes parameters:
             line number, error level, and message
    
Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
Complain about several constructs which gcc-2 accepts, but which are
not standard C++.  Warning about these in lint is one way to ease the
transition to new compilers.
put storage class first .
"%lld" instead of %qd" in printf-type functions.
"%1$d" is non-standard in printf-type functions.
"\%" is an undefined character escape sequence.
text after #endif is not allowed.
invalid inner-style forward declaration.

Additionally, check for constructor/destructor style violations as it
is very convenient to do so while checking for gcc-2 compliance.
Logs an error if we see certain non - ANSI constructs ignored by gcc - 2 . Complain about several constructs which gcc - 2 accepts but which are not standard C ++ . Warning about these in lint is one way to ease the transition to new compilers . put storage class first . " %lld " instead of %qd " in printf - type functions . " %1$d " is non - standard in printf - type functions . " \ % " is an undefined character escape sequence . text after #endif is not allowed . invalid inner - style forward declaration . Additionally check for constructor / destructor style violations as it is very convenient to do so while checking for gcc - 2 compliance .
def check_for_non_standard_constructs(clean_lines, line_number, class_state,
                                      error):
    line = clean_lines.elided[line_number]
    classinfo_stack = class_state.classinfo_stack
    class_decl_match = match(
        r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)',
        line)
    if class_decl_match:
        classinfo_stack.append(
            _ClassInfo(class_decl_match.group(3), line_number))
    if not classinfo_stack:
        return
    classinfo = classinfo_stack[-1]
    if not classinfo.seen_open_brace:
        if ';' in line:
            classinfo_stack.pop()
            return
        classinfo.seen_open_brace = ('{' in line)
        if search('(^|[^:]):($|[^:])', line):
            classinfo.is_derived = True
        if not classinfo.seen_open_brace:
            return  
    base_classname = classinfo.name.split('::')[-1]
    args = match(
        r'(?<!explicit)\s+%s\s*\(([^,()]+)\)' % re.escape(base_classname),
        line)
    if (args and args.group(1) != 'void'
            and not match(r'(const\s+)?%s\s*&' % re.escape(base_classname),
                          args.group(1).strip())):
        error(line_number, 'runtime/explicit', 5,
              'Single-argument constructors should be marked explicit.')
    if search(r'\bvirtual\b', line):
        classinfo.virtual_method_line_number = line_number
        if search(r'~%s\s*\(' % base_classname, line):
            classinfo.has_virtual_destructor = True
    brace_depth = classinfo.brace_depth
    brace_depth = brace_depth + line.count('{') - line.count('}')
    if brace_depth <= 0:
        classinfo = classinfo_stack.pop()
        if ((classinfo.virtual_method_line_number is not None)
                and (not classinfo.has_virtual_destructor)
                and (not classinfo.is_derived)):  
            error(
                classinfo.line_number, 'runtime/virtual', 4,
                'The class %s probably needs a virtual destructor due to '
                'having virtual method(s), one declared at line %d.' %
                (classinfo.name, classinfo.virtual_method_line_number))
    else:
        classinfo.brace_depth = brace_depth
    well_typed_bitfield = False
    args = search(r'\bbool\s+(\S*)\s*:\s*\d+\s*;', line)
    if args:
        classinfo.bool_bitfields.append(
            '%d: %s' % (line_number, args.group(1)))
        well_typed_bitfield = True
    args = search(r'\bunsigned\s+(?:int\s+)?(\S+)\s*:\s*\d+\s*;', line)
    if args:
        classinfo.unsigned_bitfields.append(
            '%d: %s' % (line_number, args.group(1)))
        well_typed_bitfield = True
    if not (well_typed_bitfield or classinfo.name.startswith('SameSizeAs')
            or classinfo.name.startswith('Expected')):
        args = match(r'\s*(\S+)\s+(\S+)\s*:\s*\d+\s*;', line)
        if args:
            error(
                line_number, 'runtime/bitfields', 4,
                'Member %s of class %s defined as a bitfield of type %s. '
                'Please declare all bitfields as unsigned.' %
                (args.group(2), classinfo.name, args.group(1)))
def check_for_non_standard_constructs ( clean_lines , line_number , class_state , error ) : line = clean_lines . elided [ line_number ] classinfo_stack = class_state . classinfo_stack class_decl_match = match ( r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)' , line ) if class_decl_match : classinfo_stack . append ( _ClassInfo ( class_decl_match . group ( 3 ) , line_number ) ) if not classinfo_stack : return classinfo = classinfo_stack [ - 1 ] if not classinfo . seen_open_brace : if ';' in line : classinfo_stack . pop ( ) return classinfo . seen_open_brace = ( '{' in line ) if search ( '(^|[^:]):($|[^:])' , line ) : classinfo . is_derived = True if not classinfo . seen_open_brace : return base_classname = classinfo . name . split ( '::' ) [ - 1 ] args = match ( r'(?<!explicit)\s+%s\s*\(([^,()]+)\)' % re . escape ( base_classname ) , line ) if ( args and args . group ( 1 ) != 'void' and not match ( r'(const\s+)?%s\s*&' % re . escape ( base_classname ) , args . group ( 1 ) . strip ( ) ) ) : error ( line_number , 'runtime/explicit' , 5 , 'Single-argument constructors should be marked explicit.' ) if search ( r'\bvirtual\b' , line ) : classinfo . virtual_method_line_number = line_number if search ( r'~%s\s*\(' % base_classname , line ) : classinfo . has_virtual_destructor = True brace_depth = classinfo . brace_depth brace_depth = brace_depth + line . count ( '{' ) - line . count ( '}' ) if brace_depth <= 0 : classinfo = classinfo_stack . pop ( ) if ( ( classinfo . virtual_method_line_number is not None ) and ( not classinfo . has_virtual_destructor ) and ( not classinfo . is_derived ) ) : error ( classinfo . line_number , 'runtime/virtual' , 4 , 'The class %s probably needs a virtual destructor due to ' 'having virtual method(s), one declared at line %d.' % ( classinfo . name , classinfo . virtual_method_line_number ) ) else : classinfo . brace_depth = brace_depth well_typed_bitfield = False args = search ( r'\bbool\s+(\S*)\s*:\s*\d+\s*;' , line ) if args : classinfo . bool_bitfields . append ( '%d: %s' % ( line_number , args . group ( 1 ) ) ) well_typed_bitfield = True args = search ( r'\bunsigned\s+(?:int\s+)?(\S+)\s*:\s*\d+\s*;' , line ) if args : classinfo . unsigned_bitfields . append ( '%d: %s' % ( line_number , args . group ( 1 ) ) ) well_typed_bitfield = True if not ( well_typed_bitfield or classinfo . name . startswith ( 'SameSizeAs' ) or classinfo . name . startswith ( 'Expected' ) ) : args = match ( r'\s*(\S+)\s+(\S+)\s*:\s*\d+\s*;' , line ) if args : error ( line_number , 'runtime/bitfields' , 4 , 'Member %s of class %s defined as a bitfield of type %s. ' 'Please declare all bitfields as unsigned.' % ( args . group ( 2 ) , classinfo . name , args . group ( 1 ) ) )
Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
Logs an error if we see certain non - ANSI constructs ignored by gcc - 2 .
"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.

    Complain about several constructs which gcc-2 accepts, but which are
    not standard C++.  Warning about these in lint is one way to ease the
    transition to new compilers.
    - put storage class first (e.g. "static const" instead of "const static").
    - "%lld" instead of %qd" in printf-type functions.
    - "%1$d" is non-standard in printf-type functions.
    - "\%" is an undefined character escape sequence.
    - text after #endif is not allowed.
    - invalid inner-style forward declaration.
    - >? and <? operators, and their >?= and <?= cousins.
    - classes with virtual methods need virtual destructors (compiler warning
        available, but not turned on yet.)

    Additionally, check for constructor/destructor style violations as it
    is very convenient to do so while checking for gcc-2 compliance.

    Args:
      clean_lines: A CleansedLines instance containing the file.
      line_number: The number of the line to check.
      class_state: A _ClassState instance which maintains information about
                   the current stack of nested class declarations being parsed.
      error: A callable to which errors are reported, which takes parameters:
             line number, error level, and message
    """ # Work with both comments and strings removed. # Track class entry and exit, and attempt to find cases within the # class declaration that don't meet the C++ style # guidelines. Tracking is very dependent on the code matching Google # style guidelines, but it seems to perform well enough in testing # to be a worthwhile addition to the checks. # Look for a class declaration # Everything else in this function uses the top of the stack if it's # not empty. # If the opening brace hasn't been seen look for it and also # parent class declarations. # If the line has a ';' in it, assume it's a forward declaration or # a single-line class declaration, which we won't process. # Look for a bare ':' # Everything else in this function is for after open brace # The class may have been declared with namespace or classname qualifiers. # The constructor and destructor will not have those qualifiers. # Look for single-argument constructors that aren't marked explicit. # Technically a valid construct, but against style. # Look for methods declared virtual. # Only look for a destructor declaration on the same line. It would # be extremely unlikely for the destructor declaration to occupy # more than one line. # Look for class end. # Try to detect missing virtual destructor declarations. # For now, only warn if a non-derived class with virtual methods lacks # a virtual destructor. This is to make it less likely that people will # declare derived virtual destructors without declaring the base # destructor virtual. # Only warn for base classes # Look for bool <name> : 1 declarations. # Look for unsigned <name> : n declarations. # Look for other bitfield declarations. We don't care about those in # size-matching structs.
clean_lines
A CleansedLines instance containing the file.
A CleansedLines instance containing the file .
line_number
The number of the line to check.
The number of the line to check .
class_state
A _ClassState instance which maintains information about
the current stack of nested class declarations being parsed.
A _ClassState instance which maintains information about the current stack of nested class declarations being parsed .
error
A callable to which errors are reported, which takes parameters:
line number, error level, and message
A callable to which errors are reported which takes parameters : line number error level and message