<div dir="ltr">It looks like this change introduced a small bug;  Specifically, the following cast test:<div><br></div><div>-      if (auto PT = dyn_cast<llvm::PointerType>(DestTy)) {<div>...<br><div>+  // If we're producing a pointer, this is easy.<br>+  if (auto destPtrTy = cast<llvm::PointerType>(destTy)) {</div></div></div><div><br></div><div>Since the cast can fail, shouldn't you prefer dyn_cast<>(), which can return nullptr, over cast<>(), which will assert?</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Aug 16, 2017 at 11:04 PM John McCall via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: rjmccall<br>
Date: Wed Aug 16 22:03:55 2017<br>
New Revision: 311065<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=311065&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=311065&view=rev</a><br>
Log:<br>
Further refactoring of the constant emitter.  NFC.<br>
<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=311065&r1=311064&r2=311065&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=311065&r1=311064&r2=311065&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Wed Aug 16 22:03:55 2017<br>
@@ -1044,120 +1044,6 @@ public:<br>
   llvm::Type *ConvertType(QualType T) {<br>
     return CGM.getTypes().ConvertType(T);<br>
   }<br>
-<br>
-public:<br>
-  ConstantAddress EmitLValue(APValue::LValueBase LVBase) {<br>
-    if (const ValueDecl *Decl = LVBase.dyn_cast<const ValueDecl*>()) {<br>
-      if (Decl->hasAttr<WeakRefAttr>())<br>
-        return CGM.GetWeakRefReference(Decl);<br>
-      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))<br>
-        return ConstantAddress(CGM.GetAddrOfFunction(FD), CharUnits::One());<br>
-      if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {<br>
-        // We can never refer to a variable with local storage.<br>
-        if (!VD->hasLocalStorage()) {<br>
-          CharUnits Align = CGM.getContext().getDeclAlign(VD);<br>
-          if (VD->isFileVarDecl() || VD->hasExternalStorage())<br>
-            return ConstantAddress(CGM.GetAddrOfGlobalVar(VD), Align);<br>
-          else if (VD->isLocalVarDecl()) {<br>
-            auto Ptr = CGM.getOrCreateStaticVarDecl(<br>
-                *VD, CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false));<br>
-            return ConstantAddress(Ptr, Align);<br>
-          }<br>
-        }<br>
-      }<br>
-      return ConstantAddress::invalid();<br>
-    }<br>
-<br>
-    Expr *E = const_cast<Expr*>(LVBase.get<const Expr*>());<br>
-    switch (E->getStmtClass()) {<br>
-    default: break;<br>
-    case Expr::CompoundLiteralExprClass:<br>
-      return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF,<br>
-                                          cast<CompoundLiteralExpr>(E));<br>
-    case Expr::StringLiteralClass:<br>
-      return CGM.GetAddrOfConstantStringFromLiteral(cast<StringLiteral>(E));<br>
-    case Expr::ObjCEncodeExprClass:<br>
-      return CGM.GetAddrOfConstantStringFromObjCEncode(cast<ObjCEncodeExpr>(E));<br>
-    case Expr::ObjCStringLiteralClass: {<br>
-      ObjCStringLiteral* SL = cast<ObjCStringLiteral>(E);<br>
-      ConstantAddress C =<br>
-          CGM.getObjCRuntime().GenerateConstantString(SL->getString());<br>
-      return C.getElementBitCast(ConvertType(E->getType()));<br>
-    }<br>
-    case Expr::PredefinedExprClass: {<br>
-      unsigned Type = cast<PredefinedExpr>(E)->getIdentType();<br>
-      if (auto CGF = Emitter.CGF) {<br>
-        LValue Res = CGF->EmitPredefinedLValue(cast<PredefinedExpr>(E));<br>
-        return cast<ConstantAddress>(Res.getAddress());<br>
-      } else if (Type == PredefinedExpr::PrettyFunction) {<br>
-        return CGM.GetAddrOfConstantCString("top level", ".tmp");<br>
-      }<br>
-<br>
-      return CGM.GetAddrOfConstantCString("", ".tmp");<br>
-    }<br>
-    case Expr::AddrLabelExprClass: {<br>
-      assert(Emitter.CGF &&<br>
-             "Invalid address of label expression outside function.");<br>
-      llvm::Constant *Ptr =<br>
-        Emitter.CGF->GetAddrOfLabel(cast<AddrLabelExpr>(E)->getLabel());<br>
-      Ptr = llvm::ConstantExpr::getBitCast(Ptr, ConvertType(E->getType()));<br>
-      return ConstantAddress(Ptr, CharUnits::One());<br>
-    }<br>
-    case Expr::CallExprClass: {<br>
-      CallExpr* CE = cast<CallExpr>(E);<br>
-      unsigned builtin = CE->getBuiltinCallee();<br>
-      if (builtin !=<br>
-            Builtin::BI__builtin___CFStringMakeConstantString &&<br>
-          builtin !=<br>
-            Builtin::BI__builtin___NSStringMakeConstantString)<br>
-        break;<br>
-      const Expr *Arg = CE->getArg(0)->IgnoreParenCasts();<br>
-      const StringLiteral *Literal = cast<StringLiteral>(Arg);<br>
-      if (builtin ==<br>
-            Builtin::BI__builtin___NSStringMakeConstantString) {<br>
-        return CGM.getObjCRuntime().GenerateConstantString(Literal);<br>
-      }<br>
-      // FIXME: need to deal with UCN conversion issues.<br>
-      return CGM.GetAddrOfConstantCFString(Literal);<br>
-    }<br>
-    case Expr::BlockExprClass: {<br>
-      StringRef FunctionName;<br>
-      if (auto CGF = Emitter.CGF)<br>
-        FunctionName = CGF->CurFn->getName();<br>
-      else<br>
-        FunctionName = "global";<br>
-<br>
-      // This is not really an l-value.<br>
-      llvm::Constant *Ptr =<br>
-        CGM.GetAddrOfGlobalBlock(cast<BlockExpr>(E), FunctionName);<br>
-      return ConstantAddress(Ptr, CGM.getPointerAlign());<br>
-    }<br>
-    case Expr::CXXTypeidExprClass: {<br>
-      CXXTypeidExpr *Typeid = cast<CXXTypeidExpr>(E);<br>
-      QualType T;<br>
-      if (Typeid->isTypeOperand())<br>
-        T = Typeid->getTypeOperand(CGM.getContext());<br>
-      else<br>
-        T = Typeid->getExprOperand()->getType();<br>
-      return ConstantAddress(CGM.GetAddrOfRTTIDescriptor(T),<br>
-                             CGM.getPointerAlign());<br>
-    }<br>
-    case Expr::CXXUuidofExprClass: {<br>
-      return CGM.GetAddrOfUuidDescriptor(cast<CXXUuidofExpr>(E));<br>
-    }<br>
-    case Expr::MaterializeTemporaryExprClass: {<br>
-      MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(E);<br>
-      assert(MTE->getStorageDuration() == SD_Static);<br>
-      SmallVector<const Expr *, 2> CommaLHSs;<br>
-      SmallVector<SubobjectAdjustment, 2> Adjustments;<br>
-      const Expr *Inner = MTE->GetTemporaryExpr()<br>
-          ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);<br>
-      return CGM.GetAddrOfGlobalTemporary(MTE, Inner);<br>
-    }<br>
-    }<br>
-<br>
-    return ConstantAddress::invalid();<br>
-  }<br>
 };<br>
