mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 09:32:20 +00:00
Generate code for va_start and va_end.
llvm-svn: 42939
This commit is contained in:
parent
fd0312ed79
commit
24ebce6fca
@ -135,6 +135,7 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context) {
|
||||
break;
|
||||
case 'V':
|
||||
Type = Context.getBuiltinVaListType();
|
||||
assert(!Type.isNull() && "builtin va list type not initialized!");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -145,6 +146,9 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context) {
|
||||
case '*':
|
||||
Type = Context.getPointerType(Type);
|
||||
break;
|
||||
case '&':
|
||||
Type = Context.getReferenceType(Type);
|
||||
break;
|
||||
case 'C':
|
||||
Type = Type.getQualifiedType(QualType::Const);
|
||||
break;
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
|
||||
@ -45,7 +47,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
|
||||
std::string S(Literal->getStrData(), Literal->getByteLength());
|
||||
|
||||
return RValue::get(CGM.GetAddrOfConstantCFString(S));
|
||||
}
|
||||
}
|
||||
case Builtin::BI__builtin_va_start:
|
||||
case Builtin::BI__builtin_va_end: {
|
||||
llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
|
||||
const llvm::Type *DestType = llvm::PointerType::get(llvm::Type::Int8Ty);
|
||||
if (ArgValue->getType() != DestType)
|
||||
ArgValue = Builder.CreateBitCast(ArgValue, DestType,
|
||||
ArgValue->getNameStart());
|
||||
|
||||
llvm::Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_start) ?
|
||||
llvm::Intrinsic::vastart : llvm::Intrinsic::vaend;
|
||||
llvm::Value *F = llvm::Intrinsic::getDeclaration(&CGM.getModule(), inst);
|
||||
llvm::Value *V = Builder.CreateCall(F, ArgValue);
|
||||
|
||||
return RValue::get(V);
|
||||
}
|
||||
}
|
||||
|
||||
return RValue::get(0);
|
||||
|
@ -418,6 +418,11 @@ Value *ScalarExprEmitter::VisitImplicitCastExpr(const ImplicitCastExpr *E) {
|
||||
|
||||
llvm::Value *Ops[] = {Idx0, Idx0};
|
||||
return Builder.CreateGEP(V, Ops, Ops+2, "arraydecay");
|
||||
} else if (E->getType()->isReferenceType()) {
|
||||
assert(cast<ReferenceType>(E->getType())->getReferenceeType() ==
|
||||
Op->getType() && "Incompatible types!");
|
||||
|
||||
return EmitLValue(Op).getAddress();
|
||||
}
|
||||
|
||||
return EmitCastExpr(Op, E->getType());
|
||||
|
@ -46,8 +46,8 @@ const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
|
||||
}
|
||||
|
||||
bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
|
||||
return !T->isRealType() && !T->isPointerType() && !T->isVoidType() &&
|
||||
!T->isVectorType() && !T->isFunctionType();
|
||||
return !T->isRealType() && !T->isPointerType() && !T->isReferenceType() &&
|
||||
!T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,7 +152,9 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
|
||||
Scope *S) {
|
||||
Builtin::ID BID = (Builtin::ID)bid;
|
||||
|
||||
if (BID == Builtin::BI__builtin_va_start &&
|
||||
if ((BID == Builtin::BI__builtin_va_start ||
|
||||
BID == Builtin::BI__builtin_va_copy ||
|
||||
BID == Builtin::BI__builtin_va_end) &&
|
||||
Context.getBuiltinVaListType().isNull()) {
|
||||
IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
|
||||
ScopedDecl *VaDecl = LookupScopedDecl(VaIdent, Decl::IDNS_Ordinary,
|
||||
|
@ -1014,7 +1014,10 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
|
||||
if (lhsType == rhsType) // common case, fast path...
|
||||
return Compatible;
|
||||
|
||||
if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
|
||||
if (lhsType->isReferenceType() || rhsType->isReferenceType()) {
|
||||
if (Type::referenceTypesAreCompatible(lhsType, rhsType))
|
||||
return Compatible;
|
||||
} else if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
|
||||
if (lhsType->isVectorType() || rhsType->isVectorType()) {
|
||||
if (lhsType.getCanonicalType() != rhsType.getCanonicalType())
|
||||
return Incompatible;
|
||||
@ -1036,9 +1039,6 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
|
||||
} else if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
|
||||
if (Type::tagTypesAreCompatible(lhsType, rhsType))
|
||||
return Compatible;
|
||||
} else if (lhsType->isReferenceType() || rhsType->isReferenceType()) {
|
||||
if (Type::referenceTypesAreCompatible(lhsType, rhsType))
|
||||
return Compatible;
|
||||
}
|
||||
return Incompatible;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
//
|
||||
// Types may be postfixed with the following modifiers:
|
||||
// * -> pointer
|
||||
// & -> reference
|
||||
// C -> const
|
||||
|
||||
// The third value provided to the macro specifies information about attributes
|
||||
@ -59,6 +60,8 @@ BUILTIN(__builtin_fabsl, "LdLd", "ncF")
|
||||
BUILTIN(__builtin_constant_p, "UsUs", "nc")
|
||||
BUILTIN(__builtin_classify_type, "i.", "nc")
|
||||
BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
|
||||
BUILTIN(__builtin_va_start, "vV.", "nc")
|
||||
BUILTIN(__builtin_va_start, "vV&.", "nc")
|
||||
BUILTIN(__builtin_va_end, "vV&", "nc")
|
||||
BUILTIN(__builtin_va_copy, "vV&V", "nc")
|
||||
|
||||
#undef BUILTIN
|
||||
|
@ -187,7 +187,7 @@ public:
|
||||
/// __builtin_va_list, which is target-specific.
|
||||
const char *getVAListDeclaration() const {
|
||||
// FIXME: dispatch to target impl.
|
||||
return "typedef int __builtin_va_list;";
|
||||
return "typedef char* __builtin_va_list;";
|
||||
}
|
||||
///===---- Some helper methods ------------------------------------------===//
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user