diff options
Diffstat (limited to 'gnu')
63 files changed, 1335 insertions, 1688 deletions
diff --git a/gnu/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h b/gnu/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h index 7f57fde638b..165d4bdaa6d 100644 --- a/gnu/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h +++ b/gnu/llvm/include/llvm/Transforms/Utils/OrderedInstructions.h @@ -35,11 +35,6 @@ class OrderedInstructions { /// The dominator tree of the parent function. DominatorTree *DT; - /// Return true if the first instruction comes before the second in the - /// same basic block. It will create an ordered basic block, if it does - /// not yet exist in OBBMap. - bool localDominates(const Instruction *, const Instruction *) const; - public: /// Constructor. OrderedInstructions(DominatorTree *DT) : DT(DT) {} @@ -47,12 +42,6 @@ public: /// Return true if first instruction dominates the second. bool dominates(const Instruction *, const Instruction *) const; - /// Return true if the first instruction comes before the second in the - /// dominator tree DFS traversal if they are in different basic blocks, - /// or if the first instruction comes before the second in the same basic - /// block. - bool dfsBefore(const Instruction *, const Instruction *) const; - /// Invalidate the OrderedBasicBlock cache when its basic block changes. /// i.e. If an instruction is deleted or added to the basic block, the user /// should call this function to invalidate the OrderedBasicBlock cache for diff --git a/gnu/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp b/gnu/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp index 4644ddcf24e..60416f69e13 100644 --- a/gnu/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp +++ b/gnu/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp @@ -9,6 +9,7 @@ #include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" namespace llvm { namespace pdb { diff --git a/gnu/llvm/lib/Target/Nios2/CMakeLists.txt b/gnu/llvm/lib/Target/Nios2/CMakeLists.txt index 6393cc5fcb9..78db452094b 100644 --- a/gnu/llvm/lib/Target/Nios2/CMakeLists.txt +++ b/gnu/llvm/lib/Target/Nios2/CMakeLists.txt @@ -1,30 +1,18 @@ set(LLVM_TARGET_DEFINITIONS Nios2.td) -tablegen(LLVM Nios2GenAsmWriter.inc -gen-asm-writer) -tablegen(LLVM Nios2GenCallingConv.inc -gen-callingconv) -tablegen(LLVM Nios2GenDAGISel.inc -gen-dag-isel) -tablegen(LLVM Nios2GenInstrInfo.inc -gen-instr-info) +#Generate Nios2GenRegisterInfo.inc and Nios2GenInstrInfo.inc which included by +#your hand code C++ files. +#Nios2GenRegisterInfo.inc came from Nios2RegisterInfo.td, Nios2GenInstrInfo.inc +#came from Nios2InstrInfo.td. tablegen(LLVM Nios2GenRegisterInfo.inc -gen-register-info) -tablegen(LLVM Nios2GenSubtargetInfo.inc -gen-subtarget) +tablegen(LLVM Nios2GenInstrInfo.inc -gen-instr-info) +#Nios2CommonTableGen must be defined add_public_tablegen_target(Nios2CommonTableGen) #Nios2CodeGen should match with LLVMBuild.txt Nios2CodeGen -add_llvm_target(Nios2CodeGen - Nios2AsmPrinter.cpp - Nios2FrameLowering.cpp - Nios2InstrInfo.cpp - Nios2ISelDAGToDAG.cpp - Nios2ISelLowering.cpp - Nios2MachineFunction.cpp - Nios2MCInstLower.cpp - Nios2RegisterInfo.cpp - Nios2Subtarget.cpp - Nios2TargetMachine.cpp - Nios2TargetObjectFile.cpp - ) +add_llvm_target(Nios2CodeGen Nios2TargetMachine.cpp) -#Should match with "subdirectories = InstPrinter MCTargetDesc TargetInfo" in LLVMBuild.txt -add_subdirectory(InstPrinter) -add_subdirectory(MCTargetDesc) +#Should match with "subdirectories = MCTargetDesc TargetInfo" in LLVMBuild.txt add_subdirectory(TargetInfo) +add_subdirectory(MCTargetDesc) diff --git a/gnu/llvm/lib/Target/Nios2/LLVMBuild.txt b/gnu/llvm/lib/Target/Nios2/LLVMBuild.txt index 0125bbedea5..b40a7637970 100644 --- a/gnu/llvm/lib/Target/Nios2/LLVMBuild.txt +++ b/gnu/llvm/lib/Target/Nios2/LLVMBuild.txt @@ -19,7 +19,6 @@ [common] subdirectories = - InstPrinter MCTargetDesc TargetInfo @@ -34,7 +33,6 @@ name = Nios2 parent = Target #Whether this target defines an assembly parser, assembly printer, disassembler #, and supports JIT compilation.They are optional. -has_asmprinter = 1 [component_1] #component_1 is a Library type and name is Nios2CodeGen.After build it will @@ -48,14 +46,12 @@ parent = Nios2 #dependencies for this component.When tools are built, the build system will #include the transitive closure of all required_libraries for the components #the tool needs. -required_libraries = AsmPrinter - CodeGen +required_libraries = CodeGen Core GlobalISel MC Nios2Desc Nios2Info - SelectionDAG Support Target #end of required_libraries diff --git a/gnu/llvm/lib/Target/Nios2/MCTargetDesc/CMakeLists.txt b/gnu/llvm/lib/Target/Nios2/MCTargetDesc/CMakeLists.txt index 138832d33ab..21def509a23 100644 --- a/gnu/llvm/lib/Target/Nios2/MCTargetDesc/CMakeLists.txt +++ b/gnu/llvm/lib/Target/Nios2/MCTargetDesc/CMakeLists.txt @@ -1,9 +1,2 @@ #MCTargetDesc / CMakeLists.txt -add_llvm_library(LLVMNios2Desc - Nios2AsmBackend.cpp - Nios2ELFObjectWriter.cpp - Nios2MCAsmInfo.cpp - Nios2MCExpr.cpp - Nios2MCTargetDesc.cpp - Nios2TargetStreamer.cpp) - +add_llvm_library(LLVMNios2Desc Nios2MCTargetDesc.cpp) diff --git a/gnu/llvm/lib/Target/Nios2/MCTargetDesc/LLVMBuild.txt b/gnu/llvm/lib/Target/Nios2/MCTargetDesc/LLVMBuild.txt index 3794c83e504..4dc6995e7f5 100644 --- a/gnu/llvm/lib/Target/Nios2/MCTargetDesc/LLVMBuild.txt +++ b/gnu/llvm/lib/Target/Nios2/MCTargetDesc/LLVMBuild.txt @@ -19,8 +19,7 @@ type = Library name = Nios2Desc parent = Nios2 -required_libraries = MC - Nios2AsmPrinter - Nios2Info +required_libraries = MC + Nios2Info Support add_to_library_groups = Nios2 diff --git a/gnu/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.cpp b/gnu/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.cpp index e57b44d3cfd..d913166399c 100644 --- a/gnu/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.cpp +++ b/gnu/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.cpp @@ -12,91 +12,14 @@ //===----------------------------------------------------------------------===// #include "Nios2MCTargetDesc.h" -#include "InstPrinter/Nios2InstPrinter.h" -#include "Nios2MCAsmInfo.h" -#include "Nios2TargetStreamer.h" #include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Support/TargetRegistry.h" using namespace llvm; #define GET_INSTRINFO_MC_DESC #include "Nios2GenInstrInfo.inc" -#define GET_SUBTARGETINFO_MC_DESC -#include "Nios2GenSubtargetInfo.inc" - #define GET_REGINFO_MC_DESC #include "Nios2GenRegisterInfo.inc" -static MCInstrInfo *createNios2MCInstrInfo() { - MCInstrInfo *X = new MCInstrInfo(); - InitNios2MCInstrInfo(X); // defined in Nios2GenInstrInfo.inc - return X; -} - -static MCRegisterInfo *createNios2MCRegisterInfo(const Triple &TT) { - MCRegisterInfo *X = new MCRegisterInfo(); - InitNios2MCRegisterInfo(X, Nios2::R15); // defined in Nios2GenRegisterInfo.inc - return X; -} - -static MCSubtargetInfo * -createNios2MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { - if (CPU.empty() || CPU == "generic") - CPU = "nios2r1"; - return createNios2MCSubtargetInfoImpl(TT, CPU, FS); - // createNios2MCSubtargetInfoImpl defined in Nios2GenSubtargetInfo.inc -} - -static MCAsmInfo *createNios2MCAsmInfo(const MCRegisterInfo &MRI, - const Triple &TT) { - MCAsmInfo *MAI = new Nios2MCAsmInfo(TT); - - unsigned SP = MRI.getDwarfRegNum(Nios2::SP, true); - MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0); - MAI->addInitialFrameState(Inst); - - return MAI; -} - -static MCInstPrinter *createNios2MCInstPrinter(const Triple &T, - unsigned SyntaxVariant, - const MCAsmInfo &MAI, - const MCInstrInfo &MII, - const MCRegisterInfo &MRI) { - return new Nios2InstPrinter(MAI, MII, MRI); -} - -static MCTargetStreamer *createNios2AsmTargetStreamer(MCStreamer &S, - formatted_raw_ostream &OS, - MCInstPrinter *InstPrint, - bool isVerboseAsm) { - return new Nios2TargetAsmStreamer(S, OS); -} - -extern "C" void LLVMInitializeNios2TargetMC() { - Target *T = &getTheNios2Target(); - - // Register the MC asm info. - RegisterMCAsmInfoFn X(*T, createNios2MCAsmInfo); - - // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(*T, createNios2MCInstrInfo); - - // Register the MC register info. - TargetRegistry::RegisterMCRegInfo(*T, createNios2MCRegisterInfo); - - // Register the asm target streamer. - TargetRegistry::RegisterAsmTargetStreamer(*T, createNios2AsmTargetStreamer); - - // Register the MC subtarget info. - TargetRegistry::RegisterMCSubtargetInfo(*T, createNios2MCSubtargetInfo); - // Register the MCInstPrinter. - TargetRegistry::RegisterMCInstPrinter(*T, createNios2MCInstPrinter); - - // Register the asm backend. - TargetRegistry::RegisterMCAsmBackend(*T, createNios2AsmBackend); -} +extern "C" void LLVMInitializeNios2TargetMC() {} diff --git a/gnu/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.h b/gnu/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.h index a7c4b16c6a3..d426062db16 100644 --- a/gnu/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.h +++ b/gnu/llvm/lib/Target/Nios2/MCTargetDesc/Nios2MCTargetDesc.h @@ -14,27 +14,12 @@ #ifndef LLVM_LIB_TARGET_NIOS2_MCTARGETDESC_NIOS2MCTARGETDESC_H #define LLVM_LIB_TARGET_NIOS2_MCTARGETDESC_NIOS2MCTARGETDESC_H -#include <memory> - namespace llvm { -class MCAsmBackend; -class MCObjectTargetWriter; -class MCRegisterInfo; -class MCSubtargetInfo; -class MCTargetOptions; class Target; class Triple; -class StringRef; -class raw_pwrite_stream; Target &getTheNios2Target(); -MCAsmBackend *createNios2AsmBackend(const Target &T, const MCSubtargetInfo &STI, - const MCRegisterInfo &MRI, - const MCTargetOptions &Options); - -std::unique_ptr<MCObjectTargetWriter> createNios2ELFObjectWriter(uint8_t OSABI); - } // namespace llvm // Defines symbolic names for Nios2 registers. This defines a mapping from @@ -46,7 +31,4 @@ std::unique_ptr<MCObjectTargetWriter> createNios2ELFObjectWriter(uint8_t OSABI); #define GET_INSTRINFO_ENUM #include "Nios2GenInstrInfo.inc" -#define GET_SUBTARGETINFO_ENUM -#include "Nios2GenSubtargetInfo.inc" - #endif diff --git a/gnu/llvm/lib/Target/Nios2/Nios2.h b/gnu/llvm/lib/Target/Nios2/Nios2.h index d6c5c1e4966..87202f48cfb 100644 --- a/gnu/llvm/lib/Target/Nios2/Nios2.h +++ b/gnu/llvm/lib/Target/Nios2/Nios2.h @@ -19,17 +19,7 @@ #include "llvm/Target/TargetMachine.h" namespace llvm { -class FunctionPass; -class formatted_raw_ostream; class Nios2TargetMachine; -class AsmPrinter; -class MachineInstr; -class MCInst; - -FunctionPass *createNios2ISelDag(Nios2TargetMachine &TM, - CodeGenOpt::Level OptLevel); -void LowerNios2MachineInstToMCInst(const MachineInstr *MI, MCInst &OutMI, - AsmPrinter &AP); } // namespace llvm #endif diff --git a/gnu/llvm/lib/Target/Nios2/Nios2.td b/gnu/llvm/lib/Target/Nios2/Nios2.td index 1acf4c70c42..e8abba86337 100644 --- a/gnu/llvm/lib/Target/Nios2/Nios2.td +++ b/gnu/llvm/lib/Target/Nios2/Nios2.td @@ -8,52 +8,22 @@ //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -// Calling Conv, Instruction Descriptions +// Target-independent interfaces //===----------------------------------------------------------------------===// include "llvm/Target/Target.td" -include "Nios2RegisterInfo.td" -include "Nios2Schedule.td" -include "Nios2InstrInfo.td" -include "Nios2CallingConv.td" //===----------------------------------------------------------------------===// -// Nios2 Subtarget features +// Target-dependent interfaces //===----------------------------------------------------------------------===// -def FeatureNios2r1 : SubtargetFeature<"nios2r1", "Nios2ArchVersion", - "Nios2r1", "Nios2 R1 ISA Support">; -def FeatureNios2r2 : SubtargetFeature<"nios2r2", "Nios2ArchVersion", - "Nios2r2", "Nios2 R2 ISA Support">; //===----------------------------------------------------------------------===// -// Nios2 processors supported. +// Calling Conv, Instruction Descriptions //===----------------------------------------------------------------------===// -class Proc<string Name, list<SubtargetFeature> Features> - : Processor<Name, Nios2GenericItineraries, Features>; - -def : Proc<"nios2r1", [FeatureNios2r1]>; -def : Proc<"nios2r2", [FeatureNios2r2]>; +include "Nios2RegisterInfo.td" +include "Nios2InstrInfo.td" def Nios2InstrInfo : InstrInfo; -def Nios2AsmParser : AsmParser { - let ShouldEmitMatchRegisterName = 0; -} - -//===----------------------------------------------------------------------===// -// Declare the target which we are implementing -//===----------------------------------------------------------------------===// - -def Nios2AsmWriter : AsmWriter { - string AsmWriterClassName = "InstPrinter"; - int PassSubtarget = 1; - int Variant = 0; -} - -def Nios2 : Target { -// def Nios2InstrInfo : InstrInfo as before. - let InstructionSet = Nios2InstrInfo; - let AssemblyParsers = [Nios2AsmParser]; - let AssemblyWriters = [Nios2AsmWriter]; -} +def Nios2 : Target { let InstructionSet = Nios2InstrInfo; } diff --git a/gnu/llvm/lib/Target/Nios2/Nios2InstrFormats.td b/gnu/llvm/lib/Target/Nios2/Nios2InstrFormats.td index f57bf03bba3..79868be48a4 100644 --- a/gnu/llvm/lib/Target/Nios2/Nios2InstrFormats.td +++ b/gnu/llvm/lib/Target/Nios2/Nios2InstrFormats.td @@ -16,220 +16,102 @@ // Format specifies the encoding used by the instruction. This is part of the // ad-hoc solution used to emit machine instruction encodings by our machine // code emitter. -class Format<bits<6> val> { - bits<6> Value = val; +class Format<bits<3> val> { + bits<3> Value = val; } -def Pseudo : Format<0>; -// Nios2 R1 instr formats: -def FrmI : Format<1>; -def FrmR : Format<2>; -def FrmJ : Format<3>; -def FrmOther : Format<4>; // Instruction w/ a custom format -// Nios2 R2 instr 32-bit formats: -def FrmL26 : Format<5>; // corresponds to J format in R1 -def FrmF2I16 : Format<6>; // corresponds to I format in R1 -def FrmF2X4I12 : Format<7>; -def FrmF1X4I12 : Format<8>; -def FrmF1X4L17 : Format<9>; -def FrmF3X6L5 : Format<10>; // corresponds to R format in R1 -def FrmF2X6L10 : Format<11>; -def FrmF3X6 : Format<12>; // corresponds to R format in R1 -def FrmF3X8 : Format<13>; // corresponds to custom format in R1 -// Nios2 R2 instr 16-bit formats: -def FrmI10 : Format<14>; -def FrmT1I7 : Format<15>; -def FrmT2I4 : Format<16>; -def FrmT1X1I6 : Format<17>; -def FrmX1I7 : Format<18>; -def FrmL5I4X1 : Format<19>; -def FrmT2X1L3 : Format<20>; -def FrmT2X1I3 : Format<21>; -def FrmT3X1 : Format<22>; -def FrmT2X3 : Format<23>; -def FrmF1X1 : Format<24>; -def FrmX2L5 : Format<25>; -def FrmF1I5 : Format<26>; -def FrmF2 : Format<27>; +def Pseudo : Format<0>; +def FrmI : Format<1>; +def FrmR : Format<2>; +def FrmJ : Format<3>; +def FrmOther : Format<4>; // Instruction w/ a custom format -//===----------------------------------------------------------------------===// -// Instruction Predicates: -//===----------------------------------------------------------------------===// - -def isNios2r1 : Predicate<"Subtarget->isNios2r1()">; -def isNios2r2 : Predicate<"Subtarget->isNios2r2()">; - -class PredicateControl { - // Predicates related to specific target CPU features - list<Predicate> FeaturePredicates = []; - // Predicates for the instruction group membership in given ISA - list<Predicate> InstrPredicates = []; - - list<Predicate> Predicates = !listconcat(FeaturePredicates, InstrPredicates); -} - -//===----------------------------------------------------------------------===// -// Base classes for 32-bit, 16-bit and pseudo instructions -//===----------------------------------------------------------------------===// - -class Nios2Inst32<dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin, Format f>: Instruction, - PredicateControl { +// Generic Nios2 Format +class Nios2Inst<dag outs, dag ins, string asmstr, list<dag> pattern, Format f> + : Instruction { field bits<32> Inst; Format Form = f; let Namespace = "Nios2"; + let Size = 4; bits<6> Opcode = 0; // Bottom 6 bits are the 'opcode' field - let Inst{5-0} = Opcode; + let Inst{5 - 0} = Opcode; let OutOperandList = outs; - let InOperandList = ins; + let InOperandList = ins; let AsmString = asmstr; - let Pattern = pattern; - let Itinerary = itin; + let Pattern = pattern; + // // Attributes specific to Nios2 instructions: + // + bits<3> FormBits = Form.Value; // TSFlags layout should be kept in sync with Nios2InstrInfo.h. - let TSFlags{5-0} = Form.Value; - let DecoderNamespace = "Nios2"; - field bits<32> SoftFail = 0; -} - -class Nios2Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass Itin = IIPseudo>: - Nios2Inst32<outs, ins, asmstr, pattern, Itin, Pseudo> { - - let isCodeGenOnly = 1; - let isPseudo = 1; -} + let TSFlags{2 - 0} = FormBits; -//===----------------------------------------------------------------------===// -// Base classes for R1 and R2 instructions -//===----------------------------------------------------------------------===// - -class Nios2R1Inst32<dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin, Format f>: - Nios2Inst32<outs, ins, asmstr, pattern, itin, f> { let DecoderNamespace = "Nios2"; - let InstrPredicates = [isNios2r1]; } -class Nios2R2Inst32<dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin, Format f>: - Nios2Inst32<outs, ins, asmstr, pattern, itin, f> { - let DecoderNamespace = "Nios2r2"; - let InstrPredicates = [isNios2r2]; +// Nios2 Instruction Format +class InstSE<dag outs, dag ins, string asmstr, list<dag> pattern, Format f> + : Nios2Inst<outs, ins, asmstr, pattern, f> { } //===----------------------------------------------------------------------===// // Format I instruction class in Nios2 : <|A|B|immediate|opcode|> //===----------------------------------------------------------------------===// -class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin>: Nios2R1Inst32<outs, ins, asmstr, - pattern, itin, FrmI> { - - bits<5> rA; - bits<5> rB; +class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSE<outs, ins, asmstr, pattern, FrmI> { + bits<5> rA; + bits<5> rB; bits<16> imm; let Opcode = op; - let Inst{31-27} = rA; - let Inst{26-22} = rB; - let Inst{21-6} = imm; + let Inst{31 - 27} = rA; + let Inst{26 - 22} = rB; + let Inst{21 - 6} = imm; } - //===----------------------------------------------------------------------===// // Format R instruction : <|A|B|C|opx|imm|opcode|> //===----------------------------------------------------------------------===// -class FR<bits<6> opx, dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin>: Nios2R1Inst32<outs, ins, asmstr, - pattern, itin, FrmR> { +class FR<bits<6> opx, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSE<outs, ins, asmstr, pattern, FrmR> { bits<5> rA; bits<5> rB; bits<5> rC; bits<5> imm = 0; - let Opcode = 0x3a; /* opcode is always 0x3a for R instr. */ + // opcode is always 0x3a for R instr. + let Opcode = 0x3a; - let Inst{31-27} = rA; - let Inst{26-22} = rB; - let Inst{21-17} = rC; - let Inst{16-11} = opx; /* opx stands for opcode extension */ - let Inst{10-6} = imm; /* optional 5-bit immediate value */ + let Inst{31 - 27} = rA; + let Inst{26 - 22} = rB; + let Inst{21 - 17} = rC; + // opx stands for opcode extension + let Inst{16 - 11} = opx; + // optional 5-bit immediate value + let Inst{10 - 6} = imm; } //===----------------------------------------------------------------------===// // Format J instruction class in Nios2 : <|address|opcode|> //===----------------------------------------------------------------------===// -class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin>: - Nios2R1Inst32<outs, ins, asmstr, pattern, itin, FrmJ> { +class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSE<outs, ins, asmstr, pattern, FrmJ> { bits<26> addr; - let Opcode = op; - let Inst{31-6} = addr; -} - -//===----------------------------------------------------------------------===// -// Format F3X6 (R2) instruction : <|opx|RSV|C|B|A|opcode|> -//===----------------------------------------------------------------------===// - -class F3X6<bits<6> opx, dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin>: - Nios2R2Inst32<outs, ins, asmstr, pattern, itin, FrmF3X6> { - bits<5> rC; - bits<5> rB; - bits<5> rA; - bits<5> rsv = 0; - - let Opcode = 0x20; /* opcode is always 0x20 (OPX group) for F3X6 instr. */ - - let Inst{31-26} = opx; /* opx stands for opcode extension */ - let Inst{25-21} = rsv; - let Inst{20-16} = rC; - let Inst{15-11} = rB; - let Inst{10-6} = rA; -} - -//===----------------------------------------------------------------------===// -// Multiclasses for common instructions of both R1 and R2: -//===----------------------------------------------------------------------===// -// Multiclass for instructions that have R format in R1 and F3X6 format in R2 -// and their opx values differ between R1 and R2 -multiclass CommonInstr_R_F3X6_opx<bits<6> opxR1, bits<6> opxR2, dag outs, - dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin> { - def NAME#_R1 : FR<opxR1, outs, ins, asmstr, pattern, itin>; - def NAME#_R2 : F3X6<opxR2, outs, ins, asmstr, pattern, itin>; -} + let Opcode = op; -// Multiclass for instructions that have R format in R1 and F3X6 format in R2 -// and their opx values are the same in R1 and R2 -multiclass CommonInstr_R_F3X6<bits<6> opx, dag outs, dag ins, string asmstr, - list<dag> pattern, InstrItinClass itin> : - CommonInstr_R_F3X6_opx<opx, opx, outs, ins, asmstr, pattern, itin>; - -// Multiclass for instructions that have I format in R1 and F2I16 format in R2 -// and their op code values differ between R1 and R2 -multiclass CommonInstr_I_F2I16_op<bits<6> opR1, bits<6> opR2, dag outs, dag ins, - string asmstr, list<dag> pattern, - InstrItinClass itin> { - def NAME#_R1 : FI<opR1, outs, ins, asmstr, pattern, itin>; + let Inst{31 - 6} = addr; } - -// Multiclass for instructions that have I format in R1 and F2I16 format in R2 -// and their op code values are the same in R1 and R2 -multiclass CommonInstr_I_F2I16<bits<6> op, dag outs, dag ins, string asmstr, - list<dag> pattern, InstrItinClass itin> : - CommonInstr_I_F2I16_op<op, op, outs, ins, asmstr, pattern, itin>; diff --git a/gnu/llvm/lib/Target/Nios2/Nios2InstrInfo.td b/gnu/llvm/lib/Target/Nios2/Nios2InstrInfo.td index dee84f74bcb..5e4815ab3e1 100644 --- a/gnu/llvm/lib/Target/Nios2/Nios2InstrInfo.td +++ b/gnu/llvm/lib/Target/Nios2/Nios2InstrInfo.td @@ -17,12 +17,11 @@ include "Nios2InstrFormats.td" - //===----------------------------------------------------------------------===// // Nios2 Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// -def simm16 : Operand<i32> { +def simm16 : Operand<i32> { let DecoderMethod= "DecodeSimm16"; } @@ -30,80 +29,22 @@ def simm16 : Operand<i32> { // e.g. addi, andi def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>; -// Custom return SDNode -def Nios2Ret : SDNode<"Nios2ISD::Ret", SDTNone, - [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; - //===----------------------------------------------------------------------===// // Instructions specific format //===----------------------------------------------------------------------===// -// Arithmetic and logical instructions with 2 registers and 16-bit immediate -// value. -multiclass ArithLogicRegImm16<bits<6> op, string mnemonic, SDNode opNode, - Operand immOp, PatLeaf immType>: - CommonInstr_I_F2I16<op, (outs CPURegs:$rB), - (ins CPURegs:$rA, immOp:$imm), - !strconcat(mnemonic, "\t$rB, $rA, $imm"), - [(set CPURegs:$rB, - (opNode CPURegs:$rA, immType:$imm))], - IIAlu>; - -// Arithmetic and logical instructions with 3 register operands. -// Defines R1 and R2 instruction at the same time. -multiclass ArithLogicReg<bits<6> opx, string mnemonic, - SDNode opNode>: - CommonInstr_R_F3X6<opx, (outs CPURegs:$rC), - (ins CPURegs:$rA, CPURegs:$rB), - !strconcat(mnemonic, "\t$rC, $rA, $rB"), - [(set CPURegs:$rC, (opNode CPURegs:$rA, CPURegs:$rB))], - IIAlu>; - -multiclass Return<bits<6> opx, dag outs, dag ins, string mnemonic> { - let rB = 0, rC = 0, - isReturn = 1, - isCodeGenOnly = 1, - hasCtrlDep = 1, - hasExtraSrcRegAllocReq = 1 in { - defm NAME# : CommonInstr_R_F3X6<opx, outs, ins, mnemonic, [], IIBranch>; - } +// Arithmetic and logical instructions with 2 register operands. +class ArithLogicI<bits<6> op, string instr_asm, SDNode OpNode, + Operand Od, PatLeaf imm_type, RegisterClass RC> : + FI<op, (outs RC:$rB), (ins RC:$rA, Od:$imm16), + !strconcat(instr_asm, "\t$rB, $rA, $imm16"), + [(set RC:$rB, (OpNode RC:$rA, imm_type:$imm16))]> { + let isReMaterializable = 1; } //===----------------------------------------------------------------------===// -// Nios2 Instructions +// Nios2 R1 Instructions //===----------------------------------------------------------------------===// -/// Arithmetic instructions operating on registers. -let isCommutable = 1 , - isReMaterializable = 1 in { - defm ADD : ArithLogicReg<0x31, "add", add>; - defm AND : ArithLogicReg<0x0e, "and", and>; - defm OR : ArithLogicReg<0x16, "or", or>; - defm XOR : ArithLogicReg<0x1e, "xor", xor>; - defm MUL : ArithLogicReg<0x27, "mul", mul>; -} - -let isReMaterializable = 1 in { - defm SUB : ArithLogicReg<0x39, "sub", sub>; -} - -defm DIVU : ArithLogicReg<0x24, "divu", udiv>; -defm DIV : ArithLogicReg<0x25, "div", sdiv>; - -defm SLL : ArithLogicReg<0x13, "sll", shl>; -defm SRL : ArithLogicReg<0x1b, "srl", srl>; -defm SRA : ArithLogicReg<0x3b, "sra", sra>; - /// Arithmetic Instructions (ALU Immediate) -defm ADDI : ArithLogicRegImm16<0x04, "addi", add, simm16, immSExt16>; - -// Returns: -defm RET : Return<0x05, (outs), (ins CPURegs:$rA), "ret">; - -//===----------------------------------------------------------------------===// -// Pseudo instructions -//===----------------------------------------------------------------------===// - -// Return RA. -let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in -def RetRA : Nios2Pseudo<(outs), (ins), "", [(Nios2Ret)]>; +def ADDi : ArithLogicI<0x04, "addi", add, simm16, immSExt16, CPURegs>; diff --git a/gnu/llvm/lib/Target/Nios2/Nios2TargetMachine.cpp b/gnu/llvm/lib/Target/Nios2/Nios2TargetMachine.cpp index b7594dde709..16d4eabcfaf 100644 --- a/gnu/llvm/lib/Target/Nios2/Nios2TargetMachine.cpp +++ b/gnu/llvm/lib/Target/Nios2/Nios2TargetMachine.cpp @@ -13,10 +13,6 @@ #include "Nios2TargetMachine.h" #include "Nios2.h" -#include "Nios2TargetObjectFile.h" - -#include "llvm/CodeGen/TargetPassConfig.h" -#include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -24,96 +20,27 @@ using namespace llvm; extern "C" void LLVMInitializeNios2Target() { // Register the target. - RegisterTargetMachine<Nios2TargetMachine> X(getTheNios2Target()); } -static std::string computeDataLayout() { +static std::string computeDataLayout(const Triple &TT, StringRef CPU, + const TargetOptions &Options) { return "e-p:32:32:32-i8:8:32-i16:16:32-n32"; } -static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { - if (!RM.hasValue()) +static Reloc::Model getEffectiveRelocModel(CodeModel::Model CM, + Optional<Reloc::Model> RM) { + if (!RM.hasValue() || CM == CodeModel::JITDefault) return Reloc::Static; return *RM; } -static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM, - Reloc::Model RM, bool JIT) { - if (CM) - return *CM; - return CodeModel::Small; -} - Nios2TargetMachine::Nios2TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional<Reloc::Model> RM, - Optional<CodeModel::Model> CM, - CodeGenOpt::Level OL, bool JIT) - : LLVMTargetMachine( - T, computeDataLayout(), TT, CPU, FS, Options, - getEffectiveRelocModel(RM), - getEffectiveCodeModel(CM, getEffectiveRelocModel(RM), JIT), OL), - TLOF(make_unique<Nios2TargetObjectFile>()), - Subtarget(TT, CPU, FS, *this) { - initAsmInfo(); -} + CodeModel::Model CM, + CodeGenOpt::Level OL) + : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options), TT, CPU, FS, + Options, getEffectiveRelocModel(CM, RM), CM, OL) {} Nios2TargetMachine::~Nios2TargetMachine() {} - -const Nios2Subtarget * -Nios2TargetMachine::getSubtargetImpl(const Function &F) const { - Attribute CPUAttr = F.getFnAttribute("target-cpu"); - Attribute FSAttr = F.getFnAttribute("target-features"); - - std::string CPU = !CPUAttr.hasAttribute(Attribute::None) - ? CPUAttr.getValueAsString().str() - : TargetCPU; - std::string FS = !FSAttr.hasAttribute(Attribute::None) - ? FSAttr.getValueAsString().str() - : TargetFS; - - auto &I = SubtargetMap[CPU + FS]; - if (!I) { - // This needs to be done before we create a new subtarget since any - // creation will depend on the TM and the code generation flags on the - // function that reside in TargetOptions. - resetTargetOptions(F); - I = llvm::make_unique<Nios2Subtarget>(TargetTriple, CPU, FS, *this); - } - return I.get(); -} - -namespace { -/// Nios2 Code Generator Pass Configuration Options. -class Nios2PassConfig : public TargetPassConfig { -public: - Nios2PassConfig(Nios2TargetMachine &TM, PassManagerBase *PM) - : TargetPassConfig(TM, *PM) {} - - Nios2TargetMachine &getNios2TargetMachine() const { - return getTM<Nios2TargetMachine>(); - } - - void addCodeGenPrepare() override; - bool addInstSelector() override; - void addIRPasses() override; -}; -} // namespace - -TargetPassConfig *Nios2TargetMachine::createPassConfig(PassManagerBase &PM) { - return new Nios2PassConfig(*this, &PM); -} - -void Nios2PassConfig::addCodeGenPrepare() { - TargetPassConfig::addCodeGenPrepare(); -} - -void Nios2PassConfig::addIRPasses() { TargetPassConfig::addIRPasses(); } - -// Install an instruction selector pass using -// the ISelDag to gen Nios2 code. -bool Nios2PassConfig::addInstSelector() { - addPass(createNios2ISelDag(getNios2TargetMachine(), getOptLevel())); - return false; -} diff --git a/gnu/llvm/lib/Target/Nios2/Nios2TargetMachine.h b/gnu/llvm/lib/Target/Nios2/Nios2TargetMachine.h index 1ebfb397383..7f145c82f32 100644 --- a/gnu/llvm/lib/Target/Nios2/Nios2TargetMachine.h +++ b/gnu/llvm/lib/Target/Nios2/Nios2TargetMachine.h @@ -14,31 +14,16 @@ #ifndef LLVM_LIB_TARGET_NIOS2_NIOS2TARGETMACHINE_H #define LLVM_LIB_TARGET_NIOS2_NIOS2TARGETMACHINE_H -#include "Nios2Subtarget.h" #include "llvm/Target/TargetMachine.h" namespace llvm { class Nios2TargetMachine : public LLVMTargetMachine { - mutable StringMap<std::unique_ptr<Nios2Subtarget>> SubtargetMap; - std::unique_ptr<TargetLoweringObjectFile> TLOF; - Nios2Subtarget Subtarget; - public: Nios2TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, - Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM, - CodeGenOpt::Level OL, bool JIT); + Optional<Reloc::Model> RM, CodeModel::Model CM, + CodeGenOpt::Level OL); ~Nios2TargetMachine() override; - - const Nios2Subtarget *getSubtargetImpl() const { return &Subtarget; } - const Nios2Subtarget *getSubtargetImpl(const Function &F) const override; - - TargetLoweringObjectFile *getObjFileLowering() const override { - return TLOF.get(); - } - - // Pass Pipeline Configuration - TargetPassConfig *createPassConfig(PassManagerBase &PM) override; }; } // namespace llvm diff --git a/gnu/llvm/lib/Target/Nios2/TargetInfo/Nios2TargetInfo.cpp b/gnu/llvm/lib/Target/Nios2/TargetInfo/Nios2TargetInfo.cpp index d808a96db77..e317686140f 100644 --- a/gnu/llvm/lib/Target/Nios2/TargetInfo/Nios2TargetInfo.cpp +++ b/gnu/llvm/lib/Target/Nios2/TargetInfo/Nios2TargetInfo.cpp @@ -20,5 +20,5 @@ Target &llvm::getTheNios2Target() { extern "C" void LLVMInitializeNios2TargetInfo() { RegisterTarget<Triple::nios2, /*HasJIT=*/true> - X(getTheNios2Target(), "nios2", "Nios2", "Nios2"); + X(getTheNios2Target(), "nios2", "Nios2"); } diff --git a/gnu/llvm/lib/Transforms/Utils/OrderedInstructions.cpp b/gnu/llvm/lib/Transforms/Utils/OrderedInstructions.cpp index 6d0b96f6aa8..dc780542ce6 100644 --- a/gnu/llvm/lib/Transforms/Utils/OrderedInstructions.cpp +++ b/gnu/llvm/lib/Transforms/Utils/OrderedInstructions.cpp @@ -14,38 +14,19 @@ #include "llvm/Transforms/Utils/OrderedInstructions.h" using namespace llvm; -bool OrderedInstructions::localDominates(const Instruction *InstA, - const Instruction *InstB) const { - assert(InstA->getParent() == InstB->getParent() && - "Instructions must be in the same basic block"); - - const BasicBlock *IBB = InstA->getParent(); - auto OBB = OBBMap.find(IBB); - if (OBB == OBBMap.end()) - OBB = OBBMap.insert({IBB, make_unique<OrderedBasicBlock>(IBB)}).first; - return OBB->second->dominates(InstA, InstB); -} - /// Given 2 instructions, use OrderedBasicBlock to check for dominance relation /// if the instructions are in the same basic block, Otherwise, use dominator /// tree. bool OrderedInstructions::dominates(const Instruction *InstA, const Instruction *InstB) const { + const BasicBlock *IBB = InstA->getParent(); // Use ordered basic block to do dominance check in case the 2 instructions // are in the same basic block. - if (InstA->getParent() == InstB->getParent()) - return localDominates(InstA, InstB); + if (IBB == InstB->getParent()) { + auto OBB = OBBMap.find(IBB); + if (OBB == OBBMap.end()) + OBB = OBBMap.insert({IBB, make_unique<OrderedBasicBlock>(IBB)}).first; + return OBB->second->dominates(InstA, InstB); + } return DT->dominates(InstA->getParent(), InstB->getParent()); } - -bool OrderedInstructions::dfsBefore(const Instruction *InstA, - const Instruction *InstB) const { - // Use ordered basic block in case the 2 instructions are in the same basic - // block. - if (InstA->getParent() == InstB->getParent()) - return localDominates(InstA, InstB); - - DomTreeNode *DA = DT->getNode(InstA->getParent()); - DomTreeNode *DB = DT->getNode(InstB->getParent()); - return DA->getDFSNumIn() < DB->getDFSNumIn(); -} diff --git a/gnu/llvm/tools/clang/lib/Driver/ToolChains/Arch/X86.cpp b/gnu/llvm/tools/clang/lib/Driver/ToolChains/Arch/X86.cpp index 7a4f836d2e1..a85a7f1f637 100644 --- a/gnu/llvm/tools/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/gnu/llvm/tools/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -40,29 +40,26 @@ const char *x86::getX86TargetCPU(const ArgList &Args, return Args.MakeArgString(CPU); } - if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) { - // Mapping built by looking at lib/Basic's X86TargetInfo::initFeatureMap(). + if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) { + // Mapping built by referring to X86TargetInfo::getDefaultFeatures(). StringRef Arch = A->getValue(); - const char *CPU = nullptr; - if (Triple.getArch() == llvm::Triple::x86) { // 32-bit-only /arch: flags. + const char *CPU; + if (Triple.getArch() == llvm::Triple::x86) { CPU = llvm::StringSwitch<const char *>(Arch) .Case("IA32", "i386") .Case("SSE", "pentium3") .Case("SSE2", "pentium4") + .Case("AVX", "sandybridge") + .Case("AVX2", "haswell") .Default(nullptr); - } - if (CPU == nullptr) { // 32-bit and 64-bit /arch: flags. + } else { CPU = llvm::StringSwitch<const char *>(Arch) .Case("AVX", "sandybridge") .Case("AVX2", "haswell") - .Case("AVX512F", "knl") - .Case("AVX512", "skylake-avx512") .Default(nullptr); } - if (CPU) { - A->claim(); + if (CPU) return CPU; - } } // Select the default CPU if none was given (or detection failed). @@ -104,6 +101,8 @@ const char *x86::getX86TargetCPU(const ArgList &Args, return "i486"; case llvm::Triple::Haiku: return "i586"; + case llvm::Triple::Bitrig: + return "i686"; default: // Fallback to p4. return "pentium4"; @@ -144,6 +143,30 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back("+ssse3"); } + // Set features according to the -arch flag on MSVC. + if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) { + StringRef Arch = A->getValue(); + bool ArchUsed = false; + // First, look for flags that are shared in x86 and x86-64. + if (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) { + if (Arch == "AVX" || Arch == "AVX2") { + ArchUsed = true; + Features.push_back(Args.MakeArgString("+" + Arch.lower())); + } + } + // Then, look for x86-specific flags. + if (ArchType == llvm::Triple::x86) { + if (Arch == "IA32") { + ArchUsed = true; + } else if (Arch == "SSE" || Arch == "SSE2") { + ArchUsed = true; + Features.push_back(Args.MakeArgString("+" + Arch.lower())); + } + } + if (!ArchUsed) + D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args); + } + // Now add any that the user explicitly requested on the command line, // which may override the defaults. handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group); diff --git a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp index 19c1d077afa..decc552e121 100644 --- a/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ b/gnu/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp @@ -46,7 +46,7 @@ class MisusedMovedObjectChecker : public Checker<check::PreCall, check::PostCall, check::EndFunction, check::DeadSymbols, check::RegionChanges> { public: - void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; + void checkEndFunction(CheckerContext &C) const; void checkPreCall(const CallEvent &MC, CheckerContext &C) const; void checkPostCall(const CallEvent &MC, CheckerContext &C) const; void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; @@ -56,12 +56,9 @@ public: ArrayRef<const MemRegion *> ExplicitRegions, ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call) const; - void printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const override; private: - enum MisuseKind {MK_FunCall, MK_Copy, MK_Move}; - class MovedBugVisitor : public BugReporterVisitor { + class MovedBugVisitor : public BugReporterVisitorImpl<MovedBugVisitor> { public: MovedBugVisitor(const MemRegion *R) : Region(R), Found(false) {} @@ -84,7 +81,7 @@ private: mutable std::unique_ptr<BugType> BT; ExplodedNode *reportBug(const MemRegion *Region, const CallEvent &Call, - CheckerContext &C, MisuseKind MK) const; + CheckerContext &C, bool isCopy) const; bool isInMoveSafeContext(const LocationContext *LC) const; bool isStateResetMethod(const CXXMethodDecl *MethodDec) const; bool isMoveSafeMethod(const CXXMethodDecl *MethodDec) const; @@ -101,6 +98,8 @@ static ProgramStateRef removeFromState(ProgramStateRef State, const MemRegion *Region) { if (!Region) return State; + // Note: The isSubRegionOf function is not reflexive. + State = State->remove<TrackedRegionMap>(Region); for (auto &E : State->get<TrackedRegionMap>()) { if (E.first->isSubRegionOf(Region)) State = State->remove<TrackedRegionMap>(E.first); @@ -178,7 +177,7 @@ const ExplodedNode *MisusedMovedObjectChecker::getMoveLocation( ExplodedNode *MisusedMovedObjectChecker::reportBug(const MemRegion *Region, const CallEvent &Call, CheckerContext &C, - MisuseKind MK) const { + bool isCopy = false) const { if (ExplodedNode *N = C.generateNonFatalErrorNode()) { if (!BT) BT.reset(new BugType(this, "Usage of a 'moved-from' object", @@ -194,17 +193,10 @@ ExplodedNode *MisusedMovedObjectChecker::reportBug(const MemRegion *Region, // Creating the error message. std::string ErrorMessage; - switch(MK) { - case MK_FunCall: - ErrorMessage = "Method call on a 'moved-from' object"; - break; - case MK_Copy: - ErrorMessage = "Copying a 'moved-from' object"; - break; - case MK_Move: - ErrorMessage = "Moving a 'moved-from' object"; - break; - } + if (isCopy) + ErrorMessage = "Copying a 'moved-from' object"; + else + ErrorMessage = "Method call on a 'moved-from' object"; if (const auto DecReg = Region->getAs<DeclRegion>()) { const auto *RegionDecl = dyn_cast<NamedDecl>(DecReg->getDecl()); ErrorMessage += " '" + RegionDecl->getNameAsString() + "'"; @@ -222,8 +214,7 @@ ExplodedNode *MisusedMovedObjectChecker::reportBug(const MemRegion *Region, // Removing the function parameters' MemRegion from the state. This is needed // for PODs where the trivial destructor does not even created nor executed. -void MisusedMovedObjectChecker::checkEndFunction(const ReturnStmt *RS, - CheckerContext &C) const { +void MisusedMovedObjectChecker::checkEndFunction(CheckerContext &C) const { auto State = C.getState(); TrackedRegionMapTy Objects = State->get<TrackedRegionMap>(); if (Objects.isEmpty()) @@ -359,7 +350,7 @@ void MisusedMovedObjectChecker::checkPreCall(const CallEvent &Call, const LocationContext *LC = C.getLocationContext(); ExplodedNode *N = nullptr; - // Remove the MemRegions from the map on which a ctor/dtor call or assignment + // Remove the MemRegions from the map on which a ctor/dtor call or assignement // happened. // Checking constructor calls. @@ -372,10 +363,7 @@ void MisusedMovedObjectChecker::checkPreCall(const CallEvent &Call, const RegionState *ArgState = State->get<TrackedRegionMap>(ArgRegion); if (ArgState && ArgState->isMoved()) { if (!isInMoveSafeContext(LC)) { - if(CtorDec->isMoveConstructor()) - N = reportBug(ArgRegion, Call, C, MK_Move); - else - N = reportBug(ArgRegion, Call, C, MK_Copy); + N = reportBug(ArgRegion, Call, C, /*isCopy=*/true); State = State->set<TrackedRegionMap>(ArgRegion, RegionState::getReported()); } @@ -390,11 +378,8 @@ void MisusedMovedObjectChecker::checkPreCall(const CallEvent &Call, return; // In case of destructor call we do not track the object anymore. const MemRegion *ThisRegion = IC->getCXXThisVal().getAsRegion(); - if (!ThisRegion) - return; - if (dyn_cast_or_null<CXXDestructorDecl>(Call.getDecl())) { - State = removeFromState(State, ThisRegion); + State = removeFromState(State, IC->getCXXThisVal().getAsRegion()); C.addTransition(State); return; } @@ -415,10 +400,7 @@ void MisusedMovedObjectChecker::checkPreCall(const CallEvent &Call, State->get<TrackedRegionMap>(IC->getArgSVal(0).getAsRegion()); if (ArgState && ArgState->isMoved() && !isInMoveSafeContext(LC)) { const MemRegion *ArgRegion = IC->getArgSVal(0).getAsRegion(); - if(MethodDecl->isMoveAssignmentOperator()) - N = reportBug(ArgRegion, Call, C, MK_Move); - else - N = reportBug(ArgRegion, Call, C, MK_Copy); + N = reportBug(ArgRegion, Call, C, /*isCopy=*/true); State = State->set<TrackedRegionMap>(ArgRegion, RegionState::getReported()); } @@ -428,35 +410,28 @@ void MisusedMovedObjectChecker::checkPreCall(const CallEvent &Call, } // The remaining part is check only for method call on a moved-from object. - - // We want to investigate the whole object, not only sub-object of a parent - // class in which the encountered method defined. - while (const CXXBaseObjectRegion *BR = - dyn_cast<CXXBaseObjectRegion>(ThisRegion)) - ThisRegion = BR->getSuperRegion(); - if (isMoveSafeMethod(MethodDecl)) return; if (isStateResetMethod(MethodDecl)) { - State = removeFromState(State, ThisRegion); + State = State->remove<TrackedRegionMap>(ThisRegion); C.addTransition(State); return; } - // If it is already reported then we don't report the bug again. + // If it is already reported then we dont report the bug again. const RegionState *ThisState = State->get<TrackedRegionMap>(ThisRegion); if (!(ThisState && ThisState->isMoved())) return; - // Don't report it in case if any base region is already reported + // Dont report it in case if any base region is already reported if (isAnyBaseRegionReported(State, ThisRegion)) return; if (isInMoveSafeContext(LC)) return; - N = reportBug(ThisRegion, Call, C, MK_FunCall); + N = reportBug(ThisRegion, Call, C); State = State->set<TrackedRegionMap>(ThisRegion, RegionState::getReported()); C.addTransition(State, N); } @@ -501,25 +476,6 @@ ProgramStateRef MisusedMovedObjectChecker::checkRegionChanges( return State; } -void MisusedMovedObjectChecker::printState(raw_ostream &Out, - ProgramStateRef State, - const char *NL, - const char *Sep) const { - - TrackedRegionMapTy RS = State->get<TrackedRegionMap>(); - - if (!RS.isEmpty()) { - Out << Sep << "Moved-from objects :" << NL; - for (auto I: RS) { - I.first->dumpToStream(Out); - if (I.second.isMoved()) - Out << ": moved"; - else - Out << ": moved and reported"; - Out << NL; - } - } -} void ento::registerMisusedMovedObjectChecker(CheckerManager &mgr) { mgr.registerChecker<MisusedMovedObjectChecker>(); } diff --git a/gnu/llvm/tools/lldb/include/lldb/Core/Broadcaster.h b/gnu/llvm/tools/lldb/include/lldb/Core/Broadcaster.h index 4851007c9a2..825287db598 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Core/Broadcaster.h +++ b/gnu/llvm/tools/lldb/include/lldb/Core/Broadcaster.h @@ -59,9 +59,10 @@ public: uint32_t GetEventBits() const { return m_event_bits; } - // Tell whether this BroadcastEventSpec is contained in in_spec. That is: (a) - // the two spec's share the same broadcaster class (b) the event bits of this - // spec are wholly contained in those of in_spec. + // Tell whether this BroadcastEventSpec is contained in in_spec. + // That is: + // (a) the two spec's share the same broadcaster class + // (b) the event bits of this spec are wholly contained in those of in_spec. bool IsContainedIn(BroadcastEventSpec in_spec) const { if (m_broadcaster_class != in_spec.GetBroadcasterClass()) return false; @@ -223,21 +224,21 @@ private: }; //---------------------------------------------------------------------- -/// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h" An event -/// broadcasting class. +/// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h" +/// @brief An event broadcasting class. /// -/// The Broadcaster class is designed to be subclassed by objects that wish to -/// vend events in a multi-threaded environment. Broadcaster objects can each -/// vend 32 events. Each event is represented by a bit in a 32 bit value and -/// these bits can be set: +/// The Broadcaster class is designed to be subclassed by objects that +/// wish to vend events in a multi-threaded environment. Broadcaster +/// objects can each vend 32 events. Each event is represented by a bit +/// in a 32 bit value and these bits can be set: /// @see Broadcaster::SetEventBits(uint32_t) /// or cleared: /// @see Broadcaster::ResetEventBits(uint32_t) -/// When an event gets set the Broadcaster object will notify the Listener -/// object that is listening for the event (if there is one). +/// When an event gets set the Broadcaster object will notify the +/// Listener object that is listening for the event (if there is one). /// -/// Subclasses should provide broadcast bit definitions for any events they -/// vend, typically using an enumeration: +/// Subclasses should provide broadcast bit definitions for any events +/// they vend, typically using an enumeration: /// \code /// class Foo : public Broadcaster /// { @@ -323,11 +324,12 @@ public: //------------------------------------------------------------------ /// Listen for any events specified by \a event_mask. /// - /// Only one listener can listen to each event bit in a given Broadcaster. - /// Once a listener has acquired an event bit, no other broadcaster will - /// have access to it until it is relinquished by the first listener that - /// gets it. The actual event bits that get acquired by \a listener may be - /// different from what is requested in \a event_mask, and to track this the + /// Only one listener can listen to each event bit in a given + /// Broadcaster. Once a listener has acquired an event bit, no + /// other broadcaster will have access to it until it is + /// relinquished by the first listener that gets it. The actual + /// event bits that get acquired by \a listener may be different + /// from what is requested in \a event_mask, and to track this the /// actual event bits that are acquired get returned. /// /// @param[in] listener @@ -347,7 +349,8 @@ public: } //------------------------------------------------------------------ - /// Get the NULL terminated C string name of this Broadcaster object. + /// Get the NULL terminated C string name of this Broadcaster + /// object. /// /// @return /// The NULL terminated C string name of this Broadcaster. @@ -392,10 +395,10 @@ public: } //------------------------------------------------------------------ - /// Removes a Listener from this broadcasters list and frees the event bits - /// specified by \a event_mask that were previously acquired by \a listener - /// (assuming \a listener was listening to this object) for other listener - /// objects to use. + /// Removes a Listener from this broadcasters list and frees the + /// event bits specified by \a event_mask that were previously + /// acquired by \a listener (assuming \a listener was listening to + /// this object) for other listener objects to use. /// /// @param[in] listener /// A Listener object that previously called AddListener. @@ -417,9 +420,10 @@ public: //------------------------------------------------------------------ /// Provides a simple mechanism to temporarily redirect events from /// broadcaster. When you call this function passing in a listener and - /// event type mask, all events from the broadcaster matching the mask will - /// now go to the hijacking listener. Only one hijack can occur at a time. - /// If we need more than this we will have to implement a Listener stack. + /// event type mask, all events from the broadcaster matching the mask + /// will now go to the hijacking listener. + /// Only one hijack can occur at a time. If we need more than this we + /// will have to implement a Listener stack. /// /// @param[in] listener /// A Listener object. You do not need to call StartListeningForEvents @@ -450,7 +454,8 @@ public: void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); } // This needs to be filled in if you are going to register the broadcaster - // with the broadcaster manager and do broadcaster class matching. + // with the broadcaster + // manager and do broadcaster class matching. // FIXME: Probably should make a ManagedBroadcaster subclass with all the bits // needed to work // with the BroadcasterManager, so that it is clearer how to add one. @@ -460,17 +465,21 @@ public: protected: // BroadcasterImpl contains the actual Broadcaster implementation. The - // Broadcaster makes a BroadcasterImpl which lives as long as it does. The - // Listeners & the Events hold a weak pointer to the BroadcasterImpl, so that - // they can survive if a Broadcaster they were listening to is destroyed w/o - // their being able to unregister from it (which can happen if the - // Broadcasters & Listeners are being destroyed on separate threads - // simultaneously. The Broadcaster itself can't be shared out as a weak - // pointer, because some things that are broadcasters (e.g. the Target and - // the Process) are shared in their own right. + // Broadcaster makes a BroadcasterImpl + // which lives as long as it does. The Listeners & the Events hold a weak + // pointer to the BroadcasterImpl, + // so that they can survive if a Broadcaster they were listening to is + // destroyed w/o their being able to + // unregister from it (which can happen if the Broadcasters & Listeners are + // being destroyed on separate threads + // simultaneously. + // The Broadcaster itself can't be shared out as a weak pointer, because some + // things that are broadcasters + // (e.g. the Target and the Process) are shared in their own right. // // For the most part, the Broadcaster functions dispatch to the - // BroadcasterImpl, and are documented in the public Broadcaster API above. + // BroadcasterImpl, and are documented in the + // public Broadcaster API above. class BroadcasterImpl { friend class Listener; @@ -548,7 +557,7 @@ protected: llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4> GetListeners(); - Broadcaster &m_broadcaster; ///< The broadcaster that this implements + Broadcaster &m_broadcaster; ///< The broadcsater that this implements event_names_map m_event_names; ///< Optionally define event names for ///readability and logging for each event bit collection m_listeners; ///< A list of Listener / event_mask pairs that are diff --git a/gnu/llvm/tools/lldb/include/lldb/Core/Event.h b/gnu/llvm/tools/lldb/include/lldb/Core/Event.h index fa301705767..f4c7f4769a3 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Core/Event.h +++ b/gnu/llvm/tools/lldb/include/lldb/Core/Event.h @@ -121,8 +121,10 @@ public: const ConstString &GetFlavor() const override { return GetFlavorString(); } - bool WaitForEventReceived(const Timeout<std::micro> &timeout = llvm::None) { - return m_predicate.WaitForValueEqualTo(true, timeout); + bool WaitForEventReceived( + const std::chrono::microseconds &abstime = std::chrono::microseconds(0), + bool *timed_out = nullptr) { + return m_predicate.WaitForValueEqualTo(true, abstime, timed_out); } private: diff --git a/gnu/llvm/tools/lldb/include/lldb/Core/RegisterValue.h b/gnu/llvm/tools/lldb/include/lldb/Core/RegisterValue.h index b369c3dff9a..a45db00fb76 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Core/RegisterValue.h +++ b/gnu/llvm/tools/lldb/include/lldb/Core/RegisterValue.h @@ -35,7 +35,7 @@ namespace lldb_private { class RegisterValue { public: - enum { kMaxRegisterByteSize = 64u }; + enum { kMaxRegisterByteSize = 32u }; enum Type { eTypeInvalid, @@ -95,13 +95,14 @@ public: bool GetData(DataExtractor &data) const; - // Copy the register value from this object into a buffer in "dst" and obey - // the "dst_byte_order" when copying the data. Also watch out in case - // "dst_len" is longer or shorter than the register value described by - // "reg_info" and only copy the least significant bytes of the register - // value, or pad the destination with zeroes if the register byte size is - // shorter that "dst_len" (all while correctly abiding the "dst_byte_order"). - // Returns the number of bytes copied into "dst". + // Copy the register value from this object into a buffer in "dst" + // and obey the "dst_byte_order" when copying the data. Also watch out + // in case "dst_len" is longer or shorter than the register value + // described by "reg_info" and only copy the least significant bytes + // of the register value, or pad the destination with zeroes if the + // register byte size is shorter that "dst_len" (all while correctly + // abiding the "dst_byte_order"). Returns the number of bytes copied + // into "dst". uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const; @@ -248,6 +249,12 @@ public: Status SetValueFromData(const RegisterInfo *reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok); + // The default value of 0 for reg_name_right_align_at means no alignment at + // all. + bool Dump(Stream *s, const RegisterInfo *reg_info, bool prefix_with_name, + bool prefix_with_alt_name, lldb::Format format, + uint32_t reg_name_right_align_at = 0) const; + const void *GetBytes() const; lldb::ByteOrder GetByteOrder() const { diff --git a/gnu/llvm/tools/lldb/include/lldb/Core/Scalar.h b/gnu/llvm/tools/lldb/include/lldb/Core/Scalar.h index 40671a242ec..943398b8802 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Core/Scalar.h +++ b/gnu/llvm/tools/lldb/include/lldb/Core/Scalar.h @@ -36,9 +36,9 @@ namespace lldb_private { //---------------------------------------------------------------------- // A class designed to hold onto values and their corresponding types. -// Operators are defined and Scalar objects will correctly promote their types -// and values before performing these operations. Type promotion currently -// follows the ANSI C type promotion rules. +// Operators are defined and Scalar objects will correctly promote +// their types and values before performing these operations. Type +// promotion currently follows the ANSI C type promotion rules. //---------------------------------------------------------------------- class Scalar { public: @@ -50,13 +50,13 @@ public: e_ulong, e_slonglong, e_ulonglong, - e_sint128, - e_uint128, - e_sint256, - e_uint256, e_float, e_double, - e_long_double + e_long_double, + e_uint128, + e_sint128, + e_uint256, + e_sint256 }; //------------------------------------------------------------------ @@ -165,6 +165,8 @@ public: bool Promote(Scalar::Type type); + bool Cast(Scalar::Type type); + bool MakeSigned(); bool MakeUnsigned(); @@ -180,10 +182,10 @@ public: static Scalar::Type GetValueTypeForFloatWithByteSize(size_t byte_size); //---------------------------------------------------------------------- - // All operators can benefits from the implicit conversions that will happen - // automagically by the compiler, so no temporary objects will need to be - // created. As a result, we currently don't need a variety of overloaded set - // value accessors. + // All operators can benefits from the implicit conversions that will + // happen automagically by the compiler, so no temporary objects will + // need to be created. As a result, we currently don't need a variety of + // overloaded set value accessors. //---------------------------------------------------------------------- Scalar &operator=(const int i); Scalar &operator=(unsigned int v); @@ -202,27 +204,27 @@ public: Scalar &operator&=(const Scalar &rhs); //---------------------------------------------------------------------- - // Shifts the current value to the right without maintaining the current sign - // of the value (if it is signed). + // Shifts the current value to the right without maintaining the current + // sign of the value (if it is signed). //---------------------------------------------------------------------- bool ShiftRightLogical(const Scalar &rhs); // Returns true on success //---------------------------------------------------------------------- - // Takes the absolute value of the current value if it is signed, else the - // value remains unchanged. Returns false if the contained value has a void - // type. + // Takes the absolute value of the current value if it is signed, else + // the value remains unchanged. + // Returns false if the contained value has a void type. //---------------------------------------------------------------------- bool AbsoluteValue(); // Returns true on success //---------------------------------------------------------------------- - // Negates the current value (even for unsigned values). Returns false if the - // contained value has a void type. + // Negates the current value (even for unsigned values). + // Returns false if the contained value has a void type. //---------------------------------------------------------------------- bool UnaryNegate(); // Returns true on success //---------------------------------------------------------------------- - // Inverts all bits in the current value as long as it isn't void or a - // float/double/long double type. Returns false if the contained value has a - // void/float/double/long double type, else the value is inverted and true is - // returned. + // Inverts all bits in the current value as long as it isn't void or + // a float/double/long double type. + // Returns false if the contained value has a void/float/double/long + // double type, else the value is inverted and true is returned. //---------------------------------------------------------------------- bool OnesComplement(); // Returns true on success @@ -232,9 +234,9 @@ public: Scalar::Type GetType() const { return m_type; } //---------------------------------------------------------------------- - // Returns a casted value of the current contained data without modifying the - // current value. FAIL_VALUE will be returned if the type of the value is - // void or invalid. + // Returns a casted value of the current contained data without + // modifying the current value. FAIL_VALUE will be returned if the type + // of the value is void or invalid. //---------------------------------------------------------------------- int SInt(int fail_value = 0) const; @@ -342,8 +344,8 @@ private: }; //---------------------------------------------------------------------- -// Split out the operators into a format where the compiler will be able to -// implicitly convert numbers into Scalar objects. +// Split out the operators into a format where the compiler will be able +// to implicitly convert numbers into Scalar objects. // // This allows code like: // Scalar two(2); diff --git a/gnu/llvm/tools/lldb/include/lldb/Host/Predicate.h b/gnu/llvm/tools/lldb/include/lldb/Host/Predicate.h index d8128e71c53..3ee27e74b4b 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Host/Predicate.h +++ b/gnu/llvm/tools/lldb/include/lldb/Host/Predicate.h @@ -20,7 +20,6 @@ // Other libraries and framework includes // Project includes -#include "lldb/Utility/Timeout.h" #include "lldb/lldb-defines.h" //#define DB_PTHREAD_LOG_EVENTS @@ -39,8 +38,8 @@ typedef enum { //---------------------------------------------------------------------- /// @class Predicate Predicate.h "lldb/Host/Predicate.h" -/// A C++ wrapper class for providing threaded access to a value of -/// type T. +/// @brief A C++ wrapper class for providing threaded access to a value +/// of type T. /// /// A templatized class that provides multi-threaded access to a value /// of type T. Threads can efficiently wait for bits within T to be set @@ -119,39 +118,169 @@ public: } //------------------------------------------------------------------ - /// Wait for Cond(m_value) to be true. + /// Set some bits in \a m_value. /// - /// Waits in a thread safe way for Cond(m_value) to be true. If Cond(m_value) - /// is already true, this function will return without waiting. + /// Logically set the bits \a bits in the contained \a m_value in a + /// thread safe way and broadcast if needed. /// - /// It is possible for the value to be changed between the time the value is - /// set and the time the waiting thread wakes up. If the value no longer - /// satisfies the condition when the waiting thread wakes up, it will go back - /// into a wait state. It may be necessary for the calling code to use - /// additional thread synchronization methods to detect transitory states. + /// @param[in] bits + /// The bits to set in \a m_value. /// - /// @param[in] Cond - /// The condition we want \a m_value satisfy. + /// @param[in] broadcast_type + /// A value indicating when and if to broadcast. See the + /// PredicateBroadcastType enumeration for details. + /// + /// @see Predicate::Broadcast() + //------------------------------------------------------------------ + void SetValueBits(T bits, PredicateBroadcastType broadcast_type) { + std::lock_guard<std::mutex> guard(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x, broadcast_type = %i)\n", __FUNCTION__, bits, + broadcast_type); +#endif + const T old_value = m_value; + m_value |= bits; + + Broadcast(old_value, broadcast_type); + } + + //------------------------------------------------------------------ + /// Reset some bits in \a m_value. + /// + /// Logically reset (clear) the bits \a bits in the contained + /// \a m_value in a thread safe way and broadcast if needed. + /// + /// @param[in] bits + /// The bits to clear in \a m_value. + /// + /// @param[in] broadcast_type + /// A value indicating when and if to broadcast. See the + /// PredicateBroadcastType enumeration for details. + /// + /// @see Predicate::Broadcast() + //------------------------------------------------------------------ + void ResetValueBits(T bits, PredicateBroadcastType broadcast_type) { + std::lock_guard<std::mutex> guard(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x, broadcast_type = %i)\n", __FUNCTION__, bits, + broadcast_type); +#endif + const T old_value = m_value; + m_value &= ~bits; + + Broadcast(old_value, broadcast_type); + } + + //------------------------------------------------------------------ + /// Wait for bits to be set in \a m_value. + /// + /// Waits in a thread safe way for any bits in \a bits to get + /// logically set in \a m_value. If any bits are already set in + /// \a m_value, this function will return without waiting. + /// + /// It is possible for the value to be changed between the time + /// the bits are set and the time the waiting thread wakes up. + /// If the bits are no longer set when the waiting thread wakes + /// up, it will go back into a wait state. It may be necessary + /// for the calling code to use additional thread synchronization + /// methods to detect transitory states. + /// + /// @param[in] bits + /// The bits we are waiting to be set in \a m_value. + /// + /// @param[in] abstime + /// If non-nullptr, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. + /// + /// @return + /// Any bits of the requested bits that actually were set within + /// the time specified. Zero if a timeout or unrecoverable error + /// occurred. + //------------------------------------------------------------------ + T WaitForSetValueBits(T bits, const std::chrono::microseconds &timeout = + std::chrono::microseconds(0)) { + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (std::lock_guard) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. + std::unique_lock<std::mutex> lock(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x, timeout = %llu), m_value = 0x%8.8x\n", + __FUNCTION__, bits, timeout.count(), m_value); +#endif + while ((m_value & bits) == 0) { + if (timeout == std::chrono::microseconds(0)) { + m_condition.wait(lock); + } else { + std::cv_status result = m_condition.wait_for(lock, timeout); + if (result == std::cv_status::timeout) + break; + } + } +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x), m_value = 0x%8.8x, returning 0x%8.8x\n", + __FUNCTION__, bits, m_value, m_value & bits); +#endif + + return m_value & bits; + } + + //------------------------------------------------------------------ + /// Wait for bits to be reset in \a m_value. + /// + /// Waits in a thread safe way for any bits in \a bits to get + /// logically reset in \a m_value. If all bits are already reset in + /// \a m_value, this function will return without waiting. + /// + /// It is possible for the value to be changed between the time + /// the bits are reset and the time the waiting thread wakes up. + /// If the bits are no set when the waiting thread wakes up, it will + /// go back into a wait state. It may be necessary for the calling + /// code to use additional thread synchronization methods to detect + /// transitory states. + /// + /// @param[in] bits + /// The bits we are waiting to be reset in \a m_value. /// - /// @param[in] timeout - /// How long to wait for the condition to hold. + /// @param[in] abstime + /// If non-nullptr, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. /// /// @return - /// @li m_value if Cond(m_value) is true. - /// @li None otherwise (timeout occurred). + /// Zero on successful waits, or non-zero if a timeout or + /// unrecoverable error occurs. //------------------------------------------------------------------ - template <typename C> - llvm::Optional<T> WaitFor(C Cond, const Timeout<std::micro> &timeout) { + T WaitForResetValueBits(T bits, const std::chrono::microseconds &timeout = + std::chrono::microseconds(0)) { + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (std::lock_guard) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. std::unique_lock<std::mutex> lock(m_mutex); - auto RealCond = [&] { return Cond(m_value); }; - if (!timeout) { - m_condition.wait(lock, RealCond); - return m_value; + +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x, timeout = %llu), m_value = 0x%8.8x\n", + __FUNCTION__, bits, timeout.count(), m_value); +#endif + while ((m_value & bits) != 0) { + if (timeout == std::chrono::microseconds(0)) { + m_condition.wait(lock); + } else { + std::cv_status result = m_condition.wait_for(lock, timeout); + if (result == std::cv_status::timeout) + break; + } } - if (m_condition.wait_for(lock, *timeout, RealCond)) - return m_value; - return llvm::None; + +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x), m_value = 0x%8.8x, returning 0x%8.8x\n", + __FUNCTION__, bits, m_value, m_value & bits); +#endif + return m_value & bits; } + //------------------------------------------------------------------ /// Wait for \a m_value to be equal to \a value. /// @@ -169,17 +298,124 @@ public: /// @param[in] value /// The value we want \a m_value to be equal to. /// - /// @param[in] timeout - /// How long to wait for the condition to hold. + /// @param[in] abstime + /// If non-nullptr, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. + /// + /// @param[out] timed_out + /// If not null, set to true if we return because of a time out, + /// and false if the value was set. /// /// @return /// @li \b true if the \a m_value is equal to \a value - /// @li \b false otherwise (timeout occurred) + /// @li \b false otherwise //------------------------------------------------------------------ - bool WaitForValueEqualTo(T value, - const Timeout<std::micro> &timeout = llvm::None) { - return WaitFor([&value](T current) { return value == current; }, timeout) != - llvm::None; + bool WaitForValueEqualTo(T value, const std::chrono::microseconds &timeout = + std::chrono::microseconds(0), + bool *timed_out = nullptr) { + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (std::lock_guard) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. + std::unique_lock<std::mutex> lock(m_mutex); + +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (value = 0x%8.8x, timeout = %llu), m_value = 0x%8.8x\n", + __FUNCTION__, value, timeout.count(), m_value); +#endif + if (timed_out) + *timed_out = false; + + while (m_value != value) { + if (timeout == std::chrono::microseconds(0)) { + m_condition.wait(lock); + } else { + std::cv_status result = m_condition.wait_for(lock, timeout); + if (result == std::cv_status::timeout) { + if (timed_out) + *timed_out = true; + break; + } + } + } + + return m_value == value; + } + + //------------------------------------------------------------------ + /// Wait for \a m_value to be equal to \a value and then set it to + /// a new value. + /// + /// Waits in a thread safe way for \a m_value to be equal to \a + /// value and then sets \a m_value to \a new_value. If \a m_value + /// is already equal to \a value, this function will immediately + /// set \a m_value to \a new_value and return without waiting. + /// + /// It is possible for the value to be changed between the time + /// the value is set and the time the waiting thread wakes up. + /// If the value no longer matches the requested value when the + /// waiting thread wakes up, it will go back into a wait state. It + /// may be necessary for the calling code to use additional thread + /// synchronization methods to detect transitory states. + /// + /// @param[in] value + /// The value we want \a m_value to be equal to. + /// + /// @param[in] new_value + /// The value to which \a m_value will be set if \b true is + /// returned. + /// + /// @param[in] abstime + /// If non-nullptr, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. + /// + /// @param[out] timed_out + /// If not null, set to true if we return because of a time out, + /// and false if the value was set. + /// + /// @return + /// @li \b true if the \a m_value became equal to \a value + /// @li \b false otherwise + //------------------------------------------------------------------ + bool WaitForValueEqualToAndSetValueTo( + T wait_value, T new_value, + const std::chrono::microseconds &timeout = std::chrono::microseconds(0), + bool *timed_out = nullptr) { + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (std::lock_guard) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. + std::unique_lock<std::mutex> lock(m_mutex); + +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (wait_value = 0x%8.8x, new_value = 0x%8.8x, timeout = %llu), " + "m_value = 0x%8.8x\n", + __FUNCTION__, wait_value, new_value, timeout.count(), m_value); +#endif + if (timed_out) + *timed_out = false; + + while (m_value != wait_value) { + if (timeout == std::chrono::microseconds(0)) { + m_condition.wait(lock); + } else { + std::cv_status result = m_condition.wait_for(lock, timeout); + if (result == std::cv_status::timeout) { + if (timed_out) + *timed_out = true; + break; + } + } + } + + if (m_value == wait_value) { + m_value = new_value; + return true; + } + + return false; } //------------------------------------------------------------------ @@ -199,23 +435,51 @@ public: /// @param[in] value /// The value we want \a m_value to not be equal to. /// - /// @param[in] timeout - /// How long to wait for the condition to hold. + /// @param[out] new_value + /// The new value if \b true is returned. + /// + /// @param[in] abstime + /// If non-nullptr, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. /// /// @return - /// @li m_value if m_value != value - /// @li None otherwise (timeout occurred). + /// @li \b true if the \a m_value is equal to \a value + /// @li \b false otherwise //------------------------------------------------------------------ - llvm::Optional<T> - WaitForValueNotEqualTo(T value, - const Timeout<std::micro> &timeout = llvm::None) { - return WaitFor([&value](T current) { return value != current; }, timeout); + bool WaitForValueNotEqualTo( + T value, T &new_value, + const std::chrono::microseconds &timeout = std::chrono::microseconds(0)) { + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (std::lock_guard) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. + std::unique_lock<std::mutex> lock(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (value = 0x%8.8x, timeout = %llu), m_value = 0x%8.8x\n", + __FUNCTION__, value, timeout.count(), m_value); +#endif + while (m_value == value) { + if (timeout == std::chrono::microseconds(0)) { + m_condition.wait(lock); + } else { + std::cv_status result = m_condition.wait_for(lock, timeout); + if (result == std::cv_status::timeout) + break; + } + } + + if (m_value != value) { + new_value = m_value; + return true; + } + return false; } protected: //---------------------------------------------------------------------- - // pthread condition and mutex variable to control access and allow blocking - // between the main thread and the spotlight index thread. + // pthread condition and mutex variable to control access and allow + // blocking between the main thread and the spotlight index thread. //---------------------------------------------------------------------- T m_value; ///< The templatized value T that we are protecting access to mutable std::mutex m_mutex; ///< The mutex to use when accessing the data diff --git a/gnu/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpoint.h b/gnu/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpoint.h index 681570aadef..73639d64c9e 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpoint.h +++ b/gnu/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpoint.h @@ -45,8 +45,8 @@ protected: private: bool m_enabled; - // ----------------------------------------------------------- interface for - // NativeBreakpointList + // ----------------------------------------------------------- + // interface for NativeBreakpointList // ----------------------------------------------------------- void AddRef(); int32_t DecRef(); diff --git a/gnu/llvm/tools/lldb/include/lldb/Symbol/GoASTContext.h b/gnu/llvm/tools/lldb/include/lldb/Symbol/GoASTContext.h index 29c8cdceacf..6feac7abf16 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Symbol/GoASTContext.h +++ b/gnu/llvm/tools/lldb/include/lldb/Symbol/GoASTContext.h @@ -216,7 +216,8 @@ public: CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; // Returns -1 if this isn't a function of if the function doesn't have a - // prototype Returns a value >= 0 if there is a prototype. + // prototype + // Returns a value >= 0 if there is a prototype. int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, @@ -293,8 +294,8 @@ public: bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags) override; - // Lookup a child given a name. This function will match base class names and - // member member names in "clang_type" only, not descendants. + // Lookup a child given a name. This function will match base class names + // and member member names in "clang_type" only, not descendants. uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) override; @@ -314,6 +315,12 @@ public: return 0; } + CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx, + lldb::TemplateArgumentKind &kind) override { + return CompilerType(); + } + //---------------------------------------------------------------------- // Dumping types //---------------------------------------------------------------------- @@ -346,8 +353,8 @@ public: Stream *s, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size) override; - // Converts "s" to a floating point value and place resulting floating point - // bytes in the "dst" buffer. + // Converts "s" to a floating point value and place resulting floating + // point bytes in the "dst" buffer. size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size) override; diff --git a/gnu/llvm/tools/lldb/include/lldb/Symbol/JavaASTContext.h b/gnu/llvm/tools/lldb/include/lldb/Symbol/JavaASTContext.h index 41a881dcf4e..4fdd2371b67 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Symbol/JavaASTContext.h +++ b/gnu/llvm/tools/lldb/include/lldb/Symbol/JavaASTContext.h @@ -203,6 +203,10 @@ public: size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; + CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx, + lldb::TemplateArgumentKind &kind) override; + int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, diff --git a/gnu/llvm/tools/lldb/include/lldb/Symbol/OCamlASTContext.h b/gnu/llvm/tools/lldb/include/lldb/Symbol/OCamlASTContext.h index 7144886e1c7..a261d43519e 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Symbol/OCamlASTContext.h +++ b/gnu/llvm/tools/lldb/include/lldb/Symbol/OCamlASTContext.h @@ -231,6 +231,12 @@ public: return 0; } + CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx, + lldb::TemplateArgumentKind &kind) override { + return CompilerType(); + } + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, diff --git a/gnu/llvm/tools/lldb/include/lldb/Utility/SafeMachO.h b/gnu/llvm/tools/lldb/include/lldb/Utility/SafeMachO.h index 1565b313f42..791410a38b3 100644 --- a/gnu/llvm/tools/lldb/include/lldb/Utility/SafeMachO.h +++ b/gnu/llvm/tools/lldb/include/lldb/Utility/SafeMachO.h @@ -9,15 +9,18 @@ #ifndef liblldb_SafeMachO_h_ #define liblldb_SafeMachO_h_ -// This header file is required to work around collisions between the defines -// in mach/machine.h, and enum members of the same name in llvm's MachO.h. If -// you want to use llvm/Support/MachO.h, use this file instead. The caveats -// are: 1) You can only use the MachO.h enums, you can't use the defines. That -// won't make a difference since the values +// This header file is required to work around collisions between the defines in +// mach/machine.h, and enum members +// of the same name in llvm's MachO.h. If you want to use llvm/Support/MachO.h, +// use this file instead. +// The caveats are: +// 1) You can only use the MachO.h enums, you can't use the defines. That won't +// make a difference since the values // are the same. // 2) If you need any header file that relies on mach/machine.h, you must -// include that first. 3) This isn't a total solution, it doesn't undef every -// define that MachO.h has borrowed from various system headers, +// include that first. +// 3) This isn't a total solution, it doesn't undef every define that MachO.h +// has borrowed from various system headers, // only the ones that come from mach/machine.h because that is the one we // ended up pulling in from various places. // diff --git a/gnu/llvm/tools/lldb/lit/Unit/lit.cfg b/gnu/llvm/tools/lldb/lit/Unit/lit.cfg index 338adfd7bd9..7dfb344e6fa 100644 --- a/gnu/llvm/tools/lldb/lit/Unit/lit.cfg +++ b/gnu/llvm/tools/lldb/lit/Unit/lit.cfg @@ -6,6 +6,19 @@ import os import lit.formats +# Check that the object root is known. +if config.test_exec_root is None: + # Otherwise, we haven't loaded the site specific configuration (the user is + # probably trying to run on a test file directly, and either the site + # configuration hasn't been created by the build system, or we are in an + # out-of-tree build situation). + + # Check for 'llvm_unit_site_config' user parameter, and use that if available. + site_cfg = lit_config.params.get('lldb_unit_site_config', None) + if site_cfg and os.path.exists(site_cfg): + lit_config.load_config(config, site_cfg) + raise SystemExit + # name: The name of this test suite. config.name = 'lldb-Unit' @@ -18,4 +31,6 @@ config.test_source_root = os.path.join(config.lldb_obj_root, 'unittests') config.test_exec_root = config.test_source_root # testFormat: The test format to use to interpret tests. +if not hasattr(config, 'llvm_build_mode'): + lit_config.fatal("unable to find llvm_build_mode value on config") config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests') diff --git a/gnu/llvm/tools/lldb/lit/lit.cfg b/gnu/llvm/tools/lldb/lit/lit.cfg index 98d69bb4c81..8dea61b2716 100644 --- a/gnu/llvm/tools/lldb/lit/lit.cfg +++ b/gnu/llvm/tools/lldb/lit/lit.cfg @@ -9,9 +9,6 @@ import locale import lit.formats import lit.util -def binary_feature(on, feature, off_prefix): - return feature if on else off_prefix + feature - # Configuration file for the 'lit' test runner. # name: The name of this test suite. @@ -28,39 +25,104 @@ config.test_format = lit.formats.ShTest(execute_external) # suffixes: We only support unit tests config.suffixes = [] -config.excludes = ['Inputs'] - # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__) # test_exec_root: The root path where tests should be run. -config.test_exec_root = os.path.join(config.lldb_obj_root, 'lit') - -# Tweak the PATH to include the tools dir and the scripts dir. -lldb_tools_dir = config.lldb_tools_dir -llvm_tools_dir = config.llvm_tools_dir -path = os.path.pathsep.join((config.lldb_tools_dir, config.llvm_tools_dir, config.environment['PATH'])) - -config.environment['PATH'] = path +lldb_obj_root = getattr(config, 'lldb_obj_root', None) +if lldb_obj_root is not None: + config.test_exec_root = os.path.join(lldb_obj_root, 'lit') -path = os.path.pathsep.join((config.lldb_libs_dir, config.llvm_libs_dir, - config.environment.get('LD_LIBRARY_PATH',''))) -config.environment['LD_LIBRARY_PATH'] = path +# Set llvm_{src,obj}_root for use by others. +config.llvm_src_root = getattr(config, 'llvm_src_root', None) +config.llvm_obj_root = getattr(config, 'llvm_obj_root', None) -# Propagate LLVM_SRC_ROOT into the environment. -config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '') - -# Propagate PYTHON_EXECUTABLE into the environment -config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable', '') +# Tweak the PATH to include the tools dir and the scripts dir. +if lldb_obj_root is not None: + lldb_tools_dir = getattr(config, 'lldb_tools_dir', None) + if not lldb_tools_dir: + lit_config.fatal('No LLDB tools dir set!') + llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) + if not llvm_tools_dir: + lit_config.fatal('No LLVM tools dir set!') + path = os.path.pathsep.join((lldb_tools_dir, llvm_tools_dir, config.environment['PATH'])) + path = os.path.pathsep.join((os.path.join(getattr(config, 'llvm_src_root', None),'test','Scripts'),path)) + + config.environment['PATH'] = path + + lldb_libs_dir = getattr(config, 'lldb_libs_dir', None) + if not lldb_libs_dir: + lit_config.fatal('No LLDB libs dir set!') + llvm_libs_dir = getattr(config, 'llvm_libs_dir', None) + if not llvm_libs_dir: + lit_config.fatal('No LLVM libs dir set!') + path = os.path.pathsep.join((lldb_libs_dir, llvm_libs_dir, + config.environment.get('LD_LIBRARY_PATH',''))) + config.environment['LD_LIBRARY_PATH'] = path + + # Propagate LLVM_SRC_ROOT into the environment. + config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '') + + # Propagate PYTHON_EXECUTABLE into the environment + config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable', + '') +### + +# Check that the object root is known. +if config.test_exec_root is None: + # Otherwise, we haven't loaded the site specific configuration (the user is + # probably trying to run on a test file directly, and either the site + # configuration hasn't been created by the build system, or we are in an + # out-of-tree build situation). + + # Check for 'lldb_site_config' user parameter, and use that if available. + site_cfg = lit_config.params.get('lldb_site_config', None) + if site_cfg and os.path.exists(site_cfg): + lit_config.load_config(config, site_cfg) + raise SystemExit + + # Try to detect the situation where we are using an out-of-tree build by + # looking for 'llvm-config'. + # + # FIXME: I debated (i.e., wrote and threw away) adding logic to + # automagically generate the lit.site.cfg if we are in some kind of fresh + # build situation. This means knowing how to invoke the build system though, + # and I decided it was too much magic. We should solve this by just having + # the .cfg files generated during the configuration step. + + llvm_config = lit.util.which('llvm-config', config.environment['PATH']) + if not llvm_config: + lit_config.fatal('No site specific configuration available!') + + # Get the source and object roots. + llvm_src_root = subprocess.check_output(['llvm-config', '--src-root']).strip() + llvm_obj_root = subprocess.check_output(['llvm-config', '--obj-root']).strip() + lldb_src_root = os.path.join(llvm_src_root, "tools", "lldb") + lldb_obj_root = os.path.join(llvm_obj_root, "tools", "lldb") + + # Validate that we got a tree which points to here, using the standard + # tools/lldb layout. + this_src_root = os.path.dirname(config.test_source_root) + if os.path.realpath(lldb_src_root) != os.path.realpath(this_src_root): + lit_config.fatal('No site specific configuration available!') + + # Check that the site specific configuration exists. + site_cfg = os.path.join(lldb_obj_root, 'test', 'lit.site.cfg') + if not os.path.exists(site_cfg): + lit_config.fatal( + 'No site specific configuration available! You may need to ' + 'run "make test" in your lldb build directory.') + + # Okay, that worked. Notify the user of the automagic, and reconfigure. + lit_config.note('using out-of-tree build at %r' % lldb_obj_root) + lit_config.load_config(config, site_cfg) + raise SystemExit # Register substitutions -config.substitutions.append(('%python', "'%s'" % (config.python_executable))) +config.substitutions.append(('%python', config.python_executable)) debugserver = lit.util.which('debugserver', lldb_tools_dir) -lldb = "%s -S %s/lit-lldb-init" % (lit.util.which('lldb', lldb_tools_dir), - config.test_source_root) - -lldbmi = lit.util.which('lldb-mi', lldb_tools_dir) +lldb = lit.util.which('lldb', lldb_tools_dir) if not os.path.exists(config.cc): config.cc = lit.util.which(config.cc, config.environment['PATH']) @@ -80,32 +142,25 @@ if platform.system() in ['Darwin']: config.cc += " -isysroot %s" % sdk_path config.cxx += " -isysroot %s" % sdk_path -if platform.system() in ['OpenBSD']: - config.cc += " -pthread" - config.cxx += " -pthread" - config.substitutions.append(('%cc', config.cc)) config.substitutions.append(('%cxx', config.cxx)) -config.substitutions.append(('%lldbmi', lldbmi + " --synchronous")) config.substitutions.append(('%lldb', lldb)) if debugserver is not None: config.substitutions.append(('%debugserver', debugserver)) for pattern in [r"\bFileCheck\b", - r"\blldb-test\b", - r"\byaml2obj\b", r"\| \bnot\b"]: tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$", pattern) tool_pipe = tool_match.group(2) tool_name = tool_match.group(4) - tool_path = lit.util.which(tool_name, config.environment['PATH']) + tool_path = lit.util.which(tool_name, config.llvm_tools_dir) if not tool_path: # Warn, but still provide a substitution. lit_config.note( - 'Did not find ' + tool_name + ' in ' + config.environment['PATH']) + 'Did not find ' + tool_name + ' in ' + config.llvm_tools_dir) config.substitutions.append((pattern, tool_pipe + tool_path)) # Shell execution @@ -125,8 +180,8 @@ if platform.system() in ['FreeBSD', 'Linux']: else: config.available_features.add('linux') -config.available_features.add( - binary_feature(platform.system() in ['Windows'], 'windows', 'no')) +if platform.system() in ['Windows']: + config.available_features.add('windows') if re.match(r'^arm(hf.*-linux)|(.*-linux-gnuabihf)', config.target_triple): config.available_features.add("armhf-linux") @@ -140,10 +195,6 @@ elif re.match(r'gcc', config.cc): elif re.match(r'cl', config.cc): config.available_features.add("compiler-msvc") -config.available_features.add(binary_feature(config.have_zlib, "zlib", "no")) -if config.have_lld: - config.available_features.add("lld") - # llvm-config knows whether it is compiled with asserts (and) # whether we are operating in release/debug mode. import subprocess @@ -167,8 +218,6 @@ if re.search(r'ARM', llvm_config_output_list[2]): config.available_features.add('arm') if re.search(r'Mips', llvm_config_output_list[2]): config.available_features.add('mips') -if re.search(r'PowerPC', llvm_config_output_list[2]): - config.available_features.add('powerpc') if re.search(r'X86', llvm_config_output_list[2]): config.available_features.add('x86') llvm_config_cmd.wait() diff --git a/gnu/llvm/tools/lldb/lit/lit.site.cfg.in b/gnu/llvm/tools/lldb/lit/lit.site.cfg.in index 55942db64c4..03aa3df9ac5 100644 --- a/gnu/llvm/tools/lldb/lit/lit.site.cfg.in +++ b/gnu/llvm/tools/lldb/lit/lit.site.cfg.in @@ -6,24 +6,32 @@ config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" config.llvm_libs_dir = "@LLVM_LIBS_DIR@" config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.lldb_obj_root = "@LLDB_BINARY_DIR@" -config.lldb_libs_dir = "@LLDB_LIBS_DIR@" -config.lldb_tools_dir = "@LLDB_TOOLS_DIR@" +config.lldb_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@" +config.lldb_tools_dir = "@LLVM_RUNTIME_OUTPUT_INTDIR@" config.target_triple = "@TARGET_TRIPLE@" config.python_executable = "@PYTHON_EXECUTABLE@" -config.cc = "@LLDB_TEST_C_COMPILER@" -config.cxx = "@LLDB_TEST_CXX_COMPILER@" -config.have_zlib = @LLVM_ENABLE_ZLIB@ -config.have_lld = @LLDB_HAVE_LLD@ +config.cc = "@CMAKE_C_COMPILER@" +config.cxx = "@CMAKE_CXX_COMPILER@" + +test_c_compiler = "@LLDB_TEST_C_COMPILER@" +test_cxx_compiler = "@LLDB_TEST_CXX_COMPILER@" +test_clang = "@LLDB_TEST_CLANG@".lower() +test_clang = test_clang == "on" or test_clang == "true" or test_clang == "1" + +if len(test_c_compiler) > 0: + config.cc = test_c_compiler +if len(test_c_compiler) > 0: + config.cxx = test_cxx_compiler + +if test_clang: + config.cc = 'clang' + config.cxx = 'clang++' # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. try: config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params - config.lldb_libs_dir = config.lldb_libs_dir % lit_config.params - config.lldb_tools_dir = config.lldb_tools_dir % lit_config.params - config.cc = config.cc % lit_config.params - config.cxx = config.cxx % lit_config.params except KeyError as e: key, = e.args lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py index 7f639a46220..aa369ebeff8 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py @@ -28,7 +28,7 @@ class MultilineExpressionsTestCase(TestBase): """Test that multiline expressions work correctly""" self.build() import pexpect - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") prompt = "(lldb) " # So that the child gets torn down after the test. diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py index 0f130b3ecba..937ac927001 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py @@ -29,7 +29,7 @@ class ConvenienceVariablesCase(TestBase): """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame.""" self.build() import pexpect - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") prompt = "(lldb) " python_prompt = ">>> " diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py index 767b368cc7d..3d23f644554 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py @@ -38,7 +38,7 @@ class StopHookCmdTestCase(TestBase): def test(self): """Test a sequence of target stop-hook commands.""" self.build() - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py index b76d98a333c..fa5c6de0565 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py @@ -39,13 +39,12 @@ class StopHookMechanismTestCase(TestBase): @expectedFailureAll( hostoslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows") - @skipIf(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'armv7k']) # <rdar://problem/34582291> problem with armv7 and step-over and stop-hook firing on ios etc systems def test(self): """Test the stop-hook mechanism.""" self.build() import pexpect - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") prompt = "(lldb) " add_prompt = "Enter your stop hook command(s). Type 'DONE' to end." add_prompt1 = "> " diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py index 88267b60b97..3a18877ef2d 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py @@ -46,7 +46,7 @@ class StopHookForMultipleThreadsTestCase(TestBase): self.setTearDownCleanup(dictionary=self.d) import pexpect - exe = self.getBuildArtifact(self.exe_name) + exe = os.path.join(os.getcwd(), self.exe_name) prompt = "(lldb) " # So that the child gets torn down after the test. diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py index 963e0676100..306b00840df 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/expressions/TestExpressions.py @@ -15,7 +15,6 @@ class TestGoUserExpression(TestBase): @add_test_categories(['pyapi']) @skipIfRemote # Not remote test suit ready - @skipIfFreeBSD # Test hanging on FreeBSD - llvm.org/pr37194 @skipUnlessGoInstalled def test_with_dsym_and_python_api(self): """Test GoASTUserExpress.""" @@ -41,7 +40,7 @@ class TestGoUserExpression(TestBase): self.assertEqual(size, t.size) def launchProcess(self): - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py index b31ac35be46..c48cd1f6af0 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/formatters/TestGoFormatters.py @@ -31,7 +31,7 @@ class TestGoLanguage(TestBase): self.break_line = line_number(self.main_source, '// stop here') def launchProcess(self): - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py index 027fb3adc0c..e0cf9e8d775 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/goroutines/TestGoroutines.py @@ -36,7 +36,7 @@ class TestGoASTContext(TestBase): self.break_line3 = line_number(self.main_source, '// stop3') def launchProcess(self): - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime index b06aa656aaa..30381ccd24c 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/runtime/TestGoLanguageRuntime @@ -30,7 +30,7 @@ class TestGoLanguageRuntime(TestBase): def launchProcess(self): - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) diff --git a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py index 8fb56b9577a..9571e259629 100644 --- a/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py +++ b/gnu/llvm/tools/lldb/packages/Python/lldbsuite/test/lang/go/types/TestGoASTContext.py @@ -46,7 +46,7 @@ class TestGoASTContext(TestBase): self.assertEqual(size, t.size) def launchProcess(self): - exe = self.getBuildArtifact("a.out") + exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) diff --git a/gnu/llvm/tools/lldb/source/Core/Broadcaster.cpp b/gnu/llvm/tools/lldb/source/Core/Broadcaster.cpp index 198434b46c2..7a4932c4987 100644 --- a/gnu/llvm/tools/lldb/source/Core/Broadcaster.cpp +++ b/gnu/llvm/tools/lldb/source/Core/Broadcaster.cpp @@ -74,8 +74,9 @@ Broadcaster::BroadcasterImpl::GetListeners() { void Broadcaster::BroadcasterImpl::Clear() { std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex); - // Make sure the listener forgets about this broadcaster. We do this in the - // broadcaster in case the broadcaster object initiates the removal. + // Make sure the listener forgets about this broadcaster. We do + // this in the broadcaster in case the broadcaster object initiates + // the removal. for (auto &pair : GetListeners()) pair.first->BroadcasterWillDestruct(&m_broadcaster); diff --git a/gnu/llvm/tools/lldb/source/Core/Event.cpp b/gnu/llvm/tools/lldb/source/Core/Event.cpp index 3ebad7acdef..8d351d8ba1a 100644 --- a/gnu/llvm/tools/lldb/source/Core/Event.cpp +++ b/gnu/llvm/tools/lldb/source/Core/Event.cpp @@ -10,6 +10,7 @@ #include "lldb/Core/Event.h" #include "lldb/Core/Broadcaster.h" +#include "lldb/Core/DumpDataExtractor.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Stream.h" @@ -133,13 +134,14 @@ const ConstString &EventDataBytes::GetFlavor() const { void EventDataBytes::Dump(Stream *s) const { size_t num_printable_chars = std::count_if(m_bytes.begin(), m_bytes.end(), isprint); - if (num_printable_chars == m_bytes.size()) - s->Format("\"{0}\"", m_bytes); - else - s->Format("{0:$[ ]@[x-2]}", llvm::make_range( - reinterpret_cast<const uint8_t *>(m_bytes.data()), - reinterpret_cast<const uint8_t *>(m_bytes.data() + - m_bytes.size()))); + if (num_printable_chars == m_bytes.size()) { + s->Printf("\"%s\"", m_bytes.c_str()); + } else if (!m_bytes.empty()) { + DataExtractor data; + data.SetData(m_bytes.data(), m_bytes.size(), endian::InlHostByteOrder()); + DumpDataExtractor(data, s, 0, eFormatBytes, 1, m_bytes.size(), 32, + LLDB_INVALID_ADDRESS, 0, 0); + } } const void *EventDataBytes::GetBytes() const { diff --git a/gnu/llvm/tools/lldb/source/Core/Listener.cpp b/gnu/llvm/tools/lldb/source/Core/Listener.cpp index a39ce6121b3..1afa11649b5 100644 --- a/gnu/llvm/tools/lldb/source/Core/Listener.cpp +++ b/gnu/llvm/tools/lldb/source/Core/Listener.cpp @@ -304,9 +304,11 @@ bool Listener::FindNextEventInternal( if (remove) { m_events.erase(pos); - // Unlock the event queue here. We've removed this event and are about - // to return it so it should be okay to get the next event off the queue - // here - and it might be useful to do that in the "DoOnRemoval". + // Unlock the event queue here. We've removed this event and are about to + // return + // it so it should be okay to get the next event off the queue here - and + // it might + // be useful to do that in the "DoOnRemoval". lock.unlock(); event_sp->DoOnRemoval(); } @@ -432,8 +434,8 @@ Listener::StartListeningForEventSpec(BroadcasterManagerSP manager_sp, if (!manager_sp) return 0; - // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to - // avoid violating the lock hierarchy (manager before broadcasters). + // The BroadcasterManager mutex must be locked before m_broadcasters_mutex + // to avoid violating the lock hierarchy (manager before broadcasters). std::lock_guard<std::recursive_mutex> manager_guard( manager_sp->m_manager_mutex); std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex); diff --git a/gnu/llvm/tools/lldb/source/Core/RegisterValue.cpp b/gnu/llvm/tools/lldb/source/Core/RegisterValue.cpp index 4f908609dde..28ce67e63dc 100644 --- a/gnu/llvm/tools/lldb/source/Core/RegisterValue.cpp +++ b/gnu/llvm/tools/lldb/source/Core/RegisterValue.cpp @@ -9,8 +9,9 @@ #include "lldb/Core/RegisterValue.h" +#include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Scalar.h" -#include "lldb/Utility/Args.h" +#include "lldb/Interpreter/Args.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" @@ -33,6 +34,67 @@ using namespace lldb; using namespace lldb_private; +bool RegisterValue::Dump(Stream *s, const RegisterInfo *reg_info, + bool prefix_with_name, bool prefix_with_alt_name, + Format format, + uint32_t reg_name_right_align_at) const { + DataExtractor data; + if (GetData(data)) { + bool name_printed = false; + // For simplicity, alignment of the register name printing applies only + // in the most common case where: + // + // prefix_with_name^prefix_with_alt_name is true + // + StreamString format_string; + if (reg_name_right_align_at && (prefix_with_name ^ prefix_with_alt_name)) + format_string.Printf("%%%us", reg_name_right_align_at); + else + format_string.Printf("%%s"); + std::string fmt = format_string.GetString(); + if (prefix_with_name) { + if (reg_info->name) { + s->Printf(fmt.c_str(), reg_info->name); + name_printed = true; + } else if (reg_info->alt_name) { + s->Printf(fmt.c_str(), reg_info->alt_name); + prefix_with_alt_name = false; + name_printed = true; + } + } + if (prefix_with_alt_name) { + if (name_printed) + s->PutChar('/'); + if (reg_info->alt_name) { + s->Printf(fmt.c_str(), reg_info->alt_name); + name_printed = true; + } else if (!name_printed) { + // No alternate name but we were asked to display a name, so show the + // main name + s->Printf(fmt.c_str(), reg_info->name); + name_printed = true; + } + } + if (name_printed) + s->PutCString(" = "); + + if (format == eFormatDefault) + format = reg_info->format; + + DumpDataExtractor(data, s, + 0, // Offset in "data" + format, // Format to use when dumping + reg_info->byte_size, // item_byte_size + 1, // item_count + UINT32_MAX, // num_per_line + LLDB_INVALID_ADDRESS, // base_addr + 0, // item_bit_size + 0); // item_bit_offset + return true; + } + return false; +} + bool RegisterValue::GetData(DataExtractor &data) const { return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0; } @@ -313,9 +375,9 @@ static bool ParseVectorEncoding(const RegisterInfo *reg_info, std::vector<uint8_t> bytes; unsigned byte = 0; - // Using radix auto-sensing by passing 0 as the radix. Keep on processing the - // vector elements as long as the parsing succeeds and the vector size is < - // byte_size. + // Using radix auto-sensing by passing 0 as the radix. + // Keep on processing the vector elements as long as the parsing succeeds and + // the vector size is < byte_size. while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) { bytes.push_back(byte); std::tie(car, cdr) = cdr.split(Sep); @@ -477,9 +539,6 @@ bool RegisterValue::SignExtend(uint32_t sign_bitpos) { } bool RegisterValue::CopyValue(const RegisterValue &rhs) { - if (this == &rhs) - return rhs.m_type == eTypeInvalid ? false : true; - m_type = rhs.m_type; switch (m_type) { case eTypeInvalid: @@ -750,9 +809,10 @@ bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) { void RegisterValue::SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order) { - // If this assertion fires off we need to increase the size of buffer.bytes, - // or make it something that is allocated on the heap. Since the data buffer - // is in a union, we can't make it a collection class like SmallVector... + // If this assertion fires off we need to increase the size of + // buffer.bytes, or make it something that is allocated on + // the heap. Since the data buffer is in a union, we can't make it + // a collection class like SmallVector... if (bytes && length > 0) { assert(length <= sizeof(buffer.bytes) && "Storing too many bytes in a RegisterValue."); diff --git a/gnu/llvm/tools/lldb/source/Core/Scalar.cpp b/gnu/llvm/tools/lldb/source/Core/Scalar.cpp index 6a7186969ef..630083bae93 100644 --- a/gnu/llvm/tools/lldb/source/Core/Scalar.cpp +++ b/gnu/llvm/tools/lldb/source/Core/Scalar.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/Scalar.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" @@ -24,8 +25,8 @@ using namespace lldb; using namespace lldb_private; //---------------------------------------------------------------------- -// Promote to max type currently follows the ANSI C rule for type promotion in -// expressions. +// Promote to max type currently follows the ANSI C rule for type +// promotion in expressions. //---------------------------------------------------------------------- static Scalar::Type PromoteToMaxType( const Scalar &lhs, // The const left hand side object @@ -40,9 +41,10 @@ static Scalar::Type PromoteToMaxType( // lhs/rhs will get promoted) ) { Scalar result; - // Initialize the promoted values for both the right and left hand side - // values to be the objects themselves. If no promotion is needed (both right - // and left have the same type), then the temp_value will not get used. + // Initialize the promoted values for both the right and left hand side values + // to be the objects themselves. If no promotion is needed (both right and + // left + // have the same type), then the temp_value will not get used. promoted_lhs_ptr = &lhs; promoted_rhs_ptr = &rhs; // Extract the types of both the right and left hand side values @@ -126,13 +128,14 @@ bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const { if (limit_byte_size < byte_size) { if (endian::InlHostByteOrder() == eByteOrderLittle) { - // On little endian systems if we want fewer bytes from the current - // type we just specify fewer bytes since the LSByte is first... + // On little endian systems if we want fewer bytes from the + // current type we just specify fewer bytes since the LSByte + // is first... byte_size = limit_byte_size; } else if (endian::InlHostByteOrder() == eByteOrderBig) { - // On big endian systems if we want fewer bytes from the current type - // have to advance our initial byte pointer and trim down the number of - // bytes since the MSByte is first + // On big endian systems if we want fewer bytes from the + // current type have to advance our initial byte pointer and + // trim down the number of bytes since the MSByte is first bytes += byte_size - limit_byte_size; byte_size = limit_byte_size; } @@ -161,8 +164,9 @@ const void *Scalar::GetBytes() const { case e_slonglong: case e_ulonglong: bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData()); - // getRawData always returns a pointer to an uint64_t. If we have a - // smaller type, we need to update the pointer on big-endian systems. + // getRawData always returns a pointer to an uint64_t. If we have a smaller + // type, + // we need to update the pointer on big-endian systems. if (endian::InlHostByteOrder() == eByteOrderBig) { size_t byte_size = m_integer.getBitWidth() / 8; if (byte_size < 8) @@ -487,24 +491,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -551,24 +551,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -611,24 +607,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -667,24 +659,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -719,24 +707,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -767,24 +751,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -815,24 +795,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -859,24 +835,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -903,24 +875,20 @@ bool Scalar::Promote(Scalar::Type type) { break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -943,24 +911,20 @@ bool Scalar::Promote(Scalar::Type type) { success = true; break; case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToFloat()); success = true; break; case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + m_float = llvm::APFloat(m_integer.bitsToDouble()); success = true; break; case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); success = true; break; } @@ -984,19 +948,20 @@ bool Scalar::Promote(Scalar::Type type) { success = true; break; case e_double: - m_float = llvm::APFloat((double_t)m_float.convertToFloat()); + m_float = llvm::APFloat((float_t)m_float.convertToFloat()); success = true; break; - case e_long_double: { - bool ignore; - m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended(), - llvm::APFloat::rmNearestTiesToEven, &ignore); + case e_long_double: + if (m_ieee_quad) + m_float = + llvm::APFloat(llvm::APFloat::IEEEquad(), m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), + m_float.bitcastToAPInt()); success = true; break; } - } break; case e_double: @@ -1017,15 +982,16 @@ bool Scalar::Promote(Scalar::Type type) { case e_double: success = true; break; - case e_long_double: { - bool ignore; - m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended(), - llvm::APFloat::rmNearestTiesToEven, &ignore); + case e_long_double: + if (m_ieee_quad) + m_float = + llvm::APFloat(llvm::APFloat::IEEEquad(), m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), + m_float.bitcastToAPInt()); success = true; break; } - } break; case e_long_double: @@ -1122,6 +1088,253 @@ Scalar::Type Scalar::GetValueTypeForFloatWithByteSize(size_t byte_size) { return e_void; } +bool Scalar::Cast(Scalar::Type type) { + bool success = false; + switch (m_type) { + case e_void: + break; + + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + case e_sint256: + case e_uint256: + switch (type) { + case e_void: + break; + case e_sint: + m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8); + success = true; + break; + + case e_uint: + m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8); + success = true; + break; + + case e_slong: + m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8); + success = true; + break; + + case e_ulong: + m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8); + success = true; + break; + + case e_slonglong: + m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); + success = true; + break; + + case e_ulonglong: + m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8); + success = true; + break; + + case e_sint128: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + + case e_uint128: + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); + success = true; + break; + + case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + + case e_uint256: + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); + success = true; + break; + + case e_float: + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + + case e_double: + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + + case e_long_double: + if (m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), m_integer); + success = true; + break; + } + break; + + case e_float: + switch (type) { + case e_void: + break; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + case e_sint256: + case e_uint256: + m_integer = m_float.bitcastToAPInt(); + success = true; + break; + case e_float: + m_float = llvm::APFloat(m_float.convertToFloat()); + success = true; + break; + case e_double: + m_float = llvm::APFloat(m_float.convertToFloat()); + success = true; + break; + case e_long_double: + if (m_ieee_quad) + m_float = + llvm::APFloat(llvm::APFloat::IEEEquad(), m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), + m_float.bitcastToAPInt()); + success = true; + break; + } + break; + + case e_double: + switch (type) { + case e_void: + break; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + case e_sint256: + case e_uint256: + m_integer = m_float.bitcastToAPInt(); + success = true; + break; + case e_float: + m_float = llvm::APFloat(m_float.convertToDouble()); + success = true; + break; + case e_double: + m_float = llvm::APFloat(m_float.convertToDouble()); + success = true; + break; + case e_long_double: + if (m_ieee_quad) + m_float = + llvm::APFloat(llvm::APFloat::IEEEquad(), m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), + m_float.bitcastToAPInt()); + success = true; + break; + } + break; + + case e_long_double: + switch (type) { + case e_void: + break; + case e_sint: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8); + success = true; + break; + + case e_uint: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8); + success = true; + break; + + case e_slong: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8); + success = true; + break; + + case e_ulong: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8); + success = true; + break; + + case e_slonglong: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); + success = true; + break; + + case e_ulonglong: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8); + success = true; + break; + + case e_sint128: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + + case e_uint128: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); + success = true; + break; + + case e_sint256: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + + case e_uint256: + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); + success = true; + break; + + case e_float: + m_float = llvm::APFloat(m_float.convertToFloat()); + success = true; + break; + case e_double: + m_float = llvm::APFloat(m_float.convertToFloat()); + success = true; + break; + case e_long_double: + success = true; + break; + } + break; + } + + if (success) + m_type = type; + return success; +} + bool Scalar::MakeSigned() { bool success = false; @@ -1184,38 +1397,38 @@ bool Scalar::MakeUnsigned() { case e_void: break; case e_sint: - m_type = e_uint; success = true; break; case e_uint: + m_type = e_uint; success = true; break; case e_slong: - m_type = e_ulong; success = true; break; case e_ulong: + m_type = e_ulong; success = true; break; case e_slonglong: - m_type = e_ulonglong; success = true; break; case e_ulonglong: + m_type = e_ulonglong; success = true; break; case e_sint128: - m_type = e_uint128; success = true; break; case e_uint128: + m_type = e_uint128; success = true; break; case e_sint256: - m_type = e_uint256; success = true; break; case e_uint256: + m_type = e_uint256; success = true; break; case e_float: @@ -1606,7 +1819,7 @@ float Scalar::Float(float fail_value) const { case e_uint128: case e_sint256: case e_uint256: - return llvm::APIntOps::RoundAPIntToFloat(m_integer); + return m_integer.bitsToFloat(); case e_float: return m_float.convertToFloat(); case e_double: @@ -1632,7 +1845,7 @@ double Scalar::Double(double fail_value) const { case e_uint128: case e_sint256: case e_uint256: - return llvm::APIntOps::RoundAPIntToDouble(m_integer); + return m_integer.bitsToDouble(); case e_float: return (double_t)m_float.convertToFloat(); case e_double: @@ -1658,7 +1871,7 @@ long double Scalar::LongDouble(long double fail_value) const { case e_uint128: case e_sint256: case e_uint256: - return (long_double_t)llvm::APIntOps::RoundAPIntToDouble(m_integer); + return (long_double_t)m_integer.bitsToDouble(); case e_float: return (long_double_t)m_float.convertToFloat(); case e_double: @@ -2053,7 +2266,7 @@ const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) { case Scalar::e_float: case Scalar::e_double: case Scalar::e_long_double: - if (!b->m_float.isZero()) { + if (b->m_float.isZero()) { result.m_float = a->m_float / b->m_float; return result; } @@ -2061,7 +2274,8 @@ const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) { } } // For division only, the only way it should make it here is if a promotion - // failed, or if we are trying to do a divide by zero. + // failed, + // or if we are trying to do a divide by zero. result.m_type = Scalar::e_void; return result; } @@ -2253,15 +2467,17 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding, error.SetErrorString("Invalid c-string value string."); return error; } + bool success = false; switch (encoding) { case eEncodingInvalid: error.SetErrorString("Invalid encoding."); break; case eEncodingUint: - if (byte_size <= sizeof(uint64_t)) { - uint64_t uval64; - if (!llvm::to_integer(value_str, uval64)) + if (byte_size <= sizeof(unsigned long long)) { + uint64_t uval64 = + StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success); + if (!success) error.SetErrorStringWithFormat( "'%s' is not a valid unsigned integer string value", value_str); else if (!UIntValueIsValidForSize(uval64, byte_size)) @@ -2297,9 +2513,10 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding, break; case eEncodingSint: - if (byte_size <= sizeof(int64_t)) { - int64_t sval64; - if (!llvm::to_integer(value_str, sval64)) + if (byte_size <= sizeof(long long)) { + uint64_t sval64 = + StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success); + if (!success) error.SetErrorStringWithFormat( "'%s' is not a valid signed integer string value", value_str); else if (!SIntValueIsValidForSize(sval64, byte_size)) diff --git a/gnu/llvm/tools/lldb/source/Host/common/NativeBreakpointList.cpp b/gnu/llvm/tools/lldb/source/Host/common/NativeBreakpointList.cpp index cfcbe083106..ce5eb94a8d1 100644 --- a/gnu/llvm/tools/lldb/source/Host/common/NativeBreakpointList.cpp +++ b/gnu/llvm/tools/lldb/source/Host/common/NativeBreakpointList.cpp @@ -104,8 +104,8 @@ Status NativeBreakpointList::DecRef(lldb::addr_t addr) { return error; } - // Breakpoint has no more references. Disable it if it's not already - // disabled. + // Breakpoint has no more references. Disable it if it's not + // already disabled. if (log) log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removing due to no remaining references", diff --git a/gnu/llvm/tools/lldb/source/Host/common/SoftwareBreakpoint.cpp b/gnu/llvm/tools/lldb/source/Host/common/SoftwareBreakpoint.cpp index 353dadf6ce6..14dbafd94c0 100644 --- a/gnu/llvm/tools/lldb/source/Host/common/SoftwareBreakpoint.cpp +++ b/gnu/llvm/tools/lldb/source/Host/common/SoftwareBreakpoint.cpp @@ -17,8 +17,9 @@ using namespace lldb_private; -// ------------------------------------------------------------------- static -// members ------------------------------------------------------------------- +// ------------------------------------------------------------------- +// static members +// ------------------------------------------------------------------- Status SoftwareBreakpoint::CreateSoftwareBreakpoint( NativeProcessProtocol &process, lldb::addr_t addr, size_t size_hint, @@ -33,7 +34,8 @@ Status SoftwareBreakpoint::CreateSoftwareBreakpoint( __FUNCTION__); // Ask the NativeProcessProtocol subclass to fill in the correct software - // breakpoint trap for the breakpoint site. + // breakpoint + // trap for the breakpoint site. size_t bp_opcode_size = 0; const uint8_t *bp_opcode_bytes = NULL; Status error = process.GetSoftwareBreakpointTrapOpcode( @@ -96,8 +98,9 @@ Status SoftwareBreakpoint::CreateSoftwareBreakpoint( log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS", __FUNCTION__, addr); - // Set the breakpoint and verified it was written properly. Now create a - // breakpoint remover that understands how to undo this breakpoint. + // Set the breakpoint and verified it was written properly. Now + // create a breakpoint remover that understands how to undo this + // breakpoint. breakpoint_sp.reset(new SoftwareBreakpoint(process, addr, saved_opcode_bytes, bp_opcode_bytes, bp_opcode_size)); return Status(); @@ -277,8 +280,8 @@ Status SoftwareBreakpoint::DoDisable() { // Make sure the breakpoint opcode exists at this address if (::memcmp(curr_break_op, m_trap_opcodes, m_opcode_size) == 0) { break_op_found = true; - // We found a valid breakpoint opcode at this address, now restore the - // saved opcode. + // We found a valid breakpoint opcode at this address, now restore + // the saved opcode. size_t bytes_written = 0; error = m_process.WriteMemory(m_addr, m_saved_opcodes, m_opcode_size, bytes_written); diff --git a/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp b/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp index 9c845d02bca..538bd05e25f 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp @@ -67,9 +67,7 @@ private: size_t m_pos; }; -GoParser::GoParser(const char *src) - : m_lexer(src), m_pos(0), m_last_tok(GoLexer::TOK_INVALID), - m_failed(false) {} +GoParser::GoParser(const char *src) : m_lexer(src), m_pos(0), m_failed(false) {} GoASTStmt *GoParser::Statement() { Rule r("Statement", this); @@ -439,10 +437,8 @@ GoASTExpr *GoParser::CompositeLit() { if (!type) return r.error(); GoASTCompositeLit *lit = LiteralValue(); - if (!lit) { - delete type; + if (!lit) return r.error(); - } lit->SetType(type); return lit; } @@ -550,7 +546,6 @@ GoASTExpr *GoParser::Arguments(GoASTExpr *e) { GoASTExpr *GoParser::Conversion() { Rule r("Conversion", this); if (GoASTExpr *t = Type2()) { - std::unique_ptr<GoASTExpr> owner(t); if (match(GoLexer::OP_LPAREN)) { GoASTExpr *v = Expression(); if (!v) @@ -560,7 +555,6 @@ GoASTExpr *GoParser::Conversion() { return r.error(); GoASTCallExpr *call = new GoASTCallExpr(false); call->SetFun(t); - owner.release(); call->AddArgs(v); return call; } diff --git a/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp b/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp index 3a10a1dc767..f4b8cfbe03d 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp @@ -171,11 +171,12 @@ private: VariableSP FindGlobalVariable(TargetSP target, llvm::Twine name) { ConstString fullname(name.str()); VariableList variable_list; + const bool append = true; if (!target) { return nullptr; } - const uint32_t match_count = - target->GetImages().FindGlobalVariables(fullname, 1, variable_list); + const uint32_t match_count = target->GetImages().FindGlobalVariables( + fullname, append, 1, variable_list); if (match_count == 1) { return variable_list.GetVariableAtIndex(0); } @@ -271,8 +272,7 @@ GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, PersistentExpressionState *pv = target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo); if (pv != nullptr) { - result->SetName(pv->GetNextPersistentVariableName( - *target, pv->GetPersistentVariablePrefix())); + result->SetName(pv->GetNextPersistentVariableName()); pv->AddVariable(result); } return lldb::eExpressionCompleted; @@ -400,7 +400,8 @@ ValueObjectSP GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e) { val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic); else { // When a variable is on the heap instead of the stack, go records a - // variable '&x' instead of 'x'. + // variable + // '&x' instead of 'x'. var_sp = var_list_sp->FindVariable(ConstString("&" + varname)); if (var_sp) { val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic); @@ -650,6 +651,15 @@ ValueObjectSP GoUserExpression::GoInterpreter::VisitCallExpr( GoPersistentExpressionState::GoPersistentExpressionState() : PersistentExpressionState(eKindGo) {} +ConstString GoPersistentExpressionState::GetNextPersistentVariableName() { + char name_cstr[256]; + // We can't use the same variable format as clang. + ::snprintf(name_cstr, sizeof(name_cstr), "$go%u", + m_next_persistent_variable_id++); + ConstString name(name_cstr); + return name; +} + void GoPersistentExpressionState::RemovePersistentVariable( lldb::ExpressionVariableSP variable) { RemoveVariable(variable); diff --git a/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h b/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h index e2839da9bfd..03ceb76b843 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h +++ b/gnu/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h @@ -29,10 +29,8 @@ class GoPersistentExpressionState : public PersistentExpressionState { public: GoPersistentExpressionState(); - llvm::StringRef - GetPersistentVariablePrefix(bool is_error) const override { - return "$go"; - } + ConstString GetNextPersistentVariableName() override; + void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override; lldb::addr_t LookupSymbol(const ConstString &name) override { @@ -50,12 +48,12 @@ private: //---------------------------------------------------------------------- /// @class GoUserExpression GoUserExpression.h -/// "lldb/Expression/GoUserExpression.h" Encapsulates a single expression for -/// use with Go +/// "lldb/Expression/GoUserExpression.h" +/// @brief Encapsulates a single expression for use with Go /// /// LLDB uses expressions for various purposes, notably to call functions -/// and as a backend for the expr command. GoUserExpression encapsulates the -/// objects needed to parse and interpret an expression. +/// and as a backend for the expr command. GoUserExpression encapsulates +/// the objects needed to parse and interpret an expression. //---------------------------------------------------------------------- class GoUserExpression : public UserExpression { public: diff --git a/gnu/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/gnu/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp index 3f608393151..75bc518f753 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp @@ -312,8 +312,8 @@ bool OperatingSystemGo::UpdateThreadList(ThreadList &old_thread_list, } std::vector<Goroutine> goroutines; // The threads that are in "new_thread_list" upon entry are the threads from - // the lldb_private::Process subclass, no memory threads will be in this - // list. + // the + // lldb_private::Process subclass, no memory threads will be in this list. Status err; for (uint64_t i = 0; i < allglen; ++i) { @@ -402,6 +402,7 @@ lldb::ThreadSP OperatingSystemGo::CreateThread(lldb::tid_t tid, ValueObjectSP OperatingSystemGo::FindGlobal(TargetSP target, const char *name) { VariableList variable_list; + const bool append = true; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); @@ -413,7 +414,7 @@ ValueObjectSP OperatingSystemGo::FindGlobal(TargetSP target, const char *name) { } uint32_t match_count = target->GetImages().FindGlobalVariables( - ConstString(name), 1, variable_list); + ConstString(name), append, 1, variable_list); if (match_count > 0) { ExecutionContextScope *exe_scope = target->GetProcessSP().get(); if (exe_scope == NULL) diff --git a/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp index 328212e4b68..2507465750c 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp @@ -10,6 +10,7 @@ #include "DWARFASTParserGo.h" #include "DWARFASTParserGo.h" +#include "DWARFCompileUnit.h" #include "DWARFDIE.h" #include "DWARFDIECollection.h" #include "DWARFDebugInfo.h" @@ -157,8 +158,7 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF( Type *type = dwarf->ResolveTypeUID(encoding_uid); if (type) { if (go_kind == 0 && type->GetName() == type_name_const_str) { - // Go emits extra typedefs as a forward declaration. Ignore - // these. + // Go emits extra typedefs as a forward declaration. Ignore these. dwarf->m_die_to_type[die.GetDIE()] = type; return type->shared_from_this(); } @@ -213,10 +213,10 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF( // TODO(ribrdb): Do we need this? - // UniqueDWARFASTType is large, so don't create a local variables on - // the stack, put it on the heap. This function is often called - // recursively and clang isn't good and sharing the stack space for - // variables in different blocks. + // UniqueDWARFASTType is large, so don't create a local variables on the + // stack, put it on the heap. This function is often called recursively + // and clang isn't good and sharing the stack space for variables in + // different blocks. std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap( new UniqueDWARFASTType()); @@ -225,10 +225,11 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF( dwarf->GetUniqueDWARFASTTypeMap().Find( type_name_const_str, die, decl, byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) { - // We have already parsed this type or from another compile unit. GCC - // loves to use the "one definition rule" which can result in - // multiple definitions of the same class over and over in each - // compile unit. + // We have already parsed this type or from another + // compile unit. GCC loves to use the "one definition + // rule" which can result in multiple definitions + // of the same class over and over in each compile + // unit. type_sp = unique_ast_entry_ap->m_type_sp; if (type_sp) { dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); @@ -254,9 +255,9 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF( Type::eEncodingIsUID, &decl, compiler_type, Type::eResolveStateForward)); - // Add our type to the unique type map so we don't end up creating many - // copies of the same type over and over in the ASTContext for our - // module + // Add our type to the unique type map so we don't + // end up creating many copies of the same type over + // and over in the ASTContext for our module unique_ast_entry_ap->m_type_sp = type_sp; unique_ast_entry_ap->m_die = die; unique_ast_entry_ap->m_declaration = decl; @@ -265,19 +266,19 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF( *unique_ast_entry_ap); if (!is_forward_declaration) { - // Always start the definition for a class type so that if the class - // has child classes or types that require the class to be created - // for use as their decl contexts the class will be ready to accept - // these child definitions. + // Always start the definition for a class type so that + // if the class has child classes or types that require + // the class to be created for use as their decl contexts + // the class will be ready to accept these child definitions. if (die.HasChildren() == false) { // No children for this struct/union/class, lets finish it m_ast.CompleteStructType(compiler_type); } else if (compiler_type_was_created) { - // Leave this as a forward declaration until we need to know the - // details of the type. lldb_private::Type will automatically call - // the SymbolFile virtual function - // "SymbolFileDWARF::CompleteType(Type *)" When the definition - // needs to be defined. + // Leave this as a forward declaration until we need + // to know the details of the type. lldb_private::Type + // will automatically call the SymbolFile virtual function + // "SymbolFileDWARF::CompleteType(Type *)" + // When the definition needs to be defined. dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] = compiler_type.GetOpaqueQualType(); dwarf->m_forward_decl_clang_type_to_die[compiler_type @@ -431,8 +432,7 @@ TypeSP DWARFASTParserGo::ParseTypeFromDWARF( dw_tag_t sc_parent_tag = sc_parent_die.Tag(); SymbolContextScope *symbol_context_scope = NULL; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { + if (sc_parent_tag == DW_TAG_compile_unit) { symbol_context_scope = sc.comp_unit; } else if (sc.function != NULL && sc_parent_die) { symbol_context_scope = @@ -655,12 +655,15 @@ size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, if (form_value.BlockData()) { Value initialValue(0); Value memberOffset(0); - const DWARFDataExtractor &debug_info_data = die.GetData(); + const DWARFDataExtractor &debug_info_data = + die.GetDWARF()->get_debug_info_data(); uint32_t block_length = form_value.Unsigned(); uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); if (DWARFExpression::Evaluate( NULL, // ExecutionContext * + NULL, // ClangExpressionVariableList * + NULL, // ClangExpressionDeclMap * NULL, // RegisterContext * module_sp, debug_info_data, die.GetCU(), block_offset, block_length, eRegisterKindDWARF, &initialValue, NULL, @@ -669,8 +672,8 @@ size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, } } else { // With DWARF 3 and later, if the value is an integer constant, - // this form value is the offset in bytes from the beginning of - // the containing entity. + // this form value is the offset in bytes from the beginning + // of the containing entity. member_byte_offset = form_value.Unsigned(); } break; diff --git a/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp index 47639448798..8b5202ba265 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp @@ -9,7 +9,7 @@ #include "DWARFASTParserJava.h" #include "DWARFAttribute.h" -#include "DWARFUnit.h" +#include "DWARFCompileUnit.h" #include "DWARFDebugInfoEntry.h" #include "DWARFDebugInfoEntry.h" #include "DWARFDeclContext.h" @@ -324,8 +324,7 @@ lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF( dw_tag_t sc_parent_tag = sc_parent_die.Tag(); SymbolContextScope *symbol_context_scope = nullptr; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { + if (sc_parent_tag == DW_TAG_compile_unit) { symbol_context_scope = sc.comp_unit; } else if (sc.function != nullptr && sc_parent_die) { symbol_context_scope = @@ -419,7 +418,7 @@ bool DWARFASTParserJava::CompleteTypeFromDWARF( void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, CompilerType &compiler_type) { - DWARFUnit *dwarf_cu = parent_die.GetCU(); + DWARFCompileUnit *dwarf_cu = parent_die.GetCU(); for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { switch (die.Tag()) { diff --git a/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp b/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp index 3ef5c2eb862..3b1466df21b 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp @@ -98,8 +98,7 @@ lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc, dw_tag_t sc_parent_tag = sc_parent_die.Tag(); SymbolContextScope *symbol_context_scope = nullptr; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { + if (sc_parent_tag == DW_TAG_compile_unit) { symbol_context_scope = sc.comp_unit; } else if (sc.function != nullptr && sc_parent_die) { symbol_context_scope = diff --git a/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h b/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h index 09cb5e14934..e3b2279ca8f 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h +++ b/gnu/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h @@ -4,6 +4,7 @@ #define SymbolFileDWARF_DWARFASTParserOCaml_h_ #include "DWARFASTParser.h" +#include "DWARFCompileUnit.h" #include "DWARFDIE.h" #include "DWARFDebugInfo.h" #include "DWARFDefines.h" diff --git a/gnu/llvm/tools/lldb/source/Symbol/GoASTContext.cpp b/gnu/llvm/tools/lldb/source/Symbol/GoASTContext.cpp index da5c82b2cb5..6761a605e46 100644 --- a/gnu/llvm/tools/lldb/source/Symbol/GoASTContext.cpp +++ b/gnu/llvm/tools/lldb/source/Symbol/GoASTContext.cpp @@ -667,7 +667,8 @@ GoASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) { } // Returns -1 if this isn't a function of if the function doesn't have a -// prototype Returns a value >= 0 if there is a prototype. +// prototype +// Returns a value >= 0 if there is a prototype. int GoASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) { return GetNumberOfFunctionArguments(type); } @@ -1007,8 +1008,8 @@ CompilerType GoASTContext::GetChildCompilerTypeAtIndex( return CompilerType(); } -// Lookup a child given a name. This function will match base class names and -// member member names in "clang_type" only, not descendants. +// Lookup a child given a name. This function will match base class names +// and member member names in "clang_type" only, not descendants. uint32_t GoASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, @@ -1047,8 +1048,8 @@ size_t GoASTContext::GetIndexOfChildMemberWithName( return 1; } -// Converts "s" to a floating point value and place resulting floating point -// bytes in the "dst" buffer. +// Converts "s" to a floating point value and place resulting floating +// point bytes in the "dst" buffer. size_t GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, @@ -1079,8 +1080,9 @@ void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type, uint32_t field_idx = 0; for (auto *field = st->GetField(field_idx); field != nullptr; field_idx++) { - // Print the starting squiggly bracket (if this is the first member) or - // comma (for member 2 and beyond) for the struct/union/class member. + // Print the starting squiggly bracket (if this is the + // first member) or comma (for member 2 and beyond) for + // the struct/union/class member. if (field_idx == 0) s->PutChar('{'); else @@ -1135,8 +1137,9 @@ void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type, uint64_t element_idx; for (element_idx = 0; element_idx < a->GetLength(); ++element_idx) { - // Print the starting squiggly bracket (if this is the first member) or - // comman (for member 2 and beyong) for the struct/union/class member. + // Print the starting squiggly bracket (if this is the + // first member) or comman (for member 2 and beyong) for + // the struct/union/class member. if (element_idx == 0) s->PutChar('{'); else diff --git a/gnu/llvm/tools/lldb/source/Symbol/JavaASTContext.cpp b/gnu/llvm/tools/lldb/source/Symbol/JavaASTContext.cpp index ff317eb19e9..ae4e9d5134b 100644 --- a/gnu/llvm/tools/lldb/source/Symbol/JavaASTContext.cpp +++ b/gnu/llvm/tools/lldb/source/Symbol/JavaASTContext.cpp @@ -7,7 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Symbol/JavaASTContext.h" +#include <sstream> + +#include "lldb/Core/ArchSpec.h" #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -15,12 +17,11 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/CompilerType.h" +#include "lldb/Symbol/JavaASTContext.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Type.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Stream.h" -#include <sstream> #include "Plugins/SymbolFile/DWARF/DWARFASTParserJava.h" @@ -133,9 +134,9 @@ public: obj_load_address.SetValueType(Value::eValueTypeLoadAddress); Value result; - if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), 0, - &obj_load_address, nullptr, result, - nullptr)) { + if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), + nullptr, nullptr, 0, &obj_load_address, + nullptr, result, nullptr)) { Status error; lldb::addr_t type_id_addr = result.GetScalar().UInt(); @@ -314,8 +315,9 @@ public: ExecutionContextScope *exec_ctx_scope = value_obj->GetExecutionContextRef() .Lock(true) .GetBestExecutionContextScope(); - if (m_length_expression.Evaluate(exec_ctx_scope, 0, nullptr, - &obj_load_address, result, nullptr)) + if (m_length_expression.Evaluate(exec_ctx_scope, nullptr, nullptr, 0, + nullptr, &obj_load_address, result, + nullptr)) return result.GetScalar().UInt(); return UINT32_MAX; @@ -883,6 +885,13 @@ JavaASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { return 0; } +CompilerType +JavaASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx, + lldb::TemplateArgumentKind &kind) { + return CompilerType(); +} + uint32_t JavaASTContext::GetNumFields(lldb::opaque_compiler_type_t type) { if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) { diff --git a/gnu/llvm/tools/lldb/source/Utility/FastDemangle.cpp b/gnu/llvm/tools/lldb/source/Utility/FastDemangle.cpp index d92670a9199..90326c5f15c 100644 --- a/gnu/llvm/tools/lldb/source/Utility/FastDemangle.cpp +++ b/gnu/llvm/tools/lldb/source/Utility/FastDemangle.cpp @@ -25,7 +25,7 @@ namespace { -/// Represents the collection of qualifiers on a type +/// @brief Represents the collection of qualifiers on a type enum Qualifiers { QualifierNone = 0, @@ -37,7 +37,7 @@ enum Qualifiers { QualifierPointer = 32 }; -/// Categorizes the recognized operators +/// @brief Categorizes the recognized operators enum class OperatorKind { Unary, @@ -50,23 +50,23 @@ enum class OperatorKind { NoMatch }; -/// Represents one of the recognized two-character operator abbreviations used -/// when parsing operators as names and expressions +/// @brief Represents one of the recognized two-character operator +/// abbreviations used when parsing operators as names and expressions struct Operator { const char *name; OperatorKind kind; }; -/// Represents a range of characters in the output buffer, typically for use -/// with RewriteRange() +/// @brief Represents a range of characters in the output buffer, typically for +/// use with RewriteRange() struct BufferRange { int offset; int length; }; -/// Transient state required while parsing a name +/// @brief Transient state required while parsing a name struct NameState { bool parse_function_params; @@ -75,13 +75,12 @@ struct NameState { BufferRange last_name_range; }; -/// LLDB's fast C++ demangler +/// @brief LLDB's fast C++ demangler /// /// This is an incomplete implementation designed to speed up the demangling /// process that is often a bottleneck when LLDB stops a process for the first /// time. Where the implementation doesn't know how to demangle a symbol it -/// fails gracefully to allow the caller to fall back to the existing -/// demangler. +/// fails gracefully to allow the caller to fall back to the existing demangler. /// /// Over time the full mangling spec should be supported without compromising /// performance for the most common cases. @@ -92,7 +91,7 @@ public: // Public API //---------------------------------------------------- - /// Create a SymbolDemangler + /// @brief Create a SymbolDemangler /// /// The newly created demangler allocates and owns scratch memory sufficient /// for demangling typical symbols. Additional memory will be allocated if @@ -108,18 +107,18 @@ public: m_owns_m_rewrite_ranges = true; } - /// Create a SymbolDemangler that uses provided scratch memory + /// @brief Create a SymbolDemangler that uses provided scratch memory /// /// The provided memory is not owned by the demangler. It will be - /// overwritten during calls to GetDemangledCopy() but can be used for other - /// purposes between calls. The provided memory will not be freed when this - /// instance is destroyed. + /// overwritten during calls to GetDemangledCopy() but can be used for + /// other purposes between calls. The provided memory will not be freed + /// when this instance is destroyed. /// /// If demangling a symbol requires additional space it will be allocated /// and managed by the demangler instance. /// - /// @param storage_ptr Valid pointer to at least storage_size bytes of space - /// that the SymbolDemangler can use during demangling + /// @param storage_ptr Valid pointer to at least storage_size bytes of + /// space that the SymbolDemangler can use during demangling /// /// @param storage_size Number of bytes of space available scratch memory /// referenced by storage_ptr @@ -139,8 +138,8 @@ public: m_owns_buffer = false; } - /// Destroys the SymbolDemangler and deallocates any scratch memory that it - /// owns + /// @brief Destroys the SymbolDemangler and deallocates any scratch + /// memory that it owns ~SymbolDemangler() { if (m_owns_buffer) @@ -154,11 +153,11 @@ public: int highwater_buffer = 0; #endif - /// Parses the provided mangled name and returns a newly allocated + /// @brief Parses the provided mangled name and returns a newly allocated /// demangling /// - /// @param mangled_name Valid null-terminated C++ mangled name following the - /// Itanium C++ ABI mangling specification as implemented by Clang + /// @param mangled_name Valid null-terminated C++ mangled name following + /// the Itanium C++ ABI mangling specification as implemented by Clang /// /// @result Newly allocated null-terminated demangled name when demangling /// is successful, and nullptr when demangling fails. The caller is @@ -201,7 +200,8 @@ private: if (growth > 1 << 20) growth = 1 << 20; - // ... but never grow by less than requested, or 1K, whichever is greater + // ... but never grow by less than requested, + // or 1K, whichever is greater if (min_growth < 1024) min_growth = 1024; if (growth < min_growth) @@ -282,8 +282,9 @@ private: if (index == m_rewrite_ranges_size) break; - // Affected ranges are either shuffled forward when after the insertion - // but before the source, or backward when inside the source + // Affected ranges are either shuffled forward when after the + // insertion but before the source, or backward when inside the + // source int candidate_offset = m_rewrite_ranges[index].offset; if (candidate_offset >= insertion_point_cookie) { if (candidate_offset < source_range.offset) { @@ -401,7 +402,8 @@ private: //---------------------------------------------------- // Rewrite methods // - // Write another copy of content already present earlier in the output buffer + // Write another copy of content already present + // earlier in the output buffer //---------------------------------------------------- void RewriteRange(BufferRange range) { @@ -434,11 +436,11 @@ private: //---------------------------------------------------- // TryParse methods // - // Provide information with return values instead of writing to the output - // buffer + // Provide information with return values instead of + // writing to the output buffer // - // Values indicating failure guarantee that the pre- call m_read_ptr is - // unchanged + // Values indicating failure guarantee that the pre- + // call m_read_ptr is unchanged //---------------------------------------------------- int TryParseNumber() { @@ -818,8 +820,8 @@ private: } // <CV-qualifiers> ::= [r] [V] [K] - // <ref-qualifier> ::= R # & ref-qualifier <ref-qualifier> - // ::= O # && ref-qualifier + // <ref-qualifier> ::= R # & ref-qualifier + // <ref-qualifier> ::= O # && ref-qualifier int TryParseQualifiers(bool allow_cv, bool allow_ro) { int qualifiers = QualifierNone; @@ -888,10 +890,11 @@ private: //---------------------------------------------------- // Parse methods // - // Consume input starting from m_read_ptr and produce buffered output at - // m_write_ptr + // Consume input starting from m_read_ptr and produce + // buffered output at m_write_ptr // - // Failures return false and may leave m_read_ptr in an indeterminate state + // Failures return false and may leave m_read_ptr in an + // indeterminate state //---------------------------------------------------- bool Parse(char character) { @@ -929,14 +932,17 @@ private: // <substitution> ::= S <seq-id> _ // ::= S_ - // <substitution> ::= Sa # ::std::allocator <substitution> ::= Sb # - // ::std::basic_string <substitution> ::= Ss # ::std::basic_string < char, + // <substitution> ::= Sa # ::std::allocator + // <substitution> ::= Sb # ::std::basic_string + // <substitution> ::= Ss # ::std::basic_string < char, // ::std::char_traits<char>, // ::std::allocator<char> > // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> - // > <substitution> ::= So # ::std::basic_ostream<char, - // std::char_traits<char> > <substitution> ::= Sd # - // ::std::basic_iostream<char, std::char_traits<char> > + // > + // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> + // > + // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> + // > bool ParseSubstitution() { const char *substitution; @@ -961,8 +967,7 @@ private: break; default: // A failed attempt to parse a number will return -1 which turns out to be - // perfect here as S_ is the first substitution, S0_ the next and so - // forth + // perfect here as S_ is the first substitution, S0_ the next and so forth int substitution_index = TryParseBase36Number(); if (*m_read_ptr++ != '_') { #ifdef DEBUG_FAILURES @@ -979,17 +984,17 @@ private: // <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E // - // <bare-function-type> ::= <signature type>+ # types are possible - // return type, then parameter types + // <bare-function-type> ::= <signature type>+ # types are possible return + // type, then parameter types bool ParseFunctionType(int inner_qualifiers = QualifierNone) { #ifdef DEBUG_FAILURES printf("*** Function types not supported\n"); #endif // TODO: first steps toward an implementation follow, but they're far - // from complete. Function types tend to bracket other types eg: int (*)() - // when used as the type for "name" becomes int (*name)(). This makes - // substitution et al ... interesting. + // from complete. Function types tend to bracket other types eg: + // int (*)() when used as the type for "name" becomes int (*name)(). + // This makes substitution et al ... interesting. return false; #if 0 // TODO @@ -1149,8 +1154,8 @@ private: if (!Parse('_')) return false; - // When no number is present we get -1, which is convenient since T_ is the - // zeroth element T0_ is element 1, and so on + // When no number is present we get -1, which is convenient since + // T_ is the zeroth element T0_ is element 1, and so on return RewriteTemplateArg(count + 1); } @@ -1188,13 +1193,13 @@ private: // ::= G <type> # imaginary (C 2000) // ::= Dp <type> # pack expansion (C++0x) // ::= U <source-name> <type> # vendor extended type qualifier - // extension := U <objc-name> <objc-type> # objc-type<identifier> extension - // := <vector-type> # <vector-type> starts with Dv + // extension := U <objc-name> <objc-type> # objc-type<identifier> + // extension := <vector-type> # <vector-type> starts with Dv // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + - // <number of digits in k1> + k1 <objc-type> := <source-name> # - // PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source- - // name> + // <number of digits in k1> + k1 + // <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> + // 11objc_object -> id<source-name> bool ParseType() { #ifdef DEBUG_FAILURES @@ -1471,8 +1476,8 @@ private: // ::= <unnamed-type-name> bool ParseUnqualifiedName(NameState &name_state) { - // Note that these are detected directly in ParseNestedName for performance - // rather than switching on the same options twice + // Note that these are detected directly in ParseNestedName for + // performance rather than switching on the same options twice char next = *m_read_ptr; switch (next) { case 'C': @@ -1938,8 +1943,7 @@ private: break; } - // Record a substitution candidate for all prefixes, but not the full - // name + // Record a substitution candidate for all prefixes, but not the full name if (suppress_substitution) suppress_substitution = false; else @@ -2243,9 +2247,9 @@ private: if (next == 'E' || next == '\0' || next == '.') return true; - // Clang has a bad habit of making unique manglings by just sticking - // numbers on the end of a symbol, which is ambiguous with malformed source - // name manglings + // Clang has a bad habit of making unique manglings by just sticking numbers + // on the end of a symbol, + // which is ambiguous with malformed source name manglings const char *before_clang_uniquing_test = m_read_ptr; if (TryParseNumber()) { if (*m_read_ptr == '\0') diff --git a/gnu/llvm/tools/lldb/unittests/Core/DataExtractorTest.cpp b/gnu/llvm/tools/lldb/unittests/Core/DataExtractorTest.cpp index 0267f6d1405..213d5a7b43f 100644 --- a/gnu/llvm/tools/lldb/unittests/Core/DataExtractorTest.cpp +++ b/gnu/llvm/tools/lldb/unittests/Core/DataExtractorTest.cpp @@ -49,120 +49,3 @@ TEST(DataExtractorTest, PeekData) { EXPECT_EQ(buffer + 4, E.PeekData(4, 0)); EXPECT_EQ(nullptr, E.PeekData(4, 1)); } - -TEST(DataExtractorTest, GetMaxU64) { - uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - // Check with the minimum allowed byte size. - offset = 0; - EXPECT_EQ(0x01U, LE.GetMaxU64(&offset, 1)); - EXPECT_EQ(1U, offset); - offset = 0; - EXPECT_EQ(0x01U, BE.GetMaxU64(&offset, 1)); - EXPECT_EQ(1U, offset); - - // Check with a non-zero offset. - offset = 1; - EXPECT_EQ(0x0302U, LE.GetMaxU64(&offset, 2)); - EXPECT_EQ(3U, offset); - offset = 1; - EXPECT_EQ(0x0203U, BE.GetMaxU64(&offset, 2)); - EXPECT_EQ(3U, offset); - - // Check with the byte size not being a multiple of 2. - offset = 0; - EXPECT_EQ(0x07060504030201U, LE.GetMaxU64(&offset, 7)); - EXPECT_EQ(7U, offset); - offset = 0; - EXPECT_EQ(0x01020304050607U, BE.GetMaxU64(&offset, 7)); - EXPECT_EQ(7U, offset); - - // Check with the maximum allowed byte size. - offset = 0; - EXPECT_EQ(0x0807060504030201U, LE.GetMaxU64(&offset, 8)); - EXPECT_EQ(8U, offset); - offset = 0; - EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64(&offset, 8)); - EXPECT_EQ(8U, offset); -} - -TEST(DataExtractorTest, GetMaxS64) { - uint8_t buffer[] = {0x01, 0x02, 0x83, 0x04, 0x05, 0x06, 0x07, 0x08}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - // Check with the minimum allowed byte size. - offset = 0; - EXPECT_EQ(0x01, LE.GetMaxS64(&offset, 1)); - EXPECT_EQ(1U, offset); - offset = 0; - EXPECT_EQ(0x01, BE.GetMaxS64(&offset, 1)); - EXPECT_EQ(1U, offset); - - // Check that sign extension works correctly. - offset = 0; - int64_t value = LE.GetMaxS64(&offset, 3); - EXPECT_EQ(0xffffffffff830201U, *reinterpret_cast<uint64_t *>(&value)); - EXPECT_EQ(3U, offset); - offset = 2; - value = BE.GetMaxS64(&offset, 3); - EXPECT_EQ(0xffffffffff830405U, *reinterpret_cast<uint64_t *>(&value)); - EXPECT_EQ(5U, offset); - - // Check with the maximum allowed byte size. - offset = 0; - EXPECT_EQ(0x0807060504830201, LE.GetMaxS64(&offset, 8)); - EXPECT_EQ(8U, offset); - offset = 0; - EXPECT_EQ(0x0102830405060708, BE.GetMaxS64(&offset, 8)); - EXPECT_EQ(8U, offset); -} - -TEST(DataExtractorTest, GetMaxU64_unchecked) { - uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, - sizeof(void *)); - DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *)); - - lldb::offset_t offset; - - // Check with the minimum allowed byte size. - offset = 0; - EXPECT_EQ(0x01U, LE.GetMaxU64_unchecked(&offset, 1)); - EXPECT_EQ(1U, offset); - offset = 0; - EXPECT_EQ(0x01U, BE.GetMaxU64_unchecked(&offset, 1)); - EXPECT_EQ(1U, offset); - - // Check with a non-zero offset. - offset = 1; - EXPECT_EQ(0x0302U, LE.GetMaxU64_unchecked(&offset, 2)); - EXPECT_EQ(3U, offset); - offset = 1; - EXPECT_EQ(0x0203U, BE.GetMaxU64_unchecked(&offset, 2)); - EXPECT_EQ(3U, offset); - - // Check with the byte size not being a multiple of 2. - offset = 0; - EXPECT_EQ(0x07060504030201U, LE.GetMaxU64_unchecked(&offset, 7)); - EXPECT_EQ(7U, offset); - offset = 0; - EXPECT_EQ(0x01020304050607U, BE.GetMaxU64_unchecked(&offset, 7)); - EXPECT_EQ(7U, offset); - - // Check with the maximum allowed byte size. - offset = 0; - EXPECT_EQ(0x0807060504030201U, LE.GetMaxU64_unchecked(&offset, 8)); - EXPECT_EQ(8U, offset); - offset = 0; - EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64_unchecked(&offset, 8)); - EXPECT_EQ(8U, offset); -} diff --git a/gnu/llvm/tools/lldb/unittests/Core/ScalarTest.cpp b/gnu/llvm/tools/lldb/unittests/Core/ScalarTest.cpp index 9c241c26e66..692aa8aaf11 100644 --- a/gnu/llvm/tools/lldb/unittests/Core/ScalarTest.cpp +++ b/gnu/llvm/tools/lldb/unittests/Core/ScalarTest.cpp @@ -14,10 +14,8 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" -#include "llvm/Testing/Support/Error.h" using namespace lldb_private; -using namespace llvm; TEST(ScalarTest, RightShiftOperator) { int a = 0x00001000; @@ -33,7 +31,7 @@ TEST(ScalarTest, RightShiftOperator) { TEST(ScalarTest, GetBytes) { int a = 0x01020304; long long b = 0x0102030405060708LL; - float c = 1234567.89e32f; + float c = 1234567.89e42; double d = 1234567.89e42; char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; char f[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, @@ -75,12 +73,6 @@ TEST(ScalarTest, CastOperations) { ASSERT_EQ((unsigned long)a, a_scalar.ULong()); ASSERT_EQ((signed long long)a, a_scalar.SLongLong()); ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong()); - - int a2 = 23; - Scalar a2_scalar(a2); - ASSERT_EQ((float)a2, a2_scalar.Float()); - ASSERT_EQ((double)a2, a2_scalar.Double()); - ASSERT_EQ((long double)a2, a2_scalar.LongDouble()); } TEST(ScalarTest, ExtractBitfield) { @@ -140,81 +132,3 @@ TEST(ScalarTest, GetValue) { EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long long>::max()), ScalarGetValue(std::numeric_limits<unsigned long long>::max())); } - -TEST(ScalarTest, Division) { - Scalar lhs(5.0); - Scalar rhs(2.0); - Scalar r = lhs / rhs; - EXPECT_TRUE(r.IsValid()); - EXPECT_EQ(r, Scalar(2.5)); -} - -TEST(ScalarTest, Promotion) { - static Scalar::Type int_types[] = { - Scalar::e_sint, Scalar::e_uint, Scalar::e_slong, - Scalar::e_ulong, Scalar::e_slonglong, Scalar::e_ulonglong, - Scalar::e_sint128, Scalar::e_uint128, Scalar::e_sint256, - Scalar::e_uint256, - Scalar::e_void // sentinel - }; - - static Scalar::Type float_types[] = { - Scalar::e_float, Scalar::e_double, Scalar::e_long_double, - Scalar::e_void // sentinel - }; - - for (int i = 0; int_types[i] != Scalar::e_void; ++i) { - for (int j = 0; float_types[j] != Scalar::e_void; ++j) { - Scalar lhs(2); - EXPECT_TRUE(lhs.Promote(int_types[i])) << "int promotion #" << i; - Scalar rhs(0.5f); - EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j; - Scalar x(2.5f); - EXPECT_TRUE(x.Promote(float_types[j])); - EXPECT_EQ(lhs + rhs, x); - } - } - - for (int i = 0; float_types[i] != Scalar::e_void; ++i) { - for (int j = 0; float_types[j] != Scalar::e_void; ++j) { - Scalar lhs(2); - EXPECT_TRUE(lhs.Promote(float_types[i])) << "float promotion #" << i; - Scalar rhs(0.5f); - EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j; - Scalar x(2.5f); - EXPECT_TRUE(x.Promote(float_types[j])); - EXPECT_EQ(lhs + rhs, x); - } - } -} - -TEST(ScalarTest, SetValueFromCString) { - Scalar a; - - EXPECT_THAT_ERROR( - a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 8).ToError(), - Succeeded()); - EXPECT_EQ(1234567890123ull, a); - - EXPECT_THAT_ERROR( - a.SetValueFromCString("-1234567890123", lldb::eEncodingSint, 8).ToError(), - Succeeded()); - EXPECT_EQ(-1234567890123ll, a); - - EXPECT_THAT_ERROR( - a.SetValueFromCString("asdf", lldb::eEncodingSint, 8).ToError(), - Failed()); - EXPECT_THAT_ERROR( - a.SetValueFromCString("asdf", lldb::eEncodingUint, 8).ToError(), - Failed()); - EXPECT_THAT_ERROR( - a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 4).ToError(), - Failed()); - EXPECT_THAT_ERROR(a.SetValueFromCString("123456789012345678901234567890", - lldb::eEncodingUint, 8) - .ToError(), - Failed()); - EXPECT_THAT_ERROR( - a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(), - Failed()); -} diff --git a/gnu/llvm/tools/llvm-pdbutil/Analyze.cpp b/gnu/llvm/tools/llvm-pdbutil/Analyze.cpp index 974ab49d944..6c603dd8542 100644 --- a/gnu/llvm/tools/llvm-pdbutil/Analyze.cpp +++ b/gnu/llvm/tools/llvm-pdbutil/Analyze.cpp @@ -125,7 +125,7 @@ Error AnalysisStyle::dump() { const auto &Collisions = CollisionsIter->second; outs() << TypeName << "\n"; - outs() << formatv(" [HEAD] {0:x} {1} {2}\n", uint32_t(A.second), + outs() << formatv(" [HEAD] {0:x} {1} {2}\n", A.second, getLeafTypeName(HeadRecord.Type), TypeName); for (const auto &Chain : Collisions) { if (Chain.TI == TI) diff --git a/gnu/llvm/unittests/Analysis/MemorySSA.cpp b/gnu/llvm/unittests/Analysis/MemorySSA.cpp index 0eb543b5477..affa0e71820 100644 --- a/gnu/llvm/unittests/Analysis/MemorySSA.cpp +++ b/gnu/llvm/unittests/Analysis/MemorySSA.cpp @@ -50,7 +50,7 @@ protected: TestAnalyses(MemorySSATest &Test) : DT(*Test.F), AC(*Test.F), AA(Test.TLI), - BAA(Test.DL, *Test.F, Test.TLI, AC, &DT) { + BAA(Test.DL, Test.TLI, AC, &DT) { AA.addAAResult(BAA); MSSA = make_unique<MemorySSA>(*Test.F, &AA, &DT); Walker = MSSA->getWalker(); @@ -909,359 +909,3 @@ TEST_F(MemorySSATest, Irreducible) { Updater.insertUse(LoadAccess); MSSA.verifyMemorySSA(); } - -TEST_F(MemorySSATest, MoveToBeforeLiveOnEntryInvalidatesCache) { - // Create: - // %1 = alloca i8 - // ; 1 = MemoryDef(liveOnEntry) - // store i8 0, i8* %1 - // ; 2 = MemoryDef(1) - // store i8 0, i8* %1 - // - // ...And be sure that MSSA's caching doesn't give us `1` for the clobber of - // `2` after `1` is removed. - IRBuilder<> B(C); - F = Function::Create( - FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false), - GlobalValue::ExternalLinkage, "F", &M); - - BasicBlock *Entry = BasicBlock::Create(C, "if", F); - B.SetInsertPoint(Entry); - - Value *A = B.CreateAlloca(B.getInt8Ty()); - StoreInst *StoreA = B.CreateStore(B.getInt8(0), A); - StoreInst *StoreB = B.CreateStore(B.getInt8(0), A); - - setupAnalyses(); - - MemorySSA &MSSA = *Analyses->MSSA; - - auto *DefA = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA)); - auto *DefB = cast<MemoryDef>(MSSA.getMemoryAccess(StoreB)); - - MemoryAccess *BClobber = MSSA.getWalker()->getClobberingMemoryAccess(DefB); - ASSERT_EQ(DefA, BClobber); - - MemorySSAUpdater(&MSSA).removeMemoryAccess(DefA); - StoreA->eraseFromParent(); - - EXPECT_EQ(DefB->getDefiningAccess(), MSSA.getLiveOnEntryDef()); - - EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefB), - MSSA.getLiveOnEntryDef()) - << "(DefA = " << DefA << ")"; -} - -TEST_F(MemorySSATest, RemovingDefInvalidatesCache) { - // Create: - // %x = alloca i8 - // %y = alloca i8 - // ; 1 = MemoryDef(liveOnEntry) - // store i8 0, i8* %x - // ; 2 = MemoryDef(1) - // store i8 0, i8* %y - // ; 3 = MemoryDef(2) - // store i8 0, i8* %x - // - // And be sure that MSSA's caching handles the removal of def `1` - // appropriately. - IRBuilder<> B(C); - F = Function::Create( - FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false), - GlobalValue::ExternalLinkage, "F", &M); - - BasicBlock *Entry = BasicBlock::Create(C, "if", F); - B.SetInsertPoint(Entry); - - Value *X = B.CreateAlloca(B.getInt8Ty()); - Value *Y = B.CreateAlloca(B.getInt8Ty()); - StoreInst *StoreX1 = B.CreateStore(B.getInt8(0), X); - StoreInst *StoreY = B.CreateStore(B.getInt8(0), Y); - StoreInst *StoreX2 = B.CreateStore(B.getInt8(0), X); - - setupAnalyses(); - - MemorySSA &MSSA = *Analyses->MSSA; - - auto *DefX1 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX1)); - auto *DefY = cast<MemoryDef>(MSSA.getMemoryAccess(StoreY)); - auto *DefX2 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX2)); - - EXPECT_EQ(DefX2->getDefiningAccess(), DefY); - MemoryAccess *X2Clobber = MSSA.getWalker()->getClobberingMemoryAccess(DefX2); - ASSERT_EQ(DefX1, X2Clobber); - - MemorySSAUpdater(&MSSA).removeMemoryAccess(DefX1); - StoreX1->eraseFromParent(); - - EXPECT_EQ(DefX2->getDefiningAccess(), DefY); - EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefX2), - MSSA.getLiveOnEntryDef()) - << "(DefX1 = " << DefX1 << ")"; -} - -// Test Must alias for optimized uses -TEST_F(MemorySSATest, TestLoadMustAlias) { - F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false), - GlobalValue::ExternalLinkage, "F", &M); - B.SetInsertPoint(BasicBlock::Create(C, "", F)); - Type *Int8 = Type::getInt8Ty(C); - Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A"); - Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B"); - - B.CreateStore(ConstantInt::get(Int8, 1), AllocaB); - // Check load from LOE - LoadInst *LA1 = B.CreateLoad(AllocaA, ""); - // Check load alias cached for second load - LoadInst *LA2 = B.CreateLoad(AllocaA, ""); - - B.CreateStore(ConstantInt::get(Int8, 1), AllocaA); - // Check load from store/def - LoadInst *LA3 = B.CreateLoad(AllocaA, ""); - // Check load alias cached for second load - LoadInst *LA4 = B.CreateLoad(AllocaA, ""); - - setupAnalyses(); - MemorySSA &MSSA = *Analyses->MSSA; - - unsigned I = 0; - for (LoadInst *V : {LA1, LA2}) { - MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V)); - EXPECT_EQ(MemUse->getOptimizedAccessType(), None) - << "Load " << I << " doesn't have the correct alias information"; - // EXPECT_EQ expands such that if we increment I above, it won't get - // incremented except when we try to print the error message. - ++I; - } - for (LoadInst *V : {LA3, LA4}) { - MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V)); - EXPECT_EQ(MemUse->getOptimizedAccessType(), MustAlias) - << "Load " << I << " doesn't have the correct alias information"; - // EXPECT_EQ expands such that if we increment I above, it won't get - // incremented except when we try to print the error message. - ++I; - } -} - -// Test Must alias for optimized defs. -TEST_F(MemorySSATest, TestStoreMustAlias) { - F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false), - GlobalValue::ExternalLinkage, "F", &M); - B.SetInsertPoint(BasicBlock::Create(C, "", F)); - Type *Int8 = Type::getInt8Ty(C); - Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A"); - Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B"); - StoreInst *SA1 = B.CreateStore(ConstantInt::get(Int8, 1), AllocaA); - StoreInst *SB1 = B.CreateStore(ConstantInt::get(Int8, 1), AllocaB); - StoreInst *SA2 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaA); - StoreInst *SB2 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaB); - StoreInst *SA3 = B.CreateStore(ConstantInt::get(Int8, 3), AllocaA); - StoreInst *SB3 = B.CreateStore(ConstantInt::get(Int8, 3), AllocaB); - - setupAnalyses(); - MemorySSA &MSSA = *Analyses->MSSA; - MemorySSAWalker *Walker = Analyses->Walker; - - unsigned I = 0; - for (StoreInst *V : {SA1, SB1, SA2, SB2, SA3, SB3}) { - MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V)); - EXPECT_EQ(MemDef->isOptimized(), false) - << "Store " << I << " is optimized from the start?"; - EXPECT_EQ(MemDef->getOptimizedAccessType(), MayAlias) - << "Store " << I - << " has correct alias information before being optimized?"; - if (V == SA1) - Walker->getClobberingMemoryAccess(V); - else { - MemoryAccess *Def = MemDef->getDefiningAccess(); - MemoryAccess *Clob = Walker->getClobberingMemoryAccess(V); - EXPECT_NE(Def, Clob) << "Store " << I - << " has Defining Access equal to Clobbering Access"; - } - EXPECT_EQ(MemDef->isOptimized(), true) - << "Store " << I << " was not optimized"; - if (I == 0 || I == 1) - EXPECT_EQ(MemDef->getOptimizedAccessType(), None) - << "Store " << I << " doesn't have the correct alias information"; - else - EXPECT_EQ(MemDef->getOptimizedAccessType(), MustAlias) - << "Store " << I << " doesn't have the correct alias information"; - // EXPECT_EQ expands such that if we increment I above, it won't get - // incremented except when we try to print the error message. - ++I; - } -} - -// Test May alias for optimized uses. -TEST_F(MemorySSATest, TestLoadMayAlias) { - F = Function::Create(FunctionType::get(B.getVoidTy(), - {B.getInt8PtrTy(), B.getInt8PtrTy()}, - false), - GlobalValue::ExternalLinkage, "F", &M); - B.SetInsertPoint(BasicBlock::Create(C, "", F)); - Type *Int8 = Type::getInt8Ty(C); - auto *ArgIt = F->arg_begin(); - Argument *PointerA = &*ArgIt; - Argument *PointerB = &*(++ArgIt); - B.CreateStore(ConstantInt::get(Int8, 1), PointerB); - LoadInst *LA1 = B.CreateLoad(PointerA, ""); - B.CreateStore(ConstantInt::get(Int8, 0), PointerA); - LoadInst *LB1 = B.CreateLoad(PointerB, ""); - B.CreateStore(ConstantInt::get(Int8, 0), PointerA); - LoadInst *LA2 = B.CreateLoad(PointerA, ""); - B.CreateStore(ConstantInt::get(Int8, 0), PointerB); - LoadInst *LB2 = B.CreateLoad(PointerB, ""); - - setupAnalyses(); - MemorySSA &MSSA = *Analyses->MSSA; - - unsigned I = 0; - for (LoadInst *V : {LA1, LB1}) { - MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V)); - EXPECT_EQ(MemUse->getOptimizedAccessType(), MayAlias) - << "Load " << I << " doesn't have the correct alias information"; - // EXPECT_EQ expands such that if we increment I above, it won't get - // incremented except when we try to print the error message. - ++I; - } - for (LoadInst *V : {LA2, LB2}) { - MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V)); - EXPECT_EQ(MemUse->getOptimizedAccessType(), MustAlias) - << "Load " << I << " doesn't have the correct alias information"; - // EXPECT_EQ expands such that if we increment I above, it won't get - // incremented except when we try to print the error message. - ++I; - } -} - -// Test May alias for optimized defs. -TEST_F(MemorySSATest, TestStoreMayAlias) { - F = Function::Create(FunctionType::get(B.getVoidTy(), - {B.getInt8PtrTy(), B.getInt8PtrTy()}, - false), - GlobalValue::ExternalLinkage, "F", &M); - B.SetInsertPoint(BasicBlock::Create(C, "", F)); - Type *Int8 = Type::getInt8Ty(C); - auto *ArgIt = F->arg_begin(); - Argument *PointerA = &*ArgIt; - Argument *PointerB = &*(++ArgIt); - Value *AllocaC = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "C"); - // Store into arg1, must alias because it's LOE => must - StoreInst *SA1 = B.CreateStore(ConstantInt::get(Int8, 0), PointerA); - // Store into arg2, may alias store to arg1 => may - StoreInst *SB1 = B.CreateStore(ConstantInt::get(Int8, 1), PointerB); - // Store into aloca, no alias with args, so must alias LOE => must - StoreInst *SC1 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaC); - // Store into arg1, may alias store to arg2 => may - StoreInst *SA2 = B.CreateStore(ConstantInt::get(Int8, 3), PointerA); - // Store into arg2, may alias store to arg1 => may - StoreInst *SB2 = B.CreateStore(ConstantInt::get(Int8, 4), PointerB); - // Store into aloca, no alias with args, so must alias SC1 => must - StoreInst *SC2 = B.CreateStore(ConstantInt::get(Int8, 5), AllocaC); - // Store into arg2, must alias store to arg2 => must - StoreInst *SB3 = B.CreateStore(ConstantInt::get(Int8, 6), PointerB); - std::initializer_list<StoreInst *> Sts = {SA1, SB1, SC1, SA2, SB2, SC2, SB3}; - - setupAnalyses(); - MemorySSA &MSSA = *Analyses->MSSA; - MemorySSAWalker *Walker = Analyses->Walker; - - unsigned I = 0; - for (StoreInst *V : Sts) { - MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V)); - EXPECT_EQ(MemDef->isOptimized(), false) - << "Store " << I << " is optimized from the start?"; - EXPECT_EQ(MemDef->getOptimizedAccessType(), MayAlias) - << "Store " << I - << " has correct alias information before being optimized?"; - ++I; - } - - for (StoreInst *V : Sts) - Walker->getClobberingMemoryAccess(V); - - I = 0; - for (StoreInst *V : Sts) { - MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V)); - EXPECT_EQ(MemDef->isOptimized(), true) - << "Store " << I << " was not optimized"; - if (I == 1 || I == 3 || I == 4) - EXPECT_EQ(MemDef->getOptimizedAccessType(), MayAlias) - << "Store " << I << " doesn't have the correct alias information"; - else if (I == 0 || I == 2) - EXPECT_EQ(MemDef->getOptimizedAccessType(), None) - << "Store " << I << " doesn't have the correct alias information"; - else - EXPECT_EQ(MemDef->getOptimizedAccessType(), MustAlias) - << "Store " << I << " doesn't have the correct alias information"; - // EXPECT_EQ expands such that if we increment I above, it won't get - // incremented except when we try to print the error message. - ++I; - } -} - -TEST_F(MemorySSATest, LifetimeMarkersAreClobbers) { - // Example code: - // define void @a(i8* %foo) { - // %bar = getelementptr i8, i8* %foo, i64 1 - // store i8 0, i8* %foo - // store i8 0, i8* %bar - // call void @llvm.lifetime.end.p0i8(i64 8, i32* %p) - // call void @llvm.lifetime.start.p0i8(i64 8, i32* %p) - // store i8 0, i8* %foo - // store i8 0, i8* %bar - // ret void - // } - // - // Patterns like this are possible after inlining; the stores to %foo and %bar - // should both be clobbered by the lifetime.start call if they're dominated by - // it. - - IRBuilder<> B(C); - F = Function::Create( - FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false), - GlobalValue::ExternalLinkage, "F", &M); - - // Make blocks - BasicBlock *Entry = BasicBlock::Create(C, "entry", F); - - B.SetInsertPoint(Entry); - Value *Foo = &*F->arg_begin(); - - Value *Bar = B.CreateGEP(Foo, B.getInt64(1), "bar"); - - B.CreateStore(B.getInt8(0), Foo); - B.CreateStore(B.getInt8(0), Bar); - - auto GetLifetimeIntrinsic = [&](Intrinsic::ID ID) { - return Intrinsic::getDeclaration(&M, ID, {Foo->getType()}); - }; - - B.CreateCall(GetLifetimeIntrinsic(Intrinsic::lifetime_end), - {B.getInt64(2), Foo}); - Instruction *LifetimeStart = B.CreateCall( - GetLifetimeIntrinsic(Intrinsic::lifetime_start), {B.getInt64(2), Foo}); - - Instruction *FooStore = B.CreateStore(B.getInt8(0), Foo); - Instruction *BarStore = B.CreateStore(B.getInt8(0), Bar); - - setupAnalyses(); - MemorySSA &MSSA = *Analyses->MSSA; - - MemoryAccess *LifetimeStartAccess = MSSA.getMemoryAccess(LifetimeStart); - ASSERT_NE(LifetimeStartAccess, nullptr); - - MemoryAccess *FooAccess = MSSA.getMemoryAccess(FooStore); - ASSERT_NE(FooAccess, nullptr); - - MemoryAccess *BarAccess = MSSA.getMemoryAccess(BarStore); - ASSERT_NE(BarAccess, nullptr); - - MemoryAccess *FooClobber = - MSSA.getWalker()->getClobberingMemoryAccess(FooAccess); - EXPECT_EQ(FooClobber, LifetimeStartAccess); - - MemoryAccess *BarClobber = - MSSA.getWalker()->getClobberingMemoryAccess(BarAccess); - EXPECT_EQ(BarClobber, LifetimeStartAccess); -} |