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