diff options
-rw-r--r-- | AST/StmtPrinter.cpp | 11 | ||||
-rw-r--r-- | CodeGen/CGExpr.cpp | 48 | ||||
-rw-r--r-- | CodeGen/CodeGenFunction.h | 8 |
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 |