[lld] r228646 - Driver: Replace switch cases with ifs.

Rui Ueyama ruiu at google.com
Mon Feb 9 17:10:23 PST 2015


Author: ruiu
Date: Mon Feb  9 19:10:23 2015
New Revision: 228646

URL: http://llvm.org/viewvc/llvm-project?rev=228646&view=rev
Log:
Driver: Replace switch cases with ifs.

We used to do like this instead of putting all command line processing
code within one gigantic switch statement. It is converted to a switch
in r188958, which introduced InputGraph.

In this patch I roll that change back. Now all "break"s are removed,
and the nesting is one level shallow.

Modified:
    lld/trunk/lib/Driver/WinLinkDriver.cpp

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





More information about the llvm-commits mailing list