+#include <algorithm>
+#include <iomanip>
+#include <memory>
+using namespace llvm;
+
+// Option for compatibility with AIX, not used but must allow it to be present.
+static cl::opt<bool>
+X32Option ("X32_64", cl::Hidden,
+ cl::desc("Ignored option for compatibility with AIX"));
+
+// llvm-ar operation code and modifier flags. This must come first.
+static cl::opt<std::string>
+Options(cl::Positional, cl::Required, cl::desc("{operation}[modifiers]..."));
+
+// llvm-ar remaining positional arguments.
+static cl::list<std::string>
+RestOfArgs(cl::Positional, cl::OneOrMore,
+ cl::desc("[relpos] [count] <archive-file> [members]..."));
+
+// MoreHelp - Provide additional help output explaining the operations and
+// modifiers of llvm-ar. This object instructs the CommandLine library
+// to print the text of the constructor when the --help option is given.
+static cl::extrahelp MoreHelp(
+ "\nOPERATIONS:\n"
+ " d[NsS] - delete file(s) from the archive\n"
+ " m[abiSs] - move file(s) in the archive\n"
+ " p[kN] - print file(s) found in the archive\n"
+ " q[ufsS] - quick append file(s) to the archive\n"
+ " r[abfiuzRsS] - replace or insert file(s) into the archive\n"
+ " t - display contents of archive\n"
+ " x[No] - extract file(s) from the archive\n"
+ "\nMODIFIERS (operation specific):\n"
+ " [a] - put file(s) after [relpos]\n"
+ " [b] - put file(s) before [relpos] (same as [i])\n"
+ " [f] - truncate inserted file names\n"
+ " [i] - put file(s) before [relpos] (same as [b])\n"
+ " [k] - always print bitcode files (default is to skip them)\n"
+ " [N] - use instance [count] of name\n"
+ " [o] - preserve original dates\n"
+ " [P] - use full path names when matching\n"
+ " [R] - recurse through directories when inserting\n"
+ " [s] - create an archive index (cf. ranlib)\n"
+ " [S] - do not build a symbol table\n"
+ " [u] - update only files newer than archive contents\n"
+ " [z] - compress files before inserting/extracting\n"
+ "\nMODIFIERS (generic):\n"
+ " [c] - do not warn if the library had to be created\n"
+ " [v] - be verbose about actions taken\n"
+ " [V] - be *really* verbose about actions taken\n"
+);
+
+// This enumeration delineates the kinds of operations on an archive
+// that are permitted.
+enum ArchiveOperation {
+ NoOperation, ///< An operation hasn't been specified
+ Print, ///< Print the contents of the archive
+ Delete, ///< Delete the specified members
+ Move, ///< Move members to end or as given by {a,b,i} modifiers
+ QuickAppend, ///< Quickly append to end of archive
+ ReplaceOrInsert, ///< Replace or Insert members
+ DisplayTable, ///< Display the table of contents
+ Extract ///< Extract files back to file system
+};
+
+// Modifiers to follow operation to vary behavior
+bool AddAfter = false; ///< 'a' modifier
+bool AddBefore = false; ///< 'b' modifier
+bool Create = false; ///< 'c' modifier
+bool TruncateNames = false; ///< 'f' modifier
+bool InsertBefore = false; ///< 'i' modifier
+bool DontSkipBitcode = false; ///< 'k' modifier
+bool UseCount = false; ///< 'N' modifier
+bool OriginalDates = false; ///< 'o' modifier
+bool FullPath = false; ///< 'P' modifier
+bool RecurseDirectories = false; ///< 'R' modifier
+bool SymTable = true; ///< 's' & 'S' modifiers
+bool OnlyUpdate = false; ///< 'u' modifier
+bool Verbose = false; ///< 'v' modifier
+bool ReallyVerbose = false; ///< 'V' modifier
+bool Compression = false; ///< 'z' modifier
+
+// Relative Positional Argument (for insert/move). This variable holds
+// the name of the archive member to which the 'a', 'b' or 'i' modifier
+// refers. Only one of 'a', 'b' or 'i' can be specified so we only need
+// one variable.
+std::string RelPos;
+
+// Select which of multiple entries in the archive with the same name should be
+// used (specified with -N) for the delete and extract operations.
+int Count = 1;
+
+// This variable holds the name of the archive file as given on the
+// command line.
+std::string ArchiveName;
+
+// This variable holds the list of member files to proecess, as given
+// on the command line.
+std::vector<std::string> Members;
+
+// This variable holds the (possibly expanded) list of path objects that
+// correspond to files we will
+std::set<sys::Path> Paths;
+
+// The Archive object to which all the editing operations will be sent.
+Archive* TheArchive = 0;
+
+// getRelPos - Extract the member filename from the command line for
+// the [relpos] argument associated with a, b, and i modifiers
+void getRelPos() {
+ if(RestOfArgs.size() > 0) {
+ RelPos = RestOfArgs[0];
+ RestOfArgs.erase(RestOfArgs.begin());
+ }
+ else
+ throw "Expected [relpos] for a, b, or i modifier";