AsmWriterEmitter.cpp revision b0b55e74a090454711b1bb17e4f872d62d6e6b65
12e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===// 22e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// 32e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// The LLVM Compiler Infrastructure 42e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// 52e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// This file was developed by the LLVM research group and is distributed under 62e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details. 72e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// 82e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===----------------------------------------------------------------------===// 92e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// 102e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// This tablegen backend is emits an assembly printer for the current target. 112e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// Note that this is currently fairly skeletal, but will grow over time. 122e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// 132e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===----------------------------------------------------------------------===// 142e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 152e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "AsmWriterEmitter.h" 162e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "CodeGenTarget.h" 17175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner#include "Record.h" 182e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include <ostream> 192e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattnerusing namespace llvm; 202e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 21076efa771aa634801202f7b8189e33ee79dfc4edChris Lattnerstatic bool isIdentChar(char C) { 22076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner return (C >= 'a' && C <= 'z') || 23076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner (C >= 'A' && C <= 'Z') || 24076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner (C >= '0' && C <= '9') || 25076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner C == '_'; 26076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner} 27076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner 28b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattnernamespace { 29b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner struct AsmWriterOperand { 30b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner enum { isLiteralTextOperand, isMachineInstrOperand } OperandType; 31b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 32b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// Str - For isLiteralTextOperand, this IS the literal text. For 33b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// isMachineInstrOperand, this is the PrinterMethodName for the operand. 34b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string Str; 35b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 36b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// MiOpNo - For isMachineInstrOperand, this is the operand number of the 37b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// machine instruction. 38b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner unsigned MIOpNo; 39b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 40b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// OpVT - For isMachineInstrOperand, this is the value type for the 41b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// operand. 42b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner MVT::ValueType OpVT; 43b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 44b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmWriterOperand(const std::string &LitStr) 45b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner : OperandType(isLiteralTextOperand), Str(LitStr) {} 46b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 47b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmWriterOperand(const std::string &Printer, unsigned OpNo, 48b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner MVT::ValueType VT) : OperandType(isMachineInstrOperand), 49b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Str(Printer), MIOpNo(OpNo), OpVT(VT){} 50b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 51b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner void EmitCode(std::ostream &OS) const; 52b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner }; 53b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 54b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner struct AsmWriterInst { 55b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::vector<AsmWriterOperand> Operands; 56b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 57b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner void ParseAsmString(const CodeGenInstruction &CGI, unsigned Variant); 58b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner void EmitCode(std::ostream &OS) const { 59b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner for (unsigned i = 0, e = Operands.size(); i != e; ++i) 60b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Operands[i].EmitCode(OS); 61b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 62b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner private: 63b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner void AddLiteralString(const std::string &Str) { 64b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // If the last operand was already a literal text string, append this to 65b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // it, otherwise add a new operand. 66b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (!Operands.empty() && 67b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand) 68b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Operands.back().Str.append(Str); 69b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner else 70b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Operands.push_back(AsmWriterOperand(Str)); 71b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 72b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner }; 73b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner} 74b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 75b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 76b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattnervoid AsmWriterOperand::EmitCode(std::ostream &OS) const { 77b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (OperandType == isLiteralTextOperand) 78b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner OS << "O << \"" << Str << "\"; "; 79b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner else 80b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner OS << Str << "(MI, " << MIOpNo << ", MVT::" << getName(OpVT) << "); "; 81b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner} 82b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 83b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 84b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner/// ParseAsmString - Parse the specified Instruction's AsmString into this 85b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner/// AsmWriterInst. 86b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner/// 87b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattnervoid AsmWriterInst::ParseAsmString(const CodeGenInstruction &CGI, 88b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner unsigned Variant) { 89b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner bool inVariant = false; // True if we are inside a {.|.|.} region. 90b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 91b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner const std::string &AsmString = CGI.AsmString; 92b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string::size_type LastEmitted = 0; 93b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner while (LastEmitted != AsmString.size()) { 94b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string::size_type DollarPos = 95b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmString.find_first_of("${|}", LastEmitted); 96b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (DollarPos == std::string::npos) DollarPos = AsmString.size(); 97b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 98b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // Emit a constant string fragment. 99b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (DollarPos != LastEmitted) { 100b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // TODO: this should eventually handle escaping. 101b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AddLiteralString(std::string(AsmString.begin()+LastEmitted, 102b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmString.begin()+DollarPos)); 103b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = DollarPos; 104b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else if (AsmString[DollarPos] == '{') { 105b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (inVariant) 106b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "Nested variants found for instruction '" + CGI.Name + "'!"; 107b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = DollarPos+1; 108b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner inVariant = true; // We are now inside of the variant! 109b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner for (unsigned i = 0; i != Variant; ++i) { 110b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // Skip over all of the text for an irrelevant variant here. The 111b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // next variant starts at |, or there may not be text for this 112b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // variant if we see a }. 113b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string::size_type NP = 114b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmString.find_first_of("|}", LastEmitted); 115b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (NP == std::string::npos) 116b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "Incomplete variant for instruction '" + CGI.Name + "'!"; 117b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = NP+1; 118b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (AsmString[NP] == '}') { 119b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner inVariant = false; // No text for this variant. 120b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner break; 121b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 122b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 123b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else if (AsmString[DollarPos] == '|') { 124b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (!inVariant) 125b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "'|' character found outside of a variant in instruction '" 126b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner + CGI.Name + "'!"; 127b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // Move to the end of variant list. 128b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string::size_type NP = AsmString.find('}', LastEmitted); 129b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (NP == std::string::npos) 130b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "Incomplete variant for instruction '" + CGI.Name + "'!"; 131b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = NP+1; 132b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner inVariant = false; 133b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else if (AsmString[DollarPos] == '}') { 134b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (!inVariant) 135b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "'}' character found outside of a variant in instruction '" 136b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner + CGI.Name + "'!"; 137b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = DollarPos+1; 138b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner inVariant = false; 139b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else if (DollarPos+1 != AsmString.size() && 140b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmString[DollarPos+1] == '$') { 141b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AddLiteralString("$"); // "$$" -> $ 142b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = DollarPos+2; 143b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else { 144b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // Get the name of the variable. 145b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // TODO: should eventually handle ${foo}bar as $foo 146b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string::size_type VarEnd = DollarPos+1; 147b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd])) 148b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner ++VarEnd; 149b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string VarName(AsmString.begin()+DollarPos+1, 150b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmString.begin()+VarEnd); 151b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (VarName.empty()) 152b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "Stray '$' in '" + CGI.Name + "' asm string, maybe you want $$?"; 153b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 154b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner unsigned OpNo = CGI.getOperandNamed(VarName); 155b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 156b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // If this is a two-address instruction and we are not accessing the 157b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // 0th operand, remove an operand. 158b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner unsigned MIOp = CGI.OperandList[OpNo].MIOperandNo; 159b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (CGI.isTwoAddress && MIOp != 0) { 160b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (MIOp == 1) 161b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "Should refer to operand #0 instead of #1 for two-address" 162b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner " instruction '" + CGI.Name + "'!"; 163b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner --MIOp; 164b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 165b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 166b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Operands.push_back(AsmWriterOperand(CGI.OperandList[OpNo].PrinterMethodName, 167b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner MIOp, CGI.OperandList[OpNo].Ty)); 168b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = VarEnd; 169b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 170b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 171b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 172b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AddLiteralString("\\n"); 173b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner} 174b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 175b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 1762e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattnervoid AsmWriterEmitter::run(std::ostream &O) { 1772e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner EmitSourceFileHeader("Assembly Writer Source Fragment", O); 1782e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 1792e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner CodeGenTarget Target; 180175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner Record *AsmWriter = Target.getAsmWriter(); 181953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 182953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner unsigned Variant = AsmWriter->getValueAsInt("Variant"); 183175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner 1842e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner O << 1852e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// printInstruction - This method is automatically generated by tablegen\n" 1862e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// from the instruction set description. This method returns true if the\n" 1872e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// machine instruction was sufficiently described to print it, otherwise\n" 1882e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// it returns false.\n" 189953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner "bool " << Target.getName() << ClassName 190175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner << "::printInstruction(const MachineInstr *MI) {\n"; 1912e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner O << " switch (MI->getOpcode()) {\n" 1922e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner " default: return false;\n"; 1932e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 1942e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner std::string Namespace = Target.inst_begin()->second.Namespace; 1952e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 1962e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 1972e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner E = Target.inst_end(); I != E; ++I) 1982e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner if (!I->second.AsmString.empty()) { 199b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner O << " case " << Namespace << "::" << I->first << ": "; 200076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner 201b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmWriterInst AWI; 202b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AWI.ParseAsmString(I->second, Variant); 203b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AWI.EmitCode(O); 204b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner O << " break;\n"; 2052e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner } 2062e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 2072e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner O << " }\n" 2082e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner " return true;\n" 2092e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "}\n"; 2102e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner} 211