Skip to content

Commit d540221

Browse files
committed
Fix some issues
1 parent 7ae5095 commit d540221

File tree

2 files changed

+158
-120
lines changed

2 files changed

+158
-120
lines changed

clang/lib/Interpreter/InterpreterValuePrinter.cpp

Lines changed: 129 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ static std::string FunctionToString(ASTContext &Ctx, QualType QT,
136136
// *OpaqueType, void *Val);
137137
const FunctionDecl *FD = nullptr;
138138
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+
140141
// Get rid of cast nodes.
141142
while (const CastExpr *CastE = llvm::dyn_cast<CastExpr>(Arg))
142143
Arg = CastE->getSubExpr();
@@ -156,32 +157,32 @@ static std::string FunctionToString(ASTContext &Ctx, QualType QT,
156157
static std::string escapeString(const std::vector<uint8_t> &Raw) {
157158
std::string Out;
158159
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;
184183
}
184+
// break;
185+
// }
185186
}
186187
return Out;
187188
}
@@ -212,16 +213,16 @@ std::string ValueToString::BuiltinToString(const BuiltinValueBuffer &B) {
212213
if (NonRefTy->isCharType()) {
213214
unsigned char c = B.as<unsigned char>();
214215
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 "'\\'";
225226
case '\0':
226227
return "";
227228
default:
@@ -312,16 +313,19 @@ std::string ValueToString::PointerToString(const PointerValueBuffer &P) {
312313
QualType DesugaredTy = QT.getDesugaredType(Ctx);
313314
QualType NonRefTy = DesugaredTy.getNonReferenceType();
314315

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();
318321

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+
}
320327

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);
325329
}
326330

327331
if (P.Address == 0)
@@ -334,6 +338,9 @@ std::string ValueToString::PointerToString(const PointerValueBuffer &P) {
334338
if (NonRefTy->isFunctionType())
335339
return FunctionToString(Ctx, QT, (void *)P.Address);
336340

341+
if (NonRefTy->isNullPtrType())
342+
return "nullptr\n";
343+
337344
std::ostringstream OS;
338345
OS << "@0x" << std::hex << P.Address;
339346
return OS.str();
@@ -342,24 +349,26 @@ std::string ValueToString::PointerToString(const PointerValueBuffer &P) {
342349
std::string ValueToString::ArrayToString(const ArrayValueBuffer &A) {
343350
if (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(A.Ty)) {
344351
QualType ElemTy = CAT->getElementType();
345-
std::ostringstream OS;
346352
// Treat null terminated char arrays as strings basically.
347353
if (ElemTy->isCharType() && !A.Elements.empty()) {
348354
if (const auto *B =
349355
llvm::dyn_cast<BuiltinValueBuffer>(A.Elements.back().get())) {
350-
char last = (char)B->raw.back();
356+
char last = (char)B->raw.front();
351357
if (last != '\0')
352358
goto not_a_string;
353359
}
354-
OS << "\"";
360+
std::string Res;
361+
Res += "\"";
355362
for (size_t i = 0; i < A.Elements.size(); ++i) {
356363
if (const auto *B =
357364
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;
359368
}
360369
}
361-
OS << "\"";
362-
return OS.str();
370+
Res += "\"";
371+
return Res;
363372
}
364373
}
365374
not_a_string:
@@ -436,73 +445,90 @@ Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) const {
436445
}
437446

438447
class ExprConverter {
448+
Sema &S;
439449
ASTContext &Ctx;
440450

441451
public:
442-
ExprConverter(ASTContext &Ctx) : Ctx(Ctx) {}
452+
ExprConverter(Sema &S, ASTContext &Ctx) : S(S), Ctx(Ctx) {}
443453

444454
/// Create (&E) as a void*
445-
ExprResult CreateAddressOfVoidPtrExpr(QualType Ty, Expr *ForCast) {
455+
ExprResult CreateAddressOfVoidPtrExpr(QualType Ty, Expr *ForCast,
456+
bool takeAddr = false) {
446457
QualType VoidPtrTy = Ctx.getPointerType(Ctx.VoidTy);
447458

448459
// &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+
}
452466

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();
453472
// 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());
475477
}
476478

477479
/// Wrap rvalues in a temporary (var) so they become addressable.
478480
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);
481483
}
482484

483-
/// Generic helper: materialize if needed, then &expr as void*.
484-
ExprResult makeAddressable(QualType QTy, Expr *E) {
485+
ExprResult makeScalarAddressable(QualType Ty, Expr *E) {
485486
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);
492490
}
493491

494492
ExprResult handleBuiltinTypeExpr(const BuiltinType *, QualType QTy, Expr *E) {
495-
return makeAddressable(QTy, E);
493+
return makeScalarAddressable(QTy, E);
496494
}
495+
496+
ExprResult handleEnumTypeExpr(const EnumType *, QualType QTy, Expr *E) {
497+
return makeScalarAddressable(QTy, E);
498+
}
499+
497500
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);
499504
}
505+
500506
ExprResult handleArrayTypeExpr(const ConstantArrayType *, QualType QTy,
501507
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);
503518
}
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);
506532
}
507533
};
508534

@@ -514,10 +540,15 @@ class InterfaceKindVisitor : public TypeVisitor<InterfaceKindVisitor, bool> {
514540

515541
public:
516542
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()) {}
518544

519545
bool transformExpr(QualType Ty) { return Visit(Ty.getTypePtr()); }
520546

547+
bool VisitType(const Type *T) {
548+
Args.push_back(Converter.handleAnyObjectExpr(T, QualType(T, 0), E).get());
549+
return true;
550+
}
551+
521552
bool VisitBuiltinType(const BuiltinType *Ty) {
522553
if (Ty->isNullPtrType()) {
523554
Args.push_back(E);
@@ -548,14 +579,16 @@ class InterfaceKindVisitor : public TypeVisitor<InterfaceKindVisitor, bool> {
548579
return true;
549580
}
550581

582+
bool VisitFunctionType(const FunctionType *Ty) {
583+
Args.push_back(
584+
Converter.handleFunctionTypeExpr(Ty, QualType(Ty, 0), E).get());
585+
return true;
586+
}
587+
551588
bool VisitEnumType(const EnumType *Ty) {
552589
Args.push_back(Converter.handleEnumTypeExpr(Ty, QualType(Ty, 0), E).get());
553590
return true;
554591
}
555-
556-
bool VisitRecordType(const RecordType *) { return true; }
557-
bool VisitMemberPointerType(const MemberPointerType *) { return true; }
558-
bool VisitFunctionType(const FunctionType *) { return true; }
559592
};
560593

561594
enum RunTimeFnTag { OrcSendResult, ClangSendResult };

0 commit comments

Comments
 (0)