diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-01-14 19:56:06 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-01-14 19:56:06 +0000 |
commit | 58d2a1455eaf2a25cbbbfd698204928abfcc2ab8 (patch) | |
tree | 76057e4ec1b75d230181ddb6c54b4eff5aca6cd6 /gnu/llvm | |
parent | f9281bea671e07297b2f4b4c82b3e0f876fae560 (diff) |
Import LLVM 3.9.1 including clang and lld.
Diffstat (limited to 'gnu/llvm')
-rw-r--r-- | gnu/llvm/include/llvm/Support/CodeGenCWrappers.h | 18 | ||||
-rw-r--r-- | gnu/llvm/include/llvm/Transforms/GCOVProfiler.h | 2 | ||||
-rw-r--r-- | gnu/llvm/include/llvm/Transforms/InstrProfiling.h | 59 | ||||
-rw-r--r-- | gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h | 43 | ||||
-rw-r--r-- | gnu/llvm/include/llvm/Transforms/SampleProfile.h | 21 | ||||
-rw-r--r-- | gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h | 2 | ||||
-rw-r--r-- | gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp | 102 | ||||
-rw-r--r-- | gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp | 13 | ||||
-rw-r--r-- | gnu/llvm/tools/lld/ELF/Strings.cpp | 82 | ||||
-rw-r--r-- | gnu/llvm/tools/lld/ELF/Strings.h | 64 |
10 files changed, 159 insertions, 247 deletions
diff --git a/gnu/llvm/include/llvm/Support/CodeGenCWrappers.h b/gnu/llvm/include/llvm/Support/CodeGenCWrappers.h index 47971e80cef..6db4433a435 100644 --- a/gnu/llvm/include/llvm/Support/CodeGenCWrappers.h +++ b/gnu/llvm/include/llvm/Support/CodeGenCWrappers.h @@ -17,20 +17,17 @@ #define LLVM_SUPPORT_CODEGENCWRAPPERS_H #include "llvm-c/TargetMachine.h" -#include "llvm/ADT/Optional.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" namespace llvm { -inline Optional<CodeModel::Model> unwrap(LLVMCodeModel Model, bool &JIT) { - JIT = false; +inline CodeModel::Model unwrap(LLVMCodeModel Model) { switch (Model) { - case LLVMCodeModelJITDefault: - JIT = true; - LLVM_FALLTHROUGH; case LLVMCodeModelDefault: - return None; + return CodeModel::Default; + case LLVMCodeModelJITDefault: + return CodeModel::JITDefault; case LLVMCodeModelSmall: return CodeModel::Small; case LLVMCodeModelKernel: @@ -40,11 +37,15 @@ inline Optional<CodeModel::Model> unwrap(LLVMCodeModel Model, bool &JIT) { case LLVMCodeModelLarge: return CodeModel::Large; } - return CodeModel::Small; + return CodeModel::Default; } inline LLVMCodeModel wrap(CodeModel::Model Model) { switch (Model) { + case CodeModel::Default: + return LLVMCodeModelDefault; + case CodeModel::JITDefault: + return LLVMCodeModelJITDefault; case CodeModel::Small: return LLVMCodeModelSmall; case CodeModel::Kernel: @@ -60,3 +61,4 @@ inline LLVMCodeModel wrap(CodeModel::Model Model) { } // end llvm namespace #endif + diff --git a/gnu/llvm/include/llvm/Transforms/GCOVProfiler.h b/gnu/llvm/include/llvm/Transforms/GCOVProfiler.h index 66bd75c88e2..f6521901a33 100644 --- a/gnu/llvm/include/llvm/Transforms/GCOVProfiler.h +++ b/gnu/llvm/include/llvm/Transforms/GCOVProfiler.h @@ -21,7 +21,7 @@ namespace llvm { class GCOVProfilerPass : public PassInfoMixin<GCOVProfilerPass> { public: GCOVProfilerPass(const GCOVOptions &Options = GCOVOptions::getDefault()) : GCOVOpts(Options) { } - PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); + PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM); private: GCOVOptions GCOVOpts; diff --git a/gnu/llvm/include/llvm/Transforms/InstrProfiling.h b/gnu/llvm/include/llvm/Transforms/InstrProfiling.h index 0fe6ad5eeac..9ac6d63b96a 100644 --- a/gnu/llvm/include/llvm/Transforms/InstrProfiling.h +++ b/gnu/llvm/include/llvm/Transforms/InstrProfiling.h @@ -1,4 +1,4 @@ -//===- Transforms/InstrProfiling.h - Instrumentation passes -----*- C++ -*-===// +//===- Transforms/InstrProfiling.h - Instrumentation passes ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,72 +14,54 @@ #ifndef LLVM_TRANSFORMS_INSTRPROFILING_H #define LLVM_TRANSFORMS_INSTRPROFILING_H -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/PassManager.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/Transforms/Instrumentation.h" -#include <cstddef> -#include <cstdint> -#include <cstring> -#include <vector> namespace llvm { -class TargetLibraryInfo; -using LoadStorePair = std::pair<Instruction *, Instruction *>; - -/// Instrumentation based profiling lowering pass. This pass lowers +/// Instrumenation based profiling lowering pass. This pass lowers /// the profile instrumented code generated by FE or the IR based /// instrumentation pass. class InstrProfiling : public PassInfoMixin<InstrProfiling> { public: - InstrProfiling() = default; + InstrProfiling() {} InstrProfiling(const InstrProfOptions &Options) : Options(Options) {} - PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); - bool run(Module &M, const TargetLibraryInfo &TLI); + PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM); + bool run(Module &M); private: InstrProfOptions Options; Module *M; - Triple TT; - const TargetLibraryInfo *TLI; struct PerFunctionProfileData { uint32_t NumValueSites[IPVK_Last + 1]; - GlobalVariable *RegionCounters = nullptr; - GlobalVariable *DataVar = nullptr; - - PerFunctionProfileData() { + GlobalVariable *RegionCounters; + GlobalVariable *DataVar; + PerFunctionProfileData() : RegionCounters(nullptr), DataVar(nullptr) { memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last + 1)); } }; DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap; - std::vector<GlobalValue *> UsedVars; + std::vector<Value *> UsedVars; std::vector<GlobalVariable *> ReferencedNames; GlobalVariable *NamesVar; size_t NamesSize; - // vector of counter load/store pairs to be register promoted. - std::vector<LoadStorePair> PromotionCandidates; + bool isMachO() const; - // The start value of precise value profile range for memory intrinsic sizes. - int64_t MemOPSizeRangeStart; - // The end value of precise value profile range for memory intrinsic sizes. - int64_t MemOPSizeRangeLast; + /// Get the section name for the counter variables. + StringRef getCountersSection() const; - int64_t TotalCountersPromoted = 0; + /// Get the section name for the name variables. + StringRef getNameSection() const; - /// Lower instrumentation intrinsics in the function. Returns true if there - /// any lowering. - bool lowerIntrinsics(Function *F); + /// Get the section name for the profile data variables. + StringRef getDataSection() const; - /// Register-promote counter loads and stores in loops. - void promoteCounterLoadStores(Function *F); - - /// Returns true if profile counter update register promotion is enabled. - bool isCounterPromotionEnabled() const; + /// Get the section name for the coverage mapping data. + StringRef getCoverageSection() const; /// Count the number of instrumented value sites for the function. void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins); @@ -119,6 +101,5 @@ private: void emitInitialization(); }; -} // end namespace llvm - -#endif // LLVM_TRANSFORMS_INSTRPROFILING_H +} // End llvm namespace +#endif diff --git a/gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h b/gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h index c2cc76c422d..f6b5639e5aa 100644 --- a/gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h +++ b/gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h @@ -1,4 +1,4 @@ -//===- Transforms/PGOInstrumentation.h - PGO gen/use passes -----*- C++ -*-===// +//===- Transforms/PGOInstrumentation.h - PGO gen/use passes ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,40 +6,31 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// /// \file /// This file provides the interface for IR based instrumentation passes ( /// (profile-gen, and profile-use). -// //===----------------------------------------------------------------------===// #ifndef LLVM_TRANSFORMS_PGOINSTRUMENTATION_H #define LLVM_TRANSFORMS_PGOINSTRUMENTATION_H -#include "llvm/ADT/ArrayRef.h" #include "llvm/IR/PassManager.h" -#include <cstdint> -#include <string> +#include "llvm/Transforms/Instrumentation.h" namespace llvm { -class Function; -class Instruction; -class Module; - /// The instrumentation (profile-instr-gen) pass for IR based PGO. class PGOInstrumentationGen : public PassInfoMixin<PGOInstrumentationGen> { public: - PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); + PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM); }; /// The profile annotation (profile-instr-use) pass for IR based PGO. class PGOInstrumentationUse : public PassInfoMixin<PGOInstrumentationUse> { public: + PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM); PGOInstrumentationUse(std::string Filename = ""); - PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); - private: std::string ProfileFileName; }; @@ -47,29 +38,11 @@ private: /// The indirect function call promotion pass. class PGOIndirectCallPromotion : public PassInfoMixin<PGOIndirectCallPromotion> { public: - PGOIndirectCallPromotion(bool IsInLTO = false, bool SamplePGO = false) - : InLTO(IsInLTO), SamplePGO(SamplePGO) {} - - PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); - + PGOIndirectCallPromotion(bool IsInLTO = false) : InLTO(IsInLTO) {} + PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM); private: bool InLTO; - bool SamplePGO; }; -/// The profile size based optimization pass for memory intrinsics. -class PGOMemOPSizeOpt : public PassInfoMixin<PGOMemOPSizeOpt> { -public: - PGOMemOPSizeOpt() = default; - - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); -}; - -void setProfMetadata(Module *M, Instruction *TI, ArrayRef<uint64_t> EdgeCounts, - uint64_t MaxCount); - -void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count); - -} // end namespace llvm - -#endif // LLVM_TRANSFORMS_PGOINSTRUMENTATION_H +} // End llvm namespace +#endif diff --git a/gnu/llvm/include/llvm/Transforms/SampleProfile.h b/gnu/llvm/include/llvm/Transforms/SampleProfile.h index f5a8590e14a..0fdfa2f85e5 100644 --- a/gnu/llvm/include/llvm/Transforms/SampleProfile.h +++ b/gnu/llvm/include/llvm/Transforms/SampleProfile.h @@ -1,4 +1,4 @@ -//===- Transforms/SampleProfile.h - SamplePGO pass --------------*- C++ -*-===// +//===- Transforms/SampleProfile.h - SamplePGO pass--------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,35 +6,22 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// /// \file /// This file provides the interface for the sampled PGO loader pass. -// //===----------------------------------------------------------------------===// #ifndef LLVM_TRANSFORMS_SAMPLEPROFILE_H #define LLVM_TRANSFORMS_SAMPLEPROFILE_H #include "llvm/IR/PassManager.h" -#include <string> namespace llvm { -class Module; - /// The sample profiler data loader pass. class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> { public: - SampleProfileLoaderPass(std::string File = "", bool IsThinLTOPreLink = false) - : ProfileFileName(File), IsThinLTOPreLink(IsThinLTOPreLink) {} - - PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); - -private: - std::string ProfileFileName; - bool IsThinLTOPreLink; + PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM); }; -} // end namespace llvm - -#endif // LLVM_TRANSFORMS_SAMPLEPROFILE_H +} // End llvm namespace +#endif diff --git a/gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h b/gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h index 3f838611626..ea491dc5058 100644 --- a/gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h +++ b/gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h @@ -24,7 +24,7 @@ namespace llvm { /// This pass removes redundant instructions. class InstSimplifierPass : public PassInfoMixin<InstSimplifierPass> { public: - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM); }; } // end namespace llvm diff --git a/gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp b/gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp index da67c1bcea9..10022ba6068 100644 --- a/gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp +++ b/gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp @@ -1,4 +1,4 @@ -//===- MipsHazardSchedule.cpp - Workaround pipeline hazards ---------------===// +//===-- MipsHazardSchedule.cpp - Workaround pipeline hazards --------------===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// /// \file -/// This pass is used to workaround certain pipeline hazards. For now, this -/// covers compact branch hazards. In future this pass can be extended to other -/// pipeline hazards, such as various MIPS1 hazards, processor errata that -/// require instruction reorganization, etc. +/// This pass is used to workaround certain pipeline hazards. For now, this covers +/// compact branch hazards. In future this pass can be extended to other pipeline +/// hazards, such as various MIPS1 hazards, processor errata that require +/// instruction reorganization, etc. /// /// This pass has to run after the delay slot filler as that pass can introduce /// pipeline hazards, hence the existing hazard recognizer is not suitable. @@ -18,8 +18,8 @@ /// Hazards handled: forbidden slots for MIPSR6. /// /// A forbidden slot hazard occurs when a compact branch instruction is executed -/// and the adjacent instruction in memory is a control transfer instruction -/// such as a branch or jump, ERET, ERETNC, DERET, WAIT and PAUSE. +/// and the adjacent instruction in memory is a control transfer instruction such +/// as a branch or jump, ERET, ERETNC, DERET, WAIT and PAUSE. /// /// For example: /// @@ -36,7 +36,7 @@ /// /// A) A previous pass has created a compact branch directly. /// B) Transforming a delay slot branch into compact branch. This case can be -/// difficult to process as lookahead for hazards is insufficient, as +/// difficult to process as lookahead for hazards is insufficent, as /// backwards delay slot fillling can also produce hazards in previously /// processed instuctions. /// @@ -44,15 +44,15 @@ #include "Mips.h" #include "MipsInstrInfo.h" -#include "MipsSubtarget.h" +#include "MipsSEInstrInfo.h" +#include "MipsTargetMachine.h" #include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include <algorithm> -#include <iterator> -#include <utility> +#include "llvm/IR/Function.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; @@ -62,73 +62,49 @@ STATISTIC(NumInsertedNops, "Number of nops inserted"); namespace { -using Iter = MachineBasicBlock::iterator; -using ReverseIter = MachineBasicBlock::reverse_iterator; +typedef MachineBasicBlock::iterator Iter; +typedef MachineBasicBlock::reverse_iterator ReverseIter; class MipsHazardSchedule : public MachineFunctionPass { + public: MipsHazardSchedule() : MachineFunctionPass(ID) {} - StringRef getPassName() const override { return "Mips Hazard Schedule"; } + const char *getPassName() const override { return "Mips Hazard Schedule"; } bool runOnMachineFunction(MachineFunction &F) override; MachineFunctionProperties getRequiredProperties() const override { return MachineFunctionProperties().set( - MachineFunctionProperties::Property::NoVRegs); + MachineFunctionProperties::Property::AllVRegsAllocated); } private: static char ID; }; -} // end of anonymous namespace - char MipsHazardSchedule::ID = 0; +} // end of anonymous namespace /// Returns a pass that clears pipeline hazards. FunctionPass *llvm::createMipsHazardSchedule() { return new MipsHazardSchedule(); } -// Find the next real instruction from the current position in current basic -// block. -static Iter getNextMachineInstrInBB(Iter Position) { +// Find the next real instruction from the current position. +static Iter getNextMachineInstr(Iter Position) { Iter I = Position, E = Position->getParent()->end(); - I = std::find_if_not(I, E, - [](const Iter &Insn) { return Insn->isTransient(); }); - + I = std::find_if_not(I, E, [](const Iter &Insn) { return Insn->isTransient(); }); + assert(I != E); return I; } -// Find the next real instruction from the current position, looking through -// basic block boundaries. -static std::pair<Iter, bool> getNextMachineInstr(Iter Position, MachineBasicBlock * Parent) { - if (Position == Parent->end()) { - do { - MachineBasicBlock *Succ = Parent->getNextNode(); - if (Succ != nullptr && Parent->isSuccessor(Succ)) { - Position = Succ->begin(); - Parent = Succ; - } else { - return std::make_pair(Position, true); - } - } while (Parent->empty()); - } - - Iter Instr = getNextMachineInstrInBB(Position); - if (Instr == Parent->end()) { - return getNextMachineInstr(Instr, Parent); - } - return std::make_pair(Instr, false); -} - bool MipsHazardSchedule::runOnMachineFunction(MachineFunction &MF) { const MipsSubtarget *STI = &static_cast<const MipsSubtarget &>(MF.getSubtarget()); - // Forbidden slot hazards are only defined for MIPSR6 but not microMIPSR6. + // Forbidden slot hazards are only defined for MIPSR6. if (!STI->hasMips32r6() || STI->inMicroMipsMode()) return false; @@ -142,19 +118,27 @@ bool MipsHazardSchedule::runOnMachineFunction(MachineFunction &MF) { if (!TII->HasForbiddenSlot(*I)) continue; - Iter Inst; - bool LastInstInFunction = - std::next(I) == FI->end() && std::next(FI) == MF.end(); - if (!LastInstInFunction) { - std::pair<Iter, bool> Res = getNextMachineInstr(std::next(I), &*FI); - LastInstInFunction |= Res.second; - Inst = Res.first; + bool InsertNop = false; + // Next instruction in the basic block. + if (std::next(I) != FI->end() && + !TII->SafeInForbiddenSlot(*getNextMachineInstr(std::next(I)))) { + InsertNop = true; + } else { + // Next instruction in the physical successor basic block. + for (auto *Succ : FI->successors()) { + if (FI->isLayoutSuccessor(Succ) && + getNextMachineInstr(Succ->begin()) != Succ->end() && + !TII->SafeInForbiddenSlot(*getNextMachineInstr(Succ->begin()))) { + InsertNop = true; + break; + } + } } - if (LastInstInFunction || !TII->SafeInForbiddenSlot(*Inst)) { + if (InsertNop) { Changed = true; - MIBundleBuilder(&*I) - .append(BuildMI(MF, I->getDebugLoc(), TII->get(Mips::NOP))); + MIBundleBuilder(&*I).append( + BuildMI(MF, I->getDebugLoc(), TII->get(Mips::NOP))); NumInsertedNops++; } } diff --git a/gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp b/gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp index 2921f3ead50..012f63a48ad 100644 --- a/gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp +++ b/gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp @@ -34,11 +34,6 @@ namespace { bool shouldTraversePostOrder() const { return VisitPostOrder; } - bool VisitUnaryOperator(UnaryOperator *Op) { - VisitedNodes.push_back(Op->getOpcodeStr(Op->getOpcode())); - return true; - } - bool VisitBinaryOperator(BinaryOperator *Op) { VisitedNodes.push_back(Op->getOpcodeStr()); return true; @@ -81,7 +76,7 @@ TEST(RecursiveASTVisitor, PostOrderTraversal) { auto ASTUnit = tooling::buildASTFromCode( "class A {" " class B {" - " int foo() { while(4) { int i = 9; int j = -5; } return (1 + 3) + 2; }" + " int foo() { while(4) { int i = 9; } return (1 + 3) + 2; }" " };" "};" ); @@ -91,9 +86,9 @@ TEST(RecursiveASTVisitor, PostOrderTraversal) { RecordingVisitor Visitor(true); Visitor.TraverseTranslationUnitDecl(TU); - std::vector<std::string> expected = {"4", "9", "i", "5", "-", - "j", "1", "3", "+", "2", - "+", "return", "A::B::foo", "A::B", "A"}; + std::vector<std::string> expected = { + "4", "9", "i", "1", "3", "+", "2", "+", "return", "A::B::foo", "A::B", "A" + }; // Compare the list of actually visited nodes // with the expected list of visited nodes. ASSERT_EQ(expected.size(), Visitor.VisitedNodes.size()); diff --git a/gnu/llvm/tools/lld/ELF/Strings.cpp b/gnu/llvm/tools/lld/ELF/Strings.cpp index 0ef33a14bc3..0c21e8819d6 100644 --- a/gnu/llvm/tools/lld/ELF/Strings.cpp +++ b/gnu/llvm/tools/lld/ELF/Strings.cpp @@ -8,36 +8,44 @@ //===----------------------------------------------------------------------===// #include "Strings.h" -#include "Config.h" -#include "lld/Common/ErrorHandler.h" -#include "llvm/ADT/ArrayRef.h" +#include "Error.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" -#include "llvm/Demangle/Demangle.h" +#include "llvm/Config/config.h" #include <algorithm> -#include <cstring> + +#ifdef HAVE_CXXABI_H +#include <cxxabi.h> +#endif using namespace llvm; using namespace lld; using namespace lld::elf; -StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) { - for (StringRef S : Pat) { - Expected<GlobPattern> Pat = GlobPattern::create(S); - if (!Pat) - error(toString(Pat.takeError())); - else - Patterns.push_back(*Pat); +// Returns true if S matches T. S can contain glob meta-characters. +// The asterisk ('*') matches zero or more characters, and the question +// mark ('?') matches one character. +bool elf::globMatch(StringRef S, StringRef T) { + for (;;) { + if (S.empty()) + return T.empty(); + if (S[0] == '*') { + S = S.substr(1); + if (S.empty()) + // Fast path. If a pattern is '*', it matches anything. + return true; + for (size_t I = 0, E = T.size(); I < E; ++I) + if (globMatch(S, T.substr(I))) + return true; + return false; + } + if (T.empty() || (S[0] != T[0] && S[0] != '?')) + return false; + S = S.substr(1); + T = T.substr(1); } } -bool StringMatcher::match(StringRef S) const { - for (const GlobPattern &Pat : Patterns) - if (Pat.match(S)) - return true; - return false; -} - // Converts a hex string (e.g. "deadbeef") to a vector. std::vector<uint8_t> elf::parseHex(StringRef S) { std::vector<uint8_t> Hex; @@ -45,7 +53,7 @@ std::vector<uint8_t> elf::parseHex(StringRef S) { StringRef B = S.substr(0, 2); S = S.substr(2); uint8_t H; - if (!to_integer(B, H, 16)) { + if (B.getAsInteger(16, H)) { error("not a hexadecimal value: " + B); return {}; } @@ -54,9 +62,37 @@ std::vector<uint8_t> elf::parseHex(StringRef S) { return Hex; } +static bool isAlpha(char C) { + return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_'; +} + +static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <= '9'); } + // Returns true if S is valid as a C language identifier. bool elf::isValidCIdentifier(StringRef S) { - return !S.empty() && (isAlpha(S[0]) || S[0] == '_') && - std::all_of(S.begin() + 1, S.end(), - [](char C) { return C == '_' || isAlnum(C); }); + return !S.empty() && isAlpha(S[0]) && + std::all_of(S.begin() + 1, S.end(), isAlnum); +} + +// Returns the demangled C++ symbol name for Name. +std::string elf::demangle(StringRef Name) { +#if !defined(HAVE_CXXABI_H) + return Name; +#else + // __cxa_demangle can be used to demangle strings other than symbol + // names which do not necessarily start with "_Z". Name can be + // either a C or C++ symbol. Don't call __cxa_demangle if the name + // does not look like a C++ symbol name to avoid getting unexpected + // result for a C symbol that happens to match a mangled type name. + if (!Name.startswith("_Z")) + return Name; + + char *Buf = + abi::__cxa_demangle(Name.str().c_str(), nullptr, nullptr, nullptr); + if (!Buf) + return Name; + std::string S(Buf); + free(Buf); + return S; +#endif } diff --git a/gnu/llvm/tools/lld/ELF/Strings.h b/gnu/llvm/tools/lld/ELF/Strings.h index 5009df65f4c..4948e9dbd56 100644 --- a/gnu/llvm/tools/lld/ELF/Strings.h +++ b/gnu/llvm/tools/lld/ELF/Strings.h @@ -7,69 +7,23 @@ // //===----------------------------------------------------------------------===// -#ifndef LLD_ELF_STRINGS_H -#define LLD_ELF_STRINGS_H +#ifndef LLD_COFF_STRINGS_H +#define LLD_COFF_STRINGS_H -#include "lld/Common/LLVM.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/GlobPattern.h" +#include "lld/Core/LLVM.h" #include <vector> namespace lld { namespace elf { - +bool globMatch(StringRef S, StringRef T); std::vector<uint8_t> parseHex(StringRef S); bool isValidCIdentifier(StringRef S); -// This is a lazy version of StringRef. String size is computed lazily -// when it is needed. It is more efficient than StringRef to instantiate -// if you have a string whose size is unknown. -// -// ELF string tables contain a lot of null-terminated strings. -// Most of them are not necessary for the linker because they are names -// of local symbols and the linker doesn't use local symbol names for -// name resolution. So, we use this class to represents strings read -// from string tables. -class StringRefZ { -public: - StringRefZ() : Start(nullptr), Size(0) {} - StringRefZ(const char *S, size_t Size) : Start(S), Size(Size) {} - - /*implicit*/ StringRefZ(const char *S) : Start(S), Size(-1) {} - - /*implicit*/ StringRefZ(llvm::StringRef S) - : Start(S.data()), Size(S.size()) {} - - operator llvm::StringRef() const { - if (Size == (size_t)-1) - Size = strlen(Start); - return {Start, Size}; - } - -private: - const char *Start; - mutable size_t Size; -}; - -// This class represents multiple glob patterns. -class StringMatcher { -public: - StringMatcher() = default; - explicit StringMatcher(ArrayRef<StringRef> Pat); - - bool match(StringRef S) const; - -private: - std::vector<llvm::GlobPattern> Patterns; -}; - -inline ArrayRef<uint8_t> toArrayRef(StringRef S) { - return {(const uint8_t *)S.data(), S.size()}; +// Returns a demangled C++ symbol name. If Name is not a mangled +// name or the system does not provide __cxa_demangle function, +// it returns an unmodified string. +std::string demangle(StringRef Name); +} } -} // namespace elf -} // namespace lld #endif |