diff options
author | John McCall <rjmccall@apple.com> | 2011-09-21 08:08:30 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-09-21 08:08:30 +0000 |
commit | cbc038a6c3fcb45439473a70d0284916d47d900e (patch) | |
tree | 068e2cd6328fb13ba95832e950d6bc6a8e0e2c7e /clang/lib/CodeGen/TargetInfo.h | |
parent | 3b4de99158766ca7f41d7f6baafbd9b94a81e0a5 (diff) | |
download | bcm5719-llvm-cbc038a6c3fcb45439473a70d0284916d47d900e.tar.gz bcm5719-llvm-cbc038a6c3fcb45439473a70d0284916d47d900e.zip |
ANSI C requires that a call to an unprototyped function type succeed
if the definition has a non-variadic prototype with compatible
parameters. Therefore, the default rule for such calls must be to
use a non-variadic convention. Achieve this by casting the callee to
the function type with which it is required to be compatible, unless
the target specifically opts out and insists that unprototyped calls
should use the variadic rules. The only case of that I'm aware of is
the x86-64 convention, which passes arguments the same way in both
cases but also sets a small amount of extra information; here we seek
to maintain compatibility with GCC, which does set this when calling
an unprototyped function.
Addresses PR10810 and PR10713.
llvm-svn: 140241
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.h')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.h | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 22e6eb8383b..8f90c7bdd92 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -16,6 +16,7 @@ #define CLANG_CODEGEN_TARGETINFO_H #include "clang/Basic/LLVM.h" +#include "clang/AST/Type.h" #include "llvm/ADT/StringRef.h" namespace llvm { @@ -126,6 +127,40 @@ namespace clang { virtual StringRef getARCRetainAutoreleasedReturnValueMarker() const { return ""; } + + /// Determine whether a call to an unprototyped functions under + /// the given calling convention should use the variadic + /// convention or the non-variadic convention. + /// + /// There's a good reason to make a platform's variadic calling + /// convention be different from its non-variadic calling + /// convention: the non-variadic arguments can be passed in + /// registers (better for performance), and the variadic arguments + /// can be passed on the stack (also better for performance). If + /// this is done, however, unprototyped functions *must* use the + /// non-variadic convention, because C99 states that a call + /// through an unprototyped function type must succeed if the + /// function was defined with a non-variadic prototype with + /// compatible parameters. Therefore, splitting the conventions + /// makes it impossible to call a variadic function through an + /// unprototyped type. Since function prototypes came out in the + /// late 1970s, this is probably an acceptable trade-off. + /// Nonetheless, not all platforms are willing to make it, and in + /// particularly x86-64 bends over backwards to make the + /// conventions compatible. + /// + /// The default is false. This is correct whenever: + /// - the conventions are exactly the same, because it does not + /// matter and the resulting IR will be somewhat prettier in + /// certain cases; or + /// - the conventions are substantively different in how they pass + /// arguments, because in this case using the variadic convention + /// will lead to C99 violations. + /// It is not necessarily correct when arguments are passed in the + /// same way and some out-of-band information is passed for the + /// benefit of variadic callees, as is the case for x86-64. + /// In this case the ABI should be consulted. + virtual bool isNoProtoCallVariadic(CallingConv CC) const; }; } |