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