]> granicus.if.org Git - clang/commitdiff
"Codegen for Character Literals and Conditional Operator
authorChris Lattner <sabre@nondot.org>
Fri, 13 Jul 2007 05:18:11 +0000 (05:18 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 13 Jul 2007 05:18:11 +0000 (05:18 +0000)
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

AST/StmtPrinter.cpp
CodeGen/CGExpr.cpp
CodeGen/CodeGenFunction.h

index 08dec3c269262b039fc9eed2d44667a6cdf2804a..948b20fd35aa08ab7ba357d6c72692aabc07ab8a 100644 (file)
@@ -17,6 +17,7 @@
 #include "clang/Lex/IdentifierTable.h"
 #include "llvm/Support/Compiler.h"
 #include <iostream>
+#include <iomanip>
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -291,8 +292,14 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
 }
 
 void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
-  // FIXME: print value.
-  OS << "x";
+  unsigned value = Node->getValue();
+  if (isprint(value)) {
+    OS << "'" << (char)value << "'";
+  } else {
+    // FIXME something to indicate this is a character literal?
+    OS << std::hex << std::setiosflags(std::ios_base::showbase) << value
+       << std::dec << std::resetiosflags(std::ios_base::showbase);
+  }
 }
 
 void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
index ff55e960869f2a465cfa6e2e75691cea37facafa..fc59ec076b038484d29daffdbd22e26e25a143ed 100644 (file)
@@ -464,6 +464,8 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) {
     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 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) {
     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 @@ RValue CodeGenFunction::EmitFloatingLiteral(const FloatingLiteral *E) {
   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 @@ RValue CodeGenFunction::EmitBinaryComma(const BinaryOperator *E) {
   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);
+}
index 268a70276a7dbbbd7cc2493edf262a6871b67cff..7a07f252bb05f8f7626eaa9ffda01f0a81afb390 100644 (file)
@@ -46,12 +46,14 @@ namespace clang {
   class StringLiteral;
   class IntegerLiteral;
   class FloatingLiteral;
+  class CharacterLiteral;
   class CastExpr;
   class CallExpr;
   class UnaryOperator;
   class BinaryOperator;
   class CompoundAssignOperator;
   class ArraySubscriptExpr;
+  class ConditionalOperator;
   
   class BlockVarDecl;
   class EnumConstantDecl;
@@ -309,7 +311,8 @@ public:
   RValue EmitExpr(const Expr *E);
   RValue EmitIntegerLiteral(const IntegerLiteral *E);
   RValue EmitFloatingLiteral(const FloatingLiteral *E);
-  
+  RValue EmitCharacterLiteral(const CharacterLiteral *E);
+   
   RValue EmitCastExpr(const CastExpr *E);
   RValue EmitCallExpr(const CallExpr *E);
   RValue EmitArraySubscriptExprRV(const ArraySubscriptExpr *E);
@@ -351,6 +354,9 @@ public:
   
   RValue EmitBinaryAssign(const BinaryOperator *E);
   RValue EmitBinaryComma(const BinaryOperator *E);
+  
+  // Conditional Operator.
+  RValue EmitConditionalOperator(const ConditionalOperator *E);
 };
 }  // end namespace CodeGen
 }  // end namespace clang