Help required for adding a new attribute

Hello Clang Developers,

I want to add a new attribute which is required to work with function declaration as shown in example given below:

extern void foo(int param) attribute((regmask(“R8,R11”)));

int foo2(int param) {
foo(param);
return param;
}

For this I have done following changes:

Attr.td

def RegMask : Attr {
let Spellings = [GNU<“regmask”>];
let Args = [StringArgument<“ClobbersList”>];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}

lib/Sema/SemaDeclAttr.cpp

static void handleRegMaskAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// Make sure that there is a string literal as the annotation’s single
// argument.
StringRef Str;
if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
return;

D->addAttr(::new (S.Context)
AnnotateAttr(Attr.getRange(), S.Context, Str,
Attr.getAttributeSpellingListIndex()));
llvm::dbgs() << "Reg Mask attribute : " << Str << “\n”;
}

above method is very similar to handleAnnotateAttr

and use this method inside ProcessDeclAttribute method as follows :

// Attribute to help interprocedural register allocation
case AttributeList::AT_RegMask:
handleRegMaskAttr(S, D, Attr);
break;
}

but this does not work for me, it works on function definitions but not with function declaration.

Am I missing here any thing?

Note: I want to parse this string at MI level if possible or at IR level to create a RegMask out of that.

Sincerely,
Vivek

Hello Clang Developers,

I want to add a new attribute which is required to work with function
declaration as shown in example given below:

extern void foo(int param) __attribute__((regmask("R8,R11")));

int foo2(int param) {
foo(param);
return param;
}

For this I have done following changes:

Attr.td

def RegMask : Attr {
  let Spellings = [GNU<"regmask">];
  let Args = [StringArgument<"ClobbersList">];
  let Subjects = SubjectList<[Function]>;
  let Documentation = [Undocumented];
}

lib/Sema/SemaDeclAttr.cpp

static void handleRegMaskAttr(Sema &S, Decl *D, const AttributeList &Attr) {
  // Make sure that there is a string literal as the annotation's single
  // argument.
  StringRef Str;
  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
    return;

  D->addAttr(::new (S.Context)
             AnnotateAttr(Attr.getRange(), S.Context, Str,
                          Attr.getAttributeSpellingListIndex()));
  llvm::dbgs() << "Reg Mask attribute : " << Str << "\n";
}

above method is very similar to handleAnnotateAttr

and use this method inside ProcessDeclAttribute method as follows :

// Attribute to help interprocedural register allocation
  case AttributeList::AT_RegMask:
    handleRegMaskAttr(S, D, Attr);
    break;
  }

but this does not work for me, it works on function definitions but not with
function declaration.

Am I missing here any thing?

The attribute should inherit from InheritableAttr instead of just
Attr. That should cause it to be inherited by later redeclarations.

Note: I want to parse this string at MI level if possible or at IR level to
create a RegMask out of that.

How do you intend to report diagnostics to the user if the parsed
string contains something unexpected?

~Aaron

> Hello Clang Developers,
>
> I want to add a new attribute which is required to work with function
> declaration as shown in example given below:
>
> extern void foo(int param) __attribute__((regmask("R8,R11")));
>
> int foo2(int param) {
> foo(param);
> return param;
> }
>
> For this I have done following changes:
>
> Attr.td
>
> def RegMask : Attr {
> let Spellings = [GNU<"regmask">];
> let Args = [StringArgument<"ClobbersList">];
> let Subjects = SubjectList<[Function]>;
> let Documentation = [Undocumented];
> }
>
> lib/Sema/SemaDeclAttr.cpp
>
> static void handleRegMaskAttr(Sema &S, Decl *D, const AttributeList
&Attr) {
> // Make sure that there is a string literal as the annotation's single
> // argument.
> StringRef Str;
> if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
> return;
>
> D->addAttr(::new (S.Context)
> AnnotateAttr(Attr.getRange(), S.Context, Str,
> Attr.getAttributeSpellingListIndex()));
> llvm::dbgs() << "Reg Mask attribute : " << Str << "\n";
> }
>
> above method is very similar to handleAnnotateAttr
>
> and use this method inside ProcessDeclAttribute method as follows :
>
> // Attribute to help interprocedural register allocation
> case AttributeList::AT_RegMask:
> handleRegMaskAttr(S, D, Attr);
> break;
> }
>
> but this does not work for me, it works on function definitions but not
with
> function declaration.
>
> Am I missing here any thing?

The attribute should inherit from InheritableAttr instead of just
Attr. That should cause it to be inherited by later redeclarations.

I think my question is not clear, in the example given above foo and foo2
both are different function and what I want is that foo is extern function
for current module and for this declaration I want regmask attribute as a
string.
Why should I need InheritableAttr when foo is not going to be redeclared in
the current module?

> Note: I want to parse this string at MI level if possible or at IR level
to
> create a RegMask out of that.

How do you intend to report diagnostics to the user if the parsed
string contains something unexpected?

If I am not able to use clang's diagnostics then I believe I should take
help of some thing like LLVM_ERROR.
-Vivek

Summary of discussion happened on IRC with Aaron Ballman :

The actual problem is that for function declaration clang does not process any thing else except lowring it to appropriate LLVM IR construct thus regmask attribute is getting dropped also annotate attribute. ( This can be verified from lib/CodeGen/CGDecl.cpp )

So this needs to be fixed in CGDecl.cpp at least for custom attribute like regmask.

The fix should be some thing similar to

void CodeGenModule::AddGlobalAnnotations()

So while clang codegen to LLVM IR the attribute should be propagated to LLVM IR appropriately.

-Vivek