|
4 | 4 | #include "converter/converter.h" |
5 | 5 |
|
6 | 6 | #include <clang/AST/APValue.h> |
| 7 | +#include <clang/AST/IgnoreExpr.h> |
7 | 8 | #include <clang/AST/ParentMapContext.h> |
8 | 9 | #include <clang/Basic/LangOptions.h> |
9 | 10 | #include <clang/Basic/SourceManager.h> |
@@ -303,6 +304,9 @@ Converter::ConvertFunctionPointerType(const clang::FunctionProtoType *proto) { |
303 | 304 | result += ToString(p_ty); |
304 | 305 | result += ','; |
305 | 306 | } |
| 307 | + if (proto->isVariadic()) { |
| 308 | + result += "Box<[VaArg]>,"; |
| 309 | + } |
306 | 310 | result += ')'; |
307 | 311 | if (!proto->getReturnType()->isVoidType()) { |
308 | 312 | result += std::format(" -> {}", ToString(proto->getReturnType())); |
@@ -522,6 +526,9 @@ bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) { |
522 | 526 | ENSURE(decl_ids_.insert(GetID(decl)).second); |
523 | 527 | global_inits_.push_back(ForceGlobalInit(decl)); |
524 | 528 | } else if (decl->isStaticLocal()) { |
| 529 | + if (!globals_.insert(name).second) { |
| 530 | + return false; |
| 531 | + } |
525 | 532 | StrCat(keyword::kStatic, keyword_mut_); |
526 | 533 | } else if (decl->isLocalVarDecl()) { |
527 | 534 | StrCat(keyword::kLet); |
@@ -2012,6 +2019,16 @@ std::string Converter::GetFunctionRefName(const clang::FunctionDecl *fn_decl) { |
2012 | 2019 |
|
2013 | 2020 | void Converter::ConvertFunctionToFunctionPointer( |
2014 | 2021 | const clang::FunctionDecl *fn_decl) { |
| 2022 | + if (auto *method = clang::dyn_cast<clang::CXXMethodDecl>(fn_decl); |
| 2023 | + method && method->isLambdaStaticInvoker()) { |
| 2024 | + assert(!method->getParent()->isGenericLambda()); |
| 2025 | + StrCat("Some"); |
| 2026 | + PushParen paren(*this); |
| 2027 | + ConvertLambdaClosure(method->getParent(), |
| 2028 | + method->getParent()->getLambdaCallOperator()); |
| 2029 | + computed_expr_type_ = ComputedExprType::FreshPointer; |
| 2030 | + return; |
| 2031 | + } |
2015 | 2032 | StrCat(std::format("Some({})", GetFunctionRefName(fn_decl))); |
2016 | 2033 | computed_expr_type_ = ComputedExprType::FreshPointer; |
2017 | 2034 | } |
@@ -2063,7 +2080,11 @@ Converter::CallInfo Converter::CollectCallInfo(clang::CallExpr *expr) { |
2063 | 2080 | unsigned num_named_params = |
2064 | 2081 | function ? function->getNumParams() : proto->getNumParams(); |
2065 | 2082 | info.is_variadic = function ? function->isVariadic() : proto->isVariadic(); |
2066 | | - info.is_fn_ptr_call = !function || AsLambdaClass(callee->getType()); |
| 2083 | + info.is_fn_ptr_call = |
| 2084 | + !function || AsLambdaClass(callee->getType()) || |
| 2085 | + clang::isa<clang::SubstNonTypeTemplateParmExpr>( |
| 2086 | + clang::IgnoreExprNodes(callee, clang::IgnoreParensSingleStep, |
| 2087 | + clang::IgnoreImplicitCastsSingleStep)); |
2067 | 2088 | info.is_libc_passthrough = RuleRegistry::IsLibcPassthrough(ctx_, expr); |
2068 | 2089 |
|
2069 | 2090 | for (unsigned i = 0; i < num_named_params && i < num_args; ++i) { |
@@ -2224,8 +2245,9 @@ void Converter::EmitArgList(const CallInfo &info) { |
2224 | 2245 |
|
2225 | 2246 | if (info.is_variadic) { |
2226 | 2247 | if (!info.is_libc_passthrough) { |
2227 | | - StrCat(token::kRef); |
| 2248 | + StrCat("Box::new"); |
2228 | 2249 | } |
| 2250 | + PushParen box(*this, !info.is_libc_passthrough); |
2229 | 2251 | PushBracket push(*this, !info.is_libc_passthrough); |
2230 | 2252 | for (auto *arg : info.variadic_args) { |
2231 | 2253 | { |
@@ -3244,6 +3266,13 @@ std::string Converter::ConvertDeclRef(clang::Expr *expr, |
3244 | 3266 | } |
3245 | 3267 |
|
3246 | 3268 | bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) { |
| 3269 | + if (auto param = |
| 3270 | + clang::dyn_cast<clang::TemplateParamObjectDecl>(expr->getDecl()); |
| 3271 | + param && AsLambdaClass(param->getType())) { |
| 3272 | + StrCat(GetDefaultAsString(param->getType())); |
| 3273 | + computed_expr_type_ = ComputedExprType::FreshValue; |
| 3274 | + return false; |
| 3275 | + } |
3247 | 3276 | if (auto init = AsLambdaUncapturedConstant(curr_function_, expr)) { |
3248 | 3277 | Convert(init); |
3249 | 3278 | return false; |
@@ -4055,6 +4084,9 @@ void Converter::ConvertLambdaClosure(const clang::CXXRecordDecl *decl, |
4055 | 4084 | ConvertVarDeclSkipInit(p); |
4056 | 4085 | StrCat(token::kComma); |
4057 | 4086 | } |
| 4087 | + if (call_operator->isVariadic()) { |
| 4088 | + StrCat("__args: Box<[VaArg]>", token::kComma); |
| 4089 | + } |
4058 | 4090 | in_function_formals_ = false; |
4059 | 4091 | StrCat('|'); |
4060 | 4092 | ConvertFunctionReturnType(call_operator); |
@@ -4270,10 +4302,6 @@ std::string Converter::GetArrayDefaultAsString(clang::QualType qual_type) { |
4270 | 4302 | std::string Converter::GetDefaultAsString(clang::QualType qual_type) { |
4271 | 4303 | if (auto lambda = AsLambdaClass(qual_type); |
4272 | 4304 | lambda && lambda->captures().empty()) { |
4273 | | - if (HasStaticLocal(lambda->getLambdaCallOperator()->getBody())) { |
4274 | | - llvm::report_fatal_error("default-constructed lambda with a static local " |
4275 | | - "is not supported yet"); |
4276 | | - } |
4277 | 4305 | Buffer buf(*this); |
4278 | 4306 | ConvertCapturelessLambda(lambda); |
4279 | 4307 | return std::move(buf).str(); |
@@ -4616,7 +4644,7 @@ void Converter::ConvertFunctionParameters(clang::FunctionDecl *decl) { |
4616 | 4644 | StrCat(token::kComma); |
4617 | 4645 | } |
4618 | 4646 | if (decl->isVariadic()) { |
4619 | | - StrCat("__args: &[VaArg]", token::kComma); |
| 4647 | + StrCat("__args: Box<[VaArg]>", token::kComma); |
4620 | 4648 | } |
4621 | 4649 | in_function_formals_ = false; |
4622 | 4650 | } |
@@ -5311,15 +5339,15 @@ Converter::ConvertVariadicTail(clang::Expr *expr, |
5311 | 5339 | unsigned fixed = tgt_ir ? tgt_ir->params.size() : 0; |
5312 | 5340 |
|
5313 | 5341 | Buffer buf(*this); |
5314 | | - StrCat("&["); |
| 5342 | + StrCat("Box::<[VaArg]>::from(["); |
5315 | 5343 | for (unsigned i = fixed; i < all_args.size(); ++i) { |
5316 | 5344 | { |
5317 | 5345 | PushParen p(*this); |
5318 | 5346 | ConvertVariadicArg(all_args[i]); |
5319 | 5347 | } |
5320 | 5348 | StrCat(".into()", token::kComma); |
5321 | 5349 | } |
5322 | | - StrCat("]"); |
| 5350 | + StrCat("])"); |
5323 | 5351 | return std::move(buf).str(); |
5324 | 5352 | } |
5325 | 5353 |
|
|
0 commit comments