Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions llvm/include/llvm/CodeGen/SDNodeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,3 @@ def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'.
def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'.
def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand
def SDNPVariadic : SDNodeProperty; // Node has variable arguments.
def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match
def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent
8 changes: 8 additions & 0 deletions llvm/include/llvm/Target/TargetSelectionDAG.td
Original file line number Diff line number Diff line change
Expand Up @@ -2086,4 +2086,12 @@ class ComplexPattern<ValueType ty, int numops, string fn,
list<SDNode> RootNodes = roots;
list<SDNodeProperty> Properties = props;
int Complexity = complexity;

// Set this to true if SelectFunc wants an additional argument
// that is the root of the matched pattern.
bit WantsRoot = false;

// Set this to true if SelectFunc wants an additional argument
// that is the parent of the matched node.
bit WantsParent = false;
}
3 changes: 2 additions & 1 deletion llvm/lib/Target/AArch64/SMEInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def tileslicerange2s4 : ComplexPattern<i32, 2, "SelectSMETileSlice<12, 4>", []>;
def tileslicerange1s4 : ComplexPattern<i32, 2, "SelectSMETileSlice<4, 4>", []>;
def tileslicerange0s4 : ComplexPattern<i32, 2, "SelectSMETileSlice<0, 4>", []>;

def am_sme_indexed_b4 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<0,15>", [], [SDNPWantRoot]>;
let WantsRoot = true in
def am_sme_indexed_b4 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<0, 15>">;

def SDTZALoadStore : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisInt<2>]>;
def AArch64SMELdr : SDNode<"AArch64ISD::SME_ZA_LDR", SDTZALoadStore,
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Target/AArch64/SVEInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -9567,8 +9567,10 @@ multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatter
}

/// Addressing modes
def am_sve_indexed_s4 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8,7>", [], [SDNPWantRoot]>;
def am_sve_indexed_s6 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32,31>", [], [SDNPWantRoot]>;
let WantsRoot = true in {
def am_sve_indexed_s4 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8, 7>">;
def am_sve_indexed_s6 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32, 31>">;
}

def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Target/AMDGPU/BUFInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
def MUBUFAddr64 : ComplexPattern<iPTR, 4, "SelectMUBUFAddr64">;
def MUBUFOffset : ComplexPattern<iPTR, 3, "SelectMUBUFOffset">;

def MUBUFScratchOffen : ComplexPattern<iPTR, 4, "SelectMUBUFScratchOffen", [], [SDNPWantParent]>;
def MUBUFScratchOffset : ComplexPattern<iPTR, 3, "SelectMUBUFScratchOffset", [], [SDNPWantParent], 20>;
let WantsParent = true in {
def MUBUFScratchOffen : ComplexPattern<iPTR, 4, "SelectMUBUFScratchOffen">;
def MUBUFScratchOffset : ComplexPattern<iPTR, 3, "SelectMUBUFScratchOffset", [], [], 20>;
}

def BUFSOffset : ComplexPattern<iPTR, 1, "SelectBUFSOffset">;

Expand Down
14 changes: 8 additions & 6 deletions llvm/lib/Target/AMDGPU/FLATInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
//
//===----------------------------------------------------------------------===//

def FlatOffset : ComplexPattern<iPTR, 2, "SelectFlatOffset", [], [SDNPWantRoot], -10>;
def GlobalOffset : ComplexPattern<iPTR, 2, "SelectGlobalOffset", [], [SDNPWantRoot], -10>;
def ScratchOffset : ComplexPattern<iPTR, 2, "SelectScratchOffset", [], [SDNPWantRoot], -10>;
let WantsRoot = true in {
def FlatOffset : ComplexPattern<iPTR, 2, "SelectFlatOffset", [], [], -10>;
def GlobalOffset : ComplexPattern<iPTR, 2, "SelectGlobalOffset", [], [], -10>;
def ScratchOffset : ComplexPattern<iPTR, 2, "SelectScratchOffset", [], [], -10>;

def GlobalSAddr : ComplexPattern<iPTR, 3, "SelectGlobalSAddr", [], [SDNPWantRoot], -10>;
def ScratchSAddr : ComplexPattern<iPTR, 2, "SelectScratchSAddr", [], [SDNPWantRoot], -10>;
def ScratchSVAddr : ComplexPattern<iPTR, 3, "SelectScratchSVAddr", [], [SDNPWantRoot], -10>;
def GlobalSAddr : ComplexPattern<iPTR, 3, "SelectGlobalSAddr", [], [], -10>;
def ScratchSAddr : ComplexPattern<iPTR, 2, "SelectScratchSAddr", [], [], -10>;
def ScratchSVAddr : ComplexPattern<iPTR, 3, "SelectScratchSVAddr", [], [], -10>;
}

