"Codegen for Character Literals and Conditional Operator

Both in one patch, and the test case that Chris didn't commit last
time is in there too...

I'll split the patch up if somebody wants it split."

Patch by Keith Bauer.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39796 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp
index ff55e96..fc59ec0 100644
--- a/CodeGen/CGExpr.cpp
+++ b/CodeGen/CGExpr.cpp
@@ -464,6 +464,8 @@
     return EmitIntegerLiteral(cast<IntegerLiteral>(E)); 
   case Expr::FloatingLiteralClass:
     return EmitFloatingLiteral(cast<FloatingLiteral>(E));
+  case Expr::CharacterLiteralClass:
+    return EmitCharacterLiteral(cast<CharacterLiteral>(E));
     
   // Operators.  
   case Expr::ParenExprClass:
@@ -476,6 +478,9 @@
     return EmitCallExpr(cast<CallExpr>(E));
   case Expr::BinaryOperatorClass:
     return EmitBinaryOperator(cast<BinaryOperator>(E));
+  
+  case Expr::ConditionalOperatorClass:
+    return EmitConditionalOperator(cast<ConditionalOperator>(E));
   }
   
 }
@@ -487,7 +492,10 @@
   return RValue::get(llvm::ConstantFP::get(ConvertType(E->getType()),
                                            E->getValue()));
 }
-
+RValue CodeGenFunction::EmitCharacterLiteral(const CharacterLiteral *E) {
+  return RValue::get(llvm::ConstantInt::get(ConvertType(E->getType()),
+                                            E->getValue()));
+}
 
 RValue CodeGenFunction::EmitArraySubscriptExprRV(const ArraySubscriptExpr *E) {
   // Emit subscript expressions in rvalue context's.  For most cases, this just
@@ -1322,3 +1330,41 @@
   EmitExpr(E->getLHS());
   return EmitExpr(E->getRHS());
 }
+
+RValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator *E) {
+  llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
+  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
+  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
+  
+  llvm::Value *Cond = EvaluateExprAsBool(E->getCond());
+  Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
+  
+  // FIXME: LHS & RHS need the "usual arithmetic conversions" but
+  // that's not possible with the current design.
+  
+  EmitBlock(LHSBlock);
+  QualType LHSTy;
+  llvm::Value *LHSValue = E->getLHS() ? // GNU extension
+      EmitExprWithUsualUnaryConversions(E->getLHS(), LHSTy).getVal() :
+      Cond;
+  Builder.CreateBr(ContBlock);
+  LHSBlock = Builder.GetInsertBlock();
+  
+  EmitBlock(RHSBlock);
+  QualType RHSTy;
+  llvm::Value *RHSValue =
+    EmitExprWithUsualUnaryConversions(E->getRHS(), RHSTy).getVal();
+  Builder.CreateBr(ContBlock);
+  RHSBlock = Builder.GetInsertBlock();
+  
+  const llvm::Type *LHSType = LHSValue->getType();
+  assert(LHSType == RHSValue->getType() && "?: LHS & RHS must have same type");
+  
+  EmitBlock(ContBlock);
+  llvm::PHINode *PN = Builder.CreatePHI(LHSType, "cond");
+  PN->reserveOperandSpace(2);
+  PN->addIncoming(LHSValue, LHSBlock);
+  PN->addIncoming(RHSValue, RHSBlock);
+  
+  return RValue::get(PN);
+}