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