1 //===-- ASTResultSynthesizer.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 "ASTResultSynthesizer.h" 11 12 #include "ClangPersistentVariables.h" 13 14 #include "lldb/Core/Log.h" 15 #include "lldb/Symbol/ClangASTContext.h" 16 #include "lldb/Symbol/ClangASTImporter.h" 17 #include "lldb/Target/Target.h" 18 #include "lldb/Utility/LLDBAssert.h" 19 #include "stdlib.h" 20 #include "clang/AST/ASTContext.h" 21 #include "clang/AST/Decl.h" 22 #include "clang/AST/DeclCXX.h" 23 #include "clang/AST/DeclGroup.h" 24 #include "clang/AST/DeclObjC.h" 25 #include "clang/AST/Expr.h" 26 #include "clang/AST/Stmt.h" 27 #include "clang/Parse/Parser.h" 28 #include "clang/Sema/SemaDiagnostic.h" 29 #include "llvm/Support/Casting.h" 30 #include "llvm/Support/raw_ostream.h" 31 32 using namespace llvm; 33 using namespace clang; 34 using namespace lldb_private; 35 36 ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough, bool top_level, Target &target) 37 : m_ast_context(NULL), 38 m_passthrough(passthrough), 39 m_passthrough_sema(NULL), 40 m_target(target), 41 m_sema(NULL), 42 m_top_level(top_level) 43 { 44 if (!m_passthrough) 45 return; 46 47 m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough); 48 } 49 50 ASTResultSynthesizer::~ASTResultSynthesizer() 51 { 52 } 53 54 void 55 ASTResultSynthesizer::Initialize(ASTContext &Context) 56 { 57 m_ast_context = &Context; 58 59 if (m_passthrough) 60 m_passthrough->Initialize(Context); 61 } 62 63 void 64 ASTResultSynthesizer::TransformTopLevelDecl(Decl* D) 65 { 66 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 67 68 if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) 69 { 70 if (log && log->GetVerbose()) 71 { 72 if (named_decl->getIdentifier()) 73 log->Printf("TransformTopLevelDecl(%s)", named_decl->getIdentifier()->getNameStart()); 74 else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D)) 75 log->Printf("TransformTopLevelDecl(%s)", method_decl->getSelector().getAsString().c_str()); 76 else 77 log->Printf("TransformTopLevelDecl(<complex>)"); 78 } 79 80 if (m_top_level) 81 { 82 RecordPersistentDecl(named_decl); 83 } 84 } 85 86 if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D)) 87 { 88 RecordDecl::decl_iterator decl_iterator; 89 90 for (decl_iterator = linkage_spec_decl->decls_begin(); 91 decl_iterator != linkage_spec_decl->decls_end(); 92 ++decl_iterator) 93 { 94 TransformTopLevelDecl(*decl_iterator); 95 } 96 } 97 else if (!m_top_level) 98 { 99 if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D)) 100 { 101 if (m_ast_context && !method_decl->getSelector().getAsString().compare("$__lldb_expr:")) 102 { 103 RecordPersistentTypes(method_decl); 104 SynthesizeObjCMethodResult(method_decl); 105 } 106 } 107 else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D)) 108 { 109 if (m_ast_context && !function_decl->getNameInfo().getAsString().compare("$__lldb_expr")) 110 { 111 RecordPersistentTypes(function_decl); 112 SynthesizeFunctionResult(function_decl); 113 } 114 } 115 } 116 } 117 118 bool 119 ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) 120 { 121 DeclGroupRef::iterator decl_iterator; 122 123 for (decl_iterator = D.begin(); 124 decl_iterator != D.end(); 125 ++decl_iterator) 126 { 127 Decl *decl = *decl_iterator; 128 129 TransformTopLevelDecl(decl); 130 } 131 132 if (m_passthrough) 133 return m_passthrough->HandleTopLevelDecl(D); 134 return true; 135 } 136 137 bool 138 ASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl) 139 { 140 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 141 142 if (!m_sema) 143 return false; 144 145 FunctionDecl *function_decl = FunDecl; 146 147 if (!function_decl) 148 return false; 149 150 if (log && log->GetVerbose()) 151 { 152 std::string s; 153 raw_string_ostream os(s); 154 155 function_decl->print(os); 156 157 os.flush(); 158 159 log->Printf ("Untransformed function AST:\n%s", s.c_str()); 160 } 161 162 Stmt *function_body = function_decl->getBody(); 163 CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body); 164 165 bool ret = SynthesizeBodyResult (compound_stmt, 166 function_decl); 167 168 if (log && log->GetVerbose()) 169 { 170 std::string s; 171 raw_string_ostream os(s); 172 173 function_decl->print(os); 174 175 os.flush(); 176 177 log->Printf ("Transformed function AST:\n%s", s.c_str()); 178 } 179 180 return ret; 181 } 182 183 bool 184 ASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl) 185 { 186 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 187 188 if (!m_sema) 189 return false; 190 191 if (!MethodDecl) 192 return false; 193 194 if (log && log->GetVerbose()) 195 { 196 std::string s; 197 raw_string_ostream os(s); 198 199 MethodDecl->print(os); 200 201 os.flush(); 202 203 log->Printf ("Untransformed method AST:\n%s", s.c_str()); 204 } 205 206 Stmt *method_body = MethodDecl->getBody(); 207 208 if (!method_body) 209 return false; 210 211 CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body); 212 213 bool ret = SynthesizeBodyResult (compound_stmt, 214 MethodDecl); 215 216 if (log && log->GetVerbose()) 217 { 218 std::string s; 219 raw_string_ostream os(s); 220 221 MethodDecl->print(os); 222 223 os.flush(); 224 225 log->Printf("Transformed method AST:\n%s", s.c_str()); 226 } 227 228 return ret; 229 } 230 231 bool 232 ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body, 233 DeclContext *DC) 234 { 235 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 236 237 ASTContext &Ctx(*m_ast_context); 238 239 if (!Body) 240 return false; 241 242 if (Body->body_empty()) 243 return false; 244 245 Stmt **last_stmt_ptr = Body->body_end() - 1; 246 Stmt *last_stmt = *last_stmt_ptr; 247 248 while (dyn_cast<NullStmt>(last_stmt)) 249 { 250 if (last_stmt_ptr != Body->body_begin()) 251 { 252 last_stmt_ptr--; 253 last_stmt = *last_stmt_ptr; 254 } 255 else 256 { 257 return false; 258 } 259 } 260 261 Expr *last_expr = dyn_cast<Expr>(last_stmt); 262 263 if (!last_expr) 264 // No auxiliary variable necessary; expression returns void 265 return true; 266 267 // In C++11, last_expr can be a LValueToRvalue implicit cast. Strip that off if that's the 268 // case. 269 270 do { 271 ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr); 272 273 if (!implicit_cast) 274 break; 275 276 if (implicit_cast->getCastKind() != CK_LValueToRValue) 277 break; 278 279 last_expr = implicit_cast->getSubExpr(); 280 } while (0); 281 282 // is_lvalue is used to record whether the expression returns an assignable Lvalue or an 283 // Rvalue. This is relevant because they are handled differently. 284 // 285 // For Lvalues 286 // 287 // - In AST result synthesis (here!) the expression E is transformed into an initialization 288 // T *$__lldb_expr_result_ptr = &E. 289 // 290 // - In structure allocation, a pointer-sized slot is allocated in the struct that is to be 291 // passed into the expression. 292 // 293 // - In IR transformations, reads and writes to $__lldb_expr_result_ptr are redirected at 294 // an entry in the struct ($__lldb_arg) passed into the expression. (Other persistent 295 // variables are treated similarly, having been materialized as references, but in those 296 // cases the value of the reference itself is never modified.) 297 // 298 // - During materialization, $0 (the result persistent variable) is ignored. 299 // 300 // - During dematerialization, $0 is marked up as a load address with value equal to the 301 // contents of the structure entry. 302 // 303 // For Rvalues 304 // 305 // - In AST result synthesis the expression E is transformed into an initialization 306 // static T $__lldb_expr_result = E. 307 // 308 // - In structure allocation, a pointer-sized slot is allocated in the struct that is to be 309 // passed into the expression. 310 // 311 // - In IR transformations, an instruction is inserted at the beginning of the function to 312 // dereference the pointer resident in the slot. Reads and writes to $__lldb_expr_result 313 // are redirected at that dereferenced version. Guard variables for the static variable 314 // are excised. 315 // 316 // - During materialization, $0 (the result persistent variable) is populated with the location 317 // of a newly-allocated area of memory. 318 // 319 // - During dematerialization, $0 is ignored. 320 321 bool is_lvalue = 322 (last_expr->getValueKind() == VK_LValue || last_expr->getValueKind() == VK_XValue) && 323 (last_expr->getObjectKind() == OK_Ordinary); 324 325 QualType expr_qual_type = last_expr->getType(); 326 const clang::Type *expr_type = expr_qual_type.getTypePtr(); 327 328 if (!expr_type) 329 return false; 330 331 if (expr_type->isVoidType()) 332 return true; 333 334 if (log) 335 { 336 std::string s = expr_qual_type.getAsString(); 337 338 log->Printf("Last statement is an %s with type: %s", (is_lvalue ? "lvalue" : "rvalue"), s.c_str()); 339 } 340 341 clang::VarDecl *result_decl = NULL; 342 343 if (is_lvalue) 344 { 345 IdentifierInfo *result_ptr_id; 346 347 if (expr_type->isFunctionType()) 348 result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should be treated like function pointers 349 else 350 result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr"); 351 352 m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, clang::diag::err_incomplete_type); 353 354 QualType ptr_qual_type; 355 356 if (expr_qual_type->getAs<ObjCObjectType>() != NULL) 357 ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type); 358 else 359 ptr_qual_type = Ctx.getPointerType(expr_qual_type); 360 361 result_decl = VarDecl::Create(Ctx, 362 DC, 363 SourceLocation(), 364 SourceLocation(), 365 result_ptr_id, 366 ptr_qual_type, 367 NULL, 368 SC_Static); 369 370 if (!result_decl) 371 return false; 372 373 ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr); 374 375 m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false); 376 } 377 else 378 { 379 IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result"); 380 381 result_decl = VarDecl::Create(Ctx, 382 DC, 383 SourceLocation(), 384 SourceLocation(), 385 &result_id, 386 expr_qual_type, 387 NULL, 388 SC_Static); 389 390 if (!result_decl) 391 return false; 392 393 m_sema->AddInitializerToDecl(result_decl, last_expr, true, false); 394 } 395 396 DC->addDecl(result_decl); 397 398 /////////////////////////////// 399 // call AddInitializerToDecl 400 // 401 402 //m_sema->AddInitializerToDecl(result_decl, last_expr); 403 404 ///////////////////////////////// 405 // call ConvertDeclToDeclGroup 406 // 407 408 Sema::DeclGroupPtrTy result_decl_group_ptr; 409 410 result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl); 411 412 //////////////////////// 413 // call ActOnDeclStmt 414 // 415 416 StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(result_decl_group_ptr, 417 SourceLocation(), 418 SourceLocation())); 419 420 //////////////////////////////////////////////// 421 // replace the old statement with the new one 422 // 423 424 *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.get()); 425 426 return true; 427 } 428 429 void 430 ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx) 431 { 432 if (m_passthrough) 433 m_passthrough->HandleTranslationUnit(Ctx); 434 } 435 436 void 437 ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx) 438 { 439 typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator; 440 441 for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()), 442 e = TypeDeclIterator(FunDeclCtx->decls_end()); 443 i != e; 444 ++i) 445 { 446 MaybeRecordPersistentType(*i); 447 } 448 } 449 450 void 451 ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) 452 { 453 if (!D->getIdentifier()) 454 return; 455 456 StringRef name = D->getName(); 457 458 if (name.size() == 0 || name[0] != '$') 459 return; 460 461 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 462 463 ConstString name_cs(name.str().c_str()); 464 465 if (log) 466 log->Printf("Recording persistent type %s\n", name_cs.GetCString()); 467 468 m_decls.push_back(D); 469 } 470 471 void 472 ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) 473 { 474 lldbassert(m_top_level); 475 476 if (!D->getIdentifier()) 477 return; 478 479 StringRef name = D->getName(); 480 481 if (name.size() == 0) 482 return; 483 484 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 485 486 ConstString name_cs(name.str().c_str()); 487 488 if (log) 489 log->Printf("Recording persistent decl %s\n", name_cs.GetCString()); 490 491 m_decls.push_back(D); 492 } 493 494 void 495 ASTResultSynthesizer::CommitPersistentDecls() 496 { 497 for (clang::NamedDecl *decl : m_decls) 498 { 499 StringRef name = decl->getName(); 500 ConstString name_cs(name.str().c_str()); 501 502 Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl( 503 m_target.GetScratchClangASTContext()->getASTContext(), m_ast_context, decl); 504 505 if (!D_scratch) 506 { 507 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 508 509 if (log) 510 { 511 std::string s; 512 llvm::raw_string_ostream ss(s); 513 decl->dump(ss); 514 ss.flush(); 515 516 log->Printf("Couldn't commit persistent decl: %s\n", s.c_str()); 517 } 518 519 continue; 520 } 521 522 if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch)) 523 llvm::cast<ClangPersistentVariables>(m_target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)) 524 ->RegisterPersistentDecl(name_cs, NamedDecl_scratch); 525 } 526 } 527 528 void 529 ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D) 530 { 531 if (m_passthrough) 532 m_passthrough->HandleTagDeclDefinition(D); 533 } 534 535 void 536 ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) 537 { 538 if (m_passthrough) 539 m_passthrough->CompleteTentativeDefinition(D); 540 } 541 542 void 543 ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD) 544 { 545 if (m_passthrough) 546 m_passthrough->HandleVTable(RD); 547 } 548 549 void 550 ASTResultSynthesizer::PrintStats() 551 { 552 if (m_passthrough) 553 m_passthrough->PrintStats(); 554 } 555 556 void 557 ASTResultSynthesizer::InitializeSema(Sema &S) 558 { 559 m_sema = &S; 560 561 if (m_passthrough_sema) 562 m_passthrough_sema->InitializeSema(S); 563 } 564 565 void 566 ASTResultSynthesizer::ForgetSema() 567 { 568 m_sema = NULL; 569 570 if (m_passthrough_sema) 571 m_passthrough_sema->ForgetSema(); 572 } 573