TargetAttributesSema.cpp revision 9c00be5527d83dd9dc2073652ffe6ded8f408402
182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov//===-- TargetAttributesSema.cpp - Encapsulate target attributes-*- C++ -*-===// 282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// 382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// The LLVM Compiler Infrastructure 482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// 582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// This file is distributed under the University of Illinois Open Source 682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// License. See LICENSE.TXT for details. 782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// 882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov//===----------------------------------------------------------------------===// 982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// 1082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// This file contains semantic analysis implementation for target-specific 1182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// attributes. 1282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov// 1382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov//===----------------------------------------------------------------------===// 1482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "Sema.h" 1682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h" 1782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "clang/Basic/TargetInfo.h" 1882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "llvm/ADT/Triple.h" 1982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 2082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovusing namespace clang; 2182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 2282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton KorobeynikovTargetAttributesSema::~TargetAttributesSema() {} 2382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovbool TargetAttributesSema::ProcessDeclAttribute(Scope *scope, Decl *D, 2482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const AttributeList &Attr, Sema &S) const { 2582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return false; 2682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov} 2782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 2882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovstatic void HandleMSP430InterruptAttr(Decl *d, 2982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const AttributeList &Attr, Sema &S) { 3082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Check the attribute arguments. 3182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (Attr.getNumArgs() != 1) { 3282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return; 3482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 3582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 3682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // FIXME: Check for decl - it should be void ()(void). 3782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 3882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 3982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov llvm::APSInt NumParams(32); 4082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 4182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 4282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov << "interrupt" << NumParamsExpr->getSourceRange(); 4382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return; 4482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 4582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 4682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov unsigned Num = NumParams.getLimitedValue(255); 4782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if ((Num & 1) || Num > 30) { 4882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 4982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov << "interrupt" << (int)NumParams.getSExtValue() 5082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov << NumParamsExpr->getSourceRange(); 5182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return; 5282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 5382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 5482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov d->addAttr(::new (S.Context) MSP430InterruptAttr(Num)); 5582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov d->addAttr(::new (S.Context) UsedAttr()); 5682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 5782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 5882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovnamespace { 5982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov class MSP430AttributesSema : public TargetAttributesSema { 6082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov public: 6182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov MSP430AttributesSema() { } 6282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov bool ProcessDeclAttribute(Scope *scope, Decl *D, 6382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const AttributeList &Attr, Sema &S) const { 6482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (Attr.getName()->getName() == "interrupt") { 6582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov HandleMSP430InterruptAttr(D, Attr, S); 6682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return true; 6782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 6882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return false; 6982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 7082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov }; 7182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov} 7282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 735a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davisstatic void HandleX86ForceAlignArgPointerAttr(Decl *D, 745a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis const AttributeList& Attr, 755a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis Sema &S) { 765a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis // Check the attribute arguments. 775a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis if (Attr.getNumArgs() != 0) { 785a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 795a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return; 805a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis } 815a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 825a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis // If we try to apply it to a function pointer, don't warn, but don't 835a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis // do anything, either. It doesn't matter anyway, because there's nothing 845a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis // special about calling a force_align_arg_pointer function. 855a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis ValueDecl* VD = dyn_cast<ValueDecl>(D); 869c00be5527d83dd9dc2073652ffe6ded8f408402Charles Davis if (VD && VD->getType()->isFunctionPointerType()) 875a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return; 885a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis // Attribute can only be applied to function types. 899c00be5527d83dd9dc2073652ffe6ded8f408402Charles Davis if (!isa<FunctionDecl>(D)) { 905a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 915a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis << Attr.getName() << /* function */0; 925a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return; 935a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis } 945a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 955a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr()); 965a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis} 975a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 985a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davisnamespace { 995a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis class X86AttributesSema : public TargetAttributesSema { 1005a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis public: 1015a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis X86AttributesSema() { } 1025a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis bool ProcessDeclAttribute(Scope *scope, Decl *D, 1035a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis const AttributeList &Attr, Sema &S) const { 1045a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis if (Attr.getName()->getName() == "force_align_arg_pointer") { 1055a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis HandleX86ForceAlignArgPointerAttr(D, Attr, S); 1065a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return true; 1075a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis } 1085a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return false; 1095a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis } 1105a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis }; 1115a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis} 1125a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 11382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovconst TargetAttributesSema &Sema::getTargetAttributesSema() const { 11482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (TheTargetAttributesSema) 11582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return *TheTargetAttributesSema; 11682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 11782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const llvm::Triple &Triple(Context.Target.getTriple()); 11882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov switch (Triple.getArch()) { 11982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov default: 12082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return *(TheTargetAttributesSema = new TargetAttributesSema); 12182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 12282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov case llvm::Triple::msp430: 12382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return *(TheTargetAttributesSema = new MSP430AttributesSema); 1245a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis case llvm::Triple::x86: 1255a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return *(TheTargetAttributesSema = new X86AttributesSema); 12682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 12782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov} 12882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 129