<br>
 }  // end anonymous namespace.<br>
@@ -1623,67 +1509,303 @@ llvm::Constant *CodeGenModule::getNullPo<br>
   return getTargetCodeGenInfo().getNullPointer(*this, T, QT);<br>
 }<br>
<br>
-llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,<br>
-                                                QualType DestType) {<br>
-  switch (Value.getKind()) {<br>
-  case APValue::Uninitialized:<br>
-    llvm_unreachable("Constant expressions should be initialized.");<br>
-  case APValue::LValue: {<br>
-    llvm::Type *DestTy = CGM.getTypes().ConvertTypeForMem(DestType);<br>
-    llvm::Constant *Offset =<br>
-      llvm::ConstantInt::get(CGM.Int64Ty,<br>
-                             Value.getLValueOffset().getQuantity());<br>
-<br>
-    if (APValue::LValueBase LVBase = Value.getLValueBase()) {<br>
-      // An array can be represented as an lvalue referring to the base.<br>
-      if (isa<llvm::ArrayType>(DestTy)) {<br>
-        assert(Offset->isNullValue() && "offset on array initializer");<br>
-        return ConstExprEmitter(*this).Visit(<br>
-          const_cast<Expr*>(LVBase.get<const Expr*>()),<br>
-          DestType);<br>
-      }<br>
-<br>
-      auto C = ConstExprEmitter(*this).EmitLValue(LVBase).getPointer();<br>
+namespace {<br>
+/// A struct which can be used to peephole certain kinds of finalization<br>
+/// that normally happen during l-value emission.<br>
+struct ConstantLValue {<br>
+  llvm::Constant *Value;<br>
+  bool HasOffsetApplied;<br>
+<br>
+  /*implicit*/ ConstantLValue(llvm::Constant *value,<br>
+                              bool hasOffsetApplied = false)<br>
+    : Value(value), HasOffsetApplied(false) {}<br>
<br>
-      // Apply offset if necessary.<br>
-      if (!Offset->isNullValue()) {<br>
-        unsigned AS = C->getType()->getPointerAddressSpace();<br>
-        llvm::Type *CharPtrTy = CGM.Int8Ty->getPointerTo(AS);<br>
-        llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(C, CharPtrTy);<br>
-        Casted =<br>
-          llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, Casted, Offset);<br>
-        C = llvm::ConstantExpr::getPointerCast(Casted, C->getType());<br>
-      }<br>
+  /*implicit*/ ConstantLValue(ConstantAddress address)<br>
+    : ConstantLValue(address.getPointer()) {}<br>
+};<br>
<br>
-      // Convert to the appropriate type; this could be an lvalue for<br>
-      // an integer.  FIXME: performAddrSpaceCast<br>
-      if (isa<llvm::PointerType>(DestTy))<br>
-        return llvm::ConstantExpr::getPointerCast(C, DestTy);<br>
-<br>
-      return llvm::ConstantExpr::getPtrToInt(C, DestTy);<br>
-    } else {<br>
-      auto C = Offset;<br>
-<br>
-      // Convert to the appropriate type; this could be an lvalue for<br>
-      // an integer.<br>
-      if (auto PT = dyn_cast<llvm::PointerType>(DestTy)) {<br>
-        if (Value.isNullPointer())<br>
-          return CGM.getNullPointer(PT, DestType);<br>
-        // Convert the integer to a pointer-sized integer before converting it<br>
-        // to a pointer.<br>
-        C = llvm::ConstantExpr::getIntegerCast(<br>
-            C, CGM.getDataLayout().getIntPtrType(DestTy),<br>
-            /*isSigned=*/false);<br>
-        return llvm::ConstantExpr::getIntToPtr(C, DestTy);<br>
-      }<br>
+/// A helper class for emitting constant l-values.<br>
+class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,<br>
+                                                      ConstantLValue> {<br>
+  CodeGenModule &CGM;<br>
+  ConstantEmitter &Emitter;<br>
+  const APValue &Value;<br>
+  QualType DestType;<br>
<br>
-      // If the types don't match this should only be a truncate.<br>
-      if (C->getType() != DestTy)<br>
-        return llvm::ConstantExpr::getTrunc(C, DestTy);<br>
+  // Befriend StmtVisitorBase so that we don't have to expose Visit*.<br>
+  friend StmtVisitorBase;<br>
<br>
+public:<br>
+  ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value,<br>
+                        QualType destType)<br>
+    : CGM(emitter.CGM), Emitter(emitter), Value(value), DestType(destType) {}<br>
+<br>
+  llvm::Constant *tryEmit();<br>
+<br>
+private:<br>
+  llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);<br>
+  ConstantLValue tryEmitBase(const APValue::LValueBase &base);<br>
+<br>
+  ConstantLValue VisitStmt(const Stmt *S) { return nullptr; }<br>
+  ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);<br>
+  ConstantLValue VisitStringLiteral(const StringLiteral *E);<br>
+  ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E);<br>
+  ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *E);<br>
+  ConstantLValue VisitPredefinedExpr(const PredefinedExpr *E);<br>
+  ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *E);<br>
+  ConstantLValue VisitCallExpr(const CallExpr *E);<br>
+  ConstantLValue VisitBlockExpr(const BlockExpr *E);<br>
+  ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *E);<br>
+  ConstantLValue VisitCXXUuidofExpr(const CXXUuidofExpr *E);<br>
+  ConstantLValue VisitMaterializeTemporaryExpr(<br>
+                                         const MaterializeTemporaryExpr *E);<br>
+<br>
+  bool hasNonZeroOffset() const {<br>
+    return !Value.getLValueOffset().isZero();<br>
+  }<br>
+<br>
+  /// Return the value offset.<br>
+  llvm::Constant *getOffset() {<br>
+    return llvm::ConstantInt::get(CGM.Int64Ty,<br>
+                                  Value.getLValueOffset().getQuantity());<br>
+  }<br>
+<br>
+  /// Apply the value offset to the given constant.<br>
+  llvm::Constant *applyOffset(llvm::Constant *C) {<br>
+    if (!hasNonZeroOffset())<br>
       return C;<br>
+<br>
+    llvm::Type *origPtrTy = C->getType();<br>
+    unsigned AS = origPtrTy->getPointerAddressSpace();<br>
+    llvm::Type *charPtrTy = CGM.Int8Ty->getPointerTo(AS);<br>
+    C = llvm::ConstantExpr::getBitCast(C, charPtrTy);<br>
+    C = llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, C, getOffset());<br>
+    C = llvm::ConstantExpr::getPointerCast(C, origPtrTy);<br>
+    return C;<br>
+  }<br>
+};<br>
+<br>
+}<br>
+<br>
+llvm::Constant *ConstantLValueEmitter::tryEmit() {<br>
+  const APValue::LValueBase &base = Value.getLValueBase();<br>
+<br>
+  // Certain special array initializers are represented in APValue<br>
+  // as l-values referring to the base expression which generates the<br>
+  // array.  This happens with e.g. string literals.  These should<br>
+  // probably just get their own representation kind in APValue.<br>
+  if (DestType->isArrayType()) {<br>
+    assert(!hasNonZeroOffset() && "offset on array initializer");<br>
+    auto expr = const_cast<Expr*>(base.get<const Expr*>());<br>
+    return ConstExprEmitter(Emitter).Visit(expr, DestType);<br>
+  }<br>
+<br>
+  // Otherwise, the destination type should be a pointer or reference<br>
+  // type, but it might also be a cast thereof.<br>
+  //<br>
+  // FIXME: the chain of casts required should be reflected in the APValue.<br>
+  // We need this in order to correctly handle things like a ptrtoint of a<br>
+  // non-zero null pointer and addrspace casts that aren't trivially<br>
+  // represented in LLVM IR.<br>
+  auto destTy = CGM.getTypes().ConvertTypeForMem(DestType);<br>
+  assert(isa<llvm::IntegerType>(destTy) || isa<llvm::PointerType>(destTy));<br>
+<br>
+  // If there's no base at all, this is a null or absolute pointer,<br>
+  // possibly cast back to an integer type.<br>
+  if (!base) {<br>
+    return tryEmitAbsolute(destTy);<br>
+  }<br>
+<br>
+  // Otherwise, try to emit the base.<br>
+  ConstantLValue result = tryEmitBase(base);<br>
+<br>
+  // If that failed, we're done.<br>
+  llvm::Constant *value = result.Value;<br>
+  if (!value) return nullptr;<br>
+<br>
+  // Apply the offset if necessary and not already done.<br>
+  if (!result.HasOffsetApplied) {<br>
+    value = applyOffset(value);<br>
+  }<br>
+<br>
+  // Convert to the appropriate type; this could be an lvalue for<br>
+  // an integer.  FIXME: performAddrSpaceCast<br>
+  if (isa<llvm::PointerType>(destTy))<br>
+    return llvm::ConstantExpr::getPointerCast(value, destTy);<br>
+<br>
+  return llvm::ConstantExpr::getPtrToInt(value, destTy);<br>
+}<br>
+<br>
+/// Try to emit an absolute l-value, such as a null pointer or an integer<br>
+/// bitcast to pointer type.<br>
+llvm::Constant *<br>
+ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {<br>
+  auto offset = getOffset();<br>
+<br>
+  // If we're producing a pointer, this is easy.<br>
+  if (auto destPtrTy = cast<llvm::PointerType>(destTy)) {<br>
+    if (Value.isNullPointer()) {<br>
+      // FIXME: integer offsets from non-zero null pointers.<br>
+      return CGM.getNullPointer(destPtrTy, DestType);<br>
+    }<br>
+<br>
+    // Convert the integer to a pointer-sized integer before converting it<br>
+    // to a pointer.<br>
+    // FIXME: signedness depends on the original integer type.<br>
+    auto intptrTy = CGM.getDataLayout().getIntPtrType(destPtrTy);<br>
+    llvm::Constant *C = offset;<br>
+    C = llvm::ConstantExpr::getIntegerCast(getOffset(), intptrTy,<br>
+                                           /*isSigned*/ false);<br>
+    C = llvm::ConstantExpr::getIntToPtr(C, destPtrTy);<br>
+    return C;<br>
+  }<br>
+<br>
+  // Otherwise, we're basically returning an integer constant.<br>
+<br>
+  // FIXME: this does the wrong thing with ptrtoint of a null pointer,<br>
+  // but since we don't know the original pointer type, there's not much<br>
+  // we can do about it.<br>
+<br>
+  auto C = getOffset();<br>
+  C = llvm::ConstantExpr::getIntegerCast(C, destTy, /*isSigned*/ false);<br>
+  return C;<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {<br>
+  // Handle values.<br>
+  if (const ValueDecl *D = base.dyn_cast<const ValueDecl*>()) {<br>
+    if (D->hasAttr<WeakRefAttr>())<br>
+      return CGM.GetWeakRefReference(D).getPointer();<br>
+<br>
+    if (auto FD = dyn_cast<FunctionDecl>(D))<br>
+      return CGM.GetAddrOfFunction(FD);<br>
+<br>
+    if (auto VD = dyn_cast<VarDecl>(D)) {<br>
+      // We can never refer to a variable with local storage.<br>
+      if (!VD->hasLocalStorage()) {<br>
+        if (VD->isFileVarDecl() || VD->hasExternalStorage())<br>
+          return CGM.GetAddrOfGlobalVar(VD);<br>
+<br>
+        if (VD->isLocalVarDecl()) {<br>
+          return CGM.getOrCreateStaticVarDecl(<br>
+              *VD, CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false));<br>
+        }<br>
+      }<br>
     }<br>
+<br>
+    return nullptr;<br>
+  }<br>
+<br>
+  // Otherwise, it must be an expression.<br>
+  return Visit(base.get<const Expr*>());<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {<br>
+  return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E);<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *E) {<br>
+  return CGM.GetAddrOfConstantStringFromLiteral(E);<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {<br>
+  return CGM.GetAddrOfConstantStringFromObjCEncode(E);<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *E) {<br>
+  auto C = CGM.getObjCRuntime().GenerateConstantString(E->getString());<br>
+  return C.getElementBitCast(CGM.getTypes().ConvertTypeForMem(E->getType()));<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *E) {<br>
+  if (auto CGF = Emitter.CGF) {<br>
+    LValue Res = CGF->EmitPredefinedLValue(E);<br>
+    return cast<ConstantAddress>(Res.getAddress());<br>
+  }<br>
+<br>
+  auto kind = E->getIdentType();<br>
+  if (kind == PredefinedExpr::PrettyFunction) {<br>
+    return CGM.GetAddrOfConstantCString("top level", ".tmp");<br>
   }<br>
+<br>
+  return CGM.GetAddrOfConstantCString("", ".tmp");<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *E) {<br>
+  assert(Emitter.CGF && "Invalid address of label expression outside function");<br>
+  llvm::Constant *Ptr = Emitter.CGF->GetAddrOfLabel(E->getLabel());<br>
+  Ptr = llvm::ConstantExpr::getBitCast(Ptr,<br>
+                                   CGM.getTypes().ConvertType(E->getType()));<br>
+  return Ptr;<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) {<br>
+  unsigned builtin = E->getBuiltinCallee();<br>
+  if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&<br>
+      builtin != Builtin::BI__builtin___NSStringMakeConstantString)<br>
+    return nullptr;<br>
+<br>
+  auto literal = cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts());<br>
+  if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {<br>
+    return CGM.getObjCRuntime().GenerateConstantString(literal);<br>
+  } else {<br>
+    // FIXME: need to deal with UCN conversion issues.<br>
+    return CGM.GetAddrOfConstantCFString(literal);<br>
+  }<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *E) {<br>
+  StringRef functionName;<br>
+  if (auto CGF = Emitter.CGF)<br>
+    functionName = CGF->CurFn->getName();<br>
+  else<br>
+    functionName = "global";<br>
+<br>
+  return CGM.GetAddrOfGlobalBlock(E, functionName);<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {<br>
+  QualType T;<br>
+  if (E->isTypeOperand())<br>
+    T = E->getTypeOperand(CGM.getContext());<br>
+  else<br>
+    T = E->getExprOperand()->getType();<br>
+  return CGM.GetAddrOfRTTIDescriptor(T);<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {<br>
+  return CGM.GetAddrOfUuidDescriptor(E);<br>
+}<br>
+<br>
+ConstantLValue<br>
+ConstantLValueEmitter::VisitMaterializeTemporaryExpr(<br>
+                                            const MaterializeTemporaryExpr *E) {<br>
+  assert(E->getStorageDuration() == SD_Static);<br>
+  SmallVector<const Expr *, 2> CommaLHSs;<br>
+  SmallVector<SubobjectAdjustment, 2> Adjustments;<br>
+  const Expr *Inner = E->GetTemporaryExpr()<br>
+      ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);<br>
+  return CGM.GetAddrOfGlobalTemporary(E, Inner);<br>
+}<br>
+<br>
+llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,<br>
+                                                QualType DestType) {<br>
+  switch (Value.getKind()) {<br>
+  case APValue::Uninitialized:<br>
+    llvm_unreachable("Constant expressions should be initialized.");<br>
+  case APValue::LValue:<br>
+    return ConstantLValueEmitter(*this, Value, DestType).tryEmit();<br>
   case APValue::Int:<br>
     return llvm::ConstantInt::get(CGM.getLLVMContext(), Value.getInt());<br>
   case APValue::ComplexInt: {<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>