FYI this fails on Windows FAILED: cmd.exe /c cd . && "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -E vs_link_exe C:\PROGRA~2\MICROS~2.0\VC\bin\cl.exe /nologo /DWIN32 /D_WINDOWS /W3 /Zm1000 /GR- /EHs-c- /MD /O2 /Ob2 /Febin\diagtool.exe /Fdbin\diagtool.pdb tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\diagtool_main.cpp.obj tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\DiagTool.cpp.obj tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\DiagnosticNames.cpp.obj tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\ListWarnings.cpp.obj tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\ShowEnabledWarnings.cpp.obj tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\TreeView.cpp.obj /link /implib:lib\diagtool.lib /version:0.0 /STACK:10000000 /machine:X86 /INCREMENTAL:NO /subsystem:console lib\LLVMX86CodeGen.lib lib\LLVMX86AsmParser.lib lib\LLVMX86Disassembler.lib lib\LLVMAsmParser.lib lib\LLVMBitReader.lib lib\LLVMAsmPrinter.lib lib\LLVMSelectionDAG.lib lib\LLVMX86Desc.lib lib\LLVMMCParser.lib lib\LLVMCodeGen.lib lib\LLVMX86AsmPrinter.lib lib\LLVMX86Info.lib lib\LLVMObjCARCOpts.lib lib\LLVMScalarOpts.lib lib\LLVMX86Utils.lib lib\LLVMInstCombine.lib lib\LLVMTransformUtils.lib lib\LLVMipa.lib lib\LLVMAnalysis.lib lib\LLVMTarget.lib lib\LLVMCore.lib lib\LLVMMC.lib lib\LLVMObject.lib lib\LLVMSupport.lib lib\clangBasic.lib lib\clangLex.lib lib\clangSema.lib lib\clangFrontend.lib lib\clangDriver.lib lib\LLVMOption.lib lib\clangParse.lib lib\clangSerialization.lib lib\LLVMBitReader.lib lib\clangSema.lib lib\LLVMX86CodeGen.lib lib\LLVMX86AsmParser.lib lib\LLVMX86Disassembler.lib lib\LLVMAsmParser.lib lib\LLVMAsmPrinter.lib lib\LLVMSelectionDAG.lib lib\LLVMX86Desc.lib lib\LLVMMCParser.lib lib\LLVMCodeGen.lib lib\LLVMX86AsmPrinter.lib lib\LLVMX86Info.lib lib\LLVMObjCARCOpts.lib lib\LLVMScalarOpts.lib lib\LLVMX86Utils.lib lib\LLVMInstCombine.lib lib\LLVMTransformUtils.lib lib\LLVMipa.lib lib\LLVMAnalysis.lib lib\LLVMTarget.lib lib\LLVMCore.lib lib\clangAnalysis.lib lib\clangEdit.lib lib\clangAST.lib lib\clangLex.lib lib\clangBasic.lib lib\LLVMMC.lib lib\LLVMObject.lib lib\LLVMSupport.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd . Creating library lib\diagtool.lib and object lib\diagtool.exp
clangSerialization.lib(ASTReaderDecl.cpp.obj) : error LNK2001: unresolved external symbol "public: virtual class clang::ARMInterruptAttr * __thiscall clang::ARMInterruptAttr::clone(class clang::ASTContext &)const " (?clone@ARMInterruptAttr@clang@@UBEPAV12@AAVASTContext@2@@Z) clangSema.lib(TargetAttributesSema.cpp.obj) : error LNK2001: unresolved external symbol "public: virtual class clang::ARMInterruptAttr * __thiscall clang::ARMInterruptAttr::clone(class clang::ASTContext &)const " (?clone@ARMInterruptAttr@clang@@UBEPAV12@AAVASTContext@2@@Z) clangSerialization.lib(ASTReaderDecl.cpp.obj) : error LNK2001: unresolved external symbol "public: virtual void __thiscall clang::ARMInterruptAttr::printPretty(class llvm::raw_ostream &,struct clang::PrintingPolicy const &)const " (?printPretty@ARMInterruptAttr@clang@@UBEXAAVraw_ostream@llvm@@ABUPrintingPolicy@2@@Z) clangSema.lib(TargetAttributesSema.cpp.obj) : error LNK2019: unresolved external symbol "public: virtual void __thiscall clang::ARMInterruptAttr::printPretty(class llvm::raw_ostream &,struct clang::PrintingPolicy const &)const " (?printPretty@ARMInterruptAttr@clang@@UBEXAAVraw_ostream@llvm@@ABUPrintingPolicy@2@@Z) referenced in function "private: class clang::ExtQualsTypeCommonBase const * __thiscall clang::QualType::getCommonPtr(void)const " (?getCommonPtr@QualType@clang@@ABEPBVExtQualsTypeCommonBase@2@XZ) 2013/10/1 Tim Northover <[email protected]>: > Author: tnorthover > Date: Tue Oct 1 09:34:25 2013 > New Revision: 191769 > > URL: http://llvm.org/viewvc/llvm-project?rev=191769&view=rev > Log: > Implement ARM GNU-style interrupt attribute > > This attribute allows users to use a modified C or C++ function as an ARM > exception-handling function and, with care, to successfully return control to > user-space after the issue has been dealt with. > > rdar://problem/14207019 > > Added: > cfe/trunk/test/CodeGen/arm-interrupt-attr.c > cfe/trunk/test/Sema/arm-interrupt-attr.c > Modified: > cfe/trunk/docs/LanguageExtensions.rst > cfe/trunk/include/clang/Basic/Attr.td > cfe/trunk/lib/CodeGen/TargetInfo.cpp > cfe/trunk/lib/Sema/SemaDeclAttr.cpp > cfe/trunk/lib/Sema/TargetAttributesSema.cpp > > Modified: cfe/trunk/docs/LanguageExtensions.rst > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=191769&r1=191768&r2=191769&view=diff > ============================================================================== > --- cfe/trunk/docs/LanguageExtensions.rst (original) > +++ cfe/trunk/docs/LanguageExtensions.rst Tue Oct 1 09:34:25 2013 > @@ -1843,6 +1843,48 @@ Which compiles to (on X86-32): > movl %gs:(%eax), %eax > ret > > +ARM Language Extensions > +----------------------- > + > +Interrupt attribute > +^^^^^^^^^^^^^^^^^^^ > + > +Clang supports the GNU style ``__attribite__((interrupt("TYPE")))`` > attribute on > +ARM targets. This attribute may be attached to a function definiton and > +instructs the backend to generate appropriate function entry/exit code so > that > +it can be used directly as an interrupt service routine. > + > + The parameter passed to the interrupt attribute is optional, but if > +provided it must be a string literal with one of the following values: "IRQ", > +"FIQ", "SWI", "ABORT", "UNDEF". > + > +The semantics are as follows: > + > +- If the function is AAPCS, Clang instructs the backend to realign the stack > to > + 8 bytes on entry. This is a general requirement of the AAPCS at public > + interfaces, but may not hold when an exception is taken. Doing this allows > + other AAPCS functions to be called. > +- If the CPU is M-class this is all that needs to be done since the > architecture > + itself is designed in such a way that functions obeying the normal AAPCS > ABI > + constraints are valid exception handlers. > +- If the CPU is not M-class, the prologue and epilogue are modified to save > all > + non-banked registers that are used, so that upon return the user-mode state > + will not be corrupted. Note that to avoid unnecessary overhead, only > + general-purpose (integer) registers are saved in this way. If VFP > operations > + are needed, that state must be saved manually. > + > + Specifically, interrupt kinds other than "FIQ" will save all core registers > + except "lr" and "sp". "FIQ" interrupts will save r0-r7. > +- If the CPU is not M-class, the return instruction is changed to one of the > + canonical sequences permitted by the architecture for exception return. > Where > + possible the function itself will make the necessary "lr" adjustments so > that > + the "preferred return address" is selected. > + > + Unfortunately the compiler is unable to make this guarantee for nn "UNDEF" > + handler, where the offset from "lr" to the preferred return address > depends on > + the execution state of the code which generated the exception. In this case > + a sequence equivalent to "movs pc, lr" will be used. > + > Extensions for Static Analysis > ============================== > > > Modified: cfe/trunk/include/clang/Basic/Attr.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=191769&r1=191768&r2=191769&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/Attr.td (original) > +++ cfe/trunk/include/clang/Basic/Attr.td Tue Oct 1 09:34:25 2013 > @@ -210,6 +210,14 @@ def Annotate : InheritableParamAttr { > let Args = [StringArgument<"Annotation">]; > } > > +def ARMInterrupt : InheritableAttr, TargetSpecificAttr { > + let Spellings = [GNU<"interrupt">]; > + let Args = [EnumArgument<"Interrupt", "InterruptType", > + ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], > + ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", > "Generic"], > + 1>]; > +} > + > def AsmLabel : InheritableAttr { > let Spellings = []; > let Args = [StringArgument<"Label">]; > > Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=191769&r1=191768&r2=191769&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Oct 1 09:34:25 2013 > @@ -3056,9 +3056,9 @@ public: > Env == "android" || Env == "androideabi"); > } > > -private: > ABIKind getABIKind() const { return Kind; } > > +private: > ABIArgInfo classifyReturnType(QualType RetTy) const; > ABIArgInfo classifyArgumentType(QualType RetTy, int *VFPRegs, > unsigned &AllocatedVFP, > @@ -3105,6 +3105,45 @@ public: > if (getABIInfo().isEABI()) return 88; > return TargetCodeGenInfo::getSizeOfUnwindException(); > } > + > + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, > + CodeGen::CodeGenModule &CGM) const { > + const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); > + if (!FD) > + return; > + > + const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>(); > + if (!Attr) > + return; > + > + const char *Kind; > + switch (Attr->getInterrupt()) { > + case ARMInterruptAttr::Generic: Kind = ""; break; > + case ARMInterruptAttr::IRQ: Kind = "IRQ"; break; > + case ARMInterruptAttr::FIQ: Kind = "FIQ"; break; > + case ARMInterruptAttr::SWI: Kind = "SWI"; break; > + case ARMInterruptAttr::ABORT: Kind = "ABORT"; break; > + case ARMInterruptAttr::UNDEF: Kind = "UNDEF"; break; > + } > + > + llvm::Function *Fn = cast<llvm::Function>(GV); > + > + Fn->addFnAttr("interrupt", Kind); > + > + if (cast<ARMABIInfo>(getABIInfo()).getABIKind() == ARMABIInfo::APCS) > + return; > + > + // AAPCS guarantees that sp will be 8-byte aligned on any public > interface, > + // however this is not necessarily true on taking any interrupt. Instruct > + // the backend to perform a realignment as part of the function prologue. > + llvm::AttrBuilder B; > + B.addStackAlignmentAttr(8); > + Fn->addAttributes(llvm::AttributeSet::FunctionIndex, > + llvm::AttributeSet::get(CGM.getLLVMContext(), > + > llvm::AttributeSet::FunctionIndex, > + B)); > + } > + > }; > > } > > Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=191769&r1=191768&r2=191769&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Oct 1 09:34:25 2013 > @@ -289,7 +289,7 @@ static bool checkFunctionOrMethodArgumen > /// literal. > bool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr, > unsigned ArgNum, StringRef &Str, > - SourceLocation *ArgLocation = 0) { > + SourceLocation *ArgLocation) { > // Look for identifiers. If we have one emit a hint to fix it to a literal. > if (Attr.isArgIdent(ArgNum)) { > IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum); > > Modified: cfe/trunk/lib/Sema/TargetAttributesSema.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=191769&r1=191768&r2=191769&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (original) > +++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Tue Oct 1 09:34:25 2013 > @@ -26,6 +26,50 @@ bool TargetAttributesSema::ProcessDeclAt > return false; > } > > +static void HandleARMInterruptAttr(Decl *d, > + const AttributeList &Attr, Sema &S) { > + // Check the attribute arguments. > + if (Attr.getNumArgs() > 1) { > + S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) > + << 1; > + return; > + } > + > + StringRef Str; > + SourceLocation ArgLoc; > + > + if (Attr.getNumArgs() == 0) > + Str = ""; > + else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc)) > + return; > + > + ARMInterruptAttr::InterruptType Kind; > + if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { > + S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) > + << Attr.getName() << Str << ArgLoc; > + return; > + } > + > + unsigned Index = Attr.getAttributeSpellingListIndex(); > + d->addAttr(::new (S.Context) > + ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index)); > +} > + > +namespace { > + class ARMAttributesSema : public TargetAttributesSema { > + public: > + ARMAttributesSema() { } > + bool ProcessDeclAttribute(Scope *scope, Decl *D, > + const AttributeList &Attr, Sema &S) const { > + if (Attr.getName()->getName() == "interrupt") { > + HandleARMInterruptAttr(D, Attr, S); > + return true; > + } > + return false; > + } > + }; > +} > + > static void HandleMSP430InterruptAttr(Decl *d, > const AttributeList &Attr, Sema &S) { > // Check the attribute arguments. > @@ -292,6 +336,9 @@ const TargetAttributesSema &Sema::getTar > > const llvm::Triple &Triple(Context.getTargetInfo().getTriple()); > switch (Triple.getArch()) { > + case llvm::Triple::arm: > + case llvm::Triple::thumb: > + return *(TheTargetAttributesSema = new ARMAttributesSema); > case llvm::Triple::msp430: > return *(TheTargetAttributesSema = new MSP430AttributesSema); > case llvm::Triple::x86: > > Added: cfe/trunk/test/CodeGen/arm-interrupt-attr.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-interrupt-attr.c?rev=191769&view=auto > ============================================================================== > --- cfe/trunk/test/CodeGen/arm-interrupt-attr.c (added) > +++ cfe/trunk/test/CodeGen/arm-interrupt-attr.c Tue Oct 1 09:34:25 2013 > @@ -0,0 +1,38 @@ > +// RUN: %clang_cc1 -triple thumb-apple-darwin -target-abi aapcs -target-cpu > cortex-m3 -emit-llvm -o - %s | FileCheck %s > +// RUN: %clang_cc1 -triple arm-apple-darwin -target-abi apcs-gnu -emit-llvm > -o - %s | FileCheck %s --check-prefix=CHECK-APCS > + > +__attribute__((interrupt)) void test_generic_interrupt() { > + // CHECK: define arm_aapcscc void @test_generic_interrupt() > [[GENERIC_ATTR:#[0-9]+]] > + > + // CHECK-APCS: define void @test_generic_interrupt() > [[GENERIC_ATTR:#[0-9]+]] > +} > + > +__attribute__((interrupt("IRQ"))) void test_irq_interrupt() { > + // CHECK: define arm_aapcscc void @test_irq_interrupt() > [[IRQ_ATTR:#[0-9]+]] > +} > + > +__attribute__((interrupt("FIQ"))) void test_fiq_interrupt() { > + // CHECK: define arm_aapcscc void @test_fiq_interrupt() > [[FIQ_ATTR:#[0-9]+]] > +} > + > +__attribute__((interrupt("SWI"))) void test_swi_interrupt() { > + // CHECK: define arm_aapcscc void @test_swi_interrupt() > [[SWI_ATTR:#[0-9]+]] > +} > + > +__attribute__((interrupt("ABORT"))) void test_abort_interrupt() { > + // CHECK: define arm_aapcscc void @test_abort_interrupt() > [[ABORT_ATTR:#[0-9]+]] > +} > + > + > +__attribute__((interrupt("UNDEF"))) void test_undef_interrupt() { > + // CHECK: define arm_aapcscc void @test_undef_interrupt() > [[UNDEF_ATTR:#[0-9]+]] > +} > + > +// CHECK: attributes [[GENERIC_ATTR]] = { nounwind alignstack=8 > {{"interrupt"[^=]}} > +// CHECK: attributes [[IRQ_ATTR]] = { nounwind alignstack=8 "interrupt"="IRQ" > +// CHECK: attributes [[FIQ_ATTR]] = { nounwind alignstack=8 "interrupt"="FIQ" > +// CHECK: attributes [[SWI_ATTR]] = { nounwind alignstack=8 "interrupt"="SWI" > +// CHECK: attributes [[ABORT_ATTR]] = { nounwind alignstack=8 > "interrupt"="ABORT" > +// CHECK: attributes [[UNDEF_ATTR]] = { nounwind alignstack=8 > "interrupt"="UNDEF" > + > +// CHECK-APCS: attributes [[GENERIC_ATTR]] = { nounwind "interrupt" > > Added: cfe/trunk/test/Sema/arm-interrupt-attr.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/arm-interrupt-attr.c?rev=191769&view=auto > ============================================================================== > --- cfe/trunk/test/Sema/arm-interrupt-attr.c (added) > +++ cfe/trunk/test/Sema/arm-interrupt-attr.c Tue Oct 1 09:34:25 2013 > @@ -0,0 +1,16 @@ > +// RUN: %clang_cc1 %s -triple arm-apple-darwin -verify -fsyntax-only > + > +__attribute__((interrupt(IRQ))) void foo() {} // expected-error > {{'interrupt' attribute requires a string}} > +__attribute__((interrupt("irq"))) void foo1() {} // expected-warning > {{'interrupt' attribute argument not supported: irq}} > + > +__attribute__((interrupt("IRQ", 1))) void foo2() {} // expected-error > {{attribute takes no more than 1 argument}} > + > +__attribute__((interrupt("IRQ"))) void foo3() {} > +__attribute__((interrupt("FIQ"))) void foo4() {} > +__attribute__((interrupt("SWI"))) void foo5() {} > +__attribute__((interrupt("ABORT"))) void foo6() {} > +__attribute__((interrupt("UNDEF"))) void foo7() {} > + > +__attribute__((interrupt)) void foo8() {} > +__attribute__((interrupt())) void foo9() {} > +__attribute__((interrupt(""))) void foo10() {} > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
