1212
1313#include " CIRGenFunction.h"
1414
15+ #include " CIRGenCall.h"
16+ #include " mlir/IR/Location.h"
1517#include " clang/AST/GlobalDecl.h"
1618#include " clang/CIR/MissingFeatures.h"
1719
@@ -132,15 +134,17 @@ mlir::Location CIRGenFunction::getLoc(mlir::Location lhs, mlir::Location rhs) {
132134 return mlir::FusedLoc::get (locs, metadata, &getMLIRContext ());
133135}
134136
135- mlir::LogicalResult CIRGenFunction::declare (Address addr, const Decl *var,
136- QualType ty, mlir::Location loc,
137- CharUnits alignment) {
137+ mlir::LogicalResult CIRGenFunction::declare (mlir::Value addrVal,
138+ const Decl *var, QualType ty,
139+ mlir::Location loc,
140+ CharUnits alignment, bool isParam) {
138141 const auto *namedVar = dyn_cast_or_null<NamedDecl>(var);
139142 assert (namedVar && " Needs a named decl" );
140143 assert (!cir::MissingFeatures::cgfSymbolTable ());
141144
142- mlir::Value addrVal = addr.getPointer ();
143145 auto allocaOp = cast<cir::AllocaOp>(addrVal.getDefiningOp ());
146+ if (isParam)
147+ allocaOp.setInitAttr (mlir::UnitAttr::get (&getMLIRContext ()));
144148 if (ty->isReferenceType () || ty.isConstQualified ())
145149 allocaOp.setConstantAttr (mlir::UnitAttr::get (&getMLIRContext ()));
146150
@@ -149,16 +153,49 @@ mlir::LogicalResult CIRGenFunction::declare(Address addr, const Decl *var,
149153
150154void CIRGenFunction::startFunction (GlobalDecl gd, QualType returnType,
151155 cir::FuncOp fn, cir::FuncType funcType,
152- SourceLocation loc,
156+ FunctionArgList args, SourceLocation loc,
153157 SourceLocation startLoc) {
154158 assert (!curFn &&
155159 " CIRGenFunction can only be used for one function at a time" );
156160
157161 fnRetTy = returnType;
158162 curFn = fn;
159163
164+ const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.getDecl ());
165+
160166 mlir::Block *entryBB = &fn.getBlocks ().front ();
161167 builder.setInsertionPointToStart (entryBB);
168+
169+ // TODO(cir): this should live in `emitFunctionProlog
170+ // Declare all the function arguments in the symbol table.
171+ for (const auto nameValue : llvm::zip (args, entryBB->getArguments ())) {
172+ const VarDecl *paramVar = std::get<0 >(nameValue);
173+ mlir::Value paramVal = std::get<1 >(nameValue);
174+ CharUnits alignment = getContext ().getDeclAlign (paramVar);
175+ mlir::Location paramLoc = getLoc (paramVar->getSourceRange ());
176+ paramVal.setLoc (paramLoc);
177+
178+ mlir::Value addrVal =
179+ emitAlloca (cast<NamedDecl>(paramVar)->getName (),
180+ convertType (paramVar->getType ()), paramLoc, alignment);
181+
182+ declare (addrVal, paramVar, paramVar->getType (), paramLoc, alignment,
183+ /* isParam=*/ true );
184+
185+ setAddrOfLocalVar (paramVar, Address (addrVal, alignment));
186+
187+ bool isPromoted = isa<ParmVarDecl>(paramVar) &&
188+ cast<ParmVarDecl>(paramVar)->isKNRPromoted ();
189+ assert (!cir::MissingFeatures::constructABIArgDirectExtend ());
190+ if (isPromoted)
191+ cgm.errorNYI (fd->getSourceRange (), " Function argument demotion" );
192+
193+ // Location of the store to the param storage tracked as beginning of
194+ // the function body.
195+ mlir::Location fnBodyBegin = getLoc (fd->getBody ()->getBeginLoc ());
196+ builder.CIRBaseBuilderTy ::createStore (fnBodyBegin, paramVal, addrVal);
197+ }
198+ assert (builder.getInsertionBlock () && " Should be valid" );
162199}
163200
164201void CIRGenFunction::finishFunction (SourceLocation endLoc) {}
@@ -187,8 +224,10 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
187224 // This will be used once more code is upstreamed.
188225 [[maybe_unused]] mlir::Block *entryBB = fn.addEntryBlock ();
189226
190- startFunction (gd, funcDecl->getReturnType (), fn, funcType, loc,
191- bodyRange.getBegin ());
227+ FunctionArgList args;
228+ QualType retTy = buildFunctionArgList (gd, args);
229+
230+ startFunction (gd, retTy, fn, funcType, args, loc, bodyRange.getBegin ());
192231
193232 if (isa<CXXDestructorDecl>(funcDecl))
194233 getCIRGenModule ().errorNYI (bodyRange, " C++ destructor definition" );
@@ -234,6 +273,29 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
234273 return fn;
235274}
236275
276+ clang::QualType CIRGenFunction::buildFunctionArgList (clang::GlobalDecl gd,
277+ FunctionArgList &args) {
278+ const auto *fd = cast<FunctionDecl>(gd.getDecl ());
279+ QualType retTy = fd->getReturnType ();
280+
281+ const auto *md = dyn_cast<CXXMethodDecl>(fd);
282+ if (md && md->isInstance ())
283+ cgm.errorNYI (fd->getSourceRange (), " buildFunctionArgList: CXXMethodDecl" );
284+
285+ if (isa<CXXConstructorDecl>(fd))
286+ cgm.errorNYI (fd->getSourceRange (),
287+ " buildFunctionArgList: CXXConstructorDecl" );
288+
289+ for (auto *param : fd->parameters ())
290+ args.push_back (param);
291+
292+ if (md && (isa<CXXConstructorDecl>(md) || isa<CXXDestructorDecl>(md)))
293+ cgm.errorNYI (fd->getSourceRange (),
294+ " buildFunctionArgList: implicit structor params" );
295+
296+ return retTy;
297+ }
298+
237299// / Emit code to compute a designator that specifies the location
238300// / of the expression.
239301// / FIXME: document this function better.
0 commit comments