<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>