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