Date: Thu, 19 Nov 2009 09:00:00 +0000 (UTC) From: Roman Divacky <rdivacky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r199512 - in vendor/clang/dist: include/clang include/clang/AST include/clang/Analysis/PathSensitive/Checkers include/clang/Analysis/Visitors include/clang/Basic include/clang/Driver in... Message-ID: <200911190900.nAJ900eg099314@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rdivacky Date: Thu Nov 19 09:00:00 2009 New Revision: 199512 URL: http://svn.freebsd.org/changeset/base/199512 Log: Update clang to r89337. Added: vendor/clang/dist/include/clang/Driver/CC1Options.h vendor/clang/dist/include/clang/Driver/CC1Options.td vendor/clang/dist/include/clang/Driver/CMakeLists.txt vendor/clang/dist/include/clang/Driver/Makefile vendor/clang/dist/include/clang/Driver/OptParser.td vendor/clang/dist/include/clang/Driver/OptSpecifier.h vendor/clang/dist/include/clang/Driver/OptTable.h vendor/clang/dist/include/clang/Driver/Options.td vendor/clang/dist/lib/Driver/CC1Options.cpp vendor/clang/dist/lib/Driver/DriverOptions.cpp vendor/clang/dist/test/CXX/special/class.dtor/p2.cpp vendor/clang/dist/test/Index/complete-categories.m vendor/clang/dist/test/Index/complete-interfaces.m vendor/clang/dist/test/Index/complete-properties.m vendor/clang/dist/test/Index/complete-property-flags.m vendor/clang/dist/test/Index/complete-property-getset.m vendor/clang/dist/test/Parser/objc-synthesized-recover.m vendor/clang/dist/test/SemaCXX/cxx-member-pointer-op.cpp vendor/clang/dist/test/SemaObjC/class-protocol.m vendor/clang/dist/test/SemaObjC/no-warn-qual-mismatch.m vendor/clang/dist/test/SemaTemplate/instantiate-case.cpp vendor/clang/dist/tools/driver/cc1_main.cpp Deleted: vendor/clang/dist/include/clang/AST/CFG.h vendor/clang/dist/include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h vendor/clang/dist/include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h vendor/clang/dist/include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h vendor/clang/dist/include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h vendor/clang/dist/include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h vendor/clang/dist/include/clang/Analysis/Visitors/CFGVarDeclVisitor.h vendor/clang/dist/include/clang/Driver/Options.def vendor/clang/dist/include/clang/Frontend/CompileOptions.h vendor/clang/dist/include/clang/Frontend/InitHeaderSearch.h vendor/clang/dist/include/clang/Frontend/InitPreprocessor.h vendor/clang/dist/include/clang/Frontend/ManagerRegistry.h Modified: vendor/clang/dist/include/clang/AST/DeclObjC.h vendor/clang/dist/include/clang/Basic/Diagnostic.h vendor/clang/dist/include/clang/Basic/DiagnosticParseKinds.td vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td vendor/clang/dist/include/clang/CMakeLists.txt vendor/clang/dist/include/clang/Driver/ArgList.h vendor/clang/dist/include/clang/Driver/Option.h vendor/clang/dist/include/clang/Driver/Options.h vendor/clang/dist/include/clang/Frontend/HeaderSearchOptions.h vendor/clang/dist/include/clang/Makefile vendor/clang/dist/include/clang/Parse/Action.h vendor/clang/dist/include/clang/Parse/Parser.h vendor/clang/dist/include/clang/Sema/CodeCompleteConsumer.h vendor/clang/dist/lib/CodeGen/CGCXX.cpp vendor/clang/dist/lib/CodeGen/CGDecl.cpp vendor/clang/dist/lib/CodeGen/CGRecordLayoutBuilder.cpp vendor/clang/dist/lib/CodeGen/CGRtti.cpp vendor/clang/dist/lib/CodeGen/CGVtable.cpp vendor/clang/dist/lib/CodeGen/CGVtable.h vendor/clang/dist/lib/CodeGen/CodeGenModule.cpp vendor/clang/dist/lib/Driver/ArgList.cpp vendor/clang/dist/lib/Driver/CMakeLists.txt vendor/clang/dist/lib/Driver/Compilation.cpp vendor/clang/dist/lib/Driver/Driver.cpp vendor/clang/dist/lib/Driver/HostInfo.cpp vendor/clang/dist/lib/Driver/OptTable.cpp vendor/clang/dist/lib/Driver/Option.cpp vendor/clang/dist/lib/Driver/ToolChains.cpp vendor/clang/dist/lib/Driver/Tools.cpp vendor/clang/dist/lib/Driver/Types.cpp vendor/clang/dist/lib/Frontend/CompilerInvocation.cpp vendor/clang/dist/lib/Frontend/InitPreprocessor.cpp vendor/clang/dist/lib/Frontend/PCHReader.cpp vendor/clang/dist/lib/Headers/stdint.h vendor/clang/dist/lib/Parse/ParseExpr.cpp vendor/clang/dist/lib/Parse/ParseObjc.cpp vendor/clang/dist/lib/Sema/CodeCompleteConsumer.cpp vendor/clang/dist/lib/Sema/Lookup.h vendor/clang/dist/lib/Sema/Sema.cpp vendor/clang/dist/lib/Sema/Sema.h vendor/clang/dist/lib/Sema/SemaCXXCast.cpp vendor/clang/dist/lib/Sema/SemaCodeComplete.cpp vendor/clang/dist/lib/Sema/SemaDecl.cpp vendor/clang/dist/lib/Sema/SemaDeclCXX.cpp vendor/clang/dist/lib/Sema/SemaDeclObjC.cpp vendor/clang/dist/lib/Sema/SemaExprCXX.cpp vendor/clang/dist/lib/Sema/SemaLookup.cpp vendor/clang/dist/lib/Sema/SemaOverload.cpp vendor/clang/dist/lib/Sema/SemaTemplate.cpp vendor/clang/dist/lib/Sema/SemaTemplateInstantiateDecl.cpp vendor/clang/dist/lib/Sema/TreeTransform.h vendor/clang/dist/test/Analysis/null-deref-ps.c vendor/clang/dist/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp vendor/clang/dist/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp vendor/clang/dist/test/CodeGen/libcalls.c vendor/clang/dist/test/Driver/analyze.c vendor/clang/dist/test/Driver/clang-translation.c vendor/clang/dist/test/Driver/clang_f_opts.c vendor/clang/dist/test/Index/TestClassDecl.m vendor/clang/dist/test/Index/TestClassForwardDecl.m vendor/clang/dist/test/Index/c-index-api-loadTU-test.m vendor/clang/dist/test/Index/complete-objc-message.m vendor/clang/dist/test/Preprocessor/init.c vendor/clang/dist/test/Preprocessor/stdint.c vendor/clang/dist/test/Sema/unused-expr.c vendor/clang/dist/test/SemaCXX/abstract.cpp vendor/clang/dist/test/SemaCXX/overloaded-operator.cpp vendor/clang/dist/test/SemaCXX/reinterpret-cast.cpp vendor/clang/dist/test/SemaCXX/rval-references.cpp vendor/clang/dist/test/SemaCXX/using-directive.cpp vendor/clang/dist/test/SemaTemplate/constructor-template.cpp vendor/clang/dist/tools/CIndex/CIndex.cpp vendor/clang/dist/tools/clang-cc/Options.cpp vendor/clang/dist/tools/driver/CMakeLists.txt vendor/clang/dist/tools/driver/Makefile vendor/clang/dist/tools/driver/driver.cpp Modified: vendor/clang/dist/include/clang/AST/DeclObjC.h ============================================================================== --- vendor/clang/dist/include/clang/AST/DeclObjC.h Thu Nov 19 08:59:28 2009 (r199511) +++ vendor/clang/dist/include/clang/AST/DeclObjC.h Thu Nov 19 09:00:00 2009 (r199512) @@ -808,7 +808,7 @@ public: /// - myMethod; /// @end /// -/// Cateogries also allow you to split the implementation of a class across +/// Categories also allow you to split the implementation of a class across /// several files (a feature more naturally supported in C++). /// /// Categories were originally inspired by dynamic languages such as Common Modified: vendor/clang/dist/include/clang/Basic/Diagnostic.h ============================================================================== --- vendor/clang/dist/include/clang/Basic/Diagnostic.h Thu Nov 19 08:59:28 2009 (r199511) +++ vendor/clang/dist/include/clang/Basic/Diagnostic.h Thu Nov 19 09:00:00 2009 (r199512) @@ -235,8 +235,8 @@ public: // Diagnostic characterization methods, used by a client to customize how // - DiagnosticClient *getClient() { return Client; }; - const DiagnosticClient *getClient() const { return Client; }; + DiagnosticClient *getClient() { return Client; } + const DiagnosticClient *getClient() const { return Client; } /// pushMappings - Copies the current DiagMappings and pushes the new copy Modified: vendor/clang/dist/include/clang/Basic/DiagnosticParseKinds.td ============================================================================== --- vendor/clang/dist/include/clang/Basic/DiagnosticParseKinds.td Thu Nov 19 08:59:28 2009 (r199511) +++ vendor/clang/dist/include/clang/Basic/DiagnosticParseKinds.td Thu Nov 19 09:00:00 2009 (r199512) @@ -117,8 +117,6 @@ def err_expected_semi_after_static_asser "expected ';' after static_assert">; def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">; def err_expected_colon_after : Error<"expected ':' after %0">; -def err_pointer_to_member_type : Error< - "invalid use of pointer to member type after %0">; def err_label_end_of_compound_statement : Error< "label at end of compound statement: expected statement">; def err_expected_string_literal : Error<"expected string literal">; @@ -201,6 +199,8 @@ def warn_expected_implementation : Warni "@end must appear in an @implementation context">; def error_property_ivar_decl : Error< "property synthesize requires specification of an ivar">; +def err_synthesized_property_name : Error< + "expected a property name in @synthesize">; def warn_semicolon_before_method_body : Warning< "semicolon before method body is ignored">, InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore; Modified: vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td ============================================================================== --- vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td Thu Nov 19 08:59:28 2009 (r199511) +++ vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td Thu Nov 19 09:00:00 2009 (r199512) @@ -979,6 +979,8 @@ def err_template_arg_not_pointer_to_memb "non-type template argument is not a pointer to member constant">; def err_template_arg_extra_parens : Error< "non-type template argument cannot be surrounded by parentheses">; +def err_pointer_to_member_type : Error< + "invalid use of pointer to member type after %select{.*|->*}0">; // C++ template specialization def err_template_spec_unknown_kind : Error< @@ -1811,6 +1813,8 @@ def err_typecheck_bool_condition : Error "value of type %0 is not contextually convertible to 'bool'">; def err_typecheck_ambiguous_condition : Error< "conversion from %0 to %1 is ambiguous">; +def err_typecheck_nonviable_condition : Error< + "no viable conversion from %0 to %1 is possible">; def err_expected_class_or_namespace : Error<"expected a class or namespace">; def err_invalid_declarator_scope : Error< "definition or redeclaration of %0 not in a namespace enclosing %1">; Modified: vendor/clang/dist/include/clang/CMakeLists.txt ============================================================================== --- vendor/clang/dist/include/clang/CMakeLists.txt Thu Nov 19 08:59:28 2009 (r199511) +++ vendor/clang/dist/include/clang/CMakeLists.txt Thu Nov 19 09:00:00 2009 (r199512) @@ -1 +1,2 @@ add_subdirectory(Basic) +add_subdirectory(Driver) Modified: vendor/clang/dist/include/clang/Driver/ArgList.h ============================================================================== --- vendor/clang/dist/include/clang/Driver/ArgList.h Thu Nov 19 08:59:28 2009 (r199511) +++ vendor/clang/dist/include/clang/Driver/ArgList.h Thu Nov 19 09:00:00 2009 (r199512) @@ -10,8 +10,7 @@ #ifndef CLANG_DRIVER_ARGLIST_H_ #define CLANG_DRIVER_ARGLIST_H_ -#include "clang/Driver/Options.h" - +#include "clang/Driver/OptSpecifier.h" #include "clang/Driver/Util.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -26,6 +25,7 @@ namespace llvm { namespace clang { namespace driver { class Arg; + class Option; /// ArgList - Ordered collection of driver arguments. /// @@ -77,20 +77,26 @@ namespace driver { /// hasArg - Does the arg list contain any option matching \arg Id. /// /// \arg Claim Whether the argument should be claimed, if it exists. - bool hasArg(options::ID Id, bool Claim=true) const { - return getLastArg(Id, Claim) != 0; + bool hasArgNoClaim(OptSpecifier Id) const { + return getLastArgNoClaim(Id) != 0; + } + bool hasArg(OptSpecifier Id) const { + return getLastArg(Id) != 0; + } + bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const { + return getLastArg(Id0, Id1) != 0; } - bool hasArg(options::ID Id0, options::ID Id1, bool Claim=true) const { - return getLastArg(Id0, Id1, Claim) != 0; + bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { + return getLastArg(Id0, Id1, Id2) != 0; } /// getLastArg - Return the last argument matching \arg Id, or null. /// /// \arg Claim Whether the argument should be claimed, if it exists. - Arg *getLastArg(options::ID Id, bool Claim=true) const; - Arg *getLastArg(options::ID Id0, options::ID Id1, bool Claim=true) const; - Arg *getLastArg(options::ID Id0, options::ID Id1, options::ID Id2, - bool Claim=true) const; + Arg *getLastArgNoClaim(OptSpecifier Id) const; + Arg *getLastArg(OptSpecifier Id) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const; /// getArgString - Return the input argument string at \arg Index. virtual const char *getArgString(unsigned Index) const = 0; @@ -102,24 +108,24 @@ namespace driver { /// negation is present, and \arg Default if neither option is /// given. If both the option and its negation are present, the /// last one wins. - bool hasFlag(options::ID Pos, options::ID Neg, bool Default=true) const; + bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const; /// AddLastArg - Render only the last argument match \arg Id0, if /// present. - void AddLastArg(ArgStringList &Output, options::ID Id0) const; + void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; /// AddAllArgs - Render all arguments matching the given ids. - void AddAllArgs(ArgStringList &Output, options::ID Id0) const; - void AddAllArgs(ArgStringList &Output, options::ID Id0, - options::ID Id1) const; - void AddAllArgs(ArgStringList &Output, options::ID Id0, options::ID Id1, - options::ID Id2) const; + void AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const; + void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1) const; + void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1, + OptSpecifier Id2) const; /// AddAllArgValues - Render the argument values of all arguments /// matching the given ids. - void AddAllArgValues(ArgStringList &Output, options::ID Id0) const; - void AddAllArgValues(ArgStringList &Output, options::ID Id0, - options::ID Id1) const; + void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const; + void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1) const; /// AddAllArgsTranslated - Render all the arguments matching the /// given ids, but forced to separate args and using the provided @@ -127,13 +133,13 @@ namespace driver { /// /// \param Joined - If true, render the argument as joined with /// the option specifier. - void AddAllArgsTranslated(ArgStringList &Output, options::ID Id0, + void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, const char *Translation, bool Joined = false) const; /// ClaimAllArgs - Claim all arguments which match the given /// option id. - void ClaimAllArgs(options::ID Id0) const; + void ClaimAllArgs(OptSpecifier Id0) const; /// @} /// @name Arg Synthesis Added: vendor/clang/dist/include/clang/Driver/CC1Options.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist/include/clang/Driver/CC1Options.h Thu Nov 19 09:00:00 2009 (r199512) @@ -0,0 +1,34 @@ +//===--- CC1Options.h - Clang CC1 Options Table -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_DRIVER_CC1OPTIONS_H +#define CLANG_DRIVER_CC1OPTIONS_H + +namespace clang { +namespace driver { + class OptTable; + +namespace cc1options { + enum ID { + OPT_INVALID = 0, // This is not an option ID. + OPT_INPUT, // Reserved ID for input option. + OPT_UNKNOWN, // Reserved ID for unknown option. +#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) OPT_##ID, +#include "clang/Driver/CC1Options.inc" + LastOption +#undef OPTION + }; +} + + OptTable *createCC1OptTable(); +} +} + +#endif Added: vendor/clang/dist/include/clang/Driver/CC1Options.td ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist/include/clang/Driver/CC1Options.td Thu Nov 19 09:00:00 2009 (r199512) @@ -0,0 +1,26 @@ +//===--- CC1Options.td - Options for clang -cc1 ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the options accepted by clang -cc1. +// +//===----------------------------------------------------------------------===// + +// Include the common option parsing interfaces. +include "OptParser.td" + +// Target Options + +def target_abi : Separate<"-target-abi">, + HelpText<"Target a particular ABI type">; +def target_cpu : Separate<"-mcpu">, + HelpText<"Target a specific cpu type (-mcpu=help for details)">; +def target_features : Separate<"-target-feature">, + HelpText<"Target specific attributes">; +def target_triple : Separate<"-triple">, + HelpText<"Specify target triple (e.g. i686-apple-darwin9)">; Added: vendor/clang/dist/include/clang/Driver/CMakeLists.txt ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist/include/clang/Driver/CMakeLists.txt Thu Nov 19 09:00:00 2009 (r199512) @@ -0,0 +1,11 @@ +set(LLVM_TARGET_DEFINITIONS Options.td) +tablegen(Options.inc + -gen-opt-parser-defs) +add_custom_target(ClangDriverOptions + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Options.inc) + +set(LLVM_TARGET_DEFINITIONS CC1Options.td) +tablegen(CC1Options.inc + -gen-opt-parser-defs) +add_custom_target(ClangCC1Options + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CC1Options.inc) Added: vendor/clang/dist/include/clang/Driver/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist/include/clang/Driver/Makefile Thu Nov 19 09:00:00 2009 (r199512) @@ -0,0 +1,16 @@ +LEVEL = ../../../../.. +BUILT_SOURCES = Options.inc CC1Options.inc + +TABLEGEN_INC_FILES_COMMON = 1 + +include $(LEVEL)/Makefile.common + +$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(ObjDir)/.dir + $(Echo) "Building Clang Driver Option tables with tblgen" + $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $< + +$(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(ObjDir)/.dir + $(Echo) "Building Clang CC1 Option tables with tblgen" + $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $< + + Added: vendor/clang/dist/include/clang/Driver/OptParser.td ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist/include/clang/Driver/OptParser.td Thu Nov 19 09:00:00 2009 (r199512) @@ -0,0 +1,116 @@ +//===--- OptParser.td - Common Option Parsing Interfaces ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the common interfaces used by the option parsing TableGen +// backend. +// +//===----------------------------------------------------------------------===// + +// Define the kinds of options. + +class OptionKind<string name, int predecence = 0> { + string Name = name; + // The kind precedence, kinds with lower precedence are matched first. + int Precedence = predecence; +} + +// An option group. +def KIND_GROUP : OptionKind<"Group">; +// A flag with no values. +def KIND_FLAG : OptionKind<"Flag">; +// An option which prefixes its (single) value. +def KIND_JOINED : OptionKind<"Joined", 1>; +// An option which is followed by its value. +def KIND_SEPARATE : OptionKind<"Separate">; +// An option followed by its values, which are separated by commas. +def KIND_COMMAJOINED : OptionKind<"CommaJoined">; +// An option which is which takes multiple (separate) arguments. +def KIND_MULTIARG : OptionKind<"MultiArg">; +// An option which is either joined to its (non-empty) value, or followed by its +// value. +def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">; +// An option which is both joined to its (first) value, and followed by its +// (second) value. +def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">; + +// Define the option flags. + +class OptionFlag {} + +// DriverOption - The option is a "driver" option, and should not be forwarded +// to gcc. +def DriverOption : OptionFlag; + +// LinkerInput - The option is a linker input. +def LinkerInput : OptionFlag; + +// NoArgumentUnused - Don't report argument unused warnings for this option; this +// is useful for options like -static or -dynamic which a user may always end up +// passing, even if the platform defaults to (or only supports) that option. +def NoArgumentUnused : OptionFlag; + +// RenderAsInput - The option should not render the name when rendered as an +// input (i.e., the option is rendered as values). +def RenderAsInput : OptionFlag; + +// RenderJoined - The option should be rendered joined, even if separate (only +// sensible on single value separate options). +def RenderJoined : OptionFlag; + +// RenderSeparate - The option should be rendered separately, even if joined +// (only sensible on joined options). +def RenderSeparate : OptionFlag; + +// Unsupported - The option is unsupported, and the driver will reject command +// lines that use it. +def Unsupported : OptionFlag; + +// Define the option group class. + +class OptionGroup<string name> { + string EnumName = ?; // Uses the def name if undefined. + string Name = name; + OptionGroup Group = ?; +} + +// Define the option class. + +class Option<string name, OptionKind kind> { + string EnumName = ?; // Uses the def name if undefined. + string Name = name; + OptionKind Kind = kind; + // Used by MultiArg option kind. + int NumArgs = 0; + string HelpText = ?; + string MetaVarName = ?; + list<OptionFlag> Flags = []; + OptionGroup Group = ?; + Option Alias = ?; +} + +// Helpers for defining options. + +class Flag<string name> : Option<name, KIND_FLAG>; +class Joined<string name> : Option<name, KIND_JOINED>; +class Separate<string name> : Option<name, KIND_SEPARATE>; +class CommaJoined<string name> : Option<name, KIND_COMMAJOINED>; +class MultiArg<string name, int numargs> : Option<name, KIND_MULTIARG> { + int NumArgs = numargs; +} +class JoinedOrSeparate<string name> : Option<name, KIND_JOINED_OR_SEPARATE>; +class JoinedAndSeparate<string name> : Option<name, KIND_JOINED_AND_SEPARATE>; + +// Mix-ins for adding optional attributes. + +class Alias<Option alias> { Option Alias = alias; } +class EnumName<string name> { string EnumName = name; } +class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; } +class Group<OptionGroup group> { OptionGroup Group = group; } +class HelpText<string text> { string HelpText = text; } +class MetaVarName<string name> { string MetaVarName = name; } Added: vendor/clang/dist/include/clang/Driver/OptSpecifier.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist/include/clang/Driver/OptSpecifier.h Thu Nov 19 09:00:00 2009 (r199512) @@ -0,0 +1,36 @@ +//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_DRIVER_OPTSPECIFIER_H +#define CLANG_DRIVER_OPTSPECIFIER_H + +namespace clang { +namespace driver { + class Option; + + /// OptSpecifier - Wrapper class for abstracting references to option IDs. + class OptSpecifier { + unsigned ID; + + private: + explicit OptSpecifier(bool); // DO NOT IMPLEMENT + + public: + /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {} + /*implicit*/ OptSpecifier(const Option *Opt); + + unsigned getID() const { return ID; } + + bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); } + bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); } + }; +} +} + +#endif Added: vendor/clang/dist/include/clang/Driver/OptTable.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist/include/clang/Driver/OptTable.h Thu Nov 19 09:00:00 2009 (r199512) @@ -0,0 +1,163 @@ +//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_DRIVER_OPTTABLE_H +#define CLANG_DRIVER_OPTTABLE_H + +#include "clang/Driver/OptSpecifier.h" +#include <cassert> + +namespace clang { +namespace driver { +namespace options { + enum DriverFlag { + DriverOption = (1 << 0), + LinkerInput = (1 << 1), + NoArgumentUnused = (1 << 2), + RenderAsInput = (1 << 3), + RenderJoined = (1 << 4), + RenderSeparate = (1 << 5), + Unsupported = (1 << 6) + }; +} + + class Arg; + class InputArgList; + class Option; + + /// OptTable - Provide access to the Option info table. + /// + /// The OptTable class provides a layer of indirection which allows Option + /// instance to be created lazily. In the common case, only a few options will + /// be needed at runtime; the OptTable class maintains enough information to + /// parse command lines without instantiating Options, while letting other + /// parts of the driver still use Option instances where convenient. + class OptTable { + public: + /// Info - Entry for a single option instance in the option data table. + struct Info { + const char *Name; + const char *HelpText; + const char *MetaVar; + unsigned char Kind; + unsigned char Flags; + unsigned char Param; + unsigned short GroupID; + unsigned short AliasID; + }; + + private: + /// The static option information table. + const Info *OptionInfos; + unsigned NumOptionInfos; + + /// The lazily constructed options table, indexed by option::ID - 1. + mutable Option **Options; + + /// Prebound input option instance. + const Option *TheInputOption; + + /// Prebound unknown option instance. + const Option *TheUnknownOption; + + /// The index of the first option which can be parsed (i.e., is not a + /// special option like 'input' or 'unknown', and is not an option group). + unsigned FirstSearchableIndex; + + private: + const Info &getInfo(OptSpecifier Opt) const { + unsigned id = Opt.getID(); + assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID."); + return OptionInfos[id - 1]; + } + + Option *CreateOption(unsigned id) const; + + protected: + OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos); + public: + ~OptTable(); + + /// getNumOptions - Return the total number of option classes. + unsigned getNumOptions() const { return NumOptionInfos; } + + /// getOption - Get the given \arg id's Option instance, lazily creating it + /// if necessary. + /// + /// \return The option, or null for the INVALID option id. + const Option *getOption(OptSpecifier Opt) const { + unsigned id = Opt.getID(); + if (id == 0) + return 0; + + assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID."); + Option *&Entry = Options[id - 1]; + if (!Entry) + Entry = CreateOption(id); + return Entry; + } + + /// getOptionName - Lookup the name of the given option. + const char *getOptionName(OptSpecifier id) const { + return getInfo(id).Name; + } + + /// getOptionKind - Get the kind of the given option. + unsigned getOptionKind(OptSpecifier id) const { + return getInfo(id).Kind; + } + + /// getOptionHelpText - Get the help text to use to describe this option. + const char *getOptionHelpText(OptSpecifier id) const { + return getInfo(id).HelpText; + } + + /// getOptionMetaVar - Get the meta-variable name to use when describing + /// this options values in the help text. + const char *getOptionMetaVar(OptSpecifier id) const { + return getInfo(id).MetaVar; + } + + /// ParseOneArg - Parse a single argument; returning the new argument and + /// updating Index. + /// + /// \param [in] [out] Index - The current parsing position in the argument + /// string list; on return this will be the index of the next argument + /// string to parse. + /// + /// \return - The parsed argument, or 0 if the argument is missing values + /// (in which case Index still points at the conceptual next argument string + /// to parse). + Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const; + + /// ParseArgs - Parse an list of arguments into an InputArgList. + /// + /// The resulting InputArgList will reference the strings in [ArgBegin, + /// ArgEnd), and their lifetime should extend past that of the returned + /// InputArgList. + /// + /// The only error that can occur in this routine is if an argument is + /// missing values; in this case \arg MissingArgCount will be non-zero. + /// + /// \param ArgBegin - The beginning of the argument vector. + /// \param ArgEnd - The end of the argument vector. + /// \param MissingArgIndex - On error, the index of the option which could + /// not be parsed. + /// \param MissingArgCount - On error, the number of missing options. + /// \return - An InputArgList; on error this will contain all the options + /// which could be parsed. + InputArgList *ParseArgs(const char **ArgBegin, + const char **ArgEnd, + unsigned &MissingArgIndex, + unsigned &MissingArgCount) const; + }; +} +} + +#endif Modified: vendor/clang/dist/include/clang/Driver/Option.h ============================================================================== --- vendor/clang/dist/include/clang/Driver/Option.h Thu Nov 19 08:59:28 2009 (r199511) +++ vendor/clang/dist/include/clang/Driver/Option.h Thu Nov 19 09:00:00 2009 (r199512) @@ -10,8 +10,7 @@ #ifndef CLANG_DRIVER_OPTION_H_ #define CLANG_DRIVER_OPTION_H_ -#include "Options.h" - +#include "clang/Driver/OptSpecifier.h" #include "llvm/Support/Casting.h" using llvm::isa; using llvm::cast; @@ -54,7 +53,8 @@ namespace driver { private: OptionClass Kind; - options::ID ID; + /// The option ID. + OptSpecifier ID; /// The option name. const char *Name; @@ -89,12 +89,12 @@ namespace driver { bool NoArgumentUnused : 1; protected: - Option(OptionClass Kind, options::ID ID, const char *Name, + Option(OptionClass Kind, OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); public: virtual ~Option(); - options::ID getId() const { return ID; } + unsigned getID() const { return ID.getID(); } OptionClass getKind() const { return Kind; } const char *getName() const { return Name; } const OptionGroup *getGroup() const { return Group; } @@ -138,8 +138,11 @@ namespace driver { /// matches - Predicate for whether this option is part of the /// given option (which may be a group). - bool matches(const Option *Opt) const; - bool matches(options::ID Id) const; + /// + /// Note that matches against options which are an alias should never be + /// done -- aliases do not participate in matching and so such a query will + /// always be false. + bool matches(OptSpecifier ID) const; /// accept - Potentially accept the current argument, returning a /// new Arg instance, or 0 if the option does not accept this @@ -159,7 +162,7 @@ namespace driver { /// by the driver. class OptionGroup : public Option { public: - OptionGroup(options::ID ID, const char *Name, const OptionGroup *Group); + OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -174,7 +177,7 @@ namespace driver { /// InputOption - Dummy option class for representing driver inputs. class InputOption : public Option { public: - InputOption(); + InputOption(OptSpecifier ID); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -187,7 +190,7 @@ namespace driver { /// UnknownOption - Dummy option class for represent unknown arguments. class UnknownOption : public Option { public: - UnknownOption(); + UnknownOption(OptSpecifier ID); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -201,7 +204,7 @@ namespace driver { class FlagOption : public Option { public: - FlagOption(options::ID ID, const char *Name, const OptionGroup *Group, + FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -214,7 +217,7 @@ namespace driver { class JoinedOption : public Option { public: - JoinedOption(options::ID ID, const char *Name, const OptionGroup *Group, + JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -227,8 +230,8 @@ namespace driver { class SeparateOption : public Option { public: - SeparateOption(options::ID ID, const char *Name, const OptionGroup *Group, - const Option *Alias); + SeparateOption(OptSpecifier ID, const char *Name, + const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -240,7 +243,7 @@ namespace driver { class CommaJoinedOption : public Option { public: - CommaJoinedOption(options::ID ID, const char *Name, + CommaJoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -259,7 +262,7 @@ namespace driver { unsigned NumArgs; public: - MultiArgOption(options::ID ID, const char *Name, const OptionGroup *Group, + MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias, unsigned NumArgs); unsigned getNumArgs() const { return NumArgs; } @@ -276,7 +279,7 @@ namespace driver { /// prefixes its (non-empty) value, or is follwed by a value. class JoinedOrSeparateOption : public Option { public: - JoinedOrSeparateOption(options::ID ID, const char *Name, + JoinedOrSeparateOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -291,7 +294,7 @@ namespace driver { /// value and is followed by another value. class JoinedAndSeparateOption : public Option { public: - JoinedAndSeparateOption(options::ID ID, const char *Name, + JoinedAndSeparateOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; Modified: vendor/clang/dist/include/clang/Driver/Options.h ============================================================================== --- vendor/clang/dist/include/clang/Driver/Options.h Thu Nov 19 08:59:28 2009 (r199511) +++ vendor/clang/dist/include/clang/Driver/Options.h Thu Nov 19 09:00:00 2009 (r199512) @@ -7,11 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef CLANG_DRIVER_OPTIONS_H_ -#define CLANG_DRIVER_OPTIONS_H_ +#ifndef CLANG_DRIVER_OPTIONS_H +#define CLANG_DRIVER_OPTIONS_H namespace clang { namespace driver { + class OptTable; + namespace options { enum ID { OPT_INVALID = 0, // This is not an option ID. @@ -19,71 +21,13 @@ namespace options { OPT_UNKNOWN, // Reserved ID for unknown option. #define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ HELPTEXT, METAVAR) OPT_##ID, -#include "clang/Driver/Options.def" +#include "clang/Driver/Options.inc" LastOption #undef OPTION }; } - class Arg; - class InputArgList; - class Option; - - /// OptTable - Provide access to the Option info table. - /// - /// The OptTable class provides a layer of indirection which allows - /// Option instance to be created lazily. In the common case, only a - /// few options will be needed at runtime; the OptTable class - /// maintains enough information to parse command lines without - /// instantiating Options, while letting other parts of the driver - /// still use Option instances where convient. - class OptTable { - /// The table of options which have been constructed, indexed by - /// option::ID - 1. - mutable Option **Options; - - /// The index of the first option which can be parsed (i.e., is - /// not a special option like 'input' or 'unknown', and is not an - /// option group). - unsigned FirstSearchableOption; - - Option *constructOption(options::ID id) const; - - public: - OptTable(); - ~OptTable(); - - unsigned getNumOptions() const; - - const char *getOptionName(options::ID id) const; - - /// getOption - Get the given \arg id's Option instance, lazily - /// creating it if necessary. - const Option *getOption(options::ID id) const; - - /// getOptionKind - Get the kind of the given option. - unsigned getOptionKind(options::ID id) const; - - /// getOptionHelpText - Get the help text to use to describe this - /// option. - const char *getOptionHelpText(options::ID id) const; - - /// getOptionMetaVar - Get the meta-variable name to use when - /// describing this options values in the help text. - const char *getOptionMetaVar(options::ID id) const; - - /// parseOneArg - Parse a single argument; returning the new - /// argument and updating Index. - /// - /// \param [in] [out] Index - The current parsing position in the - /// argument string list; on return this will be the index of the - /// next argument string to parse. - /// - /// \return - The parsed argument, or 0 if the argument is missing - /// values (in which case Index still points at the conceptual - /// next argument string to parse). - Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const; - }; + OptTable *createDriverOptTable(); } } Added: vendor/clang/dist/include/clang/Driver/Options.td ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist/include/clang/Driver/Options.td Thu Nov 19 09:00:00 2009 (r199512) @@ -0,0 +1,607 @@ +//===--- DriverOptions.td - Options for clang -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the options accepted by clang. +// +//===----------------------------------------------------------------------===// + +// Include the common option parsing interfaces. +include "OptParser.td" + +///////// +// Groups + +def I_Group : OptionGroup<"<I group>">; +def M_Group : OptionGroup<"<M group>">; +def T_Group : OptionGroup<"<T group>">; +def O_Group : OptionGroup<"<O group>">; +def W_Group : OptionGroup<"<W group>">; +def X_Group : OptionGroup<"<X group>">; +def a_Group : OptionGroup<"<a group>">; +def d_Group : OptionGroup<"<d group>">; +def f_Group : OptionGroup<"<f group>">; +def g_Group : OptionGroup<"<g group>">; +def i_Group : OptionGroup<"<i group>">; +def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>; +def m_Group : OptionGroup<"<m group>">; +def m_x86_Features_Group : OptionGroup<"<m x86 features group>">; +def u_Group : OptionGroup<"<u group>">; + +def pedantic_Group : OptionGroup<"<pedantic group>">; + +// Temporary groups for clang options which we know we don't support, +// but don't want to verbosely warn the user about. +def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">, + Group<f_Group>; +def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">, + Group<m_Group>; + +///////// +// Options + +// The internal option ID must be a valid C++ identifier and results in a +// clang::driver::options::OPT_XX enum constant for XX. +// +// We want to unambiguously be able to refer to options from the driver source +// code, for this reason the option name is mangled into an ID. This mangling +// isn't guaranteed to have an inverse, but for practical purposes it does. +// +// The mangling scheme is to ignore the leading '-', and perform the following +// substitutions: +// _ => __ +// - => _ +// # => _HASH +// , => _COMMA +// = => _EQ +// C++ => CXX + +def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>, + HelpText<"Print the commands to run for this compilation">; +def A : JoinedOrSeparate<"-A">; +def B : JoinedOrSeparate<"-B">, Flags<[Unsupported]>; +def CC : Flag<"-CC">; +def C : Flag<"-C">; +def D : JoinedOrSeparate<"-D">; +def E : Flag<"-E">, Flags<[DriverOption]>, + HelpText<"Only run the preprocessor">; +def F : JoinedOrSeparate<"-F">; +def H : Flag<"-H">; +def I_ : Flag<"-I-">, Group<I_Group>; +def I : JoinedOrSeparate<"-I">, Group<I_Group>; +def L : JoinedOrSeparate<"-L">; +def MD : Flag<"-MD">, Group<M_Group>; +def MF : JoinedOrSeparate<"-MF">, Group<M_Group>; +def MG : Flag<"-MG">, Group<M_Group>; +def MMD : Flag<"-MMD">, Group<M_Group>; +def MM : Flag<"-MM">, Group<M_Group>; +def MP : Flag<"-MP">, Group<M_Group>; +def MQ : JoinedOrSeparate<"-MQ">, Group<M_Group>; +def MT : JoinedOrSeparate<"-MT">, Group<M_Group>; +def Mach : Flag<"-Mach">; +def M : Flag<"-M">, Group<M_Group>; +def O4 : Joined<"-O4">, Group<O_Group>; +def ObjCXX : Flag<"-ObjC++">, Flags<[DriverOption]>, + HelpText<"Treat source input files as Objective-C++ inputs">; +def ObjC : Flag<"-ObjC">, Flags<[DriverOption]>, + HelpText<"Treat source input files as Objective-C inputs">; +def O : Joined<"-O">, Group<O_Group>; +def P : Flag<"-P">; +def Qn : Flag<"-Qn">; +def Qunused_arguments : Flag<"-Qunused-arguments">, Flags<[DriverOption]>, + HelpText<"Don't emit warning for unused driver arguments">; +def Q : Flag<"-Q">; +def R : Flag<"-R">; +def S : Flag<"-S">, Flags<[DriverOption]>, + HelpText<"Only run preprocess and compilation steps">; +def Tbss : JoinedOrSeparate<"-Tbss">, Group<T_Group>; +def Tdata : JoinedOrSeparate<"-Tdata">, Group<T_Group>; +def Ttext : JoinedOrSeparate<"-Ttext">, Group<T_Group>; +def T : JoinedOrSeparate<"-T">, Group<T_Group>; +def U : JoinedOrSeparate<"-U">; +def V : JoinedOrSeparate<"-V">, Flags<[DriverOption, Unsupported]>; +def Wa_COMMA : CommaJoined<"-Wa,">, + HelpText<"Pass the comma separated arguments in <arg> to the assembler">, + MetaVarName<"<arg>">; +def Wall : Flag<"-Wall">, Group<W_Group>; +def Wextra : Flag<"-Wextra">, Group<W_Group>; +def Wl_COMMA : CommaJoined<"-Wl,">, Flags<[LinkerInput, RenderAsInput]>, + HelpText<"Pass the comma separated arguments in <arg> to the linker">, + MetaVarName<"<arg>">; +def Wno_nonportable_cfstrings : Joined<"-Wno-nonportable-cfstrings">, Group<W_Group>; +def Wnonportable_cfstrings : Joined<"-Wnonportable-cfstrings">, Group<W_Group>; +def Wp_COMMA : CommaJoined<"-Wp,">, + HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">, + MetaVarName<"<arg>">; +def W_Joined : Joined<"-W">, Group<W_Group>; +def Xanalyzer : Separate<"-Xanalyzer">, + HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">; +def Xarch__ : JoinedAndSeparate<"-Xarch_">, Flags<[DriverOption]>; +def Xassembler : Separate<"-Xassembler">, + HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">; +def Xclang : Separate<"-Xclang">, + HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">; +def Xlinker : Separate<"-Xlinker">, Flags<[LinkerInput, RenderAsInput]>, + HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">; +def Xpreprocessor : Separate<"-Xpreprocessor">, + HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">; +def X_Flag : Flag<"-X">; +def X_Joined : Joined<"-X">; +def Z_Flag : Flag<"-Z">; +def Z_Joined : Joined<"-Z">; +def all__load : Flag<"-all_load">; +def allowable__client : Separate<"-allowable_client">; +def ansi : Flag<"-ansi">, Group<a_Group>; +def arch__errors__fatal : Flag<"-arch_errors_fatal">; +def arch : Separate<"-arch">, Flags<[DriverOption]>; +def a : Joined<"-a">, Group<a_Group>; +def bind__at__load : Flag<"-bind_at_load">; +def bundle__loader : Separate<"-bundle_loader">; +def bundle : Flag<"-bundle">; +def b : JoinedOrSeparate<"-b">, Flags<[Unsupported]>; +def client__name : JoinedOrSeparate<"-client_name">; +def combine : Flag<"-combine">, Flags<[DriverOption, Unsupported]>; +def compatibility__version : JoinedOrSeparate<"-compatibility_version">; +def coverage : Flag<"-coverage">; +def cpp_precomp : Flag<"-cpp-precomp">; +def current__version : JoinedOrSeparate<"-current_version">; +def c : Flag<"-c">, Flags<[DriverOption]>, + HelpText<"Only run preprocess, compile, and assemble steps">; +def dA : Flag<"-dA">, Group<d_Group>; +def dD : Flag<"-dD">, Group<d_Group>; +def dM : Flag<"-dM">, Group<d_Group>; +def dead__strip : Flag<"-dead_strip">; +def dependency_file : Separate<"-dependency-file">; +def dumpmachine : Flag<"-dumpmachine">, Flags<[Unsupported]>; +def dumpspecs : Flag<"-dumpspecs">, Flags<[Unsupported]>; +def dumpversion : Flag<"-dumpversion">; +def dylib__file : Separate<"-dylib_file">; +def dylinker__install__name : JoinedOrSeparate<"-dylinker_install_name">; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911190900.nAJ900eg099314>