Explicitly create FunctionDecl in DeclExtractor

The function EnforceInitOrder() was using ImplicitlyDefineFunction()
as a shortcut to define a function returning an int. Future upgrades
of LLVM will add an assert in that function because it is not allowed
to be used when compiling C++, which Cling obviously does.
This commit is contained in:
Jonas Hahnfeld 2023-01-18 11:19:54 +01:00 committed by jenkins
parent 2129e96274
commit 2f48c65752

View File

@ -239,58 +239,60 @@ namespace cling {
std::string FunctionName = "__fd";
createUniqueName(FunctionName);
IdentifierInfo& IIFD = m_Context->Idents.get(FunctionName);
clang::DeclarationName DeclName = &m_Context->Idents.get(FunctionName);
SourceLocation Loc;
NamedDecl* ND = m_Sema->ImplicitlyDefineFunction(Loc, IIFD, TUScope);
if (FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(ND)) {
Sema::SynthesizedFunctionScope Scope(*m_Sema, FD);
FD->setImplicit(false); // Better for debugging
clang::QualType FnTy =
m_Context->getFunctionType(m_Context->IntTy, {},
clang::FunctionProtoType::ExtProtoInfo());
clang::FunctionDecl* FD = clang::FunctionDecl::Create(
*m_Context, m_Context->getTranslationUnitDecl(), Loc, Loc, DeclName,
FnTy, m_Context->getTrivialTypeSourceInfo(FnTy), clang::SC_None);
// Add a return statement if it doesn't exist
if (!isa<ReturnStmt>(Stmts.back())) {
Sema::ContextRAII pushedDC(*m_Sema, FD);
// Generate the return statement:
// First a literal 0, then the return taking that literal.
// One bit is enough:
llvm::APInt ZeroInt(m_Context->getIntWidth(m_Context->IntTy), 0,
/*isSigned=*/true);
IntegerLiteral* ZeroLit
= IntegerLiteral::Create(*m_Context, ZeroInt, m_Context->IntTy,
SourceLocation());
Stmts.push_back(m_Sema->ActOnReturnStmt(ZeroLit->getExprLoc(),
ZeroLit,
m_Sema->getCurScope()).get());
}
Sema::SynthesizedFunctionScope Scope(*m_Sema, FD);
FD->setImplicit(false); // Better for debugging
// Wrap Stmts into a function body.
llvm::ArrayRef<Stmt*> StmtsRef(Stmts.data(), Stmts.size());
CompoundStmt* CS = CompoundStmt::Create(*m_Context, StmtsRef, Loc, Loc);
FD->setBody(CS);
Emit(FD);
// Create the VarDecl with the init
std::string VarName = "__vd";
createUniqueName(VarName);
IdentifierInfo& IIVD = m_Context->Idents.get(VarName);
VarDecl* VD = VarDecl::Create(*m_Context, TUDC, Loc, Loc, &IIVD,
FD->getReturnType(), (TypeSourceInfo*)0,
SC_None);
LookupResult R(*m_Sema, FD->getDeclName(), Loc, Sema::LookupMemberName);
R.addDecl(FD);
CXXScopeSpec CSS;
Expr* UnresolvedLookup
= m_Sema->BuildDeclarationNameExpr(CSS, R, /*ADL*/ false).get();
Expr* TheCall = m_Sema->ActOnCallExpr(TUScope, UnresolvedLookup, Loc,
MultiExprArg(), Loc).get();
assert(VD && TheCall && "Missing VD or its init!");
VD->setInit(TheCall);
Emit(VD); // Add it to the transaction for codegenning
TUDC->addHiddenDecl(VD);
Stmts.clear();
return;
// Add a return statement if it doesn't exist
if (!isa<ReturnStmt>(Stmts.back())) {
Sema::ContextRAII pushedDC(*m_Sema, FD);
// Generate the return statement:
// First a literal 0, then the return taking that literal.
// One bit is enough:
llvm::APInt ZeroInt(m_Context->getIntWidth(m_Context->IntTy), 0,
/*isSigned=*/true);
IntegerLiteral* ZeroLit
= IntegerLiteral::Create(*m_Context, ZeroInt, m_Context->IntTy,
SourceLocation());
Stmts.push_back(m_Sema->ActOnReturnStmt(ZeroLit->getExprLoc(),
ZeroLit,
m_Sema->getCurScope()).get());
}
llvm_unreachable("Must be able to enforce init order.");
// Wrap Stmts into a function body.
llvm::ArrayRef<Stmt*> StmtsRef(Stmts.data(), Stmts.size());
CompoundStmt* CS = CompoundStmt::Create(*m_Context, StmtsRef, Loc, Loc);
FD->setBody(CS);
Emit(FD);
// Create the VarDecl with the init
std::string VarName = "__vd";
createUniqueName(VarName);
IdentifierInfo& IIVD = m_Context->Idents.get(VarName);
VarDecl* VD = VarDecl::Create(*m_Context, TUDC, Loc, Loc, &IIVD,
FD->getReturnType(), (TypeSourceInfo*)0,
SC_None);
LookupResult R(*m_Sema, FD->getDeclName(), Loc, Sema::LookupMemberName);
R.addDecl(FD);
CXXScopeSpec CSS;
Expr* UnresolvedLookup
= m_Sema->BuildDeclarationNameExpr(CSS, R, /*ADL*/ false).get();
Expr* TheCall = m_Sema->ActOnCallExpr(TUScope, UnresolvedLookup, Loc,
MultiExprArg(), Loc).get();
assert(VD && TheCall && "Missing VD or its init!");
VD->setInit(TheCall);
Emit(VD); // Add it to the transaction for codegenning
TUDC->addHiddenDecl(VD);
Stmts.clear();
}
///\brief Checks for clashing names when trying to extract a declaration.