Support __PRETTY_FUNCTION__ and friends in Obj-C methods.
Add CodeGenFunction::EmitUnsupportedLValue
- Gives error and returns undef value.
Swap some asserts() over to using EmitUnsupportedLValue
- Rumor has it users (and even some developers) prefer carat
diagnostics to backtraces.
- Works better in Release-Asserts to boot.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55328 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index de0f634..0b4bf23 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -71,6 +71,14 @@
// LValue Expression Emission
//===----------------------------------------------------------------------===//
+LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
+ const char *Name) {
+ ErrorUnsupported(E, Name);
+ llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
+ return LValue::MakeAddr(llvm::UndefValue::get(Ty),
+ E->getType().getCVRQualifiers());
+}
+
/// EmitLValue - Emit code to compute a designator that specifies the location
/// of the expression.
///
@@ -89,12 +97,7 @@
///
LValue CodeGenFunction::EmitLValue(const Expr *E) {
switch (E->getStmtClass()) {
- default: {
- ErrorUnsupported(E, "l-value expression");
- llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
- return LValue::MakeAddr(llvm::UndefValue::get(Ty),
- E->getType().getCVRQualifiers());
- }
+ default: return EmitUnsupportedLValue(E, "l-value expression");
case Expr::CallExprClass: return EmitCallExprLValue(cast<CallExpr>(E));
case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
@@ -108,13 +111,10 @@
return EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E));
case Expr::ObjCIvarRefExprClass:
return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
- case Expr::ObjCPropertyRefExprClass: {
+ case Expr::ObjCPropertyRefExprClass:
// FIXME: Implement!
- ErrorUnsupported(E, "l-value expression (Objective-C property reference)");
- llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
- return LValue::MakeAddr(llvm::UndefValue::get(Ty),
- E->getType().getCVRQualifiers());
- }
+ return EmitUnsupportedLValue(E,
+ "l-value expression (Objective-C property)");
case Expr::UnaryOperatorClass:
return EmitUnaryOpLValue(cast<UnaryOperator>(E));
@@ -503,15 +503,17 @@
std::string FunctionName;
if(const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) {
FunctionName = FD->getName();
- }
- else {
- assert(0 && "Attempting to load predefined constant for invalid decl type");
+ } else if (isa<ObjCMethodDecl>(CurFuncDecl)) {
+ // Just get the mangled name.
+ FunctionName = CurFn->getName();
+ } else {
+ return EmitUnsupportedLValue(E, "predefined expression");
}
std::string GlobalVarName;
switch (E->getIdentType()) {
default:
- assert(0 && "unknown pre-defined ident type");
+ return EmitUnsupportedLValue(E, "predefined expression");
case PredefinedExpr::Func:
GlobalVarName = "__func__.";
break;
@@ -527,7 +529,7 @@
GlobalVarName += FunctionName;
// FIXME: Can cache/reuse these within the module.
- llvm::Constant *C=llvm::ConstantArray::get(FunctionName);
+ llvm::Constant *C = llvm::ConstantArray::get(FunctionName);
// Create a global variable for this.
C = new llvm::GlobalVariable(C->getType(), true,
@@ -565,7 +567,7 @@
// We know that the pointer points to a type of the correct size, unless the
// size is a VLA.
if (!E->getType()->isConstantSizeType())
- assert(0 && "VLA idx not implemented");
+ return EmitUnsupportedLValue(E, "VLA index");
QualType ExprTy = getContext().getCanonicalType(E->getBase()->getType());
return LValue::MakeAddr(Builder.CreateGEP(Base, Idx, "arrayidx"),
@@ -759,8 +761,7 @@
// then the CGObjCRuntime subclass must return true to LateBoundIvars and
// implement the lookup itself.
if (CGM.getObjCRuntime().LateBoundIVars()) {
- assert(0 && "FIXME: Implement support for late-bound instance variables");
- return LValue(); // Not reached.
+ return EmitUnsupportedLValue(E, "late-bound instance variables");
}
// FIXME: A lot of the code below could be shared with EmitMemberExpr.
@@ -780,8 +781,8 @@
}
const ObjCIvarDecl *Field = E->getDecl();
- assert(!Field->isBitField() &&
- "Bitfields are currently not supported!");
+ if (Field->isBitField())
+ return EmitUnsupportedLValue(E, "ivar bitfields");
// TODO: Add a special case for isa (index 0)
unsigned Index = CGM.getTypes().getLLVMFieldNo(Field);
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 0d82e32..2ba6b8d 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -223,6 +223,12 @@
// LValue Expression Emission
//===--------------------------------------------------------------------===//
+ /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E
+ /// and issue an ErrorUnsupported style diagnostic (using the
+ /// provided Name).
+ LValue EmitUnsupportedLValue(const Expr *E,
+ const char *Name);
+
/// EmitLValue - Emit code to compute a designator that specifies the location
/// of the expression.
///