<div dir="ltr">Thank you for reviewing! Addressed in r228717.</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 10, 2015 at 2:24 AM, Jean-Daniel Dupas <span dir="ltr"><<a href="mailto:dev@xenonium.com" target="_blank">dev@xenonium.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I saw it is a common practice to test presence of argument using<br>
<br>
if (parsedArgs->getLastArg(OPT_dll)) {<br>
}<br>
<br>
Is there any reason to prefer the previous form over:<br>
<br>
if (parsedArgs->hasArg(OPT_dll)) {<br>
}<br>
<br>
I find the later clearer as it explicitly express that we just need to now if the arg is present.<br>
<br>
> Le 10 févr. 2015 à 02:10, Rui Ueyama <<a href="mailto:ruiu@google.com">ruiu@google.com</a>> a écrit :<br>
<div class="HOEnZb"><div class="h5">><br>
> Author: ruiu<br>
> Date: Mon Feb  9 19:10:23 2015<br>
> New Revision: 228646<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=228646&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=228646&view=rev</a><br>
> Log:<br>
> Driver: Replace switch cases with ifs.<br>
><br>
> We used to do like this instead of putting all command line processing<br>
> code within one gigantic switch statement. It is converted to a switch<br>
> in r188958, which introduced InputGraph.<br>
><br>
> In this patch I roll that change back. Now all "break"s are removed,<br>
> and the nesting is one level shallow.<br>
><br>
> Modified:<br>
>    lld/trunk/lib/Driver/WinLinkDriver.cpp<br>
><br>
> Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=228646&r1=228645&r2=228646&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=228646&r1=228645&r2=228646&view=diff</a><br>
> ==============================================================================<br>
> --- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)<br>
> +++ lld/trunk/lib/Driver/WinLinkDriver.cpp Mon Feb  9 19:10:23 2015<br>
> @@ -784,6 +784,10 @@ parseArgs(int argc, const char **argv, P<br>
>     diag << "warning: ignoring unknown argument: " << arg << "\n";<br>
>   }<br>
><br>
> +  // Copy mllvm<br>
> +  for (auto arg : parsedArgs->filtered(OPT_mllvm))<br>
> +    ctx.appendLLVMOption(arg->getValue());<br>
> +<br>
>   // If we have expaneded response files and /verbose is given, print out the<br>
>   // final command line.<br>
>   if (!isReadingDirectiveSection && expanded &&<br>
> @@ -936,168 +940,140 @@ bool WinLinkDriver::parse(int argc, cons<br>
><br>
>   // Handle /nodefaultlib:<lib>. The same option without argument is handled in<br>
>   // the following for loop.<br>
> -  for (auto nodeDefaultLib : parsedArgs->filtered(OPT_nodefaultlib)) {<br>
> -    ctx.addNoDefaultLib(nodeDefaultLib->getValue());<br>
> -  }<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_nodefaultlib))<br>
> +    ctx.addNoDefaultLib(arg->getValue());<br>
><br>
>   // Handle /defaultlib. Argument of the option is added to the input file list<br>
>   // unless it's blacklisted by /nodefaultlib.<br>
>   std::vector<StringRef> defaultLibs;<br>
> -  for (auto defaultLib : parsedArgs->filtered(OPT_defaultlib)) {<br>
> -    defaultLibs.push_back(defaultLib->getValue());<br>
> -  }<br>
> -<br>
> -  std::vector<StringRef> inputFiles;<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_defaultlib))<br>
> +    defaultLibs.push_back(arg->getValue());<br>
><br>
> -  // Process all the arguments and create input files<br>
> -  for (auto inputArg : *parsedArgs) {<br>
> -    switch (inputArg->getOption().getID()) {<br>
> -    case OPT_mllvm:<br>
> -      ctx.appendLLVMOption(inputArg->getValue());<br>
> -      break;<br>
> -<br>
> -    case OPT_alternatename: {<br>
> -      StringRef weak, def;<br>
> -      if (!parseAlternateName(inputArg->getValue(), weak, def, diag))<br>
> -        return false;<br>
> -      ctx.setAlternateName(weak, def);<br>
> -      break;<br>
> -    }<br>
> +  // -alternatename:<alias>=<symbol><br>
> +  for (auto *arg : parsedArgs->filtered(OPT_alternatename)) {<br>
> +    StringRef weak, def;<br>
> +    if (!parseAlternateName(arg->getValue(), weak, def, diag))<br>
> +      return false;<br>
> +    ctx.setAlternateName(weak, def);<br>
> +  }<br>
><br>
> -    case OPT_base:<br>
> -      // Parse /base command line option. The argument for the parameter is in<br>
> -      // the form of "<address>[:<size>]".<br>
> +  // Parse /base command line option. The argument for the parameter is in<br>
> +  // the form of "<address>[:<size>]".<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_base)) {<br>
>       uint64_t addr, size;<br>
> -<br>
>       // Size should be set to SizeOfImage field in the COFF header, and if<br>
>       // it's smaller than the actual size, the linker should warn about that.<br>
>       // Currently we just ignore the value of size parameter.<br>
> -      if (!parseMemoryOption(inputArg->getValue(), addr, size))<br>
> +      if (!parseMemoryOption(arg->getValue(), addr, size))<br>
>         return false;<br>
>       ctx.setBaseAddress(addr);<br>
> -      break;<br>
> +  }<br>
><br>
> -    case OPT_dll:<br>
> -      // Parse /dll command line option<br>
> -      ctx.setIsDll(true);<br>
> -      // Default base address of a DLL is 0x10000000.<br>
> -      if (!parsedArgs->getLastArg(OPT_base))<br>
> -        ctx.setBaseAddress(0x10000000);<br>
> -      break;<br>
> +  // Parse /dll command line option<br>
> +  if (parsedArgs->getLastArg(OPT_dll)) {<br>
> +    ctx.setIsDll(true);<br>
> +    // Default base address of a DLL is 0x10000000.<br>
> +    if (!parsedArgs->getLastArg(OPT_base))<br>
> +      ctx.setBaseAddress(0x10000000);<br>
> +  }<br>
><br>
> -    case OPT_stack: {<br>
> -      // Parse /stack command line option<br>
> -      uint64_t reserve;<br>
> -      uint64_t commit = ctx.getStackCommit();<br>
> -      if (!parseMemoryOption(inputArg->getValue(), reserve, commit))<br>
> -        return false;<br>
> -      ctx.setStackReserve(reserve);<br>
> -      ctx.setStackCommit(commit);<br>
> -      break;<br>
> -    }<br>
> +  // Parse /stack command line option<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_stack)) {<br>
> +    uint64_t reserve;<br>
> +    uint64_t commit = ctx.getStackCommit();<br>
> +    if (!parseMemoryOption(arg->getValue(), reserve, commit))<br>
> +      return false;<br>
> +    ctx.setStackReserve(reserve);<br>
> +    ctx.setStackCommit(commit);<br>
> +  }<br>
><br>
> -    case OPT_heap: {<br>
> -      // Parse /heap command line option<br>
> -      uint64_t reserve;<br>
> -      uint64_t commit = ctx.getHeapCommit();<br>
> -      if (!parseMemoryOption(inputArg->getValue(), reserve, commit))<br>
> -        return false;<br>
> -      ctx.setHeapReserve(reserve);<br>
> -      ctx.setHeapCommit(commit);<br>
> -      break;<br>
> -    }<br>
> +  // Parse /heap command line option<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_heap)) {<br>
> +    uint64_t reserve;<br>
> +    uint64_t commit = ctx.getHeapCommit();<br>
> +    if (!parseMemoryOption(arg->getValue(), reserve, commit))<br>
> +      return false;<br>
> +    ctx.setHeapReserve(reserve);<br>
> +    ctx.setHeapCommit(commit);<br>
> +  }<br>
><br>
> -    case OPT_align: {<br>
> -      uint32_t align;<br>
> -      StringRef arg = inputArg->getValue();<br>
> -      if (arg.getAsInteger(10, align)) {<br>
> -        diag << "error: invalid value for /align: " << arg << "\n";<br>
> -        return false;<br>
> -      }<br>
> -      ctx.setSectionDefaultAlignment(align);<br>
> -      break;<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_align)) {<br>
> +    uint32_t align;<br>
> +    StringRef val = arg->getValue();<br>
> +    if (val.getAsInteger(10, align)) {<br>
> +      diag << "error: invalid value for /align: " << val << "\n";<br>
> +      return false;<br>
>     }<br>
> +    ctx.setSectionDefaultAlignment(align);<br>
> +  }<br>
><br>
> -    case OPT_version: {<br>
> -      uint32_t major, minor;<br>
> -      if (!parseVersion(inputArg->getValue(), major, minor))<br>
> -        return false;<br>
> -      ctx.setImageVersion(PECOFFLinkingContext::Version(major, minor));<br>
> -      break;<br>
> -    }<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_version)) {<br>
> +    uint32_t major, minor;<br>
> +    if (!parseVersion(arg->getValue(), major, minor))<br>
> +      return false;<br>
> +    ctx.setImageVersion(PECOFFLinkingContext::Version(major, minor));<br>
> +  }<br>
><br>
> -    case OPT_merge: {<br>
> -      // Parse /merge:<from>=<to>.<br>
> -      StringRef from, to;<br>
> -      std::tie(from, to) = StringRef(inputArg->getValue()).split('=');<br>
> -      if (from.empty() || to.empty()) {<br>
> -        diag << "error: malformed /merge option: " << inputArg->getValue()<br>
> -             << "\n";<br>
> -        return false;<br>
> -      }<br>
> -      if (!ctx.addSectionRenaming(diag, from, to))<br>
> -        return false;<br>
> -      break;<br>
> +  // Parse /merge:<from>=<to>.<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_merge)) {<br>
> +    StringRef from, to;<br>
> +    std::tie(from, to) = StringRef(arg->getValue()).split('=');<br>
> +    if (from.empty() || to.empty()) {<br>
> +      diag << "error: malformed /merge option: " << arg->getValue() << "\n";<br>
> +      return false;<br>
>     }<br>
> +    if (!ctx.addSectionRenaming(diag, from, to))<br>
> +      return false;<br>
> +  }<br>
><br>
> -    case OPT_subsystem: {<br>
> -      // Parse /subsystem:<subsystem>[,<majorOSVersion>[.<minorOSVersion>]].<br>
> -      llvm::COFF::WindowsSubsystem subsystem;<br>
> -      llvm::Optional<uint32_t> major, minor;<br>
> -      if (!parseSubsystem(inputArg->getValue(), subsystem, major, minor, diag))<br>
> -        return false;<br>
> -      ctx.setSubsystem(subsystem);<br>
> -      if (major.hasValue())<br>
> -        ctx.setMinOSVersion(PECOFFLinkingContext::Version(*major, *minor));<br>
> -      break;<br>
> -    }<br>
> +  // Parse /subsystem:<subsystem>[,<majorOSVersion>[.<minorOSVersion>]].<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_subsystem)) {<br>
> +    llvm::COFF::WindowsSubsystem subsystem;<br>
> +    llvm::Optional<uint32_t> major, minor;<br>
> +    if (!parseSubsystem(arg->getValue(), subsystem, major, minor, diag))<br>
> +      return false;<br>
> +    ctx.setSubsystem(subsystem);<br>
> +    if (major.hasValue())<br>
> +      ctx.setMinOSVersion(PECOFFLinkingContext::Version(*major, *minor));<br>
> +  }<br>
><br>
> -    case OPT_section: {<br>
> -      // Parse /section:name,[[!]{DEKPRSW}]<br>
> -      std::string section;<br>
> -      llvm::Optional<uint32_t> flags, mask;<br>
> -      if (!parseSection(inputArg->getValue(), section, flags, mask)) {<br>
> -        diag << "Unknown argument for /section: " << inputArg->getValue()<br>
> -             << "\n";<br>
> -        return false;<br>
> -      }<br>
> -      if (flags.hasValue())<br>
> -        ctx.setSectionSetMask(section, *flags);<br>
> -      if (mask.hasValue())<br>
> -        ctx.setSectionClearMask(section, *mask);<br>
> -      break;<br>
> +  // Parse /section:name,[[!]{DEKPRSW}]<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_section)) {<br>
> +    std::string section;<br>
> +    llvm::Optional<uint32_t> flags, mask;<br>
> +    if (!parseSection(arg->getValue(), section, flags, mask)) {<br>
> +      diag << "Unknown argument for /section: " << arg->getValue() << "\n";<br>
> +      return false;<br>
>     }<br>
> +    if (flags.hasValue())<br>
> +      ctx.setSectionSetMask(section, *flags);<br>
> +    if (mask.hasValue())<br>
> +      ctx.setSectionClearMask(section, *mask);<br>
> +  }<br>
><br>
> -    case OPT_manifest:<br>
> -      // Do nothing. This is default.<br>
> -      break;<br>
> -<br>
> -    case OPT_manifest_colon: {<br>
> -      // Parse /manifest:EMBED[,ID=#]|NO.<br>
> -      bool enable = true;<br>
> -      bool embed = false;<br>
> -      int id = 1;<br>
> -      if (!parseManifest(inputArg->getValue(), enable, embed, id)) {<br>
> -        diag << "Unknown argument for /manifest: " << inputArg->getValue()<br>
> -             << "\n";<br>
> -        return false;<br>
> -      }<br>
> -      ctx.setCreateManifest(enable);<br>
> -      ctx.setEmbedManifest(embed);<br>
> -      ctx.setManifestId(id);<br>
> -      break;<br>
> +  // Parse /manifest:EMBED[,ID=#]|NO.<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_manifest_colon)) {<br>
> +    bool enable = true;<br>
> +    bool embed = false;<br>
> +    int id = 1;<br>
> +    if (!parseManifest(arg->getValue(), enable, embed, id)) {<br>
> +      diag << "Unknown argument for /manifest: " << arg->getValue() << "\n";<br>
> +      return false;<br>
>     }<br>
> +    ctx.setCreateManifest(enable);<br>
> +    ctx.setEmbedManifest(embed);<br>
> +    ctx.setManifestId(id);<br>
> +  }<br>
><br>
> -    case OPT_manifestuac: {<br>
> -      // Parse /manifestuac.<br>
> -      if (StringRef(inputArg->getValue()).equals_lower("no")) {<br>
> -        ctx.setManifestUAC(false);<br>
> -        break;<br>
> -      }<br>
> +  // Parse /manifestuac.<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_manifestuac)) {<br>
> +    if (StringRef(arg->getValue()).equals_lower("no")) {<br>
> +      ctx.setManifestUAC(false);<br>
> +    } else {<br>
>       llvm::Optional<std::string> privilegeLevel;<br>
>       llvm::Optional<std::string> uiAccess;<br>
> -      if (!parseManifestUAC(inputArg->getValue(), privilegeLevel, uiAccess)) {<br>
> -        diag << "Unknown argument for /manifestuac: " << inputArg->getValue()<br>
> +      if (!parseManifestUAC(arg->getValue(), privilegeLevel, uiAccess)) {<br>
> +        diag << "Unknown argument for /manifestuac: " << arg->getValue()<br>
>              << "\n";<br>
>         return false;<br>
>       }<br>
> @@ -1105,231 +1081,197 @@ bool WinLinkDriver::parse(int argc, cons<br>
>         ctx.setManifestLevel(privilegeLevel.getValue());<br>
>       if (uiAccess.hasValue())<br>
>         ctx.setManifestUiAccess(uiAccess.getValue());<br>
> -      break;<br>
>     }<br>
> +  }<br>
><br>
> -    case OPT_manifestfile:<br>
> -      ctx.setManifestOutputPath(ctx.allocate(inputArg->getValue()));<br>
> -      break;<br>
> -<br>
> -    case OPT_manifestdependency:<br>
> -      // /manifestdependency:<string> option. Note that the argument will be<br>
> -      // embedded to the manifest XML file with no error check, for link.exe<br>
> -      // compatibility. We do not gurantete that the resulting XML file is<br>
> -      // valid.<br>
> -      ctx.setManifestDependency(ctx.allocate(inputArg->getValue()));<br>
> -      break;<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_manifestfile))<br>
> +    ctx.setManifestOutputPath(ctx.allocate(arg->getValue()));<br>
><br>
> -    case OPT_failifmismatch:<br>
> -      if (handleFailIfMismatchOption(inputArg->getValue(), failIfMismatchMap,<br>
> -                                     diag))<br>
> -        return false;<br>
> -      break;<br>
> +  // /manifestdependency:<string> option. Note that the argument will be<br>
> +  // embedded to the manifest XML file with no error check, for link.exe<br>
> +  // compatibility. We do not gurantete that the resulting XML file is<br>
> +  // valid.<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_manifestdependency))<br>
> +    ctx.setManifestDependency(ctx.allocate(arg->getValue()));<br>
><br>
> -    case OPT_entry:<br>
> -      ctx.setEntrySymbolName(ctx.allocate(inputArg->getValue()));<br>
> -      break;<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_failifmismatch))<br>
> +    if (handleFailIfMismatchOption(arg->getValue(), failIfMismatchMap, diag))<br>
> +      return false;<br>
><br>
> -    case OPT_export: {<br>
> -      PECOFFLinkingContext::ExportDesc desc;<br>
> -      if (!parseExport(inputArg->getValue(), desc)) {<br>
> -        diag << "Error: malformed /export option: " << inputArg->getValue()<br>
> -             << "\n";<br>
> -        return false;<br>
> -      }<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_entry))<br>
> +    ctx.setEntrySymbolName(ctx.allocate(arg->getValue()));<br>
><br>
> -      // Mangle the symbol name only if it is reading user-supplied command line<br>
> -      // arguments. Because the symbol name in the .drectve section is already<br>
> -      // mangled by the compiler, we shouldn't add a leading underscore in that<br>
> -      // case. It's odd that the command line option has different semantics in<br>
> -      // the .drectve section, but this behavior is needed for compatibility<br>
> -      // with MSVC's link.exe.<br>
> -      if (!isReadingDirectiveSection)<br>
> -        <a href="http://desc.name" target="_blank">desc.name</a> = ctx.decorateSymbol(<a href="http://desc.name" target="_blank">desc.name</a>);<br>
> -      ctx.addDllExport(desc);<br>
> -      break;<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_export)) {<br>
> +    PECOFFLinkingContext::ExportDesc desc;<br>
> +    if (!parseExport(arg->getValue(), desc)) {<br>
> +      diag << "Error: malformed /export option: " << arg->getValue() << "\n";<br>
> +      return false;<br>
>     }<br>
><br>
> -    case OPT_deffile: {<br>
> -      llvm::BumpPtrAllocator alloc;<br>
> -      std::vector<moduledef::Directive *> dirs;<br>
> -      if (!parseDef(inputArg->getValue(), alloc, dirs)) {<br>
> -        diag << "Error: invalid module-definition file\n";<br>
> -        return false;<br>
> -      }<br>
> -      for (moduledef::Directive *dir : dirs) {<br>
> -        if (auto *exp = dyn_cast<moduledef::Exports>(dir)) {<br>
> -          for (PECOFFLinkingContext::ExportDesc desc : exp->getExports()) {<br>
> -            <a href="http://desc.name" target="_blank">desc.name</a> = ctx.decorateSymbol(<a href="http://desc.name" target="_blank">desc.name</a>);<br>
> -            ctx.addDllExport(desc);<br>
> -          }<br>
> -        } else if (auto *hs = dyn_cast<moduledef::Heapsize>(dir)) {<br>
> -          ctx.setHeapReserve(hs->getReserve());<br>
> -          ctx.setHeapCommit(hs->getCommit());<br>
> -        } else if (auto *lib = dyn_cast<moduledef::Library>(dir)) {<br>
> -          ctx.setIsDll(true);<br>
> -          ctx.setOutputPath(ctx.allocate(lib->getName()));<br>
> -          if (lib->getBaseAddress() && !ctx.getBaseAddress())<br>
> -            ctx.setBaseAddress(lib->getBaseAddress());<br>
> -        } else if (auto *name = dyn_cast<moduledef::Name>(dir)) {<br>
> -          if (!name->getOutputPath().empty() && ctx.outputPath().empty())<br>
> -            ctx.setOutputPath(ctx.allocate(name->getOutputPath()));<br>
> -          if (name->getBaseAddress() && ctx.getBaseAddress())<br>
> -            ctx.setBaseAddress(name->getBaseAddress());<br>
> -        } else if (auto *ver = dyn_cast<moduledef::Version>(dir)) {<br>
> -          ctx.setImageVersion(PECOFFLinkingContext::Version(<br>
> -              ver->getMajorVersion(), ver->getMinorVersion()));<br>
> -        } else {<br>
> -          llvm::dbgs() << static_cast<int>(dir->getKind()) << "\n";<br>
> -          llvm_unreachable("Unknown module-definition directive.\n");<br>
> +    // Mangle the symbol name only if it is reading user-supplied command line<br>
> +    // arguments. Because the symbol name in the .drectve section is already<br>
> +    // mangled by the compiler, we shouldn't add a leading underscore in that<br>
> +    // case. It's odd that the command line option has different semantics in<br>
> +    // the .drectve section, but this behavior is needed for compatibility<br>
> +    // with MSVC's link.exe.<br>
> +    if (!isReadingDirectiveSection)<br>
> +      <a href="http://desc.name" target="_blank">desc.name</a> = ctx.decorateSymbol(<a href="http://desc.name" target="_blank">desc.name</a>);<br>
> +    ctx.addDllExport(desc);<br>
> +  }<br>
> +<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_deffile)) {<br>
> +    llvm::BumpPtrAllocator alloc;<br>
> +    std::vector<moduledef::Directive *> dirs;<br>
> +    if (!parseDef(arg->getValue(), alloc, dirs)) {<br>
> +      diag << "Error: invalid module-definition file\n";<br>
> +      return false;<br>
> +    }<br>
> +    for (moduledef::Directive *dir : dirs) {<br>
> +      if (auto *exp = dyn_cast<moduledef::Exports>(dir)) {<br>
> +        for (PECOFFLinkingContext::ExportDesc desc : exp->getExports()) {<br>
> +          <a href="http://desc.name" target="_blank">desc.name</a> = ctx.decorateSymbol(<a href="http://desc.name" target="_blank">desc.name</a>);<br>
> +          ctx.addDllExport(desc);<br>
>         }<br>
> +      } else if (auto *hs = dyn_cast<moduledef::Heapsize>(dir)) {<br>
> +        ctx.setHeapReserve(hs->getReserve());<br>
> +        ctx.setHeapCommit(hs->getCommit());<br>
> +      } else if (auto *lib = dyn_cast<moduledef::Library>(dir)) {<br>
> +        ctx.setIsDll(true);<br>
> +        ctx.setOutputPath(ctx.allocate(lib->getName()));<br>
> +        if (lib->getBaseAddress() && !ctx.getBaseAddress())<br>
> +          ctx.setBaseAddress(lib->getBaseAddress());<br>
> +      } else if (auto *name = dyn_cast<moduledef::Name>(dir)) {<br>
> +        if (!name->getOutputPath().empty() && ctx.outputPath().empty())<br>
> +          ctx.setOutputPath(ctx.allocate(name->getOutputPath()));<br>
> +        if (name->getBaseAddress() && ctx.getBaseAddress())<br>
> +          ctx.setBaseAddress(name->getBaseAddress());<br>
> +      } else if (auto *ver = dyn_cast<moduledef::Version>(dir)) {<br>
> +        ctx.setImageVersion(PECOFFLinkingContext::Version(<br>
> +                              ver->getMajorVersion(), ver->getMinorVersion()));<br>
> +      } else {<br>
> +        llvm::dbgs() << static_cast<int>(dir->getKind()) << "\n";<br>
> +        llvm_unreachable("Unknown module-definition directive.\n");<br>
>       }<br>
>     }<br>
> +  }<br>
><br>
> -    case OPT_libpath:<br>
> -      ctx.appendInputSearchPath(ctx.allocate(inputArg->getValue()));<br>
> -      break;<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_libpath))<br>
> +    ctx.appendInputSearchPath(ctx.allocate(arg->getValue()));<br>
><br>
> -    case OPT_opt: {<br>
> -      StringRef arg = inputArg->getValue();<br>
> -      if (arg.equals_lower("noref")) {<br>
> -        ctx.setDeadStripping(false);<br>
> -        break;<br>
> -      }<br>
> -      if (arg.equals_lower("ref") || arg.equals_lower("icf") ||<br>
> -          arg.equals_lower("noicf") || arg.startswith_lower("icf=") ||<br>
> -          arg.equals_lower("lbr") || arg.equals_lower("nolbr")) {<br>
> -        // Ignore known but unsupported options.<br>
> -        break;<br>
> -      }<br>
> -      diag << "unknown option for /opt: " << arg << "\n";<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_opt)) {<br>
> +    std::string val = StringRef(arg->getValue()).lower();<br>
> +    if (val == "noref") {<br>
> +      ctx.setDeadStripping(false);<br>
> +    } else if (val != "ref" && val != "icf" && val != "noicf" &&<br>
> +            val != "lbr" && val != "nolbr" &&<br>
> +               !StringRef(val).startswith("icf=")) {<br>
> +      diag << "unknown option for /opt: " << val << "\n";<br>
>       return false;<br>
>     }<br>
> +  }<br>
><br>
> -    case OPT_debug:<br>
> -      // LLD is not yet capable of creating a PDB file, so /debug does not have<br>
> -      // any effect.<br>
> -      // TODO: This should disable dead stripping. Currently we can't do that<br>
> -      // because removal of associative sections depends on dead stripping.<br>
> -      ctx.setDebug(true);<br>
> -      break;<br>
> -<br>
> -    case OPT_verbose:<br>
> -      ctx.setLogInputFiles(true);<br>
> -      break;<br>
> -<br>
> -    case OPT_force:<br>
> -    case OPT_force_unresolved:<br>
> -      // /force and /force:unresolved mean the same thing. We do not currently<br>
> -      // support /force:multiple.<br>
> -      ctx.setAllowRemainingUndefines(true);<br>
> -      break;<br>
> -<br>
> -    case OPT_fixed:<br>
> -      // /fixed is not compatible with /dynamicbase. Check for it.<br>
> -      if (parsedArgs->getLastArg(OPT_dynamicbase)) {<br>
> -        diag << "/dynamicbase must not be specified with /fixed\n";<br>
> -        return false;<br>
> -      }<br>
> -      ctx.setBaseRelocationEnabled(false);<br>
> -      ctx.setDynamicBaseEnabled(false);<br>
> -      break;<br>
> -<br>
> -    case OPT_swaprun_cd:<br>
> -      // /swaprun:{cd,net} options set IMAGE_FILE_{REMOVABLE,NET}_RUN_FROM_SWAP<br>
> -      // bits in the COFF header, respectively. If one of the bits is on, the<br>
> -      // Windows loader will copy the entire file to swap area then execute it,<br>
> -      // so that the user can eject a CD or disconnect from the network.<br>
> -      ctx.setSwapRunFromCD(true);<br>
> -      break;<br>
> +  // LLD is not yet capable of creating a PDB file, so /debug does not have<br>
> +  // any effect.<br>
> +  // TODO: This should disable dead stripping. Currently we can't do that<br>
> +  // because removal of associative sections depends on dead stripping.<br>
> +  if (parsedArgs->getLastArg(OPT_debug))<br>
> +    ctx.setDebug(true);<br>
> +<br>
> +  if (parsedArgs->getLastArg(OPT_verbose))<br>
> +    ctx.setLogInputFiles(true);<br>
> +<br>
> +  // /force and /force:unresolved mean the same thing. We do not currently<br>
> +  // support /force:multiple.<br>
> +  if (parsedArgs->getLastArg(OPT_force) ||<br>
> +      parsedArgs->getLastArg(OPT_force_unresolved)) {<br>
> +    ctx.setAllowRemainingUndefines(true);<br>
> +  }<br>
><br>
> -    case OPT_swaprun_net:<br>
> -      ctx.setSwapRunFromNet(true);<br>
> -      break;<br>
> +  if (parsedArgs->getLastArg(OPT_fixed)) {<br>
> +    // /fixed is not compatible with /dynamicbase. Check for it.<br>
> +    if (parsedArgs->getLastArg(OPT_dynamicbase)) {<br>
> +      diag << "/dynamicbase must not be specified with /fixed\n";<br>
> +      return false;<br>
> +    }<br>
> +    ctx.setBaseRelocationEnabled(false);<br>
> +    ctx.setDynamicBaseEnabled(false);<br>
> +  }<br>
><br>
> -    case OPT_profile:<br>
> -      // /profile implies /opt:ref, /opt:noicf, /incremental:no and /fixed:no.<br>
> -      ctx.setDeadStripping(true);<br>
> -      ctx.setBaseRelocationEnabled(true);<br>
> -      ctx.setDynamicBaseEnabled(true);<br>
> -      break;<br>
> +  // /swaprun:{cd,net} options set IMAGE_FILE_{REMOVABLE,NET}_RUN_FROM_SWAP<br>
> +  // bits in the COFF header, respectively. If one of the bits is on, the<br>
> +  // Windows loader will copy the entire file to swap area then execute it,<br>
> +  // so that the user can eject a CD or disconnect from the network.<br>
> +  if (parsedArgs->getLastArg(OPT_swaprun_cd))<br>
> +    ctx.setSwapRunFromCD(true);<br>
> +<br>
> +  if (parsedArgs->getLastArg(OPT_swaprun_net))<br>
> +    ctx.setSwapRunFromNet(true);<br>
> +<br>
> +  if (parsedArgs->getLastArg(OPT_profile)) {<br>
> +    // /profile implies /opt:ref, /opt:noicf, /incremental:no and /fixed:no.<br>
> +    ctx.setDeadStripping(true);<br>
> +    ctx.setBaseRelocationEnabled(true);<br>
> +    ctx.setDynamicBaseEnabled(true);<br>
> +  }<br>
><br>
> -    case OPT_implib:<br>
> -      ctx.setOutputImportLibraryPath(inputArg->getValue());<br>
> -      break;<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_implib))<br>
> +    ctx.setOutputImportLibraryPath(arg->getValue());<br>
><br>
> -    case OPT_delayload:<br>
> -      ctx.addInitialUndefinedSymbol(ctx.getDelayLoadHelperName());<br>
> -      ctx.addDelayLoadDLL(inputArg->getValue());<br>
> -      break;<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_delayload)) {<br>
> +    ctx.addInitialUndefinedSymbol(ctx.getDelayLoadHelperName());<br>
> +    ctx.addDelayLoadDLL(arg->getValue());<br>
> +  }<br>
><br>
> -    case OPT_stub: {<br>
> -      ArrayRef<uint8_t> contents;<br>
> -      if (!readFile(ctx, inputArg->getValue(), contents)) {<br>
> -        diag << "Failed to read DOS stub file " << inputArg->getValue() << "\n";<br>
> -        return false;<br>
> -      }<br>
> -      ctx.setDosStub(contents);<br>
> -      break;<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_stub)) {<br>
> +    ArrayRef<uint8_t> contents;<br>
> +    if (!readFile(ctx, arg->getValue(), contents)) {<br>
> +      diag << "Failed to read DOS stub file " << arg->getValue() << "\n";<br>
> +      return false;<br>
>     }<br>
> +    ctx.setDosStub(contents);<br>
> +  }<br>
><br>
> -    case OPT_incl: {<br>
> -      StringRef sym = ctx.allocate(inputArg->getValue());<br>
> -      if (isReadingDirectiveSection) {<br>
> -        undefinedSymbols->insert(sym);<br>
> -      } else {<br>
> -        ctx.addInitialUndefinedSymbol(sym);<br>
> -      }<br>
> -      break;<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_incl)) {<br>
> +    StringRef sym = ctx.allocate(arg->getValue());<br>
> +    if (isReadingDirectiveSection) {<br>
> +      undefinedSymbols->insert(sym);<br>
> +    } else {<br>
> +      ctx.addInitialUndefinedSymbol(sym);<br>
>     }<br>
> +  }<br>
><br>
> -    case OPT_noentry:<br>
> -      ctx.setHasEntry(false);<br>
> -      break;<br>
> -<br>
> -    case OPT_nodefaultlib_all:<br>
> -      ctx.setNoDefaultLibAll(true);<br>
> -      break;<br>
> -<br>
> -    case OPT_out:<br>
> -      ctx.setOutputPath(ctx.allocate(inputArg->getValue()));<br>
> -      break;<br>
> +  if (parsedArgs->getLastArg(OPT_noentry))<br>
> +    ctx.setHasEntry(false);<br>
><br>
> -    case OPT_INPUT:<br>
> -      inputFiles.push_back(ctx.allocate(inputArg->getValue()));<br>
> -      break;<br>
> +  if (parsedArgs->getLastArg(OPT_nodefaultlib_all))<br>
> +    ctx.setNoDefaultLibAll(true);<br>
><br>
> -    case OPT_pdb:<br>
> -      ctx.setPDBFilePath(inputArg->getValue());<br>
> -      break;<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_out))<br>
> +    ctx.setOutputPath(ctx.allocate(arg->getValue()));<br>
><br>
> -    case OPT_lldmoduledeffile:<br>
> -      ctx.setModuleDefinitionFile(inputArg->getValue());<br>
> -      break;<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_pdb))<br>
> +    ctx.setPDBFilePath(arg->getValue());<br>
><br>
> -#define DEFINE_BOOLEAN_FLAG(name, setter)       \<br>
> -    case OPT_##name:                            \<br>
> -      ctx.setter(true);                         \<br>
> -      break;                                    \<br>
> -    case OPT_##name##_no:                       \<br>
> -      ctx.setter(false);                        \<br>
> -      break<br>
> -<br>
> -    DEFINE_BOOLEAN_FLAG(nxcompat, setNxCompat);<br>
> -    DEFINE_BOOLEAN_FLAG(largeaddressaware, setLargeAddressAware);<br>
> -    DEFINE_BOOLEAN_FLAG(allowbind, setAllowBind);<br>
> -    DEFINE_BOOLEAN_FLAG(allowisolation, setAllowIsolation);<br>
> -    DEFINE_BOOLEAN_FLAG(dynamicbase, setDynamicBaseEnabled);<br>
> -    DEFINE_BOOLEAN_FLAG(tsaware, setTerminalServerAware);<br>
> -    DEFINE_BOOLEAN_FLAG(highentropyva, setHighEntropyVA);<br>
> -    DEFINE_BOOLEAN_FLAG(safeseh, setSafeSEH);<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_lldmoduledeffile))<br>
> +    ctx.setModuleDefinitionFile(arg->getValue());<br>
><br>
> -#undef DEFINE_BOOLEAN_FLAG<br>
> +  std::vector<StringRef> inputFiles;<br>
> +  for (auto *arg : parsedArgs->filtered(OPT_INPUT))<br>
> +    inputFiles.push_back(ctx.allocate(arg->getValue()));<br>
><br>
> -    default:<br>
> -      break;<br>
> -    }<br>
> -  }<br>
> +#define BOOLEAN_FLAG(name, setter) \<br>
> +  if (auto *arg = parsedArgs->getLastArg(OPT_##name, OPT_##name##_no)) \<br>
> +    ctx.setter(arg->getOption().matches(OPT_##name));<br>
> +<br>
> +  BOOLEAN_FLAG(nxcompat, setNxCompat);<br>
> +  BOOLEAN_FLAG(largeaddressaware, setLargeAddressAware);<br>
> +  BOOLEAN_FLAG(allowbind, setAllowBind);<br>
> +  BOOLEAN_FLAG(allowisolation, setAllowIsolation);<br>
> +  BOOLEAN_FLAG(dynamicbase, setDynamicBaseEnabled);<br>
> +  BOOLEAN_FLAG(tsaware, setTerminalServerAware);<br>
> +  BOOLEAN_FLAG(highentropyva, setHighEntropyVA);<br>
> +  BOOLEAN_FLAG(safeseh, setSafeSEH);<br>
> +#undef BOOLEAN_FLAG<br>
><br>
>   // Arguments after "--" are interpreted as filenames even if they<br>
>   // start with a hypen or a slash. This is not compatible with link.exe<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
</div></div></blockquote></div><br></div>