blob: 7c19bf6e4fd4a5f2f9af942c7e3515f1e32774b1 [file] [log] [blame]
Shih-wei Liaof8fd82b2010-02-10 11:10:31 -08001//===-- TargetAttributesSema.cpp - Encapsulate target attributes-*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains semantic analysis implementation for target-specific
11// attributes.
12//
13//===----------------------------------------------------------------------===//
14
15#include "Sema.h"
16#include "TargetAttributesSema.h"
17#include "clang/Basic/TargetInfo.h"
18#include "llvm/ADT/Triple.h"
19
20using namespace clang;
21
22TargetAttributesSema::~TargetAttributesSema() {}
23bool TargetAttributesSema::ProcessDeclAttribute(Scope *scope, Decl *D,
24 const AttributeList &Attr, Sema &S) const {
25 return false;
26}
27
28static void HandleMSP430InterruptAttr(Decl *d,
29 const AttributeList &Attr, Sema &S) {
30 // Check the attribute arguments.
31 if (Attr.getNumArgs() != 1) {
32 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
33 return;
34 }
35
36 // FIXME: Check for decl - it should be void ()(void).
37
38 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
39 llvm::APSInt NumParams(32);
40 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
41 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
42 << "interrupt" << NumParamsExpr->getSourceRange();
43 return;
44 }
45
46 unsigned Num = NumParams.getLimitedValue(255);
47 if ((Num & 1) || Num > 30) {
48 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
49 << "interrupt" << (int)NumParams.getSExtValue()
50 << NumParamsExpr->getSourceRange();
51 return;
52 }
53
54 d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
55 d->addAttr(::new (S.Context) UsedAttr());
56 }
57
58namespace {
59 class MSP430AttributesSema : public TargetAttributesSema {
60 public:
61 MSP430AttributesSema() { }
62 bool ProcessDeclAttribute(Scope *scope, Decl *D,
63 const AttributeList &Attr, Sema &S) const {
64 if (Attr.getName()->getName() == "interrupt") {
65 HandleMSP430InterruptAttr(D, Attr, S);
66 return true;
67 }
68 return false;
69 }
70 };
71}
72
73const TargetAttributesSema &Sema::getTargetAttributesSema() const {
74 if (TheTargetAttributesSema)
75 return *TheTargetAttributesSema;
76
77 const llvm::Triple &Triple(Context.Target.getTriple());
78 switch (Triple.getArch()) {
79 default:
80 return *(TheTargetAttributesSema = new TargetAttributesSema);
81
82 case llvm::Triple::msp430:
83 return *(TheTargetAttributesSema = new MSP430AttributesSema);
84 }
85}
86