// ConstExprEmitter
//===----------------------------------------------------------------------===//
-static ConstantAddress tryEmitGlobalCompoundLiteral(CodeGenModule &CGM,
- CodeGenFunction *CGF,
- const CompoundLiteralExpr *E) {
+static ConstantAddress
+tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
+ const CompoundLiteralExpr *E) {
+ CodeGenModule &CGM = emitter.CGM;
CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
if (llvm::GlobalVariable *Addr =
CGM.getAddrOfConstantCompoundLiteralIfEmitted(E))
return ConstantAddress(Addr, Addr->getValueType(), Align);
LangAS addressSpace = E->getType().getAddressSpace();
-
- ConstantEmitter emitter(CGM, CGF);
llvm::Constant *C = emitter.tryEmitForInitializer(E->getInitializer(),
addressSpace, E->getType());
if (!C) {
ConstantLValue
ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
- return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E);
+ ConstantEmitter CompoundLiteralEmitter(CGM, Emitter.CGF);
+ CompoundLiteralEmitter.setInConstantContext(Emitter.isInConstantContext());
+ return tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter, E);
}
ConstantLValue
ConstantAddress
CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
assert(E->isFileScope() && "not a file-scope compound literal expr");
- return tryEmitGlobalCompoundLiteral(*this, nullptr, E);
+ ConstantEmitter emitter(*this);
+ return tryEmitGlobalCompoundLiteral(emitter, E);
}
llvm::Constant *
return Abstract;
}
+ bool isInConstantContext() const { return InConstantContext; }
+ void setInConstantContext(bool var) { InConstantContext = var; }
+
/// Try to emit the initiaizer of the given declaration as an abstract
/// constant. If this succeeds, the emission must be finalized.
llvm::Constant *tryEmitForInitializer(const VarDecl &D);
-// RUN: %clang_cc1 -no-opaque-pointers -triple i386-pc-linux-gnu -ffreestanding -Wno-pointer-to-int-cast -Wno-int-conversion -emit-llvm -o - %s | FileCheck %s
+// setting strict FP behaviour in the run line below tests that the compiler
+// does the right thing for global compound literals (compoundliteral test)
+// RUN: %clang_cc1 -no-opaque-pointers -triple i386-pc-linux-gnu -ffreestanding -Wno-pointer-to-int-cast -Wno-int-conversion -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s
#include <stdint.h>
#pragma pack()
// CHECK: @g31.a = internal global %struct.anon.2 { i16 23122, i32 -12312731, i16 -312 }, align 4
}
+
+// Clang should evaluate this in constant context, so floating point mode should
+// have no effect.
+// CHECK: @.compoundliteral = internal global [1 x float] [float 0x3FB99999A0000000], align 4
+struct { const float *floats; } compoundliteral = {
+ (float[1]) { 0.1, },
+};