//===----------------------------------------------------------------------===//
// FLAT classes
Expand Down
37 changes: 18 additions & 19 deletions llvm/lib/Target/ARM/ARMInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1225,25 +1225,25 @@ def PostIdxRegShiftedAsmOperand : AsmOperandClass {
let ParserMethod = "parsePostIdxReg";
}
def am2offset_reg : MemOperand,
ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg",
[], [SDNPWantRoot]> {
ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg"> {
let EncoderMethod = "getAddrMode2OffsetOpValue";
let PrintMethod = "printAddrMode2OffsetOperand";
// When using this for assembly, it's always as a post-index offset.
let ParserMatchClass = PostIdxRegShiftedAsmOperand;
let MIOperandInfo = (ops GPRnopc, i32imm);
let WantsRoot = true;
}

// FIXME: am2offset_imm should only need the immediate, not the GPR. Having
// the GPR is purely vestigal at this point.
def AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; }
def am2offset_imm : MemOperand,
ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm",
[], [SDNPWantRoot]> {
ComplexPattern<i32, 2, "SelectAddrMode2OffsetImm"> {
let EncoderMethod = "getAddrMode2OffsetOpValue";
let PrintMethod = "printAddrMode2OffsetOperand";
let ParserMatchClass = AM2OffsetImmAsmOperand;
let MIOperandInfo = (ops GPRnopc, i32imm);
let WantsRoot = true;
}


Expand Down Expand Up @@ -1275,13 +1275,12 @@ def AM3OffsetAsmOperand : AsmOperandClass {
let Name = "AM3Offset";
let ParserMethod = "parseAM3Offset";
}
def am3offset : MemOperand,
ComplexPattern<i32, 2, "SelectAddrMode3Offset",
[], [SDNPWantRoot]> {
def am3offset : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode3Offset"> {
let EncoderMethod = "getAddrMode3OffsetOpValue";
let PrintMethod = "printAddrMode3OffsetOperand";
let ParserMatchClass = AM3OffsetAsmOperand;
let MIOperandInfo = (ops GPR, i32imm);
let WantsRoot = true;
}

// ldstm_mode := {ia, ib, da, db}
Expand Down Expand Up @@ -1328,40 +1327,39 @@ def addrmode5fp16 : AddrMode5FP16 {
// addrmode6 := reg with optional alignment
//
def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; }
def addrmode6 : MemOperand,
ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
def addrmode6 : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6"> {
let PrintMethod = "printAddrMode6Operand";
let MIOperandInfo = (ops GPR:$addr, i32imm:$align);
let EncoderMethod = "getAddrMode6AddressOpValue";
let DecoderMethod = "DecodeAddrMode6Operand";
let ParserMatchClass = AddrMode6AsmOperand;
let WantsParent = true;
}

