aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AST/StmtPrinter.cpp11
-rw-r--r--CodeGen/CGExpr.cpp48
-rw-r--r--CodeGen/CodeGenFunction.h8
3 files changed, 63 insertions, 4 deletions
diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp
index 08dec3c269..948b20fd35 100644
--- a/AST/StmtPrinter.cpp
+++ b/AST/StmtPrinter.cpp
@@ -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) {
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp
index ff55e96086..fc59ec076b 100644
--- a/CodeGen/CGExpr.cpp
+++ b/CodeGen/CGExpr.cpp
@@ -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);
+}
diff --git a/CodeGen/CodeGenFunction.h b/CodeGen/CodeGenFunction.h
index 268a70276a..7a07f252bb 100644
--- a/CodeGen/CodeGenFunction.h
+++ b/CodeGen/CodeGenFunction.h
@@ -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