@@ -136,7 +136,8 @@ static std::string FunctionToString(ASTContext &Ctx, QualType QT,
136
136
// *OpaqueType, void *Val);
137
137
const FunctionDecl *FD = nullptr ;
138
138
if (auto *InterfaceCall = llvm::dyn_cast<CallExpr>(TLSD->getStmt ())) {
139
- const auto *Arg = InterfaceCall->getArg (/* Val*/ 3 );
139
+ const auto *Arg = InterfaceCall->getArg (InterfaceCall->getNumArgs () - 1 );
140
+
140
141
// Get rid of cast nodes.
141
142
while (const CastExpr *CastE = llvm::dyn_cast<CastExpr>(Arg))
142
143
Arg = CastE->getSubExpr ();
@@ -156,32 +157,32 @@ static std::string FunctionToString(ASTContext &Ctx, QualType QT,
156
157
static std::string escapeString (const std::vector<uint8_t > &Raw) {
157
158
std::string Out;
158
159
for (char c : Raw) {
159
- switch (c) {
160
- case ' \n ' :
161
- Out += " \\ n" ;
162
- break ;
163
- case ' \t ' :
164
- Out += " \\ t" ;
165
- break ;
166
- case ' \r ' :
167
- Out += " \\ r" ;
168
- break ;
169
- case ' \" ' :
170
- Out += " \\\" " ;
171
- break ;
172
- case ' \\ ' :
173
- Out += " \\\\ " ;
174
- break ;
175
- default :
176
- if (std::isprint (static_cast <unsigned char >(c)))
177
- Out.push_back (c);
178
- else {
179
- char buf[5 ];
180
- snprintf (buf, sizeof (buf), " \\ x%02X" , static_cast <unsigned char >(c));
181
- Out += buf;
182
- }
183
- break ;
160
+ // switch (c) {
161
+ // case '\n':
162
+ // Out += "\\n";
163
+ // break;
164
+ // case '\t':
165
+ // Out += "\\t";
166
+ // break;
167
+ // case '\r':
168
+ // Out += "\\r";
169
+ // break;
170
+ // case '\"':
171
+ // Out += "\\\"";
172
+ // break;
173
+ // case '\\':
174
+ // Out += "\\\\";
175
+ // break;
176
+ // default:
177
+ if (std::isprint (static_cast <unsigned char >(c)))
178
+ Out.push_back (c);
179
+ else {
180
+ char buf[5 ];
181
+ snprintf (buf, sizeof (buf), " \\ x%02X" , static_cast <unsigned char >(c));
182
+ Out += buf;
184
183
}
184
+ // break;
185
+ // }
185
186
}
186
187
return Out;
187
188
}
@@ -212,16 +213,16 @@ std::string ValueToString::BuiltinToString(const BuiltinValueBuffer &B) {
212
213
if (NonRefTy->isCharType ()) {
213
214
unsigned char c = B.as <unsigned char >();
214
215
switch (c) {
215
- case ' \n ' :
216
- return " '\\ n'" ;
217
- case ' \t ' :
218
- return " '\\ t'" ;
219
- case ' \r ' :
220
- return " '\\ r'" ;
221
- case ' \' ' :
222
- return " '\\ ''" ;
223
- case ' \\ ' :
224
- return " '\\ '" ;
216
+ // case '\n':
217
+ // return "'\\n'";
218
+ // case '\t':
219
+ // return "'\\t'";
220
+ // case '\r':
221
+ // return "'\\r'";
222
+ // case '\'':
223
+ // return "'\\''";
224
+ // case '\\':
225
+ // return "'\\'";
225
226
case ' \0 ' :
226
227
return " " ;
227
228
default :
@@ -312,16 +313,19 @@ std::string ValueToString::PointerToString(const PointerValueBuffer &P) {
312
313
QualType DesugaredTy = QT.getDesugaredType (Ctx);
313
314
QualType NonRefTy = DesugaredTy.getNonReferenceType ();
314
315
315
- auto PtrTy = dyn_cast<PointerType>(QT.getTypePtr ());
316
- if (!PtrTy)
317
- return " " ;
316
+ if (auto PtrTy = dyn_cast<PointerType>(QT.getTypePtr ())) {
317
+ if (!PtrTy)
318
+ return " " ;
319
+
320
+ auto PointeeTy = PtrTy->getPointeeType ();
318
321
319
- auto PointeeTy = PtrTy->getPointeeType ();
322
+ // char* -> print string literal
323
+ if (PointeeTy->isCharType () && P.Pointee ) {
324
+ if (auto *BE = static_cast <BuiltinValueBuffer *>(P.Pointee .get ()))
325
+ return " \" " + escapeString (BE->raw ) + " \" " ;
326
+ }
320
327
321
- // char* -> print string literal
322
- if (PointeeTy->isCharType () && P.Pointee ) {
323
- if (auto *BE = static_cast <BuiltinValueBuffer *>(P.Pointee .get ()))
324
- return " \" " + escapeString (BE->raw ) + " \" " ;
328
+ return std::to_string (P.Address );
325
329
}
326
330
327
331
if (P.Address == 0 )
@@ -334,6 +338,9 @@ std::string ValueToString::PointerToString(const PointerValueBuffer &P) {
334
338
if (NonRefTy->isFunctionType ())
335
339
return FunctionToString (Ctx, QT, (void *)P.Address );
336
340
341
+ if (NonRefTy->isNullPtrType ())
342
+ return " nullptr\n " ;
343
+
337
344
std::ostringstream OS;
338
345
OS << " @0x" << std::hex << P.Address ;
339
346
return OS.str ();
@@ -342,24 +349,26 @@ std::string ValueToString::PointerToString(const PointerValueBuffer &P) {
342
349
std::string ValueToString::ArrayToString (const ArrayValueBuffer &A) {
343
350
if (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType (A.Ty )) {
344
351
QualType ElemTy = CAT->getElementType ();
345
- std::ostringstream OS;
346
352
// Treat null terminated char arrays as strings basically.
347
353
if (ElemTy->isCharType () && !A.Elements .empty ()) {
348
354
if (const auto *B =
349
355
llvm::dyn_cast<BuiltinValueBuffer>(A.Elements .back ().get ())) {
350
- char last = (char )B->raw .back ();
356
+ char last = (char )B->raw .front ();
351
357
if (last != ' \0 ' )
352
358
goto not_a_string;
353
359
}
354
- OS << " \" " ;
360
+ std::string Res;
361
+ Res += " \" " ;
355
362
for (size_t i = 0 ; i < A.Elements .size (); ++i) {
356
363
if (const auto *B =
357
364
llvm::dyn_cast<BuiltinValueBuffer>(A.Elements [i].get ())) {
358
- OS << static_cast <char >(B->raw .back ());
365
+ char c = static_cast <char >(B->raw .back ());
366
+ if (c != ' \0 ' )
367
+ Res += c;
359
368
}
360
369
}
361
- OS << " \" " ;
362
- return OS. str () ;
370
+ Res += " \" " ;
371
+ return Res ;
363
372
}
364
373
}
365
374
not_a_string:
@@ -436,73 +445,90 @@ Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) const {
436
445
}
437
446
438
447
class ExprConverter {
448
+ Sema &S;
439
449
ASTContext &Ctx;
440
450
441
451
public:
442
- ExprConverter (ASTContext &Ctx) : Ctx(Ctx) {}
452
+ ExprConverter (Sema &S, ASTContext &Ctx) : S(S), Ctx(Ctx) {}
443
453
444
454
// / Create (&E) as a void*
445
- ExprResult CreateAddressOfVoidPtrExpr (QualType Ty, Expr *ForCast) {
455
+ ExprResult CreateAddressOfVoidPtrExpr (QualType Ty, Expr *ForCast,
456
+ bool takeAddr = false ) {
446
457
QualType VoidPtrTy = Ctx.getPointerType (Ctx.VoidTy );
447
458
448
459
// &E
449
- Expr *AddrOf = UnaryOperator::Create (
450
- Ctx, ForCast, UO_AddrOf, Ctx.getPointerType (Ty), VK_PRValue,
451
- OK_Ordinary, SourceLocation (), false , FPOptionsOverride ());
460
+ Expr *AddrOf = ForCast;
461
+ if (takeAddr) {
462
+ AddrOf = UnaryOperator::Create (
463
+ Ctx, ForCast, UO_AddrOf, Ctx.getPointerType (Ty), VK_PRValue,
464
+ OK_Ordinary, SourceLocation (), false , FPOptionsOverride ());
465
+ }
452
466
467
+ TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo (Ctx.VoidPtrTy );
468
+ ExprResult CastedExpr =
469
+ S.BuildCStyleCastExpr (SourceLocation (), TSI, SourceLocation (), AddrOf);
470
+ assert (!CastedExpr.isInvalid () && " Can not create cstyle cast expression" );
471
+ return CastedExpr.get ();
453
472
// static_cast<void*>(&E)
454
- return CXXStaticCastExpr::Create (
455
- Ctx, VoidPtrTy, VK_PRValue, CK_BitCast, AddrOf, nullptr ,
456
- Ctx.getTrivialTypeSourceInfo (VoidPtrTy), FPOptionsOverride (),
457
- SourceLocation (), SourceLocation (), SourceRange ());
458
- }
459
-
460
- // / Create a temporary VarDecl with initializer.
461
- VarDecl *createTempVarDecl (QualType Ty, llvm::StringRef BaseName,
462
- Expr *Init) {
463
- static unsigned Counter = 0 ;
464
- IdentifierInfo &Id = Ctx.Idents .get ((BaseName + Twine (++Counter)).str ());
465
-
466
- VarDecl *VD = VarDecl::Create (Ctx, Ctx.getTranslationUnitDecl (),
467
- SourceLocation (), SourceLocation (), &Id, Ty,
468
- Ctx.getTrivialTypeSourceInfo (Ty), SC_Auto);
469
-
470
- VD->setInit (Init);
471
- VD->setInitStyle (VarDecl::CInit);
472
- VD->markUsed (Ctx);
473
-
474
- return VD;
473
+ // return CXXStaticCastExpr::Create(
474
+ // Ctx, VoidPtrTy, VK_PRValue, CK_BitCast, AddrOf, nullptr,
475
+ // Ctx.getTrivialTypeSourceInfo(VoidPtrTy), FPOptionsOverride(),
476
+ // SourceLocation(), SourceLocation(), SourceRange());
475
477
}
476
478
477
479
// / Wrap rvalues in a temporary (var) so they become addressable.
478
480
Expr *CreateMaterializeTemporaryExpr (Expr *E) {
479
- return new (Ctx) MaterializeTemporaryExpr (E->getType (), E,
480
- /* BoundToLvalueReference=*/ true );
481
+ return S. CreateMaterializeTemporaryExpr (E->getType (), E,
482
+ /* BoundToLvalueReference=*/ true );
481
483
}
482
484
483
- // / Generic helper: materialize if needed, then &expr as void*.
484
- ExprResult makeAddressable (QualType QTy, Expr *E) {
485
+ ExprResult makeScalarAddressable (QualType Ty, Expr *E) {
485
486
if (E->isLValue () || E->isXValue ())
486
- return CreateAddressOfVoidPtrExpr (QTy, E);
487
-
488
- if (E->isPRValue ())
489
- return CreateAddressOfVoidPtrExpr (QTy, CreateMaterializeTemporaryExpr (E));
490
-
491
- return ExprError ();
487
+ return CreateAddressOfVoidPtrExpr (Ty, E, /* takeAddr=*/ true );
488
+ return CreateAddressOfVoidPtrExpr (Ty, CreateMaterializeTemporaryExpr (E),
489
+ /* takeAddr=*/ true );
492
490
}
493
491
494
492
ExprResult handleBuiltinTypeExpr (const BuiltinType *, QualType QTy, Expr *E) {
495
- return makeAddressable (QTy, E);
493
+ return makeScalarAddressable (QTy, E);
496
494
}
495
+
496
+ ExprResult handleEnumTypeExpr (const EnumType *, QualType QTy, Expr *E) {
497
+ return makeScalarAddressable (QTy, E);
498
+ }
499
+
497
500
ExprResult handlePointerTypeExpr (const PointerType *, QualType QTy, Expr *E) {
498
- return makeAddressable (QTy, E);
501
+ // Pointer expressions always evaluate to a pointer value.
502
+ // No need to take address or materialize.
503
+ return CreateAddressOfVoidPtrExpr (QTy, E, /* takeAddr=*/ false );
499
504
}
505
+
500
506
ExprResult handleArrayTypeExpr (const ConstantArrayType *, QualType QTy,
501
507
Expr *E) {
502
- return makeAddressable (QTy, E);
508
+ if (isa<StringLiteral>(E)) {
509
+ if (Ctx.getLangOpts ().CPlusPlus )
510
+ return CreateAddressOfVoidPtrExpr (QTy, E, /* takeAddr=*/ true );
511
+ return CreateAddressOfVoidPtrExpr (QTy, E, /* takeAddr=*/ false );
512
+ }
513
+
514
+ if (E->isLValue () || E->isXValue ())
515
+ return CreateAddressOfVoidPtrExpr (QTy, E, /* takeAddr=*/ true );
516
+ return CreateAddressOfVoidPtrExpr (QTy, E,
517
+ /* takeAddr=*/ false );
503
518
}
504
- ExprResult handleEnumTypeExpr (const EnumType *, QualType QTy, Expr *E) {
505
- return makeAddressable (QTy, E);
519
+
520
+ ExprResult handleFunctionTypeExpr (const FunctionType *, QualType QTy,
521
+ Expr *E) {
522
+ if (Ctx.getLangOpts ().CPlusPlus )
523
+ return CreateAddressOfVoidPtrExpr (QTy, E, /* takeAddr=*/ true );
524
+ return CreateAddressOfVoidPtrExpr (QTy, E, /* takeAddr=*/ false );
525
+ }
526
+
527
+ ExprResult handleAnyObjectExpr (const Type *, QualType QTy, Expr *E) {
528
+ if (E->isLValue () || E->isXValue ())
529
+ return CreateAddressOfVoidPtrExpr (QTy, E, /* takeAddr=*/ true );
530
+ return CreateAddressOfVoidPtrExpr (QTy, CreateMaterializeTemporaryExpr (E),
531
+ /* takeAddr=*/ true );
506
532
}
507
533
};
508
534
@@ -514,10 +540,15 @@ class InterfaceKindVisitor : public TypeVisitor<InterfaceKindVisitor, bool> {
514
540
515
541
public:
516
542
InterfaceKindVisitor (Sema &S, Expr *E, llvm::SmallVectorImpl<Expr *> &Args)
517
- : S(S), E(E), Args(Args), Converter(S.getASTContext()) {}
543
+ : S(S), E(E), Args(Args), Converter(S, S .getASTContext()) {}
518
544
519
545
bool transformExpr (QualType Ty) { return Visit (Ty.getTypePtr ()); }
520
546
547
+ bool VisitType (const Type *T) {
548
+ Args.push_back (Converter.handleAnyObjectExpr (T, QualType (T, 0 ), E).get ());
549
+ return true ;
550
+ }
551
+
521
552
bool VisitBuiltinType (const BuiltinType *Ty) {
522
553
if (Ty->isNullPtrType ()) {
523
554
Args.push_back (E);
@@ -548,14 +579,16 @@ class InterfaceKindVisitor : public TypeVisitor<InterfaceKindVisitor, bool> {
548
579
return true ;
549
580
}
550
581
582
+ bool VisitFunctionType (const FunctionType *Ty) {
583
+ Args.push_back (
584
+ Converter.handleFunctionTypeExpr (Ty, QualType (Ty, 0 ), E).get ());
585
+ return true ;
586
+ }
587
+
551
588
bool VisitEnumType (const EnumType *Ty) {
552
589
Args.push_back (Converter.handleEnumTypeExpr (Ty, QualType (Ty, 0 ), E).get ());
553
590
return true ;
554
591
}
555
-
556
- bool VisitRecordType (const RecordType *) { return true ; }
557
- bool VisitMemberPointerType (const MemberPointerType *) { return true ; }
558
- bool VisitFunctionType (const FunctionType *) { return true ; }
559
592
};
560
593
561
594
enum RunTimeFnTag { OrcSendResult, ClangSendResult };
0 commit comments