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