
class WarningOption {
  string name = ?;            // Name of the option on the command line
  string description = ?;     // Description of the option for the help
  bit display = 1;            // Whether to display this warning in the help
}

class WarningGroup : WarningOption {
  list<WarningOption> members = ?;  // Members of this warning group
}

class Warning : WarningOption {
  string diag = name;         // Name of the diag constant of this warning
  string default = "ignore";  // Default behavior for the warning
                              // can be "ignore", "warn" or "error"
}

// Preprocessor/lexer warnings
def UnusedMacros : Warning {
  let name = "unused-macros";
  let diag = "pp_macro_not_used";
  let description = "Warn for unused macros in the main translation unit";
}
def UndefMacros : Warning {
  let name = "undef";
  let diag = "warn_pp_undef_identifier";
  let description = "Warn on use of undefined macros in #if's";
}
def NullInString : Warning {
  let name = "null-in-string";
  let diag = "null_in_string";
  let description =
    "Warn if a literal null character appears in a string literal";
  let display = 0;
}
def NullInCharacter : Warning {
  let name = "null-in-char";
  let diag = "null_in_char";
  let description =
    "Warn if a literal null character appears in a character literal";
  let display = 0;
}
def NullInFile : Warning {
  let name = "null-in-file";
  let diag = "null_in_file";
  let description = "Warn if a literal null character appears in a file";
  let display = 0;
}
def NullChar : WarningGroup {
  let name = "null-character";
  let description = "Warn about literal null characters in the source";
  let members = [NullInString, NullInCharacter, NullInFile];
}
def NestedComment : Warning {
  let name = "comment"; // GCC equivalence
  let diag = "warn_nested_block_comment";
}


// Generic language warnings
def FloatEqual : Warning {
  let name = "float-equal";
  let description = "Warn about equality comparisons of floating point values";
}
def FormatNonLiteral : Warning {
  let name = "format-nonliteral";
  let description = "Warn about non-literal format strings";
  let default = "warn";
}
def IntegerTooLarge : Warning {
  let name = "integer-too-large";
  let diag = "warn_integer_too_large";
  let description = "Warn when an integer constant is too large for its type";
}
def IntegerTooLargeForSigned : Warning {
  let name = "integer-too-large-for-signed";
  let diag = "warn_integer_too_large_for_signed";
  let description =
    "Warn when an integer constant is so large that it is unsigned";
}


// C-specific warnings
def ImplicitFunctionDeclaration : Warning {
  let name = "implicit-function-declaration";
  let description = "Warn about uses of implicitly defined functions";
}

// C++-specific warnings


// ObjC-specific warnings
def PropertyReadonlyAttrs : Warning {
  let name = "readonly-setter-attrs";
  let description = "Warn about readonly properties with writable attributes";
}
def StrictSelectorMatch : Warning {
  let name = "strict-selector-match";
  let description =
    "Warn about duplicate methods that have the same size and alignment";
  let default = "warn";
}


def ArchaicC : WarningGroup {
  let name = "archaic-c";
  let description = "Warn about uses of archaic C features";
  let members = [ ImplicitFunctionDeclaration ];
}

def Everything : WarningGroup {
  let name = "everything";
  let description = "Enable every single warning";
  let members = [
    UnusedMacros, UndefMacros, NullChar, NestedComment,
    FloatEqual, FormatNonLiteral, IntegerTooLarge, IntegerTooLargeForSigned,
    ImplicitFunctionDeclaration,
    PropertyReadonlyAttrs, StrictSelectorMatch
  ];
}
