blob: b3aecebaeacc75c8d1d23bed873efdcf79d2535e [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangStmtVisitor.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/ClangStmtVisitor.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15#include "clang/AST/RecordLayout.h"
16
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/dwarf.h"
18#include "lldb/Core/Scalar.h"
19#include "lldb/Core/StreamString.h"
20#include "lldb/Expression/ClangExpressionDeclMap.h"
21#include "lldb/Expression/ClangExpressionVariable.h"
22
23//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
24#ifdef ENABLE_DEBUG_PRINTF
25#include <stdio.h>
26#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
27#else
28#define DEBUG_PRINTF(fmt, ...)
29#endif
30
31// Project includes
32
33static lldb_private::Scalar::Type
34GetScalarTypeForClangType (clang::ASTContext &ast_context, clang::QualType clang_type, uint32_t &count)
35{
36 count = 1;
37
38 switch (clang_type->getTypeClass())
39 {
40 case clang::Type::FunctionNoProto:
41 case clang::Type::FunctionProto:
42 break;
43
44 case clang::Type::IncompleteArray:
45 case clang::Type::VariableArray:
46 break;
47
48 case clang::Type::ConstantArray:
49 break;
50
51 case clang::Type::ExtVector:
52 case clang::Type::Vector:
53 // TODO: Set this to more than one???
54 break;
55
56 case clang::Type::Builtin:
57 switch (cast<clang::BuiltinType>(clang_type)->getKind())
58 {
59 default: assert(0 && "Unknown builtin type!");
60 case clang::BuiltinType::Void:
61 break;
62
63 case clang::BuiltinType::Bool:
64 case clang::BuiltinType::Char_S:
65 case clang::BuiltinType::SChar:
66 case clang::BuiltinType::WChar:
67 case clang::BuiltinType::Char16:
68 case clang::BuiltinType::Char32:
69 case clang::BuiltinType::Short:
70 case clang::BuiltinType::Int:
71 case clang::BuiltinType::Long:
72 case clang::BuiltinType::LongLong:
73 case clang::BuiltinType::Int128:
74 return lldb_private::Scalar::GetValueTypeForSignedIntegerWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count);
75
76 case clang::BuiltinType::Char_U:
77 case clang::BuiltinType::UChar:
78 case clang::BuiltinType::UShort:
79 case clang::BuiltinType::UInt:
80 case clang::BuiltinType::ULong:
81 case clang::BuiltinType::ULongLong:
82 case clang::BuiltinType::UInt128:
83 case clang::BuiltinType::NullPtr:
84 return lldb_private::Scalar::GetValueTypeForUnsignedIntegerWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count);
85
86 case clang::BuiltinType::Float:
87 case clang::BuiltinType::Double:
88 case clang::BuiltinType::LongDouble:
89 return lldb_private::Scalar::GetValueTypeForFloatWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count);
90 }
91 break;
92 // All pointer types are represented as unsigned integer encodings.
93 // We may nee to add a eEncodingPointer if we ever need to know the
94 // difference
95 case clang::Type::ObjCObjectPointer:
96 case clang::Type::BlockPointer:
97 case clang::Type::Pointer:
98 case clang::Type::LValueReference:
99 case clang::Type::RValueReference:
100 case clang::Type::MemberPointer:
101 return lldb_private::Scalar::GetValueTypeForUnsignedIntegerWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count);
102
103 // Complex numbers are made up of floats
104 case clang::Type::Complex:
105 count = 2;
106 return lldb_private::Scalar::GetValueTypeForFloatWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT) / count);
107
108 case clang::Type::ObjCInterface: break;
109 case clang::Type::Record: break;
110 case clang::Type::Enum:
111 return lldb_private::Scalar::GetValueTypeForSignedIntegerWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count);
112
113 case clang::Type::Typedef:
114 return GetScalarTypeForClangType(ast_context, cast<clang::TypedefType>(clang_type)->LookThroughTypedefs(), count);
115 break;
116
117 case clang::Type::TypeOfExpr:
118 case clang::Type::TypeOf:
119 case clang::Type::Decltype:
120 //case clang::Type::QualifiedName:
121 case clang::Type::TemplateSpecialization: break;
122 }
123 count = 0;
124 return lldb_private::Scalar::e_void;
125}
126
127//----------------------------------------------------------------------
128// ClangStmtVisitor constructor
129//----------------------------------------------------------------------
130lldb_private::ClangStmtVisitor::ClangStmtVisitor
131(
132 clang::ASTContext &ast_context,
133 lldb_private::ClangExpressionVariableList &variable_list,
134 lldb_private::ClangExpressionDeclMap *decl_map,
135 lldb_private::StreamString &strm
136) :
137 m_ast_context (ast_context),
138 m_variable_list (variable_list),
139 m_decl_map (decl_map),
140 m_stream (strm)
141{
142}
143
144//----------------------------------------------------------------------
145// Destructor
146//----------------------------------------------------------------------
147lldb_private::ClangStmtVisitor::~ClangStmtVisitor()
148{
149}
150
151CLANG_STMT_RESULT
152lldb_private::ClangStmtVisitor::VisitStmt (clang::Stmt *Node)
153{
154 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
155
156 clang::Stmt::child_iterator pos;
157 clang::Stmt::child_iterator begin = Node->child_begin();
158 clang::Stmt::child_iterator end = Node->child_end();
159 bool clear_before_next_stmt = false;
160 for (pos = begin; pos != end; ++pos)
161 {
162#ifdef ENABLE_DEBUG_PRINTF
163 pos->dump();
164#endif
165 clang::Stmt *child_stmt = *pos;
166 uint32_t pre_visit_stream_offset = m_stream.GetSize();
167 bool not_null_stmt = dyn_cast<clang::NullStmt>(child_stmt) == NULL;
168 if (clear_before_next_stmt && not_null_stmt)
169 m_stream.PutHex8(DW_OP_APPLE_clear);
170 Visit (child_stmt);
171 if (not_null_stmt)
172 clear_before_next_stmt = pre_visit_stream_offset != m_stream.GetSize();
173 }
174}
175
176CLANG_STMT_RESULT
177lldb_private::ClangStmtVisitor::VisitDeclStmt (clang::DeclStmt *decl_stmt)
178{
179 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
180 clang::DeclGroupRef decl_group_ref = decl_stmt->getDeclGroup();
181 clang::DeclGroupRef::iterator pos, end = decl_group_ref.end();
182 for (pos = decl_group_ref.begin(); pos != end; ++pos)
183 {
184 clang::Decl *decl = *pos;
185 if (decl)
186 {
187 clang::Decl::Kind decl_kind = decl->getKind();
188
189 switch (decl_kind)
190 {
191 case clang::Decl::Namespace:
192 case clang::Decl::Enum:
193 case clang::Decl::Record:
194 case clang::Decl::CXXRecord:
195 case clang::Decl::ObjCMethod:
196 case clang::Decl::ObjCInterface:
197 case clang::Decl::ObjCCategory:
198 case clang::Decl::ObjCProtocol:
199 case clang::Decl::ObjCImplementation:
200 case clang::Decl::ObjCCategoryImpl:
201 case clang::Decl::LinkageSpec:
202 case clang::Decl::Block:
203 case clang::Decl::Function:
204 case clang::Decl::CXXMethod:
205 case clang::Decl::CXXConstructor:
206 case clang::Decl::CXXDestructor:
207 case clang::Decl::CXXConversion:
208 case clang::Decl::Field:
209 case clang::Decl::Typedef:
210 case clang::Decl::EnumConstant:
211 case clang::Decl::ImplicitParam:
212 case clang::Decl::ParmVar:
213 case clang::Decl::ObjCProperty:
214 break;
215
216 case clang::Decl::Var:
217 {
218 const clang::VarDecl *var_decl = cast<clang::VarDecl>(decl)->getCanonicalDecl();
219 uint32_t expr_local_var_idx = UINT32_MAX;
220 if (m_variable_list.GetVariableForVarDecl (m_ast_context, var_decl, expr_local_var_idx, true))
221 {
222 const clang::Expr* var_decl_expr = var_decl->getAnyInitializer();
223 // If there is an inialization expression, then assign the
224 // variable.
225 if (var_decl_expr)
226 {
227 m_stream.PutHex8(DW_OP_APPLE_expr_local);
228 m_stream.PutULEB128(expr_local_var_idx);
229 Visit ((clang::Stmt *)var_decl_expr);
230 m_stream.PutHex8(DW_OP_APPLE_assign);
231 }
232 }
233 }
234 break;
235
236 default:
237 assert(!"decl unhandled");
238 break;
239 }
240 }
241 }
242}
243
244CLANG_STMT_RESULT
245lldb_private::ClangStmtVisitor::VisitLabelStmt (clang::LabelStmt *Node)
246{
247 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
248}
249
250
251CLANG_STMT_RESULT
252lldb_private::ClangStmtVisitor::VisitGotoStmt (clang::GotoStmt *Node)
253{
254 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
255}
256
257
258// Exprs
259CLANG_STMT_RESULT
260lldb_private::ClangStmtVisitor::VisitExpr (clang::Expr *Node)
261{
262 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
263}
264
265
266CLANG_STMT_RESULT
267lldb_private::ClangStmtVisitor::VisitDeclRefExpr (clang::DeclRefExpr *Node)
268{
269 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
270 clang::NamedDecl *decl = Node->getDecl();
271 clang::QualType clang_type = Node->getType();
272
273#ifdef ENABLE_DEBUG_PRINTF
274 //decl->dump();
275 //clang_type.dump("lldb_private::ClangStmtVisitor::VisitDeclRefExpr() -> clang_type.dump() = ");
276#endif
277 uint32_t expr_local_var_idx = UINT32_MAX;
278 if (m_variable_list.GetVariableForVarDecl (m_ast_context, cast<clang::VarDecl>(decl)->getCanonicalDecl(), expr_local_var_idx, false) &&
279 expr_local_var_idx != UINT32_MAX)
280 {
281 m_stream.PutHex8(DW_OP_APPLE_expr_local);
282 m_stream.PutULEB128(expr_local_var_idx);
283 }
284 else if (m_decl_map &&
285 m_decl_map->GetIndexForDecl(expr_local_var_idx, decl->getCanonicalDecl()))
286 {
287 m_stream.PutHex8(DW_OP_APPLE_extern);
288 m_stream.PutULEB128(expr_local_var_idx);
289 }
290 else
291 {
292 m_stream.PutHex8 (DW_OP_APPLE_error);
293 }
294}
295
296
297CLANG_STMT_RESULT
298lldb_private::ClangStmtVisitor::VisitPredefinedExpr (clang::PredefinedExpr *Node)
299{
300 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
301}
302
303
304CLANG_STMT_RESULT
305lldb_private::ClangStmtVisitor::VisitCharacterLiteral (clang::CharacterLiteral *Node)
306{
307 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
308 clang::QualType clang_type = Node->getType();
309 uint64_t clang_type_size = m_ast_context.getTypeSize (clang_type);
310 if (clang_type_size <= 64)
311 {
312 // Encode the integer into our DWARF expression
313 if (clang_type->isSignedIntegerType())
314 EncodeSInt64(Node->getValue(), clang_type_size);
315 else
316 EncodeUInt64(Node->getValue(), clang_type_size);
317 }
318 else
319 {
320 // TODO: eventually support integer math over 64 bits, probably using
321 // APInt as the class.
322 m_stream.PutHex8(DW_OP_APPLE_error);
323 }
324}
325
326bool
327lldb_private::ClangStmtVisitor::EncodeUInt64 (uint64_t uval, uint32_t bit_size)
328{
329 // If "bit_size" is zero, then encode "uval" in the most efficient way
330 if (bit_size <= 8 || (bit_size == 0 && uval <= UINT8_MAX))
331 {
332 m_stream.PutHex8 (DW_OP_const1u);
333 m_stream.PutHex8 (uval);
334 }
335 else if (bit_size <= 16 || (bit_size == 0 && uval <= UINT16_MAX))
336 {
337 m_stream.PutHex8 (DW_OP_const2u);
338 m_stream.PutHex16 (uval);
339 }
340 else if (bit_size <= 32 || (bit_size == 0 && uval <= UINT32_MAX))
341 {
342 m_stream.PutHex8 (DW_OP_const4u);
343 m_stream.PutHex32 (uval);
344 }
345 else if (bit_size <= 64 || (bit_size == 0))
346 {
347 m_stream.PutHex8 (DW_OP_const8u);
348 m_stream.PutHex64 (uval);
349 }
350 else
351 {
352 m_stream.PutHex8 (DW_OP_APPLE_error);
353 return false;
354 }
355 return true;
356}
357
358bool
359lldb_private::ClangStmtVisitor::EncodeSInt64 (int64_t sval, uint32_t bit_size)
360{
361 if (bit_size <= 8 || (bit_size == 0 && INT8_MIN <= sval && sval <= INT8_MAX))
362 {
363 m_stream.PutHex8 (DW_OP_const1s);
364 m_stream.PutHex8 (sval);
365 }
366 else if (bit_size <= 16 || (bit_size == 0 && INT16_MIN <= sval && sval <= INT16_MAX))
367 {
368 m_stream.PutHex8 (DW_OP_const2s);
369 m_stream.PutHex16 (sval);
370 }
371 else if (bit_size <= 32 || (bit_size == 0 && INT32_MIN <= sval && sval <= INT32_MAX))
372 {
373 m_stream.PutHex8 (DW_OP_const4s);
374 m_stream.PutHex32 (sval);
375 }
376 else if (bit_size <= 64 || (bit_size == 0))
377 {
378 m_stream.PutHex8 (DW_OP_const8s);
379 m_stream.PutHex64 (sval);
380 }
381 else
382 {
383 m_stream.PutHex8 (DW_OP_APPLE_error);
384 return false;
385 }
386 return true;
387}
388
389CLANG_STMT_RESULT
390lldb_private::ClangStmtVisitor::VisitIntegerLiteral (clang::IntegerLiteral *Node)
391{
392 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
393 const llvm::APInt &ap_int = Node->getValue();
394 if (ap_int.getBitWidth() <= 64)
395 {
396 clang::QualType clang_type = Node->getType();
397 uint64_t clang_type_size = m_ast_context.getTypeSize (clang_type);
398 // Encode the integer into our DWARF expression
399 if (clang_type->isSignedIntegerType())
400 EncodeSInt64(ap_int.getLimitedValue(), clang_type_size);
401 else
402 EncodeUInt64(ap_int.getLimitedValue(), clang_type_size);
403 }
404 else
405 {
406 // TODO: eventually support integer math over 64 bits, probably using
407 // APInt as the class.
408 m_stream.PutHex8(DW_OP_APPLE_error);
409 }
410}
411
412
413CLANG_STMT_RESULT
414lldb_private::ClangStmtVisitor::VisitFloatingLiteral (clang::FloatingLiteral *Node)
415{
416 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
417 const llvm::APFloat &ap_float = Node->getValue();
418 // Put the length of the float in bytes into a single byte
419 llvm::APInt ap_int(ap_float.bitcastToAPInt());
420 const unsigned byte_size = ap_int.getBitWidth() / CHAR_BIT;
421 if (byte_size == sizeof(float))
422 {
423 if (sizeof(float) == 4)
424 {
425 m_stream.PutHex8(DW_OP_APPLE_constf);
426 m_stream.PutHex8 (byte_size);
427 m_stream.PutHex32 (ap_int.getLimitedValue());
428 return;
429 }
430 else if (sizeof(float) == 8)
431 {
432 m_stream.PutHex8(DW_OP_APPLE_constf);
433 m_stream.PutHex8 (byte_size);
434 m_stream.PutHex64 (ap_int.getLimitedValue());
435 return;
436 }
437 }
438 else if (byte_size == sizeof(double))
439 {
440 if (sizeof(double) == 4)
441 {
442 m_stream.PutHex8(DW_OP_APPLE_constf);
443 m_stream.PutHex8 (byte_size);
444 m_stream.PutHex32 (ap_int.getLimitedValue());
445 return;
446 }
447 else if (sizeof(double) == 8)
448 {
449 m_stream.PutHex8(DW_OP_APPLE_constf);
450 m_stream.PutHex8 (byte_size);
451 m_stream.PutHex64 (ap_int.getLimitedValue());
452 return;
453 }
454 }
455 else if (byte_size == sizeof(long double))
456 {
457 if (sizeof(long double) == 8)
458 {
459 m_stream.PutHex8(DW_OP_APPLE_constf);
460 m_stream.PutHex8 (byte_size);
461 m_stream.PutHex64 (ap_int.getLimitedValue());
462 return;
463 }
464 }
465 // TODO: eventually support float constants of all sizes using
466 // APFloat as the class.
467 m_stream.PutHex8(DW_OP_APPLE_error);
468}
469
470
471CLANG_STMT_RESULT
472lldb_private::ClangStmtVisitor::VisitStringLiteral (clang::StringLiteral *Str)
473{
474 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
475
476 size_t byte_length = Str->getByteLength();
477 bool is_wide = Str->isWide();
478
479 size_t new_length = byte_length + (is_wide ? 1 : 2);
480
481 uint8_t null_terminated_string[new_length];
482
483 memcpy(&null_terminated_string[0], Str->getStrData(), byte_length);
484
485 if(is_wide)
486 {
487 null_terminated_string[byte_length] = '\0';
488 null_terminated_string[byte_length + 1] = '\0';
489 }
490 else
491 {
492 null_terminated_string[byte_length] = '\0';
493 }
494
495 Value *val = new Value(null_terminated_string, new_length);
496 val->SetContext(Value::eContextTypeOpaqueClangQualType, Str->getType().getAsOpaquePtr());
497
498 uint32_t val_idx = m_variable_list.AppendValue(val);
499
500 m_stream.PutHex8(DW_OP_APPLE_expr_local);
501 m_stream.PutULEB128(val_idx);
502}
503
504
505CLANG_STMT_RESULT
506lldb_private::ClangStmtVisitor::VisitUnaryOperator (clang::UnaryOperator *unary_op)
507{
508 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
509
510 Visit(unary_op->getSubExpr());
511
512 switch (unary_op->getOpcode())
513 {
514 case clang::UnaryOperator::PostInc:
515 // Duplciate the top of stack value (which must be something that can
516 // be assignable/incremented) and push its current value
517 m_stream.PutHex8 (DW_OP_dup); // x, x
518 m_stream.PutHex8 (DW_OP_APPLE_value_of); // x, val(x)
519 m_stream.PutHex8 (DW_OP_swap); // val(x), x
520 m_stream.PutHex8 (DW_OP_dup); // val(x), x, x
521 m_stream.PutHex8 (DW_OP_lit1); // val(x), x, x, 1
522 m_stream.PutHex8 (DW_OP_plus); // val(x), x, val(x)+1
523 m_stream.PutHex8 (DW_OP_APPLE_assign); // val(x), x
524 m_stream.PutHex8 (DW_OP_drop); // val(x)
525 break;
526
527 case clang::UnaryOperator::PostDec:
528 // Duplciate the top of stack value (which must be something that can
529 // be assignable/incremented) and push its current value
530 m_stream.PutHex8 (DW_OP_dup); // x, x
531 m_stream.PutHex8 (DW_OP_APPLE_value_of); // x, val(x)
532 m_stream.PutHex8 (DW_OP_swap); // val(x), x
533 m_stream.PutHex8 (DW_OP_dup); // val(x), x, x
534 m_stream.PutHex8 (DW_OP_lit1); // val(x), x, x, 1
535 m_stream.PutHex8 (DW_OP_minus); // val(x), x, val(x)-1
536 m_stream.PutHex8 (DW_OP_APPLE_assign); // val(x), x
537 m_stream.PutHex8 (DW_OP_drop); // val(x)
538 break;
539
540 case clang::UnaryOperator::PreInc:
541 m_stream.PutHex8 (DW_OP_dup); // x, x
542 m_stream.PutHex8 (DW_OP_APPLE_value_of); // x, val(x)
543 m_stream.PutHex8 (DW_OP_lit1); // x, val(x), 1
544 m_stream.PutHex8 (DW_OP_plus); // x, val(x)+1
545 m_stream.PutHex8 (DW_OP_APPLE_assign); // x with new value
546 break;
547
548 case clang::UnaryOperator::PreDec:
549 m_stream.PutHex8 (DW_OP_dup); // x, x
550 m_stream.PutHex8 (DW_OP_APPLE_value_of); // x, val(x)
551 m_stream.PutHex8 (DW_OP_lit1); // x, val(x), 1
552 m_stream.PutHex8 (DW_OP_minus); // x, val(x)-1
553 m_stream.PutHex8 (DW_OP_APPLE_assign); // x with new value
554 break;
555
556 case clang::UnaryOperator::AddrOf:
557 m_stream.PutHex8 (DW_OP_APPLE_address_of);
558 break;
559
560 case clang::UnaryOperator::Deref:
561 m_stream.PutHex8 (DW_OP_APPLE_deref_type);
562 break;
563
564 case clang::UnaryOperator::Plus:
565 m_stream.PutHex8 (DW_OP_abs);
566 break;
567
568 case clang::UnaryOperator::Minus:
569 m_stream.PutHex8 (DW_OP_neg);
570 break;
571
572 case clang::UnaryOperator::Not:
573 m_stream.PutHex8 (DW_OP_not);
574 break;
575
576 case clang::UnaryOperator::LNot:
577 m_stream.PutHex8 (DW_OP_lit0);
578 m_stream.PutHex8 (DW_OP_eq);
579 break;
580
581 case clang::UnaryOperator::Real:
582 m_stream.PutHex8(DW_OP_APPLE_error);
583 break;
584
585 case clang::UnaryOperator::Imag:
586 m_stream.PutHex8(DW_OP_APPLE_error);
587 break;
588
589 case clang::UnaryOperator::Extension:
590 m_stream.PutHex8(DW_OP_APPLE_error);
591 break;
592
593 case clang::UnaryOperator::OffsetOf:
594 break;
595
596 default:
597 assert(!"Unknown unary operator!");
598 break;
599 }
600}
601
602CLANG_STMT_RESULT
603lldb_private::ClangStmtVisitor::VisitCastExpr (clang::CastExpr *Node)
604{
605 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
606// CastExpr::CastKind cast_kind = Node->getCastKind();
607// switch (cast_kind)
608// {
609// case CastExpr::CK_Unknown:
610// case CastExpr::CK_BitCast: // Used for reinterpret_cast.
611// case CastExpr::CK_NoOp: // Used for const_cast.
612// case CastExpr::CK_BaseToDerived: // Base to derived class casts.
613// case CastExpr::CK_DerivedToBase: // Derived to base class casts.
614// case CastExpr::CK_Dynamic: // Dynamic cast.
615// case CastExpr::CK_ToUnion: // Cast to union (GCC extension).
616// case CastExpr::CK_ArrayToPointerDecay: // Array to pointer decay.
617// case CastExpr::CK_FunctionToPointerDecay: // Function to pointer decay.
618// case CastExpr::CK_NullToMemberPointer: // Null pointer to member pointer.
619// case CastExpr::CK_BaseToDerivedMemberPointer: // Member pointer in base class to member pointer in derived class.
620// case CastExpr::CK_DerivedToBaseMemberPointer: // Member pointer in derived class to member pointer in base class.
621// case CastExpr::CK_UserDefinedConversion: // Conversion using a user defined type conversion function.
622// case CastExpr::CK_ConstructorConversion: // Conversion by constructor
623// case CastExpr::CK_IntegralToPointer: // Integral to pointer
624// case CastExpr::CK_PointerToIntegral: // Pointer to integral
625// case CastExpr::CK_ToVoid: // Cast to void
626// case CastExpr::CK_VectorSplat: // Casting from an integer/floating type to an extended
627// // vector type with the same element type as the src type. Splats the
628// // src expression into the destination expression.
629// case CastExpr::CK_IntegralCast: // Casting between integral types of different size.
630// case CastExpr::CK_IntegralToFloating: // Integral to floating point.
631// case CastExpr::CK_FloatingToIntegral: // Floating point to integral.
632// case CastExpr::CK_FloatingCast: // Casting between floating types of different size.
633// m_stream.PutHex8(DW_OP_APPLE_error);
634// break;
635// }
636 uint32_t cast_type_count = 0;
637 lldb_private::Scalar::Type cast_type_encoding = GetScalarTypeForClangType (m_ast_context, Node->getType(), cast_type_count);
638
639
640 Visit (Node->getSubExpr());
641
642 // Simple scalar cast
643 if (cast_type_encoding != lldb_private::Scalar::e_void && cast_type_count == 1)
644 {
645 // Only cast if our scalar types mismatch
646 uint32_t castee_type_count = 0;
647 lldb_private::Scalar::Type castee_type_encoding = GetScalarTypeForClangType (m_ast_context, Node->getSubExpr()->getType(), castee_type_count);
648 if (cast_type_encoding != castee_type_encoding &&
649 castee_type_encoding != lldb_private::Scalar::e_void)
650 {
651 m_stream.PutHex8(DW_OP_APPLE_scalar_cast);
652 m_stream.PutHex8(cast_type_encoding);
653 }
654 }
655 else
656 {
657 // Handle more complex casts with clang types soon!
658 m_stream.PutHex8(DW_OP_APPLE_error);
659 }
660}
661
662CLANG_STMT_RESULT
663lldb_private::ClangStmtVisitor::VisitArraySubscriptExpr (clang::ArraySubscriptExpr *Node)
664{
665 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
666 Visit (Node->getBase());
667 Visit (Node->getIdx());
668 m_stream.PutHex8(DW_OP_APPLE_array_ref);
669}
670
671//
672//CLANG_STMT_RESULT
673//lldb_private::ClangStmtVisitor::VisitImplicitCastExpr (clang::ImplicitCastExpr *Node)
674//{
675// DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
676// m_stream.PutHex8(DW_OP_APPLE_scalar_cast);
677// Visit (Node->getSubExpr());
678//}
679
680CLANG_STMT_RESULT
681lldb_private::ClangStmtVisitor::VisitSizeOfAlignOfExpr (clang::SizeOfAlignOfExpr *Node)
682{
683 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
684}
685
686
687CLANG_STMT_RESULT
688lldb_private::ClangStmtVisitor::VisitMemberExpr (clang::MemberExpr *Node)
689{
690 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
691 clang::Expr *parent = Node->getBase();
692 Visit (parent);
693 clang::QualType parent_clang_type = parent->getType();
694 clang::NamedDecl *member_named_decl = cast<clang::NamedDecl>(Node->getMemberDecl()->getCanonicalDecl());
695
696// DeclarationName member_name = member->getDeclName();
697
698 clang::Type::TypeClass parent_type_class = parent_clang_type->getTypeClass();
699 if (parent_type_class == clang::Type::Pointer)
700 {
701 clang::PointerType *pointer_type = cast<clang::PointerType>(parent_clang_type.getTypePtr());
702 parent_clang_type = pointer_type->getPointeeType();
703 parent_type_class = parent_clang_type->getTypeClass();
704 }
705
706 switch (parent_type_class)
707 {
708 case clang::Type::Record:
709 {
710 const clang::RecordType *record_type = cast<clang::RecordType>(parent_clang_type.getTypePtr());
711 const clang::RecordDecl *record_decl = record_type->getDecl();
712 assert(record_decl);
713 const clang::ASTRecordLayout &record_layout = m_ast_context.getASTRecordLayout(record_decl);
714 uint32_t field_idx = 0;
715 clang::RecordDecl::field_iterator field, field_end;
716 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
717 {
718 clang::NamedDecl *field_named_decl = cast<clang::NamedDecl>(field->getCanonicalDecl());
719 if (field_named_decl == member_named_decl)
720 {
721 std::pair<uint64_t, unsigned> field_type_info = m_ast_context.getTypeInfo(field->getType());
722 uint64_t field_bit_offset = record_layout.getFieldOffset (field_idx);
723 uint64_t field_byte_offset = field_bit_offset / 8;
724 uint32_t field_bitfield_bit_size = 0;
725 //uint32_t field_bitfield_bit_offset = field_bit_offset % 8;
726
727 if (field->isBitField())
728 {
729 clang::Expr* bit_width_expr = field->getBitWidth();
730 if (bit_width_expr)
731 {
732 llvm::APSInt bit_width_apsint;
733 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, m_ast_context))
734 {
735 field_bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
736 }
737 }
738 }
739
740 if (Node->isArrow())
741 {
742 m_stream.PutHex8(DW_OP_deref);
743 }
744 else
745 {
746 m_stream.PutHex8(DW_OP_APPLE_address_of);
747 }
748
749 if (field_byte_offset)
750 {
751 if (EncodeUInt64(field_byte_offset, 0))
752 {
753 m_stream.PutHex8(DW_OP_plus);
754 }
755 }
756 m_stream.PutHex8(DW_OP_APPLE_clang_cast);
757 m_stream.PutPointer(field->getType().getAsOpaquePtr());
758 break;
759 }
760 }
761 }
762 break;
763
764 default:
765 assert(!"Unhandled MemberExpr");
766 break;
767 }
768}
769
770
771CLANG_STMT_RESULT
772lldb_private::ClangStmtVisitor::VisitExtVectorElementExpr (clang::ExtVectorElementExpr *Node)
773{
774 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
775}
776
777CLANG_STMT_RESULT
778lldb_private::ClangStmtVisitor::VisitParenExpr(clang::ParenExpr *paren_expr)
779{
780 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
781 Visit (paren_expr->getSubExpr());
782}
783
784CLANG_STMT_RESULT
785lldb_private::ClangStmtVisitor::VisitInitListExpr (clang::InitListExpr *init_list_expr)
786{
787 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
788}
789
790CLANG_STMT_RESULT
791lldb_private::ClangStmtVisitor::VisitBinaryOperator (clang::BinaryOperator *Node)
792{
793 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
794
795 Visit(Node->getLHS());
796 Visit(Node->getRHS());
797
798 switch (Node->getOpcode())
799 {
800 default: assert(0 && "Unknown binary operator!");
801 case clang::BinaryOperator::PtrMemD: m_stream.PutHex8(DW_OP_APPLE_error); break;
802 case clang::BinaryOperator::PtrMemI: m_stream.PutHex8(DW_OP_APPLE_error); break;
803 case clang::BinaryOperator::Mul: m_stream.PutHex8(DW_OP_mul); break;
804 case clang::BinaryOperator::Div: m_stream.PutHex8(DW_OP_div); break;
805 case clang::BinaryOperator::Rem: m_stream.PutHex8(DW_OP_mod); break;
806 case clang::BinaryOperator::Add: m_stream.PutHex8(DW_OP_plus); break;
807 case clang::BinaryOperator::Sub: m_stream.PutHex8(DW_OP_minus); break;
808 case clang::BinaryOperator::Shl: m_stream.PutHex8(DW_OP_shl); break;
809 case clang::BinaryOperator::Shr: m_stream.PutHex8(DW_OP_shr); break;
810 case clang::BinaryOperator::LT: m_stream.PutHex8(DW_OP_lt); break;
811 case clang::BinaryOperator::GT: m_stream.PutHex8(DW_OP_gt); break;
812 case clang::BinaryOperator::LE: m_stream.PutHex8(DW_OP_le); break;
813 case clang::BinaryOperator::GE: m_stream.PutHex8(DW_OP_ge); break;
814 case clang::BinaryOperator::EQ: m_stream.PutHex8(DW_OP_eq); break;
815 case clang::BinaryOperator::NE: m_stream.PutHex8(DW_OP_ne); break;
816 case clang::BinaryOperator::And: m_stream.PutHex8(DW_OP_and); break;
817 case clang::BinaryOperator::Xor: m_stream.PutHex8(DW_OP_xor); break;
818 case clang::BinaryOperator::Or : m_stream.PutHex8(DW_OP_or); break;
819 case clang::BinaryOperator::LAnd:
820 // Do we need to call an operator here on objects? If so
821 // we will need a DW_OP_apple_logical_and
822 m_stream.PutHex8(DW_OP_lit0);
823 m_stream.PutHex8(DW_OP_ne);
824 m_stream.PutHex8(DW_OP_swap);
825 m_stream.PutHex8(DW_OP_lit0);
826 m_stream.PutHex8(DW_OP_ne);
827 m_stream.PutHex8(DW_OP_and);
828 break;
829
830 case clang::BinaryOperator::LOr :
831 // Do we need to call an operator here on objects? If so
832 // we will need a DW_OP_apple_logical_or
833 m_stream.PutHex8(DW_OP_lit0);
834 m_stream.PutHex8(DW_OP_ne);
835 m_stream.PutHex8(DW_OP_swap);
836 m_stream.PutHex8(DW_OP_lit0);
837 m_stream.PutHex8(DW_OP_ne);
838 m_stream.PutHex8(DW_OP_or);
839 break;
840
841 case clang::BinaryOperator::Assign:
842 m_stream.PutHex8(DW_OP_APPLE_assign);
843 break;
844
845 case clang::BinaryOperator::MulAssign:
846 m_stream.PutHex8(DW_OP_over);
847 m_stream.PutHex8(DW_OP_swap);
848 m_stream.PutHex8(DW_OP_mul);
849 m_stream.PutHex8(DW_OP_APPLE_assign);
850 break;
851
852 case clang::BinaryOperator::DivAssign:
853 m_stream.PutHex8(DW_OP_over);
854 m_stream.PutHex8(DW_OP_swap);
855 m_stream.PutHex8(DW_OP_div);
856 m_stream.PutHex8(DW_OP_APPLE_assign);
857 break;
858
859 case clang::BinaryOperator::RemAssign:
860 m_stream.PutHex8(DW_OP_over);
861 m_stream.PutHex8(DW_OP_swap);
862 m_stream.PutHex8(DW_OP_mod);
863 m_stream.PutHex8(DW_OP_APPLE_assign);
864 break;
865
866 case clang::BinaryOperator::AddAssign:
867 m_stream.PutHex8(DW_OP_over);
868 m_stream.PutHex8(DW_OP_swap);
869 m_stream.PutHex8(DW_OP_plus);
870 m_stream.PutHex8(DW_OP_APPLE_assign);
871 break;
872
873 case clang::BinaryOperator::SubAssign:
874 m_stream.PutHex8(DW_OP_over);
875 m_stream.PutHex8(DW_OP_swap);
876 m_stream.PutHex8(DW_OP_minus);
877 m_stream.PutHex8(DW_OP_APPLE_assign);
878 break;
879
880 case clang::BinaryOperator::ShlAssign:
881 m_stream.PutHex8(DW_OP_over);
882 m_stream.PutHex8(DW_OP_swap);
883 m_stream.PutHex8(DW_OP_shl);
884 m_stream.PutHex8(DW_OP_APPLE_assign);
885 break;
886
887 case clang::BinaryOperator::ShrAssign:
888 m_stream.PutHex8(DW_OP_over);
889 m_stream.PutHex8(DW_OP_swap);
890 m_stream.PutHex8(DW_OP_shr);
891 m_stream.PutHex8(DW_OP_APPLE_assign);
892 break;
893
894 case clang::BinaryOperator::AndAssign:
895 m_stream.PutHex8(DW_OP_over);
896 m_stream.PutHex8(DW_OP_swap);
897 m_stream.PutHex8(DW_OP_and);
898 m_stream.PutHex8(DW_OP_APPLE_assign);
899 break;
900
901 case clang::BinaryOperator::OrAssign:
902 m_stream.PutHex8(DW_OP_over);
903 m_stream.PutHex8(DW_OP_swap);
904 m_stream.PutHex8(DW_OP_or);
905 m_stream.PutHex8(DW_OP_APPLE_assign);
906 break;
907
908 case clang::BinaryOperator::XorAssign:
909 m_stream.PutHex8(DW_OP_over);
910 m_stream.PutHex8(DW_OP_swap);
911 m_stream.PutHex8(DW_OP_xor);
912 m_stream.PutHex8(DW_OP_APPLE_assign);
913 break;
914
915 case clang::BinaryOperator::Comma:
916 // Nothing needs to be done here right?
917 break;
918 }
919}
920
921
922//CLANG_STMT_RESULT
923//lldb_private::ClangStmtVisitor::VisitCompoundAssignOperator (CompoundAssignOperator *Node)
924//{
925// DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
926//
927//}
928
929
930CLANG_STMT_RESULT
931lldb_private::ClangStmtVisitor::VisitAddrLabelExpr (clang::AddrLabelExpr *Node)
932{
933 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
934}
935
936
937CLANG_STMT_RESULT
938lldb_private::ClangStmtVisitor::VisitTypesCompatibleExpr (clang::TypesCompatibleExpr *Node)
939{
940 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
941}
942
943
944
945 // C++
946CLANG_STMT_RESULT
947lldb_private::ClangStmtVisitor::VisitCXXNamedCastExpr (clang::CXXNamedCastExpr *Node)
948{
949 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
950}
951
952
953CLANG_STMT_RESULT
954lldb_private::ClangStmtVisitor::VisitCXXBoolLiteralExpr (clang::CXXBoolLiteralExpr *Node)
955{
956 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
957}
958
959
960CLANG_STMT_RESULT
961lldb_private::ClangStmtVisitor::VisitCXXThisExpr (clang::CXXThisExpr *Node)
962{
963 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
964}
965
966
967CLANG_STMT_RESULT
968lldb_private::ClangStmtVisitor::VisitCXXFunctionalCastExpr (clang::CXXFunctionalCastExpr *Node)
969{
970 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
971}
972
973
974
975 // ObjC
976CLANG_STMT_RESULT
977lldb_private::ClangStmtVisitor::VisitObjCEncodeExpr (clang::ObjCEncodeExpr *Node)
978{
979 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
980}
981
982
983CLANG_STMT_RESULT
984lldb_private::ClangStmtVisitor::VisitObjCMessageExpr (clang::ObjCMessageExpr* Node)
985{
986 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
987}
988
989
990CLANG_STMT_RESULT
991lldb_private::ClangStmtVisitor::VisitObjCSelectorExpr (clang::ObjCSelectorExpr *Node)
992{
993 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
994}
995
996
997CLANG_STMT_RESULT
998lldb_private::ClangStmtVisitor::VisitObjCProtocolExpr (clang::ObjCProtocolExpr *Node)
999{
1000 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
1001}
1002
1003
1004CLANG_STMT_RESULT
1005lldb_private::ClangStmtVisitor::VisitObjCPropertyRefExpr (clang::ObjCPropertyRefExpr *Node)
1006{
1007 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
1008}
1009
1010
1011CLANG_STMT_RESULT
1012lldb_private::ClangStmtVisitor::VisitObjCImplicitSetterGetterRefExpr (clang::ObjCImplicitSetterGetterRefExpr *Node)
1013{
1014 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
1015}
1016
1017
1018CLANG_STMT_RESULT
1019lldb_private::ClangStmtVisitor::VisitObjCIvarRefExpr (clang::ObjCIvarRefExpr *Node)
1020{
1021 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
1022}
1023
1024
1025CLANG_STMT_RESULT
1026lldb_private::ClangStmtVisitor::VisitObjCSuperExpr (clang::ObjCSuperExpr *Node)
1027{
1028 DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__);
1029}
1030
1031