Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
39648 views
//===-- ASTStructExtractor.cpp --------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "ASTStructExtractor.h"910#include "lldb/Utility/Log.h"11#include "clang/AST/ASTContext.h"12#include "clang/AST/Decl.h"13#include "clang/AST/DeclCXX.h"14#include "clang/AST/DeclGroup.h"15#include "clang/AST/Expr.h"16#include "clang/AST/RecordLayout.h"17#include "clang/AST/Stmt.h"18#include "clang/Parse/Parser.h"19#include "clang/Sema/Sema.h"20#include "llvm/Support/Casting.h"21#include "llvm/Support/raw_ostream.h"22#include <cstdlib>2324using namespace llvm;25using namespace clang;26using namespace lldb_private;2728ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough,29const char *struct_name,30ClangFunctionCaller &function)31: m_ast_context(nullptr), m_passthrough(passthrough),32m_passthrough_sema(nullptr), m_sema(nullptr), m_function(function),33m_struct_name(struct_name) {34if (!m_passthrough)35return;3637m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);38}3940ASTStructExtractor::~ASTStructExtractor() = default;4142void ASTStructExtractor::Initialize(ASTContext &Context) {43m_ast_context = &Context;4445if (m_passthrough)46m_passthrough->Initialize(Context);47}4849void ASTStructExtractor::ExtractFromFunctionDecl(FunctionDecl *F) {50if (!F->hasBody())51return;5253Stmt *body_stmt = F->getBody();54CompoundStmt *body_compound_stmt = dyn_cast<CompoundStmt>(body_stmt);5556if (!body_compound_stmt)57return; // do we have to handle this?5859RecordDecl *struct_decl = nullptr;6061StringRef desired_name(m_struct_name);6263for (CompoundStmt::const_body_iterator bi = body_compound_stmt->body_begin(),64be = body_compound_stmt->body_end();65bi != be; ++bi) {66Stmt *curr_stmt = *bi;67DeclStmt *curr_decl_stmt = dyn_cast<DeclStmt>(curr_stmt);68if (!curr_decl_stmt)69continue;70DeclGroupRef decl_group = curr_decl_stmt->getDeclGroup();71for (Decl *candidate_decl : decl_group) {72RecordDecl *candidate_record_decl = dyn_cast<RecordDecl>(candidate_decl);73if (!candidate_record_decl)74continue;75if (candidate_record_decl->getName() == desired_name) {76struct_decl = candidate_record_decl;77break;78}79}80if (struct_decl)81break;82}8384if (!struct_decl)85return;8687const ASTRecordLayout *struct_layout(88&m_ast_context->getASTRecordLayout(struct_decl));8990if (!struct_layout)91return;9293m_function.m_struct_size =94struct_layout->getSize()95.getQuantity(); // TODO Store m_struct_size as CharUnits96m_function.m_return_offset =97struct_layout->getFieldOffset(struct_layout->getFieldCount() - 1) / 8;98m_function.m_return_size =99struct_layout->getDataSize().getQuantity() - m_function.m_return_offset;100101for (unsigned field_index = 0, num_fields = struct_layout->getFieldCount();102field_index < num_fields; ++field_index) {103m_function.m_member_offsets.push_back(104struct_layout->getFieldOffset(field_index) / 8);105}106107m_function.m_struct_valid = true;108}109110void ASTStructExtractor::ExtractFromTopLevelDecl(Decl *D) {111LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D);112113if (linkage_spec_decl) {114RecordDecl::decl_iterator decl_iterator;115116for (decl_iterator = linkage_spec_decl->decls_begin();117decl_iterator != linkage_spec_decl->decls_end(); ++decl_iterator) {118ExtractFromTopLevelDecl(*decl_iterator);119}120}121122FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D);123124if (m_ast_context && function_decl &&125!m_function.m_wrapper_function_name.compare(126function_decl->getNameAsString())) {127ExtractFromFunctionDecl(function_decl);128}129}130131bool ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D) {132DeclGroupRef::iterator decl_iterator;133134for (decl_iterator = D.begin(); decl_iterator != D.end(); ++decl_iterator) {135Decl *decl = *decl_iterator;136137ExtractFromTopLevelDecl(decl);138}139140if (m_passthrough)141return m_passthrough->HandleTopLevelDecl(D);142return true;143}144145void ASTStructExtractor::HandleTranslationUnit(ASTContext &Ctx) {146if (m_passthrough)147m_passthrough->HandleTranslationUnit(Ctx);148}149150void ASTStructExtractor::HandleTagDeclDefinition(TagDecl *D) {151if (m_passthrough)152m_passthrough->HandleTagDeclDefinition(D);153}154155void ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D) {156if (m_passthrough)157m_passthrough->CompleteTentativeDefinition(D);158}159160void ASTStructExtractor::HandleVTable(CXXRecordDecl *RD) {161if (m_passthrough)162m_passthrough->HandleVTable(RD);163}164165void ASTStructExtractor::PrintStats() {166if (m_passthrough)167m_passthrough->PrintStats();168}169170void ASTStructExtractor::InitializeSema(Sema &S) {171m_sema = &S;172173if (m_passthrough_sema)174m_passthrough_sema->InitializeSema(S);175}176177void ASTStructExtractor::ForgetSema() {178m_sema = nullptr;179180if (m_passthrough_sema)181m_passthrough_sema->ForgetSema();182}183184185