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