[cfe-commits] r46388 - /cfe/trunk/CodeGen/CGExprConstant.cpp

Anders Carlsson andersca at mac.com
Fri Jan 25 18:08:50 PST 2008


Author: andersca
Date: Fri Jan 25 20:08:50 2008
New Revision: 46388

URL: http://llvm.org/viewvc/llvm-project?rev=46388&view=rev
Log:
Add CodeGen for AddrOf in constant initializers. Original patch by Eli Friedman.

Modified:
    cfe/trunk/CodeGen/CGExprConstant.cpp

Modified: cfe/trunk/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprConstant.cpp?rev=46388&r1=46387&r2=46388&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/CodeGen/CGExprConstant.cpp Fri Jan 25 20:08:50 2008
@@ -237,6 +237,9 @@
   llvm::Constant *VisitUnaryAlignOf(const UnaryOperator *E) {
     return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
   }
+  llvm::Constant *VisitUnaryAddrOf(const UnaryOperator *E) {
+    return EmitLValue(E->getSubExpr());
+  }
   
   // Utility methods
   const llvm::Type *ConvertType(QualType T) {
@@ -351,7 +354,91 @@
     return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
   }
   
-  };
+  llvm::Constant *EmitLValue(const Expr *E) {
+    switch (E->getStmtClass()) {
+    default: {
+      CGM.WarnUnsupported(E, "constant l-value expression");
+      llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
+      return llvm::UndefValue::get(Ty);
+    }
+    case Expr::ParenExprClass:
+      // Elide parenthesis
+      return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
+    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<CompoundLiteralExpr>(E);
+      llvm::Constant* C = CGM.EmitGlobalInit(CLE->getInitializer());
+      C =new llvm::GlobalVariable(C->getType(), E->getType().isConstQualified(), 
+                                   llvm::GlobalValue::InternalLinkage,
+                                   C, ".compoundliteral", &CGM.getModule());
+      return C;
+    }      
+    case Expr::DeclRefExprClass: {
+      const ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
+        return CGM.GetAddrOfFunctionDecl(FD, false);
+      if (const FileVarDecl* FVD = dyn_cast<FileVarDecl>(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?!
+      assert(0 && "Unimplemented Decl type");
+      return 0;
+    }
+    case Expr::MemberExprClass: {
+      const MemberExpr* ME = cast<MemberExpr>(E);
+      unsigned FieldNumber = CGM.getTypes().getLLVMFieldNo(ME->getMemberDecl());
+      llvm::Constant *Base = EmitLValue(ME->getBase());
+      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<ArraySubscriptExpr>(E);
+      llvm::Constant *Base = EmitLValue(ASExpr->getBase());
+      llvm::Constant *Index = EmitLValue(ASExpr->getIdx());
+      assert(!ASExpr->getBase()->getType()->isVectorType() &&
+             "Taking the address of a vector component is illegal!");
+      return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
+    }
+    case Expr::StringLiteralClass: {
+      const StringLiteral *String = cast<StringLiteral>(E);
+      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<UnaryOperator>(E);
+    switch (Exp->getOpcode()) {
+    default: assert(0 && "Unsupported unary operator.");
+    case UnaryOperator::Extension:
+      // Extension is just a wrapper for expressions
+      return EmitLValue(Exp->getSubExpr());
+    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 = EmitLValue(Exp->getSubExpr());
+      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 Visit(Exp->getSubExpr());
+    }
+  }
+  } 
+}
+
+};
+  
 }  // end anonymous namespace.
 
 





More information about the cfe-commits mailing list