diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h --- a/lld/ELF/Driver.h +++ b/lld/ELF/Driver.h @@ -33,7 +33,7 @@ private: void createFiles(llvm::opt::InputArgList &args); void inferMachineType(); - template void link(llvm::opt::InputArgList &args); + void link(llvm::opt::InputArgList &args); template void compileBitcodeFiles(bool skipLinkedOutput); // True if we are in --whole-archive and --no-whole-archive. diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -553,22 +553,7 @@ // values such as a default image base address. target = getTarget(); - switch (config->ekind) { - case ELF32LEKind: - link(args); - break; - case ELF32BEKind: - link(args); - break; - case ELF64LEKind: - link(args); - break; - case ELF64BEKind: - link(args); - break; - default: - llvm_unreachable("unknown Config->EKind"); - } + link(args); } if (config->timeTraceEnabled) { @@ -2232,7 +2217,7 @@ // Do actual linking. Note that when this function is called, // all linker scripts have already been parsed. -template void LinkerDriver::link(opt::InputArgList &args) { +void LinkerDriver::link(opt::InputArgList &args) { llvm::TimeTraceScope timeScope("Link", StringRef("LinkerDriver::Link")); // If a --hash-style option was not given, set to a default value, // which varies depending on the target. @@ -2400,7 +2385,7 @@ // // With this the symbol table should be complete. After this, no new names // except a few linker-synthesized ones will be added to the symbol table. - compileBitcodeFiles(skipLinkedOutput); + invokeELFT(compileBitcodeFiles, skipLinkedOutput); // Symbol resolution finished. Report backward reference problems. reportBackrefs(); @@ -2441,7 +2426,7 @@ llvm::TimeTraceScope timeScope("Strip sections"); llvm::erase_if(inputSections, [](InputSectionBase *s) { if (s->type == SHT_LLVM_SYMPART) { - readSymbolPartitionSection(s); + invokeELFT(readSymbolPartitionSection, s); return true; } @@ -2508,10 +2493,10 @@ inputSections.push_back(createCommentSection()); // Split SHF_MERGE and .eh_frame sections into pieces in preparation for garbage collection. - splitSections(); + invokeELFT(splitSections); // Garbage collection and removal of shared symbols from unused shared objects. - markLive(); + invokeELFT(markLive); demoteSharedSymbols(); // Make copies of any input sections that need to be copied into each @@ -2520,7 +2505,7 @@ // Create synthesized sections such as .got and .plt. This is called before // processSectionCommands() so that they can be placed by SECTIONS commands. - createSyntheticSections(); + invokeELFT(createSyntheticSections); // Some input sections that are used for exception handling need to be moved // into synthetic sections. Do that now so that they aren't assigned to @@ -2559,8 +2544,8 @@ // Two input sections with different output sections should not be folded. // ICF runs after processSectionCommands() so that we know the output sections. if (config->icf != ICFLevel::None) { - findKeepUniqueSections(args); - doIcf(); + invokeELFT(findKeepUniqueSections, args); + invokeELFT(doIcf); } // Read the callgraph now that we know what was gced or icfed @@ -2568,9 +2553,9 @@ if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file)) if (Optional buffer = readFile(arg->getValue())) readCallGraph(*buffer); - readCallGraphsFromObjectFiles(); + invokeELFT(readCallGraphsFromObjectFiles); } // Write the result to the file. - writeResult(); + invokeELFT(writeResult); } diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -84,22 +84,7 @@ if (!zlib::isAvailable()) error(toString(file) + ": contains a compressed section, " + "but zlib is not available"); - switch (config->ekind) { - case ELF32LEKind: - parseCompressedHeader(); - break; - case ELF32BEKind: - parseCompressedHeader(); - break; - case ELF64LEKind: - parseCompressedHeader(); - break; - case ELF64BEKind: - parseCompressedHeader(); - break; - default: - llvm_unreachable("unknown ELFT"); - } + invokeELFT(parseCompressedHeader); } } diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -298,4 +298,25 @@ } // namespace elf } // namespace lld +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" +#endif +#define invokeELFT(f, ...) \ + switch (config->ekind) { \ + case ELF32LEKind: \ + f(__VA_ARGS__); \ + break; \ + case ELF32BEKind: \ + f(__VA_ARGS__); \ + break; \ + case ELF64LEKind: \ + f(__VA_ARGS__); \ + break; \ + case ELF64BEKind: \ + f(__VA_ARGS__); \ + break; \ + default: \ + llvm_unreachable(""); \ + } + #endif