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 "llvm/ADT/SmallString.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/ADT/SmallSet.h" 17 #include "llvm/TableGen/Record.h" 18 #include "llvm/TableGen/StringMatcher.h" 19 #include "llvm/TableGen/TableGenBackend.h" 20 #include <algorithm> 21 #include <cctype> 22 23 using namespace llvm; 24 25 static const std::vector<StringRef> 26 getValueAsListOfStrings(Record &R, StringRef FieldName) { 27 ListInit *List = R.getValueAsListInit(FieldName); 28 assert (List && "Got a null ListInit"); 29 30 std::vector<StringRef> Strings; 31 Strings.reserve(List->getSize()); 32 33 for (ListInit::const_iterator i = List->begin(), e = List->end(); 34 i != e; 35 ++i) { 36 assert(*i && "Got a null element in a ListInit"); 37 if (StringInit *S = dyn_cast<StringInit>(*i)) 38 Strings.push_back(S->getValue()); 39 else 40 assert(false && "Got a non-string, non-code element in a ListInit"); 41 } 42 43 return Strings; 44 } 45 46 static std::string ReadPCHRecord(StringRef type) { 47 return StringSwitch<std::string>(type) 48 .EndsWith("Decl *", "GetLocalDeclAs<" 49 + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])") 50 .Case("QualType", "getLocalType(F, Record[Idx++])") 51 .Case("Expr *", "ReadExpr(F)") 52 .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)") 53 .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)") 54 .Default("Record[Idx++]"); 55 } 56 57 // Assumes that the way to get the value is SA->getname() 58 static std::string WritePCHRecord(StringRef type, StringRef name) { 59 return StringSwitch<std::string>(type) 60 .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + 61 ", Record);\n") 62 .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n") 63 .Case("Expr *", "AddStmt(" + std::string(name) + ");\n") 64 .Case("IdentifierInfo *", 65 "AddIdentifierRef(" + std::string(name) + ", Record);\n") 66 .Case("SourceLocation", 67 "AddSourceLocation(" + std::string(name) + ", Record);\n") 68 .Default("Record.push_back(" + std::string(name) + ");\n"); 69 } 70 71 // Normalize attribute name by removing leading and trailing 72 // underscores. For example, __foo, foo__, __foo__ would 73 // become foo. 74 static StringRef NormalizeAttrName(StringRef AttrName) { 75 if (AttrName.startswith("__")) 76 AttrName = AttrName.substr(2, AttrName.size()); 77 78 if (AttrName.endswith("__")) 79 AttrName = AttrName.substr(0, AttrName.size() - 2); 80 81 return AttrName; 82 } 83 84 // Normalize attribute spelling only if the spelling has both leading 85 // and trailing underscores. For example, __ms_struct__ will be 86 // normalized to "ms_struct"; __cdecl will remain intact. 87 static StringRef NormalizeAttrSpelling(StringRef AttrSpelling) { 88 if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) { 89 AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4); 90 } 91 92 return AttrSpelling; 93 } 94 95 namespace { 96 class Argument { 97 std::string lowerName, upperName; 98 StringRef attrName; 99 bool isOpt; 100 101 public: 102 Argument(Record &Arg, StringRef Attr) 103 : lowerName(Arg.getValueAsString("Name")), upperName(lowerName), 104 attrName(Attr), isOpt(false) { 105 if (!lowerName.empty()) { 106 lowerName[0] = std::tolower(lowerName[0]); 107 upperName[0] = std::toupper(upperName[0]); 108 } 109 } 110 virtual ~Argument() {} 111 112 StringRef getLowerName() const { return lowerName; } 113 StringRef getUpperName() const { return upperName; } 114 StringRef getAttrName() const { return attrName; } 115 116 bool isOptional() const { return isOpt; } 117 void setOptional(bool set) { isOpt = set; } 118 119 // These functions print the argument contents formatted in different ways. 120 virtual void writeAccessors(raw_ostream &OS) const = 0; 121 virtual void writeAccessorDefinitions(raw_ostream &OS) const {} 122 virtual void writeCloneArgs(raw_ostream &OS) const = 0; 123 virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0; 124 virtual void writeTemplateInstantiation(raw_ostream &OS) const {} 125 virtual void writeCtorBody(raw_ostream &OS) const {} 126 virtual void writeCtorInitializers(raw_ostream &OS) const = 0; 127 virtual void writeCtorDefaultInitializers(raw_ostream &OS) const = 0; 128 virtual void writeCtorParameters(raw_ostream &OS) const = 0; 129 virtual void writeDeclarations(raw_ostream &OS) const = 0; 130 virtual void writePCHReadArgs(raw_ostream &OS) const = 0; 131 virtual void writePCHReadDecls(raw_ostream &OS) const = 0; 132 virtual void writePCHWrite(raw_ostream &OS) const = 0; 133 virtual void writeValue(raw_ostream &OS) const = 0; 134 virtual void writeDump(raw_ostream &OS) const = 0; 135 virtual void writeDumpChildren(raw_ostream &OS) const {} 136 virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; } 137 138 virtual bool isEnumArg() const { return false; } 139 virtual bool isVariadicEnumArg() const { return false; } 140 }; 141 142 class SimpleArgument : public Argument { 143 std::string type; 144 145 public: 146 SimpleArgument(Record &Arg, StringRef Attr, std::string T) 147 : Argument(Arg, Attr), type(T) 148 {} 149 150 std::string getType() const { return type; } 151 152 void writeAccessors(raw_ostream &OS) const { 153 OS << " " << type << " get" << getUpperName() << "() const {\n"; 154 OS << " return " << getLowerName() << ";\n"; 155 OS << " }"; 156 } 157 void writeCloneArgs(raw_ostream &OS) const { 158 OS << getLowerName(); 159 } 160 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 161 OS << "A->get" << getUpperName() << "()"; 162 } 163 void writeCtorInitializers(raw_ostream &OS) const { 164 OS << getLowerName() << "(" << getUpperName() << ")"; 165 } 166 void writeCtorDefaultInitializers(raw_ostream &OS) const { 167 OS << getLowerName() << "()"; 168 } 169 void writeCtorParameters(raw_ostream &OS) const { 170 OS << type << " " << getUpperName(); 171 } 172 void writeDeclarations(raw_ostream &OS) const { 173 OS << type << " " << getLowerName() << ";"; 174 } 175 void writePCHReadDecls(raw_ostream &OS) const { 176 std::string read = ReadPCHRecord(type); 177 OS << " " << type << " " << getLowerName() << " = " << read << ";\n"; 178 } 179 void writePCHReadArgs(raw_ostream &OS) const { 180 OS << getLowerName(); 181 } 182 void writePCHWrite(raw_ostream &OS) const { 183 OS << " " << WritePCHRecord(type, "SA->get" + 184 std::string(getUpperName()) + "()"); 185 } 186 void writeValue(raw_ostream &OS) const { 187 if (type == "FunctionDecl *") { 188 OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \""; 189 } else if (type == "IdentifierInfo *") { 190 OS << "\" << get" << getUpperName() << "()->getName() << \""; 191 } else if (type == "QualType") { 192 OS << "\" << get" << getUpperName() << "().getAsString() << \""; 193 } else if (type == "SourceLocation") { 194 OS << "\" << get" << getUpperName() << "().getRawEncoding() << \""; 195 } else { 196 OS << "\" << get" << getUpperName() << "() << \""; 197 } 198 } 199 void writeDump(raw_ostream &OS) const { 200 if (type == "FunctionDecl *") { 201 OS << " OS << \" \";\n"; 202 OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n"; 203 } else if (type == "IdentifierInfo *") { 204 OS << " OS << \" \" << SA->get" << getUpperName() 205 << "()->getName();\n"; 206 } else if (type == "QualType") { 207 OS << " OS << \" \" << SA->get" << getUpperName() 208 << "().getAsString();\n"; 209 } else if (type == "SourceLocation") { 210 OS << " OS << \" \";\n"; 211 OS << " SA->get" << getUpperName() << "().print(OS, *SM);\n"; 212 } else if (type == "bool") { 213 OS << " if (SA->get" << getUpperName() << "()) OS << \" " 214 << getUpperName() << "\";\n"; 215 } else if (type == "int" || type == "unsigned") { 216 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; 217 } else { 218 llvm_unreachable("Unknown SimpleArgument type!"); 219 } 220 } 221 }; 222 223 class StringArgument : public Argument { 224 public: 225 StringArgument(Record &Arg, StringRef Attr) 226 : Argument(Arg, Attr) 227 {} 228 229 void writeAccessors(raw_ostream &OS) const { 230 OS << " llvm::StringRef get" << getUpperName() << "() const {\n"; 231 OS << " return llvm::StringRef(" << getLowerName() << ", " 232 << getLowerName() << "Length);\n"; 233 OS << " }\n"; 234 OS << " unsigned get" << getUpperName() << "Length() const {\n"; 235 OS << " return " << getLowerName() << "Length;\n"; 236 OS << " }\n"; 237 OS << " void set" << getUpperName() 238 << "(ASTContext &C, llvm::StringRef S) {\n"; 239 OS << " " << getLowerName() << "Length = S.size();\n"; 240 OS << " this->" << getLowerName() << " = new (C, 1) char [" 241 << getLowerName() << "Length];\n"; 242 OS << " std::memcpy(this->" << getLowerName() << ", S.data(), " 243 << getLowerName() << "Length);\n"; 244 OS << " }"; 245 } 246 void writeCloneArgs(raw_ostream &OS) const { 247 OS << "get" << getUpperName() << "()"; 248 } 249 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 250 OS << "A->get" << getUpperName() << "()"; 251 } 252 void writeCtorBody(raw_ostream &OS) const { 253 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 254 << ".data(), " << getLowerName() << "Length);"; 255 } 256 void writeCtorInitializers(raw_ostream &OS) const { 257 OS << getLowerName() << "Length(" << getUpperName() << ".size())," 258 << getLowerName() << "(new (Ctx, 1) char[" << getLowerName() 259 << "Length])"; 260 } 261 void writeCtorDefaultInitializers(raw_ostream &OS) const { 262 OS << getLowerName() << "Length(0)," << getLowerName() << "(0)"; 263 } 264 void writeCtorParameters(raw_ostream &OS) const { 265 OS << "llvm::StringRef " << getUpperName(); 266 } 267 void writeDeclarations(raw_ostream &OS) const { 268 OS << "unsigned " << getLowerName() << "Length;\n"; 269 OS << "char *" << getLowerName() << ";"; 270 } 271 void writePCHReadDecls(raw_ostream &OS) const { 272 OS << " std::string " << getLowerName() 273 << "= ReadString(Record, Idx);\n"; 274 } 275 void writePCHReadArgs(raw_ostream &OS) const { 276 OS << getLowerName(); 277 } 278 void writePCHWrite(raw_ostream &OS) const { 279 OS << " AddString(SA->get" << getUpperName() << "(), Record);\n"; 280 } 281 void writeValue(raw_ostream &OS) const { 282 OS << "\\\"\" << get" << getUpperName() << "() << \"\\\""; 283 } 284 void writeDump(raw_ostream &OS) const { 285 OS << " OS << \" \\\"\" << SA->get" << getUpperName() 286 << "() << \"\\\"\";\n"; 287 } 288 }; 289 290 class AlignedArgument : public Argument { 291 public: 292 AlignedArgument(Record &Arg, StringRef Attr) 293 : Argument(Arg, Attr) 294 {} 295 296 void writeAccessors(raw_ostream &OS) const { 297 OS << " bool is" << getUpperName() << "Dependent() const;\n"; 298 299 OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n"; 300 301 OS << " bool is" << getUpperName() << "Expr() const {\n"; 302 OS << " return is" << getLowerName() << "Expr;\n"; 303 OS << " }\n"; 304 305 OS << " Expr *get" << getUpperName() << "Expr() const {\n"; 306 OS << " assert(is" << getLowerName() << "Expr);\n"; 307 OS << " return " << getLowerName() << "Expr;\n"; 308 OS << " }\n"; 309 310 OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n"; 311 OS << " assert(!is" << getLowerName() << "Expr);\n"; 312 OS << " return " << getLowerName() << "Type;\n"; 313 OS << " }"; 314 } 315 void writeAccessorDefinitions(raw_ostream &OS) const { 316 OS << "bool " << getAttrName() << "Attr::is" << getUpperName() 317 << "Dependent() const {\n"; 318 OS << " if (is" << getLowerName() << "Expr)\n"; 319 OS << " return " << getLowerName() << "Expr && (" << getLowerName() 320 << "Expr->isValueDependent() || " << getLowerName() 321 << "Expr->isTypeDependent());\n"; 322 OS << " else\n"; 323 OS << " return " << getLowerName() 324 << "Type->getType()->isDependentType();\n"; 325 OS << "}\n"; 326 327 // FIXME: Do not do the calculation here 328 // FIXME: Handle types correctly 329 // A null pointer means maximum alignment 330 // FIXME: Load the platform-specific maximum alignment, rather than 331 // 16, the x86 max. 332 OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName() 333 << "(ASTContext &Ctx) const {\n"; 334 OS << " assert(!is" << getUpperName() << "Dependent());\n"; 335 OS << " if (is" << getLowerName() << "Expr)\n"; 336 OS << " return (" << getLowerName() << "Expr ? " << getLowerName() 337 << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)" 338 << "* Ctx.getCharWidth();\n"; 339 OS << " else\n"; 340 OS << " return 0; // FIXME\n"; 341 OS << "}\n"; 342 } 343 void writeCloneArgs(raw_ostream &OS) const { 344 OS << "is" << getLowerName() << "Expr, is" << getLowerName() 345 << "Expr ? static_cast<void*>(" << getLowerName() 346 << "Expr) : " << getLowerName() 347 << "Type"; 348 } 349 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 350 // FIXME: move the definition in Sema::InstantiateAttrs to here. 351 // In the meantime, aligned attributes are cloned. 352 } 353 void writeCtorBody(raw_ostream &OS) const { 354 OS << " if (is" << getLowerName() << "Expr)\n"; 355 OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>(" 356 << getUpperName() << ");\n"; 357 OS << " else\n"; 358 OS << " " << getLowerName() 359 << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName() 360 << ");"; 361 } 362 void writeCtorInitializers(raw_ostream &OS) const { 363 OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)"; 364 } 365 void writeCtorDefaultInitializers(raw_ostream &OS) const { 366 OS << "is" << getLowerName() << "Expr(false)"; 367 } 368 void writeCtorParameters(raw_ostream &OS) const { 369 OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName(); 370 } 371 void writeDeclarations(raw_ostream &OS) const { 372 OS << "bool is" << getLowerName() << "Expr;\n"; 373 OS << "union {\n"; 374 OS << "Expr *" << getLowerName() << "Expr;\n"; 375 OS << "TypeSourceInfo *" << getLowerName() << "Type;\n"; 376 OS << "};"; 377 } 378 void writePCHReadArgs(raw_ostream &OS) const { 379 OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr"; 380 } 381 void writePCHReadDecls(raw_ostream &OS) const { 382 OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n"; 383 OS << " void *" << getLowerName() << "Ptr;\n"; 384 OS << " if (is" << getLowerName() << "Expr)\n"; 385 OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n"; 386 OS << " else\n"; 387 OS << " " << getLowerName() 388 << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n"; 389 } 390 void writePCHWrite(raw_ostream &OS) const { 391 OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n"; 392 OS << " if (SA->is" << getUpperName() << "Expr())\n"; 393 OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n"; 394 OS << " else\n"; 395 OS << " AddTypeSourceInfo(SA->get" << getUpperName() 396 << "Type(), Record);\n"; 397 } 398 void writeValue(raw_ostream &OS) const { 399 OS << "\";\n" 400 << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n" 401 << " OS << \""; 402 } 403 void writeDump(raw_ostream &OS) const { 404 } 405 void writeDumpChildren(raw_ostream &OS) const { 406 OS << " if (SA->is" << getUpperName() << "Expr()) {\n"; 407 OS << " lastChild();\n"; 408 OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n"; 409 OS << " } else\n"; 410 OS << " dumpType(SA->get" << getUpperName() 411 << "Type()->getType());\n"; 412 } 413 void writeHasChildren(raw_ostream &OS) const { 414 OS << "SA->is" << getUpperName() << "Expr()"; 415 } 416 }; 417 418 class VariadicArgument : public Argument { 419 std::string type; 420 421 public: 422 VariadicArgument(Record &Arg, StringRef Attr, std::string T) 423 : Argument(Arg, Attr), type(T) 424 {} 425 426 std::string getType() const { return type; } 427 428 void writeAccessors(raw_ostream &OS) const { 429 OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n"; 430 OS << " " << getLowerName() << "_iterator " << getLowerName() 431 << "_begin() const {\n"; 432 OS << " return " << getLowerName() << ";\n"; 433 OS << " }\n"; 434 OS << " " << getLowerName() << "_iterator " << getLowerName() 435 << "_end() const {\n"; 436 OS << " return " << getLowerName() << " + " << getLowerName() 437 << "Size;\n"; 438 OS << " }\n"; 439 OS << " unsigned " << getLowerName() << "_size() const {\n" 440 << " return " << getLowerName() << "Size;\n"; 441 OS << " }"; 442 } 443 void writeCloneArgs(raw_ostream &OS) const { 444 OS << getLowerName() << ", " << getLowerName() << "Size"; 445 } 446 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 447 // This isn't elegant, but we have to go through public methods... 448 OS << "A->" << getLowerName() << "_begin(), " 449 << "A->" << getLowerName() << "_size()"; 450 } 451 void writeCtorBody(raw_ostream &OS) const { 452 // FIXME: memcpy is not safe on non-trivial types. 453 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 454 << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n"; 455 } 456 void writeCtorInitializers(raw_ostream &OS) const { 457 OS << getLowerName() << "Size(" << getUpperName() << "Size), " 458 << getLowerName() << "(new (Ctx, 16) " << getType() << "[" 459 << getLowerName() << "Size])"; 460 } 461 void writeCtorDefaultInitializers(raw_ostream &OS) const { 462 OS << getLowerName() << "Size(0), " << getLowerName() << "(0)"; 463 } 464 void writeCtorParameters(raw_ostream &OS) const { 465 OS << getType() << " *" << getUpperName() << ", unsigned " 466 << getUpperName() << "Size"; 467 } 468 void writeDeclarations(raw_ostream &OS) const { 469 OS << " unsigned " << getLowerName() << "Size;\n"; 470 OS << " " << getType() << " *" << getLowerName() << ";"; 471 } 472 void writePCHReadDecls(raw_ostream &OS) const { 473 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; 474 OS << " SmallVector<" << type << ", 4> " << getLowerName() 475 << ";\n"; 476 OS << " " << getLowerName() << ".reserve(" << getLowerName() 477 << "Size);\n"; 478 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; 479 480 std::string read = ReadPCHRecord(type); 481 OS << " " << getLowerName() << ".push_back(" << read << ");\n"; 482 } 483 void writePCHReadArgs(raw_ostream &OS) const { 484 OS << getLowerName() << ".data(), " << getLowerName() << "Size"; 485 } 486 void writePCHWrite(raw_ostream &OS) const{ 487 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; 488 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 489 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" 490 << getLowerName() << "_end(); i != e; ++i)\n"; 491 OS << " " << WritePCHRecord(type, "(*i)"); 492 } 493 void writeValue(raw_ostream &OS) const { 494 OS << "\";\n"; 495 OS << " bool isFirst = true;\n" 496 << " for (" << getAttrName() << "Attr::" << getLowerName() 497 << "_iterator i = " << getLowerName() << "_begin(), e = " 498 << getLowerName() << "_end(); i != e; ++i) {\n" 499 << " if (isFirst) isFirst = false;\n" 500 << " else OS << \", \";\n" 501 << " OS << *i;\n" 502 << " }\n"; 503 OS << " OS << \""; 504 } 505 void writeDump(raw_ostream &OS) const { 506 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 507 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" 508 << getLowerName() << "_end(); I != E; ++I)\n"; 509 OS << " OS << \" \" << *I;\n"; 510 } 511 }; 512 513 class EnumArgument : public Argument { 514 std::string type; 515 std::vector<StringRef> values, enums, uniques; 516 public: 517 EnumArgument(Record &Arg, StringRef Attr) 518 : Argument(Arg, Attr), type(Arg.getValueAsString("Type")), 519 values(getValueAsListOfStrings(Arg, "Values")), 520 enums(getValueAsListOfStrings(Arg, "Enums")), 521 uniques(enums) 522 { 523 // Calculate the various enum values 524 std::sort(uniques.begin(), uniques.end()); 525 uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end()); 526 // FIXME: Emit a proper error 527 assert(!uniques.empty()); 528 } 529 530 bool isEnumArg() const { return true; } 531 532 void writeAccessors(raw_ostream &OS) const { 533 OS << " " << type << " get" << getUpperName() << "() const {\n"; 534 OS << " return " << getLowerName() << ";\n"; 535 OS << " }"; 536 } 537 void writeCloneArgs(raw_ostream &OS) const { 538 OS << getLowerName(); 539 } 540 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 541 OS << "A->get" << getUpperName() << "()"; 542 } 543 void writeCtorInitializers(raw_ostream &OS) const { 544 OS << getLowerName() << "(" << getUpperName() << ")"; 545 } 546 void writeCtorDefaultInitializers(raw_ostream &OS) const { 547 OS << getLowerName() << "(" << type << "(0))"; 548 } 549 void writeCtorParameters(raw_ostream &OS) const { 550 OS << type << " " << getUpperName(); 551 } 552 void writeDeclarations(raw_ostream &OS) const { 553 std::vector<StringRef>::const_iterator i = uniques.begin(), 554 e = uniques.end(); 555 // The last one needs to not have a comma. 556 --e; 557 558 OS << "public:\n"; 559 OS << " enum " << type << " {\n"; 560 for (; i != e; ++i) 561 OS << " " << *i << ",\n"; 562 OS << " " << *e << "\n"; 563 OS << " };\n"; 564 OS << "private:\n"; 565 OS << " " << type << " " << getLowerName() << ";"; 566 } 567 void writePCHReadDecls(raw_ostream &OS) const { 568 OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName() 569 << "(static_cast<" << getAttrName() << "Attr::" << type 570 << ">(Record[Idx++]));\n"; 571 } 572 void writePCHReadArgs(raw_ostream &OS) const { 573 OS << getLowerName(); 574 } 575 void writePCHWrite(raw_ostream &OS) const { 576 OS << "Record.push_back(SA->get" << getUpperName() << "());\n"; 577 } 578 void writeValue(raw_ostream &OS) const { 579 OS << "\" << get" << getUpperName() << "() << \""; 580 } 581 void writeDump(raw_ostream &OS) const { 582 OS << " switch(SA->get" << getUpperName() << "()) {\n"; 583 for (std::vector<StringRef>::const_iterator I = uniques.begin(), 584 E = uniques.end(); I != E; ++I) { 585 OS << " case " << getAttrName() << "Attr::" << *I << ":\n"; 586 OS << " OS << \" " << *I << "\";\n"; 587 OS << " break;\n"; 588 } 589 OS << " }\n"; 590 } 591 592 void writeConversion(raw_ostream &OS) const { 593 OS << " static bool ConvertStrTo" << type << "(StringRef Val, "; 594 OS << type << " &Out) {\n"; 595 OS << " Optional<" << type << "> R = llvm::StringSwitch<Optional<"; 596 OS << type << "> >(Val)\n"; 597 for (size_t I = 0; I < enums.size(); ++I) { 598 OS << " .Case(\"" << values[I] << "\", "; 599 OS << getAttrName() << "Attr::" << enums[I] << ")\n"; 600 } 601 OS << " .Default(Optional<" << type << ">());\n"; 602 OS << " if (R) {\n"; 603 OS << " Out = *R;\n return true;\n }\n"; 604 OS << " return false;\n"; 605 OS << " }\n"; 606 } 607 }; 608 609 class VariadicEnumArgument: public VariadicArgument { 610 std::string type, QualifiedTypeName; 611 std::vector<StringRef> values, enums, uniques; 612 public: 613 VariadicEnumArgument(Record &Arg, StringRef Attr) 614 : VariadicArgument(Arg, Attr, Arg.getValueAsString("Type")), 615 type(Arg.getValueAsString("Type")), 616 values(getValueAsListOfStrings(Arg, "Values")), 617 enums(getValueAsListOfStrings(Arg, "Enums")), 618 uniques(enums) 619 { 620 // Calculate the various enum values 621 std::sort(uniques.begin(), uniques.end()); 622 uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end()); 623 624 QualifiedTypeName = getAttrName().str() + "Attr::" + type; 625 626 // FIXME: Emit a proper error 627 assert(!uniques.empty()); 628 } 629 630 bool isVariadicEnumArg() const { return true; } 631 632 void writeDeclarations(raw_ostream &OS) const { 633 std::vector<StringRef>::const_iterator i = uniques.begin(), 634 e = uniques.end(); 635 // The last one needs to not have a comma. 636 --e; 637 638 OS << "public:\n"; 639 OS << " enum " << type << " {\n"; 640 for (; i != e; ++i) 641 OS << " " << *i << ",\n"; 642 OS << " " << *e << "\n"; 643 OS << " };\n"; 644 OS << "private:\n"; 645 646 VariadicArgument::writeDeclarations(OS); 647 } 648 void writeDump(raw_ostream &OS) const { 649 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 650 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" 651 << getLowerName() << "_end(); I != E; ++I) {\n"; 652 OS << " switch(*I) {\n"; 653 for (std::vector<StringRef>::const_iterator UI = uniques.begin(), 654 UE = uniques.end(); UI != UE; ++UI) { 655 OS << " case " << getAttrName() << "Attr::" << *UI << ":\n"; 656 OS << " OS << \" " << *UI << "\";\n"; 657 OS << " break;\n"; 658 } 659 OS << " }\n"; 660 OS << " }\n"; 661 } 662 void writePCHReadDecls(raw_ostream &OS) const { 663 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; 664 OS << " SmallVector<" << QualifiedTypeName << ", 4> " << getLowerName() 665 << ";\n"; 666 OS << " " << getLowerName() << ".reserve(" << getLowerName() 667 << "Size);\n"; 668 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; 669 OS << " " << getLowerName() << ".push_back(" << "static_cast<" 670 << QualifiedTypeName << ">(Record[Idx++]));\n"; 671 } 672 void writePCHWrite(raw_ostream &OS) const{ 673 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; 674 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 675 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" 676 << getLowerName() << "_end(); i != e; ++i)\n"; 677 OS << " " << WritePCHRecord(QualifiedTypeName, "(*i)"); 678 } 679 void writeConversion(raw_ostream &OS) const { 680 OS << " static bool ConvertStrTo" << type << "(StringRef Val, "; 681 OS << type << " &Out) {\n"; 682 OS << " Optional<" << type << "> R = llvm::StringSwitch<Optional<"; 683 OS << type << "> >(Val)\n"; 684 for (size_t I = 0; I < enums.size(); ++I) { 685 OS << " .Case(\"" << values[I] << "\", "; 686 OS << getAttrName() << "Attr::" << enums[I] << ")\n"; 687 } 688 OS << " .Default(Optional<" << type << ">());\n"; 689 OS << " if (R) {\n"; 690 OS << " Out = *R;\n return true;\n }\n"; 691 OS << " return false;\n"; 692 OS << " }\n"; 693 } 694 }; 695 696 class VersionArgument : public Argument { 697 public: 698 VersionArgument(Record &Arg, StringRef Attr) 699 : Argument(Arg, Attr) 700 {} 701 702 void writeAccessors(raw_ostream &OS) const { 703 OS << " VersionTuple get" << getUpperName() << "() const {\n"; 704 OS << " return " << getLowerName() << ";\n"; 705 OS << " }\n"; 706 OS << " void set" << getUpperName() 707 << "(ASTContext &C, VersionTuple V) {\n"; 708 OS << " " << getLowerName() << " = V;\n"; 709 OS << " }"; 710 } 711 void writeCloneArgs(raw_ostream &OS) const { 712 OS << "get" << getUpperName() << "()"; 713 } 714 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 715 OS << "A->get" << getUpperName() << "()"; 716 } 717 void writeCtorBody(raw_ostream &OS) const { 718 } 719 void writeCtorInitializers(raw_ostream &OS) const { 720 OS << getLowerName() << "(" << getUpperName() << ")"; 721 } 722 void writeCtorDefaultInitializers(raw_ostream &OS) const { 723 OS << getLowerName() << "()"; 724 } 725 void writeCtorParameters(raw_ostream &OS) const { 726 OS << "VersionTuple " << getUpperName(); 727 } 728 void writeDeclarations(raw_ostream &OS) const { 729 OS << "VersionTuple " << getLowerName() << ";\n"; 730 } 731 void writePCHReadDecls(raw_ostream &OS) const { 732 OS << " VersionTuple " << getLowerName() 733 << "= ReadVersionTuple(Record, Idx);\n"; 734 } 735 void writePCHReadArgs(raw_ostream &OS) const { 736 OS << getLowerName(); 737 } 738 void writePCHWrite(raw_ostream &OS) const { 739 OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n"; 740 } 741 void writeValue(raw_ostream &OS) const { 742 OS << getLowerName() << "=\" << get" << getUpperName() << "() << \""; 743 } 744 void writeDump(raw_ostream &OS) const { 745 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; 746 } 747 }; 748 749 class ExprArgument : public SimpleArgument { 750 public: 751 ExprArgument(Record &Arg, StringRef Attr) 752 : SimpleArgument(Arg, Attr, "Expr *") 753 {} 754 755 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 756 OS << "tempInst" << getUpperName(); 757 } 758 759 void writeTemplateInstantiation(raw_ostream &OS) const { 760 OS << " " << getType() << " tempInst" << getUpperName() << ";\n"; 761 OS << " {\n"; 762 OS << " EnterExpressionEvaluationContext " 763 << "Unevaluated(S, Sema::Unevaluated);\n"; 764 OS << " ExprResult " << "Result = S.SubstExpr(" 765 << "A->get" << getUpperName() << "(), TemplateArgs);\n"; 766 OS << " tempInst" << getUpperName() << " = " 767 << "Result.takeAs<Expr>();\n"; 768 OS << " }\n"; 769 } 770 771 void writeDump(raw_ostream &OS) const { 772 } 773 774 void writeDumpChildren(raw_ostream &OS) const { 775 OS << " lastChild();\n"; 776 OS << " dumpStmt(SA->get" << getUpperName() << "());\n"; 777 } 778 void writeHasChildren(raw_ostream &OS) const { OS << "true"; } 779 }; 780 781 class VariadicExprArgument : public VariadicArgument { 782 public: 783 VariadicExprArgument(Record &Arg, StringRef Attr) 784 : VariadicArgument(Arg, Attr, "Expr *") 785 {} 786 787 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 788 OS << "tempInst" << getUpperName() << ", " 789 << "A->" << getLowerName() << "_size()"; 790 } 791 792 void writeTemplateInstantiation(raw_ostream &OS) const { 793 OS << " " << getType() << " *tempInst" << getUpperName() 794 << " = new (C, 16) " << getType() 795 << "[A->" << getLowerName() << "_size()];\n"; 796 OS << " {\n"; 797 OS << " EnterExpressionEvaluationContext " 798 << "Unevaluated(S, Sema::Unevaluated);\n"; 799 OS << " " << getType() << " *TI = tempInst" << getUpperName() 800 << ";\n"; 801 OS << " " << getType() << " *I = A->" << getLowerName() 802 << "_begin();\n"; 803 OS << " " << getType() << " *E = A->" << getLowerName() 804 << "_end();\n"; 805 OS << " for (; I != E; ++I, ++TI) {\n"; 806 OS << " ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n"; 807 OS << " *TI = Result.takeAs<Expr>();\n"; 808 OS << " }\n"; 809 OS << " }\n"; 810 } 811 812 void writeDump(raw_ostream &OS) const { 813 } 814 815 void writeDumpChildren(raw_ostream &OS) const { 816 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 817 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" 818 << getLowerName() << "_end(); I != E; ++I) {\n"; 819 OS << " if (I + 1 == E)\n"; 820 OS << " lastChild();\n"; 821 OS << " dumpStmt(*I);\n"; 822 OS << " }\n"; 823 } 824 825 void writeHasChildren(raw_ostream &OS) const { 826 OS << "SA->" << getLowerName() << "_begin() != " 827 << "SA->" << getLowerName() << "_end()"; 828 } 829 }; 830 } 831 832 static Argument *createArgument(Record &Arg, StringRef Attr, 833 Record *Search = 0) { 834 if (!Search) 835 Search = &Arg; 836 837 Argument *Ptr = 0; 838 llvm::StringRef ArgName = Search->getName(); 839 840 if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr); 841 else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr); 842 else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr); 843 else if (ArgName == "FunctionArgument") 844 Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *"); 845 else if (ArgName == "IdentifierArgument") 846 Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *"); 847 else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 848 "bool"); 849 else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int"); 850 else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr); 851 else if (ArgName == "TypeArgument") 852 Ptr = new SimpleArgument(Arg, Attr, "QualType"); 853 else if (ArgName == "UnsignedArgument") 854 Ptr = new SimpleArgument(Arg, Attr, "unsigned"); 855 else if (ArgName == "SourceLocArgument") 856 Ptr = new SimpleArgument(Arg, Attr, "SourceLocation"); 857 else if (ArgName == "VariadicUnsignedArgument") 858 Ptr = new VariadicArgument(Arg, Attr, "unsigned"); 859 else if (ArgName == "VariadicEnumArgument") 860 Ptr = new VariadicEnumArgument(Arg, Attr); 861 else if (ArgName == "VariadicExprArgument") 862 Ptr = new VariadicExprArgument(Arg, Attr); 863 else if (ArgName == "VersionArgument") 864 Ptr = new VersionArgument(Arg, Attr); 865 866 if (!Ptr) { 867 std::vector<Record*> Bases = Search->getSuperClasses(); 868 for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end(); 869 i != e; ++i) { 870 Ptr = createArgument(Arg, Attr, *i); 871 if (Ptr) 872 break; 873 } 874 } 875 876 if (Ptr && Arg.getValueAsBit("Optional")) 877 Ptr->setOptional(true); 878 879 return Ptr; 880 } 881 882 static void writeAvailabilityValue(raw_ostream &OS) { 883 OS << "\" << getPlatform()->getName();\n" 884 << " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n" 885 << " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n" 886 << " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n" 887 << " if (getUnavailable()) OS << \", unavailable\";\n" 888 << " OS << \""; 889 } 890 891 static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args, 892 raw_ostream &OS) { 893 std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); 894 895 OS << "void " << R.getName() << "Attr::printPretty(" 896 << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n"; 897 898 if (Spellings.size() == 0) { 899 OS << "}\n\n"; 900 return; 901 } 902 903 OS << 904 " switch (SpellingListIndex) {\n" 905 " default:\n" 906 " llvm_unreachable(\"Unknown attribute spelling!\");\n" 907 " break;\n"; 908 909 for (unsigned I = 0; I < Spellings.size(); ++ I) { 910 llvm::SmallString<16> Prefix; 911 llvm::SmallString<8> Suffix; 912 // The actual spelling of the name and namespace (if applicable) 913 // of an attribute without considering prefix and suffix. 914 llvm::SmallString<64> Spelling; 915 std::string Name = Spellings[I]->getValueAsString("Name"); 916 std::string Variety = Spellings[I]->getValueAsString("Variety"); 917 918 if (Variety == "GNU") { 919 Prefix = " __attribute__(("; 920 Suffix = "))"; 921 } else if (Variety == "CXX11") { 922 Prefix = " [["; 923 Suffix = "]]"; 924 std::string Namespace = Spellings[I]->getValueAsString("Namespace"); 925 if (Namespace != "") { 926 Spelling += Namespace; 927 Spelling += "::"; 928 } 929 } else if (Variety == "Declspec") { 930 Prefix = " __declspec("; 931 Suffix = ")"; 932 } else if (Variety == "Keyword") { 933 Prefix = " "; 934 Suffix = ""; 935 } else { 936 llvm_unreachable("Unknown attribute syntax variety!"); 937 } 938 939 Spelling += Name; 940 941 OS << 942 " case " << I << " : {\n" 943 " OS << \"" + Prefix.str() + Spelling.str(); 944 945 if (Args.size()) OS << "("; 946 if (Spelling == "availability") { 947 writeAvailabilityValue(OS); 948 } else { 949 for (std::vector<Argument*>::const_iterator I = Args.begin(), 950 E = Args.end(); I != E; ++ I) { 951 if (I != Args.begin()) OS << ", "; 952 (*I)->writeValue(OS); 953 } 954 } 955 956 if (Args.size()) OS << ")"; 957 OS << Suffix.str() + "\";\n"; 958 959 OS << 960 " break;\n" 961 " }\n"; 962 } 963 964 // End of the switch statement. 965 OS << "}\n"; 966 // End of the print function. 967 OS << "}\n\n"; 968 } 969 970 /// \brief Return the index of a spelling in a spelling list. 971 static unsigned getSpellingListIndex(const std::vector<Record*> &SpellingList, 972 const Record &Spelling) { 973 assert(SpellingList.size() && "Spelling list is empty!"); 974 975 for (unsigned Index = 0; Index < SpellingList.size(); ++Index) { 976 Record *S = SpellingList[Index]; 977 if (S->getValueAsString("Variety") != Spelling.getValueAsString("Variety")) 978 continue; 979 if (S->getValueAsString("Variety") == "CXX11" && 980 S->getValueAsString("Namespace") != 981 Spelling.getValueAsString("Namespace")) 982 continue; 983 if (S->getValueAsString("Name") != Spelling.getValueAsString("Name")) 984 continue; 985 986 return Index; 987 } 988 989 llvm_unreachable("Unknown spelling!"); 990 } 991 992 static void writeAttrAccessorDefinition(Record &R, raw_ostream &OS) { 993 std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors"); 994 for (std::vector<Record*>::const_iterator I = Accessors.begin(), 995 E = Accessors.end(); I != E; ++I) { 996 Record *Accessor = *I; 997 std::string Name = Accessor->getValueAsString("Name"); 998 std::vector<Record*> Spellings = Accessor->getValueAsListOfDefs( 999 "Spellings"); 1000 std::vector<Record*> SpellingList = R.getValueAsListOfDefs("Spellings"); 1001 assert(SpellingList.size() && 1002 "Attribute with empty spelling list can't have accessors!"); 1003 1004 OS << " bool " << Name << "() const { return SpellingListIndex == "; 1005 for (unsigned Index = 0; Index < Spellings.size(); ++Index) { 1006 OS << getSpellingListIndex(SpellingList, *Spellings[Index]); 1007 if (Index != Spellings.size() -1) 1008 OS << " ||\n SpellingListIndex == "; 1009 else 1010 OS << "; }\n"; 1011 } 1012 } 1013 } 1014 1015 namespace clang { 1016 1017 // Emits the class definitions for attributes. 1018 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { 1019 emitSourceFileHeader("Attribute classes' definitions", OS); 1020 1021 OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; 1022 OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; 1023 1024 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1025 1026 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 1027 i != e; ++i) { 1028 Record &R = **i; 1029 1030 if (!R.getValueAsBit("ASTNode")) 1031 continue; 1032 1033 const std::vector<Record *> Supers = R.getSuperClasses(); 1034 assert(!Supers.empty() && "Forgot to specify a superclass for the attr"); 1035 std::string SuperName; 1036 for (std::vector<Record *>::const_reverse_iterator I = Supers.rbegin(), 1037 E = Supers.rend(); I != E; ++I) { 1038 const Record &R = **I; 1039 if (R.getName() != "TargetSpecificAttr" && SuperName.empty()) 1040 SuperName = R.getName(); 1041 } 1042 1043 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; 1044 1045 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 1046 std::vector<Argument*> Args; 1047 std::vector<Argument*>::iterator ai, ae; 1048 Args.reserve(ArgRecords.size()); 1049 1050 for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 1051 re = ArgRecords.end(); 1052 ri != re; ++ri) { 1053 Record &ArgRecord = **ri; 1054 Argument *Arg = createArgument(ArgRecord, R.getName()); 1055 assert(Arg); 1056 Args.push_back(Arg); 1057 1058 Arg->writeDeclarations(OS); 1059 OS << "\n\n"; 1060 } 1061 1062 ae = Args.end(); 1063 1064 OS << "\n public:\n"; 1065 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; 1066 1067 bool HasOpt = false; 1068 for (ai = Args.begin(); ai != ae; ++ai) { 1069 OS << " , "; 1070 (*ai)->writeCtorParameters(OS); 1071 OS << "\n"; 1072 if ((*ai)->isOptional()) 1073 HasOpt = true; 1074 } 1075 1076 OS << " , "; 1077 OS << "unsigned SI = 0\n"; 1078 1079 OS << " )\n"; 1080 OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; 1081 1082 for (ai = Args.begin(); ai != ae; ++ai) { 1083 OS << " , "; 1084 (*ai)->writeCtorInitializers(OS); 1085 OS << "\n"; 1086 } 1087 1088 OS << " {\n"; 1089 1090 for (ai = Args.begin(); ai != ae; ++ai) { 1091 (*ai)->writeCtorBody(OS); 1092 OS << "\n"; 1093 } 1094 OS << " }\n\n"; 1095 1096 // If there are optional arguments, write out a constructor that elides the 1097 // optional arguments as well. 1098 if (HasOpt) { 1099 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; 1100 for (ai = Args.begin(); ai != ae; ++ai) { 1101 if (!(*ai)->isOptional()) { 1102 OS << " , "; 1103 (*ai)->writeCtorParameters(OS); 1104 OS << "\n"; 1105 } 1106 } 1107 1108 OS << " , "; 1109 OS << "unsigned SI = 0\n"; 1110 1111 OS << " )\n"; 1112 OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; 1113 1114 for (ai = Args.begin(); ai != ae; ++ai) { 1115 OS << " , "; 1116 (*ai)->writeCtorDefaultInitializers(OS); 1117 OS << "\n"; 1118 } 1119 1120 OS << " {\n"; 1121 1122 for (ai = Args.begin(); ai != ae; ++ai) { 1123 if (!(*ai)->isOptional()) { 1124 (*ai)->writeCtorBody(OS); 1125 OS << "\n"; 1126 } 1127 } 1128 OS << " }\n\n"; 1129 } 1130 1131 OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; 1132 OS << " virtual void printPretty(raw_ostream &OS,\n" 1133 << " const PrintingPolicy &Policy) const;\n"; 1134 1135 writeAttrAccessorDefinition(R, OS); 1136 1137 for (ai = Args.begin(); ai != ae; ++ai) { 1138 (*ai)->writeAccessors(OS); 1139 OS << "\n\n"; 1140 1141 if ((*ai)->isEnumArg()) { 1142 EnumArgument *EA = (EnumArgument *)*ai; 1143 EA->writeConversion(OS); 1144 } else if ((*ai)->isVariadicEnumArg()) { 1145 VariadicEnumArgument *VEA = (VariadicEnumArgument *)*ai; 1146 VEA->writeConversion(OS); 1147 } 1148 } 1149 1150 OS << R.getValueAsString("AdditionalMembers"); 1151 OS << "\n\n"; 1152 1153 OS << " static bool classof(const Attr *A) { return A->getKind() == " 1154 << "attr::" << R.getName() << "; }\n"; 1155 1156 bool LateParsed = R.getValueAsBit("LateParsed"); 1157 OS << " virtual bool isLateParsed() const { return " 1158 << LateParsed << "; }\n"; 1159 1160 OS << "};\n\n"; 1161 } 1162 1163 OS << "#endif\n"; 1164 } 1165 1166 static bool isIdentifierArgument(Record *Arg) { 1167 return !Arg->getSuperClasses().empty() && 1168 llvm::StringSwitch<bool>(Arg->getSuperClasses().back()->getName()) 1169 .Case("IdentifierArgument", true) 1170 .Case("EnumArgument", true) 1171 .Default(false); 1172 } 1173 1174 // Emits the first-argument-is-identifier property for attributes. 1175 void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) { 1176 emitSourceFileHeader("llvm::StringSwitch code to match attributes with " 1177 "an identifier argument", OS); 1178 1179 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1180 1181 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1182 I != E; ++I) { 1183 Record &Attr = **I; 1184 1185 // Determine whether the first argument is an identifier. 1186 std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args"); 1187 if (Args.empty() || !isIdentifierArgument(Args[0])) 1188 continue; 1189 1190 // All these spellings take an identifier argument. 1191 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); 1192 std::set<std::string> Emitted; 1193 for (std::vector<Record*>::const_iterator I = Spellings.begin(), 1194 E = Spellings.end(); I != E; ++I) { 1195 if (Emitted.insert((*I)->getValueAsString("Name")).second) 1196 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", " 1197 << "true" << ")\n"; 1198 } 1199 } 1200 } 1201 1202 // Emits the class method definitions for attributes. 1203 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { 1204 emitSourceFileHeader("Attribute classes' member function definitions", OS); 1205 1206 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1207 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; 1208 std::vector<Argument*>::iterator ai, ae; 1209 1210 for (; i != e; ++i) { 1211 Record &R = **i; 1212 1213 if (!R.getValueAsBit("ASTNode")) 1214 continue; 1215 1216 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 1217 std::vector<Argument*> Args; 1218 for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) 1219 Args.push_back(createArgument(**ri, R.getName())); 1220 1221 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 1222 (*ai)->writeAccessorDefinitions(OS); 1223 1224 OS << R.getName() << "Attr *" << R.getName() 1225 << "Attr::clone(ASTContext &C) const {\n"; 1226 OS << " return new (C) " << R.getName() << "Attr(getLocation(), C"; 1227 for (ai = Args.begin(); ai != ae; ++ai) { 1228 OS << ", "; 1229 (*ai)->writeCloneArgs(OS); 1230 } 1231 OS << ", getSpellingListIndex());\n}\n\n"; 1232 1233 writePrettyPrintFunction(R, Args, OS); 1234 } 1235 } 1236 1237 } // end namespace clang 1238 1239 static void EmitAttrList(raw_ostream &OS, StringRef Class, 1240 const std::vector<Record*> &AttrList) { 1241 std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end(); 1242 1243 if (i != e) { 1244 // Move the end iterator back to emit the last attribute. 1245 for(--e; i != e; ++i) { 1246 if (!(*i)->getValueAsBit("ASTNode")) 1247 continue; 1248 1249 OS << Class << "(" << (*i)->getName() << ")\n"; 1250 } 1251 1252 OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; 1253 } 1254 } 1255 1256 namespace clang { 1257 1258 // Emits the enumeration list for attributes. 1259 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { 1260 emitSourceFileHeader("List of all attributes that Clang recognizes", OS); 1261 1262 OS << "#ifndef LAST_ATTR\n"; 1263 OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; 1264 OS << "#endif\n\n"; 1265 1266 OS << "#ifndef INHERITABLE_ATTR\n"; 1267 OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n"; 1268 OS << "#endif\n\n"; 1269 1270 OS << "#ifndef LAST_INHERITABLE_ATTR\n"; 1271 OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; 1272 OS << "#endif\n\n"; 1273 1274 OS << "#ifndef INHERITABLE_PARAM_ATTR\n"; 1275 OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n"; 1276 OS << "#endif\n\n"; 1277 1278 OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n"; 1279 OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)" 1280 " INHERITABLE_PARAM_ATTR(NAME)\n"; 1281 OS << "#endif\n\n"; 1282 1283 OS << "#ifndef MS_INHERITANCE_ATTR\n"; 1284 OS << "#define MS_INHERITANCE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; 1285 OS << "#endif\n\n"; 1286 1287 OS << "#ifndef LAST_MS_INHERITANCE_ATTR\n"; 1288 OS << "#define LAST_MS_INHERITANCE_ATTR(NAME)" 1289 " MS_INHERITANCE_ATTR(NAME)\n"; 1290 OS << "#endif\n\n"; 1291 1292 Record *InhClass = Records.getClass("InheritableAttr"); 1293 Record *InhParamClass = Records.getClass("InheritableParamAttr"); 1294 Record *MSInheritanceClass = Records.getClass("MSInheritanceAttr"); 1295 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 1296 NonInhAttrs, InhAttrs, InhParamAttrs, MSInhAttrs; 1297 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 1298 i != e; ++i) { 1299 if (!(*i)->getValueAsBit("ASTNode")) 1300 continue; 1301 1302 if ((*i)->isSubClassOf(InhParamClass)) 1303 InhParamAttrs.push_back(*i); 1304 else if ((*i)->isSubClassOf(MSInheritanceClass)) 1305 MSInhAttrs.push_back(*i); 1306 else if ((*i)->isSubClassOf(InhClass)) 1307 InhAttrs.push_back(*i); 1308 else 1309 NonInhAttrs.push_back(*i); 1310 } 1311 1312 EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); 1313 EmitAttrList(OS, "MS_INHERITANCE_ATTR", MSInhAttrs); 1314 EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); 1315 EmitAttrList(OS, "ATTR", NonInhAttrs); 1316 1317 OS << "#undef LAST_ATTR\n"; 1318 OS << "#undef INHERITABLE_ATTR\n"; 1319 OS << "#undef MS_INHERITANCE_ATTR\n"; 1320 OS << "#undef LAST_INHERITABLE_ATTR\n"; 1321 OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; 1322 OS << "#undef LAST_MS_INHERITANCE_ATTR\n"; 1323 OS << "#undef ATTR\n"; 1324 } 1325 1326 // Emits the code to read an attribute from a precompiled header. 1327 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { 1328 emitSourceFileHeader("Attribute deserialization code", OS); 1329 1330 Record *InhClass = Records.getClass("InheritableAttr"); 1331 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 1332 ArgRecords; 1333 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 1334 std::vector<Argument*> Args; 1335 std::vector<Argument*>::iterator ri, re; 1336 1337 OS << " switch (Kind) {\n"; 1338 OS << " default:\n"; 1339 OS << " assert(0 && \"Unknown attribute!\");\n"; 1340 OS << " break;\n"; 1341 for (; i != e; ++i) { 1342 Record &R = **i; 1343 if (!R.getValueAsBit("ASTNode")) 1344 continue; 1345 1346 OS << " case attr::" << R.getName() << ": {\n"; 1347 if (R.isSubClassOf(InhClass)) 1348 OS << " bool isInherited = Record[Idx++];\n"; 1349 ArgRecords = R.getValueAsListOfDefs("Args"); 1350 Args.clear(); 1351 for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { 1352 Argument *A = createArgument(**ai, R.getName()); 1353 Args.push_back(A); 1354 A->writePCHReadDecls(OS); 1355 } 1356 OS << " New = new (Context) " << R.getName() << "Attr(Range, Context"; 1357 for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) { 1358 OS << ", "; 1359 (*ri)->writePCHReadArgs(OS); 1360 } 1361 OS << ");\n"; 1362 if (R.isSubClassOf(InhClass)) 1363 OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n"; 1364 OS << " break;\n"; 1365 OS << " }\n"; 1366 } 1367 OS << " }\n"; 1368 } 1369 1370 // Emits the code to write an attribute to a precompiled header. 1371 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) { 1372 emitSourceFileHeader("Attribute serialization code", OS); 1373 1374 Record *InhClass = Records.getClass("InheritableAttr"); 1375 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; 1376 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 1377 1378 OS << " switch (A->getKind()) {\n"; 1379 OS << " default:\n"; 1380 OS << " llvm_unreachable(\"Unknown attribute kind!\");\n"; 1381 OS << " break;\n"; 1382 for (; i != e; ++i) { 1383 Record &R = **i; 1384 if (!R.getValueAsBit("ASTNode")) 1385 continue; 1386 OS << " case attr::" << R.getName() << ": {\n"; 1387 Args = R.getValueAsListOfDefs("Args"); 1388 if (R.isSubClassOf(InhClass) || !Args.empty()) 1389 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() 1390 << "Attr>(A);\n"; 1391 if (R.isSubClassOf(InhClass)) 1392 OS << " Record.push_back(SA->isInherited());\n"; 1393 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 1394 createArgument(**ai, R.getName())->writePCHWrite(OS); 1395 OS << " break;\n"; 1396 OS << " }\n"; 1397 } 1398 OS << " }\n"; 1399 } 1400 1401 // Emits the list of spellings for attributes. 1402 void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) { 1403 emitSourceFileHeader("llvm::StringSwitch code to match all known attributes", 1404 OS); 1405 1406 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1407 1408 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { 1409 Record &Attr = **I; 1410 1411 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); 1412 1413 for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { 1414 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n"; 1415 } 1416 } 1417 1418 } 1419 1420 void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) { 1421 emitSourceFileHeader("Code to translate different attribute spellings " 1422 "into internal identifiers", OS); 1423 1424 OS << 1425 " unsigned Index = 0;\n" 1426 " switch (AttrKind) {\n" 1427 " default:\n" 1428 " llvm_unreachable(\"Unknown attribute kind!\");\n" 1429 " break;\n"; 1430 1431 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1432 for (std::vector<Record*>::const_iterator I = Attrs.begin(), E = Attrs.end(); 1433 I != E; ++I) { 1434 Record &R = **I; 1435 // We only care about attributes that participate in Sema checking, so 1436 // skip those attributes that are not able to make their way to Sema. 1437 if (!R.getValueAsBit("SemaHandler")) 1438 continue; 1439 1440 std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); 1441 // Each distinct spelling yields an attribute kind. 1442 if (R.getValueAsBit("DistinctSpellings")) { 1443 for (unsigned I = 0; I < Spellings.size(); ++ I) { 1444 OS << 1445 " case AT_" << Spellings[I]->getValueAsString("Name") << ": \n" 1446 " Index = " << I << ";\n" 1447 " break;\n"; 1448 } 1449 } else { 1450 OS << " case AT_" << R.getName() << " : {\n"; 1451 for (unsigned I = 0; I < Spellings.size(); ++ I) { 1452 SmallString<16> Namespace; 1453 if (Spellings[I]->getValueAsString("Variety") == "CXX11") 1454 Namespace = Spellings[I]->getValueAsString("Namespace"); 1455 else 1456 Namespace = ""; 1457 1458 OS << " if (Name == \"" 1459 << Spellings[I]->getValueAsString("Name") << "\" && " 1460 << "SyntaxUsed == " 1461 << StringSwitch<unsigned>(Spellings[I]->getValueAsString("Variety")) 1462 .Case("GNU", 0) 1463 .Case("CXX11", 1) 1464 .Case("Declspec", 2) 1465 .Case("Keyword", 3) 1466 .Default(0) 1467 << " && Scope == \"" << Namespace << "\")\n" 1468 << " return " << I << ";\n"; 1469 } 1470 1471 OS << " break;\n"; 1472 OS << " }\n"; 1473 } 1474 } 1475 1476 OS << " }\n"; 1477 OS << " return Index;\n"; 1478 } 1479 1480 // Emits the LateParsed property for attributes. 1481 void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) { 1482 emitSourceFileHeader("llvm::StringSwitch code to match late parsed " 1483 "attributes", OS); 1484 1485 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1486 1487 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1488 I != E; ++I) { 1489 Record &Attr = **I; 1490 1491 bool LateParsed = Attr.getValueAsBit("LateParsed"); 1492 1493 if (LateParsed) { 1494 std::vector<Record*> Spellings = 1495 Attr.getValueAsListOfDefs("Spellings"); 1496 1497 // FIXME: Handle non-GNU attributes 1498 for (std::vector<Record*>::const_iterator I = Spellings.begin(), 1499 E = Spellings.end(); I != E; ++I) { 1500 if ((*I)->getValueAsString("Variety") != "GNU") 1501 continue; 1502 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", " 1503 << LateParsed << ")\n"; 1504 } 1505 } 1506 } 1507 } 1508 1509 // Emits code to instantiate dependent attributes on templates. 1510 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { 1511 emitSourceFileHeader("Template instantiation code for attributes", OS); 1512 1513 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1514 1515 OS << "namespace clang {\n" 1516 << "namespace sema {\n\n" 1517 << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, " 1518 << "Sema &S,\n" 1519 << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n" 1520 << " switch (At->getKind()) {\n" 1521 << " default:\n" 1522 << " break;\n"; 1523 1524 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1525 I != E; ++I) { 1526 Record &R = **I; 1527 if (!R.getValueAsBit("ASTNode")) 1528 continue; 1529 1530 OS << " case attr::" << R.getName() << ": {\n"; 1531 bool ShouldClone = R.getValueAsBit("Clone"); 1532 1533 if (!ShouldClone) { 1534 OS << " return NULL;\n"; 1535 OS << " }\n"; 1536 continue; 1537 } 1538 1539 OS << " const " << R.getName() << "Attr *A = cast<" 1540 << R.getName() << "Attr>(At);\n"; 1541 bool TDependent = R.getValueAsBit("TemplateDependent"); 1542 1543 if (!TDependent) { 1544 OS << " return A->clone(C);\n"; 1545 OS << " }\n"; 1546 continue; 1547 } 1548 1549 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 1550 std::vector<Argument*> Args; 1551 std::vector<Argument*>::iterator ai, ae; 1552 Args.reserve(ArgRecords.size()); 1553 1554 for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 1555 re = ArgRecords.end(); 1556 ri != re; ++ri) { 1557 Record &ArgRecord = **ri; 1558 Argument *Arg = createArgument(ArgRecord, R.getName()); 1559 assert(Arg); 1560 Args.push_back(Arg); 1561 } 1562 ae = Args.end(); 1563 1564 for (ai = Args.begin(); ai != ae; ++ai) { 1565 (*ai)->writeTemplateInstantiation(OS); 1566 } 1567 OS << " return new (C) " << R.getName() << "Attr(A->getLocation(), C"; 1568 for (ai = Args.begin(); ai != ae; ++ai) { 1569 OS << ", "; 1570 (*ai)->writeTemplateInstantiationArgs(OS); 1571 } 1572 OS << ");\n }\n"; 1573 } 1574 OS << " } // end switch\n" 1575 << " llvm_unreachable(\"Unknown attribute!\");\n" 1576 << " return 0;\n" 1577 << "}\n\n" 1578 << "} // end namespace sema\n" 1579 << "} // end namespace clang\n"; 1580 } 1581 1582 typedef std::vector<std::pair<std::string, Record *> > ParsedAttrMap; 1583 1584 static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records) { 1585 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1586 ParsedAttrMap R; 1587 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1588 I != E; ++I) { 1589 Record &Attr = **I; 1590 1591 bool SemaHandler = Attr.getValueAsBit("SemaHandler"); 1592 bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings"); 1593 1594 if (SemaHandler) { 1595 if (DistinctSpellings) { 1596 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); 1597 1598 for (std::vector<Record*>::const_iterator I = Spellings.begin(), 1599 E = Spellings.end(); I != E; ++I) { 1600 std::string AttrName = (*I)->getValueAsString("Name"); 1601 1602 StringRef Spelling = NormalizeAttrName(AttrName); 1603 R.push_back(std::make_pair(Spelling.str(), &Attr)); 1604 } 1605 } else { 1606 StringRef AttrName = Attr.getName(); 1607 AttrName = NormalizeAttrName(AttrName); 1608 R.push_back(std::make_pair(AttrName.str(), *I)); 1609 } 1610 } 1611 } 1612 return R; 1613 } 1614 1615 // Emits the list of parsed attributes. 1616 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { 1617 emitSourceFileHeader("List of all attributes that Clang recognizes", OS); 1618 1619 OS << "#ifndef PARSED_ATTR\n"; 1620 OS << "#define PARSED_ATTR(NAME) NAME\n"; 1621 OS << "#endif\n\n"; 1622 1623 ParsedAttrMap Names = getParsedAttrList(Records); 1624 for (ParsedAttrMap::iterator I = Names.begin(), E = Names.end(); I != E; 1625 ++I) { 1626 OS << "PARSED_ATTR(" << I->first << ")\n"; 1627 } 1628 } 1629 1630 static void emitArgInfo(const Record &R, raw_ostream &OS) { 1631 // This function will count the number of arguments specified for the 1632 // attribute and emit the number of required arguments followed by the 1633 // number of optional arguments. 1634 std::vector<Record *> Args = R.getValueAsListOfDefs("Args"); 1635 unsigned ArgCount = 0, OptCount = 0; 1636 for (std::vector<Record *>::const_iterator I = Args.begin(), E = Args.end(); 1637 I != E; ++I) { 1638 const Record &Arg = **I; 1639 Arg.getValueAsBit("Optional") ? ++OptCount : ++ArgCount; 1640 } 1641 OS << ArgCount << ", " << OptCount; 1642 } 1643 1644 /// Emits the parsed attribute helpers 1645 void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) { 1646 emitSourceFileHeader("Parsed attribute helpers", OS); 1647 1648 ParsedAttrMap Attrs = getParsedAttrList(Records); 1649 1650 OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n"; 1651 for (ParsedAttrMap::iterator I = Attrs.begin(), E = Attrs.end(); I != E; 1652 ++I) { 1653 // We need to generate struct instances based off ParsedAttrInfo from 1654 // AttributeList.cpp. 1655 OS << " { "; 1656 emitArgInfo(*I->second, OS); 1657 OS << ", " << I->second->getValueAsBit("HasCustomParsing"); 1658 OS << " }"; 1659 1660 if (I + 1 != E) 1661 OS << ","; 1662 1663 OS << " // AT_" << I->first << "\n"; 1664 } 1665 OS << "};\n\n"; 1666 } 1667 1668 // Emits the kind list of parsed attributes 1669 void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { 1670 emitSourceFileHeader("Attribute name matcher", OS); 1671 1672 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1673 1674 std::vector<StringMatcher::StringPair> Matches; 1675 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1676 I != E; ++I) { 1677 Record &Attr = **I; 1678 1679 bool SemaHandler = Attr.getValueAsBit("SemaHandler"); 1680 bool Ignored = Attr.getValueAsBit("Ignored"); 1681 bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings"); 1682 if (SemaHandler || Ignored) { 1683 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); 1684 1685 for (std::vector<Record*>::const_iterator I = Spellings.begin(), 1686 E = Spellings.end(); I != E; ++I) { 1687 std::string RawSpelling = (*I)->getValueAsString("Name"); 1688 StringRef AttrName = NormalizeAttrName(DistinctSpellings 1689 ? StringRef(RawSpelling) 1690 : StringRef(Attr.getName())); 1691 1692 SmallString<64> Spelling; 1693 if ((*I)->getValueAsString("Variety") == "CXX11") { 1694 Spelling += (*I)->getValueAsString("Namespace"); 1695 Spelling += "::"; 1696 } 1697 Spelling += NormalizeAttrSpelling(RawSpelling); 1698 1699 if (SemaHandler) 1700 Matches.push_back( 1701 StringMatcher::StringPair( 1702 StringRef(Spelling), 1703 "return AttributeList::AT_" + AttrName.str() + ";")); 1704 else 1705 Matches.push_back( 1706 StringMatcher::StringPair( 1707 StringRef(Spelling), 1708 "return AttributeList::IgnoredAttribute;")); 1709 } 1710 } 1711 } 1712 1713 OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n"; 1714 StringMatcher("Name", Matches, OS).Emit(); 1715 OS << "return AttributeList::UnknownAttribute;\n" 1716 << "}\n"; 1717 } 1718 1719 // Emits the code to dump an attribute. 1720 void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) { 1721 emitSourceFileHeader("Attribute dumper", OS); 1722 1723 OS << 1724 " switch (A->getKind()) {\n" 1725 " default:\n" 1726 " llvm_unreachable(\"Unknown attribute kind!\");\n" 1727 " break;\n"; 1728 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; 1729 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1730 I != E; ++I) { 1731 Record &R = **I; 1732 if (!R.getValueAsBit("ASTNode")) 1733 continue; 1734 OS << " case attr::" << R.getName() << ": {\n"; 1735 Args = R.getValueAsListOfDefs("Args"); 1736 if (!Args.empty()) { 1737 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() 1738 << "Attr>(A);\n"; 1739 for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end(); 1740 I != E; ++I) 1741 createArgument(**I, R.getName())->writeDump(OS); 1742 1743 // Code for detecting the last child. 1744 OS << " bool OldMoreChildren = hasMoreChildren();\n"; 1745 OS << " bool MoreChildren = OldMoreChildren;\n"; 1746 1747 for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end(); 1748 I != E; ++I) { 1749 // More code for detecting the last child. 1750 OS << " MoreChildren = OldMoreChildren"; 1751 for (std::vector<Record*>::iterator Next = I + 1; Next != E; ++Next) { 1752 OS << " || "; 1753 createArgument(**Next, R.getName())->writeHasChildren(OS); 1754 } 1755 OS << ";\n"; 1756 OS << " setMoreChildren(MoreChildren);\n"; 1757 1758 createArgument(**I, R.getName())->writeDumpChildren(OS); 1759 } 1760 1761 // Reset the last child. 1762 OS << " setMoreChildren(OldMoreChildren);\n"; 1763 } 1764 OS << 1765 " break;\n" 1766 " }\n"; 1767 } 1768 OS << " }\n"; 1769 } 1770 1771 } // end namespace clang 1772