def am6offset : MemOperand,
ComplexPattern<i32, 1, "SelectAddrMode6Offset",
[], [SDNPWantRoot]> {
def am6offset : MemOperand, ComplexPattern<i32, 1, "SelectAddrMode6Offset"> {
let PrintMethod = "printAddrMode6OffsetOperand";
let MIOperandInfo = (ops GPR);
let EncoderMethod = "getAddrMode6OffsetOpValue";
let DecoderMethod = "DecodeGPRRegisterClass";
let WantsRoot = true;
}

// Special version of addrmode6 to handle alignment encoding for VST1/VLD1
// (single element from one lane) for size 32.
def addrmode6oneL32 : MemOperand,
ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
def addrmode6oneL32 : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6"> {
let PrintMethod = "printAddrMode6Operand";
let MIOperandInfo = (ops GPR:$addr, i32imm);
let EncoderMethod = "getAddrMode6OneLane32AddressOpValue";
let WantsParent = true;
}

// Base class for addrmode6 with specific alignment restrictions.
class AddrMode6Align : MemOperand,
ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
class AddrMode6Align : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6"> {
let PrintMethod = "printAddrMode6Operand";
let MIOperandInfo = (ops GPR:$addr, i32imm:$align);
let EncoderMethod = "getAddrMode6AddressOpValue";
let DecoderMethod = "DecodeAddrMode6Operand";
let WantsParent = true;
}

