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,134 @@ 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+ mlir::Attribute metadata;
48+ return mlir::FusedLoc::get ({begin, end}, metadata, builder.getContext ());
49+ }
50+
51+ void CIRGenModule::buildGlobal (clang::GlobalDecl gd) {
52+ const auto *global = cast<ValueDecl>(gd.getDecl ());
53+
54+ if (const auto *fd = dyn_cast<FunctionDecl>(global)) {
55+ // Update deferred annotations with the latest declaration if the function
56+ // was already used or defined.
57+ if (fd->hasAttr <AnnotateAttr>())
58+ errorNYI (fd->getSourceRange (), " deferredAnnotations" );
59+ if (!fd->doesThisDeclarationHaveABody ()) {
60+ if (!fd->doesDeclarationForceExternallyVisibleDefinition ())
61+ return ;
62+
63+ errorNYI (fd->getSourceRange (),
64+ " function declaration that forces code gen" );
65+ return ;
66+ }
67+ } else {
68+ errorNYI (global->getSourceRange (), " global variable declaration" );
69+ }
70+
71+ // TODO(CIR): Defer emitting some global definitions until later
72+ buildGlobalDefinition (gd);
73+ }
74+
75+ void CIRGenModule::buildGlobalFunctionDefinition (clang::GlobalDecl gd,
76+ mlir::Operation *op) {
77+ auto const *funcDecl = cast<FunctionDecl>(gd.getDecl ());
78+ auto funcOp = builder.create <mlir::cir::FuncOp>(
79+ getLoc (funcDecl->getSourceRange ()), funcDecl->getIdentifier ()->getName ());
80+ theModule.push_back (funcOp);
81+ }
82+
83+ void CIRGenModule::buildGlobalDefinition (clang::GlobalDecl gd,
84+ mlir::Operation *op) {
85+ const auto *decl = cast<ValueDecl>(gd.getDecl ());
86+ if (const auto *fd = dyn_cast<FunctionDecl>(decl)) {
87+ // TODO(CIR): Skip generation of CIR for functions with available_externally
88+ // linkage at -O0.
89+
90+ if (const auto *method = dyn_cast<CXXMethodDecl>(decl)) {
91+ // Make sure to emit the definition(s) before we emit the thunks. This is
92+ // necessary for the generation of certain thunks.
93+ (void )method;
94+ errorNYI (method->getSourceRange (), " member function" );
95+ return ;
96+ }
97+
98+ if (fd->isMultiVersion ())
99+ errorNYI (fd->getSourceRange (), " multiversion functions" );
100+ buildGlobalFunctionDefinition (gd, op);
101+ return ;
102+ }
103+
104+ llvm_unreachable (" Invalid argument to CIRGenModule::buildGlobalDefinition" );
105+ }
30106
31107// Emit code for a single top level declaration.
32- void CIRGenModule::buildTopLevelDecl (Decl *decl) {}
108+ void CIRGenModule::buildTopLevelDecl (Decl *decl) {
109+
110+ // Ignore dependent declarations.
111+ if (decl->isTemplated ())
112+ return ;
113+
114+ switch (decl->getKind ()) {
115+ default :
116+ errorNYI (decl->getBeginLoc (), " declaration of kind" ,
117+ decl->getDeclKindName ());
118+ break ;
119+
120+ case Decl::Function: {
121+ auto *fd = cast<FunctionDecl>(decl);
122+ // Consteval functions shouldn't be emitted.
123+ if (!fd->isConsteval ())
124+ buildGlobal (fd);
125+ break ;
126+ }
127+ }
128+ }
129+
130+ DiagnosticBuilder CIRGenModule::errorNYI (llvm::StringRef feature) {
131+ unsigned diagID = diags.getCustomDiagID (
132+ DiagnosticsEngine::Error, " ClangIR code gen Not Yet Implemented: %0" );
133+ return diags.Report (diagID) << feature;
134+ }
135+
136+ DiagnosticBuilder CIRGenModule::errorNYI (SourceLocation loc,
137+ llvm::StringRef feature) {
138+ unsigned diagID = diags.getCustomDiagID (
139+ DiagnosticsEngine::Error, " ClangIR code gen Not Yet Implemented: %0" );
140+ return diags.Report (loc, diagID) << feature;
141+ }
142+
143+ DiagnosticBuilder CIRGenModule::errorNYI (SourceLocation loc,
144+ llvm::StringRef feature,
145+ llvm::StringRef name) {
146+ unsigned diagID = diags.getCustomDiagID (
147+ DiagnosticsEngine::Error, " ClangIR code gen Not Yet Implemented: %0: %1" );
148+ return diags.Report (loc, diagID) << feature << name;
149+ }
150+
151+ DiagnosticBuilder CIRGenModule::errorNYI (SourceRange loc,
152+ llvm::StringRef feature) {
153+ return errorNYI (loc.getBegin (), feature) << loc;
154+ }
155+
156+ DiagnosticBuilder CIRGenModule::errorNYI (SourceRange loc,
157+ llvm::StringRef feature,
158+ llvm::StringRef name) {
159+ return errorNYI (loc.getBegin (), feature, name) << loc;
160+ }
0 commit comments