DeclarationName and the StringRef.

To context was ,

Basic requirement was to append extra string to the decl name and update all his references to the updated name. ,

So we are constructing the DeclarationName instance as stated below code snap.
and from DeclarationName instance ,we are constructing the DeclarationNameInfo and same info used to create decl spec with FunctionDecl::Create () .

Question is ,

How do ,someone instantiate the DeclarationName instance using StringRef ,because in the current trunk code snap ,we see that the DeclarationName can be constructed using the IdentifierInfo or Objc Selector or CXXOperatorId etc as argument in the constructor .

The code i.e

void appendExtern(StringRef Sr)
{
char *ExternChar = const_cast<char *> (Sr.data());

*Ptr =reinterpret_cast<void *>(ExternChar);

this->ExternName = DeclarationName::getFromOpaquePtr(Ptr);

}

the above is kind of hack ,may result in dangling memory references ,Any thoughts on this ?

we thought to change the DeclarationName class ,with adding new DeclarationName constructor ,that construct the DeclarationName instance by StringRef as argument. i.e DeclarationName(StringRef Sr) ;

Before doing this ,we thought to check with community for better alternative / suggestions .

Thank you
~Umesh

Usually it’s better to send questions about the clang frontend to just cfe-dev, rather than llvm-dev.

Thank you eli, my bad will take care that next time.

Hi Eli and All ,

We added the support to rename the function name ,i.e something like “func” to “test_func” for any function we append the string “test_”,hence modified the code @ @ lib/Sema/SemaDecl.cpp like

static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
DeclContext *DC, QualType &R,
TypeSourceInfo *TInfo,
StorageClass SC,
bool &IsVirtualOkay){

DeclarationNameInfo NameInfo = SemaRef.GetNameForDeclarator(D);
DeclarationName Name = NameInfo.getName();
std::string ExtPreRef;

SmallString<32> Str;
StringRef EP = (“Test_” + Name.getAsString()).toStringRef(Str);
const IdentifierInfo &test = SemaRef.PP.getIdentifierTable().get(EP);
DeclarationName ExternName(&test);
SemaRef.ExternPrefixMap[Name.getAsString()] = ExternName;
NameInfo.setName(ExternName);

FunctionDecl *NewFD = nullptr;
bool isInline = D.getDeclSpec().isInlineSpecified();

}

testcase.c

int foo();
int bar();

int bar()
{
return 1;
}

int foo()
{
return foo() + bar();
}

int (*ptr) ();

int main()
{
ptr = bar;
return ptr();
}

we we try to compile the source testcase.c ,we ended up with the below warnings and error.

test.c:12:9: warning: implicit declaration of function ‘foo’ is invalid in C99 [-Wimplicit-function-declaration]
return foo() + bar();
^
DefinefooFound:foo
test.c:12:17: warning: implicit declaration of function ‘bar’ is invalid in C99 [-Wimplicit-function-declaration]
return foo() + bar();
^
DefinebarFound:bar
DefinemainCome
maintest.c:19:6: error: assigning to ‘int (*)()’ from incompatible type ‘’
ptr = Test_list_bar;
^ ~~~~~~~~~~~~~
test.c:12:17: note: candidate function
return foo() + bar();

to overcome the above issue ,we modified the source @ lib/Sema/SemaExpr.cpp ,i.e

ExprResult
Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
SourceLocation TemplateKWLoc, UnqualifiedId &Id,
bool HasTrailingLParen, bool IsAddressOfOperand,
std::unique_ptr CCC,
bool IsInlineAsmIdentifier, Token *KeywordReplacement) {
assert(!(IsAddressOfOperand && HasTrailingLParen) &&
“cannot be direct & operand and have a trailing lparen”);
if (SS.isInvalid())
return ExprError();

TemplateArgumentListInfo TemplateArgsBuffer;

// Decompose the UnqualifiedId into the following data.
DeclarationNameInfo NameInfo;
const TemplateArgumentListInfo TemplateArgs;
DecomposeUnqualifiedId(Id, TemplateArgsBuffer, NameInfo, TemplateArgs);
/
This Map will have functions that are renamed ,Key is Function Name and Value is the DeclarationName of renamed function.*/
if(this->ExternPrefixMap.count( NameInfo.getName().getAsString()) == 1){
auto ExternName = this->ExternPrefixMap.find(NameInfo.getName().getAsString());
if(ExternName != this->ExternPrefixMap.end()){
NameInfo.setName(this->ExternPrefixMap[NameInfo.getName().getAsString()]);
}
}
DeclarationName Name = NameInfo.getName();
IdentifierInfo *II = Name.getAsIdentifierInfo();
SourceLocation NameLoc = NameInfo.getLoc();

}

But ,we ended up with errors like ,

test.c:12:9: error: use of undeclared identifier ‘Test_foo’; did you mean ‘Test_foo’?
return foo() + bar();
^~~
Test_foo
test.c:10:5: note: ‘Test_foo’ declared here
int foo()
^
test.c:12:17: error: use of undeclared identifier ‘Test_bar’; did you mean ‘Test_bar’?
return foo() + bar();
^~~
Test_bar
test.c:5:5: note: ‘Test_bar’ declared here
int bar()
^

maintest.c:19:6: error: assigning to ‘int (*)()’ from incompatible type ‘’
ptr = bar;

debugging the same ,any inputs or suggestions or comments here ,will be highly appreciated .

Thank you
~Umesh

Hang on, lets take a step back at this point. Why are you doing this? If you don't want the function to have a different name, don't rename it.

If you need to change the name of a function in the generated IR/assembly without changing the semantic name, you can use the __asm__ attribute (as in `int f() __asm__("test_f");`).

-Eli