[llvm-commits] [dragonegg] r126079 - in /dragonegg/trunk: llvm-backend.cpp llvm-convert.cpp llvm-internal.h llvm-types.cpp
Duncan Sands
baldrick at free.fr
Sun Feb 20 04:15:27 PST 2011
Author: baldrick
Date: Sun Feb 20 06:15:27 2011
New Revision: 126079
URL: http://llvm.org/viewvc/llvm-project?rev=126079&view=rev
Log:
The Fortran frontend likes to declare intrinsics as taking, say, one argument
but calls them with more arguments. This is the case for _gfortran_shape_4
for example. In llvm-gcc this was fixed by having the Fortran frontend declare
intrinsics and externals as taking a variable number of arguments. This patch
obtains the same effect without modifying the Fortran frontend by having all
prototypes be declared varargs (except for builtins, such as malloc and free;
these are different to Fortran intrinsics) when compiling Fortran.
Modified:
dragonegg/trunk/llvm-backend.cpp
dragonegg/trunk/llvm-convert.cpp
dragonegg/trunk/llvm-internal.h
dragonegg/trunk/llvm-types.cpp
Modified: dragonegg/trunk/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=126079&r1=126078&r2=126079&view=diff
==============================================================================
--- dragonegg/trunk/llvm-backend.cpp (original)
+++ dragonegg/trunk/llvm-backend.cpp Sun Feb 20 06:15:27 2011
@@ -509,6 +509,11 @@
/// "T foo() {}" will be treated like "T foo(void) {}" and not "T foo(...) {}".
bool flag_vararg_requires_arguments;
+/// flag_force_vararg_prototypes - Force prototypes to take a variable number of
+/// arguments (...). This is helpful if the language front-end sometimes emits
+/// calls where the call arguments do not match the callee function declaration.
+bool flag_force_vararg_prototypes;
+
/// InstallLanguageSettings - Do any language-specific back-end configuration.
static void InstallLanguageSettings() {
// The principal here is that not doing any language-specific configuration
@@ -524,6 +529,7 @@
} else if (LanguageName == "GNU C++") {
flag_odr = true; // C++ obeys the one-definition-rule
} else if (LanguageName == "GNU Fortran") {
+ flag_force_vararg_prototypes = true;
} else if (LanguageName == "GNU GIMPLE") { // LTO gold plugin
} else if (LanguageName == "GNU Java") {
} else if (LanguageName == "GNU Objective-C") {
Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=126079&r1=126078&r2=126079&view=diff
==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Sun Feb 20 06:15:27 2011
@@ -541,6 +541,8 @@
CallingConv::ID CallingConv;
AttrListPtr PAL;
+ bool getFunctionTypeFromArgList = false;
+
// If the function has no arguments and is varargs (...), turn it into a
// non-varargs function by scanning the param list for the function. This
// allows C functions declared as "T foo() {}" to be treated like
@@ -549,18 +551,30 @@
//
// Note that we only do this in C/Objective-C. Doing this in C++ for
// functions explicitly declared as taking (...) is bad.
- if (TYPE_ARG_TYPES(TREE_TYPE(FnDecl)) == 0 && flag_vararg_requires_arguments){
+ if (TYPE_ARG_TYPES(TREE_TYPE(FnDecl)) == 0 && flag_vararg_requires_arguments)
+ getFunctionTypeFromArgList = true;
+
+ // When forcing vararg prototypes ensure that the function only gets a varargs
+ // part if it was originally declared varargs.
+ if (flag_force_vararg_prototypes) {
+ tree Args = TYPE_ARG_TYPES(TREE_TYPE(FnDecl));
+ while (Args && TREE_VALUE(Args) != void_type_node)
+ Args = TREE_CHAIN(Args);
+ if (Args != 0)
+ getFunctionTypeFromArgList = true;
+ }
+
+ if (getFunctionTypeFromArgList)
FTy = TheTypeConverter->ConvertArgListToFnType(TREE_TYPE(FnDecl),
DECL_ARGUMENTS(FnDecl),
static_chain,
CallingConv, PAL);
- } else {
+ else
// Otherwise, just get the type from the function itself.
FTy = TheTypeConverter->ConvertFunctionType(TREE_TYPE(FnDecl),
FnDecl,
static_chain,
CallingConv, PAL);
- }
// If we've already seen this function and created a prototype, and if the
// proto has the right LLVM type, just use it.
Modified: dragonegg/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=126079&r1=126078&r2=126079&view=diff
==============================================================================
--- dragonegg/trunk/llvm-internal.h (original)
+++ dragonegg/trunk/llvm-internal.h Sun Feb 20 06:15:27 2011
@@ -93,6 +93,11 @@
/// "T foo() {}" will be treated like "T foo(void) {}" and not "T foo(...) {}".
extern bool flag_vararg_requires_arguments;
+/// flag_force_vararg_prototypes - Force prototypes to take a variable number of
+/// arguments (...). This is helpful if the language front-end sometimes emits
+/// calls where the call arguments do not match the callee function declaration.
+extern bool flag_force_vararg_prototypes;
+
/// AttributeUsedGlobals - The list of globals that are marked attribute(used).
extern SmallSetVector<Constant *,32> AttributeUsedGlobals;
Modified: dragonegg/trunk/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-types.cpp?rev=126079&r1=126078&r2=126079&view=diff
==============================================================================
--- dragonegg/trunk/llvm-types.cpp (original)
+++ dragonegg/trunk/llvm-types.cpp Sun Feb 20 06:15:27 2011
@@ -1249,8 +1249,13 @@
if (HasByVal)
FnAttributes &= ~(Attribute::ReadNone | Attribute::ReadOnly);
- // If the argument list ends with a void type node, it isn't vararg.
- isVarArg = (Args == 0);
+ if (flag_force_vararg_prototypes)
+ // If forcing prototypes to be varargs, make all function types varargs
+ // except those for builtin functions.
+ isVarArg = decl ? !DECL_BUILT_IN(decl) : true;
+ else
+ // If the argument list ends with a void type node, it isn't vararg.
+ isVarArg = (Args == 0);
assert(RetTy && "Return type not specified!");
if (FnAttributes != Attribute::None)
More information about the llvm-commits
mailing list