summaryrefslogtreecommitdiffstats
path: root/lib/Parse/AttributeList.cpp
blob: 0170a0671db7f83216c15f9b4d7b469895ee0f34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//===--- AttributeList.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the AttributeList class implementation
//
//===----------------------------------------------------------------------===//

#include "clang/Parse/AttributeList.h"
#include "clang/Basic/IdentifierTable.h"
using namespace clang;

AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
                             IdentifierInfo *pName, SourceLocation pLoc,
                             ActionBase::ExprTy **ExprList, unsigned numArgs,
                             AttributeList *n)
  : AttrName(aName), AttrLoc(aLoc), ParmName(pName), ParmLoc(pLoc),
    NumArgs(numArgs), Next(n) {
  
  if (numArgs == 0)
    Args = 0;
  else {
    Args = new ActionBase::ExprTy*[numArgs];
    memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
  }
}

AttributeList::~AttributeList() {
  if (Args) {
    // FIXME: before we delete the vector, we need to make sure the Expr's 
    // have been deleted. Since ActionBase::ExprTy is "void", we are dependent
    // on the actions module for actually freeing the memory. The specific
    // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType, 
    // ParseField, ParseTag. Once these routines have freed the expression, 
    // they should zero out the Args slot (to indicate the memory has been 
    // freed). If any element of the vector is non-null, we should assert.
    delete [] Args;
  }
  delete Next;
}

AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
  const char *Str = Name->getName();
  unsigned Len = Name->getLength();

  // Normalize the attribute name, __foo__ becomes foo.
  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
    Str += 2;
    Len -= 4;
  }
  
  // FIXME: Hand generating this is neither smart nor efficient.
  switch (Len) {
  case 4:
    if (!memcmp(Str, "weak", 4)) return AT_weak;
    if (!memcmp(Str, "pure", 4)) return AT_pure;
    if (!memcmp(Str, "mode", 4)) return AT_mode;
    if (!memcmp(Str, "used", 4)) return AT_used;
    break;
  case 5:
    if (!memcmp(Str, "alias", 5)) return AT_alias;
    if (!memcmp(Str, "const", 5)) return AT_const;
    break;
  case 6:
    if (!memcmp(Str, "packed", 6)) return AT_packed;
    if (!memcmp(Str, "malloc", 6)) return IgnoredAttribute; // FIXME: noalias.
    if (!memcmp(Str, "format", 6)) return AT_format;
    if (!memcmp(Str, "unused", 6)) return AT_unused;
    if (!memcmp(Str, "blocks", 6)) return AT_blocks;
    break;
  case 7:
    if (!memcmp(Str, "aligned", 7)) return AT_aligned;
    if (!memcmp(Str, "cleanup", 7)) return AT_cleanup;
    if (!memcmp(Str, "nodebug", 7)) return AT_nodebug;
    if (!memcmp(Str, "nonnull", 7)) return AT_nonnull;
    if (!memcmp(Str, "nothrow", 7)) return AT_nothrow;
    if (!memcmp(Str, "objc_gc", 7)) return AT_objc_gc;
    if (!memcmp(Str, "regparm", 7)) return AT_regparm;
    if (!memcmp(Str, "section", 7)) return AT_section;
    if (!memcmp(Str, "stdcall", 7)) return AT_stdcall;
    break;
  case 8:
    if (!memcmp(Str, "annotate", 8)) return AT_annotate;
    if (!memcmp(Str, "noreturn", 8)) return AT_noreturn;
    if (!memcmp(Str, "noinline", 8)) return AT_noinline;
    if (!memcmp(Str, "fastcall", 8)) return AT_fastcall;
    if (!memcmp(Str, "iboutlet", 8)) return AT_IBOutlet;
    if (!memcmp(Str, "sentinel", 8)) return AT_sentinel;
    if (!memcmp(Str, "NSObject", 8)) return AT_nsobject;
    break;
  case 9:
    if (!memcmp(Str, "dllimport", 9)) return AT_dllimport;
    if (!memcmp(Str, "dllexport", 9)) return AT_dllexport;
    if (!memcmp(Str, "may_alias", 9)) return IgnoredAttribute; // FIXME: TBAA
    break;
  case 10:
    if (!memcmp(Str, "deprecated", 10)) return AT_deprecated;
    if (!memcmp(Str, "visibility", 10)) return AT_visibility;
    if (!memcmp(Str, "destructor", 10)) return AT_destructor;
    if (!memcmp(Str, "format_arg", 10)) return AT_format_arg; 
    if (!memcmp(Str, "gnu_inline", 10)) return AT_gnu_inline;
    break;
  case 11:
    if (!memcmp(Str, "weak_import", 11)) return AT_weak_import;
    if (!memcmp(Str, "vector_size", 11)) return AT_vector_size;
    if (!memcmp(Str, "constructor", 11)) return AT_constructor;
    if (!memcmp(Str, "unavailable", 11)) return AT_unavailable;
    break;
  case 12:
    if (!memcmp(Str, "overloadable", 12)) return AT_overloadable;
    break;
  case 13:
    if (!memcmp(Str, "address_space", 13)) return AT_address_space;
    if (!memcmp(Str, "always_inline", 13)) return AT_always_inline;
    break;
  case 14:
    if (!memcmp(Str, "objc_exception", 14)) return AT_objc_exception;
    break;
  case 15:
    if (!memcmp(Str, "ext_vector_type", 15)) return AT_ext_vector_type;
    break;
  case 17:
    if (!memcmp(Str, "transparent_union", 17)) return AT_transparent_union;
    if (!memcmp(Str, "analyzer_noreturn", 17)) return AT_analyzer_noreturn;
    break;
  case 18:
    if (!memcmp(Str, "warn_unused_result", 18)) return AT_warn_unused_result;
    break;
  case 19:
    if (!memcmp(Str, "ns_returns_retained", 19)) return AT_ns_returns_retained;
    if (!memcmp(Str, "cf_returns_retained", 19)) return AT_cf_returns_retained;
    break;            
  case 22:
    if (!memcmp(Str, "no_instrument_function", 22))
      return AT_no_instrument_function;
    break;
  }  
  return UnknownAttribute;
}
OpenPOWER on IntegriCloud