1414
1515#include " clang/AST/ASTContext.h"
1616#include " clang/AST/DeclBase.h"
17+ #include " clang/AST/GlobalDecl.h"
18+ #include " clang/Basic/SourceManager.h"
19+ #include " clang/CIR/Dialect/IR/CIRDialect.h"
1720
1821#include " mlir/IR/BuiltinOps.h"
1922#include " mlir/IR/Location.h"
@@ -24,9 +27,149 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
2427 clang::ASTContext &astctx,
2528 const clang::CodeGenOptions &cgo,
2629 DiagnosticsEngine &diags)
27- : astCtx(astctx), langOpts(astctx.getLangOpts()),
28- theModule{mlir::ModuleOp::create (mlir::UnknownLoc ())},
29- target (astCtx.getTargetInfo()) {}
30+ : builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()),
31+ theModule{mlir::ModuleOp::create (mlir::UnknownLoc::get (&context))},
32+ diags (diags), target(astCtx.getTargetInfo()) {}
33+
34+ mlir::Location CIRGenModule::getLoc (SourceLocation cLoc) {
35+ assert (cLoc.isValid () && " expected valid source location" );
36+ const SourceManager &sm = astCtx.getSourceManager ();
37+ PresumedLoc pLoc = sm.getPresumedLoc (cLoc);
38+ StringRef filename = pLoc.getFilename ();
39+ return mlir::FileLineColLoc::get (builder.getStringAttr (filename),
40+ pLoc.getLine (), pLoc.getColumn ());
41+ }
42+
43+ mlir::Location CIRGenModule::getLoc (SourceRange cRange) {
44+ assert (cRange.isValid () && " expected a valid source range" );
45+ mlir::Location begin = getLoc (cRange.getBegin ());
46+ mlir::Location end = getLoc (cRange.getEnd ());
47+ SmallVector<mlir::Location, 2 > locs = {begin, end};
48+ mlir::Attribute metadata;
49+ return mlir::FusedLoc::get (locs, metadata, builder.getContext ());
50+ }
51+
52+ void CIRGenModule::buildGlobal (clang::GlobalDecl gd) {
53+
54+ const auto *global = cast<ValueDecl>(gd.getDecl ());
55+
56+ if (const auto *fd = dyn_cast<FunctionDecl>(global)) {
57+ // Update deferred annotations with the latest declaration if the function
58+ // was already used or defined.
59+ if (fd->hasAttr <AnnotateAttr>()) {
60+ errorNYI (fd->getSourceRange (), " defferedAnnotations" );
61+ }
62+ if (!fd->doesThisDeclarationHaveABody ()) {
63+ if (!fd->doesDeclarationForceExternallyVisibleDefinition ())
64+ return ;
65+
66+ errorNYI (fd->getSourceRange (),
67+ " function declaration that forces code gen" );
68+ return ;
69+ }
70+ } else {
71+ const auto *vd = cast<VarDecl>(global);
72+ assert (vd->isFileVarDecl () && " Cannot emit local var decl as global." );
73+ errorNYI (vd->getSourceRange (), " global variable declaration" );
74+ }
75+
76+ // NYI: Defer emitting some global definitions until later
77+ buildGlobalDefinition (gd);
78+ }
79+
80+ void CIRGenModule::buildGlobalFunctionDefinition (clang::GlobalDecl gd,
81+ mlir::Operation *op) {
82+ auto const *d = cast<FunctionDecl>(gd.getDecl ());
83+
84+ builder.create <mlir::cir::FuncOp>(getLoc (d->getSourceRange ()),
85+ d->getIdentifier ()->getName ());
86+ }
87+
88+ void CIRGenModule::buildGlobalDefinition (clang::GlobalDecl gd,
89+ mlir::Operation *op) {
90+ const auto *d = cast<ValueDecl>(gd.getDecl ());
91+ if (const auto *fd = dyn_cast<FunctionDecl>(d)) {
92+ // NYI: Skip generation of CIR for functions with available_externally
93+ // linkage at -O0.
94+
95+ if (const auto *method = dyn_cast<CXXMethodDecl>(d)) {
96+ // Make sure to emit the definition(s) before we emit the thunks. This is
97+ // necessary for the generation of certain thunks.
98+ (void )method;
99+ errorNYI (method->getSourceRange (), " member function" );
100+ return ;
101+ }
102+
103+ if (fd->isMultiVersion ())
104+ errorNYI (fd->getSourceRange (), " multiversion functions" );
105+ buildGlobalFunctionDefinition (gd, op);
106+ return ;
107+ }
108+
109+ if (const auto *vd = dyn_cast<VarDecl>(d)) {
110+ (void )vd;
111+ errorNYI (vd->getSourceRange (), " global variable definition" );
112+ return ;
113+ }
114+
115+ llvm_unreachable (" Invalid argument to CIRGenModule::buildGlobalDefinition" );
116+ }
30117
31118// Emit code for a single top level declaration.
32- void CIRGenModule::buildTopLevelDecl (Decl *decl) {}
119+ void CIRGenModule::buildTopLevelDecl (Decl *decl) {
120+
121+ // Ignore dependent declarations.
122+ if (decl->isTemplated ())
123+ return ;
124+
125+ switch (decl->getKind ()) {
126+ default :
127+ errorNYI (decl->getBeginLoc (), " declaration of kind" ,
128+ decl->getDeclKindName ());
129+ break ;
130+
131+ case Decl::Function: {
132+ auto *fd = cast<FunctionDecl>(decl);
133+ // Consteval functions shouldn't be emitted.
134+ if (!fd->isConsteval ())
135+ buildGlobal (fd);
136+ break ;
137+ }
138+ }
139+ }
140+
141+ DiagnosticBuilder CIRGenModule::errorNYI (llvm::StringRef feature) {
142+ unsigned diagID = diags.getCustomDiagID (DiagnosticsEngine::Error,
143+ " ClangIR code gen NYI: %0" );
144+ return diags.Report (diagID) << feature;
145+ }
146+
147+ DiagnosticBuilder CIRGenModule::errorNYI (SourceLocation loc,
148+ llvm::StringRef feature) {
149+ unsigned diagID = diags.getCustomDiagID (DiagnosticsEngine::Error,
150+ " ClangIR code gen NYI: %0" );
151+ return diags.Report (loc, diagID) << feature;
152+ }
153+
154+ DiagnosticBuilder CIRGenModule::errorNYI (SourceLocation loc,
155+ llvm::StringRef feature,
156+ llvm::StringRef name) {
157+ unsigned diagID = diags.getCustomDiagID (DiagnosticsEngine::Error,
158+ " ClangIR code gen NYI: %0: %1" );
159+ return diags.Report (loc, diagID) << feature << name;
160+ }
161+
162+ DiagnosticBuilder CIRGenModule::errorNYI (SourceRange loc,
163+ llvm::StringRef feature) {
164+ unsigned diagID = diags.getCustomDiagID (DiagnosticsEngine::Error,
165+ " ClangIR code gen NYI: %0" );
166+ return diags.Report (loc.getBegin (), diagID) << feature << loc;
167+ }
168+
169+ DiagnosticBuilder CIRGenModule::errorNYI (SourceRange loc,
170+ llvm::StringRef feature,
171+ llvm::StringRef name) {
172+ unsigned diagID = diags.getCustomDiagID (DiagnosticsEngine::Error,
173+ " ClangIR code gen NYI: %0: %1" );
174+ return diags.Report (loc.getBegin (), diagID) << feature << name << loc;
175+ }
0 commit comments