How do I add an attribute alias to LLVM (add targeted support)?
I am working on adding AVR target to LLVM and Clang . Now I have to add support __attribute__ ((progmem))
.
The first thing I tried to do was add a new attribute to Attr.td
:
def TargetAVR : TargetArch<["avr"]>;
def AVRProgmem : InheritableAttr, TargetSpecificAttr<TargetAVR> {
let Spellings = [GCC<"progmem">];
let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
"ExpectedFunctionGlobalVarMethodOrProperty">;
let Documentation = [SectionDocs];
}
I tested it with the following code:
#include <avr/io.h>
#define PROGMEM __attribute__ ((progmem))
static const uint8_t tone_pin_to_timer_PGM[] PROGMEM = { 2 };
int main()
{
DDRB = 0x00; //configure portB as input
DDRC = 0xFF; //configure portC as output
while(1)
{
PORTC = PINB;
}
return 0;
}
Unfortunately, this does not work because the "section" attribute is not a normal attribute, but special attributes that LLVM knows that the item it is attached to should be placed in a specific section.
Assertion failed: (Attr.isTypeAttr() && "Non-type attribute not handled"), function ProcessDeclAttribute, file /Users/asmirnov/Documents/dev/src/llvm_dylan/tools/clang/lib/Sema/SemaDeclAttr.cpp, line 4232.
0 clang 0x000000011001b72e llvm::sys::PrintStackTrace(__sFILE*) + 46
1 clang 0x000000011001cadb PrintStackTraceSignalHandler(void*) + 27
2 clang 0x000000011001cf25 SignalHandler(int) + 565
3 libsystem_platform.dylib 0x00007fff8fd785aa _sigtramp + 26
4 libsystem_platform.dylib 0x00007fff532b82e8 _sigtramp + 3277061464
5 clang 0x000000011001cb0b raise + 27
6 clang 0x000000011001cbc2 abort + 18
7 clang 0x000000011001cba1 __assert_rtn + 129
8 clang 0x000000010d38b415 ProcessDeclAttribute(clang::Sema&, clang::Scope*, clang::Decl*, clang::AttributeList const&, bool) + 485
9 clang 0x000000010d38aff5 clang::Sema::ProcessDeclAttributeList(clang::Scope*, clang::Decl*, clang::AttributeList const*, bool) + 101
10 clang 0x000000010d38d3e1 clang::Sema::ProcessDeclAttributes(clang::Scope*, clang::Decl*, clang::Declarator const&) + 273
11 clang 0x000000010d347d8d clang::Sema::ActOnVariableDeclarator(clang::Scope*, clang::Declarator&, clang::DeclContext*, clang::TypeSourceInfo*, clang::LookupResult&, llvm::MutableArrayRef<clang::TemplateParameterList*>, bool&) + 6845
12 clang 0x000000010d340dbe clang::Sema::HandleDeclarator(clang::Scope*, clang::Declarator&, llvm::MutableArrayRef<clang::TemplateParameterList*>) + 3214
13 clang 0x000000010d3400ae clang::Sema::ActOnDeclarator(clang::Scope*, clang::Declarator&) + 94
14 clang 0x000000010d1199c7 clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*) + 215
15 clang 0x000000010d118a29 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, unsigned int, bool, clang::SourceLocation*, clang::Parser::ForRangeInit*) + 2185
16 clang 0x000000010d1afb7c clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) + 1228
17 clang 0x000000010d1af295 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier) + 197
18 clang 0x000000010d1aea21 clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) + 3441
19 clang 0x000000010d1adc65 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&) + 773
20 clang 0x000000010d1059fc clang::ParseAST(clang::Sema&, bool, bool) + 988
21 clang 0x000000010caaf82a clang::ASTFrontendAction::ExecuteAction() + 522
22 clang 0x000000010cface23 clang::CodeGenAction::ExecuteAction() + 3939
23 clang 0x000000010caaeda8 clang::FrontendAction::Execute() + 120
24 clang 0x000000010ca40a89 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 1017
25 clang 0x000000010c964c01 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 3201
26 clang 0x000000010c944360 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) + 2496
27 clang 0x000000010c959deb ExecuteCC1Tool(llvm::ArrayRef<char const*>, llvm::StringRef) + 171
28 clang 0x000000010c958c5b main + 1275
29 libdyld.dylib 0x00007fff8aeb05fd start + 1
30 libdyld.dylib 0x000000000000002e start + 1964309042
I don't want to copy this code, so I can make llvm know __attribute__ ((progmem))
- is this just an alias for __attribute__ ((section ("progmem") ))
?
PS. It is undesirable to use a macro, as it requires additional inclusion with macros in each source code.
source to share
In ./libs/Sema/SemaDeclAttr.cpp
you will find the function ProcessDeclAttributte
. There you will find a huge operator switch
where you have to add case
for your attribute. ProcessDeclAttribute
is the main dispatch function when the attribute is inside the code to compile. You can add code here to specify how clang should react to the attribute.
The statement indicates the problem:
Assertion failed: (Attr.isTypeAttr() && "Non-type attribute not handled"), function ProcessDeclAttribute, file /Users/asmirnov/Documents/dev/src/llvm_dylan/tools/clang/lib/Sema/SemaDeclAttr.cpp, line 4232.
source to share