Index: CodeGen/CodeGenModule.cpp =================================================================== --- CodeGen/CodeGenModule.cpp (revision 46353) +++ CodeGen/CodeGenModule.cpp (working copy) @@ -356,6 +387,97 @@ return llvm::ConstantArray::get(AType, Elts); } +/// GenerateStaticAddress - Recursively builds the address of the +/// given expression. +static llvm::Constant *GenerateStaticAddress(const Expr *Expression, + CodeGenModule &CGM) { + CodeGenTypes& Types = CGM.getTypes(); + switch (Expression->getStmtClass()) { + default: assert(0 && "We shouldn't get here"); + case Expr::ParenExprClass: + // Elide parenthesis + return GenerateStaticAddress(cast(Expression)->getSubExpr(), CGM); + case Expr::CompoundLiteralExprClass: { + // Note that due to the nature of compound literals, this is guaranteed + // to be the only use of the variable, so we just generate it here. + const CompoundLiteralExpr *CLE = cast(Expression); + llvm::Constant* C = CGM.EmitGlobalInit(CLE->getInitializer()); + C = new llvm::GlobalVariable(C->getType(), Expression->getType().isConstQualified(), + llvm::GlobalValue::InternalLinkage, + C, ".compoundliteral", &CGM.getModule()); + return C; + } + case Expr::DeclRefExprClass: { + const ValueDecl *Decl = cast(Expression)->getDecl(); + if (const FunctionDecl *FD = dyn_cast(Decl)) + return CGM.GetAddrOfFunctionDecl(FD, false); + if (const FileVarDecl* FVD = dyn_cast(Decl)) + return CGM.GetAddrOfGlobalVar(FVD, false); + // We can end up here with static block-scope variables (and others?) + // FIXME: How do we implement block-scope variables?! + break; // UNIMPLEMENTED + } + case Expr::MemberExprClass: { + const MemberExpr* MemExpr = cast(Expression); + unsigned fieldNumber = Types.getLLVMFieldNo(MemExpr->getMemberDecl()); + llvm::Constant *Base = GenerateStaticAddress(MemExpr->getBase(), CGM); + llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); + llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, + fieldNumber); + llvm::Value *Ops[] = {Zero, Idx}; + return llvm::ConstantExpr::getGetElementPtr(Base, Ops, 2); + } + case Expr::ArraySubscriptExprClass: { + const ArraySubscriptExpr* ASExpr = cast(Expression); + llvm::Constant *Base = GenerateConstantExpr(ASExpr->getBase(), CGM); + llvm::Constant *Index = GenerateConstantExpr(ASExpr->getIdx(), CGM); + assert(!ASExpr->getBase()->getType()->isVectorType() && + "Taking the address of a vector component is illegal!"); + return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1); + } + case Expr::PreDefinedExprClass: { + break; // UNIMPLEMENTED + } + case Expr::StringLiteralClass: { + const StringLiteral *String = cast(Expression); + assert(!String->isWide() && "Cannot codegen wide strings yet"); + const char *StrData = String->getStrData(); + unsigned Len = String->getByteLength(); + + return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len)); + } + case Expr::UnaryOperatorClass: { + const UnaryOperator *Exp = cast(Expression); + switch (Exp->getOpcode()) { + default: assert(0 && "We shouldn't get here"); + case UnaryOperator::Extension: + // Extension is just a wrapper for expressions + return GenerateStaticAddress(Exp->getSubExpr(), CGM); + case UnaryOperator::Real: + case UnaryOperator::Imag: { + // The address of __real or __imag is just a GEP off the address + // of the internal expression + llvm::Constant* C = GenerateStaticAddress(Exp->getSubExpr(), CGM); + llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); + llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, + Exp->getOpcode() == UnaryOperator::Imag); + llvm::Value *Ops[] = {Zero, Idx}; + return llvm::ConstantExpr::getGetElementPtr(C, Ops, 2); + } + case UnaryOperator::Deref: + // The address of a deref is just the value of the expression + return GenerateConstantExpr(Exp->getSubExpr(), CGM); + } + break; + } + } + CGM.WarnUnsupported(Expression, "initializer"); + return llvm::UndefValue::get( + llvm::PointerType::getUnqual( + Types.ConvertType(Expression->getType()))); +} + + /// GenerateConstantExpr - Recursively builds a constant initialiser for the /// given expression. static llvm::Constant *GenerateConstantExpr(const Expr *Expression, @@ -446,6 +565,9 @@ CGM); case Stmt::UnaryOperatorClass: { const UnaryOperator *Op = cast(Expression); + if (Op->getOpcode() == UnaryOperator::AddrOf) { + return GenerateStaticAddress(Op->getSubExpr(), CGM); + } llvm::Constant *SubExpr = GenerateConstantExpr(Op->getSubExpr(), CGM); // FIXME: These aren't right for complex. switch (Op->getOpcode()) {