ClangAttrEmitter.cpp revision 331d2ec7cd4c6b5e29cc61fcdc617bf708223cd4
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 674 if (!R.getValueAsBit("ASTNode")) 675 continue; 676 677 const std::string &SuperName = R.getSuperClasses().back()->getName(); 678 679 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; 680 681 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 682 std::vector<Argument*> Args; 683 std::vector<Argument*>::iterator ai, ae; 684 Args.reserve(ArgRecords.size()); 685 686 for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 687 re = ArgRecords.end(); 688 ri != re; ++ri) { 689 Record &ArgRecord = **ri; 690 Argument *Arg = createArgument(ArgRecord, R.getName()); 691 assert(Arg); 692 Args.push_back(Arg); 693 694 Arg->writeDeclarations(OS); 695 OS << "\n\n"; 696 } 697 698 ae = Args.end(); 699 700 OS << "\n public:\n"; 701 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; 702 703 for (ai = Args.begin(); ai != ae; ++ai) { 704 OS << " , "; 705 (*ai)->writeCtorParameters(OS); 706 OS << "\n"; 707 } 708 709 OS << " )\n"; 710 OS << " : " << SuperName << "(attr::" << R.getName() << ", R)\n"; 711 712 for (ai = Args.begin(); ai != ae; ++ai) { 713 OS << " , "; 714 (*ai)->writeCtorInitializers(OS); 715 OS << "\n"; 716 } 717 718 OS << " {\n"; 719 720 for (ai = Args.begin(); ai != ae; ++ai) { 721 (*ai)->writeCtorBody(OS); 722 OS << "\n"; 723 } 724 OS << " }\n\n"; 725 726 OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; 727 OS << " virtual void printPretty(llvm::raw_ostream &OS, ASTContext &Ctx) const;\n"; 728 729 for (ai = Args.begin(); ai != ae; ++ai) { 730 (*ai)->writeAccessors(OS); 731 OS << "\n\n"; 732 } 733 734 OS << R.getValueAsString("AdditionalMembers"); 735 OS << "\n\n"; 736 737 OS << " static bool classof(const Attr *A) { return A->getKind() == " 738 << "attr::" << R.getName() << "; }\n"; 739 OS << " static bool classof(const " << R.getName() 740 << "Attr *) { return true; }\n"; 741 742 bool LateParsed = R.getValueAsBit("LateParsed"); 743 OS << " virtual bool isLateParsed() const { return " 744 << LateParsed << "; }\n"; 745 746 OS << "};\n\n"; 747 } 748 749 OS << "#endif\n"; 750} 751 752void ClangAttrImplEmitter::run(raw_ostream &OS) { 753 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 754 755 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 756 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; 757 std::vector<Argument*>::iterator ai, ae; 758 759 for (; i != e; ++i) { 760 Record &R = **i; 761 762 if (!R.getValueAsBit("ASTNode")) 763 continue; 764 765 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 766 std::vector<StringRef> Spellings = getValueAsListOfStrings(R, "Spellings"); 767 std::vector<Argument*> Args; 768 for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) 769 Args.push_back(createArgument(**ri, R.getName())); 770 771 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 772 (*ai)->writeAccessorDefinitions(OS); 773 774 OS << R.getName() << "Attr *" << R.getName() 775 << "Attr::clone(ASTContext &C) const {\n"; 776 OS << " return new (C) " << R.getName() << "Attr(getLocation(), C"; 777 for (ai = Args.begin(); ai != ae; ++ai) { 778 OS << ", "; 779 (*ai)->writeCloneArgs(OS); 780 } 781 OS << ");\n}\n\n"; 782 783 OS << "void " << R.getName() << "Attr::printPretty(" 784 << "llvm::raw_ostream &OS, ASTContext &Ctx) const {\n"; 785 if (Spellings.begin() != Spellings.end()) { 786 OS << " OS << \" __attribute__((" << *Spellings.begin(); 787 if (Args.size()) OS << "("; 788 if (*Spellings.begin()=="availability") { 789 writeAvailabilityValue(OS); 790 } else { 791 for (ai = Args.begin(); ai != ae; ++ai) { 792 if (ai!=Args.begin()) OS <<", "; 793 (*ai)->writeValue(OS); 794 } 795 } 796 if (Args.size()) OS << ")"; 797 OS << "))\";\n"; 798 } 799 OS << "}\n\n"; 800 } 801} 802 803static void EmitAttrList(raw_ostream &OS, StringRef Class, 804 const std::vector<Record*> &AttrList) { 805 std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end(); 806 807 if (i != e) { 808 // Move the end iterator back to emit the last attribute. 809 for(--e; i != e; ++i) { 810 if (!(*i)->getValueAsBit("ASTNode")) 811 continue; 812 813 OS << Class << "(" << (*i)->getName() << ")\n"; 814 } 815 816 OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; 817 } 818} 819 820void ClangAttrListEmitter::run(raw_ostream &OS) { 821 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 822 823 OS << "#ifndef LAST_ATTR\n"; 824 OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; 825 OS << "#endif\n\n"; 826 827 OS << "#ifndef INHERITABLE_ATTR\n"; 828 OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n"; 829 OS << "#endif\n\n"; 830 831 OS << "#ifndef LAST_INHERITABLE_ATTR\n"; 832 OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; 833 OS << "#endif\n\n"; 834 835 OS << "#ifndef INHERITABLE_PARAM_ATTR\n"; 836 OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n"; 837 OS << "#endif\n\n"; 838 839 OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n"; 840 OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)" 841 " INHERITABLE_PARAM_ATTR(NAME)\n"; 842 OS << "#endif\n\n"; 843 844 Record *InhClass = Records.getClass("InheritableAttr"); 845 Record *InhParamClass = Records.getClass("InheritableParamAttr"); 846 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 847 NonInhAttrs, InhAttrs, InhParamAttrs; 848 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 849 i != e; ++i) { 850 if (!(*i)->getValueAsBit("ASTNode")) 851 continue; 852 853 if ((*i)->isSubClassOf(InhParamClass)) 854 InhParamAttrs.push_back(*i); 855 else if ((*i)->isSubClassOf(InhClass)) 856 InhAttrs.push_back(*i); 857 else 858 NonInhAttrs.push_back(*i); 859 } 860 861 EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); 862 EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); 863 EmitAttrList(OS, "ATTR", NonInhAttrs); 864 865 OS << "#undef LAST_ATTR\n"; 866 OS << "#undef INHERITABLE_ATTR\n"; 867 OS << "#undef LAST_INHERITABLE_ATTR\n"; 868 OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; 869 OS << "#undef ATTR\n"; 870} 871 872void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { 873 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 874 875 Record *InhClass = Records.getClass("InheritableAttr"); 876 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 877 ArgRecords; 878 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 879 std::vector<Argument*> Args; 880 std::vector<Argument*>::iterator ri, re; 881 882 OS << " switch (Kind) {\n"; 883 OS << " default:\n"; 884 OS << " assert(0 && \"Unknown attribute!\");\n"; 885 OS << " break;\n"; 886 for (; i != e; ++i) { 887 Record &R = **i; 888 if (!R.getValueAsBit("ASTNode")) 889 continue; 890 891 OS << " case attr::" << R.getName() << ": {\n"; 892 if (R.isSubClassOf(InhClass)) 893 OS << " bool isInherited = Record[Idx++];\n"; 894 ArgRecords = R.getValueAsListOfDefs("Args"); 895 Args.clear(); 896 for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { 897 Argument *A = createArgument(**ai, R.getName()); 898 Args.push_back(A); 899 A->writePCHReadDecls(OS); 900 } 901 OS << " New = new (Context) " << R.getName() << "Attr(Range, Context"; 902 for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) { 903 OS << ", "; 904 (*ri)->writePCHReadArgs(OS); 905 } 906 OS << ");\n"; 907 if (R.isSubClassOf(InhClass)) 908 OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n"; 909 OS << " break;\n"; 910 OS << " }\n"; 911 } 912 OS << " }\n"; 913} 914 915void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { 916 Record *InhClass = Records.getClass("InheritableAttr"); 917 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; 918 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 919 920 OS << " switch (A->getKind()) {\n"; 921 OS << " default:\n"; 922 OS << " llvm_unreachable(\"Unknown attribute kind!\");\n"; 923 OS << " break;\n"; 924 for (; i != e; ++i) { 925 Record &R = **i; 926 if (!R.getValueAsBit("ASTNode")) 927 continue; 928 OS << " case attr::" << R.getName() << ": {\n"; 929 Args = R.getValueAsListOfDefs("Args"); 930 if (R.isSubClassOf(InhClass) || !Args.empty()) 931 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() 932 << "Attr>(A);\n"; 933 if (R.isSubClassOf(InhClass)) 934 OS << " Record.push_back(SA->isInherited());\n"; 935 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 936 createArgument(**ai, R.getName())->writePCHWrite(OS); 937 OS << " break;\n"; 938 OS << " }\n"; 939 } 940 OS << " }\n"; 941} 942 943void ClangAttrSpellingListEmitter::run(raw_ostream &OS) { 944 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 945 946 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 947 948 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { 949 Record &Attr = **I; 950 951 std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings"); 952 953 for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { 954 StringRef Spelling = *I; 955 OS << ".Case(\"" << Spelling << "\", true)\n"; 956 } 957 } 958 959} 960 961void ClangAttrLateParsedListEmitter::run(raw_ostream &OS) { 962 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 963 964 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 965 966 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 967 I != E; ++I) { 968 Record &Attr = **I; 969 970 bool LateParsed = Attr.getValueAsBit("LateParsed"); 971 972 if (LateParsed) { 973 std::vector<StringRef> Spellings = 974 getValueAsListOfStrings(Attr, "Spellings"); 975 976 for (std::vector<StringRef>::const_iterator I = Spellings.begin(), 977 E = Spellings.end(); I != E; ++I) { 978 OS << ".Case(\"" << (*I) << "\", " << LateParsed << ")\n"; 979 } 980 } 981 } 982} 983 984 985void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) { 986 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 987 988 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 989 990 OS << "namespace clang {\n" 991 << "namespace sema {\n\n" 992 << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, " 993 << "Sema &S,\n" 994 << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n" 995 << " switch (At->getKind()) {\n" 996 << " default:\n" 997 << " break;\n"; 998 999 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1000 I != E; ++I) { 1001 Record &R = **I; 1002 if (!R.getValueAsBit("ASTNode")) 1003 continue; 1004 1005 OS << " case attr::" << R.getName() << ": {\n"; 1006 OS << " const " << R.getName() << "Attr *A = cast<" 1007 << R.getName() << "Attr>(At);\n"; 1008 bool TDependent = R.getValueAsBit("TemplateDependent"); 1009 1010 if (!TDependent) { 1011 OS << " return A->clone(C);\n"; 1012 OS << " }\n"; 1013 continue; 1014 } 1015 1016 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 1017 std::vector<Argument*> Args; 1018 std::vector<Argument*>::iterator ai, ae; 1019 Args.reserve(ArgRecords.size()); 1020 1021 for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 1022 re = ArgRecords.end(); 1023 ri != re; ++ri) { 1024 Record &ArgRecord = **ri; 1025 Argument *Arg = createArgument(ArgRecord, R.getName()); 1026 assert(Arg); 1027 Args.push_back(Arg); 1028 } 1029 ae = Args.end(); 1030 1031 for (ai = Args.begin(); ai != ae; ++ai) { 1032 (*ai)->writeTemplateInstantiation(OS); 1033 } 1034 OS << " return new (C) " << R.getName() << "Attr(A->getLocation(), C"; 1035 for (ai = Args.begin(); ai != ae; ++ai) { 1036 OS << ", "; 1037 (*ai)->writeTemplateInstantiationArgs(OS); 1038 } 1039 OS << ");\n }\n"; 1040 } 1041 OS << " } // end switch\n" 1042 << " llvm_unreachable(\"Unknown attribute!\");\n" 1043 << " return 0;\n" 1044 << "}\n\n" 1045 << "} // end namespace sema\n" 1046 << "} // end namespace clang\n"; 1047} 1048 1049void ClangAttrParsedAttrListEmitter::run(raw_ostream &OS) { 1050 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 1051 1052 OS << "#ifndef PARSED_ATTR\n"; 1053 OS << "#define PARSED_ATTR(NAME) NAME\n"; 1054 OS << "#endif\n\n"; 1055 1056 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1057 std::set<StringRef> ProcessedAttrs; 1058 1059 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1060 I != E; ++I) { 1061 Record &Attr = **I; 1062 1063 bool SemaHandler = Attr.getValueAsBit("SemaHandler"); 1064 1065 if (SemaHandler) { 1066 std::vector<StringRef> Spellings = 1067 getValueAsListOfStrings(Attr, "Spellings"); 1068 1069 for (std::vector<StringRef>::const_iterator I = Spellings.begin(), 1070 E = Spellings.end(); I != E; ++I) { 1071 StringRef AttrName = *I; 1072 1073 AttrName = NormalizeAttrName(AttrName); 1074 // skip if a normalized version has been processed. 1075 if (ProcessedAttrs.find(AttrName) != ProcessedAttrs.end()) 1076 continue; 1077 else 1078 ProcessedAttrs.insert(AttrName); 1079 1080 OS << "PARSED_ATTR(" << AttrName << ")\n"; 1081 } 1082 } 1083 } 1084} 1085 1086void ClangAttrParsedAttrKindsEmitter::run(raw_ostream &OS) { 1087 OS << "// This file is generated by TableGen. Do not edit.\n\n"; 1088 1089 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1090 1091 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1092 I != E; ++I) { 1093 Record &Attr = **I; 1094 1095 bool SemaHandler = Attr.getValueAsBit("SemaHandler"); 1096 bool Ignored = Attr.getValueAsBit("Ignored"); 1097 1098 if (SemaHandler || Ignored) { 1099 std::vector<StringRef> Spellings = 1100 getValueAsListOfStrings(Attr, "Spellings"); 1101 1102 for (std::vector<StringRef>::const_iterator I = Spellings.begin(), 1103 E = Spellings.end(); I != E; ++I) { 1104 StringRef AttrName = *I, Spelling = *I; 1105 1106 AttrName = NormalizeAttrName(AttrName); 1107 Spelling = NormalizeAttrSpelling(Spelling); 1108 1109 if (SemaHandler) 1110 OS << ".Case(\"" << Spelling << "\", " << "AT_" << AttrName << ")\n"; 1111 else 1112 OS << ".Case(\"" << Spelling << "\", IgnoredAttribute)\n"; 1113 } 1114 } 1115 } 1116} 1117 1118 1119