Skip to content

Commit

Permalink
Fixed function prototype handling of original function type syntax in…
Browse files Browse the repository at this point in the history
… code generation (modified IR to support added type_syntax, but only for function declarations at this point).
  • Loading branch information
danquinlan committed Jul 11, 2014
1 parent 1f1e7bf commit bb3a5ef
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 3 deletions.
24 changes: 24 additions & 0 deletions README.git
Expand Up @@ -936,3 +936,27 @@ Working with the new_app branch on tux231:
Working with the new_app branch on zeus:
145 9:45 smgit fetch origin
146 9:46 smgit merge origin/dquinlan/dq-new_app-rc


Technique for debugging exceptions:
1) Look for the name of the exception
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid

2) search for the name of the exception to find the associated function in the
include-staging/g++_HEADERS directory.
grep -r "basic_string::_S_construct NULL not valid" *

3) Set a break point in gdb to detect when that function is called.
(gdb) b std::__throw_logic_error(char const*)

4) Use the where command in gdb to get the trace back to the location of the exception.
(gdb) w

Example ouput of gdb trace:
#0 0x000000348f4617d0 in std::__throw_logic_error(char const*) () from /usr/lib64/libstdc++.so.6
#1 0x000000348f49ce59 in ?? () from /usr/lib64/libstdc++.so.6
#2 0x000000348f49cf33 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib64/libstdc++.so.6
#3 0x00007ffff6680036 in EDG_ROSE_Translation::getDeclarationScope (scp=...) at /home/dquinlan/ROSE/git-dq-new_app-rc/src/frontend/CxxFrontend/EDG/edgRose/edgRose.C:31917
#4 0x00007ffff668d7f8 in EDG_ROSE_Translation::convert_variable_use (p=0x947d90) at /home/dquinlan/ROSE/git-dq-new_app-rc/src/frontend/CxxFrontend/EDG/edgRose/edgRose.C:30057
#5 0x00007ffff667358b in EDG_ROSE_Translation::convert_expression (e=0x9486a8) at /home/dquinlan/ROSE/git-dq-new_app-rc/src/frontend/CxxFrontend/EDG/edgRose/edgRose.C:8025
14 changes: 14 additions & 0 deletions src/ROSETTA/src/statement.C
Expand Up @@ -1042,6 +1042,20 @@ Grammar::setUpStatements ()
FunctionDeclaration.setDataPrototype ( "int","gnu_regparm_attribute", "= 0",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);

// DQ (7/9/2014): Example test2014_85.C demonstrates that the declared type of a function can be
// equivalent to other same functions (associated defining and non-defining declarations), but
// syntatically different in a way that makes a difference to the code generated from the unparser
// (but not to the formal type system). I am not clear if this type should be traversed, I think
// not, since it is a function type used only for the representation of syntax.
FunctionDeclaration.setDataPrototype ( "SgFunctionType*", "type_syntax", "= NULL",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL /* || DEF2TYPE_TRAVERSAL */, NO_DELETE);

// DQ (7/9/2014): Added boolean flag to communicate when the function's type syntax is different from
// the function's type. However, when the type_syntax is non-null, it is always an equivalent type.
// Future work will enforce this concept fo type equivalence, not yet supported.
FunctionDeclaration.setDataPrototype ( "bool","type_syntax_is_available", "= false",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);


