~ubuntu-branches/debian/sid/clamav/sid

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/utils/TableGen/ClangAttrEmitter.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman, Sebastian Andrzej Siewior, Andreas Cadhalpun, Scott Kitterman, Javier Fernández-Sanguino
  • Date: 2015-01-28 00:25:13 UTC
  • mfrom: (1.3.15)
  • Revision ID: package-import@ubuntu.com-20150128002513-4apvvjyr1213db8x
Tags: 0.98.6+dfsg-1
[ Sebastian Andrzej Siewior ]
* update "fix-ssize_t-size_t-off_t-printf-modifier", include of misc.h was
  missing but was pulled in via the systemd patch.
* Don't leak return codes from libmspack to clamav API. (Closes: #774686).

[ Andreas Cadhalpun ]
* Add patch to avoid emitting incremental progress messages when not
  outputting to a terminal. (Closes: #767350)
* Update lintian-overrides for unused-file-paragraph-in-dep5-copyright.
* clamav-base.postinst: always chown /var/log/clamav and /var/lib/clamav
  to clamav:clamav, not only on fresh installations. (Closes: #775400)
* Adapt the clamav-daemon and clamav-freshclam logrotate scripts,
  so that they correctly work under systemd.
* Move the PidFile variable from the clamd/freshclam configuration files
  to the init scripts. This makes the init scripts more robust against
  misconfiguration and avoids error messages with systemd. (Closes: #767353)
* debian/copyright: drop files from Files-Excluded only present in github
  tarballs
* Drop Workaround-a-bug-in-libc-on-Hurd.patch, because hurd got fixed.
  (see #752237)
* debian/rules: Remove useless --with-system-tommath --without-included-ltdl
  configure options.

[ Scott Kitterman ]
* Stop stripping llvm when repacking the tarball as the system llvm on some
  releases is too old to use
* New upstream bugfix release
  - Library shared object revisions.
  - Includes a patch from Sebastian Andrzej Siewior making ClamAV pid files
    compatible with systemd.
  - Fix a heap out of bounds condition with crafted Yoda's crypter files.
    This issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted mew packer files. This
    issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted upx packer files. This
    issue was discovered by Kevin Szkudlapski of Quarkslab.
  - Fix a heap out of bounds condition with crafted upack packer files. This
    issue was discovered by Sebastian Andrzej Siewior. CVE-2014-9328.
  - Compensate a crash due to incorrect compiler optimization when handling
    crafted petite packer files. This issue was discovered by Sebastian
    Andrzej Siewior.
* Update lintian override for embedded zlib to match new so version

[ Javier Fernández-Sanguino ]
* Updated Spanish Debconf template translation (Closes: #773563)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- 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
// These tablegen backends emit Clang attribute processing code
 
11
//
 
12
//===----------------------------------------------------------------------===//
 
13
 
 
14
#include "ClangAttrEmitter.h"
 
15
#include "Record.h"
 
16
#include "llvm/ADT/StringSwitch.h"
 
17
#include <algorithm>
 
18
#include <cctype>
 
19
 
 
20
using namespace llvm;
 
21
 
 
22
static const std::vector<StringRef> getValueAsListOfStrings(Record &R,
 
23
                                                            StringRef FieldName) {
 
24
  ListInit *List = R.getValueAsListInit(FieldName);
 
25
  assert (List && "Got a null ListInit");
 
26
 
 
27
  std::vector<StringRef> Strings;
 
28
  Strings.reserve(List->getSize());
 
29
 
 
30
  for (ListInit::iterator i = List->begin(), e = List->end(); i != e; ++i) {
 
31
    assert(*i && "Got a null element in a ListInit");
 
32
    if (StringInit *S = dynamic_cast<StringInit *>(*i))
 
33
      Strings.push_back(S->getValue());
 
34
    else if (CodeInit *C = dynamic_cast<CodeInit *>(*i))
 
35
      Strings.push_back(C->getValue());
 
36
    else
 
37
      assert(false && "Got a non-string, non-code element in a ListInit");
 
38
  }
 
39
 
 
40
  return Strings;
 
41
}
 
42
 
 
43
std::string ReadPCHRecord(StringRef type) {
 
44
  return StringSwitch<std::string>(type)
 
45
    .EndsWith("Decl *", "cast_or_null<" + std::string(type, 0, type.size()-1) +
 
46
              ">(GetDecl(Record[Idx++]))")
 
47
    .Case("QualType", "ReadTypeRecord(Idx++)")
 
48
    .Default("Record[Idx++]");
 
49
}
 
50
 
 
51
// Assumes that the way to get the value is SA->getname()
 
52
std::string WritePCHRecord(StringRef type, StringRef name) {
 
53
  return StringSwitch<std::string>(type)
 
54
    .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
 
55
                        ", Record);\n")
 
56
    .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n")
 
57
    .Default("Record.push_back(" + std::string(name) + ");\n");
 
58
}
 
59
 
 
60
namespace {
 
61
  class Argument {
 
62
    std::string lowerName, upperName;
 
63
    StringRef attrName;
 
64
 
 
65
  public:
 
66
    Argument(Record &Arg, StringRef Attr)
 
67
      : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
 
68
        attrName(Attr) {
 
69
      if (!lowerName.empty()) {
 
70
        lowerName[0] = std::tolower(lowerName[0]);
 
71
        upperName[0] = std::toupper(upperName[0]);
 
72
      }
 
73
    }
 
74
    virtual ~Argument() {}
 
75
 
 
76
    StringRef getLowerName() const { return lowerName; }
 
77
    StringRef getUpperName() const { return upperName; }
 
78
    StringRef getAttrName() const { return attrName; }
 
79
 
 
80
    // These functions print the argument contents formatted in different ways.
 
81
    virtual void writeAccessors(raw_ostream &OS) const = 0;
 
82
    virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
 
83
    virtual void writeCloneArgs(raw_ostream &OS) const = 0;
 
84
    virtual void writeCtorBody(raw_ostream &OS) const {}
 
85
    virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
 
86
    virtual void writeCtorParameters(raw_ostream &OS) const = 0;
 
87
    virtual void writeDeclarations(raw_ostream &OS) const = 0;
 
88
    virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
 
89
    virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
 
90
    virtual void writePCHWrite(raw_ostream &OS) const = 0;
 
91
  };
 
92
 
 
93
  class SimpleArgument : public Argument {
 
94
    std::string type;
 
95
 
 
96
  public:
 
97
    SimpleArgument(Record &Arg, StringRef Attr, std::string T)
 
98
      : Argument(Arg, Attr), type(T)
 
99
    {}
 
100
 
 
101
    void writeAccessors(raw_ostream &OS) const {
 
102
      OS << "  " << type << " get" << getUpperName() << "() const {\n";
 
103
      OS << "    return " << getLowerName() << ";\n";
 
104
      OS << "  }";
 
105
    }
 
106
    void writeCloneArgs(raw_ostream &OS) const {
 
107
      OS << getLowerName();
 
108
    }
 
109
    void writeCtorInitializers(raw_ostream &OS) const {
 
110
      OS << getLowerName() << "(" << getUpperName() << ")";
 
111
    }
 
112
    void writeCtorParameters(raw_ostream &OS) const {
 
113
      OS << type << " " << getUpperName();
 
114
    }
 
115
    void writeDeclarations(raw_ostream &OS) const {
 
116
      OS << type << " " << getLowerName() << ";";
 
117
    }
 
118
    void writePCHReadDecls(raw_ostream &OS) const {
 
119
      std::string read = ReadPCHRecord(type);
 
120
      OS << "    " << type << " " << getLowerName() << " = " << read << ";\n";
 
121
    }
 
122
    void writePCHReadArgs(raw_ostream &OS) const {
 
123
      OS << getLowerName();
 
124
    }
 
125
    void writePCHWrite(raw_ostream &OS) const {
 
126
      OS << "    " << WritePCHRecord(type, "SA->get" +
 
127
                                           std::string(getUpperName()) + "()");
 
128
    }
 
129
  };
 
130
 
 
131
  class StringArgument : public Argument {
 
132
  public:
 
133
    StringArgument(Record &Arg, StringRef Attr)
 
134
      : Argument(Arg, Attr)
 
135
    {}
 
136
 
 
137
    void writeAccessors(raw_ostream &OS) const {
 
138
      OS << "  llvm::StringRef get" << getUpperName() << "() const {\n";
 
139
      OS << "    return llvm::StringRef(" << getLowerName() << ", "
 
140
         << getLowerName() << "Length);\n";
 
141
      OS << "  }\n";
 
142
      OS << "  unsigned get" << getUpperName() << "Length() const {\n";
 
143
      OS << "    return " << getLowerName() << "Length;\n";
 
144
      OS << "  }\n";
 
145
      OS << "  void set" << getUpperName()
 
146
         << "(ASTContext &C, llvm::StringRef S) {\n";
 
147
      OS << "    " << getLowerName() << "Length = S.size();\n";
 
148
      OS << "    this->" << getLowerName() << " = new (C, 1) char ["
 
149
         << getLowerName() << "Length];\n";
 
150
      OS << "    std::memcpy(this->" << getLowerName() << ", S.data(), "
 
151
         << getLowerName() << "Length);\n";
 
152
      OS << "  }";
 
153
    }
 
154
    void writeCloneArgs(raw_ostream &OS) const {
 
155
      OS << "get" << getUpperName() << "()";
 
156
    }
 
157
    void writeCtorBody(raw_ostream &OS) const {
 
158
      OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
 
159
         << ".data(), " << getLowerName() << "Length);";
 
160
    }
 
161
    void writeCtorInitializers(raw_ostream &OS) const {
 
162
      OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
 
163
         << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
 
164
         << "Length])";
 
165
    }
 
166
    void writeCtorParameters(raw_ostream &OS) const {
 
167
      OS << "llvm::StringRef " << getUpperName();
 
168
    }
 
169
    void writeDeclarations(raw_ostream &OS) const {
 
170
      OS << "unsigned " << getLowerName() << "Length;\n";
 
171
      OS << "char *" << getLowerName() << ";";
 
172
    }
 
173
    void writePCHReadDecls(raw_ostream &OS) const {
 
174
      OS << "    std::string " << getLowerName() << "= ReadString(Record, Idx);\n";
 
175
    }
 
176
    void writePCHReadArgs(raw_ostream &OS) const {
 
177
      OS << getLowerName();
 
178
    }
 
179
    void writePCHWrite(raw_ostream &OS) const {
 
180
      OS << "    AddString(SA->get" << getUpperName() << "(), Record);\n";
 
181
    }
 
182
  };
 
183
 
 
184
  class AlignedArgument : public Argument {
 
185
  public:
 
186
    AlignedArgument(Record &Arg, StringRef Attr)
 
187
      : Argument(Arg, Attr)
 
188
    {}
 
189
 
 
190
    void writeAccessors(raw_ostream &OS) const {
 
191
      OS << "  bool is" << getUpperName() << "Dependent() const;\n";
 
192
 
 
193
      OS << "  unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
 
194
 
 
195
      OS << "  bool is" << getUpperName() << "Expr() const {\n";
 
196
      OS << "    return is" << getLowerName() << "Expr;\n";
 
197
      OS << "  }\n";
 
198
 
 
199
      OS << "  Expr *get" << getUpperName() << "Expr() const {\n";
 
200
      OS << "    assert(is" << getLowerName() << "Expr);\n";
 
201
      OS << "    return " << getLowerName() << "Expr;\n";
 
202
      OS << "  }\n";
 
203
 
 
204
      OS << "  TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
 
205
      OS << "    assert(!is" << getLowerName() << "Expr);\n";
 
206
      OS << "    return " << getLowerName() << "Type;\n";
 
207
      OS << "  }";
 
208
    }
 
209
    void writeAccessorDefinitions(raw_ostream &OS) const {
 
210
      OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
 
211
         << "Dependent() const {\n";
 
212
      OS << "  if (is" << getLowerName() << "Expr)\n";
 
213
      OS << "    return " << getLowerName() << "Expr && (" << getLowerName()
 
214
         << "Expr->isValueDependent() || " << getLowerName()
 
215
         << "Expr->isTypeDependent());\n"; 
 
216
      OS << "  else\n";
 
217
      OS << "    return " << getLowerName()
 
218
         << "Type->getType()->isDependentType();\n";
 
219
      OS << "}\n";
 
220
 
 
221
      // FIXME: Do not do the calculation here
 
222
      // FIXME: Handle types correctly
 
223
      // A null pointer means maximum alignment
 
224
      // FIXME: Load the platform-specific maximum alignment, rather than
 
225
      //        16, the x86 max.
 
226
      OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
 
227
         << "(ASTContext &Ctx) const {\n";
 
228
      OS << "  assert(!is" << getUpperName() << "Dependent());\n";
 
229
      OS << "  if (is" << getLowerName() << "Expr)\n";
 
230
      OS << "    return (" << getLowerName() << "Expr ? " << getLowerName()
 
231
         << "Expr->EvaluateAsInt(Ctx).getZExtValue() : 16)"
 
232
         << "* Ctx.getCharWidth();\n";
 
233
      OS << "  else\n";
 
234
      OS << "    return 0; // FIXME\n";
 
235
      OS << "}\n";
 
236
    }
 
237
    void writeCloneArgs(raw_ostream &OS) const {
 
238
      OS << "is" << getLowerName() << "Expr, is" << getLowerName()
 
239
         << "Expr ? static_cast<void*>(" << getLowerName()
 
240
         << "Expr) : " << getLowerName()
 
241
         << "Type";
 
242
    }
 
243
    void writeCtorBody(raw_ostream &OS) const {
 
244
      OS << "    if (is" << getLowerName() << "Expr)\n";
 
245
      OS << "       " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
 
246
         << getUpperName() << ");\n";
 
247
      OS << "    else\n";
 
248
      OS << "       " << getLowerName()
 
249
         << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
 
250
         << ");";
 
251
    }
 
252
    void writeCtorInitializers(raw_ostream &OS) const {
 
253
      OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
 
254
    }
 
255
    void writeCtorParameters(raw_ostream &OS) const {
 
256
      OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
 
257
    }
 
258
    void writeDeclarations(raw_ostream &OS) const {
 
259
      OS << "bool is" << getLowerName() << "Expr;\n";
 
260
      OS << "union {\n";
 
261
      OS << "Expr *" << getLowerName() << "Expr;\n";
 
262
      OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
 
263
      OS << "};";
 
264
    }
 
265
    void writePCHReadArgs(raw_ostream &OS) const {
 
266
      OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
 
267
    }
 
268
    void writePCHReadDecls(raw_ostream &OS) const {
 
269
      OS << "    bool is" << getLowerName() << "Expr = Record[Idx++];\n";
 
270
      OS << "    void *" << getLowerName() << "Ptr;\n";
 
271
      OS << "    if (is" << getLowerName() << "Expr)\n";
 
272
      OS << "      " << getLowerName() << "Ptr = ReadExpr(DeclsCursor);\n";
 
273
      OS << "    else\n";
 
274
      OS << "      " << getLowerName()
 
275
         << "Ptr = GetTypeSourceInfo(DeclsCursor, Record, Idx);\n";
 
276
    }
 
277
    void writePCHWrite(raw_ostream &OS) const {
 
278
      OS << "    Record.push_back(SA->is" << getUpperName() << "Expr());\n";
 
279
      OS << "    if (SA->is" << getUpperName() << "Expr())\n";
 
280
      OS << "      AddStmt(SA->get" << getUpperName() << "Expr());\n";
 
281
      OS << "    else\n";
 
282
      OS << "      AddTypeSourceInfo(SA->get" << getUpperName()
 
283
         << "Type(), Record);\n";
 
284
    }
 
285
  };
 
286
 
 
287
  class VariadicArgument : public Argument {
 
288
    std::string type;
 
289
 
 
290
  public:
 
291
    VariadicArgument(Record &Arg, StringRef Attr, std::string T)
 
292
      : Argument(Arg, Attr), type(T)
 
293
    {}
 
294
 
 
295
    std::string getType() const { return type; }
 
296
 
 
297
    void writeAccessors(raw_ostream &OS) const {
 
298
      OS << "  typedef " << type << "* " << getLowerName() << "_iterator;\n";
 
299
      OS << "  " << getLowerName() << "_iterator " << getLowerName()
 
300
         << "_begin() const {\n";
 
301
      OS << "    return " << getLowerName() << ";\n";
 
302
      OS << "  }\n";
 
303
      OS << "  " << getLowerName() << "_iterator " << getLowerName()
 
304
         << "_end() const {\n";
 
305
      OS << "    return " << getLowerName() << " + " << getLowerName()
 
306
         << "Size;\n";
 
307
      OS << "  }\n";
 
308
      OS << "  unsigned " << getLowerName() << "_size() const {\n"
 
309
         << "    return " << getLowerName() << "Size;\n;";
 
310
      OS << "  }";
 
311
    }
 
312
    void writeCloneArgs(raw_ostream &OS) const {
 
313
      OS << getLowerName() << ", " << getLowerName() << "Size";
 
314
    }
 
315
    void writeCtorBody(raw_ostream &OS) const {
 
316
      // FIXME: memcpy is not safe on non-trivial types.
 
317
      OS << "    std::memcpy(" << getLowerName() << ", " << getUpperName()
 
318
         << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
 
319
    }
 
320
    void writeCtorInitializers(raw_ostream &OS) const {
 
321
      OS << getLowerName() << "Size(" << getUpperName() << "Size), "
 
322
         << getLowerName() << "(new (Ctx, 16) " << getType() << "["
 
323
         << getLowerName() << "Size])";
 
324
    }
 
325
    void writeCtorParameters(raw_ostream &OS) const {
 
326
      OS << getType() << " *" << getUpperName() << ", unsigned "
 
327
         << getUpperName() << "Size";
 
328
    }
 
329
    void writeDeclarations(raw_ostream &OS) const {
 
330
      OS << "  unsigned " << getLowerName() << "Size;\n";
 
331
      OS << "  " << getType() << " *" << getLowerName() << ";";
 
332
    }
 
333
    void writePCHReadDecls(raw_ostream &OS) const {
 
334
      OS << "  unsigned " << getLowerName() << "Size = Record[Idx++];\n";
 
335
      OS << "  llvm::SmallVector<" << type << ", 4> " << getLowerName()
 
336
         << ";\n";
 
337
      OS << "  " << getLowerName() << ".reserve(" << getLowerName()
 
338
         << "Size);\n";
 
339
      OS << "  for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
 
340
      
 
341
      std::string read = ReadPCHRecord(type);
 
342
      OS << "    " << getLowerName() << ".push_back(" << read << ");\n";
 
343
    }
 
344
    void writePCHReadArgs(raw_ostream &OS) const {
 
345
      OS << getLowerName() << ".data(), " << getLowerName() << "Size";
 
346
    }
 
347
    void writePCHWrite(raw_ostream &OS) const{
 
348
      OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
 
349
      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
 
350
         << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
 
351
         << getLowerName() << "_end(); i != e; ++i)\n";
 
352
      OS << "      " << WritePCHRecord(type, "(*i)");
 
353
    }
 
354
  };
 
355
 
 
356
  class EnumArgument : public Argument {
 
357
    std::string type;
 
358
    std::vector<StringRef> values, enums;
 
359
  public:
 
360
    EnumArgument(Record &Arg, StringRef Attr)
 
361
      : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
 
362
        values(getValueAsListOfStrings(Arg, "Values")),
 
363
        enums(getValueAsListOfStrings(Arg, "Enums"))
 
364
    {}
 
365
 
 
366
    void writeAccessors(raw_ostream &OS) const {
 
367
      OS << "  " << type << " get" << getUpperName() << "() const {\n";
 
368
      OS << "    return " << getLowerName() << ";\n";
 
369
      OS << "  }";
 
370
    }
 
371
    void writeCloneArgs(raw_ostream &OS) const {
 
372
      OS << getLowerName();
 
373
    }
 
374
    void writeCtorInitializers(raw_ostream &OS) const {
 
375
      OS << getLowerName() << "(" << getUpperName() << ")";
 
376
    }
 
377
    void writeCtorParameters(raw_ostream &OS) const {
 
378
      OS << type << " " << getUpperName();
 
379
    }
 
380
    void writeDeclarations(raw_ostream &OS) const {
 
381
      // Calculate the various enum values
 
382
      std::vector<StringRef> uniques(enums);
 
383
      std::sort(uniques.begin(), uniques.end());
 
384
      uniques.erase(std::unique(uniques.begin(), uniques.end()),
 
385
                    uniques.end());
 
386
      // FIXME: Emit a proper error
 
387
      assert(!uniques.empty());
 
388
 
 
389
      std::vector<StringRef>::iterator i = uniques.begin(),
 
390
                                       e = uniques.end();
 
391
      // The last one needs to not have a comma.
 
392
      --e;
 
393
 
 
394
      OS << "public:\n";
 
395
      OS << "  enum " << type << " {\n";
 
396
      for (; i != e; ++i)
 
397
        OS << "    " << *i << ",\n";
 
398
      OS << "    " << *e << "\n";
 
399
      OS << "  };\n";
 
400
      OS << "private:\n";
 
401
      OS << "  " << type << " " << getLowerName() << ";";
 
402
    }
 
403
    void writePCHReadDecls(raw_ostream &OS) const {
 
404
      OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
 
405
         << "(static_cast<" << getAttrName() << "Attr::" << type
 
406
         << ">(Record[Idx++]));\n";
 
407
    }
 
408
    void writePCHReadArgs(raw_ostream &OS) const {
 
409
      OS << getLowerName();
 
410
    }
 
411
    void writePCHWrite(raw_ostream &OS) const {
 
412
      OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
 
413
    }
 
414
  };
 
415
}
 
416
 
 
417
static Argument *createArgument(Record &Arg, StringRef Attr,
 
418
                                Record *Search = 0) {
 
419
  if (!Search)
 
420
    Search = &Arg;
 
421
 
 
422
  Argument *Ptr = 0;
 
423
  llvm::StringRef ArgName = Search->getName();
 
424
 
 
425
  if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
 
426
  else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
 
427
  else if (ArgName == "ExprArgument") Ptr = new SimpleArgument(Arg, Attr,
 
428
                                                               "Expr *");
 
429
  else if (ArgName == "FunctionArgument")
 
430
    Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
 
431
  else if (ArgName == "IdentifierArgument")
 
432
    Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
 
433
  else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
 
434
  else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
 
435
  else if (ArgName == "TypeArgument")
 
436
    Ptr = new SimpleArgument(Arg, Attr, "QualType");
 
437
  else if (ArgName == "UnsignedArgument")
 
438
    Ptr = new SimpleArgument(Arg, Attr, "unsigned");
 
439
  else if (ArgName == "VariadicUnsignedArgument")
 
440
    Ptr = new VariadicArgument(Arg, Attr, "unsigned");
 
441
 
 
442
  if (!Ptr) {
 
443
    std::vector<Record*> Bases = Search->getSuperClasses();
 
444
    for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
 
445
         i != e; ++i) {
 
446
      Ptr = createArgument(Arg, Attr, *i);
 
447
      if (Ptr)
 
448
        break;
 
449
    }
 
450
  }
 
451
  return Ptr;
 
452
}
 
453
 
 
454
void ClangAttrClassEmitter::run(raw_ostream &OS) {
 
455
  OS << "// This file is generated by TableGen. Do not edit.\n\n";
 
456
  OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
 
457
  OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
 
458
 
 
459
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
 
460
 
 
461
  for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
 
462
       i != e; ++i) {
 
463
    Record &R = **i;
 
464
 
 
465
    OS << "class " << R.getName() << "Attr : public Attr {\n";
 
466
 
 
467
    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
 
468
    std::vector<Argument*> Args;
 
469
    std::vector<Argument*>::iterator ai, ae;
 
470
    Args.reserve(ArgRecords.size());
 
471
 
 
472
    for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
 
473
                                        re = ArgRecords.end();
 
474
         ri != re; ++ri) {
 
475
      Record &ArgRecord = **ri;
 
476
      Argument *Arg = createArgument(ArgRecord, R.getName());
 
477
      assert(Arg);
 
478
      Args.push_back(Arg);
 
479
 
 
480
      Arg->writeDeclarations(OS);
 
481
      OS << "\n\n";
 
482
    }
 
483
 
 
484
    ae = Args.end();
 
485
 
 
486
    OS << "\n public:\n";
 
487
    OS << "  " << R.getName() << "Attr(SourceLocation L, ASTContext &Ctx\n";
 
488
    
 
489
    for (ai = Args.begin(); ai != ae; ++ai) {
 
490
      OS << "              , ";
 
491
      (*ai)->writeCtorParameters(OS);
 
492
      OS << "\n";
 
493
    }
 
494
    
 
495
    OS << "             )\n";
 
496
    OS << "    : Attr(attr::" << R.getName() << ", L)\n";
 
497
 
 
498
    for (ai = Args.begin(); ai != ae; ++ai) {
 
499
      OS << "              , ";
 
500
      (*ai)->writeCtorInitializers(OS);
 
501
      OS << "\n";
 
502
    }
 
503
 
 
504
    OS << "  {\n";
 
505
  
 
506
    for (ai = Args.begin(); ai != ae; ++ai) {
 
507
      (*ai)->writeCtorBody(OS);
 
508
      OS << "\n";
 
509
    }
 
510
    OS << "  }\n\n";
 
511
 
 
512
    OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
 
513
 
 
514
    for (ai = Args.begin(); ai != ae; ++ai) {
 
515
      (*ai)->writeAccessors(OS);
 
516
      OS << "\n\n";
 
517
    }
 
518
 
 
519
    OS << R.getValueAsCode("AdditionalMembers");
 
520
    OS << "\n\n";
 
521
 
 
522
    OS << "  static bool classof(const Attr *A) { return A->getKind() == "
 
523
       << "attr::" << R.getName() << "; }\n";
 
524
    OS << "  static bool classof(const " << R.getName()
 
525
       << "Attr *) { return true; }\n";
 
526
    OS << "};\n\n";
 
527
  }
 
528
 
 
529
  OS << "#endif\n";
 
530
}
 
531
 
 
532
void ClangAttrImplEmitter::run(raw_ostream &OS) {
 
533
  OS << "// This file is generated by TableGen. Do not edit.\n\n";
 
534
 
 
535
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
 
536
  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
 
537
  std::vector<Argument*>::iterator ai, ae;
 
538
 
 
539
  for (; i != e; ++i) {
 
540
    Record &R = **i;
 
541
    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
 
542
    std::vector<Argument*> Args;
 
543
    for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
 
544
      Args.push_back(createArgument(**ri, R.getName()));
 
545
 
 
546
    for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
 
547
      (*ai)->writeAccessorDefinitions(OS);
 
548
 
 
549
    OS << R.getName() << "Attr *" << R.getName()
 
550
       << "Attr::clone(ASTContext &C) const {\n";
 
551
    OS << "  return new (C) " << R.getName() << "Attr(getLocation(), C";
 
552
    for (ai = Args.begin(); ai != ae; ++ai) {
 
553
      OS << ", ";
 
554
      (*ai)->writeCloneArgs(OS);
 
555
    }
 
556
    OS << ");\n}\n\n";
 
557
  }
 
558
}
 
559
 
 
560
void ClangAttrListEmitter::run(raw_ostream &OS) {
 
561
  OS << "// This file is generated by TableGen. Do not edit.\n\n";
 
562
 
 
563
  OS << "#ifndef LAST_ATTR\n";
 
564
  OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
 
565
  OS << "#endif\n\n";
 
566
   
 
567
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
 
568
  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
 
569
 
 
570
  if (i != e) {
 
571
    // Move the end iterator back to emit the last attribute.
 
572
    for(--e; i != e; ++i)
 
573
      OS << "ATTR(" << (*i)->getName() << ")\n";
 
574
    
 
575
    OS << "LAST_ATTR(" << (*i)->getName() << ")\n\n";
 
576
  }
 
577
 
 
578
  OS << "#undef LAST_ATTR\n";
 
579
  OS << "#undef ATTR\n";
 
580
}
 
581
 
 
582
void ClangAttrPCHReadEmitter::run(raw_ostream &OS) {
 
583
  OS << "// This file is generated by TableGen. Do not edi.\n\n";
 
584
 
 
585
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
 
586
                       ArgRecords;
 
587
  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
 
588
  std::vector<Argument*> Args;
 
589
  std::vector<Argument*>::iterator ri, re;
 
590
 
 
591
  OS << "  switch (Kind) {\n";
 
592
  OS << "  default:\n";
 
593
  OS << "    assert(0 && \"Unknown attribute!\");\n";
 
594
  OS << "    break;\n";
 
595
  for (; i != e; ++i) {
 
596
    Record &R = **i;
 
597
    OS << "  case attr::" << R.getName() << ": {\n";
 
598
    ArgRecords = R.getValueAsListOfDefs("Args");
 
599
    Args.clear();
 
600
    for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
 
601
      Argument *A = createArgument(**ai, R.getName());
 
602
      Args.push_back(A);
 
603
      A->writePCHReadDecls(OS);
 
604
    }
 
605
    OS << "    New = new (*Context) " << R.getName() << "Attr(Loc, *Context";
 
606
    for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
 
607
      OS << ", ";
 
608
      (*ri)->writePCHReadArgs(OS);
 
609
    }
 
610
    OS << ");\n";
 
611
    OS << "    break;\n";
 
612
    OS << "  }\n";
 
613
  }
 
614
  OS << "  }\n";
 
615
}
 
616
 
 
617
void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) {
 
618
  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
 
619
  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
 
620
 
 
621
  OS << "  switch (A->getKind()) {\n";
 
622
  OS << "  default:\n";
 
623
  OS << "    llvm_unreachable(\"Unknown attribute kind!\");\n";
 
624
  OS << "    break;\n";
 
625
  for (; i != e; ++i) {
 
626
    Record &R = **i;
 
627
    OS << "  case attr::" << R.getName() << ": {\n";
 
628
    Args = R.getValueAsListOfDefs("Args");
 
629
    if (!Args.empty())
 
630
      OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
 
631
         << "Attr>(A);\n";
 
632
    for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
 
633
      createArgument(**ai, R.getName())->writePCHWrite(OS);
 
634
    OS << "    break;\n";
 
635
    OS << "  }\n";
 
636
  }
 
637
  OS << "  }\n";
 
638
}