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> 23 getValueAsListOfStrings(Record &R, 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", "GetType(Record[Idx++])") 48 .Case("Expr *", "ReadSubExpr()") 49 .Case("IdentifierInfo *", "GetIdentifierInfo(Record, Idx)") 50 .Default("Record[Idx++]"); 51 } 52 53 // Assumes that the way to get the value is SA->getname() 54 std::string WritePCHRecord(StringRef type, StringRef name) { 55 return StringSwitch<std::string>(type) 56 .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + 57 ", Record);\n") 58 .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n") 59 .Case("Expr *", "AddStmt(" + std::string(name) + ");\n") 60 .Case("IdentifierInfo *", 61 "AddIdentifierRef(" + std::string(name) + ", Record);\n") 62 .Default("Record.push_back(" + std::string(name) + ");\n"); 63 } 64 65 namespace { 66 class Argument { 67 std::string lowerName, upperName; 68 StringRef attrName; 69 70 public: 71 Argument(Record &Arg, StringRef Attr) 72 : lowerName(Arg.getValueAsString("Name")), upperName(lowerName), 73 attrName(Attr) { 74 if (!lowerName.empty()) { 75 lowerName[0] = std::tolower(lowerName[0]); 76 upperName[0] = std::toupper(upperName[0]); 77 } 78 } 79 virtual ~Argument() {} 80 81 StringRef getLowerName() const { return lowerName; } 82 StringRef getUpperName() const { return upperName; } 83 StringRef getAttrName() const { return attrName; } 84 85 // These functions print the argument contents formatted in different ways. 86 virtual void writeAccessors(raw_ostream &OS) const = 0; 87 virtual void writeAccessorDefinitions(raw_ostream &OS) const {} 88 virtual void writeCloneArgs(raw_ostream &OS) const = 0; 89 virtual void writeCtorBody(raw_ostream &OS) const {} 90 virtual void writeCtorInitializers(raw_ostream &OS) const = 0; 91 virtual void writeCtorParameters(raw_ostream &OS) const = 0; 92 virtual void writeDeclarations(raw_ostream &OS) const = 0; 93 virtual void writePCHReadArgs(raw_ostream &OS) const = 0; 94 virtual void writePCHReadDecls(raw_ostream &OS) const = 0; 95 virtual void writePCHWrite(raw_ostream &OS) const = 0; 96 }; 97 98 class SimpleArgument : public Argument { 99 std::string type; 100 101 public: 102 SimpleArgument(Record &Arg, StringRef Attr, std::string T) 103 : Argument(Arg, Attr), type(T) 104 {} 105 106 void writeAccessors(raw_ostream &OS) const { 107 OS << " " << type << " get" << getUpperName() << "() const {\n"; 108 OS << " return " << getLowerName() << ";\n"; 109 OS << " }"; 110 } 111 void writeCloneArgs(raw_ostream &OS) const { 112 OS << getLowerName(); 113 } 114 void writeCtorInitializers(raw_ostream &OS) const { 115 OS << getLowerName() << "(" << getUpperName() << ")"; 116 } 117 void writeCtorParameters(raw_ostream &OS) const { 118 OS << type << " " << getUpperName(); 119 } 120 void writeDeclarations(raw_ostream &OS) const { 121 OS << type << " " << getLowerName() << ";"; 122 } 123 void writePCHReadDecls(raw_ostream &OS) const { 124 std::string read = ReadPCHRecord(type); 125 OS << " " << type << " " << getLowerName() << " = " << read << ";\n"; 126 } 127 void writePCHReadArgs(raw_ostream &OS) const { 128 OS << getLowerName(); 129 } 130 void writePCHWrite(raw_ostream &OS) const { 131 OS << " " << WritePCHRecord(type, "SA->get" + 132 std::string(getUpperName()) + "()"); 133 } 134 }; 135 136 class StringArgument : public Argument { 137 public: 138 StringArgument(Record &Arg, StringRef Attr) 139 : Argument(Arg, Attr) 140 {} 141 142 void writeAccessors(raw_ostream &OS) const { 143 OS << " llvm::StringRef get" << getUpperName() << "() const {\n"; 144 OS << " return llvm::StringRef(" << getLowerName() << ", " 145 << getLowerName() << "Length);\n"; 146 OS << " }\n"; 147 OS << " unsigned get" << getUpperName() << "Length() const {\n"; 148 OS << " return " << getLowerName() << "Length;\n"; 149 OS << " }\n"; 150 OS << " void set" << getUpperName() 151 << "(ASTContext &C, llvm::StringRef S) {\n"; 152 OS << " " << getLowerName() << "Length = S.size();\n"; 153 OS << " this->" << getLowerName() << " = new (C, 1) char [" 154 << getLowerName() << "Length];\n"; 155 OS << " std::memcpy(this->" << getLowerName() << ", S.data(), " 156 << getLowerName() << "Length);\n"; 157 OS << " }"; 158 } 159 void writeCloneArgs(raw_ostream &OS) const { 160 OS << "get" << getUpperName() << "()"; 161 } 162 void writeCtorBody(raw_ostream &OS) const { 163 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 164 << ".data(), " << getLowerName() << "Length);"; 165 } 166 void writeCtorInitializers(raw_ostream &OS) const { 167 OS << getLowerName() << "Length(" << getUpperName() << ".size())," 168 << getLowerName() << "(new (Ctx, 1) char[" << getLowerName() 169 << "Length])"; 170 } 171 void writeCtorParameters(raw_ostream &OS) const { 172 OS << "llvm::StringRef " << getUpperName(); 173 } 174 void writeDeclarations(raw_ostream &OS) const { 175 OS << "unsigned " << getLowerName() << "Length;\n"; 176 OS << "char *" << getLowerName() << ";"; 177 } 178 void writePCHReadDecls(raw_ostream &OS) const { 179 OS << " std::string " << getLowerName() 180 << "= ReadString(Record, Idx);\n"; 181 } 182 void writePCHReadArgs(raw_ostream &OS) const { 183 OS << getLowerName(); 184 } 185 void writePCHWrite(raw_ostream &OS) const { 186 OS << " AddString(SA->get" << getUpperName() << "(), Record);\n"; 187 } 188 }; 189 190 class AlignedArgument : public Argument { 191 public: 192 AlignedArgument(Record &Arg, StringRef Attr) 193 : Argument(Arg, Attr) 194 {} 195 196 void writeAccessors(raw_ostream &OS) const { 197 OS << " bool is" << getUpperName() << "Dependent() const;\n"; 198 199 OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n"; 200 201 OS << " bool is" << getUpperName() << "Expr() const {\n"; 202 OS << " return is" << getLowerName() << "Expr;\n"; 203 OS << " }\n"; 204 205 OS << " Expr *get" << getUpperName() << "Expr() const {\n"; 206 OS << " assert(is" << getLowerName() << "Expr);\n"; 207 OS << " return " << getLowerName() << "Expr;\n"; 208 OS << " }\n"; 209 210 OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n"; 211 OS << " assert(!is" << getLowerName() << "Expr);\n"; 212 OS << " return " << getLowerName() << "Type;\n"; 213 OS << " }"; 214 } 215 void writeAccessorDefinitions(raw_ostream &OS) const { 216 OS << "bool " << getAttrName() << "Attr::is" << getUpperName() 217 << "Dependent() const {\n"; 218 OS << " if (is" << getLowerName() << "Expr)\n"; 219 OS << " return " << getLowerName() << "Expr && (" << getLowerName() 220 << "Expr->isValueDependent() || " << getLowerName() 221 << "Expr->isTypeDependent());\n"; 222 OS << " else\n"; 223 OS << " return " << getLowerName() 224 << "Type->getType()->isDependentType();\n"; 225 OS << "}\n"; 226 227 // FIXME: Do not do the calculation here 228 // FIXME: Handle types correctly 229 // A null pointer means maximum alignment 230 // FIXME: Load the platform-specific maximum alignment, rather than 231 // 16, the x86 max. 232 OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName() 233 << "(ASTContext &Ctx) const {\n"; 234 OS << " assert(!is" << getUpperName() << "Dependent());\n"; 235 OS << " if (is" << getLowerName() << "Expr)\n"; 236 OS << " return (" << getLowerName() << "Expr ? " << getLowerName() 237 << "Expr->EvaluateAsInt(Ctx).getZExtValue() : 16)" 238 << "* Ctx.getCharWidth();\n"; 239 OS << " else\n"; 240 OS << " return 0; // FIXME\n"; 241 OS << "}\n"; 242 } 243 void writeCloneArgs(raw_ostream &OS) const { 244 OS << "is" << getLowerName() << "Expr, is" << getLowerName() 245 << "Expr ? static_cast<void*>(" << getLowerName() 246 << "Expr) : " << getLowerName() 247 << "Type"; 248 } 249 void writeCtorBody(raw_ostream &OS) const { 250 OS << " if (is" << getLowerName() << "Expr)\n"; 251 OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>(" 252 << getUpperName() << ");\n"; 253 OS << " else\n"; 254 OS << " " << getLowerName() 255 << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName() 256 << ");"; 257 } 258 void writeCtorInitializers(raw_ostream &OS) const { 259 OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)"; 260 } 261 void writeCtorParameters(raw_ostream &OS) const { 262 OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName(); 263 } 264 void writeDeclarations(raw_ostream &OS) const { 265 OS << "bool is" << getLowerName() << "Expr;\n"; 266 OS << "union {\n"; 267 OS << "Expr *" << getLowerName() << "Expr;\n"; 268 OS << "TypeSourceInfo *" << getLowerName() << "Type;\n"; 269 OS << "};"; 270 } 271 void writePCHReadArgs(raw_ostream &OS) const { 272 OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr"; 273 } 274 void writePCHReadDecls(raw_ostream &OS) const { 275 OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n"; 276 OS << " void *" << getLowerName() << "Ptr;\n"; 277 OS << " if (is" << getLowerName() << "Expr)\n"; 278 OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n"; 279 OS << " else\n"; 280 OS << " " << getLowerName() 281 << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n"; 282 } 283 void writePCHWrite(raw_ostream &OS) const { 284 OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n"; 285 OS << " if (SA->is" << getUpperName() << "Expr())\n"; 286 OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n"; 287 OS << " else\n"; 288 OS << " AddTypeSourceInfo(SA->get" << getUpperName() 289 << "Type(), Record);\n"; 290 } 291 }; 292 293 class VariadicArgument : public Argument { 294 std::string type; 295 296 public: 297 VariadicArgument(Record &Arg, StringRef Attr, std::string T) 298 : Argument(Arg, Attr), type(T) 299 {} 300 301 std::string getType() const { return type; } 302 303 void writeAccessors(raw_ostream &OS) const { 304 OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n"; 305 OS << " " << getLowerName() << "_iterator " << getLowerName() 306 << "_begin() const {\n"; 307 OS << " return " << getLowerName() << ";\n"; 308 OS << " }\n"; 309 OS << " " << getLowerName() << "_iterator " << getLowerName() 310 << "_end() const {\n"; 311 OS << " return " << getLowerName() << " + " << getLowerName() 312 << "Size;\n"; 313 OS << " }\n"; 314 OS << " unsigned " << getLowerName() << "_size() const {\n" 315 << " return " << getLowerName() << "Size;\n;"; 316 OS << " }"; 317 } 318 void writeCloneArgs(raw_ostream &OS) const { 319 OS << getLowerName() << ", " << getLowerName() << "Size"; 320 } 321 void writeCtorBody(raw_ostream &OS) const { 322 // FIXME: memcpy is not safe on non-trivial types. 323 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 324 << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n"; 325 } 326 void writeCtorInitializers(raw_ostream &OS) const { 327 OS << getLowerName() << "Size(" << getUpperName() << "Size), " 328 << getLowerName() << "(new (Ctx, 16) " << getType() << "[" 329 << getLowerName() << "Size])"; 330 } 331 void writeCtorParameters(raw_ostream &OS) const { 332 OS << getType() << " *" << getUpperName() << ", unsigned " 333 << getUpperName() << "Size"; 334 } 335 void writeDeclarations(raw_ostream &OS) const { 336 OS << " unsigned " << getLowerName() << "Size;\n"; 337 OS << " " << getType() << " *" << getLowerName() << ";"; 338 } 339 void writePCHReadDecls(raw_ostream &OS) const { 340 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; 341 OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName() 342 << ";\n"; 343 OS << " " << getLowerName() << ".reserve(" << getLowerName() 344 << "Size);\n"; 345 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; 346 347 std::string read = ReadPCHRecord(type); 348 OS << " " << getLowerName() << ".push_back(" << read << ");\n"; 349 } 350 void writePCHReadArgs(raw_ostream &OS) const { 351 OS << getLowerName() << ".data(), " << getLowerName() << "Size"; 352 } 353 void writePCHWrite(raw_ostream &OS) const{ 354 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; 355 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 356 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" 357 << getLowerName() << "_end(); i != e; ++i)\n"; 358 OS << " " << WritePCHRecord(type, "(*i)"); 359 } 360 }; 361 362 class EnumArgument : public Argument { 363 std::string type; 364 std::vector<StringRef> values, enums; 365 public: 366 EnumArgument(Record &Arg, StringRef Attr) 367 : Argument(Arg, Attr), type(Arg.getValueAsString("Type")), 368 values(getValueAsListOfStrings(Arg, "Values")), 369 enums(getValueAsListOfStrings(Arg, "Enums")) 370 {} 371 372 void writeAccessors(raw_ostream &OS) const { 373 OS << " " << type << " get" << getUpperName() << "() const {\n"; 374 OS << " return " << getLowerName() << ";\n"; 375 OS << " }"; 376 } 377 void writeCloneArgs(raw_ostream &OS) const { 378 OS << getLowerName(); 379 } 380 void writeCtorInitializers(raw_ostream &OS) const { 381 OS << getLowerName() << "(" << getUpperName() << ")"; 382 } 383 void writeCtorParameters(raw_ostream &OS) const { 384 OS << type << " " << getUpperName(); 385 } 386 void writeDeclarations(raw_ostream &OS) const { 387 // Calculate the various enum values 388 std::vector<StringRef> uniques(enums); 389 std::sort(uniques.begin(), uniques.end()); 390 uniques.erase(std::unique(uniques.begin(), uniques.end()), 391 uniques.end()); 392 // FIXME: Emit a proper error 393 assert(!uniques.empty()); 394 395 std::vector<StringRef>::iterator i = uniques.begin(), 396 e = uniques.end(); 397 // The last one needs to not have a comma. 398 --e; 399 400 OS << "public:\n"; 401 OS << " enum " << type << " {\n"; 402 for (; i != e; ++i) 403 OS << " " << *i << ",\n"; 404 OS << " " << *e << "\n"; 405 OS << " };\n"; 406 OS << "private:\n"; 407 OS << " " << type << " " << getLowerName() << ";"; 408 } 409 void writePCHReadDecls(raw_ostream &OS) const { 410 OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName() 411 << "(static_cast<" << getAttrName() << "Attr::" << type 412 << ">(Record[Idx++]));\n"; 413 } 414 void writePCHReadArgs(raw_ostream &OS) const { 415 OS << getLowerName(); 416 } 417 void writePCHWrite(raw_ostream &OS) const { 418 OS << "Record.push_back(SA->get" << getUpperName() << "());\n"; 419 } 420 }; 421 422 class VersionArgument : public Argument { 423 public: 424 VersionArgument(Record &Arg, StringRef Attr) 425 : Argument(Arg, Attr) 426 {} 427 428 void writeAccessors(raw_ostream &OS) const { 429 OS << " VersionTuple get" << getUpperName() << "() const {\n"; 430 OS << " return " << getLowerName() << ";\n"; 431 OS << " }\n"; 432 OS << " void set" << getUpperName() 433 << "(ASTContext &C, VersionTuple V) {\n"; 434 OS << " " << getLowerName() << " = V;\n"; 435 OS << " }"; 436 } 437 void writeCloneArgs(raw_ostream &OS) const { 438 OS << "get" << getUpperName() << "()"; 439 } 440 void writeCtorBody(raw_ostream &OS) const { 441 } 442 void writeCtorInitializers(raw_ostream &OS) const { 443 OS << getLowerName() << "(" << getUpperName() << ")"; 444 } 445 void writeCtorParameters(raw_ostream &OS) const { 446 OS << "VersionTuple " << getUpperName(); 447 } 448 void writeDeclarations(raw_ostream &OS) const { 449 OS << "VersionTuple " << getLowerName() << ";\n"; 450 } 451 void writePCHReadDecls(raw_ostream &OS) const { 452 OS << " VersionTuple " << getLowerName() 453 << "= ReadVersionTuple(Record, Idx);\n"; 454 } 455 void writePCHReadArgs(raw_ostream &OS) const { 456 OS << getLowerName(); 457 } 458 void writePCHWrite(raw_ostream &OS) const { 459 OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n"; 460 } 461 }; 462 } 463 464 static Argument *createArgument(Record &Arg, StringRef Attr, 465 Record *Search = 0) { 466 if (!Search) 467 Search = &Arg; 468 469 Argument *Ptr = 0; 470 llvm::StringRef ArgName = Search->getName(); 471 472 if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr); 473 else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr); 474 else if (ArgName == "ExprArgument") Ptr = new SimpleArgument(Arg, Attr, 475 "Expr *"); 476 else if (ArgName == "FunctionArgument") 477 Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *"); 478 else if (ArgName == "IdentifierArgument") 479 Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *"); 480 else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 481 "bool"); 482 else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int"); 483 else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr); 484 else if (ArgName == "TypeArgument") 485 Ptr = new SimpleArgument(Arg, Attr, "QualType"); 486 else if (ArgName == "UnsignedArgument") 487 Ptr = new SimpleArgument(Arg, Attr, "unsigned"); 488 else if (ArgName == "VariadicUnsignedArgument") 489 Ptr = new VariadicArgument(Arg, Attr, "unsigned"); 490 else if (ArgName == "VersionArgument") 491 Ptr = new VersionArgument(Arg, Attr); 492 493 if (!Ptr) { 494 std::vector<Record*> Bases = Search->getSuperClasses(); 495 for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end(); 496 i != e; ++i) { 497 Ptr = createArgument(Arg, Attr, *i); 498 if (Ptr) 499 break; 500 } 501 } 502 return Ptr; 503 } 504 505 void ClangAttrClassEmitter::run(raw_ostream &OS) { 506 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 507 OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; 508 OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; 509 510 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 511 512 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 513 i != e; ++i) { 514 Record &R = **i; 515 const std::string &SuperName = R.getSuperClasses().back()->getName(); 516 517 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; 518 519 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 520 std::vector<Argument*> Args; 521 std::vector<Argument*>::iterator ai, ae; 522 Args.reserve(ArgRecords.size()); 523 524 for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 525 re = ArgRecords.end(); 526 ri != re; ++ri) { 527 Record &ArgRecord = **ri; 528 Argument *Arg = createArgument(ArgRecord, R.getName()); 529 assert(Arg); 530 Args.push_back(Arg); 531 532 Arg->writeDeclarations(OS); 533 OS << "\n\n"; 534 } 535 536 ae = Args.end(); 537 538 OS << "\n public:\n"; 539 OS << " " << R.getName() << "Attr(SourceLocation L, ASTContext &Ctx\n"; 540 541 for (ai = Args.begin(); ai != ae; ++ai) { 542 OS << " , "; 543 (*ai)->writeCtorParameters(OS); 544 OS << "\n"; 545 } 546 547 OS << " )\n"; 548 OS << " : " << SuperName << "(attr::" << R.getName() << ", L)\n"; 549 550 for (ai = Args.begin(); ai != ae; ++ai) { 551 OS << " , "; 552 (*ai)->writeCtorInitializers(OS); 553 OS << "\n"; 554 } 555 556 OS << " {\n"; 557 558 for (ai = Args.begin(); ai != ae; ++ai) { 559 (*ai)->writeCtorBody(OS); 560 OS << "\n"; 561 } 562 OS << " }\n\n"; 563 564 OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; 565 566 for (ai = Args.begin(); ai != ae; ++ai) { 567 (*ai)->writeAccessors(OS); 568 OS << "\n\n"; 569 } 570 571 OS << R.getValueAsCode("AdditionalMembers"); 572 OS << "\n\n"; 573 574 OS << " static bool classof(const Attr *A) { return A->getKind() == " 575 << "attr::" << R.getName() << "; }\n"; 576 OS << " static bool classof(const " << R.getName() 577 << "Attr *) { return true; }\n"; 578 OS << "};\n\n"; 579 } 580 581 OS << "#endif\n"; 582 } 583 584 void ClangAttrImplEmitter::run(raw_ostream &OS) { 585 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 586 587 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 588 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; 589 std::vector<Argument*>::iterator ai, ae; 590 591 for (; i != e; ++i) { 592 Record &R = **i; 593 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 594 std::vector<Argument*> Args; 595 for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) 596 Args.push_back(createArgument(**ri, R.getName())); 597 598 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 599 (*ai)->writeAccessorDefinitions(OS); 600 601 OS << R.getName() << "Attr *" << R.getName() 602 << "Attr::clone(ASTContext &C) const {\n"; 603 OS << " return new (C) " << R.getName() << "Attr(getLocation(), C"; 604 for (ai = Args.begin(); ai != ae; ++ai) { 605 OS << ", "; 606 (*ai)->writeCloneArgs(OS); 607 } 608 OS << ");\n}\n\n"; 609 } 610 } 611 612 static void EmitAttrList(raw_ostream &OS, StringRef Class, 613 const std::vector<Record*> &AttrList) { 614 std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end(); 615 616 if (i != e) { 617 // Move the end iterator back to emit the last attribute. 618 for(--e; i != e; ++i) 619 OS << Class << "(" << (*i)->getName() << ")\n"; 620 621 OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; 622 } 623 } 624 625 void ClangAttrListEmitter::run(raw_ostream &OS) { 626 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 627 628 OS << "#ifndef LAST_ATTR\n"; 629 OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; 630 OS << "#endif\n\n"; 631 632 OS << "#ifndef INHERITABLE_ATTR\n"; 633 OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n"; 634 OS << "#endif\n\n"; 635 636 OS << "#ifndef LAST_INHERITABLE_ATTR\n"; 637 OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; 638 OS << "#endif\n\n"; 639 640 OS << "#ifndef INHERITABLE_PARAM_ATTR\n"; 641 OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n"; 642 OS << "#endif\n\n"; 643 644 OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n"; 645 OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)" 646 " INHERITABLE_PARAM_ATTR(NAME)\n"; 647 OS << "#endif\n\n"; 648 649 Record *InhClass = Records.getClass("InheritableAttr"); 650 Record *InhParamClass = Records.getClass("InheritableParamAttr"); 651 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 652 NonInhAttrs, InhAttrs, InhParamAttrs; 653 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 654 i != e; ++i) { 655 if ((*i)->isSubClassOf(InhParamClass)) 656 InhParamAttrs.push_back(*i); 657 else if ((*i)->isSubClassOf(InhClass)) 658 InhAttrs.push_back(*i); 659 else 660 NonInhAttrs.push_back(*i); 661 } 662 663 EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); 664 EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); 665 EmitAttrList(OS, "ATTR", NonInhAttrs); 666 667 OS << "#undef LAST_ATTR\n"; 668 OS << "#undef INHERITABLE_ATTR\n"; 669 OS << "#undef LAST_INHERITABLE_ATTR\n"; 670 OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; 671 OS << "#undef ATTR\n"; 672 } 673 674 void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { 675 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 676 677 Record *InhClass = Records.getClass("InheritableAttr"); 678 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 679 ArgRecords; 680 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 681 std::vector<Argument*> Args; 682 std::vector<Argument*>::iterator ri, re; 683 684 OS << " switch (Kind) {\n"; 685 OS << " default:\n"; 686 OS << " assert(0 && \"Unknown attribute!\");\n"; 687 OS << " break;\n"; 688 for (; i != e; ++i) { 689 Record &R = **i; 690 OS << " case attr::" << R.getName() << ": {\n"; 691 if (R.isSubClassOf(InhClass)) 692 OS << " bool isInherited = Record[Idx++];\n"; 693 ArgRecords = R.getValueAsListOfDefs("Args"); 694 Args.clear(); 695 for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { 696 Argument *A = createArgument(**ai, R.getName()); 697 Args.push_back(A); 698 A->writePCHReadDecls(OS); 699 } 700 OS << " New = new (*Context) " << R.getName() << "Attr(Loc, *Context"; 701 for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) { 702 OS << ", "; 703 (*ri)->writePCHReadArgs(OS); 704 } 705 OS << ");\n"; 706 if (R.isSubClassOf(InhClass)) 707 OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n"; 708 OS << " break;\n"; 709 OS << " }\n"; 710 } 711 OS << " }\n"; 712 } 713 714 void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { 715 Record *InhClass = Records.getClass("InheritableAttr"); 716 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; 717 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 718 719 OS << " switch (A->getKind()) {\n"; 720 OS << " default:\n"; 721 OS << " llvm_unreachable(\"Unknown attribute kind!\");\n"; 722 OS << " break;\n"; 723 for (; i != e; ++i) { 724 Record &R = **i; 725 OS << " case attr::" << R.getName() << ": {\n"; 726 Args = R.getValueAsListOfDefs("Args"); 727 if (R.isSubClassOf(InhClass) || !Args.empty()) 728 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() 729 << "Attr>(A);\n"; 730 if (R.isSubClassOf(InhClass)) 731 OS << " Record.push_back(SA->isInherited());\n"; 732 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 733 createArgument(**ai, R.getName())->writePCHWrite(OS); 734 OS << " break;\n"; 735 OS << " }\n"; 736 } 737 OS << " }\n"; 738 } 739 740 void ClangAttrSpellingListEmitter::run(raw_ostream &OS) { 741 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 742 743 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 744 745 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { 746 Record &Attr = **I; 747 748 std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings"); 749 750 for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { 751 StringRef Spelling = *I; 752 OS << ".Case(\"" << Spelling << "\", true)\n"; 753 } 754 } 755 756 } 757