1254721Semaste//===-- ASTResultSynthesizer.cpp --------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "stdlib.h" 11254721Semaste#include "clang/AST/ASTContext.h" 12254721Semaste#include "clang/AST/Decl.h" 13254721Semaste#include "clang/AST/DeclCXX.h" 14254721Semaste#include "clang/AST/DeclGroup.h" 15254721Semaste#include "clang/AST/DeclObjC.h" 16254721Semaste#include "clang/AST/Expr.h" 17254721Semaste#include "clang/AST/Stmt.h" 18254721Semaste#include "clang/Parse/Parser.h" 19254721Semaste#include "clang/Sema/SemaDiagnostic.h" 20254721Semaste#include "llvm/Support/Casting.h" 21254721Semaste#include "llvm/Support/raw_ostream.h" 22254721Semaste#include "lldb/Core/Log.h" 23254721Semaste#include "lldb/Expression/ClangPersistentVariables.h" 24254721Semaste#include "lldb/Expression/ASTResultSynthesizer.h" 25254721Semaste#include "lldb/Symbol/ClangASTContext.h" 26254721Semaste#include "lldb/Symbol/ClangASTImporter.h" 27254721Semaste#include "lldb/Target/Target.h" 28254721Semaste 29254721Semasteusing namespace llvm; 30254721Semasteusing namespace clang; 31254721Semasteusing namespace lldb_private; 32254721Semaste 33254721SemasteASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough, 34254721Semaste Target &target) : 35254721Semaste m_ast_context (NULL), 36254721Semaste m_passthrough (passthrough), 37254721Semaste m_passthrough_sema (NULL), 38254721Semaste m_target (target), 39254721Semaste m_sema (NULL) 40254721Semaste{ 41254721Semaste if (!m_passthrough) 42254721Semaste return; 43254721Semaste 44254721Semaste m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough); 45254721Semaste} 46254721Semaste 47254721SemasteASTResultSynthesizer::~ASTResultSynthesizer() 48254721Semaste{ 49254721Semaste} 50254721Semaste 51254721Semastevoid 52254721SemasteASTResultSynthesizer::Initialize(ASTContext &Context) 53254721Semaste{ 54254721Semaste m_ast_context = &Context; 55254721Semaste 56254721Semaste if (m_passthrough) 57254721Semaste m_passthrough->Initialize(Context); 58254721Semaste} 59254721Semaste 60254721Semastevoid 61254721SemasteASTResultSynthesizer::TransformTopLevelDecl(Decl* D) 62254721Semaste{ 63254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 64254721Semaste 65254721Semaste if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) 66254721Semaste { 67254721Semaste if (log && log->GetVerbose()) 68254721Semaste { 69254721Semaste if (named_decl->getIdentifier()) 70254721Semaste log->Printf("TransformTopLevelDecl(%s)", named_decl->getIdentifier()->getNameStart()); 71254721Semaste else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D)) 72254721Semaste log->Printf("TransformTopLevelDecl(%s)", method_decl->getSelector().getAsString().c_str()); 73254721Semaste else 74254721Semaste log->Printf("TransformTopLevelDecl(<complex>)"); 75254721Semaste } 76254721Semaste 77254721Semaste } 78254721Semaste 79254721Semaste if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D)) 80254721Semaste { 81254721Semaste RecordDecl::decl_iterator decl_iterator; 82254721Semaste 83254721Semaste for (decl_iterator = linkage_spec_decl->decls_begin(); 84254721Semaste decl_iterator != linkage_spec_decl->decls_end(); 85254721Semaste ++decl_iterator) 86254721Semaste { 87254721Semaste TransformTopLevelDecl(*decl_iterator); 88254721Semaste } 89254721Semaste } 90254721Semaste else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D)) 91254721Semaste { 92254721Semaste if (m_ast_context && 93254721Semaste !method_decl->getSelector().getAsString().compare("$__lldb_expr:")) 94254721Semaste { 95254721Semaste RecordPersistentTypes(method_decl); 96254721Semaste SynthesizeObjCMethodResult(method_decl); 97254721Semaste } 98254721Semaste } 99254721Semaste else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D)) 100254721Semaste { 101254721Semaste if (m_ast_context && 102254721Semaste !function_decl->getNameInfo().getAsString().compare("$__lldb_expr")) 103254721Semaste { 104254721Semaste RecordPersistentTypes(function_decl); 105254721Semaste SynthesizeFunctionResult(function_decl); 106254721Semaste } 107254721Semaste } 108254721Semaste} 109254721Semaste 110254721Semastebool 111254721SemasteASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) 112254721Semaste{ 113254721Semaste DeclGroupRef::iterator decl_iterator; 114254721Semaste 115254721Semaste for (decl_iterator = D.begin(); 116254721Semaste decl_iterator != D.end(); 117254721Semaste ++decl_iterator) 118254721Semaste { 119254721Semaste Decl *decl = *decl_iterator; 120254721Semaste 121254721Semaste TransformTopLevelDecl(decl); 122254721Semaste } 123254721Semaste 124254721Semaste if (m_passthrough) 125254721Semaste return m_passthrough->HandleTopLevelDecl(D); 126254721Semaste return true; 127254721Semaste} 128254721Semaste 129254721Semastebool 130254721SemasteASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl) 131254721Semaste{ 132254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 133254721Semaste 134254721Semaste if (!m_sema) 135254721Semaste return false; 136254721Semaste 137254721Semaste FunctionDecl *function_decl = FunDecl; 138254721Semaste 139254721Semaste if (!function_decl) 140254721Semaste return false; 141254721Semaste 142254721Semaste if (log && log->GetVerbose()) 143254721Semaste { 144254721Semaste std::string s; 145254721Semaste raw_string_ostream os(s); 146254721Semaste 147254721Semaste function_decl->print(os); 148254721Semaste 149254721Semaste os.flush(); 150254721Semaste 151254721Semaste log->Printf ("Untransformed function AST:\n%s", s.c_str()); 152254721Semaste } 153254721Semaste 154254721Semaste Stmt *function_body = function_decl->getBody(); 155254721Semaste CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body); 156254721Semaste 157254721Semaste bool ret = SynthesizeBodyResult (compound_stmt, 158254721Semaste function_decl); 159254721Semaste 160254721Semaste if (log && log->GetVerbose()) 161254721Semaste { 162254721Semaste std::string s; 163254721Semaste raw_string_ostream os(s); 164254721Semaste 165254721Semaste function_decl->print(os); 166254721Semaste 167254721Semaste os.flush(); 168254721Semaste 169254721Semaste log->Printf ("Transformed function AST:\n%s", s.c_str()); 170254721Semaste } 171254721Semaste 172254721Semaste return ret; 173254721Semaste} 174254721Semaste 175254721Semastebool 176254721SemasteASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl) 177254721Semaste{ 178254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 179254721Semaste 180254721Semaste if (!m_sema) 181254721Semaste return false; 182254721Semaste 183254721Semaste if (!MethodDecl) 184254721Semaste return false; 185254721Semaste 186254721Semaste if (log && log->GetVerbose()) 187254721Semaste { 188254721Semaste std::string s; 189254721Semaste raw_string_ostream os(s); 190254721Semaste 191254721Semaste MethodDecl->print(os); 192254721Semaste 193254721Semaste os.flush(); 194254721Semaste 195254721Semaste log->Printf ("Untransformed method AST:\n%s", s.c_str()); 196254721Semaste } 197254721Semaste 198254721Semaste Stmt *method_body = MethodDecl->getBody(); 199254721Semaste 200254721Semaste if (!method_body) 201254721Semaste return false; 202254721Semaste 203254721Semaste CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body); 204254721Semaste 205254721Semaste bool ret = SynthesizeBodyResult (compound_stmt, 206254721Semaste MethodDecl); 207254721Semaste 208254721Semaste if (log && log->GetVerbose()) 209254721Semaste { 210254721Semaste std::string s; 211254721Semaste raw_string_ostream os(s); 212254721Semaste 213254721Semaste MethodDecl->print(os); 214254721Semaste 215254721Semaste os.flush(); 216254721Semaste 217254721Semaste log->Printf("Transformed method AST:\n%s", s.c_str()); 218254721Semaste } 219254721Semaste 220254721Semaste return ret; 221254721Semaste} 222254721Semaste 223254721Semastebool 224254721SemasteASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body, 225254721Semaste DeclContext *DC) 226254721Semaste{ 227254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 228254721Semaste 229254721Semaste ASTContext &Ctx(*m_ast_context); 230254721Semaste 231254721Semaste if (!Body) 232254721Semaste return false; 233254721Semaste 234254721Semaste if (Body->body_empty()) 235254721Semaste return false; 236254721Semaste 237254721Semaste Stmt **last_stmt_ptr = Body->body_end() - 1; 238254721Semaste Stmt *last_stmt = *last_stmt_ptr; 239254721Semaste 240254721Semaste while (dyn_cast<NullStmt>(last_stmt)) 241254721Semaste { 242254721Semaste if (last_stmt_ptr != Body->body_begin()) 243254721Semaste { 244254721Semaste last_stmt_ptr--; 245254721Semaste last_stmt = *last_stmt_ptr; 246254721Semaste } 247254721Semaste else 248254721Semaste { 249254721Semaste return false; 250254721Semaste } 251254721Semaste } 252254721Semaste 253254721Semaste Expr *last_expr = dyn_cast<Expr>(last_stmt); 254254721Semaste 255254721Semaste if (!last_expr) 256254721Semaste // No auxiliary variable necessary; expression returns void 257254721Semaste return true; 258254721Semaste 259254721Semaste // In C++11, last_expr can be a LValueToRvalue implicit cast. Strip that off if that's the 260254721Semaste // case. 261254721Semaste 262254721Semaste do { 263254721Semaste ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr); 264254721Semaste 265254721Semaste if (!implicit_cast) 266254721Semaste break; 267254721Semaste 268254721Semaste if (implicit_cast->getCastKind() != CK_LValueToRValue) 269254721Semaste break; 270254721Semaste 271254721Semaste last_expr = implicit_cast->getSubExpr(); 272254721Semaste } while (0); 273254721Semaste 274254721Semaste // is_lvalue is used to record whether the expression returns an assignable Lvalue or an 275254721Semaste // Rvalue. This is relevant because they are handled differently. 276254721Semaste // 277254721Semaste // For Lvalues 278254721Semaste // 279254721Semaste // - In AST result synthesis (here!) the expression E is transformed into an initialization 280254721Semaste // T *$__lldb_expr_result_ptr = &E. 281254721Semaste // 282254721Semaste // - In structure allocation, a pointer-sized slot is allocated in the struct that is to be 283254721Semaste // passed into the expression. 284254721Semaste // 285254721Semaste // - In IR transformations, reads and writes to $__lldb_expr_result_ptr are redirected at 286254721Semaste // an entry in the struct ($__lldb_arg) passed into the expression. (Other persistent 287254721Semaste // variables are treated similarly, having been materialized as references, but in those 288254721Semaste // cases the value of the reference itself is never modified.) 289254721Semaste // 290254721Semaste // - During materialization, $0 (the result persistent variable) is ignored. 291254721Semaste // 292254721Semaste // - During dematerialization, $0 is marked up as a load address with value equal to the 293254721Semaste // contents of the structure entry. 294254721Semaste // 295254721Semaste // For Rvalues 296254721Semaste // 297254721Semaste // - In AST result synthesis the expression E is transformed into an initialization 298254721Semaste // static T $__lldb_expr_result = E. 299254721Semaste // 300254721Semaste // - In structure allocation, a pointer-sized slot is allocated in the struct that is to be 301254721Semaste // passed into the expression. 302254721Semaste // 303254721Semaste // - In IR transformations, an instruction is inserted at the beginning of the function to 304254721Semaste // dereference the pointer resident in the slot. Reads and writes to $__lldb_expr_result 305254721Semaste // are redirected at that dereferenced version. Guard variables for the static variable 306254721Semaste // are excised. 307254721Semaste // 308254721Semaste // - During materialization, $0 (the result persistent variable) is populated with the location 309254721Semaste // of a newly-allocated area of memory. 310254721Semaste // 311254721Semaste // - During dematerialization, $0 is ignored. 312254721Semaste 313254721Semaste bool is_lvalue = 314254721Semaste (last_expr->getValueKind() == VK_LValue || last_expr->getValueKind() == VK_XValue) && 315254721Semaste (last_expr->getObjectKind() == OK_Ordinary); 316254721Semaste 317254721Semaste QualType expr_qual_type = last_expr->getType(); 318254721Semaste const clang::Type *expr_type = expr_qual_type.getTypePtr(); 319254721Semaste 320254721Semaste if (!expr_type) 321254721Semaste return false; 322254721Semaste 323254721Semaste if (expr_type->isVoidType()) 324254721Semaste return true; 325254721Semaste 326254721Semaste if (log) 327254721Semaste { 328254721Semaste std::string s = expr_qual_type.getAsString(); 329254721Semaste 330254721Semaste log->Printf("Last statement is an %s with type: %s", (is_lvalue ? "lvalue" : "rvalue"), s.c_str()); 331254721Semaste } 332254721Semaste 333254721Semaste clang::VarDecl *result_decl = NULL; 334254721Semaste 335254721Semaste if (is_lvalue) 336254721Semaste { 337254721Semaste IdentifierInfo *result_ptr_id; 338254721Semaste 339254721Semaste if (expr_type->isFunctionType()) 340254721Semaste result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should be treated like function pointers 341254721Semaste else 342254721Semaste result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr"); 343254721Semaste 344254721Semaste m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, clang::diag::err_incomplete_type); 345254721Semaste 346254721Semaste QualType ptr_qual_type; 347254721Semaste 348254721Semaste if (expr_qual_type->getAs<ObjCObjectType>() != NULL) 349254721Semaste ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type); 350254721Semaste else 351254721Semaste ptr_qual_type = Ctx.getPointerType(expr_qual_type); 352254721Semaste 353254721Semaste result_decl = VarDecl::Create(Ctx, 354254721Semaste DC, 355254721Semaste SourceLocation(), 356254721Semaste SourceLocation(), 357254721Semaste result_ptr_id, 358254721Semaste ptr_qual_type, 359254721Semaste NULL, 360254721Semaste SC_Static); 361254721Semaste 362254721Semaste if (!result_decl) 363254721Semaste return false; 364254721Semaste 365254721Semaste ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr); 366254721Semaste 367254721Semaste m_sema->AddInitializerToDecl(result_decl, address_of_expr.take(), true, false); 368254721Semaste } 369254721Semaste else 370254721Semaste { 371254721Semaste IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result"); 372254721Semaste 373254721Semaste result_decl = VarDecl::Create(Ctx, 374254721Semaste DC, 375254721Semaste SourceLocation(), 376254721Semaste SourceLocation(), 377254721Semaste &result_id, 378254721Semaste expr_qual_type, 379254721Semaste NULL, 380254721Semaste SC_Static); 381254721Semaste 382254721Semaste if (!result_decl) 383254721Semaste return false; 384254721Semaste 385254721Semaste m_sema->AddInitializerToDecl(result_decl, last_expr, true, false); 386254721Semaste } 387254721Semaste 388254721Semaste DC->addDecl(result_decl); 389254721Semaste 390254721Semaste /////////////////////////////// 391254721Semaste // call AddInitializerToDecl 392254721Semaste // 393254721Semaste 394254721Semaste //m_sema->AddInitializerToDecl(result_decl, last_expr); 395254721Semaste 396254721Semaste ///////////////////////////////// 397254721Semaste // call ConvertDeclToDeclGroup 398254721Semaste // 399254721Semaste 400254721Semaste Sema::DeclGroupPtrTy result_decl_group_ptr; 401254721Semaste 402254721Semaste result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl); 403254721Semaste 404254721Semaste //////////////////////// 405254721Semaste // call ActOnDeclStmt 406254721Semaste // 407254721Semaste 408254721Semaste StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(result_decl_group_ptr, 409254721Semaste SourceLocation(), 410254721Semaste SourceLocation())); 411254721Semaste 412254721Semaste //////////////////////////////////////////////// 413254721Semaste // replace the old statement with the new one 414254721Semaste // 415254721Semaste 416254721Semaste *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.take()); 417254721Semaste 418254721Semaste return true; 419254721Semaste} 420254721Semaste 421254721Semastevoid 422254721SemasteASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx) 423254721Semaste{ 424254721Semaste if (m_passthrough) 425254721Semaste m_passthrough->HandleTranslationUnit(Ctx); 426254721Semaste} 427254721Semaste 428254721Semastevoid 429254721SemasteASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx) 430254721Semaste{ 431254721Semaste typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator; 432254721Semaste 433254721Semaste for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()), 434254721Semaste e = TypeDeclIterator(FunDeclCtx->decls_end()); 435254721Semaste i != e; 436254721Semaste ++i) 437254721Semaste { 438254721Semaste MaybeRecordPersistentType(*i); 439254721Semaste } 440254721Semaste} 441254721Semaste 442254721Semastevoid 443254721SemasteASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) 444254721Semaste{ 445254721Semaste if (!D->getIdentifier()) 446254721Semaste return; 447254721Semaste 448254721Semaste StringRef name = D->getName(); 449254721Semaste 450254721Semaste if (name.size() == 0 || name[0] != '$') 451254721Semaste return; 452254721Semaste 453254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 454254721Semaste 455254721Semaste ConstString name_cs(name.str().c_str()); 456254721Semaste 457254721Semaste if (log) 458254721Semaste log->Printf ("Recording persistent type %s\n", name_cs.GetCString()); 459254721Semaste 460254721Semaste Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(m_target.GetScratchClangASTContext()->getASTContext(), 461254721Semaste m_ast_context, 462254721Semaste D); 463254721Semaste 464254721Semaste if (TypeDecl *TypeDecl_scratch = dyn_cast<TypeDecl>(D_scratch)) 465254721Semaste m_target.GetPersistentVariables().RegisterPersistentType(name_cs, TypeDecl_scratch); 466254721Semaste} 467254721Semaste 468254721Semastevoid 469254721SemasteASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D) 470254721Semaste{ 471254721Semaste if (m_passthrough) 472254721Semaste m_passthrough->HandleTagDeclDefinition(D); 473254721Semaste} 474254721Semaste 475254721Semastevoid 476254721SemasteASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) 477254721Semaste{ 478254721Semaste if (m_passthrough) 479254721Semaste m_passthrough->CompleteTentativeDefinition(D); 480254721Semaste} 481254721Semaste 482254721Semastevoid 483254721SemasteASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) 484254721Semaste{ 485254721Semaste if (m_passthrough) 486254721Semaste m_passthrough->HandleVTable(RD, DefinitionRequired); 487254721Semaste} 488254721Semaste 489254721Semastevoid 490254721SemasteASTResultSynthesizer::PrintStats() 491254721Semaste{ 492254721Semaste if (m_passthrough) 493254721Semaste m_passthrough->PrintStats(); 494254721Semaste} 495254721Semaste 496254721Semastevoid 497254721SemasteASTResultSynthesizer::InitializeSema(Sema &S) 498254721Semaste{ 499254721Semaste m_sema = &S; 500254721Semaste 501254721Semaste if (m_passthrough_sema) 502254721Semaste m_passthrough_sema->InitializeSema(S); 503254721Semaste} 504254721Semaste 505254721Semastevoid 506254721SemasteASTResultSynthesizer::ForgetSema() 507254721Semaste{ 508254721Semaste m_sema = NULL; 509254721Semaste 510254721Semaste if (m_passthrough_sema) 511254721Semaste m_passthrough_sema->ForgetSema(); 512254721Semaste} 513