@@ -616,8 +616,6 @@ static Decl* GetScopeFromType(QualType QT) {
616616 Type = Type->getUnqualifiedDesugaredType ();
617617 if (auto * ET = llvm::dyn_cast<EnumType>(Type))
618618 return ET->getDecl ();
619- if (auto * FnType = llvm::dyn_cast<FunctionProtoType>(Type))
620- Type = const_cast <clang::Type*>(FnType->getReturnType ().getTypePtr ());
621619 return Type->getAsCXXRecordDecl ();
622620 }
623621 return 0 ;
@@ -1327,6 +1325,8 @@ void GetDatamembers(TCppScope_t scope, std::vector<TCppScope_t>& datamembers) {
13271325
13281326 if (auto * CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
13291327 getSema ().ForceDeclarationOfImplicitMembers (CXXRD);
1328+ if (CXXRD->hasDefinition ())
1329+ CXXRD = CXXRD->getDefinition ();
13301330
13311331 llvm::SmallVector<RecordDecl::decl_iterator, 2 > stack_begin;
13321332 llvm::SmallVector<RecordDecl::decl_iterator, 2 > stack_end;
@@ -1447,7 +1447,7 @@ intptr_t GetVariableOffset(compat::Interpreter& I, Decl* D,
14471447 }
14481448 offset += C.toCharUnitsFromBits (C.getFieldOffset (FD)).getQuantity ();
14491449 }
1450- if (BaseCXXRD && BaseCXXRD != FieldParentRecordDecl) {
1450+ if (BaseCXXRD && BaseCXXRD != FieldParentRecordDecl-> getCanonicalDecl () ) {
14511451 // FieldDecl FD belongs to some class C, but the base class BaseCXXRD is
14521452 // not C. That means BaseCXXRD derives from C. Offset needs to be
14531453 // calculated for Derived class
@@ -1476,7 +1476,7 @@ intptr_t GetVariableOffset(compat::Interpreter& I, Decl* D,
14761476 }
14771477 if (auto * RD = llvm::dyn_cast<CXXRecordDecl>(FieldParentRecordDecl)) {
14781478 // add in the offsets for the (multi level) base classes
1479- while (BaseCXXRD != RD) {
1479+ while (BaseCXXRD != RD-> getCanonicalDecl () ) {
14801480 CXXRecordDecl* Parent = direction.at (RD);
14811481 offset +=
14821482 C.getASTRecordLayout (Parent).getBaseClassOffset (RD).getQuantity ();
@@ -1689,6 +1689,10 @@ std::string GetTypeAsString(TCppType_t var) {
16891689 PrintingPolicy Policy ((LangOptions ()));
16901690 Policy.Bool = true ; // Print bool instead of _Bool.
16911691 Policy.SuppressTagKeyword = true ; // Do not print `class std::string`.
1692+ #if CLANG_VERSION_MAJOR > 16
1693+ Policy.SuppressElaboration = true ;
1694+ #endif
1695+ Policy.FullyQualifiedName = true ;
16921696 return compat::FixTypeName (QT.getAsString (Policy));
16931697}
16941698
@@ -1833,6 +1837,7 @@ void get_type_as_string(QualType QT, std::string& type_name, ASTContext& C,
18331837#if CLANG_VERSION_MAJOR > 16
18341838 Policy.SuppressElaboration = true ;
18351839#endif
1840+ Policy.SuppressTagKeyword = !QT->isEnumeralType ();
18361841 Policy.FullyQualifiedName = true ;
18371842 QT.getAsStringInternal (type_name, Policy);
18381843}
@@ -2103,6 +2108,30 @@ void make_narg_call(const FunctionDecl* FD, const std::string& return_type,
21032108 std::string template_args = complete_name.substr (idx);
21042109 name = name_without_template_args +
21052110 (template_args.empty () ? " " : " " + template_args);
2111+
2112+ // If a template has consecutive parameter packs, then it is impossible to
2113+ // use the explicit name in the wrapper, since the type deduction is what
2114+ // determines the split of the packs. Instead, we'll revert to the
2115+ // non-templated function name and hope that the type casts in the wrapper
2116+ // will suffice.
2117+ if (FD->isTemplateInstantiation () && FD->getPrimaryTemplate ()) {
2118+ const FunctionTemplateDecl* FTDecl =
2119+ llvm::dyn_cast<FunctionTemplateDecl>(FD->getPrimaryTemplate ());
2120+ if (FTDecl) {
2121+ auto * templateParms = FTDecl->getTemplateParameters ();
2122+ int numPacks = 0 ;
2123+ for (size_t iParam = 0 , nParams = templateParms->size ();
2124+ iParam < nParams; ++iParam) {
2125+ if (templateParms->getParam (iParam)->isTemplateParameterPack ())
2126+ numPacks += 1 ;
2127+ else
2128+ numPacks = 0 ;
2129+ }
2130+ if (numPacks > 1 ) {
2131+ name = name_without_template_args;
2132+ }
2133+ }
2134+ }
21062135 }
21072136 if (op_flag || N <= 1 )
21082137 callbuf << name;
@@ -2707,7 +2736,7 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
27072736 //
27082737 {
27092738 std::ostringstream buf;
2710- buf << " __cf " ;
2739+ buf << " __jc " ;
27112740 // const NamedDecl* ND = dyn_cast<NamedDecl>(FD);
27122741 // std::string mn;
27132742 // fInterp->maybeMangleDeclName(ND, mn);
@@ -3422,6 +3451,8 @@ static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
34223451 // This will instantiate tape<T> type and return it.
34233452 SourceLocation noLoc;
34243453 QualType TT = S.CheckTemplateIdType (TemplateName (TemplateD), noLoc, TLI);
3454+ if (TT.isNull ())
3455+ return nullptr ;
34253456
34263457 // Perhaps we can extract this into a new interface.
34273458 S.RequireCompleteType (fakeLoc, TT, diag::err_tentative_def_incomplete_type);
@@ -3753,22 +3784,25 @@ void Deallocate(TCppScope_t scope, TCppObject_t address, TCppIndex_t count) {
37533784// FIXME: Add optional arguments to the operator new.
37543785TCppObject_t Construct (compat::Interpreter& interp, TCppScope_t scope,
37553786 void * arena /* =nullptr*/ , TCppIndex_t count /* =1UL*/ ) {
3756- auto * Class = (Decl*)scope;
3757- // FIXME: Diagnose.
3758- if (!HasDefaultConstructor (Class))
3759- return nullptr ;
37603787
3761- auto * const Ctor = GetDefaultConstructor (interp, Class);
3762- if (JitCall JC = MakeFunctionCallable (&interp, Ctor)) {
3763- if (arena) {
3764- JC.InvokeConstructor (&arena, count, {},
3765- (void *)~0 ); // Tell Invoke to use placement new.
3766- return arena;
3767- }
3788+ if (!Cpp::IsConstructor (scope) && !Cpp::IsClass (scope))
3789+ return nullptr ;
3790+ if (Cpp::IsClass (scope) && !HasDefaultConstructor (scope))
3791+ return nullptr ;
37683792
3769- void * obj = nullptr ;
3770- JC.InvokeConstructor (&obj, count, {}, nullptr );
3771- return obj;
3793+ TCppFunction_t ctor = nullptr ;
3794+ if (Cpp::IsClass (scope))
3795+ ctor = Cpp::GetDefaultConstructor (scope);
3796+ else // a ctor
3797+ ctor = scope;
3798+
3799+ if (JitCall JC = MakeFunctionCallable (&interp, ctor)) {
3800+ // invoke the constructor (placement/heap) in one shot
3801+ // flag is non-null for placement new, null for normal new
3802+ void * is_arena = arena ? reinterpret_cast <void *>(1 ) : nullptr ;
3803+ void * result = arena;
3804+ JC.InvokeConstructor (&result, count, /* args=*/ {}, is_arena);
3805+ return result;
37723806 }
37733807 return nullptr ;
37743808}
0 commit comments