brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · aa4d9eb Raw
182 lines · cpp
1//===--- CIRGenerator.cpp - Emit CIR from ASTs ----------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This builds an AST and converts it to CIR.10//11//===----------------------------------------------------------------------===//12 13#include "CIRGenModule.h"14 15#include "mlir/Dialect/OpenACC/OpenACC.h"16#include "mlir/IR/MLIRContext.h"17#include "mlir/Target/LLVMIR/Import.h"18 19#include "clang/AST/DeclGroup.h"20#include "clang/CIR/CIRGenerator.h"21#include "clang/CIR/Dialect/IR/CIRDialect.h"22#include "clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h"23#include "llvm/IR/DataLayout.h"24 25using namespace cir;26using namespace clang;27 28void CIRGenerator::anchor() {}29 30CIRGenerator::CIRGenerator(clang::DiagnosticsEngine &diags,31                           llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,32                           const CodeGenOptions &cgo)33    : diags(diags), fs(std::move(vfs)), codeGenOpts{cgo},34      handlingTopLevelDecls{0} {}35CIRGenerator::~CIRGenerator() {36  // There should normally not be any leftover inline method definitions.37  assert(deferredInlineMemberFuncDefs.empty() || diags.hasErrorOccurred());38}39 40static void setMLIRDataLayout(mlir::ModuleOp &mod, const llvm::DataLayout &dl) {41  mlir::MLIRContext *mlirContext = mod.getContext();42  mlir::DataLayoutSpecInterface dlSpec =43      mlir::translateDataLayout(dl, mlirContext);44  mod->setAttr(mlir::DLTIDialect::kDataLayoutAttrName, dlSpec);45}46 47void CIRGenerator::Initialize(ASTContext &astContext) {48  using namespace llvm;49 50  this->astContext = &astContext;51 52  mlirContext = std::make_unique<mlir::MLIRContext>();53  mlirContext->loadDialect<mlir::DLTIDialect>();54  mlirContext->loadDialect<cir::CIRDialect>();55  mlirContext->getOrLoadDialect<mlir::acc::OpenACCDialect>();56 57  // Register extensions to integrate CIR types with OpenACC.58  mlir::DialectRegistry registry;59  cir::acc::registerOpenACCExtensions(registry);60  mlirContext->appendDialectRegistry(registry);61 62  cgm = std::make_unique<clang::CIRGen::CIRGenModule>(63      *mlirContext.get(), astContext, codeGenOpts, diags);64  mlir::ModuleOp mod = cgm->getModule();65  llvm::DataLayout layout =66      llvm::DataLayout(astContext.getTargetInfo().getDataLayoutString());67  setMLIRDataLayout(mod, layout);68}69 70bool CIRGenerator::verifyModule() const { return cgm->verifyModule(); }71 72mlir::ModuleOp CIRGenerator::getModule() const { return cgm->getModule(); }73 74bool CIRGenerator::HandleTopLevelDecl(DeclGroupRef group) {75  if (diags.hasUnrecoverableErrorOccurred())76    return true;77 78  HandlingTopLevelDeclRAII handlingDecl(*this);79 80  for (Decl *decl : group)81    cgm->emitTopLevelDecl(decl);82 83  return true;84}85 86void CIRGenerator::HandleTranslationUnit(ASTContext &astContext) {87  // Release the Builder when there is no error.88  if (!diags.hasErrorOccurred() && cgm)89    cgm->release();90 91  // If there are errors before or when releasing the cgm, reset the module to92  // stop here before invoking the backend.93  assert(!cir::MissingFeatures::cleanupAfterErrorDiags());94}95 96void CIRGenerator::HandleInlineFunctionDefinition(FunctionDecl *d) {97  if (diags.hasErrorOccurred())98    return;99 100  assert(d->doesThisDeclarationHaveABody());101 102  // We may want to emit this definition. However, that decision might be103  // based on computing the linkage, and we have to defer that in case we are104  // inside of something that will chagne the method's final linkage, e.g.105  //   typedef struct {106  //     void bar();107  //     void foo() { bar(); }108  //   } A;109  deferredInlineMemberFuncDefs.push_back(d);110 111  // Provide some coverage mapping even for methods that aren't emitted.112  // Don't do this for templated classes though, as they may not be113  // instantiable.114  assert(!cir::MissingFeatures::coverageMapping());115}116 117void CIRGenerator::emitDeferredDecls() {118  if (deferredInlineMemberFuncDefs.empty())119    return;120 121  // Emit any deferred inline method definitions. Note that more deferred122  // methods may be added during this loop, since ASTConsumer callbacks can be123  // invoked if AST inspection results in declarations being added. Therefore,124  // we use an index to loop over the deferredInlineMemberFuncDefs rather than125  // a range.126  HandlingTopLevelDeclRAII handlingDecls(*this);127  for (unsigned i = 0; i != deferredInlineMemberFuncDefs.size(); ++i)128    cgm->emitTopLevelDecl(deferredInlineMemberFuncDefs[i]);129  deferredInlineMemberFuncDefs.clear();130}131 132/// HandleTagDeclDefinition - This callback is invoked each time a TagDecl to133/// (e.g. struct, union, enum, class) is completed. This allows the client to134/// hack on the type, which can occur at any point in the file (because these135/// can be defined in declspecs).136void CIRGenerator::HandleTagDeclDefinition(TagDecl *d) {137  if (diags.hasErrorOccurred())138    return;139 140  // Don't allow re-entrant calls to CIRGen triggered by PCH deserialization to141  // emit deferred decls.142  HandlingTopLevelDeclRAII handlingDecl(*this, /*EmitDeferred=*/false);143 144  cgm->updateCompletedType(d);145 146  // For MSVC compatibility, treat declarations of static data members with147  // inline initializers as definitions.148  if (astContext->getTargetInfo().getCXXABI().isMicrosoft())149    cgm->errorNYI(d->getSourceRange(), "HandleTagDeclDefinition: MSABI");150  // For OpenMP emit declare reduction functions, if required.151  if (astContext->getLangOpts().OpenMP)152    cgm->errorNYI(d->getSourceRange(), "HandleTagDeclDefinition: OpenMP");153}154 155void CIRGenerator::HandleTagDeclRequiredDefinition(const TagDecl *D) {156  if (diags.hasErrorOccurred())157    return;158 159  assert(!cir::MissingFeatures::generateDebugInfo());160}161 162void CIRGenerator::HandleCXXStaticMemberVarInstantiation(VarDecl *D) {163  if (diags.hasErrorOccurred())164    return;165 166  cgm->handleCXXStaticMemberVarInstantiation(D);167}168 169void CIRGenerator::CompleteTentativeDefinition(VarDecl *d) {170  if (diags.hasErrorOccurred())171    return;172 173  cgm->emitTentativeDefinition(d);174}175 176void CIRGenerator::HandleVTable(CXXRecordDecl *rd) {177  if (diags.hasErrorOccurred())178    return;179 180  cgm->emitVTable(rd);181}182