// Special version of addrmode6 to handle no allowed alignment encoding for
Expand Down Expand Up @@ -1432,22 +1430,23 @@ def addrmode6align64or128or256 : AddrMode6Align {

// Special version of addrmode6 to handle alignment encoding for VLD-dup
// instructions, specifically VLD4-dup.
def addrmode6dup : MemOperand,
ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
def addrmode6dup : MemOperand, ComplexPattern<i32, 2, "SelectAddrMode6"> {
let PrintMethod = "printAddrMode6Operand";
let MIOperandInfo = (ops GPR:$addr, i32imm);
let EncoderMethod = "getAddrMode6DupAddressOpValue";
// FIXME: This is close, but not quite right. The alignment specifier is
// different.
let ParserMatchClass = AddrMode6AsmOperand;
let WantsParent = true;
}

// Base class for addrmode6dup with specific alignment restrictions.
class AddrMode6DupAlign : MemOperand,
ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
ComplexPattern<i32, 2, "SelectAddrMode6"> {
let PrintMethod = "printAddrMode6Operand";
let MIOperandInfo = (ops GPR:$addr, i32imm);
let EncoderMethod = "getAddrMode6DupAddressOpValue";
let WantsParent = true;
}

// Special version of addrmode6 to handle no allowed alignment encoding for
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Target/ARM/ARMInstrMVE.td
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,16 @@ def t2am_imm7shift0OffsetAsmOperand : t2am_imm7shiftOffsetAsmOperand<0>;
def t2am_imm7shift1OffsetAsmOperand : t2am_imm7shiftOffsetAsmOperand<1>;
def t2am_imm7shift2OffsetAsmOperand : t2am_imm7shiftOffsetAsmOperand<2>;

class t2am_imm7_offset<int shift> : MemOperand,
ComplexPattern<i32, 1, "SelectT2AddrModeImm7Offset<"#shift#">",
[], [SDNPWantRoot]> {
class t2am_imm7_offset<int shift>
: MemOperand,
ComplexPattern<i32, 1, "SelectT2AddrModeImm7Offset<"#shift#">"> {
// They are printed the same way as the imm8 version
let PrintMethod = "printT2AddrModeImm8OffsetOperand";
let ParserMatchClass =
!cast<AsmOperandClass>("t2am_imm7shift"#shift#"OffsetAsmOperand");
let EncoderMethod = "getT2ScaledImmOpValue<7,"#shift#">";
let DecoderMethod = "DecodeT2Imm7<"#shift#">";
let WantsRoot = true;
}

// Operands for gather/scatter loads of the form [Rbase, Qoffsets]
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/ARM/ARMInstrThumb.td
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ def t_addrmode_sp : MemOperand,

// Inspects parent to determine whether an or instruction can be implemented as
// an add (i.e. whether we know overflow won't occur in the add).
def AddLikeOrOp : ComplexPattern<i32, 1, "SelectAddLikeOr", [],
[SDNPWantParent]>;
let WantsParent = true in
def AddLikeOrOp : ComplexPattern<i32, 1, "SelectAddLikeOr">;

// Pattern to exclude immediates from matching
def non_imm32 : PatLeaf<(i32 GPR), [{ return !isa<ConstantSDNode>(N); }]>;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/ARM/ARMInstrThumb2.td
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,11 @@ def t2addrmode_imm8_pre : T2AddrMode_Imm8 {
}

def t2am_imm8_offset : MemOperand,
ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
[], [SDNPWantRoot]> {
ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset"> {
let PrintMethod = "printT2AddrModeImm8OffsetOperand";
let EncoderMethod = "getT2AddrModeImm8OffsetOpValue";
let DecoderMethod = "DecodeT2Imm8";
let WantsRoot = true;
}

// t2addrmode_imm8s4 := reg +/- (imm8 << 2)
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/AVR/AVRInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ def imm_port6 : Operand<i8> {
}

// Addressing mode pattern reg+imm6
def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], [SDNPWantRoot]>;
let WantsRoot = true in
def addr : ComplexPattern<iPTR, 2, "SelectAddr">;

//===----------------------------------------------------------------------===//
// AVR predicates for subtarget features
Expand Down
36 changes: 15 additions & 21 deletions llvm/lib/Target/M68k/M68kInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -466,34 +466,28 @@ def MxCONDle : PatLeaf<(i8 15)>; // Less or Equal

// NOTE Though this CP is not strictly necessarily it will simplify instruciton
// definitions
def MxCP_ARI : ComplexPattern<iPTR, 1, "SelectARI",
[], [SDNPWantParent]>;
let WantsParent = true in {
def MxCP_ARI : ComplexPattern<iPTR, 1, "SelectARI">;

def MxCP_ARIPI : ComplexPattern<iPTR, 1, "SelectARIPI",
[], [SDNPWantParent]>;
def MxCP_ARIPI : ComplexPattern<iPTR, 1, "SelectARIPI">;

def MxCP_ARIPD : ComplexPattern<iPTR, 1, "SelectARIPD",
[], [SDNPWantParent]>;
def MxCP_ARIPD : ComplexPattern<iPTR, 1, "SelectARIPD">;

def MxCP_ARID : ComplexPattern<iPTR, 2, "SelectARID",
[add, sub, mul, or, shl, frameindex],
[SDNPWantParent]>;
def MxCP_ARID : ComplexPattern<iPTR, 2, "SelectARID",
[add, sub, mul, or, shl, frameindex]>;

def MxCP_ARII : ComplexPattern<iPTR, 3, "SelectARII",
[add, sub, mul, or, shl, frameindex],
[SDNPWantParent]>;
def MxCP_ARII : ComplexPattern<iPTR, 3, "SelectARII",
[add, sub, mul, or, shl, frameindex]>;

def MxCP_AL : ComplexPattern<iPTR, 1, "SelectAL",
[add, sub, mul, or, shl],
[SDNPWantParent]>;
def MxCP_AL : ComplexPattern<iPTR, 1, "SelectAL",
[add, sub, mul, or, shl]>;

def MxCP_PCD : ComplexPattern<iPTR, 1, "SelectPCD",
[add, sub, mul, or, shl],
[SDNPWantParent]>;

def MxCP_PCI : ComplexPattern<iPTR, 2, "SelectPCI",
[add, sub, mul, or, shl], [SDNPWantParent]>;
def MxCP_PCD : ComplexPattern<iPTR, 1, "SelectPCD",
[add, sub, mul, or, shl]>;

def MxCP_PCI : ComplexPattern<iPTR, 2, "SelectPCI",
[add, sub, mul, or, shl]>;
}

//===----------------------------------------------------------------------===//
// Pattern Fragments
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1907,10 +1907,10 @@ defm SET_f64 : SET<"f64", Float64Regs, f64imm>;
// Data Movement (Load / Store, Move)
//-----------------------------------

def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex],
[SDNPWantRoot]>;
def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri64", [frameindex],
[SDNPWantRoot]>;
let WantsRoot = true in {
def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex]>;
def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri64", [frameindex]>;
}
def ADDRvar : ComplexPattern<iPTR, 1, "SelectDirectAddr", [], []>;

