From: Anders Carlsson Date: Fri, 12 Oct 2007 23:56:29 +0000 (+0000) Subject: Generate code for va_start and va_end. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=793680ed8104bf088d1b382b963a8badcb3f07de;p=clang Generate code for va_start and va_end. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42939 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/Builtins.cpp b/AST/Builtins.cpp index 219f00c479..3fb3faf85f 100644 --- a/AST/Builtins.cpp +++ b/AST/Builtins.cpp @@ -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; diff --git a/CodeGen/CGBuiltin.cpp b/CodeGen/CGBuiltin.cpp index 6dbd272521..2ca84e25d4 100644 --- a/CodeGen/CGBuiltin.cpp +++ b/CodeGen/CGBuiltin.cpp @@ -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); diff --git a/CodeGen/CGExprScalar.cpp b/CodeGen/CGExprScalar.cpp index cd5c078b5c..755fd56de6 100644 --- a/CodeGen/CGExprScalar.cpp +++ b/CodeGen/CGExprScalar.cpp @@ -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(E->getType())->getReferenceeType() == + Op->getType() && "Incompatible types!"); + + return EmitLValue(Op).getAddress(); } return EmitCastExpr(Op, E->getType()); diff --git a/CodeGen/CodeGenFunction.cpp b/CodeGen/CodeGenFunction.cpp index 80c75afdb8..1457ec5606 100644 --- a/CodeGen/CodeGenFunction.cpp +++ b/CodeGen/CodeGenFunction.cpp @@ -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(); } diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index e7b717c59c..472df150e8 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -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, diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 44b3e73fbb..54e67141f2 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -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(lhsType) && isa(rhsType)) { if (Type::tagTypesAreCompatible(lhsType, rhsType)) return Compatible; - } else if (lhsType->isReferenceType() || rhsType->isReferenceType()) { - if (Type::referenceTypesAreCompatible(lhsType, rhsType)) - return Compatible; } return Incompatible; } diff --git a/include/clang/AST/Builtins.def b/include/clang/AST/Builtins.def index 3325d385e5..62b363b66d 100644 --- a/include/clang/AST/Builtins.def +++ b/include/clang/AST/Builtins.def @@ -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 diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index e161e65ef3..02a0f88da5 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -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 ------------------------------------------===//