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