Skip to content

Commit 01a72ff

Browse files
committed
Implement codegen for the following static var init.
void g() { static char a[10]; static char *b = a; } Now we can compile wget! llvm-svn: 47627
1 parent e9f30d3 commit 01a72ff

File tree

6 files changed

+27
-9
lines changed

6 files changed

+27
-9
lines changed

clang/CodeGen/CGDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) {
7777
if (D.getInit() == 0) {
7878
Init = llvm::Constant::getNullValue(LTy);
7979
} else {
80-
Init = CGM.EmitGlobalInit(D.getInit());
80+
Init = CGM.EmitConstantExpr(D.getInit(), this);
8181
}
8282

8383
assert(Init && "Unable to create initialiser for static decl");

clang/CodeGen/CGExprConstant.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ namespace {
2525
class VISIBILITY_HIDDEN ConstExprEmitter :
2626
public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
2727
CodeGenModule &CGM;
28+
CodeGenFunction *CGF;
2829
public:
29-
ConstExprEmitter(CodeGenModule &cgm)
30-
: CGM(cgm) {
30+
ConstExprEmitter(CodeGenModule &cgm, CodeGenFunction *cgf)
31+
: CGM(cgm), CGF(cgf) {
3132
}
3233

3334
//===--------------------------------------------------------------------===//
@@ -534,8 +535,10 @@ class VISIBILITY_HIDDEN ConstExprEmitter :
534535
return CGM.GetAddrOfFunctionDecl(FD, false);
535536
if (const FileVarDecl* VD = dyn_cast<FileVarDecl>(Decl))
536537
return CGM.GetAddrOfGlobalVar(VD, false);
537-
// We can end up here with static block-scope variables (and others?)
538-
// FIXME: How do we implement block-scope variables?!
538+
if (const BlockVarDecl* BVD = dyn_cast<BlockVarDecl>(Decl)) {
539+
assert(CGF && "Can't access static local vars without CGF");
540+
return CGF->GetAddrOfStaticLocalVar(BVD);
541+
}
539542
break;
540543
}
541544
case Expr::MemberExprClass: {
@@ -604,7 +607,8 @@ class VISIBILITY_HIDDEN ConstExprEmitter :
604607
} // end anonymous namespace.
605608

606609

607-
llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E)
610+
llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
611+
CodeGenFunction *CGF)
608612
{
609613
QualType type = E->getType().getCanonicalType();
610614

@@ -616,5 +620,5 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E)
616620
}
617621
}
618622

619-
return ConstExprEmitter(*this).Visit(const_cast<Expr*>(E));
623+
return ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
620624
}

clang/CodeGen/CodeGenFunction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
4040
return BB = new llvm::BasicBlock(S->getName());
4141
}
4242

43+
llvm::Constant *
44+
CodeGenFunction::GetAddrOfStaticLocalVar(const BlockVarDecl *BVD) {
45+
return cast<llvm::Constant>(LocalDeclMap[BVD]);
46+
}
4347

4448
const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
4549
return CGM.getTypes().ConvertType(T);

clang/CodeGen/CodeGenFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,9 @@ class CodeGenFunction {
335335

336336
/// getCGRecordLayout - Return record layout info.
337337
const CGRecordLayout *getCGRecordLayout(CodeGenTypes &CGT, QualType RTy);
338+
339+
/// GetAddrOfStaticLocalVar - Return the address of a static local variable.
340+
llvm::Constant *GetAddrOfStaticLocalVar(const BlockVarDecl *BVD);
338341
//===--------------------------------------------------------------------===//
339342
// Declaration Emission
340343
//===--------------------------------------------------------------------===//

clang/CodeGen/CodeGenModule.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ namespace clang {
4141

4242
namespace CodeGen {
4343

44+
class CodeGenFunction;
45+
4446
/// CodeGenModule - This class organizes the cross-module state that is used
4547
/// while generating LLVM code.
4648
class CodeGenModule {
@@ -95,7 +97,7 @@ class CodeGenModule {
9597
void EmitGlobalVarDeclarator(const FileVarDecl *D);
9698
void UpdateCompletedType(const TagDecl *D);
9799
llvm::Constant *EmitGlobalInit(const Expr *E);
98-
llvm::Constant *EmitConstantExpr(const Expr *E);
100+
llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
99101

100102
/// WarnUnsupported - Print out a warning that codegen doesn't support the
101103
/// specified stmt yet.

clang/test/CodeGen/staticinit.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: clang -emit-llvm %s
1+
// RUN: clang -emit-llvm < %s | grep "g.b = internal global i8. getelementptr"
22

33
struct AStruct {
44
int i;
@@ -13,3 +13,8 @@ void f() {
1313
static char* strs[] = { "one", "two", "three", "four" };
1414
static struct AStruct myStruct = { 1, "two", 3.0 };
1515
}
16+
17+
void g() {
18+
static char a[10];
19+
static char *b = a;
20+
}

0 commit comments

Comments
 (0)