ClangAttrEmitter.cpp revision 7b9ff0c09025dcbe48ec7db71330e2066d1e1863
1//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// These tablegen backends emit Clang attribute processing code 11// 12//===----------------------------------------------------------------------===// 13 14#include "ClangAttrEmitter.h" 15#include "llvm/ADT/StringSwitch.h" 16#include "llvm/TableGen/Record.h" 17#include <algorithm> 18#include <cctype> 19 20using namespace llvm; 21 22static const std::vector<StringRef> 23getValueAsListOfStrings(Record &R, StringRef FieldName) { 24 ListInit *List = R.getValueAsListInit(FieldName); 25 assert (List && "Got a null ListInit"); 26 27 std::vector<StringRef> Strings; 28 Strings.reserve(List->getSize()); 29 30 for (ListInit::const_iterator i = List->begin(), e = List->end(); 31 i != e; 32 ++i) { 33 assert(*i && "Got a null element in a ListInit"); 34 if (StringInit *S = dynamic_cast<StringInit *>(*i)) 35 Strings.push_back(S->getValue()); 36 else 37 assert(false && "Got a non-string, non-code element in a ListInit"); 38 } 39 40 return Strings; 41} 42 43static std::string ReadPCHRecord(StringRef type) { 44 return StringSwitch<std::string>(type) 45 .EndsWith("Decl *", "GetLocalDeclAs<" 46 + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])") 47 .Case("QualType", "getLocalType(F, Record[Idx++])") 48 .Case("Expr *", "ReadSubExpr()") 49 .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)") 50 .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)") 51 .Default("Record[Idx++]"); 52} 53 54// Assumes that the way to get the value is SA->getname() 55static std::string WritePCHRecord(StringRef type, StringRef name) { 56 return StringSwitch<std::string>(type) 57 .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + 58 ", Record);\n") 59 .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n") 60 .Case("Expr *", "AddStmt(" + std::string(name) + ");\n") 61 .Case("IdentifierInfo *", 62 "AddIdentifierRef(" + std::string(name) + ", Record);\n") 63 .Case("SourceLocation", 64 "AddSourceLocation(" + std::string(name) + ", Record);\n") 65 .Default("Record.push_back(" + std::string(name) + ");\n"); 66} 67 68namespace { 69 class Argument { 70 std::string lowerName, upperName; 71 StringRef attrName; 72 73 public: 74 Argument(Record &Arg, StringRef Attr) 75 : lowerName(Arg.getValueAsString("Name")), upperName(lowerName), 76 attrName(Attr) { 77 if (!lowerName.empty()) { 78 lowerName[0] = std::tolower(lowerName[0]); 79 upperName[0] = std::toupper(upperName[0]); 80 } 81 } 82 virtual ~Argument() {} 83 84 StringRef getLowerName() const { return lowerName; } 85 StringRef getUpperName() const { return upperName; } 86 StringRef getAttrName() const { return attrName; } 87 88 // These functions print the argument contents formatted in different ways. 89 virtual void writeAccessors(raw_ostream &OS) const = 0; 90 virtual void writeAccessorDefinitions(raw_ostream &OS) const {} 91 virtual void writeCloneArgs(raw_ostream &OS) const = 0; 92 virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0; 93 virtual void writeTemplateInstantiation(raw_ostream &OS) const {}; 94 virtual void writeCtorBody(raw_ostream &OS) const {} 95 virtual void writeCtorInitializers(raw_ostream &OS) const = 0; 96 virtual void writeCtorParameters(raw_ostream &OS) const = 0; 97 virtual void writeDeclarations(raw_ostream &OS) const = 0; 98 virtual void writePCHReadArgs(raw_ostream &OS) const = 0; 99 virtual void writePCHReadDecls(raw_ostream &OS) const = 0; 100 virtual void writePCHWrite(raw_ostream &OS) const = 0; 101 virtual void writeValue(raw_ostream &OS) const = 0; 102 }; 103 104 class SimpleArgument : public Argument { 105 std::string type; 106 107 public: 108 SimpleArgument(Record &Arg, StringRef Attr, std::string T) 109 : Argument(Arg, Attr), type(T) 110 {} 111 112 std::string getType() const { return type; } 113 114 void writeAccessors(raw_ostream &OS) const { 115 OS << " " << type << " get" << getUpperName() << "() const {\n"; 116 OS << " return " << getLowerName() << ";\n"; 117 OS << " }"; 118 } 119 void writeCloneArgs(raw_ostream &OS) const { 120 OS << getLowerName(); 121 } 122 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 123 OS << "A->get" << getUpperName() << "()"; 124 } 125 void writeCtorInitializers(raw_ostream &OS) const { 126 OS << getLowerName() << "(" << getUpperName() << ")"; 127 } 128 void writeCtorParameters(raw_ostream &OS) const { 129 OS << type << " " << getUpperName(); 130 } 131 void writeDeclarations(raw_ostream &OS) const { 132 OS << type << " " << getLowerName() << ";"; 133 } 134 void writePCHReadDecls(raw_ostream &OS) const { 135 std::string read = ReadPCHRecord(type); 136 OS << " " << type << " " << getLowerName() << " = " << read << ";\n"; 137 } 138 void writePCHReadArgs(raw_ostream &OS) const { 139 OS << getLowerName(); 140 } 141 void writePCHWrite(raw_ostream &OS) const { 142 OS << " " << WritePCHRecord(type, "SA->get" + 143 std::string(getUpperName()) + "()"); 144 } 145 void writeValue(raw_ostream &OS) const { 146 if (type == "FunctionDecl *") { 147 OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \""; 148 } else if (type == "IdentifierInfo *") { 149 OS << "\" << get" << getUpperName() << "()->getName() << \""; 150 } else if (type == "QualType") { 151 OS << "\" << get" << getUpperName() << "().getAsString() << \""; 152 } else if (type == "SourceLocation") { 153 OS << "\" << get" << getUpperName() << "().getRawEncoding() << \""; 154 } else { 155 OS << "\" << get" << getUpperName() << "() << \""; 156 } 157 } 158 }; 159 160 class StringArgument : public Argument { 161 public: 162 StringArgument(Record &Arg, StringRef Attr) 163 : Argument(Arg, Attr) 164 {} 165 166 void writeAccessors(raw_ostream &OS) const { 167 OS << " llvm::StringRef get" << getUpperName() << "() const {\n"; 168 OS << " return llvm::StringRef(" << getLowerName() << ", " 169 << getLowerName() << "Length);\n"; 170 OS << " }\n"; 171 OS << " unsigned get" << getUpperName() << "Length() const {\n"; 172 OS << " return " << getLowerName() << "Length;\n"; 173 OS << " }\n"; 174 OS << " void set" << getUpperName() 175 << "(ASTContext &C, llvm::StringRef S) {\n"; 176 OS << " " << getLowerName() << "Length = S.size();\n"; 177 OS << " this->" << getLowerName() << " = new (C, 1) char [" 178 << getLowerName() << "Length];\n"; 179 OS << " std::memcpy(this->" << getLowerName() << ", S.data(), " 180 << getLowerName() << "Length);\n"; 181 OS << " }"; 182 } 183 void writeCloneArgs(raw_ostream &OS) const { 184 OS << "get" << getUpperName() << "()"; 185 } 186 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 187 OS << "A->get" << getUpperName() << "()"; 188 } 189 void writeCtorBody(raw_ostream &OS) const { 190 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 191 << ".data(), " << getLowerName() << "Length);"; 192 } 193 void writeCtorInitializers(raw_ostream &OS) const { 194 OS << getLowerName() << "Length(" << getUpperName() << ".size())," 195 << getLowerName() << "(new (Ctx, 1) char[" << getLowerName() 196 << "Length])"; 197 } 198 void writeCtorParameters(raw_ostream &OS) const { 199 OS << "llvm::StringRef " << getUpperName(); 200 } 201 void writeDeclarations(raw_ostream &OS) const { 202 OS << "unsigned " << getLowerName() << "Length;\n"; 203 OS << "char *" << getLowerName() << ";"; 204 } 205 void writePCHReadDecls(raw_ostream &OS) const { 206 OS << " std::string " << getLowerName() 207 << "= ReadString(Record, Idx);\n"; 208 } 209 void writePCHReadArgs(raw_ostream &OS) const { 210 OS << getLowerName(); 211 } 212 void writePCHWrite(raw_ostream &OS) const { 213 OS << " AddString(SA->get" << getUpperName() << "(), Record);\n"; 214 } 215 void writeValue(raw_ostream &OS) const { 216 OS << "\\\"\" << get" << getUpperName() << "() << \"\\\""; 217 } 218 }; 219 220 class AlignedArgument : public Argument { 221 public: 222 AlignedArgument(Record &Arg, StringRef Attr) 223 : Argument(Arg, Attr) 224 {} 225 226 void writeAccessors(raw_ostream &OS) const { 227 OS << " bool is" << getUpperName() << "Dependent() const;\n"; 228 229 OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n"; 230 231 OS << " bool is" << getUpperName() << "Expr() const {\n"; 232 OS << " return is" << getLowerName() << "Expr;\n"; 233 OS << " }\n"; 234 235 OS << " Expr *get" << getUpperName() << "Expr() const {\n"; 236 OS << " assert(is" << getLowerName() << "Expr);\n"; 237 OS << " return " << getLowerName() << "Expr;\n"; 238 OS << " }\n"; 239 240 OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n"; 241 OS << " assert(!is" << getLowerName() << "Expr);\n"; 242 OS << " return " << getLowerName() << "Type;\n"; 243 OS << " }"; 244 } 245 void writeAccessorDefinitions(raw_ostream &OS) const { 246 OS << "bool " << getAttrName() << "Attr::is" << getUpperName() 247 << "Dependent() const {\n"; 248 OS << " if (is" << getLowerName() << "Expr)\n"; 249 OS << " return " << getLowerName() << "Expr && (" << getLowerName() 250 << "Expr->isValueDependent() || " << getLowerName() 251 << "Expr->isTypeDependent());\n"; 252 OS << " else\n"; 253 OS << " return " << getLowerName() 254 << "Type->getType()->isDependentType();\n"; 255 OS << "}\n"; 256 257 // FIXME: Do not do the calculation here 258 // FIXME: Handle types correctly 259 // A null pointer means maximum alignment 260 // FIXME: Load the platform-specific maximum alignment, rather than 261 // 16, the x86 max. 262 OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName() 263 << "(ASTContext &Ctx) const {\n"; 264 OS << " assert(!is" << getUpperName() << "Dependent());\n"; 265 OS << " if (is" << getLowerName() << "Expr)\n"; 266 OS << " return (" << getLowerName() << "Expr ? " << getLowerName() 267 << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)" 268 << "* Ctx.getCharWidth();\n"; 269 OS << " else\n"; 270 OS << " return 0; // FIXME\n"; 271 OS << "}\n"; 272 } 273 void writeCloneArgs(raw_ostream &OS) const { 274 OS << "is" << getLowerName() << "Expr, is" << getLowerName() 275 << "Expr ? static_cast<void*>(" << getLowerName() 276 << "Expr) : " << getLowerName() 277 << "Type"; 278 } 279 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 280 // FIXME: move the definition in Sema::InstantiateAttrs to here. 281 // In the meantime, aligned attributes are cloned. 282 } 283 void writeCtorBody(raw_ostream &OS) const { 284 OS << " if (is" << getLowerName() << "Expr)\n"; 285 OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>(" 286 << getUpperName() << ");\n"; 287 OS << " else\n"; 288 OS << " " << getLowerName() 289 << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName() 290 << ");"; 291 } 292 void writeCtorInitializers(raw_ostream &OS) const { 293 OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)"; 294 } 295 void writeCtorParameters(raw_ostream &OS) const { 296 OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName(); 297 } 298 void writeDeclarations(raw_ostream &OS) const { 299 OS << "bool is" << getLowerName() << "Expr;\n"; 300 OS << "union {\n"; 301 OS << "Expr *" << getLowerName() << "Expr;\n"; 302 OS << "TypeSourceInfo *" << getLowerName() << "Type;\n"; 303 OS << "};"; 304 } 305 void writePCHReadArgs(raw_ostream &OS) const { 306 OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr"; 307 } 308 void writePCHReadDecls(raw_ostream &OS) const { 309 OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n"; 310 OS << " void *" << getLowerName() << "Ptr;\n"; 311 OS << " if (is" << getLowerName() << "Expr)\n"; 312 OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n"; 313 OS << " else\n"; 314 OS << " " << getLowerName() 315 << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n"; 316 } 317 void writePCHWrite(raw_ostream &OS) const { 318 OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n"; 319 OS << " if (SA->is" << getUpperName() << "Expr())\n"; 320 OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n"; 321 OS << " else\n"; 322 OS << " AddTypeSourceInfo(SA->get" << getUpperName() 323 << "Type(), Record);\n"; 324 } 325 void writeValue(raw_ostream &OS) const { 326 OS << "\" << get" << getUpperName() << "(Ctx) << \""; 327 } 328 }; 329 330 class VariadicArgument : public Argument { 331 std::string type; 332 333 public: 334 VariadicArgument(Record &Arg, StringRef Attr, std::string T) 335 : Argument(Arg, Attr), type(T) 336 {} 337 338 std::string getType() const { return type; } 339 340 void writeAccessors(raw_ostream &OS) const { 341 OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n"; 342 OS << " " << getLowerName() << "_iterator " << getLowerName() 343 << "_begin() const {\n"; 344 OS << " return " << getLowerName() << ";\n"; 345 OS << " }\n"; 346 OS << " " << getLowerName() << "_iterator " << getLowerName() 347 << "_end() const {\n"; 348 OS << " return " << getLowerName() << " + " << getLowerName() 349 << "Size;\n"; 350 OS << " }\n"; 351 OS << " unsigned " << getLowerName() << "_size() const {\n" 352 << " return " << getLowerName() << "Size;\n;"; 353 OS << " }"; 354 } 355 void writeCloneArgs(raw_ostream &OS) const { 356 OS << getLowerName() << ", " << getLowerName() << "Size"; 357 } 358 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 359 // This isn't elegant, but we have to go through public methods... 360 OS << "A->" << getLowerName() << "_begin(), " 361 << "A->" << getLowerName() << "_size()"; 362 } 363 void writeCtorBody(raw_ostream &OS) const { 364 // FIXME: memcpy is not safe on non-trivial types. 365 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 366 << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n"; 367 } 368 void writeCtorInitializers(raw_ostream &OS) const { 369 OS << getLowerName() << "Size(" << getUpperName() << "Size), " 370 << getLowerName() << "(new (Ctx, 16) " << getType() << "[" 371 << getLowerName() << "Size])"; 372 } 373 void writeCtorParameters(raw_ostream &OS) const { 374 OS << getType() << " *" << getUpperName() << ", unsigned " 375 << getUpperName() << "Size"; 376 } 377 void writeDeclarations(raw_ostream &OS) const { 378 OS << " unsigned " << getLowerName() << "Size;\n"; 379 OS << " " << getType() << " *" << getLowerName() << ";"; 380 } 381 void writePCHReadDecls(raw_ostream &OS) const { 382 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; 383 OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName() 384 << ";\n"; 385 OS << " " << getLowerName() << ".reserve(" << getLowerName() 386 << "Size);\n"; 387 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; 388 389 std::string read = ReadPCHRecord(type); 390 OS << " " << getLowerName() << ".push_back(" << read << ");\n"; 391 } 392 void writePCHReadArgs(raw_ostream &OS) const { 393 OS << getLowerName() << ".data(), " << getLowerName() << "Size"; 394 } 395 void writePCHWrite(raw_ostream &OS) const{ 396 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; 397 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 398 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" 399 << getLowerName() << "_end(); i != e; ++i)\n"; 400 OS << " " << WritePCHRecord(type, "(*i)"); 401 } 402 void writeValue(raw_ostream &OS) const { 403 OS << "\";\n"; 404 OS << " bool isFirst = true;\n" 405 << " for (" << getAttrName() << "Attr::" << getLowerName() 406 << "_iterator i = " << getLowerName() << "_begin(), e = " 407 << getLowerName() << "_end(); i != e; ++i) {\n" 408 << " if (isFirst) isFirst = false;\n" 409 << " else OS << \", \";\n" 410 << " OS << *i;\n" 411 << " }\n"; 412 OS << " OS << \""; 413 } 414 }; 415 416 class EnumArgument : public Argument { 417 std::string type; 418 std::vector<StringRef> values, enums; 419 public: 420 EnumArgument(Record &Arg, StringRef Attr) 421 : Argument(Arg, Attr), type(Arg.getValueAsString("Type")), 422 values(getValueAsListOfStrings(Arg, "Values")), 423 enums(getValueAsListOfStrings(Arg, "Enums")) 424 {} 425 426 void writeAccessors(raw_ostream &OS) const { 427 OS << " " << type << " get" << getUpperName() << "() const {\n"; 428 OS << " return " << getLowerName() << ";\n"; 429 OS << " }"; 430 } 431 void writeCloneArgs(raw_ostream &OS) const { 432 OS << getLowerName(); 433 } 434 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 435 OS << "A->get" << getUpperName() << "()"; 436 } 437 void writeCtorInitializers(raw_ostream &OS) const { 438 OS << getLowerName() << "(" << getUpperName() << ")"; 439 } 440 void writeCtorParameters(raw_ostream &OS) const { 441 OS << type << " " << getUpperName(); 442 } 443 void writeDeclarations(raw_ostream &OS) const { 444 // Calculate the various enum values 445 std::vector<StringRef> uniques(enums); 446 std::sort(uniques.begin(), uniques.end()); 447 uniques.erase(std::unique(uniques.begin(), uniques.end()), 448 uniques.end()); 449 // FIXME: Emit a proper error 450 assert(!uniques.empty()); 451 452 std::vector<StringRef>::iterator i = uniques.begin(), 453 e = uniques.end(); 454 // The last one needs to not have a comma. 455 --e; 456 457 OS << "public:\n"; 458 OS << " enum " << type << " {\n"; 459 for (; i != e; ++i) 460 OS << " " << *i << ",\n"; 461 OS << " " << *e << "\n"; 462 OS << " };\n"; 463 OS << "private:\n"; 464 OS << " " << type << " " << getLowerName() << ";"; 465 } 466 void writePCHReadDecls(raw_ostream &OS) const { 467 OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName() 468 << "(static_cast<" << getAttrName() << "Attr::" << type 469 << ">(Record[Idx++]));\n"; 470 } 471 void writePCHReadArgs(raw_ostream &OS) const { 472 OS << getLowerName(); 473 } 474 void writePCHWrite(raw_ostream &OS) const { 475 OS << "Record.push_back(SA->get" << getUpperName() << "());\n"; 476 } 477 void writeValue(raw_ostream &OS) const { 478 OS << "\" << get" << getUpperName() << "() << \""; 479 } 480 }; 481 482 class VersionArgument : public Argument { 483 public: 484 VersionArgument(Record &Arg, StringRef Attr) 485 : Argument(Arg, Attr) 486 {} 487 488 void writeAccessors(raw_ostream &OS) const { 489 OS << " VersionTuple get" << getUpperName() << "() const {\n"; 490 OS << " return " << getLowerName() << ";\n"; 491 OS << " }\n"; 492 OS << " void set" << getUpperName() 493 << "(ASTContext &C, VersionTuple V) {\n"; 494 OS << " " << getLowerName() << " = V;\n"; 495 OS << " }"; 496 } 497 void writeCloneArgs(raw_ostream &OS) const { 498 OS << "get" << getUpperName() << "()"; 499 } 500 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 501 OS << "A->get" << getUpperName() << "()"; 502 } 503 void writeCtorBody(raw_ostream &OS) const { 504 } 505 void writeCtorInitializers(raw_ostream &OS) const { 506 OS << getLowerName() << "(" << getUpperName() << ")"; 507 } 508 void writeCtorParameters(raw_ostream &OS) const { 509 OS << "VersionTuple " << getUpperName(); 510 } 511 void writeDeclarations(raw_ostream &OS) const { 512 OS << "VersionTuple " << getLowerName() << ";\n"; 513 } 514 void writePCHReadDecls(raw_ostream &OS) const { 515 OS << " VersionTuple " << getLowerName() 516 << "= ReadVersionTuple(Record, Idx);\n"; 517 } 518 void writePCHReadArgs(raw_ostream &OS) const { 519 OS << getLowerName(); 520 } 521 void writePCHWrite(raw_ostream &OS) const { 522 OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n"; 523 } 524 void writeValue(raw_ostream &OS) const { 525 OS << getLowerName() << "=\" << get" << getUpperName() << "() << \""; 526 } 527 }; 528 529 class ExprArgument : public SimpleArgument { 530 public: 531 ExprArgument(Record &Arg, StringRef Attr) 532 : SimpleArgument(Arg, Attr, "Expr *") 533 {} 534 535 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 536 OS << "tempInst" << getUpperName(); 537 } 538 539 void writeTemplateInstantiation(raw_ostream &OS) const { 540 OS << " " << getType() << " tempInst" << getUpperName() << ";\n"; 541 OS << " {\n"; 542 OS << " EnterExpressionEvaluationContext " 543 << "Unevaluated(S, Sema::Unevaluated);\n"; 544 OS << " ExprResult " << "Result = S.SubstExpr(" 545 << "A->get" << getUpperName() << "(), TemplateArgs);\n"; 546 OS << " tempInst" << getUpperName() << " = " 547 << "Result.takeAs<Expr>();\n"; 548 OS << " }\n"; 549 } 550 }; 551 552 class VariadicExprArgument : public VariadicArgument { 553 public: 554 VariadicExprArgument(Record &Arg, StringRef Attr) 555 : VariadicArgument(Arg, Attr, "Expr *") 556 {} 557 558 void writeTemplateInstantiationArgs(raw_ostream &OS) const { 559 OS << "tempInst" << getUpperName() << ", " 560 << "A->" << getLowerName() << "_size()"; 561 } 562 563 void writeTemplateInstantiation(raw_ostream &OS) const { 564 OS << " " << getType() << " *tempInst" << getUpperName() 565 << " = new (C, 16) " << getType() 566 << "[A->" << getLowerName() << "_size()];\n"; 567 OS << " {\n"; 568 OS << " EnterExpressionEvaluationContext " 569 << "Unevaluated(S, Sema::Unevaluated);\n"; 570 OS << " " << getType() << " *TI = tempInst" << getUpperName() 571 << ";\n"; 572 OS << " " << getType() << " *I = A->" << getLowerName() 573 << "_begin();\n"; 574 OS << " " << getType() << " *E = A->" << getLowerName() 575 << "_end();\n"; 576 OS << " for (; I != E; ++I, ++TI) {\n"; 577 OS << " ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n"; 578 OS << " *TI = Result.takeAs<Expr>();\n"; 579 OS << " }\n"; 580 OS << " }\n"; 581 } 582 }; 583} 584 585static Argument *createArgument(Record &Arg, StringRef Attr, 586 Record *Search = 0) { 587 if (!Search) 588 Search = &Arg; 589 590 Argument *Ptr = 0; 591 llvm::StringRef ArgName = Search->getName(); 592 593 if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr); 594 else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr); 595 else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr); 596 else if (ArgName == "FunctionArgument") 597 Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *"); 598 else if (ArgName == "IdentifierArgument") 599 Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *"); 600 else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 601 "bool"); 602 else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int"); 603 else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr); 604 else if (ArgName == "TypeArgument") 605 Ptr = new SimpleArgument(Arg, Attr, "QualType"); 606 else if (ArgName == "UnsignedArgument") 607 Ptr = new SimpleArgument(Arg, Attr, "unsigned"); 608 else if (ArgName == "SourceLocArgument") 609 Ptr = new SimpleArgument(Arg, Attr, "SourceLocation"); 610 else if (ArgName == "VariadicUnsignedArgument") 611 Ptr = new VariadicArgument(Arg, Attr, "unsigned"); 612 else if (ArgName == "VariadicExprArgument") 613 Ptr = new VariadicExprArgument(Arg, Attr); 614 else if (ArgName == "VersionArgument") 615 Ptr = new VersionArgument(Arg, Attr); 616 617 if (!Ptr) { 618 std::vector<Record*> Bases = Search->getSuperClasses(); 619 for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end(); 620 i != e; ++i) { 621 Ptr = createArgument(Arg, Attr, *i); 622 if (Ptr) 623 break; 624 } 625 } 626 return Ptr; 627} 628 629static void writeAvailabilityValue(raw_ostream &OS) { 630 OS << "\" << getPlatform()->getName();\n" 631 << " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n" 632 << " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n" 633 << " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n" 634 << " if (getUnavailable()) OS << \", unavailable\";\n" 635 << " OS << \""; 636} 637 638void ClangAttrClassEmitter::run(raw_ostream &OS) { 639 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 640 OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; 641 OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; 642 643 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 644 645 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 646 i != e; ++i) { 647 Record &R = **i; 648 const std::string &SuperName = R.getSuperClasses().back()->getName(); 649 650 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; 651 652 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 653 std::vector<Argument*> Args; 654 std::vector<Argument*>::iterator ai, ae; 655 Args.reserve(ArgRecords.size()); 656 657 for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 658 re = ArgRecords.end(); 659 ri != re; ++ri) { 660 Record &ArgRecord = **ri; 661 Argument *Arg = createArgument(ArgRecord, R.getName()); 662 assert(Arg); 663 Args.push_back(Arg); 664 665 Arg->writeDeclarations(OS); 666 OS << "\n\n"; 667 } 668 669 ae = Args.end(); 670 671 OS << "\n public:\n"; 672 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; 673 674 for (ai = Args.begin(); ai != ae; ++ai) { 675 OS << " , "; 676 (*ai)->writeCtorParameters(OS); 677 OS << "\n"; 678 } 679 680 OS << " )\n"; 681 OS << " : " << SuperName << "(attr::" << R.getName() << ", R)\n"; 682 683 for (ai = Args.begin(); ai != ae; ++ai) { 684 OS << " , "; 685 (*ai)->writeCtorInitializers(OS); 686 OS << "\n"; 687 } 688 689 OS << " {\n"; 690 691 for (ai = Args.begin(); ai != ae; ++ai) { 692 (*ai)->writeCtorBody(OS); 693 OS << "\n"; 694 } 695 OS << " }\n\n"; 696 697 OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; 698 OS << " virtual void printPretty(llvm::raw_ostream &OS, ASTContext &Ctx) const;\n"; 699 700 for (ai = Args.begin(); ai != ae; ++ai) { 701 (*ai)->writeAccessors(OS); 702 OS << "\n\n"; 703 } 704 705 OS << R.getValueAsString("AdditionalMembers"); 706 OS << "\n\n"; 707 708 OS << " static bool classof(const Attr *A) { return A->getKind() == " 709 << "attr::" << R.getName() << "; }\n"; 710 OS << " static bool classof(const " << R.getName() 711 << "Attr *) { return true; }\n"; 712 OS << "};\n\n"; 713 } 714 715 OS << "#endif\n"; 716} 717 718void ClangAttrImplEmitter::run(raw_ostream &OS) { 719 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 720 721 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 722 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; 723 std::vector<Argument*>::iterator ai, ae; 724 725 for (; i != e; ++i) { 726 Record &R = **i; 727 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 728 std::vector<StringRef> Spellings = getValueAsListOfStrings(R, "Spellings"); 729 std::vector<Argument*> Args; 730 for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) 731 Args.push_back(createArgument(**ri, R.getName())); 732 733 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 734 (*ai)->writeAccessorDefinitions(OS); 735 736 OS << R.getName() << "Attr *" << R.getName() 737 << "Attr::clone(ASTContext &C) const {\n"; 738 OS << " return new (C) " << R.getName() << "Attr(getLocation(), C"; 739 for (ai = Args.begin(); ai != ae; ++ai) { 740 OS << ", "; 741 (*ai)->writeCloneArgs(OS); 742 } 743 OS << ");\n}\n\n"; 744 745 OS << "void " << R.getName() << "Attr::printPretty(" 746 << "llvm::raw_ostream &OS, ASTContext &Ctx) const {\n"; 747 if (Spellings.begin() != Spellings.end()) { 748 OS << " OS << \" __attribute__((" << *Spellings.begin(); 749 if (Args.size()) OS << "("; 750 if (*Spellings.begin()=="availability") { 751 writeAvailabilityValue(OS); 752 } else { 753 for (ai = Args.begin(); ai != ae; ++ai) { 754 if (ai!=Args.begin()) OS <<", "; 755 (*ai)->writeValue(OS); 756 } 757 } 758 if (Args.size()) OS << ")"; 759 OS << "))\";\n"; 760 } 761 OS << "}\n\n"; 762 } 763} 764 765static void EmitAttrList(raw_ostream &OS, StringRef Class, 766 const std::vector<Record*> &AttrList) { 767 std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end(); 768 769 if (i != e) { 770 // Move the end iterator back to emit the last attribute. 771 for(--e; i != e; ++i) 772 OS << Class << "(" << (*i)->getName() << ")\n"; 773 774 OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; 775 } 776} 777 778void ClangAttrListEmitter::run(raw_ostream &OS) { 779 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 780 781 OS << "#ifndef LAST_ATTR\n"; 782 OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; 783 OS << "#endif\n\n"; 784 785 OS << "#ifndef INHERITABLE_ATTR\n"; 786 OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n"; 787 OS << "#endif\n\n"; 788 789 OS << "#ifndef LAST_INHERITABLE_ATTR\n"; 790 OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; 791 OS << "#endif\n\n"; 792 793 OS << "#ifndef INHERITABLE_PARAM_ATTR\n"; 794 OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n"; 795 OS << "#endif\n\n"; 796 797 OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n"; 798 OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)" 799 " INHERITABLE_PARAM_ATTR(NAME)\n"; 800 OS << "#endif\n\n"; 801 802 Record *InhClass = Records.getClass("InheritableAttr"); 803 Record *InhParamClass = Records.getClass("InheritableParamAttr"); 804 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 805 NonInhAttrs, InhAttrs, InhParamAttrs; 806 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 807 i != e; ++i) { 808 if ((*i)->isSubClassOf(InhParamClass)) 809 InhParamAttrs.push_back(*i); 810 else if ((*i)->isSubClassOf(InhClass)) 811 InhAttrs.push_back(*i); 812 else 813 NonInhAttrs.push_back(*i); 814 } 815 816 EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); 817 EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); 818 EmitAttrList(OS, "ATTR", NonInhAttrs); 819 820 OS << "#undef LAST_ATTR\n"; 821 OS << "#undef INHERITABLE_ATTR\n"; 822 OS << "#undef LAST_INHERITABLE_ATTR\n"; 823 OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; 824 OS << "#undef ATTR\n"; 825} 826 827void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { 828 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 829 830 Record *InhClass = Records.getClass("InheritableAttr"); 831 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 832 ArgRecords; 833 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 834 std::vector<Argument*> Args; 835 std::vector<Argument*>::iterator ri, re; 836 837 OS << " switch (Kind) {\n"; 838 OS << " default:\n"; 839 OS << " assert(0 && \"Unknown attribute!\");\n"; 840 OS << " break;\n"; 841 for (; i != e; ++i) { 842 Record &R = **i; 843 OS << " case attr::" << R.getName() << ": {\n"; 844 if (R.isSubClassOf(InhClass)) 845 OS << " bool isInherited = Record[Idx++];\n"; 846 ArgRecords = R.getValueAsListOfDefs("Args"); 847 Args.clear(); 848 for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { 849 Argument *A = createArgument(**ai, R.getName()); 850 Args.push_back(A); 851 A->writePCHReadDecls(OS); 852 } 853 OS << " New = new (Context) " << R.getName() << "Attr(Range, Context"; 854 for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) { 855 OS << ", "; 856 (*ri)->writePCHReadArgs(OS); 857 } 858 OS << ");\n"; 859 if (R.isSubClassOf(InhClass)) 860 OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n"; 861 OS << " break;\n"; 862 OS << " }\n"; 863 } 864 OS << " }\n"; 865} 866 867void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { 868 Record *InhClass = Records.getClass("InheritableAttr"); 869 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; 870 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 871 872 OS << " switch (A->getKind()) {\n"; 873 OS << " default:\n"; 874 OS << " llvm_unreachable(\"Unknown attribute kind!\");\n"; 875 OS << " break;\n"; 876 for (; i != e; ++i) { 877 Record &R = **i; 878 OS << " case attr::" << R.getName() << ": {\n"; 879 Args = R.getValueAsListOfDefs("Args"); 880 if (R.isSubClassOf(InhClass) || !Args.empty()) 881 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() 882 << "Attr>(A);\n"; 883 if (R.isSubClassOf(InhClass)) 884 OS << " Record.push_back(SA->isInherited());\n"; 885 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 886 createArgument(**ai, R.getName())->writePCHWrite(OS); 887 OS << " break;\n"; 888 OS << " }\n"; 889 } 890 OS << " }\n"; 891} 892 893void ClangAttrSpellingListEmitter::run(raw_ostream &OS) { 894 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 895 896 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 897 898 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { 899 Record &Attr = **I; 900 901 std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings"); 902 903 for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { 904 StringRef Spelling = *I; 905 OS << ".Case(\"" << Spelling << "\", true)\n"; 906 } 907 } 908 909} 910 911void ClangAttrLateParsedListEmitter::run(raw_ostream &OS) { 912 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 913 914 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 915 916 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 917 I != E; ++I) { 918 Record &Attr = **I; 919 920 bool LateParsed = Attr.getValueAsBit("LateParsed"); 921 922 if (LateParsed) { 923 std::vector<StringRef> Spellings = 924 getValueAsListOfStrings(Attr, "Spellings"); 925 926 for (std::vector<StringRef>::const_iterator I = Spellings.begin(), 927 E = Spellings.end(); I != E; ++I) { 928 OS << ".Case(\"" << (*I) << "\", " << LateParsed << ")\n"; 929 } 930 } 931 } 932} 933 934 935void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) { 936 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 937 938 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 939 940 OS << "Attr* instantiateTemplateAttribute(const Attr *At, ASTContext &C, " 941 << "Sema &S,\n" 942 << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n" 943 << " switch (At->getKind()) {\n" 944 << " default:\n" 945 << " break;\n"; 946 947 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 948 I != E; ++I) { 949 Record &R = **I; 950 951 OS << " case attr::" << R.getName() << ": {\n"; 952 OS << " const " << R.getName() << "Attr *A = cast<" 953 << R.getName() << "Attr>(At);\n"; 954 bool TDependent = R.getValueAsBit("TemplateDependent"); 955 956 if (!TDependent) { 957 OS << " return A->clone(C);\n"; 958 OS << " }\n"; 959 continue; 960 } 961 962 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 963 std::vector<Argument*> Args; 964 std::vector<Argument*>::iterator ai, ae; 965 Args.reserve(ArgRecords.size()); 966 967 for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 968 re = ArgRecords.end(); 969 ri != re; ++ri) { 970 Record &ArgRecord = **ri; 971 Argument *Arg = createArgument(ArgRecord, R.getName()); 972 assert(Arg); 973 Args.push_back(Arg); 974 } 975 ae = Args.end(); 976 977 for (ai = Args.begin(); ai != ae; ++ai) { 978 (*ai)->writeTemplateInstantiation(OS); 979 } 980 OS << " return new (C) " << R.getName() << "Attr(A->getLocation(), C"; 981 for (ai = Args.begin(); ai != ae; ++ai) { 982 OS << ", "; 983 (*ai)->writeTemplateInstantiationArgs(OS); 984 } 985 OS << ");\n }\n"; 986 } 987 OS << " } // end switch\n" 988 << " llvm_unreachable(\"Unknown attribute!\");\n" 989 << " return 0;\n" 990 << "}\n\n"; 991} 992 993