#include "clang/Lex/IdentifierTable.h"
#include "llvm/Support/Compiler.h"
#include <iostream>
+#include <iomanip>
using namespace clang;
//===----------------------------------------------------------------------===//
}
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) {
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:
return EmitCallExpr(cast<CallExpr>(E));
case Expr::BinaryOperatorClass:
return EmitBinaryOperator(cast<BinaryOperator>(E));
+
+ case Expr::ConditionalOperatorClass:
+ return EmitConditionalOperator(cast<ConditionalOperator>(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
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);
+}
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;
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);
RValue EmitBinaryAssign(const BinaryOperator *E);
RValue EmitBinaryComma(const BinaryOperator *E);
+
+ // Conditional Operator.
+ RValue EmitConditionalOperator(const ConditionalOperator *E);
};
} // end namespace CodeGen
} // end namespace clang