blob: 803d89ee5423f530067aa6eca6aaac91da5362cb [file] [log] [blame]
Anders Carlsson022012e2007-08-20 18:05:56 +00001//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Anders Carlsson and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Builtin calls as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
Chris Lattnerbef20ac2007-08-31 04:31:45 +000016#include "clang/AST/ASTContext.h"
Anders Carlsson022012e2007-08-20 18:05:56 +000017#include "clang/AST/Builtins.h"
18#include "clang/AST/Expr.h"
Chris Lattner6de93ff2007-08-26 04:17:05 +000019#include "llvm/Constants.h"
Chris Lattnerc5e940f2007-08-31 04:44:06 +000020#include "llvm/Function.h"
Anders Carlsson793680e2007-10-12 23:56:29 +000021#include "llvm/Intrinsics.h"
22
Anders Carlsson022012e2007-08-20 18:05:56 +000023using namespace clang;
24using namespace CodeGen;
25
Chris Lattner6de93ff2007-08-26 04:17:05 +000026RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
27 switch (BuiltinID) {
28 default:
Chris Lattnerc5e940f2007-08-31 04:44:06 +000029 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
30 return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), E);
31
Chris Lattner6de93ff2007-08-26 04:17:05 +000032 fprintf(stderr, "Unimplemented builtin!!\n");
Chris Lattner419ea7e2007-09-13 01:17:29 +000033 E->dump(getContext().SourceMgr);
Chris Lattner6de93ff2007-08-26 04:17:05 +000034
35 // Unknown builtin, for now just dump it out and return undef.
36 if (hasAggregateLLVMType(E->getType()))
37 return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
38 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
39
40 case Builtin::BI__builtin___CFStringMakeConstantString: {
41 const Expr *Arg = E->getArg(0);
42
Anders Carlssond6a275f2007-11-01 00:39:26 +000043 while (1) {
44 if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
45 Arg = PE->getSubExpr();
46 else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
47 Arg = CE->getSubExpr();
48 else
49 break;
50 }
Chris Lattner6de93ff2007-08-26 04:17:05 +000051
52 const StringLiteral *Literal = cast<StringLiteral>(Arg);
53 std::string S(Literal->getStrData(), Literal->getByteLength());
54
55 return RValue::get(CGM.GetAddrOfConstantCFString(S));
Anders Carlsson793680e2007-10-12 23:56:29 +000056 }
57 case Builtin::BI__builtin_va_start:
58 case Builtin::BI__builtin_va_end: {
59 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
60 const llvm::Type *DestType = llvm::PointerType::get(llvm::Type::Int8Ty);
61 if (ArgValue->getType() != DestType)
62 ArgValue = Builder.CreateBitCast(ArgValue, DestType,
63 ArgValue->getNameStart());
64
65 llvm::Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_start) ?
66 llvm::Intrinsic::vastart : llvm::Intrinsic::vaend;
67 llvm::Value *F = llvm::Intrinsic::getDeclaration(&CGM.getModule(), inst);
68 llvm::Value *V = Builder.CreateCall(F, ArgValue);
69
70 return RValue::get(V);
71 }
Anders Carlsson89799cf2007-10-29 02:59:40 +000072 case Builtin::BI__builtin_classify_type: {
73 llvm::APSInt Result(32);
74
75 if (!E->isBuiltinClassifyType(Result))
76 assert(0 && "Expr not __builtin_classify_type!");
77
78 return RValue::get(llvm::ConstantInt::get(Result));
Anders Carlsson022012e2007-08-20 18:05:56 +000079 }
Anders Carlssond6a275f2007-11-01 00:39:26 +000080 case Builtin::BI__builtin_constant_p: {
81 llvm::APSInt Result(32);
82
83 // FIXME: Analyze the parameter and check if it is a constant.
84 Result = 0;
85
86 return RValue::get(llvm::ConstantInt::get(Result));
87 }
Anders Carlssonc2251dc2007-11-20 19:05:17 +000088 case Builtin::BI__builtin_abs: {
89 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
90
91 llvm::BinaryOperator *NegOp =
92 Builder.CreateNeg(ArgValue, (ArgValue->getName() + "neg").c_str());
93 llvm::Value *CmpResult =
94 Builder.CreateICmpSGE(ArgValue, NegOp->getOperand(0), "abscond");
95 llvm::Value *Result =
96 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
97
98 return RValue::get(Result);
99 }
Anders Carlsson89799cf2007-10-29 02:59:40 +0000100 }
101
Anders Carlsson022012e2007-08-20 18:05:56 +0000102 return RValue::get(0);
103}