ClangUserExpression.cpp revision 65dafa8344c8c018e346dd331a7782081a896239
165dafa8344c8c018e346dd331a7782081a896239Sean Callanan//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===// 265dafa8344c8c018e346dd331a7782081a896239Sean Callanan// 365dafa8344c8c018e346dd331a7782081a896239Sean Callanan// The LLVM Compiler Infrastructure 465dafa8344c8c018e346dd331a7782081a896239Sean Callanan// 565dafa8344c8c018e346dd331a7782081a896239Sean Callanan// This file is distributed under the University of Illinois Open Source 665dafa8344c8c018e346dd331a7782081a896239Sean Callanan// License. See LICENSE.TXT for details. 765dafa8344c8c018e346dd331a7782081a896239Sean Callanan// 865dafa8344c8c018e346dd331a7782081a896239Sean Callanan//===----------------------------------------------------------------------===// 965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 1065dafa8344c8c018e346dd331a7782081a896239Sean Callanan// C Includes 1165dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <stdio.h> 1265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#if HAVE_SYS_TYPES_H 1365dafa8344c8c018e346dd331a7782081a896239Sean Callanan# include <sys/types.h> 1465dafa8344c8c018e346dd331a7782081a896239Sean Callanan#endif 1565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 1665dafa8344c8c018e346dd331a7782081a896239Sean Callanan// C++ Includes 1765dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <cstdlib> 1865dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <string> 1965dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <map> 2065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 2165dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/ConstString.h" 2265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/Log.h" 2365dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/StreamString.h" 2465dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangExpressionDeclMap.h" 2565dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangExpressionParser.h" 2665dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangFunction.h" 2765dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ASTResultSynthesizer.h" 2865dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangUserExpression.h" 2965dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Host/Host.h" 3065dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/ExecutionContext.h" 3165dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/Target.h" 3265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 3365dafa8344c8c018e346dd331a7782081a896239Sean Callananusing namespace lldb_private; 3465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 3565dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::ClangUserExpression (const char *expr) : 3665dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_expr_text(expr), 3765dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_jit_addr(LLDB_INVALID_ADDRESS) 3865dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 3965dafa8344c8c018e346dd331a7782081a896239Sean Callanan StreamString m_transformed_stream; 4065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 4165dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_transformed_stream.Printf("extern \"C\" void %s(void *___clang_arg) { %s; }\n", 4265dafa8344c8c018e346dd331a7782081a896239Sean Callanan FunctionName(), 4365dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_expr_text.c_str()); 4465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 4565dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_transformed_text = m_transformed_stream.GetData(); 4665dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 4765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 4865dafa8344c8c018e346dd331a7782081a896239Sean Callananclang::ASTConsumer * 4965dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough) 5065dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 5165dafa8344c8c018e346dd331a7782081a896239Sean Callanan return new ASTResultSynthesizer(passthrough); 5265dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 5365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 5465dafa8344c8c018e346dd331a7782081a896239Sean Callananbool 5565dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx) 5665dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 5765dafa8344c8c018e346dd331a7782081a896239Sean Callanan Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 5865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 5965dafa8344c8c018e346dd331a7782081a896239Sean Callanan //////////////////////////////////// 6065dafa8344c8c018e346dd331a7782081a896239Sean Callanan // Set up the target and compiler 6165dafa8344c8c018e346dd331a7782081a896239Sean Callanan // 6265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 6365dafa8344c8c018e346dd331a7782081a896239Sean Callanan Target *target = exe_ctx.target; 6465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 6565dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!target) 6665dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 6765dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.PutCString ("error: invalid target\n"); 6865dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 6965dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 7065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 7165dafa8344c8c018e346dd331a7782081a896239Sean Callanan ConstString target_triple; 7265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 7365dafa8344c8c018e346dd331a7782081a896239Sean Callanan target->GetTargetTriple (target_triple); 7465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 7565dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!target_triple) 7665dafa8344c8c018e346dd331a7782081a896239Sean Callanan target_triple = Host::GetTargetTriple (); 7765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 7865dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!target_triple) 7965dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 8065dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.PutCString ("error: invalid target triple\n"); 8165dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 8265dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 8365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 8465dafa8344c8c018e346dd331a7782081a896239Sean Callanan ////////////////////////// 8565dafa8344c8c018e346dd331a7782081a896239Sean Callanan // Parse the expression 8665dafa8344c8c018e346dd331a7782081a896239Sean Callanan // 8765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 8865dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx)); 8965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 9065dafa8344c8c018e346dd331a7782081a896239Sean Callanan ClangExpressionParser parser(target_triple.GetCString(), *this); 9165dafa8344c8c018e346dd331a7782081a896239Sean Callanan 9265dafa8344c8c018e346dd331a7782081a896239Sean Callanan unsigned num_errors = parser.Parse (error_stream); 9365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 9465dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (num_errors) 9565dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 9665dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf ("error: %d errors parsing expression\n", num_errors); 9765dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 9865dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 9965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 10065dafa8344c8c018e346dd331a7782081a896239Sean Callanan /////////////////////////////////////////////// 10165dafa8344c8c018e346dd331a7782081a896239Sean Callanan // Convert the output of the parser to DWARF 10265dafa8344c8c018e346dd331a7782081a896239Sean Callanan // 10365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 10465dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes.reset(new StreamString); 10565dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes->SetByteOrder (lldb::eByteOrderHost); 10665dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes->GetFlags ().Set (Stream::eBinary); 10765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 10865dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_local_variables.reset(new ClangExpressionVariableStore()); 10965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 11065dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error dwarf_error = parser.MakeDWARF (); 11165dafa8344c8c018e346dd331a7782081a896239Sean Callanan 11265dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (dwarf_error.Success()) 11365dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 11465dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (log) 11565dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Code can be interpreted."); 11665dafa8344c8c018e346dd331a7782081a896239Sean Callanan 11765dafa8344c8c018e346dd331a7782081a896239Sean Callanan return true; 11865dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 11965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 12065dafa8344c8c018e346dd331a7782081a896239Sean Callanan ////////////////////////////////// 12165dafa8344c8c018e346dd331a7782081a896239Sean Callanan // JIT the output of the parser 12265dafa8344c8c018e346dd331a7782081a896239Sean Callanan // 12365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 12465dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes.reset(); 12565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 12665dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error jit_error = parser.MakeJIT (m_jit_addr, exe_ctx); 12765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 12865dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (jit_error.Success()) 12965dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 13065dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (log) 13165dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 13265dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Code can be run in the target."); 13365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 13465dafa8344c8c018e346dd331a7782081a896239Sean Callanan StreamString disassembly_stream; 13565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 13665dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error err = parser.DisassembleFunction(disassembly_stream, exe_ctx); 13765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 13865dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!err.Success()) 13965dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 14065dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error")); 14165dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 14265dafa8344c8c018e346dd331a7782081a896239Sean Callanan else 14365dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 14465dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Function disassembly:\n%s", disassembly_stream.GetData()); 14565dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 14665dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 14765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 14865dafa8344c8c018e346dd331a7782081a896239Sean Callanan return true; 14965dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 15065dafa8344c8c018e346dd331a7782081a896239Sean Callanan else 15165dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 15265dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors); 15365dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 15465dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 15565dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 15665dafa8344c8c018e346dd331a7782081a896239Sean Callanan 15765dafa8344c8c018e346dd331a7782081a896239Sean Callananbool 15865dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::Execute (Stream &error_stream, 15965dafa8344c8c018e346dd331a7782081a896239Sean Callanan ExecutionContext &exe_ctx, 16065dafa8344c8c018e346dd331a7782081a896239Sean Callanan ClangExpressionVariable *&result) 16165dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 16265dafa8344c8c018e346dd331a7782081a896239Sean Callanan Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 16365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 16465dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (m_dwarf_opcodes.get()) 16565dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 16665dafa8344c8c018e346dd331a7782081a896239Sean Callanan // TODO execute the JITted opcodes 16765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 16865dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf("We don't currently support executing DWARF expressions"); 16965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 17065dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 17165dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 17265dafa8344c8c018e346dd331a7782081a896239Sean Callanan else if (m_jit_addr != LLDB_INVALID_ADDRESS) 17365dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 17465dafa8344c8c018e346dd331a7782081a896239Sean Callanan lldb::addr_t struct_address; 17565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 17665dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error materialize_error; 17765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 17865dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!m_expr_decl_map->Materialize(&exe_ctx, struct_address, materialize_error)) 17965dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 18065dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString("unknown error")); 18165dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 18265dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 18365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 18465dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (log) 18565dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 18665dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Function address : 0x%llx", (uint64_t)m_jit_addr); 18765dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Structure address : 0x%llx", (uint64_t)struct_address); 18865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 18965dafa8344c8c018e346dd331a7782081a896239Sean Callanan StreamString args; 19065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 19165dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error dump_error; 19265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 19365dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!m_expr_decl_map->DumpMaterializedStruct(&exe_ctx, args, dump_error)) 19465dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 19565dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error")); 19665dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 19765dafa8344c8c018e346dd331a7782081a896239Sean Callanan else 19865dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 19965dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Structure contents:\n%s", args.GetData()); 20065dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 20165dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 20265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 20365dafa8344c8c018e346dd331a7782081a896239Sean Callanan ClangFunction::ExecutionResults execution_result = 20465dafa8344c8c018e346dd331a7782081a896239Sean Callanan ClangFunction::ExecuteFunction (exe_ctx, m_jit_addr, struct_address, true, true, 10000, error_stream); 20565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 20665dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (execution_result != ClangFunction::eExecutionCompleted) 20765dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 20865dafa8344c8c018e346dd331a7782081a896239Sean Callanan const char *result_name; 20965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 21065dafa8344c8c018e346dd331a7782081a896239Sean Callanan switch (execution_result) 21165dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 21265dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionCompleted: 21365dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionCompleted"; 21465dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 21565dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionDiscarded: 21665dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionDiscarded"; 21765dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 21865dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionInterrupted: 21965dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionInterrupted"; 22065dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 22165dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionSetupError: 22265dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionSetupError"; 22365dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 22465dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionTimedOut: 22565dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionTimedOut"; 22665dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 22765dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 22865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 22965dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf ("Couldn't execute function; result was %s\n", result_name); 23065dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 23165dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 23265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 23365dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error expr_error; 23465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 23565dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!m_expr_decl_map->Dematerialize(&exe_ctx, result, expr_error)) 23665dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 23765dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error")); 23865dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 23965dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 24065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 24165dafa8344c8c018e346dd331a7782081a896239Sean Callanan return true; 24265dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 24365dafa8344c8c018e346dd331a7782081a896239Sean Callanan else 24465dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 24565dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function are present"); 24665dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 24765dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 24865dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 24965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 25065dafa8344c8c018e346dd331a7782081a896239Sean CallananStreamString & 25165dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::DwarfOpcodeStream () 25265dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 25365dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!m_dwarf_opcodes.get()) 25465dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes.reset(new StreamString()); 25565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 25665dafa8344c8c018e346dd331a7782081a896239Sean Callanan return *m_dwarf_opcodes.get(); 25765dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 258