Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenerator.cpp
213799 views
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-exception
6
//
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
25
using namespace cir;
26
using namespace clang;
27
28
void CIRGenerator::anchor() {}
29
30
CIRGenerator::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} {}
35
CIRGenerator::~CIRGenerator() {
36
// There should normally not be any leftover inline method definitions.
37
assert(deferredInlineMemberFuncDefs.empty() || diags.hasErrorOccurred());
38
}
39
40
static 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
47
void 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
70
bool CIRGenerator::verifyModule() const { return cgm->verifyModule(); }
71
72
mlir::ModuleOp CIRGenerator::getModule() const { return cgm->getModule(); }
73
74
bool 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
86
void 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 to
92
// stop here before invoking the backend.
93
assert(!cir::MissingFeatures::cleanupAfterErrorDiags());
94
}
95
96
void 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 be
103
// based on computing the linkage, and we have to defer that in case we are
104
// 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 be
113
// instantiable.
114
assert(!cir::MissingFeatures::coverageMapping());
115
}
116
117
void CIRGenerator::emitDeferredDecls() {
118
if (deferredInlineMemberFuncDefs.empty())
119
return;
120
121
// Emit any deferred inline method definitions. Note that more deferred
122
// methods may be added during this loop, since ASTConsumer callbacks can be
123
// invoked if AST inspection results in declarations being added. Therefore,
124
// we use an index to loop over the deferredInlineMemberFuncDefs rather than
125
// 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 to
133
/// (e.g. struct, union, enum, class) is completed. This allows the client to
134
/// hack on the type, which can occur at any point in the file (because these
135
/// can be defined in declspecs).
136
void CIRGenerator::HandleTagDeclDefinition(TagDecl *d) {
137
if (diags.hasErrorOccurred())
138
return;
139
140
// Don't allow re-entrant calls to CIRGen triggered by PCH deserialization to
141
// 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 with
147
// 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
155
void CIRGenerator::CompleteTentativeDefinition(VarDecl *d) {
156
if (diags.hasErrorOccurred())
157
return;
158
159
cgm->emitTentativeDefinition(d);
160
}
161
162