我正在努力将AVR目标添加到LLVM和Clang。
现在我应该添加__attribute__ ((progmem))
支持。
我尝试做的第一件事就是向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];
}
我用下一个代码测试了它:
#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;
}
不幸的是它不起作用,因为“section”属性不是常规属性,但是使LLVM知道它附加的东西的特殊属性需要放在特定的部分。
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
我不想复制粘贴该代码,因此我可以让llvm知道__attribute__ ((progmem))
只是__attribute__ ((section ("progmem") ))
的别名吗?
PS。使用宏是不可取的,因为它需要为每个源代码添加宏。
答案 0 :(得分:3)
在./libs/Sema/SemaDeclAttr.cpp
中,您将找到函数ProcessDeclAttributte
。在那里,您会找到一个巨大的switch
语句,您必须为您的属性添加case
。 ProcessDeclAttribute
是在代码中找到要编译的属性时的主要调度函数。在这里,您可以添加代码以指定clang对属性的反应。
断言指出了问题所在:
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.