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