[cfe-commits] r64780 - in /cfe/trunk: lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/staticinit.c
Daniel Dunbar
daniel at zuster.org
Tue Feb 17 10:43:33 PST 2009
Author: ddunbar
Date: Tue Feb 17 12:43:32 2009
New Revision: 64780
URL: http://llvm.org/viewvc/llvm-project?rev=64780&view=rev
Log:
Change EmitConstantExpr to allow failure.
IRgen no longer relies on isConstantInitializer, instead we just try
to emit the constant. If that fails then in C we emit an error
unsupported (this occurs when Sema accepted something that it doesn't
know how to fold, and IRgen doesn't know how to emit) and in C++ we
emit a guarded initializer.
This ends up handling a few more cases, because IRgen was actually
able to emit some of the constants Sema accepts but can't Evaluate().
For example, PR3398.
Modified:
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/test/CodeGen/staticinit.c
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=64780&r1=64779&r2=64780&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Feb 17 12:43:32 2009
@@ -88,12 +88,17 @@
if ((D.getInit() == 0) || NoInit) {
Init = llvm::Constant::getNullValue(LTy);
} else {
- if (D.getInit()->isConstantInitializer(getContext()))
- Init = CGM.EmitConstantExpr(D.getInit(), this);
- else {
- assert(getContext().getLangOptions().CPlusPlus &&
- "only C++ supports non-constant static initializers!");
- return GenerateStaticCXXBlockVarDecl(D);
+ Init = CGM.EmitConstantExpr(D.getInit(), this);
+
+ // If constant emission failed, then this should be a C++ static
+ // initializer.
+ if (!Init) {
+ if (!getContext().getLangOptions().CPlusPlus) {
+ CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
+ Init = llvm::Constant::getNullValue(LTy);
+ } else {
+ return GenerateStaticCXXBlockVarDecl(D);
+ }
}
}
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=64780&r1=64779&r2=64780&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Feb 17 12:43:32 2009
@@ -61,7 +61,6 @@
}
llvm::Constant *C = Visit(E->getSubExpr());
-
return EmitConversion(C, E->getSubExpr()->getType(), E->getType());
}
@@ -90,6 +89,8 @@
bool RewriteType = false;
for (; i < NumInitableElts; ++i) {
llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(i), CGF);
+ if (!C)
+ return 0;
RewriteType |= (C->getType() != ElemTy);
Elts.push_back(C);
}
@@ -114,6 +115,9 @@
FieldDecl* Field, Expr* E) {
// Calculate the value to insert
llvm::Constant *C = CGM.EmitConstantExpr(E, CGF);
+ if (!C)
+ return;
+
llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(C);
if (!CI) {
CGM.ErrorUnsupported(E, "bitfield initialization");
@@ -198,6 +202,7 @@
} else {
unsigned FieldNo = CGM.getTypes().getLLVMFieldNo(*Field);
llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(EltNo), CGF);
+ if (!C) return 0;
RewriteType |= (C->getType() != Elts[FieldNo]->getType());
Elts[FieldNo] = C;
}
@@ -217,6 +222,9 @@
}
llvm::Constant *EmitUnion(llvm::Constant *C, const llvm::Type *Ty) {
+ if (!C)
+ return 0;
+
// Build a struct with the union sub-element as the first member,
// and padded to the appropriate size
std::vector<llvm::Constant*> Elts;
@@ -289,6 +297,8 @@
unsigned i = 0;
for (; i < NumInitableElts; ++i) {
llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(i), CGF);
+ if (!C)
+ return 0;
Elts.push_back(C);
}
@@ -402,6 +412,9 @@
llvm::Constant *EmitConversion(llvm::Constant *Src, QualType SrcType,
QualType DstType) {
+ if (!Src)
+ return 0;
+
SrcType = CGM.getContext().getCanonicalType(SrcType);
DstType = CGM.getContext().getCanonicalType(DstType);
if (SrcType == DstType) return Src;
@@ -488,9 +501,12 @@
// to be the only use of the variable, so we just generate it here.
CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
llvm::Constant* C = Visit(CLE->getInitializer());
- C = new llvm::GlobalVariable(C->getType(),E->getType().isConstQualified(),
- llvm::GlobalValue::InternalLinkage,
- C, ".compoundliteral", &CGM.getModule());
+ // FIXME: "Leaked" on failure.
+ if (C)
+ C = new llvm::GlobalVariable(C->getType(),
+ E->getType().isConstQualified(),
+ llvm::GlobalValue::InternalLinkage,
+ C, ".compoundliteral", &CGM.getModule());
return C;
}
case Expr::DeclRefExprClass:
@@ -515,6 +531,8 @@
Base = Visit(ME->getBase());
else
Base = EmitLValue(ME->getBase());
+ if (!Base)
+ return 0;
FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
// FIXME: Handle other kinds of member expressions.
@@ -528,10 +546,13 @@
}
case Expr::ArraySubscriptExprClass: {
ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(E);
- llvm::Constant *Base = Visit(ASExpr->getBase());
- llvm::Constant *Index = Visit(ASExpr->getIdx());
assert(!ASExpr->getBase()->getType()->isVectorType() &&
"Taking the address of a vector component is illegal!");
+
+ llvm::Constant *Base = Visit(ASExpr->getBase());
+ llvm::Constant *Index = Visit(ASExpr->getIdx());
+ if (!Base || !Index)
+ return 0;
return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
}
case Expr::StringLiteralClass:
@@ -594,9 +615,8 @@
return CGM.GetAddrOfConstantCFString(S);
}
}
- CGM.ErrorUnsupported(E, "constant l-value expression");
- llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
- return llvm::UndefValue::get(Ty);
+
+ return 0;
}
};
@@ -604,8 +624,6 @@
llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
CodeGenFunction *CGF) {
- QualType type = Context.getCanonicalType(E->getType());
-
Expr::EvalResult Result;
if (E->Evaluate(Result, Context)) {
@@ -613,8 +631,8 @@
"Constant expr should not have any side effects!");
switch (Result.Val.getKind()) {
case APValue::Uninitialized:
- assert(0 && "Constant expressions should be uninitialized.");
- return llvm::UndefValue::get(getTypes().ConvertType(type));
+ assert(0 && "Constant expressions should be initialized.");
+ return 0;
case APValue::LValue: {
llvm::Constant *Offset =
llvm::ConstantInt::get(llvm::Type::Int64Ty,
@@ -637,7 +655,7 @@
}
return llvm::ConstantExpr::getIntToPtr(Offset,
- getTypes().ConvertType(type));
+ getTypes().ConvertType(E->getType()));
}
case APValue::Int: {
llvm::Constant *C = llvm::ConstantInt::get(Result.Val.getInt());
@@ -683,7 +701,7 @@
}
llvm::Constant* C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
- if (C->getType() == llvm::Type::Int1Ty) {
+ if (C && C->getType() == llvm::Type::Int1Ty) {
const llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
C = llvm::ConstantExpr::getZExt(C, BoolTy);
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=64780&r1=64779&r2=64780&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Feb 17 12:43:32 2009
@@ -247,7 +247,12 @@
const std::string &Name);
void UpdateCompletedType(const TagDecl *D);
+
+ /// EmitConstantExpr - Try to emit the given expression as a
+ /// constant; returns 0 if the expression cannot be emitted as a
+ /// constant.
llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
+
llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
const AnnotateAttr *AA, unsigned LineNo);
Modified: cfe/trunk/test/CodeGen/staticinit.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/staticinit.c?rev=64780&r1=64779&r2=64780&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/staticinit.c (original)
+++ cfe/trunk/test/CodeGen/staticinit.c Tue Feb 17 12:43:32 2009
@@ -1,4 +1,5 @@
-// RUN: clang -emit-llvm < %s | grep "g.b = internal global i8. getelementptr"
+// RUN: clang -arch i386 -emit-llvm -o %t %s &&
+// RUN: grep "g.b = internal global i8. getelementptr" %t &&
struct AStruct {
int i;
@@ -24,3 +25,7 @@
void foo(void) {
static struct s var = {((void*)&((char*)0)[0])};
}
+
+// RUN: grep "f1.l0 = internal global i32 ptrtoint (i32 ()\* @f1 to i32)" %t
+int f1(void) { static int l0 = (unsigned) f1; }
+
More information about the cfe-commits
mailing list