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