FunctionDefinition.setFunctionPrototype ( "HEADER_FUNCTION_DEFINITION_STATEMENT", "../Grammar/Statement.code" );
FunctionDefinition.editSubstitute ( "HEADER_LIST_DECLARATIONS", "HEADER_LIST_DECLARATIONS", "../Grammar/Statement.code" );
Expand Down
59 changes: 58 additions & 1 deletion src/backend/unparser/CxxCodeGeneration/unparseCxx_statements.C
Expand Up @@ -273,10 +273,65 @@ Unparse_ExprStmt::unparseFunctionParameterDeclaration (
{
ROSE_ASSERT (funcdecl_stmt != NULL);

ROSE_ASSERT (initializedName != NULL);
SgName tmp_name = initializedName->get_name();
SgInitializer *tmp_init = initializedName->get_initializer();
SgType *tmp_type = initializedName->get_type();
ROSE_ASSERT (initializedName!= NULL);

// DQ (7/10/2014): Added support for using the original type syntax (saved as the declared function type).
if (funcdecl_stmt->get_type_syntax_is_available() == true)
{
// Here we want to use the type syntx that originally appears with this function declaration in the original code.
SgFunctionType* function_type = funcdecl_stmt->get_type_syntax();
ROSE_ASSERT(function_type != NULL);
#if 0
// printf ("Found the original function type syntax: function_type = %p = %s \n",function_type,function_type->unparseToString().c_str());
printf ("In unparseFunctionParameterDeclaration(): Found the original function type syntax: function_type = %p = %s \n",function_type,function_type->class_name().c_str());
#endif
SgFunctionParameterTypeList* type_argument_list = function_type->get_argument_list();
ROSE_ASSERT(type_argument_list != NULL);

// find the associated index from the initializedName.
SgFunctionParameterList* name_argument_list = funcdecl_stmt->get_parameterList();
ROSE_ASSERT(name_argument_list != NULL);

SgInitializedNamePtrList & name_list = name_argument_list->get_args();

SgInitializedNamePtrList::iterator i = name_list.begin();
size_t counter = 0;
while (i != name_list.end() && (*i) != initializedName)
{
#if 0
printf ("In unparseFunctionParameterDeclaration(): loop: counter = %zu \n",counter);
#endif
counter++;
i++;
}

ROSE_ASSERT(i != name_list.end());
#if 0
printf ("In unparseFunctionParameterDeclaration(): counter = %zu \n",counter);
#endif
// SgTypePtrList & get_arguments()
tmp_type = type_argument_list->get_arguments()[counter];
#if 0
printf ("tmp_type = %p = %s \n",tmp_type,tmp_type->class_name().c_str());
#endif
#if 0
printf ("In unparseFunctionParameterDeclaration(): (funcdecl_stmt->get_type_syntax_is_available() == true): exiting as a test! \n");
ROSE_ASSERT(false);
#endif
}
else
{
// DQ (7/10/2014): Enforce this rule.
ROSE_ASSERT(funcdecl_stmt->get_type_syntax() == NULL);
}

#if 0
printf ("In unparseFunctionParameterDeclaration(): exiting as a test! \n");
ROSE_ASSERT(false);
#endif

// DQ (8/9/2013): refactored to support additional refactoring to seperate out code to unparse SgInitializedName.
bool oldStyleDefinition = funcdecl_stmt->get_oldStyleDefinition();
Expand Down Expand Up @@ -3039,6 +3094,7 @@ Unparse_ExprStmt::unparseFuncDeclStmt(SgStatement* stmt, SgUnparse_Info& info)
#endif

#if OUTPUT_FUNCTION_DECLARATION_DATA || 0
printf ("calling unparse_helper \n");
curprint ("/* calling unparse_helper */");
#endif
unparse_helper(funcdecl_stmt, ninfo);
Expand All @@ -3047,6 +3103,7 @@ Unparse_ExprStmt::unparseFuncDeclStmt(SgStatement* stmt, SgUnparse_Info& info)
ninfo.set_declstatement_ptr(NULL);

#if 0
printf ("DONE: calling unparse_helper \n");
curprint ("/* DONE: calling unparse_helper */");
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/frontend/CxxFrontend/EDG
Submodule EDG updated from 52cf9c to 2fa353
6 changes: 6 additions & 0 deletions tests/CompileTests/Cxx_tests/Makefile.am
Expand Up @@ -121,9 +121,15 @@ EXAMPLE_TESTCODES_REQUIRED_TO_PASS += \
test2014_80.C \
test2014_81.C \
test2014_82.C \
test2014_85.C \
test2014_86.C \
lulesh.C \
luleshTALC.C

# DQ (7/10/2014): Remaining bugs in new application.
# test2014_83.C
# test2014_84.C

# DQ (7/3/2014): This C++ language feature is only properly supported in EDG version 4.9
if ROSE_USE_EDG_VERSION_4_9
EXAMPLE_TESTCODES_REQUIRED_TO_PASS += \
Expand Down
3 changes: 2 additions & 1 deletion tests/CompileTests/Cxx_tests/test2014_85.C
Expand Up @@ -5,7 +5,8 @@ namespace
const unsigned array_size = 3;
}

#if 1
void foo( int reverse_boundary[array_size] )
{
}

#endif
39 changes: 39 additions & 0 deletions tests/CompileTests/Cxx_tests/test2014_86.C
@@ -0,0 +1,39 @@
void foo(int a[1]); // size is irrelevant
void bar(int(&a)[1]); // size is irrelevant
void baz(int(*a)[1]); // size is irrelevant

namespace
{
const unsigned array_size = 3;
const unsigned array_size2 = 2;
}

/*
C++ '03 8.3.5/3: ...The type of a function is determined using the
following rules. The type of each parameter is determined from its
own decl-specifier-seq and declarator. After determining the type
of each parameter, any parameter of type "array of T" or "function
returning T" is adjusted to be "pointer to T" or "pointer to
function returning T," respectively....
*/

void foo(int a[array_size]) { // decays to a pointer and becomes int* (C inheritage)
a[0]=a[1]+1;
}

void bar(int(&a)[array_size2]) { // size is enforced
a[0]=a[1]+1;
}

void baz(int(*a)[array_size2]) { // size is enforced
(*a)[0]=(*a)[1]+1;
}

int main() {
int a[2];
a[1]=1;
foo(a);
bar(a);
baz(&a);
return 0;
}

0 comments on commit bb3a5ef

Please sign in to comment.