def MEMri : Operand<i32> {
Expand Down
16 changes: 9 additions & 7 deletions llvm/lib/Target/PowerPC/PPCInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -686,13 +686,15 @@ def addr : ComplexPattern<iPTR, 1, "SelectAddr",[], []>;
def iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>;

// Load and Store Instruction Selection addressing modes.
def DForm : ComplexPattern<iPTR, 2, "SelectDForm", [], [SDNPWantParent]>;
def DSForm : ComplexPattern<iPTR, 2, "SelectDSForm", [], [SDNPWantParent]>;
def DQForm : ComplexPattern<iPTR, 2, "SelectDQForm", [], [SDNPWantParent]>;
def XForm : ComplexPattern<iPTR, 2, "SelectXForm", [], [SDNPWantParent]>;
def ForceXForm : ComplexPattern<iPTR, 2, "SelectForceXForm", [], [SDNPWantParent]>;
def PCRelForm : ComplexPattern<iPTR, 2, "SelectPCRelForm", [], [SDNPWantParent]>;
def PDForm : ComplexPattern<iPTR, 2, "SelectPDForm", [], [SDNPWantParent]>;
let WantsParent = true in {
def DForm : ComplexPattern<iPTR, 2, "SelectDForm">;
def DSForm : ComplexPattern<iPTR, 2, "SelectDSForm">;
def DQForm : ComplexPattern<iPTR, 2, "SelectDQForm">;
def XForm : ComplexPattern<iPTR, 2, "SelectXForm">;
def ForceXForm : ComplexPattern<iPTR, 2, "SelectForceXForm">;
def PCRelForm : ComplexPattern<iPTR, 2, "SelectPCRelForm">;
def PDForm : ComplexPattern<iPTR, 2, "SelectPDForm">;
}

//===----------------------------------------------------------------------===//
// PowerPC Instruction Predicate Definitions.
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Target/X86/X86InstrFragments.td
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,8 @@ def X86cmpccxadd : SDNode<"X86ISD::CMPCCXADD", SDTX86Cmpccxadd,
SDNPMemOperand]>;

// Define X86-specific addressing mode.
def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
let WantsParent = true in
def addr : ComplexPattern<iPTR, 5, "selectAddr">;
def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
[add, sub, mul, X86mul_imm, shl, or, xor, frameindex],
[]>;
Expand All @@ -378,7 +379,8 @@ def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
[tglobaltlsaddr], []>;

def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
let WantsParent = true in
def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr">;

// A relocatable immediate is an operand that can be relocated by the linker to
// an immediate, such as a regular symbol in non-PIC code.
Expand Down
2 changes: 0 additions & 2 deletions llvm/utils/TableGen/Basic/SDNodeProperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ enum SDNP {
SDNPSideEffect,
SDNPMemOperand,
SDNPVariadic,
SDNPWantRoot,
SDNPWantParent
};

unsigned parseSDPatternOperatorProperties(const Record *R);
Expand Down
7 changes: 3 additions & 4 deletions llvm/utils/TableGen/Common/CodeGenTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,14 +424,13 @@ ComplexPattern::ComplexPattern(const Record *R) {
Properties |= 1 << SDNPMemOperand;
} else if (Prop->getName() == "SDNPVariadic") {
Properties |= 1 << SDNPVariadic;
} else if (Prop->getName() == "SDNPWantRoot") {
Properties |= 1 << SDNPWantRoot;
} else if (Prop->getName() == "SDNPWantParent") {
Properties |= 1 << SDNPWantParent;
} else {
PrintFatalError(R->getLoc(),
"Unsupported SD Node property '" + Prop->getName() +
"' on ComplexPattern '" + R->getName() + "'!");
}
}

WantsRoot = R->getValueAsBit("WantsRoot");
WantsParent = R->getValueAsBit("WantsParent");
}
Loading
Loading