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 "TargetAttributesSema.h" 162d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 1782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "clang/Basic/TargetInfo.h" 18384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 1982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "llvm/ADT/Triple.h" 2082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 2182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovusing namespace clang; 2282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 2382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton KorobeynikovTargetAttributesSema::~TargetAttributesSema() {} 2482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovbool TargetAttributesSema::ProcessDeclAttribute(Scope *scope, Decl *D, 2582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const AttributeList &Attr, Sema &S) const { 2682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return false; 2782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov} 2882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 2982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovstatic void HandleMSP430InterruptAttr(Decl *d, 3082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const AttributeList &Attr, Sema &S) { 3182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Check the attribute arguments. 3282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (Attr.getNumArgs() != 1) { 3382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return; 3582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 3682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 3782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // FIXME: Check for decl - it should be void ()(void). 3882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 3982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 4082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov llvm::APSInt NumParams(32); 4182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 4282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 4382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov << "interrupt" << NumParamsExpr->getSourceRange(); 4482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return; 4582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 4682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 4782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov unsigned Num = NumParams.getLimitedValue(255); 4882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if ((Num & 1) || Num > 30) { 4982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 5082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov << "interrupt" << (int)NumParams.getSExtValue() 5182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov << NumParamsExpr->getSourceRange(); 5282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return; 5382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 5482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 55cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num)); 56cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 5782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 5882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 5982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovnamespace { 6082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov class MSP430AttributesSema : public TargetAttributesSema { 6182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov public: 6282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov MSP430AttributesSema() { } 6382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov bool ProcessDeclAttribute(Scope *scope, Decl *D, 6482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const AttributeList &Attr, Sema &S) const { 6582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (Attr.getName()->getName() == "interrupt") { 6682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov HandleMSP430InterruptAttr(D, Attr, S); 6782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return true; 6882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 6982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return false; 7082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 7182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov }; 7282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov} 7382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 74276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peckstatic void HandleMBlazeInterruptHandlerAttr(Decl *d, const AttributeList &Attr, 75276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck Sema &S) { 76276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck // Check the attribute arguments. 77276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck if (Attr.getNumArgs() != 0) { 78276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 79276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck return; 80276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck } 81276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck 82276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck // FIXME: Check for decl - it should be void ()(void). 83276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck 84276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck d->addAttr(::new (S.Context) MBlazeInterruptHandlerAttr(Attr.getLoc(), 85276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck S.Context)); 86276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 87276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck} 88276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck 89276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peckstatic void HandleMBlazeSaveVolatilesAttr(Decl *d, const AttributeList &Attr, 90276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck Sema &S) { 91276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck // Check the attribute arguments. 92276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck if (Attr.getNumArgs() != 0) { 93276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 94276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck return; 95276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck } 96276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck 97276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck // FIXME: Check for decl - it should be void ()(void). 98276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck 99276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck d->addAttr(::new (S.Context) MBlazeSaveVolatilesAttr(Attr.getLoc(), 100276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck S.Context)); 101276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 102276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck} 103276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck 104276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck 105276fdf408050d205f3a7f34c1e788224a67d2098Wesley Pecknamespace { 106276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck class MBlazeAttributesSema : public TargetAttributesSema { 107276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck public: 108276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck MBlazeAttributesSema() { } 109276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck bool ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr, 110276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck Sema &S) const { 111276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck if (Attr.getName()->getName() == "interrupt_handler") { 112276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck HandleMBlazeInterruptHandlerAttr(D, Attr, S); 113276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck return true; 114276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck } else if (Attr.getName()->getName() == "save_volatiles") { 115276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck HandleMBlazeSaveVolatilesAttr(D, Attr, S); 116276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck return true; 117276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck } 118276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck return false; 119276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck } 120276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck }; 121276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck} 122276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck 1235a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davisstatic void HandleX86ForceAlignArgPointerAttr(Decl *D, 1245a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis const AttributeList& Attr, 1255a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis Sema &S) { 1265a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis // Check the attribute arguments. 1275a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis if (Attr.getNumArgs() != 0) { 1285a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1295a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return; 1305a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis } 1315a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 132ab44216009dbdaa9a3b26f541ead13e85f6e39b3Charles Davis // If we try to apply it to a function pointer, don't warn, but don't 133ab44216009dbdaa9a3b26f541ead13e85f6e39b3Charles Davis // do anything, either. It doesn't matter anyway, because there's nothing 134ab44216009dbdaa9a3b26f541ead13e85f6e39b3Charles Davis // special about calling a force_align_arg_pointer function. 135beaf5edfb22dd36b3d0e526291fd3a074404dd3eCharles Davis ValueDecl *VD = dyn_cast<ValueDecl>(D); 136ab44216009dbdaa9a3b26f541ead13e85f6e39b3Charles Davis if (VD && VD->getType()->isFunctionPointerType()) 1375a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return; 138beaf5edfb22dd36b3d0e526291fd3a074404dd3eCharles Davis // Also don't warn on function pointer typedefs. 139162e1c1b487352434552147967c3dd296ebee2f7Richard Smith TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 140e01c063874fa762abfba03b920bca16e1a1f10b4Charles Davis if (TD && (TD->getUnderlyingType()->isFunctionPointerType() || 141e01c063874fa762abfba03b920bca16e1a1f10b4Charles Davis TD->getUnderlyingType()->isFunctionType())) 142beaf5edfb22dd36b3d0e526291fd3a074404dd3eCharles Davis return; 1435a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis // Attribute can only be applied to function types. 1449c00be5527d83dd9dc2073652ffe6ded8f408402Charles Davis if (!isa<FunctionDecl>(D)) { 1455a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1465a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis << Attr.getName() << /* function */0; 1475a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return; 1485a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis } 1495a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 150768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getRange(), 151768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis S.Context)); 1525a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis} 1535a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 154f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 155f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // check the attribute arguments. 156f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (Attr.getNumArgs() != 0) { 157f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 158f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 159f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 160f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 161f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // Attribute can be applied only to functions or variables. 162f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (isa<VarDecl>(D)) { 163cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context)); 164f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 165f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 166f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 167f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 168f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (!FD) { 169240670c8f88a0062a76c2f15431341dd0406692fTed Kremenek // Apparently Visual C++ thinks it is okay to not emit a warning 170240670c8f88a0062a76c2f15431341dd0406692fTed Kremenek // in this case, so only emit a warning when -fms-extensions is not 171240670c8f88a0062a76c2f15431341dd0406692fTed Kremenek // specified. 17262ec1f2fd7368542bb926c04797fb07023547694Francois Pichet if (!S.getLangOptions().MicrosoftExt) 173240670c8f88a0062a76c2f15431341dd0406692fTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 174240670c8f88a0062a76c2f15431341dd0406692fTed Kremenek << Attr.getName() << 2 /*variable and function*/; 175f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 176f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 177f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 178f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // Currently, the dllimport attribute is ignored for inlined functions. 179f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // Warning is emitted. 180f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (FD->isInlineSpecified()) { 181f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 182f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 183f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 184f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 185f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // The attribute is also overridden by a subsequent declaration as dllexport. 186f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // Warning is emitted. 187f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 188f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis nextAttr = nextAttr->getNext()) { 189f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (nextAttr->getKind() == AttributeList::AT_dllexport) { 190f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 191f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 192f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 193f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 194f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 195f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (D->getAttr<DLLExportAttr>()) { 196f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 197f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 198f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 199f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 200cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context)); 201f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 202f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 203f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 204f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // check the attribute arguments. 205f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (Attr.getNumArgs() != 0) { 206f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 207f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 208f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 209f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 210f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // Attribute can be applied only to functions or variables. 211f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (isa<VarDecl>(D)) { 212cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context)); 213f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 214f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 215f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 216f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 217f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (!FD) { 218f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 219f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis << Attr.getName() << 2 /*variable and function*/; 220f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 221f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 222f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 223f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // Currently, the dllexport attribute is ignored for inlined functions, unless 224f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // the -fkeep-inline-functions flag has been used. Warning is emitted; 225f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (FD->isInlineSpecified()) { 226f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // FIXME: ... unless the -fkeep-inline-functions flag has been used. 227f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 228f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return; 229f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 230f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 231cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context)); 232f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 233f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 2345a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davisnamespace { 2355a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis class X86AttributesSema : public TargetAttributesSema { 2365a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis public: 2375a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis X86AttributesSema() { } 2385a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis bool ProcessDeclAttribute(Scope *scope, Decl *D, 2395a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis const AttributeList &Attr, Sema &S) const { 240bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor const llvm::Triple &Triple(S.Context.getTargetInfo().getTriple()); 241f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (Triple.getOS() == llvm::Triple::Win32 || 2420aa205765aec0aa5eed672f8e3cade543372edcdNAKAMURA Takumi Triple.getOS() == llvm::Triple::MinGW32) { 243f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis switch (Attr.getKind()) { 244f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis case AttributeList::AT_dllimport: HandleDLLImportAttr(D, Attr, S); 245f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return true; 246f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis case AttributeList::AT_dllexport: HandleDLLExportAttr(D, Attr, S); 247f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return true; 248f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis default: break; 249f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 250f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis } 2519afbfbe71c8e69e2643d468a041473d07d2635d4Eli Friedman if (Triple.getArch() != llvm::Triple::x86_64 && 252f2cee5cbdaf6fc017ae35cc8ecabc3b607a5f7e4Benjamin Kramer (Attr.getName()->getName() == "force_align_arg_pointer" || 253f2cee5cbdaf6fc017ae35cc8ecabc3b607a5f7e4Benjamin Kramer Attr.getName()->getName() == "__force_align_arg_pointer__")) { 2545a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis HandleX86ForceAlignArgPointerAttr(D, Attr, S); 2555a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return true; 2565a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis } 2575a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return false; 2585a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis } 2595a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis }; 2605a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis} 2615a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 26282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikovconst TargetAttributesSema &Sema::getTargetAttributesSema() const { 26382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (TheTargetAttributesSema) 26482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return *TheTargetAttributesSema; 26582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 266bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor const llvm::Triple &Triple(Context.getTargetInfo().getTriple()); 26782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov switch (Triple.getArch()) { 26882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov case llvm::Triple::msp430: 26982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov return *(TheTargetAttributesSema = new MSP430AttributesSema); 270276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck case llvm::Triple::mblaze: 271276fdf408050d205f3a7f34c1e788224a67d2098Wesley Peck return *(TheTargetAttributesSema = new MBlazeAttributesSema); 2725a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis case llvm::Triple::x86: 2739afbfbe71c8e69e2643d468a041473d07d2635d4Eli Friedman case llvm::Triple::x86_64: 2745a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis return *(TheTargetAttributesSema = new X86AttributesSema); 2759afbfbe71c8e69e2643d468a041473d07d2635d4Eli Friedman default: 2769afbfbe71c8e69e2643d468a041473d07d2635d4Eli Friedman return *(TheTargetAttributesSema = new TargetAttributesSema); 27782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov } 27882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov} 279