blob: 322361d27fab85b9b3bc9b30bebfec3178714e35 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define CHAZ_USE_SHORT_NAMES
#include "Charmonizer/Core/Compiler.h"
#include "Charmonizer/Core/ConfWriter.h"
#include "Charmonizer/Core/Util.h"
#include "Charmonizer/Probe/FuncMacro.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Code for verifying ISO func macro. */
static const char iso_func_code[] =
QUOTE( #include "_charm.h" )
QUOTE( int main() { )
QUOTE( Charm_Setup; )
QUOTE( printf("%s", __func__); )
QUOTE( return 0; )
QUOTE( } );
/* Code for verifying GNU func macro. */
static const char gnuc_func_code[] =
QUOTE( #include "_charm.h" )
QUOTE( int main() { )
QUOTE( Charm_Setup; )
QUOTE( printf("%s", __FUNCTION__); )
QUOTE( return 0; )
QUOTE( } );
/* Code for verifying inline keyword. */
static const char inline_code[] =
QUOTE( #include "_charm.h" )
QUOTE( static %s int foo() { return 1; } )
QUOTE( int main() { )
QUOTE( Charm_Setup; )
QUOTE( printf("%%d", foo()); )
QUOTE( return 0; )
QUOTE( } );
static char*
S_try_inline(const char *keyword, size_t *output_len) {
char code[sizeof(inline_code) + 30];
sprintf(code, inline_code, keyword);
return CC_capture_output(code, strlen(code), output_len);
}
static const char* inline_options[] = {
"__inline",
"__inline__",
"inline"
};
static int num_inline_options = sizeof(inline_options) / sizeof(void*);
void
FuncMacro_run(void) {
int i;
char *output;
size_t output_len;
chaz_bool_t has_funcmac = false;
chaz_bool_t has_iso_funcmac = false;
chaz_bool_t has_gnuc_funcmac = false;
chaz_bool_t has_inline = false;
ConfWriter_start_module("FuncMacro");
/* Check for ISO func macro. */
output = CC_capture_output(iso_func_code, strlen(iso_func_code),
&output_len);
if (output != NULL && strncmp(output, "main", 4) == 0) {
has_funcmac = true;
has_iso_funcmac = true;
}
free(output);
/* Check for GNUC func macro. */
output = CC_capture_output(gnuc_func_code, strlen(gnuc_func_code),
&output_len);
if (output != NULL && strncmp(output, "main", 4) == 0) {
has_funcmac = true;
has_gnuc_funcmac = true;
}
free(output);
/* Write out common defines. */
if (has_funcmac) {
const char *macro_text = has_iso_funcmac
? "__func__"
: "__FUNCTION__";
ConfWriter_append_conf(
"#define CHY_HAS_FUNC_MACRO\n"
"#define CHY_FUNC_MACRO %s\n",
macro_text
);
}
/* Write out specific defines. */
if (has_iso_funcmac) {
ConfWriter_append_conf("#define CHY_HAS_ISO_FUNC_MACRO\n");
}
if (has_gnuc_funcmac) {
ConfWriter_append_conf("#define CHY_HAS_GNUC_FUNC_MACRO\n");
}
/* Check for inline keyword. */
for (i = 0; i < num_inline_options; i++) {
const char *inline_option = inline_options[i];
output = S_try_inline(inline_option, &output_len);
if (output != NULL) {
has_inline = true;
ConfWriter_append_conf("#define CHY_INLINE %s\n", inline_option);
free(output);
break;
}
}
if (!has_inline) {
ConfWriter_append_conf("#define CHY_INLINE\n");
}
/* Shorten. */
ConfWriter_start_short_names();
if (has_iso_funcmac) {
ConfWriter_shorten_macro("HAS_ISO_FUNC_MACRO");
}
if (has_gnuc_funcmac) {
ConfWriter_shorten_macro("HAS_GNUC_FUNC_MACRO");
}
if (has_iso_funcmac || has_gnuc_funcmac) {
ConfWriter_shorten_macro("HAS_FUNC_MACRO");
ConfWriter_shorten_macro("FUNC_MACRO");
}
ConfWriter_shorten_macro("INLINE");
ConfWriter_end_short_names();
ConfWriter_end_module();
}