1 //===-- ClangAttrEmitter.cpp - Generate Clang attribute handling ----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // These tablegen backends emit Clang attribute processing code 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "TableGenBackends.h" 14 #include "ASTTableGen.h" 15 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/DenseSet.h" 19 #include "llvm/ADT/MapVector.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/ADT/SmallString.h" 22 #include "llvm/ADT/StringExtras.h" 23 #include "llvm/ADT/StringMap.h" 24 #include "llvm/ADT/StringRef.h" 25 #include "llvm/ADT/StringSwitch.h" 26 #include "llvm/Support/ErrorHandling.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include "llvm/TableGen/Error.h" 29 #include "llvm/TableGen/Record.h" 30 #include "llvm/TableGen/StringMatcher.h" 31 #include "llvm/TableGen/TableGenBackend.h" 32 #include <cassert> 33 #include <cctype> 34 #include <cstddef> 35 #include <cstdint> 36 #include <map> 37 #include <memory> 38 #include <optional> 39 #include <set> 40 #include <string> 41 #include <utility> 42 #include <vector> 43 44 using namespace llvm; 45 46 namespace { 47 48 class FlattenedSpelling { 49 StringRef V, N, NS; 50 bool K = false; 51 const Record &OriginalSpelling; 52 53 public: 54 FlattenedSpelling(StringRef Variety, StringRef Name, StringRef Namespace, 55 bool KnownToGCC, const Record &OriginalSpelling) 56 : V(Variety), N(Name), NS(Namespace), K(KnownToGCC), 57 OriginalSpelling(OriginalSpelling) {} 58 explicit FlattenedSpelling(const Record &Spelling) 59 : V(Spelling.getValueAsString("Variety")), 60 N(Spelling.getValueAsString("Name")), OriginalSpelling(Spelling) { 61 assert(V != "GCC" && V != "Clang" && 62 "Given a GCC spelling, which means this hasn't been flattened!"); 63 if (V == "CXX11" || V == "C23" || V == "Pragma") 64 NS = Spelling.getValueAsString("Namespace"); 65 } 66 67 StringRef variety() const { return V; } 68 StringRef name() const { return N; } 69 StringRef nameSpace() const { return NS; } 70 bool knownToGCC() const { return K; } 71 const Record &getSpellingRecord() const { return OriginalSpelling; } 72 }; 73 74 struct FlattenedSpellingInfo { 75 FlattenedSpellingInfo(StringRef Syntax, StringRef Scope, 76 const std::string &TargetTest, uint32_t ArgMask) 77 : Syntax(Syntax), Scope(Scope), TargetTest(TargetTest), ArgMask(ArgMask) { 78 } 79 StringRef Syntax; 80 StringRef Scope; 81 std::string TargetTest; 82 uint32_t ArgMask; 83 }; 84 using FSIVecTy = std::vector<FlattenedSpellingInfo>; 85 86 } // end anonymous namespace 87 88 static bool GenerateTargetSpecificAttrChecks(const Record *R, 89 std::vector<StringRef> &Arches, 90 std::string &Test, 91 std::string *FnName); 92 static bool isStringLiteralArgument(const Record *Arg); 93 static bool isVariadicStringLiteralArgument(const Record *Arg); 94 95 static std::vector<FlattenedSpelling> 96 GetFlattenedSpellings(const Record &Attr) { 97 std::vector<FlattenedSpelling> Ret; 98 99 for (const auto &Spelling : Attr.getValueAsListOfDefs("Spellings")) { 100 StringRef Variety = Spelling->getValueAsString("Variety"); 101 StringRef Name = Spelling->getValueAsString("Name"); 102 if (Variety == "GCC") { 103 Ret.emplace_back("GNU", Name, "", true, *Spelling); 104 Ret.emplace_back("CXX11", Name, "gnu", true, *Spelling); 105 if (Spelling->getValueAsBit("AllowInC")) 106 Ret.emplace_back("C23", Name, "gnu", true, *Spelling); 107 } else if (Variety == "Clang") { 108 Ret.emplace_back("GNU", Name, "", false, *Spelling); 109 Ret.emplace_back("CXX11", Name, "clang", false, *Spelling); 110 if (Spelling->getValueAsBit("AllowInC")) 111 Ret.emplace_back("C23", Name, "clang", false, *Spelling); 112 } else if (Variety == "ClangGCC") { 113 Ret.emplace_back("GNU", Name, "", false, *Spelling); 114 Ret.emplace_back("CXX11", Name, "clang", false, *Spelling); 115 Ret.emplace_back("CXX11", Name, "gnu", false, *Spelling); 116 if (Spelling->getValueAsBit("AllowInC")) { 117 Ret.emplace_back("C23", Name, "clang", false, *Spelling); 118 Ret.emplace_back("C23", Name, "gnu", false, *Spelling); 119 } 120 } else { 121 Ret.push_back(FlattenedSpelling(*Spelling)); 122 } 123 } 124 125 return Ret; 126 } 127 128 static std::string ReadPCHRecord(StringRef type) { 129 return StringSwitch<std::string>(type) 130 .EndsWith("Decl *", "Record.readDeclAs<" + type.drop_back().str() + ">()") 131 .Case("TypeSourceInfo *", "Record.readTypeSourceInfo()") 132 .Case("Expr *", "Record.readExpr()") 133 .Case("IdentifierInfo *", "Record.readIdentifier()") 134 .Case("StringRef", "Record.readString()") 135 .Case("ParamIdx", "ParamIdx::deserialize(Record.readInt())") 136 .Case("OMPTraitInfo *", "Record.readOMPTraitInfo()") 137 .Default("Record.readInt()"); 138 } 139 140 // Get a type that is suitable for storing an object of the specified type. 141 static StringRef getStorageType(StringRef type) { 142 return StringSwitch<StringRef>(type) 143 .Case("StringRef", "std::string") 144 .Default(type); 145 } 146 147 // Assumes that the way to get the value is SA->getname() 148 static std::string WritePCHRecord(StringRef type, StringRef name) { 149 return "Record." + 150 StringSwitch<std::string>(type) 151 .EndsWith("Decl *", "AddDeclRef(" + name.str() + ");\n") 152 .Case("TypeSourceInfo *", 153 "AddTypeSourceInfo(" + name.str() + ");\n") 154 .Case("Expr *", "AddStmt(" + name.str() + ");\n") 155 .Case("IdentifierInfo *", 156 "AddIdentifierRef(" + name.str() + ");\n") 157 .Case("StringRef", "AddString(" + name.str() + ");\n") 158 .Case("ParamIdx", "push_back(" + name.str() + ".serialize());\n") 159 .Case("OMPTraitInfo *", "writeOMPTraitInfo(" + name.str() + ");\n") 160 .Default("push_back(" + name.str() + ");\n"); 161 } 162 163 // Normalize attribute name by removing leading and trailing 164 // underscores. For example, __foo, foo__, __foo__ would 165 // become foo. 166 static StringRef NormalizeAttrName(StringRef AttrName) { 167 AttrName.consume_front("__"); 168 AttrName.consume_back("__"); 169 return AttrName; 170 } 171 172 // Normalize the name by removing any and all leading and trailing underscores. 173 // This is different from NormalizeAttrName in that it also handles names like 174 // _pascal and __pascal. 175 static StringRef NormalizeNameForSpellingComparison(StringRef Name) { 176 return Name.trim("_"); 177 } 178 179 // Normalize the spelling of a GNU attribute (i.e. "x" in "__attribute__((x))"), 180 // removing "__" if it appears at the beginning and end of the attribute's name. 181 static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) { 182 if (AttrSpelling.starts_with("__") && AttrSpelling.ends_with("__")) { 183 AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4); 184 } 185 186 return AttrSpelling; 187 } 188 189 typedef std::vector<std::pair<std::string, const Record *>> ParsedAttrMap; 190 191 static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records, 192 ParsedAttrMap *Dupes = nullptr, 193 bool SemaOnly = true) { 194 std::set<std::string> Seen; 195 ParsedAttrMap R; 196 for (const Record *Attr : Records.getAllDerivedDefinitions("Attr")) { 197 if (!SemaOnly || Attr->getValueAsBit("SemaHandler")) { 198 std::string AN; 199 if (Attr->isSubClassOf("TargetSpecificAttr") && 200 !Attr->isValueUnset("ParseKind")) { 201 AN = Attr->getValueAsString("ParseKind").str(); 202 203 // If this attribute has already been handled, it does not need to be 204 // handled again. 205 if (!Seen.insert(AN).second) { 206 if (Dupes) 207 Dupes->push_back(std::make_pair(AN, Attr)); 208 continue; 209 } 210 } else 211 AN = NormalizeAttrName(Attr->getName()).str(); 212 213 R.push_back(std::make_pair(AN, Attr)); 214 } 215 } 216 return R; 217 } 218 219 namespace { 220 221 class Argument { 222 std::string lowerName, upperName; 223 StringRef attrName; 224 bool isOpt; 225 bool Fake; 226 227 public: 228 Argument(StringRef Arg, StringRef Attr) 229 : lowerName(Arg.str()), upperName(lowerName), attrName(Attr), 230 isOpt(false), Fake(false) { 231 if (!lowerName.empty()) { 232 lowerName[0] = std::tolower(lowerName[0]); 233 upperName[0] = std::toupper(upperName[0]); 234 } 235 // Work around MinGW's macro definition of 'interface' to 'struct'. We 236 // have an attribute argument called 'Interface', so only the lower case 237 // name conflicts with the macro definition. 238 if (lowerName == "interface") 239 lowerName = "interface_"; 240 } 241 Argument(const Record &Arg, StringRef Attr) 242 : Argument(Arg.getValueAsString("Name"), Attr) {} 243 virtual ~Argument() = default; 244 245 StringRef getLowerName() const { return lowerName; } 246 StringRef getUpperName() const { return upperName; } 247 StringRef getAttrName() const { return attrName; } 248 249 bool isOptional() const { return isOpt; } 250 void setOptional(bool set) { isOpt = set; } 251 252 bool isFake() const { return Fake; } 253 void setFake(bool fake) { Fake = fake; } 254 255 // These functions print the argument contents formatted in different ways. 256 virtual void writeAccessors(raw_ostream &OS) const = 0; 257 virtual void writeAccessorDefinitions(raw_ostream &OS) const {} 258 virtual void writeASTVisitorTraversal(raw_ostream &OS) const {} 259 virtual void writeCloneArgs(raw_ostream &OS) const = 0; 260 virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0; 261 virtual void writeTemplateInstantiation(raw_ostream &OS) const {} 262 virtual void writeCtorBody(raw_ostream &OS) const {} 263 virtual void writeCtorInitializers(raw_ostream &OS) const = 0; 264 virtual void writeCtorDefaultInitializers(raw_ostream &OS) const = 0; 265 virtual void writeCtorParameters(raw_ostream &OS) const = 0; 266 virtual void writeDeclarations(raw_ostream &OS) const = 0; 267 virtual void writePCHReadArgs(raw_ostream &OS) const = 0; 268 virtual void writePCHReadDecls(raw_ostream &OS) const = 0; 269 virtual void writePCHWrite(raw_ostream &OS) const = 0; 270 virtual std::string getIsOmitted() const { return "false"; } 271 virtual void writeValue(raw_ostream &OS) const = 0; 272 virtual void writeDump(raw_ostream &OS) const = 0; 273 virtual void writeDumpChildren(raw_ostream &OS) const {} 274 virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; } 275 276 virtual bool isEnumArg() const { return false; } 277 virtual bool isVariadicEnumArg() const { return false; } 278 virtual bool isVariadic() const { return false; } 279 280 virtual void writeImplicitCtorArgs(raw_ostream &OS) const { 281 OS << getUpperName(); 282 } 283 }; 284 285 class SimpleArgument : public Argument { 286 std::string type; 287 288 public: 289 SimpleArgument(const Record &Arg, StringRef Attr, std::string T) 290 : Argument(Arg, Attr), type(std::move(T)) {} 291 292 std::string getType() const { return type; } 293 294 void writeAccessors(raw_ostream &OS) const override { 295 OS << " " << type << " get" << getUpperName() << "() const {\n"; 296 OS << " return " << getLowerName() << ";\n"; 297 OS << " }"; 298 } 299 300 void writeCloneArgs(raw_ostream &OS) const override { 301 OS << getLowerName(); 302 } 303 304 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 305 OS << "A->get" << getUpperName() << "()"; 306 } 307 308 void writeCtorInitializers(raw_ostream &OS) const override { 309 OS << getLowerName() << "(" << getUpperName() << ")"; 310 } 311 312 void writeCtorDefaultInitializers(raw_ostream &OS) const override { 313 OS << getLowerName() << "()"; 314 } 315 316 void writeCtorParameters(raw_ostream &OS) const override { 317 OS << type << " " << getUpperName(); 318 } 319 320 void writeDeclarations(raw_ostream &OS) const override { 321 OS << type << " " << getLowerName() << ";"; 322 } 323 324 void writePCHReadDecls(raw_ostream &OS) const override { 325 std::string read = ReadPCHRecord(type); 326 OS << " " << type << " " << getLowerName() << " = " << read << ";\n"; 327 } 328 329 void writePCHReadArgs(raw_ostream &OS) const override { 330 OS << getLowerName(); 331 } 332 333 void writePCHWrite(raw_ostream &OS) const override { 334 OS << " " 335 << WritePCHRecord(type, "SA->get" + getUpperName().str() + "()"); 336 } 337 338 std::string getIsOmitted() const override { 339 auto IsOneOf = [](StringRef subject, auto... list) { 340 return ((subject == list) || ...); 341 }; 342 343 if (IsOneOf(type, "IdentifierInfo *", "Expr *")) 344 return "!get" + getUpperName().str() + "()"; 345 if (IsOneOf(type, "TypeSourceInfo *")) 346 return "!get" + getUpperName().str() + "Loc()"; 347 if (IsOneOf(type, "ParamIdx")) 348 return "!get" + getUpperName().str() + "().isValid()"; 349 350 assert(IsOneOf(type, "unsigned", "int", "bool", "FunctionDecl *", 351 "VarDecl *")); 352 return "false"; 353 } 354 355 void writeValue(raw_ostream &OS) const override { 356 if (type == "FunctionDecl *") 357 OS << "\" << get" << getUpperName() 358 << "()->getNameInfo().getAsString() << \""; 359 else if (type == "IdentifierInfo *") 360 // Some non-optional (comma required) identifier arguments can be the 361 // empty string but are then recorded as a nullptr. 362 OS << "\" << (get" << getUpperName() << "() ? get" << getUpperName() 363 << "()->getName() : \"\") << \""; 364 else if (type == "VarDecl *") 365 OS << "\" << get" << getUpperName() << "()->getName() << \""; 366 else if (type == "TypeSourceInfo *") 367 OS << "\" << get" << getUpperName() << "().getAsString() << \""; 368 else if (type == "ParamIdx") 369 OS << "\" << get" << getUpperName() << "().getSourceIndex() << \""; 370 else 371 OS << "\" << get" << getUpperName() << "() << \""; 372 } 373 374 void writeDump(raw_ostream &OS) const override { 375 if (StringRef(type).ends_with("Decl *")) { 376 OS << " OS << \" \";\n"; 377 OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n"; 378 } else if (type == "IdentifierInfo *") { 379 // Some non-optional (comma required) identifier arguments can be the 380 // empty string but are then recorded as a nullptr. 381 OS << " if (SA->get" << getUpperName() << "())\n" 382 << " OS << \" \" << SA->get" << getUpperName() 383 << "()->getName();\n"; 384 } else if (type == "TypeSourceInfo *") { 385 if (isOptional()) 386 OS << " if (SA->get" << getUpperName() << "Loc())"; 387 OS << " OS << \" \" << SA->get" << getUpperName() 388 << "().getAsString();\n"; 389 } else if (type == "bool") { 390 OS << " if (SA->get" << getUpperName() << "()) OS << \" " 391 << getUpperName() << "\";\n"; 392 } else if (type == "int" || type == "unsigned") { 393 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; 394 } else if (type == "ParamIdx") { 395 if (isOptional()) 396 OS << " if (SA->get" << getUpperName() << "().isValid())\n "; 397 OS << " OS << \" \" << SA->get" << getUpperName() 398 << "().getSourceIndex();\n"; 399 } else if (type == "OMPTraitInfo *") { 400 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; 401 } else { 402 llvm_unreachable("Unknown SimpleArgument type!"); 403 } 404 } 405 }; 406 407 class DefaultSimpleArgument : public SimpleArgument { 408 int64_t Default; 409 410 public: 411 DefaultSimpleArgument(const Record &Arg, StringRef Attr, 412 std::string T, int64_t Default) 413 : SimpleArgument(Arg, Attr, T), Default(Default) {} 414 415 void writeAccessors(raw_ostream &OS) const override { 416 SimpleArgument::writeAccessors(OS); 417 418 OS << "\n\n static const " << getType() << " Default" << getUpperName() 419 << " = "; 420 if (getType() == "bool") 421 OS << (Default != 0 ? "true" : "false"); 422 else 423 OS << Default; 424 OS << ";"; 425 } 426 }; 427 428 class StringArgument : public Argument { 429 public: 430 StringArgument(const Record &Arg, StringRef Attr) 431 : Argument(Arg, Attr) 432 {} 433 434 void writeAccessors(raw_ostream &OS) const override { 435 OS << " llvm::StringRef get" << getUpperName() << "() const {\n"; 436 OS << " return llvm::StringRef(" << getLowerName() << ", " 437 << getLowerName() << "Length);\n"; 438 OS << " }\n"; 439 OS << " unsigned get" << getUpperName() << "Length() const {\n"; 440 OS << " return " << getLowerName() << "Length;\n"; 441 OS << " }\n"; 442 OS << " void set" << getUpperName() 443 << "(ASTContext &C, llvm::StringRef S) {\n"; 444 OS << " " << getLowerName() << "Length = S.size();\n"; 445 OS << " this->" << getLowerName() << " = new (C, 1) char [" 446 << getLowerName() << "Length];\n"; 447 OS << " if (!S.empty())\n"; 448 OS << " std::memcpy(this->" << getLowerName() << ", S.data(), " 449 << getLowerName() << "Length);\n"; 450 OS << " }"; 451 } 452 453 void writeCloneArgs(raw_ostream &OS) const override { 454 OS << "get" << getUpperName() << "()"; 455 } 456 457 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 458 OS << "A->get" << getUpperName() << "()"; 459 } 460 461 void writeCtorBody(raw_ostream &OS) const override { 462 OS << " if (!" << getUpperName() << ".empty())\n"; 463 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 464 << ".data(), " << getLowerName() << "Length);\n"; 465 } 466 467 void writeCtorInitializers(raw_ostream &OS) const override { 468 OS << getLowerName() << "Length(" << getUpperName() << ".size())," 469 << getLowerName() << "(new (Ctx, 1) char[" << getLowerName() 470 << "Length])"; 471 } 472 473 void writeCtorDefaultInitializers(raw_ostream &OS) const override { 474 OS << getLowerName() << "Length(0)," << getLowerName() << "(nullptr)"; 475 } 476 477 void writeCtorParameters(raw_ostream &OS) const override { 478 OS << "llvm::StringRef " << getUpperName(); 479 } 480 481 void writeDeclarations(raw_ostream &OS) const override { 482 OS << "unsigned " << getLowerName() << "Length;\n"; 483 OS << "char *" << getLowerName() << ";"; 484 } 485 486 void writePCHReadDecls(raw_ostream &OS) const override { 487 OS << " std::string " << getLowerName() 488 << "= Record.readString();\n"; 489 } 490 491 void writePCHReadArgs(raw_ostream &OS) const override { 492 OS << getLowerName(); 493 } 494 495 void writePCHWrite(raw_ostream &OS) const override { 496 OS << " Record.AddString(SA->get" << getUpperName() << "());\n"; 497 } 498 499 void writeValue(raw_ostream &OS) const override { 500 OS << "\\\"\" << get" << getUpperName() << "() << \"\\\""; 501 } 502 503 void writeDump(raw_ostream &OS) const override { 504 OS << " OS << \" \\\"\" << SA->get" << getUpperName() 505 << "() << \"\\\"\";\n"; 506 } 507 }; 508 509 class AlignedArgument : public Argument { 510 public: 511 AlignedArgument(const Record &Arg, StringRef Attr) 512 : Argument(Arg, Attr) 513 {} 514 515 void writeAccessors(raw_ostream &OS) const override { 516 OS << " bool is" << getUpperName() << "Dependent() const;\n"; 517 OS << " bool is" << getUpperName() << "ErrorDependent() const;\n"; 518 519 OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n"; 520 521 OS << " bool is" << getUpperName() << "Expr() const {\n"; 522 OS << " return is" << getLowerName() << "Expr;\n"; 523 OS << " }\n"; 524 525 OS << " Expr *get" << getUpperName() << "Expr() const {\n"; 526 OS << " assert(is" << getLowerName() << "Expr);\n"; 527 OS << " return " << getLowerName() << "Expr;\n"; 528 OS << " }\n"; 529 530 OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n"; 531 OS << " assert(!is" << getLowerName() << "Expr);\n"; 532 OS << " return " << getLowerName() << "Type;\n"; 533 OS << " }"; 534 535 OS << " std::optional<unsigned> getCached" << getUpperName() 536 << "Value() const {\n"; 537 OS << " return " << getLowerName() << "Cache;\n"; 538 OS << " }"; 539 540 OS << " void setCached" << getUpperName() 541 << "Value(unsigned AlignVal) {\n"; 542 OS << " " << getLowerName() << "Cache = AlignVal;\n"; 543 OS << " }"; 544 } 545 546 void writeAccessorDefinitions(raw_ostream &OS) const override { 547 OS << "bool " << getAttrName() << "Attr::is" << getUpperName() 548 << "Dependent() const {\n"; 549 OS << " if (is" << getLowerName() << "Expr)\n"; 550 OS << " return " << getLowerName() << "Expr && (" << getLowerName() 551 << "Expr->isValueDependent() || " << getLowerName() 552 << "Expr->isTypeDependent());\n"; 553 OS << " else\n"; 554 OS << " return " << getLowerName() 555 << "Type->getType()->isDependentType();\n"; 556 OS << "}\n"; 557 558 OS << "bool " << getAttrName() << "Attr::is" << getUpperName() 559 << "ErrorDependent() const {\n"; 560 OS << " if (is" << getLowerName() << "Expr)\n"; 561 OS << " return " << getLowerName() << "Expr && " << getLowerName() 562 << "Expr->containsErrors();\n"; 563 OS << " return " << getLowerName() 564 << "Type->getType()->containsErrors();\n"; 565 OS << "}\n"; 566 } 567 568 void writeASTVisitorTraversal(raw_ostream &OS) const override { 569 StringRef Name = getUpperName(); 570 OS << " if (A->is" << Name << "Expr()) {\n" 571 << " if (!getDerived().TraverseStmt(A->get" << Name << "Expr()))\n" 572 << " return false;\n" 573 << " } else if (auto *TSI = A->get" << Name << "Type()) {\n" 574 << " if (!getDerived().TraverseTypeLoc(TSI->getTypeLoc()))\n" 575 << " return false;\n" 576 << " }\n"; 577 } 578 579 void writeCloneArgs(raw_ostream &OS) const override { 580 OS << "is" << getLowerName() << "Expr, is" << getLowerName() 581 << "Expr ? static_cast<void*>(" << getLowerName() 582 << "Expr) : " << getLowerName() 583 << "Type"; 584 } 585 586 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 587 // FIXME: move the definition in Sema::InstantiateAttrs to here. 588 // In the meantime, aligned attributes are cloned. 589 } 590 591 void writeCtorBody(raw_ostream &OS) const override { 592 OS << " if (is" << getLowerName() << "Expr)\n"; 593 OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>(" 594 << getUpperName() << ");\n"; 595 OS << " else\n"; 596 OS << " " << getLowerName() 597 << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName() 598 << ");\n"; 599 } 600 601 void writeCtorInitializers(raw_ostream &OS) const override { 602 OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)"; 603 } 604 605 void writeCtorDefaultInitializers(raw_ostream &OS) const override { 606 OS << "is" << getLowerName() << "Expr(false)"; 607 } 608 609 void writeCtorParameters(raw_ostream &OS) const override { 610 OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName(); 611 } 612 613 void writeImplicitCtorArgs(raw_ostream &OS) const override { 614 OS << "Is" << getUpperName() << "Expr, " << getUpperName(); 615 } 616 617 void writeDeclarations(raw_ostream &OS) const override { 618 OS << "bool is" << getLowerName() << "Expr;\n"; 619 OS << "union {\n"; 620 OS << "Expr *" << getLowerName() << "Expr;\n"; 621 OS << "TypeSourceInfo *" << getLowerName() << "Type;\n"; 622 OS << "};\n"; 623 OS << "std::optional<unsigned> " << getLowerName() << "Cache;\n"; 624 } 625 626 void writePCHReadArgs(raw_ostream &OS) const override { 627 OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr"; 628 } 629 630 void writePCHReadDecls(raw_ostream &OS) const override { 631 OS << " bool is" << getLowerName() << "Expr = Record.readInt();\n"; 632 OS << " void *" << getLowerName() << "Ptr;\n"; 633 OS << " if (is" << getLowerName() << "Expr)\n"; 634 OS << " " << getLowerName() << "Ptr = Record.readExpr();\n"; 635 OS << " else\n"; 636 OS << " " << getLowerName() 637 << "Ptr = Record.readTypeSourceInfo();\n"; 638 } 639 640 void writePCHWrite(raw_ostream &OS) const override { 641 OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n"; 642 OS << " if (SA->is" << getUpperName() << "Expr())\n"; 643 OS << " Record.AddStmt(SA->get" << getUpperName() << "Expr());\n"; 644 OS << " else\n"; 645 OS << " Record.AddTypeSourceInfo(SA->get" << getUpperName() 646 << "Type());\n"; 647 } 648 649 std::string getIsOmitted() const override { 650 return "!((is" + getLowerName().str() + "Expr && " + 651 getLowerName().str() + "Expr) || (!is" + getLowerName().str() + 652 "Expr && " + getLowerName().str() + "Type))"; 653 } 654 655 void writeValue(raw_ostream &OS) const override { 656 OS << "\";\n"; 657 OS << " if (is" << getLowerName() << "Expr && " << getLowerName() 658 << "Expr)"; 659 OS << " " << getLowerName() 660 << "Expr->printPretty(OS, nullptr, Policy);\n"; 661 OS << " if (!is" << getLowerName() << "Expr && " << getLowerName() 662 << "Type)"; 663 OS << " " << getLowerName() 664 << "Type->getType().print(OS, Policy);\n"; 665 OS << " OS << \""; 666 } 667 668 void writeDump(raw_ostream &OS) const override { 669 OS << " if (!SA->is" << getUpperName() << "Expr())\n"; 670 OS << " dumpType(SA->get" << getUpperName() 671 << "Type()->getType());\n"; 672 } 673 674 void writeDumpChildren(raw_ostream &OS) const override { 675 OS << " if (SA->is" << getUpperName() << "Expr())\n"; 676 OS << " Visit(SA->get" << getUpperName() << "Expr());\n"; 677 } 678 679 void writeHasChildren(raw_ostream &OS) const override { 680 OS << "SA->is" << getUpperName() << "Expr()"; 681 } 682 }; 683 684 class VariadicArgument : public Argument { 685 std::string Type, ArgName, ArgSizeName, RangeName; 686 687 protected: 688 // Assumed to receive a parameter: raw_ostream OS. 689 virtual void writeValueImpl(raw_ostream &OS) const { 690 OS << " OS << Val;\n"; 691 } 692 // Assumed to receive a parameter: raw_ostream OS. 693 virtual void writeDumpImpl(raw_ostream &OS) const { 694 OS << " OS << \" \" << Val;\n"; 695 } 696 697 public: 698 VariadicArgument(const Record &Arg, StringRef Attr, std::string T) 699 : Argument(Arg, Attr), Type(std::move(T)), 700 ArgName(getLowerName().str() + "_"), ArgSizeName(ArgName + "Size"), 701 RangeName(getLowerName().str()) {} 702 703 VariadicArgument(StringRef Arg, StringRef Attr, std::string T) 704 : Argument(Arg, Attr), Type(std::move(T)), 705 ArgName(getLowerName().str() + "_"), ArgSizeName(ArgName + "Size"), 706 RangeName(getLowerName().str()) {} 707 708 const std::string &getType() const { return Type; } 709 const std::string &getArgName() const { return ArgName; } 710 const std::string &getArgSizeName() const { return ArgSizeName; } 711 bool isVariadic() const override { return true; } 712 713 void writeAccessors(raw_ostream &OS) const override { 714 std::string IteratorType = getLowerName().str() + "_iterator"; 715 std::string BeginFn = getLowerName().str() + "_begin()"; 716 std::string EndFn = getLowerName().str() + "_end()"; 717 718 OS << " typedef " << Type << "* " << IteratorType << ";\n"; 719 OS << " " << IteratorType << " " << BeginFn << " const {" 720 << " return " << ArgName << "; }\n"; 721 OS << " " << IteratorType << " " << EndFn << " const {" 722 << " return " << ArgName << " + " << ArgSizeName << "; }\n"; 723 OS << " unsigned " << getLowerName() << "_size() const {" 724 << " return " << ArgSizeName << "; }\n"; 725 OS << " llvm::iterator_range<" << IteratorType << "> " << RangeName 726 << "() const { return llvm::make_range(" << BeginFn << ", " << EndFn 727 << "); }\n"; 728 } 729 730 void writeSetter(raw_ostream &OS) const { 731 OS << " void set" << getUpperName() << "(ASTContext &Ctx, "; 732 writeCtorParameters(OS); 733 OS << ") {\n"; 734 OS << " " << ArgSizeName << " = " << getUpperName() << "Size;\n"; 735 OS << " " << ArgName << " = new (Ctx, 16) " << getType() << "[" 736 << ArgSizeName << "];\n"; 737 OS << " "; 738 writeCtorBody(OS); 739 OS << " }\n"; 740 } 741 742 void writeCloneArgs(raw_ostream &OS) const override { 743 OS << ArgName << ", " << ArgSizeName; 744 } 745 746 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 747 // This isn't elegant, but we have to go through public methods... 748 OS << "A->" << getLowerName() << "_begin(), " 749 << "A->" << getLowerName() << "_size()"; 750 } 751 752 void writeASTVisitorTraversal(raw_ostream &OS) const override { 753 // FIXME: Traverse the elements. 754 } 755 756 void writeCtorBody(raw_ostream &OS) const override { 757 OS << " std::copy(" << getUpperName() << ", " << getUpperName() << " + " 758 << ArgSizeName << ", " << ArgName << ");\n"; 759 } 760 761 void writeCtorInitializers(raw_ostream &OS) const override { 762 OS << ArgSizeName << "(" << getUpperName() << "Size), " 763 << ArgName << "(new (Ctx, 16) " << getType() << "[" 764 << ArgSizeName << "])"; 765 } 766 767 void writeCtorDefaultInitializers(raw_ostream &OS) const override { 768 OS << ArgSizeName << "(0), " << ArgName << "(nullptr)"; 769 } 770 771 void writeCtorParameters(raw_ostream &OS) const override { 772 OS << getType() << " *" << getUpperName() << ", unsigned " 773 << getUpperName() << "Size"; 774 } 775 776 void writeImplicitCtorArgs(raw_ostream &OS) const override { 777 OS << getUpperName() << ", " << getUpperName() << "Size"; 778 } 779 780 void writeDeclarations(raw_ostream &OS) const override { 781 OS << " unsigned " << ArgSizeName << ";\n"; 782 OS << " " << getType() << " *" << ArgName << ";"; 783 } 784 785 void writePCHReadDecls(raw_ostream &OS) const override { 786 OS << " unsigned " << getLowerName() << "Size = Record.readInt();\n"; 787 OS << " SmallVector<" << getType() << ", 4> " 788 << getLowerName() << ";\n"; 789 OS << " " << getLowerName() << ".reserve(" << getLowerName() 790 << "Size);\n"; 791 792 // If we can't store the values in the current type (if it's something 793 // like StringRef), store them in a different type and convert the 794 // container afterwards. 795 std::string StorageType = getStorageType(getType()).str(); 796 std::string StorageName = getLowerName().str(); 797 if (StorageType != getType()) { 798 StorageName += "Storage"; 799 OS << " SmallVector<" << StorageType << ", 4> " 800 << StorageName << ";\n"; 801 OS << " " << StorageName << ".reserve(" << getLowerName() 802 << "Size);\n"; 803 } 804 805 OS << " for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n"; 806 std::string read = ReadPCHRecord(Type); 807 OS << " " << StorageName << ".push_back(" << read << ");\n"; 808 809 if (StorageType != getType()) { 810 OS << " for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n"; 811 OS << " " << getLowerName() << ".push_back(" 812 << StorageName << "[i]);\n"; 813 } 814 } 815 816 void writePCHReadArgs(raw_ostream &OS) const override { 817 OS << getLowerName() << ".data(), " << getLowerName() << "Size"; 818 } 819 820 void writePCHWrite(raw_ostream &OS) const override { 821 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; 822 OS << " for (auto &Val : SA->" << RangeName << "())\n"; 823 OS << " " << WritePCHRecord(Type, "Val"); 824 } 825 826 void writeValue(raw_ostream &OS) const override { 827 OS << "\";\n"; 828 OS << " for (const auto &Val : " << RangeName << "()) {\n" 829 << " DelimitAttributeArgument(OS, IsFirstArgument);\n"; 830 writeValueImpl(OS); 831 OS << " }\n"; 832 OS << " OS << \""; 833 } 834 835 void writeDump(raw_ostream &OS) const override { 836 OS << " for (const auto &Val : SA->" << RangeName << "())\n"; 837 writeDumpImpl(OS); 838 } 839 }; 840 841 class VariadicOMPInteropInfoArgument : public VariadicArgument { 842 public: 843 VariadicOMPInteropInfoArgument(const Record &Arg, StringRef Attr) 844 : VariadicArgument(Arg, Attr, "OMPInteropInfo") {} 845 846 void writeDump(raw_ostream &OS) const override { 847 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 848 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" 849 << getLowerName() << "_end(); I != E; ++I) {\n"; 850 OS << " if (I->IsTarget && I->IsTargetSync)\n"; 851 OS << " OS << \" Target_TargetSync\";\n"; 852 OS << " else if (I->IsTarget)\n"; 853 OS << " OS << \" Target\";\n"; 854 OS << " else\n"; 855 OS << " OS << \" TargetSync\";\n"; 856 OS << " }\n"; 857 } 858 859 void writePCHReadDecls(raw_ostream &OS) const override { 860 OS << " unsigned " << getLowerName() << "Size = Record.readInt();\n"; 861 OS << " SmallVector<OMPInteropInfo, 4> " << getLowerName() << ";\n"; 862 OS << " " << getLowerName() << ".reserve(" << getLowerName() 863 << "Size);\n"; 864 OS << " for (unsigned I = 0, E = " << getLowerName() << "Size; "; 865 OS << "I != E; ++I) {\n"; 866 OS << " bool IsTarget = Record.readBool();\n"; 867 OS << " bool IsTargetSync = Record.readBool();\n"; 868 OS << " " << getLowerName() 869 << ".emplace_back(IsTarget, IsTargetSync);\n"; 870 OS << " }\n"; 871 } 872 873 void writePCHWrite(raw_ostream &OS) const override { 874 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; 875 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 876 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" 877 << getLowerName() << "_end(); I != E; ++I) {\n"; 878 OS << " Record.writeBool(I->IsTarget);\n"; 879 OS << " Record.writeBool(I->IsTargetSync);\n"; 880 OS << " }\n"; 881 } 882 }; 883 884 class VariadicParamIdxArgument : public VariadicArgument { 885 public: 886 VariadicParamIdxArgument(const Record &Arg, StringRef Attr) 887 : VariadicArgument(Arg, Attr, "ParamIdx") {} 888 889 public: 890 void writeValueImpl(raw_ostream &OS) const override { 891 OS << " OS << Val.getSourceIndex();\n"; 892 } 893 894 void writeDumpImpl(raw_ostream &OS) const override { 895 OS << " OS << \" \" << Val.getSourceIndex();\n"; 896 } 897 }; 898 899 struct VariadicParamOrParamIdxArgument : public VariadicArgument { 900 VariadicParamOrParamIdxArgument(const Record &Arg, StringRef Attr) 901 : VariadicArgument(Arg, Attr, "int") {} 902 }; 903 904 // Unique the enums, but maintain the original declaration ordering. 905 std::vector<StringRef> 906 uniqueEnumsInOrder(const std::vector<StringRef> &enums) { 907 std::vector<StringRef> uniques; 908 SmallDenseSet<StringRef, 8> unique_set; 909 for (const auto &i : enums) { 910 if (unique_set.insert(i).second) 911 uniques.push_back(i); 912 } 913 return uniques; 914 } 915 916 class EnumArgument : public Argument { 917 std::string fullType; 918 StringRef shortType; 919 std::vector<StringRef> values, enums, uniques; 920 bool isExternal; 921 bool isCovered; 922 923 public: 924 EnumArgument(const Record &Arg, StringRef Attr) 925 : Argument(Arg, Attr), values(Arg.getValueAsListOfStrings("Values")), 926 enums(Arg.getValueAsListOfStrings("Enums")), 927 uniques(uniqueEnumsInOrder(enums)), 928 isExternal(Arg.getValueAsBit("IsExternalType")), 929 isCovered(Arg.getValueAsBit("IsCovered")) { 930 StringRef Type = Arg.getValueAsString("Type"); 931 shortType = isExternal ? Type.rsplit("::").second : Type; 932 // If shortType didn't contain :: at all rsplit will give us an empty 933 // string. 934 if (shortType.empty()) 935 shortType = Type; 936 fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str(); 937 938 // FIXME: Emit a proper error 939 assert(!uniques.empty()); 940 } 941 942 bool isEnumArg() const override { return true; } 943 944 void writeAccessors(raw_ostream &OS) const override { 945 OS << " " << fullType << " get" << getUpperName() << "() const {\n"; 946 OS << " return " << getLowerName() << ";\n"; 947 OS << " }"; 948 } 949 950 void writeCloneArgs(raw_ostream &OS) const override { 951 OS << getLowerName(); 952 } 953 954 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 955 OS << "A->get" << getUpperName() << "()"; 956 } 957 void writeCtorInitializers(raw_ostream &OS) const override { 958 OS << getLowerName() << "(" << getUpperName() << ")"; 959 } 960 void writeCtorDefaultInitializers(raw_ostream &OS) const override { 961 OS << getLowerName() << "(" << fullType << "(0))"; 962 } 963 void writeCtorParameters(raw_ostream &OS) const override { 964 OS << fullType << " " << getUpperName(); 965 } 966 void writeDeclarations(raw_ostream &OS) const override { 967 if (!isExternal) { 968 auto i = uniques.cbegin(), e = uniques.cend(); 969 // The last one needs to not have a comma. 970 --e; 971 972 OS << "public:\n"; 973 OS << " enum " << shortType << " {\n"; 974 for (; i != e; ++i) 975 OS << " " << *i << ",\n"; 976 OS << " " << *e << "\n"; 977 OS << " };\n"; 978 } 979 980 OS << "private:\n"; 981 OS << " " << fullType << " " << getLowerName() << ";"; 982 } 983 984 void writePCHReadDecls(raw_ostream &OS) const override { 985 OS << " " << fullType << " " << getLowerName() << "(static_cast<" 986 << fullType << ">(Record.readInt()));\n"; 987 } 988 989 void writePCHReadArgs(raw_ostream &OS) const override { 990 OS << getLowerName(); 991 } 992 993 void writePCHWrite(raw_ostream &OS) const override { 994 OS << "Record.push_back(static_cast<uint64_t>(SA->get" << getUpperName() 995 << "()));\n"; 996 } 997 998 void writeValue(raw_ostream &OS) const override { 999 // FIXME: this isn't 100% correct -- some enum arguments require printing 1000 // as a string literal, while others require printing as an identifier. 1001 // Tablegen currently does not distinguish between the two forms. 1002 OS << "\\\"\" << " << getAttrName() << "Attr::Convert" << shortType 1003 << "ToStr(get" << getUpperName() << "()) << \"\\\""; 1004 } 1005 1006 void writeDump(raw_ostream &OS) const override { 1007 OS << " switch(SA->get" << getUpperName() << "()) {\n"; 1008 for (const auto &I : uniques) { 1009 OS << " case " << fullType << "::" << I << ":\n"; 1010 OS << " OS << \" " << I << "\";\n"; 1011 OS << " break;\n"; 1012 } 1013 if (!isCovered) { 1014 OS << " default:\n"; 1015 OS << " llvm_unreachable(\"Invalid attribute value\");\n"; 1016 } 1017 OS << " }\n"; 1018 } 1019 1020 void writeConversion(raw_ostream &OS, bool Header) const { 1021 if (Header) { 1022 OS << " static bool ConvertStrTo" << shortType << "(StringRef Val, " 1023 << fullType << " &Out);\n"; 1024 OS << " static const char *Convert" << shortType << "ToStr(" 1025 << fullType << " Val);\n"; 1026 return; 1027 } 1028 1029 OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << shortType 1030 << "(StringRef Val, " << fullType << " &Out) {\n"; 1031 OS << " std::optional<" << fullType << "> " 1032 << "R = llvm::StringSwitch<std::optional<" << fullType << ">>(Val)\n"; 1033 for (size_t I = 0; I < enums.size(); ++I) { 1034 OS << " .Case(\"" << values[I] << "\", "; 1035 OS << fullType << "::" << enums[I] << ")\n"; 1036 } 1037 OS << " .Default(std::optional<" << fullType << ">());\n"; 1038 OS << " if (R) {\n"; 1039 OS << " Out = *R;\n return true;\n }\n"; 1040 OS << " return false;\n"; 1041 OS << "}\n\n"; 1042 1043 // Mapping from enumeration values back to enumeration strings isn't 1044 // trivial because some enumeration values have multiple named 1045 // enumerators, such as type_visibility(internal) and 1046 // type_visibility(hidden) both mapping to TypeVisibilityAttr::Hidden. 1047 OS << "const char *" << getAttrName() << "Attr::Convert" << shortType 1048 << "ToStr(" << fullType << " Val) {\n" 1049 << " switch(Val) {\n"; 1050 SmallDenseSet<StringRef, 8> Uniques; 1051 for (size_t I = 0; I < enums.size(); ++I) { 1052 if (Uniques.insert(enums[I]).second) 1053 OS << " case " << fullType << "::" << enums[I] << ": return \"" 1054 << values[I] << "\";\n"; 1055 } 1056 if (!isCovered) { 1057 OS << " default: llvm_unreachable(\"Invalid attribute value\");\n"; 1058 } 1059 OS << " }\n" 1060 << " llvm_unreachable(\"No enumerator with that value\");\n" 1061 << "}\n"; 1062 } 1063 }; 1064 1065 class VariadicEnumArgument: public VariadicArgument { 1066 std::string fullType; 1067 StringRef shortType; 1068 std::vector<StringRef> values, enums, uniques; 1069 bool isExternal; 1070 bool isCovered; 1071 1072 protected: 1073 void writeValueImpl(raw_ostream &OS) const override { 1074 // FIXME: this isn't 100% correct -- some enum arguments require printing 1075 // as a string literal, while others require printing as an identifier. 1076 // Tablegen currently does not distinguish between the two forms. 1077 OS << " OS << \"\\\"\" << " << getAttrName() << "Attr::Convert" 1078 << shortType << "ToStr(Val)" 1079 << "<< \"\\\"\";\n"; 1080 } 1081 1082 public: 1083 VariadicEnumArgument(const Record &Arg, StringRef Attr) 1084 : VariadicArgument(Arg, Attr, Arg.getValueAsString("Type").str()), 1085 values(Arg.getValueAsListOfStrings("Values")), 1086 enums(Arg.getValueAsListOfStrings("Enums")), 1087 uniques(uniqueEnumsInOrder(enums)), 1088 isExternal(Arg.getValueAsBit("IsExternalType")), 1089 isCovered(Arg.getValueAsBit("IsCovered")) { 1090 StringRef Type = Arg.getValueAsString("Type"); 1091 shortType = isExternal ? Type.rsplit("::").second : Type; 1092 // If shortType didn't contain :: at all rsplit will give us an empty 1093 // string. 1094 if (shortType.empty()) 1095 shortType = Type; 1096 fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str(); 1097 1098 // FIXME: Emit a proper error 1099 assert(!uniques.empty()); 1100 } 1101 1102 bool isVariadicEnumArg() const override { return true; } 1103 1104 void writeDeclarations(raw_ostream &OS) const override { 1105 if (!isExternal) { 1106 auto i = uniques.cbegin(), e = uniques.cend(); 1107 // The last one needs to not have a comma. 1108 --e; 1109 1110 OS << "public:\n"; 1111 OS << " enum " << shortType << " {\n"; 1112 for (; i != e; ++i) 1113 OS << " " << *i << ",\n"; 1114 OS << " " << *e << "\n"; 1115 OS << " };\n"; 1116 } 1117 OS << "private:\n"; 1118 1119 VariadicArgument::writeDeclarations(OS); 1120 } 1121 1122 void writeDump(raw_ostream &OS) const override { 1123 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 1124 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" 1125 << getLowerName() << "_end(); I != E; ++I) {\n"; 1126 OS << " switch(*I) {\n"; 1127 for (const auto &UI : uniques) { 1128 OS << " case " << fullType << "::" << UI << ":\n"; 1129 OS << " OS << \" " << UI << "\";\n"; 1130 OS << " break;\n"; 1131 } 1132 if (!isCovered) { 1133 OS << " default:\n"; 1134 OS << " llvm_unreachable(\"Invalid attribute value\");\n"; 1135 } 1136 OS << " }\n"; 1137 OS << " }\n"; 1138 } 1139 1140 void writePCHReadDecls(raw_ostream &OS) const override { 1141 OS << " unsigned " << getLowerName() << "Size = Record.readInt();\n"; 1142 OS << " SmallVector<" << fullType << ", 4> " << getLowerName() 1143 << ";\n"; 1144 OS << " " << getLowerName() << ".reserve(" << getLowerName() 1145 << "Size);\n"; 1146 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; 1147 OS << " " << getLowerName() << ".push_back(" 1148 << "static_cast<" << fullType << ">(Record.readInt()));\n"; 1149 } 1150 1151 void writePCHWrite(raw_ostream &OS) const override { 1152 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; 1153 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 1154 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" 1155 << getLowerName() << "_end(); i != e; ++i)\n"; 1156 OS << " " << WritePCHRecord(fullType, "(*i)"); 1157 } 1158 1159 void writeConversion(raw_ostream &OS, bool Header) const { 1160 if (Header) { 1161 OS << " static bool ConvertStrTo" << shortType << "(StringRef Val, " 1162 << fullType << " &Out);\n"; 1163 OS << " static const char *Convert" << shortType << "ToStr(" 1164 << fullType << " Val);\n"; 1165 return; 1166 } 1167 1168 OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << shortType 1169 << "(StringRef Val, "; 1170 OS << fullType << " &Out) {\n"; 1171 OS << " std::optional<" << fullType 1172 << "> R = llvm::StringSwitch<std::optional<"; 1173 OS << fullType << ">>(Val)\n"; 1174 for (size_t I = 0; I < enums.size(); ++I) { 1175 OS << " .Case(\"" << values[I] << "\", "; 1176 OS << fullType << "::" << enums[I] << ")\n"; 1177 } 1178 OS << " .Default(std::optional<" << fullType << ">());\n"; 1179 OS << " if (R) {\n"; 1180 OS << " Out = *R;\n return true;\n }\n"; 1181 OS << " return false;\n"; 1182 OS << "}\n\n"; 1183 1184 OS << "const char *" << getAttrName() << "Attr::Convert" << shortType 1185 << "ToStr(" << fullType << " Val) {\n" 1186 << " switch(Val) {\n"; 1187 SmallDenseSet<StringRef, 8> Uniques; 1188 for (size_t I = 0; I < enums.size(); ++I) { 1189 if (Uniques.insert(enums[I]).second) 1190 OS << " case " << fullType << "::" << enums[I] << ": return \"" 1191 << values[I] << "\";\n"; 1192 } 1193 if (!isCovered) { 1194 OS << " default: llvm_unreachable(\"Invalid attribute value\");\n"; 1195 } 1196 OS << " }\n" 1197 << " llvm_unreachable(\"No enumerator with that value\");\n" 1198 << "}\n"; 1199 } 1200 }; 1201 1202 class VersionArgument : public Argument { 1203 public: 1204 VersionArgument(const Record &Arg, StringRef Attr) 1205 : Argument(Arg, Attr) 1206 {} 1207 1208 void writeAccessors(raw_ostream &OS) const override { 1209 OS << " VersionTuple get" << getUpperName() << "() const {\n"; 1210 OS << " return " << getLowerName() << ";\n"; 1211 OS << " }\n"; 1212 OS << " void set" << getUpperName() 1213 << "(ASTContext &C, VersionTuple V) {\n"; 1214 OS << " " << getLowerName() << " = V;\n"; 1215 OS << " }"; 1216 } 1217 1218 void writeCloneArgs(raw_ostream &OS) const override { 1219 OS << "get" << getUpperName() << "()"; 1220 } 1221 1222 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 1223 OS << "A->get" << getUpperName() << "()"; 1224 } 1225 1226 void writeCtorInitializers(raw_ostream &OS) const override { 1227 OS << getLowerName() << "(" << getUpperName() << ")"; 1228 } 1229 1230 void writeCtorDefaultInitializers(raw_ostream &OS) const override { 1231 OS << getLowerName() << "()"; 1232 } 1233 1234 void writeCtorParameters(raw_ostream &OS) const override { 1235 OS << "VersionTuple " << getUpperName(); 1236 } 1237 1238 void writeDeclarations(raw_ostream &OS) const override { 1239 OS << "VersionTuple " << getLowerName() << ";\n"; 1240 } 1241 1242 void writePCHReadDecls(raw_ostream &OS) const override { 1243 OS << " VersionTuple " << getLowerName() 1244 << "= Record.readVersionTuple();\n"; 1245 } 1246 1247 void writePCHReadArgs(raw_ostream &OS) const override { 1248 OS << getLowerName(); 1249 } 1250 1251 void writePCHWrite(raw_ostream &OS) const override { 1252 OS << " Record.AddVersionTuple(SA->get" << getUpperName() << "());\n"; 1253 } 1254 1255 void writeValue(raw_ostream &OS) const override { 1256 OS << getLowerName() << "=\" << get" << getUpperName() << "() << \""; 1257 } 1258 1259 void writeDump(raw_ostream &OS) const override { 1260 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; 1261 } 1262 }; 1263 1264 class ExprArgument : public SimpleArgument { 1265 public: 1266 ExprArgument(const Record &Arg, StringRef Attr) 1267 : SimpleArgument(Arg, Attr, "Expr *") 1268 {} 1269 1270 void writeASTVisitorTraversal(raw_ostream &OS) const override { 1271 OS << " if (!" 1272 << "getDerived().TraverseStmt(A->get" << getUpperName() << "()))\n"; 1273 OS << " return false;\n"; 1274 } 1275 1276 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 1277 OS << "tempInst" << getUpperName(); 1278 } 1279 1280 void writeTemplateInstantiation(raw_ostream &OS) const override { 1281 OS << " " << getType() << " tempInst" << getUpperName() << ";\n"; 1282 OS << " {\n"; 1283 OS << " EnterExpressionEvaluationContext " 1284 << "Unevaluated(S, Sema::ExpressionEvaluationContext::Unevaluated);\n"; 1285 OS << " ExprResult " << "Result = S.SubstExpr(" 1286 << "A->get" << getUpperName() << "(), TemplateArgs);\n"; 1287 OS << " if (Result.isInvalid())\n"; 1288 OS << " return nullptr;\n"; 1289 OS << " tempInst" << getUpperName() << " = Result.get();\n"; 1290 OS << " }\n"; 1291 } 1292 1293 void writeValue(raw_ostream &OS) const override { 1294 OS << "\";\n"; 1295 OS << " get" << getUpperName() 1296 << "()->printPretty(OS, nullptr, Policy);\n"; 1297 OS << " OS << \""; 1298 } 1299 1300 void writeDump(raw_ostream &OS) const override {} 1301 1302 void writeDumpChildren(raw_ostream &OS) const override { 1303 OS << " Visit(SA->get" << getUpperName() << "());\n"; 1304 } 1305 1306 void writeHasChildren(raw_ostream &OS) const override { OS << "true"; } 1307 }; 1308 1309 class VariadicExprArgument : public VariadicArgument { 1310 public: 1311 VariadicExprArgument(const Record &Arg, StringRef Attr) 1312 : VariadicArgument(Arg, Attr, "Expr *") 1313 {} 1314 1315 VariadicExprArgument(StringRef ArgName, StringRef Attr) 1316 : VariadicArgument(ArgName, Attr, "Expr *") {} 1317 1318 void writeASTVisitorTraversal(raw_ostream &OS) const override { 1319 OS << " {\n"; 1320 OS << " " << getType() << " *I = A->" << getLowerName() 1321 << "_begin();\n"; 1322 OS << " " << getType() << " *E = A->" << getLowerName() 1323 << "_end();\n"; 1324 OS << " for (; I != E; ++I) {\n"; 1325 OS << " if (!getDerived().TraverseStmt(*I))\n"; 1326 OS << " return false;\n"; 1327 OS << " }\n"; 1328 OS << " }\n"; 1329 } 1330 1331 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 1332 OS << "tempInst" << getUpperName() << ", " 1333 << "numTempInst" << getUpperName(); 1334 } 1335 1336 void writeTemplateInstantiation(raw_ostream &OS) const override { 1337 OS << " size_t numTempInst" << getUpperName() << ";\n"; 1338 OS << " " << getType() << "*tempInst" << getUpperName() << ";\n"; 1339 OS << " {\n"; 1340 OS << " EnterExpressionEvaluationContext " 1341 << "Unevaluated(S, Sema::ExpressionEvaluationContext::Unevaluated);\n"; 1342 OS << " ArrayRef<" << getType() << "> ArgsToInstantiate(A->" 1343 << getLowerName() << "_begin(), A->" << getLowerName() << "_end());\n"; 1344 OS << " SmallVector<" << getType() << ", 4> InstArgs;\n"; 1345 OS << " if (S.SubstExprs(ArgsToInstantiate, /*IsCall=*/false, " 1346 "TemplateArgs, InstArgs))\n"; 1347 OS << " return nullptr;\n"; 1348 OS << " numTempInst" << getUpperName() << " = InstArgs.size();\n"; 1349 OS << " tempInst" << getUpperName() << " = new (C, 16) " 1350 << getType() << "[numTempInst" << getUpperName() << "];\n"; 1351 OS << " std::copy(InstArgs.begin(), InstArgs.end(), tempInst" 1352 << getUpperName() << ");\n"; 1353 OS << " }\n"; 1354 } 1355 1356 void writeDump(raw_ostream &OS) const override {} 1357 1358 void writeDumpChildren(raw_ostream &OS) const override { 1359 OS << " for (" << getAttrName() << "Attr::" << getLowerName() 1360 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" 1361 << getLowerName() << "_end(); I != E; ++I)\n"; 1362 OS << " Visit(*I);\n"; 1363 } 1364 1365 void writeHasChildren(raw_ostream &OS) const override { 1366 OS << "SA->" << getLowerName() << "_begin() != " 1367 << "SA->" << getLowerName() << "_end()"; 1368 } 1369 }; 1370 1371 class VariadicIdentifierArgument : public VariadicArgument { 1372 public: 1373 VariadicIdentifierArgument(const Record &Arg, StringRef Attr) 1374 : VariadicArgument(Arg, Attr, "IdentifierInfo *") 1375 {} 1376 }; 1377 1378 class VariadicStringArgument : public VariadicArgument { 1379 public: 1380 VariadicStringArgument(const Record &Arg, StringRef Attr) 1381 : VariadicArgument(Arg, Attr, "StringRef") 1382 {} 1383 1384 void writeCtorBody(raw_ostream &OS) const override { 1385 OS << " for (size_t I = 0, E = " << getArgSizeName() << "; I != E;\n" 1386 " ++I) {\n" 1387 " StringRef Ref = " << getUpperName() << "[I];\n" 1388 " if (!Ref.empty()) {\n" 1389 " char *Mem = new (Ctx, 1) char[Ref.size()];\n" 1390 " std::memcpy(Mem, Ref.data(), Ref.size());\n" 1391 " " << getArgName() << "[I] = StringRef(Mem, Ref.size());\n" 1392 " }\n" 1393 " }\n"; 1394 } 1395 1396 void writeValueImpl(raw_ostream &OS) const override { 1397 OS << " OS << \"\\\"\" << Val << \"\\\"\";\n"; 1398 } 1399 }; 1400 1401 class TypeArgument : public SimpleArgument { 1402 public: 1403 TypeArgument(const Record &Arg, StringRef Attr) 1404 : SimpleArgument(Arg, Attr, "TypeSourceInfo *") 1405 {} 1406 1407 void writeAccessors(raw_ostream &OS) const override { 1408 OS << " QualType get" << getUpperName() << "() const {\n"; 1409 OS << " return " << getLowerName() << "->getType();\n"; 1410 OS << " }"; 1411 OS << " " << getType() << " get" << getUpperName() << "Loc() const {\n"; 1412 OS << " return " << getLowerName() << ";\n"; 1413 OS << " }"; 1414 } 1415 1416 void writeASTVisitorTraversal(raw_ostream &OS) const override { 1417 OS << " if (auto *TSI = A->get" << getUpperName() << "Loc())\n"; 1418 OS << " if (!getDerived().TraverseTypeLoc(TSI->getTypeLoc()))\n"; 1419 OS << " return false;\n"; 1420 } 1421 1422 void writeTemplateInstantiation(raw_ostream &OS) const override { 1423 OS << " " << getType() << " tempInst" << getUpperName() << " =\n"; 1424 OS << " S.SubstType(A->get" << getUpperName() << "Loc(), " 1425 << "TemplateArgs, A->getLoc(), A->getAttrName());\n"; 1426 OS << " if (!tempInst" << getUpperName() << ")\n"; 1427 OS << " return nullptr;\n"; 1428 } 1429 1430 void writeTemplateInstantiationArgs(raw_ostream &OS) const override { 1431 OS << "tempInst" << getUpperName(); 1432 } 1433 1434 void writePCHWrite(raw_ostream &OS) const override { 1435 OS << " " 1436 << WritePCHRecord(getType(), 1437 "SA->get" + getUpperName().str() + "Loc()"); 1438 } 1439 }; 1440 1441 class WrappedAttr : public SimpleArgument { 1442 public: 1443 WrappedAttr(const Record &Arg, StringRef Attr) 1444 : SimpleArgument(Arg, Attr, "Attr *") {} 1445 1446 void writePCHReadDecls(raw_ostream &OS) const override { 1447 OS << " Attr *" << getLowerName() << " = Record.readAttr();"; 1448 } 1449 1450 void writePCHWrite(raw_ostream &OS) const override { 1451 OS << " AddAttr(SA->get" << getUpperName() << "());"; 1452 } 1453 1454 void writeDump(raw_ostream &OS) const override {} 1455 1456 void writeDumpChildren(raw_ostream &OS) const override { 1457 OS << " Visit(SA->get" << getUpperName() << "());\n"; 1458 } 1459 1460 void writeHasChildren(raw_ostream &OS) const override { OS << "true"; } 1461 }; 1462 1463 } // end anonymous namespace 1464 1465 static std::unique_ptr<Argument> 1466 createArgument(const Record &Arg, StringRef Attr, 1467 const Record *Search = nullptr) { 1468 if (!Search) 1469 Search = &Arg; 1470 1471 std::unique_ptr<Argument> Ptr; 1472 StringRef ArgName = Search->getName(); 1473 1474 if (ArgName == "AlignedArgument") 1475 Ptr = std::make_unique<AlignedArgument>(Arg, Attr); 1476 else if (ArgName == "EnumArgument") 1477 Ptr = std::make_unique<EnumArgument>(Arg, Attr); 1478 else if (ArgName == "ExprArgument") 1479 Ptr = std::make_unique<ExprArgument>(Arg, Attr); 1480 else if (ArgName == "DeclArgument") 1481 Ptr = std::make_unique<SimpleArgument>( 1482 Arg, Attr, (Arg.getValueAsDef("Kind")->getName() + "Decl *").str()); 1483 else if (ArgName == "IdentifierArgument") 1484 Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "IdentifierInfo *"); 1485 else if (ArgName == "DefaultBoolArgument") 1486 Ptr = std::make_unique<DefaultSimpleArgument>( 1487 Arg, Attr, "bool", Arg.getValueAsBit("Default")); 1488 else if (ArgName == "BoolArgument") 1489 Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "bool"); 1490 else if (ArgName == "DefaultIntArgument") 1491 Ptr = std::make_unique<DefaultSimpleArgument>( 1492 Arg, Attr, "int", Arg.getValueAsInt("Default")); 1493 else if (ArgName == "IntArgument") 1494 Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "int"); 1495 else if (ArgName == "StringArgument") 1496 Ptr = std::make_unique<StringArgument>(Arg, Attr); 1497 else if (ArgName == "TypeArgument") 1498 Ptr = std::make_unique<TypeArgument>(Arg, Attr); 1499 else if (ArgName == "UnsignedArgument") 1500 Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "unsigned"); 1501 else if (ArgName == "VariadicUnsignedArgument") 1502 Ptr = std::make_unique<VariadicArgument>(Arg, Attr, "unsigned"); 1503 else if (ArgName == "VariadicStringArgument") 1504 Ptr = std::make_unique<VariadicStringArgument>(Arg, Attr); 1505 else if (ArgName == "VariadicEnumArgument") 1506 Ptr = std::make_unique<VariadicEnumArgument>(Arg, Attr); 1507 else if (ArgName == "VariadicExprArgument") 1508 Ptr = std::make_unique<VariadicExprArgument>(Arg, Attr); 1509 else if (ArgName == "VariadicParamIdxArgument") 1510 Ptr = std::make_unique<VariadicParamIdxArgument>(Arg, Attr); 1511 else if (ArgName == "VariadicParamOrParamIdxArgument") 1512 Ptr = std::make_unique<VariadicParamOrParamIdxArgument>(Arg, Attr); 1513 else if (ArgName == "ParamIdxArgument") 1514 Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "ParamIdx"); 1515 else if (ArgName == "VariadicIdentifierArgument") 1516 Ptr = std::make_unique<VariadicIdentifierArgument>(Arg, Attr); 1517 else if (ArgName == "VersionArgument") 1518 Ptr = std::make_unique<VersionArgument>(Arg, Attr); 1519 else if (ArgName == "WrappedAttr") 1520 Ptr = std::make_unique<WrappedAttr>(Arg, Attr); 1521 else if (ArgName == "OMPTraitInfoArgument") 1522 Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "OMPTraitInfo *"); 1523 else if (ArgName == "VariadicOMPInteropInfoArgument") 1524 Ptr = std::make_unique<VariadicOMPInteropInfoArgument>(Arg, Attr); 1525 1526 if (!Ptr) { 1527 // Search in reverse order so that the most-derived type is handled first. 1528 std::vector<const Record *> SCs = Search->getSuperClasses(); 1529 for (const Record *Base : reverse(SCs)) { 1530 if ((Ptr = createArgument(Arg, Attr, Base))) 1531 break; 1532 } 1533 } 1534 1535 if (Ptr && Arg.getValueAsBit("Optional")) 1536 Ptr->setOptional(true); 1537 1538 if (Ptr && Arg.getValueAsBit("Fake")) 1539 Ptr->setFake(true); 1540 1541 return Ptr; 1542 } 1543 1544 static void writeAvailabilityValue(raw_ostream &OS) { 1545 OS << "\" << getPlatform()->getName();\n" 1546 << " if (getStrict()) OS << \", strict\";\n" 1547 << " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n" 1548 << " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n" 1549 << " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n" 1550 << " if (getUnavailable()) OS << \", unavailable\";\n" 1551 << " OS << \""; 1552 } 1553 1554 static void writeDeprecatedAttrValue(raw_ostream &OS, StringRef Variety) { 1555 OS << "\\\"\" << getMessage() << \"\\\"\";\n"; 1556 // Only GNU deprecated has an optional fixit argument at the second position. 1557 if (Variety == "GNU") 1558 OS << " if (!getReplacement().empty()) OS << \", \\\"\"" 1559 " << getReplacement() << \"\\\"\";\n"; 1560 OS << " OS << \""; 1561 } 1562 1563 static void writeGetSpellingFunction(const Record &R, raw_ostream &OS) { 1564 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R); 1565 1566 OS << "const char *" << R.getName() << "Attr::getSpelling() const {\n"; 1567 if (Spellings.empty()) { 1568 OS << " return \"(No spelling)\";\n}\n\n"; 1569 return; 1570 } 1571 1572 OS << " switch (getAttributeSpellingListIndex()) {\n" 1573 " default:\n" 1574 " llvm_unreachable(\"Unknown attribute spelling!\");\n" 1575 " return \"(No spelling)\";\n"; 1576 1577 for (const auto &[Idx, S] : enumerate(Spellings)) { 1578 // clang-format off 1579 OS << " case " << Idx << ":\n" 1580 " return \"" << S.name() << "\";\n"; 1581 // clang-format on 1582 } 1583 // End of the switch statement. 1584 OS << " }\n"; 1585 // End of the getSpelling function. 1586 OS << "}\n\n"; 1587 } 1588 1589 static void 1590 writePrettyPrintFunction(const Record &R, 1591 const std::vector<std::unique_ptr<Argument>> &Args, 1592 raw_ostream &OS) { 1593 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R); 1594 1595 OS << "void " << R.getName() << "Attr::printPretty(" 1596 << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n"; 1597 1598 if (Spellings.empty()) { 1599 OS << "}\n\n"; 1600 return; 1601 } 1602 1603 OS << " bool IsFirstArgument = true; (void)IsFirstArgument;\n" 1604 << " unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;\n" 1605 << " switch (getAttributeSpellingListIndex()) {\n" 1606 << " default:\n" 1607 << " llvm_unreachable(\"Unknown attribute spelling!\");\n" 1608 << " break;\n"; 1609 1610 for (const auto &[Idx, S] : enumerate(Spellings)) { 1611 SmallString<16> Prefix; 1612 SmallString<8> Suffix; 1613 // The actual spelling of the name and namespace (if applicable) 1614 // of an attribute without considering prefix and suffix. 1615 SmallString<64> Spelling; 1616 StringRef Name = S.name(); 1617 StringRef Variety = S.variety(); 1618 1619 if (Variety == "GNU") { 1620 Prefix = "__attribute__(("; 1621 Suffix = "))"; 1622 } else if (Variety == "CXX11" || Variety == "C23") { 1623 Prefix = "[["; 1624 Suffix = "]]"; 1625 StringRef Namespace = S.nameSpace(); 1626 if (!Namespace.empty()) { 1627 Spelling += Namespace; 1628 Spelling += "::"; 1629 } 1630 } else if (Variety == "Declspec") { 1631 Prefix = "__declspec("; 1632 Suffix = ")"; 1633 } else if (Variety == "Microsoft") { 1634 Prefix = "["; 1635 Suffix = "]"; 1636 } else if (Variety == "Keyword") { 1637 Prefix = ""; 1638 Suffix = ""; 1639 } else if (Variety == "Pragma") { 1640 Prefix = "#pragma "; 1641 Suffix = "\n"; 1642 StringRef Namespace = S.nameSpace(); 1643 if (!Namespace.empty()) { 1644 Spelling += Namespace; 1645 Spelling += " "; 1646 } 1647 } else if (Variety == "HLSLAnnotation") { 1648 Prefix = ":"; 1649 Suffix = ""; 1650 } else { 1651 llvm_unreachable("Unknown attribute syntax variety!"); 1652 } 1653 1654 Spelling += Name; 1655 1656 OS << " case " << Idx << " : {\n" 1657 << " OS << \"" << Prefix << Spelling << "\";\n"; 1658 1659 if (Variety == "Pragma") { 1660 OS << " printPrettyPragma(OS, Policy);\n"; 1661 OS << " OS << \"\\n\";"; 1662 OS << " break;\n"; 1663 OS << " }\n"; 1664 continue; 1665 } 1666 1667 if (Spelling == "availability") { 1668 OS << " OS << \"("; 1669 writeAvailabilityValue(OS); 1670 OS << ")\";\n"; 1671 } else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") { 1672 OS << " OS << \"("; 1673 writeDeprecatedAttrValue(OS, Variety); 1674 OS << ")\";\n"; 1675 } else { 1676 // To avoid printing parentheses around an empty argument list or 1677 // printing spurious commas at the end of an argument list, we need to 1678 // determine where the last provided non-fake argument is. 1679 bool FoundNonOptArg = false; 1680 for (const auto &arg : reverse(Args)) { 1681 if (arg->isFake()) 1682 continue; 1683 if (FoundNonOptArg) 1684 continue; 1685 // FIXME: arg->getIsOmitted() == "false" means we haven't implemented 1686 // any way to detect whether the argument was omitted. 1687 if (!arg->isOptional() || arg->getIsOmitted() == "false") { 1688 FoundNonOptArg = true; 1689 continue; 1690 } 1691 OS << " if (" << arg->getIsOmitted() << ")\n" 1692 << " ++TrailingOmittedArgs;\n"; 1693 } 1694 unsigned ArgIndex = 0; 1695 for (const auto &arg : Args) { 1696 if (arg->isFake()) 1697 continue; 1698 std::string IsOmitted = arg->getIsOmitted(); 1699 if (arg->isOptional() && IsOmitted != "false") 1700 OS << " if (!(" << IsOmitted << ")) {\n"; 1701 // Variadic arguments print their own leading comma. 1702 if (!arg->isVariadic()) 1703 OS << " DelimitAttributeArgument(OS, IsFirstArgument);\n"; 1704 OS << " OS << \""; 1705 arg->writeValue(OS); 1706 OS << "\";\n"; 1707 if (arg->isOptional() && IsOmitted != "false") 1708 OS << " }\n"; 1709 ++ArgIndex; 1710 } 1711 if (ArgIndex != 0) 1712 OS << " if (!IsFirstArgument)\n" 1713 << " OS << \")\";\n"; 1714 } 1715 OS << " OS << \"" << Suffix << "\";\n" 1716 << " break;\n" 1717 << " }\n"; 1718 } 1719 1720 // End of the switch statement. 1721 OS << "}\n"; 1722 // End of the print function. 1723 OS << "}\n\n"; 1724 } 1725 1726 /// Return the index of a spelling in a spelling list. 1727 static unsigned getSpellingListIndex(ArrayRef<FlattenedSpelling> SpellingList, 1728 const FlattenedSpelling &Spelling) { 1729 assert(!SpellingList.empty() && "Spelling list is empty!"); 1730 1731 for (const auto &[Index, S] : enumerate(SpellingList)) { 1732 if (S.variety() == Spelling.variety() && 1733 S.nameSpace() == Spelling.nameSpace() && S.name() == Spelling.name()) 1734 return Index; 1735 } 1736 1737 PrintFatalError("Unknown spelling: " + Spelling.name()); 1738 } 1739 1740 static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) { 1741 std::vector<const Record *> Accessors = R.getValueAsListOfDefs("Accessors"); 1742 if (Accessors.empty()) 1743 return; 1744 1745 const std::vector<FlattenedSpelling> SpellingList = GetFlattenedSpellings(R); 1746 assert(!SpellingList.empty() && 1747 "Attribute with empty spelling list can't have accessors!"); 1748 for (const auto *Accessor : Accessors) { 1749 const StringRef Name = Accessor->getValueAsString("Name"); 1750 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Accessor); 1751 1752 OS << " bool " << Name 1753 << "() const { return getAttributeSpellingListIndex() == "; 1754 for (unsigned Index = 0; Index < Spellings.size(); ++Index) { 1755 OS << getSpellingListIndex(SpellingList, Spellings[Index]); 1756 if (Index != Spellings.size() - 1) 1757 OS << " ||\n getAttributeSpellingListIndex() == "; 1758 else 1759 OS << "; }\n"; 1760 } 1761 } 1762 } 1763 1764 static bool 1765 SpellingNamesAreCommon(const std::vector<FlattenedSpelling>& Spellings) { 1766 assert(!Spellings.empty() && "An empty list of spellings was provided"); 1767 StringRef FirstName = 1768 NormalizeNameForSpellingComparison(Spellings.front().name()); 1769 for (const auto &Spelling : drop_begin(Spellings)) { 1770 StringRef Name = NormalizeNameForSpellingComparison(Spelling.name()); 1771 if (Name != FirstName) 1772 return false; 1773 } 1774 return true; 1775 } 1776 1777 typedef std::map<unsigned, std::string> SemanticSpellingMap; 1778 static std::string 1779 CreateSemanticSpellings(const std::vector<FlattenedSpelling> &Spellings, 1780 SemanticSpellingMap &Map) { 1781 // The enumerants are automatically generated based on the variety, 1782 // namespace (if present) and name for each attribute spelling. However, 1783 // care is taken to avoid trampling on the reserved namespace due to 1784 // underscores. 1785 std::string Ret(" enum Spelling {\n"); 1786 std::set<std::string> Uniques; 1787 unsigned Idx = 0; 1788 1789 // If we have a need to have this many spellings we likely need to add an 1790 // extra bit to the SpellingIndex in AttributeCommonInfo, then increase the 1791 // value of SpellingNotCalculated there and here. 1792 assert(Spellings.size() < 15 && 1793 "Too many spellings, would step on SpellingNotCalculated in " 1794 "AttributeCommonInfo"); 1795 for (auto I = Spellings.begin(), E = Spellings.end(); I != E; ++I, ++Idx) { 1796 const FlattenedSpelling &S = *I; 1797 StringRef Variety = S.variety(); 1798 StringRef Spelling = S.name(); 1799 StringRef Namespace = S.nameSpace(); 1800 std::string EnumName; 1801 1802 EnumName += Variety; 1803 EnumName += "_"; 1804 if (!Namespace.empty()) 1805 EnumName += NormalizeNameForSpellingComparison(Namespace).str() + "_"; 1806 EnumName += NormalizeNameForSpellingComparison(Spelling); 1807 1808 // Even if the name is not unique, this spelling index corresponds to a 1809 // particular enumerant name that we've calculated. 1810 Map[Idx] = EnumName; 1811 1812 // Since we have been stripping underscores to avoid trampling on the 1813 // reserved namespace, we may have inadvertently created duplicate 1814 // enumerant names. These duplicates are not considered part of the 1815 // semantic spelling, and can be elided. 1816 if (!Uniques.insert(EnumName).second) 1817 continue; 1818 1819 if (I != Spellings.begin()) 1820 Ret += ",\n"; 1821 // Duplicate spellings are not considered part of the semantic spelling 1822 // enumeration, but the spelling index and semantic spelling values are 1823 // meant to be equivalent, so we must specify a concrete value for each 1824 // enumerator. 1825 Ret += " " + EnumName + " = " + utostr(Idx); 1826 } 1827 Ret += ",\n SpellingNotCalculated = 15\n"; 1828 Ret += "\n };\n\n"; 1829 return Ret; 1830 } 1831 1832 static void WriteSemanticSpellingSwitch(StringRef VarName, 1833 const SemanticSpellingMap &Map, 1834 raw_ostream &OS) { 1835 OS << " switch (" << VarName << ") {\n default: " 1836 << "llvm_unreachable(\"Unknown spelling list index\");\n"; 1837 for (const auto &I : Map) 1838 OS << " case " << I.first << ": return " << I.second << ";\n"; 1839 OS << " }\n"; 1840 } 1841 1842 // Note: these values need to match the values used by LateAttrParseKind in 1843 // `Attr.td` 1844 enum class LateAttrParseKind { Never = 0, Standard = 1, ExperimentalExt = 2 }; 1845 1846 static LateAttrParseKind getLateAttrParseKind(const Record *Attr) { 1847 // This function basically does 1848 // `Attr->getValueAsDef("LateParsed")->getValueAsInt("Kind")` but does a bunch 1849 // of sanity checking to ensure that `LateAttrParseMode` in `Attr.td` is in 1850 // sync with the `LateAttrParseKind` enum in this source file. 1851 1852 static constexpr StringRef LateParsedStr = "LateParsed"; 1853 static constexpr StringRef LateAttrParseKindStr = "LateAttrParseKind"; 1854 static constexpr StringRef KindFieldStr = "Kind"; 1855 1856 auto *LAPK = Attr->getValueAsDef(LateParsedStr); 1857 1858 // Typecheck the `LateParsed` field. 1859 if (LAPK->getDirectSuperClasses().size() != 1) 1860 PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) + 1861 "`should only have one super class"); 1862 1863 const Record *SuperClass = LAPK->getDirectSuperClasses()[0].first; 1864 if (SuperClass->getName() != LateAttrParseKindStr) 1865 PrintFatalError( 1866 Attr, "Field `" + Twine(LateParsedStr) + "`should only have type `" + 1867 Twine(LateAttrParseKindStr) + "` but found type `" + 1868 SuperClass->getName() + "`"); 1869 1870 // Get Kind and verify the enum name matches the name in `Attr.td`. 1871 unsigned Kind = LAPK->getValueAsInt(KindFieldStr); 1872 switch (LateAttrParseKind(Kind)) { 1873 #define CASE(X) \ 1874 case LateAttrParseKind::X: \ 1875 if (LAPK->getName().compare("LateAttrParse" #X) != 0) { \ 1876 PrintFatalError( \ 1877 Attr, \ 1878 "Field `" + Twine(LateParsedStr) + "` set to `" + LAPK->getName() + \ 1879 "` but this converts to `LateAttrParseKind::" + Twine(#X) + \ 1880 "`"); \ 1881 } \ 1882 return LateAttrParseKind::X; 1883 1884 CASE(Never) 1885 CASE(Standard) 1886 CASE(ExperimentalExt) 1887 #undef CASE 1888 } 1889 1890 // The Kind value is completely invalid 1891 auto KindValueStr = utostr(Kind); 1892 PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) + "` set to `" + 1893 LAPK->getName() + "` has unexpected `" + 1894 Twine(KindFieldStr) + "` value of " + KindValueStr); 1895 } 1896 1897 // Emits the LateParsed property for attributes. 1898 static void emitClangAttrLateParsedListImpl(const RecordKeeper &Records, 1899 raw_ostream &OS, 1900 LateAttrParseKind LateParseMode) { 1901 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 1902 if (LateAttrParseKind LateParsed = getLateAttrParseKind(Attr); 1903 LateParsed != LateParseMode) 1904 continue; 1905 1906 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr); 1907 1908 // FIXME: Handle non-GNU attributes 1909 for (const auto &I : Spellings) { 1910 if (I.variety() != "GNU") 1911 continue; 1912 OS << ".Case(\"" << I.name() << "\", 1)\n"; 1913 } 1914 } 1915 } 1916 1917 static void emitClangAttrLateParsedList(const RecordKeeper &Records, 1918 raw_ostream &OS) { 1919 OS << "#if defined(CLANG_ATTR_LATE_PARSED_LIST)\n"; 1920 emitClangAttrLateParsedListImpl(Records, OS, LateAttrParseKind::Standard); 1921 OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n"; 1922 } 1923 1924 static void emitClangAttrLateParsedExperimentalList(const RecordKeeper &Records, 1925 raw_ostream &OS) { 1926 OS << "#if defined(CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST)\n"; 1927 emitClangAttrLateParsedListImpl(Records, OS, 1928 LateAttrParseKind::ExperimentalExt); 1929 OS << "#endif // CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST\n\n"; 1930 } 1931 1932 static bool hasGNUorCXX11Spelling(const Record &Attribute) { 1933 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute); 1934 for (const auto &I : Spellings) { 1935 if (I.variety() == "GNU" || I.variety() == "CXX11") 1936 return true; 1937 } 1938 return false; 1939 } 1940 1941 namespace { 1942 1943 struct AttributeSubjectMatchRule { 1944 const Record *MetaSubject; 1945 const Record *Constraint; 1946 1947 AttributeSubjectMatchRule(const Record *MetaSubject, const Record *Constraint) 1948 : MetaSubject(MetaSubject), Constraint(Constraint) { 1949 assert(MetaSubject && "Missing subject"); 1950 } 1951 1952 bool isSubRule() const { return Constraint != nullptr; } 1953 1954 std::vector<const Record *> getSubjects() const { 1955 return (Constraint ? Constraint : MetaSubject) 1956 ->getValueAsListOfDefs("Subjects"); 1957 } 1958 1959 std::vector<const Record *> getLangOpts() const { 1960 if (Constraint) { 1961 // Lookup the options in the sub-rule first, in case the sub-rule 1962 // overrides the rules options. 1963 std::vector<const Record *> Opts = 1964 Constraint->getValueAsListOfDefs("LangOpts"); 1965 if (!Opts.empty()) 1966 return Opts; 1967 } 1968 return MetaSubject->getValueAsListOfDefs("LangOpts"); 1969 } 1970 1971 // Abstract rules are used only for sub-rules 1972 bool isAbstractRule() const { return getSubjects().empty(); } 1973 1974 StringRef getName() const { 1975 return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name"); 1976 } 1977 1978 bool isNegatedSubRule() const { 1979 assert(isSubRule() && "Not a sub-rule"); 1980 return Constraint->getValueAsBit("Negated"); 1981 } 1982 1983 std::string getSpelling() const { 1984 std::string Result = MetaSubject->getValueAsString("Name").str(); 1985 if (isSubRule()) { 1986 Result += '('; 1987 if (isNegatedSubRule()) 1988 Result += "unless("; 1989 Result += getName(); 1990 if (isNegatedSubRule()) 1991 Result += ')'; 1992 Result += ')'; 1993 } 1994 return Result; 1995 } 1996 1997 std::string getEnumValueName() const { 1998 SmallString<128> Result; 1999 Result += "SubjectMatchRule_"; 2000 Result += MetaSubject->getValueAsString("Name"); 2001 if (isSubRule()) { 2002 Result += "_"; 2003 if (isNegatedSubRule()) 2004 Result += "not_"; 2005 Result += Constraint->getValueAsString("Name"); 2006 } 2007 if (isAbstractRule()) 2008 Result += "_abstract"; 2009 return std::string(Result); 2010 } 2011 2012 std::string getEnumValue() const { return "attr::" + getEnumValueName(); } 2013 2014 static const char *EnumName; 2015 }; 2016 2017 const char *AttributeSubjectMatchRule::EnumName = "attr::SubjectMatchRule"; 2018 2019 struct PragmaClangAttributeSupport { 2020 std::vector<AttributeSubjectMatchRule> Rules; 2021 2022 class RuleOrAggregateRuleSet { 2023 std::vector<AttributeSubjectMatchRule> Rules; 2024 bool IsRule; 2025 RuleOrAggregateRuleSet(ArrayRef<AttributeSubjectMatchRule> Rules, 2026 bool IsRule) 2027 : Rules(Rules), IsRule(IsRule) {} 2028 2029 public: 2030 bool isRule() const { return IsRule; } 2031 2032 const AttributeSubjectMatchRule &getRule() const { 2033 assert(IsRule && "not a rule!"); 2034 return Rules[0]; 2035 } 2036 2037 ArrayRef<AttributeSubjectMatchRule> getAggregateRuleSet() const { 2038 return Rules; 2039 } 2040 2041 static RuleOrAggregateRuleSet 2042 getRule(const AttributeSubjectMatchRule &Rule) { 2043 return RuleOrAggregateRuleSet(Rule, /*IsRule=*/true); 2044 } 2045 static RuleOrAggregateRuleSet 2046 getAggregateRuleSet(ArrayRef<AttributeSubjectMatchRule> Rules) { 2047 return RuleOrAggregateRuleSet(Rules, /*IsRule=*/false); 2048 } 2049 }; 2050 DenseMap<const Record *, RuleOrAggregateRuleSet> SubjectsToRules; 2051 2052 PragmaClangAttributeSupport(const RecordKeeper &Records); 2053 2054 bool isAttributedSupported(const Record &Attribute); 2055 2056 void emitMatchRuleList(raw_ostream &OS); 2057 2058 void generateStrictConformsTo(const Record &Attr, raw_ostream &OS); 2059 2060 void generateParsingHelpers(raw_ostream &OS); 2061 }; 2062 2063 } // end anonymous namespace 2064 2065 static bool isSupportedPragmaClangAttributeSubject(const Record &Subject) { 2066 // FIXME: #pragma clang attribute does not currently support statement 2067 // attributes, so test whether the subject is one that appertains to a 2068 // declaration node. However, it may be reasonable for support for statement 2069 // attributes to be added. 2070 if (Subject.isSubClassOf("DeclNode") || Subject.isSubClassOf("DeclBase") || 2071 Subject.getName() == "DeclBase") 2072 return true; 2073 2074 if (Subject.isSubClassOf("SubsetSubject")) 2075 return isSupportedPragmaClangAttributeSubject( 2076 *Subject.getValueAsDef("Base")); 2077 2078 return false; 2079 } 2080 2081 static bool doesDeclDeriveFrom(const Record *D, const Record *Base) { 2082 const Record *CurrentBase = D->getValueAsOptionalDef(BaseFieldName); 2083 if (!CurrentBase) 2084 return false; 2085 if (CurrentBase == Base) 2086 return true; 2087 return doesDeclDeriveFrom(CurrentBase, Base); 2088 } 2089 2090 PragmaClangAttributeSupport::PragmaClangAttributeSupport( 2091 const RecordKeeper &Records) { 2092 auto MapFromSubjectsToRules = [this](const Record *SubjectContainer, 2093 const Record *MetaSubject, 2094 const Record *Constraint) { 2095 Rules.emplace_back(MetaSubject, Constraint); 2096 for (const Record *Subject : 2097 SubjectContainer->getValueAsListOfDefs("Subjects")) { 2098 bool Inserted = 2099 SubjectsToRules 2100 .try_emplace(Subject, RuleOrAggregateRuleSet::getRule( 2101 AttributeSubjectMatchRule(MetaSubject, 2102 Constraint))) 2103 .second; 2104 if (!Inserted) { 2105 PrintFatalError("Attribute subject match rules should not represent" 2106 "same attribute subjects."); 2107 } 2108 } 2109 }; 2110 for (const auto *MetaSubject : 2111 Records.getAllDerivedDefinitions("AttrSubjectMatcherRule")) { 2112 MapFromSubjectsToRules(MetaSubject, MetaSubject, /*Constraints=*/nullptr); 2113 for (const Record *Constraint : 2114 MetaSubject->getValueAsListOfDefs("Constraints")) 2115 MapFromSubjectsToRules(Constraint, MetaSubject, Constraint); 2116 } 2117 2118 ArrayRef<const Record *> DeclNodes = 2119 Records.getAllDerivedDefinitions(DeclNodeClassName); 2120 for (const auto *Aggregate : 2121 Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule")) { 2122 const Record *SubjectDecl = Aggregate->getValueAsDef("Subject"); 2123 2124 // Gather sub-classes of the aggregate subject that act as attribute 2125 // subject rules. 2126 std::vector<AttributeSubjectMatchRule> Rules; 2127 for (const auto *D : DeclNodes) { 2128 if (doesDeclDeriveFrom(D, SubjectDecl)) { 2129 auto It = SubjectsToRules.find(D); 2130 if (It == SubjectsToRules.end()) 2131 continue; 2132 if (!It->second.isRule() || It->second.getRule().isSubRule()) 2133 continue; // Assume that the rule will be included as well. 2134 Rules.push_back(It->second.getRule()); 2135 } 2136 } 2137 2138 bool Inserted = 2139 SubjectsToRules 2140 .try_emplace(SubjectDecl, 2141 RuleOrAggregateRuleSet::getAggregateRuleSet(Rules)) 2142 .second; 2143 if (!Inserted) { 2144 PrintFatalError("Attribute subject match rules should not represent" 2145 "same attribute subjects."); 2146 } 2147 } 2148 } 2149 2150 static PragmaClangAttributeSupport & 2151 getPragmaAttributeSupport(const RecordKeeper &Records) { 2152 static PragmaClangAttributeSupport Instance(Records); 2153 return Instance; 2154 } 2155 2156 void PragmaClangAttributeSupport::emitMatchRuleList(raw_ostream &OS) { 2157 OS << "#ifndef ATTR_MATCH_SUB_RULE\n"; 2158 OS << "#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, " 2159 "IsNegated) " 2160 << "ATTR_MATCH_RULE(Value, Spelling, IsAbstract)\n"; 2161 OS << "#endif\n"; 2162 for (const auto &Rule : Rules) { 2163 OS << (Rule.isSubRule() ? "ATTR_MATCH_SUB_RULE" : "ATTR_MATCH_RULE") << '('; 2164 OS << Rule.getEnumValueName() << ", \"" << Rule.getSpelling() << "\", " 2165 << Rule.isAbstractRule(); 2166 if (Rule.isSubRule()) 2167 OS << ", " 2168 << AttributeSubjectMatchRule(Rule.MetaSubject, nullptr).getEnumValue() 2169 << ", " << Rule.isNegatedSubRule(); 2170 OS << ")\n"; 2171 } 2172 OS << "#undef ATTR_MATCH_SUB_RULE\n"; 2173 } 2174 2175 bool PragmaClangAttributeSupport::isAttributedSupported( 2176 const Record &Attribute) { 2177 // If the attribute explicitly specified whether to support #pragma clang 2178 // attribute, use that setting. 2179 bool Unset; 2180 bool SpecifiedResult = 2181 Attribute.getValueAsBitOrUnset("PragmaAttributeSupport", Unset); 2182 if (!Unset) 2183 return SpecifiedResult; 2184 2185 // Opt-out rules: 2186 2187 // An attribute requires delayed parsing (LateParsed is on). 2188 switch (getLateAttrParseKind(&Attribute)) { 2189 case LateAttrParseKind::Never: 2190 break; 2191 case LateAttrParseKind::Standard: 2192 return false; 2193 case LateAttrParseKind::ExperimentalExt: 2194 // This is only late parsed in certain parsing contexts when 2195 // `LangOpts.ExperimentalLateParseAttributes` is true. Information about the 2196 // parsing context and `LangOpts` is not available in this method so just 2197 // opt this attribute out. 2198 return false; 2199 } 2200 2201 // An attribute has no GNU/CXX11 spelling 2202 if (!hasGNUorCXX11Spelling(Attribute)) 2203 return false; 2204 // An attribute subject list has a subject that isn't covered by one of the 2205 // subject match rules or has no subjects at all. 2206 if (Attribute.isValueUnset("Subjects")) 2207 return false; 2208 const Record *SubjectObj = Attribute.getValueAsDef("Subjects"); 2209 bool HasAtLeastOneValidSubject = false; 2210 for (const auto *Subject : SubjectObj->getValueAsListOfDefs("Subjects")) { 2211 if (!isSupportedPragmaClangAttributeSubject(*Subject)) 2212 continue; 2213 if (!SubjectsToRules.contains(Subject)) 2214 return false; 2215 HasAtLeastOneValidSubject = true; 2216 } 2217 return HasAtLeastOneValidSubject; 2218 } 2219 2220 static std::string GenerateTestExpression(ArrayRef<const Record *> LangOpts) { 2221 std::string Test; 2222 2223 for (auto *E : LangOpts) { 2224 if (!Test.empty()) 2225 Test += " || "; 2226 2227 const StringRef Code = E->getValueAsString("CustomCode"); 2228 if (!Code.empty()) { 2229 Test += "("; 2230 Test += Code; 2231 Test += ")"; 2232 if (!E->getValueAsString("Name").empty()) { 2233 PrintWarning( 2234 E->getLoc(), 2235 "non-empty 'Name' field ignored because 'CustomCode' was supplied"); 2236 } 2237 } else { 2238 Test += "LangOpts."; 2239 Test += E->getValueAsString("Name"); 2240 } 2241 } 2242 2243 if (Test.empty()) 2244 return "true"; 2245 2246 return Test; 2247 } 2248 2249 void 2250 PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr, 2251 raw_ostream &OS) { 2252 if (!isAttributedSupported(Attr) || Attr.isValueUnset("Subjects")) 2253 return; 2254 // Generate a function that constructs a set of matching rules that describe 2255 // to which declarations the attribute should apply to. 2256 OS << "void getPragmaAttributeMatchRules(" 2257 << "llvm::SmallVectorImpl<std::pair<" 2258 << AttributeSubjectMatchRule::EnumName 2259 << ", bool>> &MatchRules, const LangOptions &LangOpts) const override {\n"; 2260 const Record *SubjectObj = Attr.getValueAsDef("Subjects"); 2261 for (const auto *Subject : SubjectObj->getValueAsListOfDefs("Subjects")) { 2262 if (!isSupportedPragmaClangAttributeSubject(*Subject)) 2263 continue; 2264 auto It = SubjectsToRules.find(Subject); 2265 assert(It != SubjectsToRules.end() && 2266 "This attribute is unsupported by #pragma clang attribute"); 2267 for (const auto &Rule : It->getSecond().getAggregateRuleSet()) { 2268 // The rule might be language specific, so only subtract it from the given 2269 // rules if the specific language options are specified. 2270 std::vector<const Record *> LangOpts = Rule.getLangOpts(); 2271 OS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() 2272 << ", /*IsSupported=*/" << GenerateTestExpression(LangOpts) 2273 << "));\n"; 2274 } 2275 } 2276 OS << "}\n\n"; 2277 } 2278 2279 void PragmaClangAttributeSupport::generateParsingHelpers(raw_ostream &OS) { 2280 // Generate routines that check the names of sub-rules. 2281 OS << "std::optional<attr::SubjectMatchRule> " 2282 "defaultIsAttributeSubjectMatchSubRuleFor(StringRef, bool) {\n"; 2283 OS << " return std::nullopt;\n"; 2284 OS << "}\n\n"; 2285 2286 MapVector<const Record *, std::vector<AttributeSubjectMatchRule>> 2287 SubMatchRules; 2288 for (const auto &Rule : Rules) { 2289 if (!Rule.isSubRule()) 2290 continue; 2291 SubMatchRules[Rule.MetaSubject].push_back(Rule); 2292 } 2293 2294 for (const auto &SubMatchRule : SubMatchRules) { 2295 OS << "std::optional<attr::SubjectMatchRule> " 2296 "isAttributeSubjectMatchSubRuleFor_" 2297 << SubMatchRule.first->getValueAsString("Name") 2298 << "(StringRef Name, bool IsUnless) {\n"; 2299 OS << " if (IsUnless)\n"; 2300 OS << " return " 2301 "llvm::StringSwitch<std::optional<attr::SubjectMatchRule>>(Name).\n"; 2302 for (const auto &Rule : SubMatchRule.second) { 2303 if (Rule.isNegatedSubRule()) 2304 OS << " Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue() 2305 << ").\n"; 2306 } 2307 OS << " Default(std::nullopt);\n"; 2308 OS << " return " 2309 "llvm::StringSwitch<std::optional<attr::SubjectMatchRule>>(Name).\n"; 2310 for (const auto &Rule : SubMatchRule.second) { 2311 if (!Rule.isNegatedSubRule()) 2312 OS << " Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue() 2313 << ").\n"; 2314 } 2315 OS << " Default(std::nullopt);\n"; 2316 OS << "}\n\n"; 2317 } 2318 2319 // Generate the function that checks for the top-level rules. 2320 OS << "std::pair<std::optional<attr::SubjectMatchRule>, " 2321 "std::optional<attr::SubjectMatchRule> (*)(StringRef, " 2322 "bool)> isAttributeSubjectMatchRule(StringRef Name) {\n"; 2323 OS << " return " 2324 "llvm::StringSwitch<std::pair<std::optional<attr::SubjectMatchRule>, " 2325 "std::optional<attr::SubjectMatchRule> (*) (StringRef, " 2326 "bool)>>(Name).\n"; 2327 for (const auto &Rule : Rules) { 2328 if (Rule.isSubRule()) 2329 continue; 2330 std::string SubRuleFunction; 2331 if (SubMatchRules.count(Rule.MetaSubject)) 2332 SubRuleFunction = 2333 ("isAttributeSubjectMatchSubRuleFor_" + Rule.getName()).str(); 2334 else 2335 SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor"; 2336 OS << " Case(\"" << Rule.getName() << "\", std::make_pair(" 2337 << Rule.getEnumValue() << ", " << SubRuleFunction << ")).\n"; 2338 } 2339 OS << " Default(std::make_pair(std::nullopt, " 2340 "defaultIsAttributeSubjectMatchSubRuleFor));\n"; 2341 OS << "}\n\n"; 2342 2343 // Generate the function that checks for the submatch rules. 2344 OS << "const char *validAttributeSubjectMatchSubRules(" 2345 << AttributeSubjectMatchRule::EnumName << " Rule) {\n"; 2346 OS << " switch (Rule) {\n"; 2347 for (const auto &SubMatchRule : SubMatchRules) { 2348 OS << " case " 2349 << AttributeSubjectMatchRule(SubMatchRule.first, nullptr).getEnumValue() 2350 << ":\n"; 2351 OS << " return \"'"; 2352 bool IsFirst = true; 2353 for (const auto &Rule : SubMatchRule.second) { 2354 if (!IsFirst) 2355 OS << ", '"; 2356 IsFirst = false; 2357 if (Rule.isNegatedSubRule()) 2358 OS << "unless("; 2359 OS << Rule.getName(); 2360 if (Rule.isNegatedSubRule()) 2361 OS << ')'; 2362 OS << "'"; 2363 } 2364 OS << "\";\n"; 2365 } 2366 OS << " default: return nullptr;\n"; 2367 OS << " }\n"; 2368 OS << "}\n\n"; 2369 } 2370 2371 template <typename Fn> static void forEachSpelling(const Record &Attr, Fn &&F) { 2372 for (const FlattenedSpelling &S : GetFlattenedSpellings(Attr)) { 2373 F(S); 2374 } 2375 } 2376 2377 static std::map<StringRef, std::vector<const Record *>> NameToAttrsMap; 2378 2379 /// Build a map from the attribute name to the Attrs that use that name. If more 2380 /// than one Attr use a name, the arguments could be different so a more complex 2381 /// check is needed in the generated switch. 2382 static void generateNameToAttrsMap(const RecordKeeper &Records) { 2383 for (const auto *A : Records.getAllDerivedDefinitions("Attr")) { 2384 for (const FlattenedSpelling &S : GetFlattenedSpellings(*A)) { 2385 auto [It, Inserted] = NameToAttrsMap.try_emplace(S.name()); 2386 if (Inserted || !is_contained(It->second, A)) 2387 It->second.emplace_back(A); 2388 } 2389 } 2390 } 2391 2392 /// Generate the info needed to produce the case values in case more than one 2393 /// attribute has the same name. Store the info in a map that can be processed 2394 /// after all attributes are seen. 2395 static void generateFlattenedSpellingInfo(const Record &Attr, 2396 std::map<StringRef, FSIVecTy> &Map, 2397 uint32_t ArgMask = 0) { 2398 std::string TargetTest; 2399 if (Attr.isSubClassOf("TargetSpecificAttr") && 2400 !Attr.isValueUnset("ParseKind")) { 2401 const Record *T = Attr.getValueAsDef("Target"); 2402 std::vector<StringRef> Arches = T->getValueAsListOfStrings("Arches"); 2403 (void)GenerateTargetSpecificAttrChecks(T, Arches, TargetTest, nullptr); 2404 } 2405 2406 forEachSpelling(Attr, [&](const FlattenedSpelling &S) { 2407 Map[S.name()].emplace_back(S.variety(), S.nameSpace(), TargetTest, ArgMask); 2408 }); 2409 } 2410 2411 static bool nameAppliesToOneAttribute(StringRef Name) { 2412 auto It = NameToAttrsMap.find(Name); 2413 assert(It != NameToAttrsMap.end()); 2414 return It->second.size() == 1; 2415 } 2416 2417 static bool emitIfSimpleValue(StringRef Name, uint32_t ArgMask, 2418 raw_ostream &OS) { 2419 if (nameAppliesToOneAttribute(Name)) { 2420 OS << ".Case(\"" << Name << "\", "; 2421 if (ArgMask != 0) 2422 OS << ArgMask << ")\n"; 2423 else 2424 OS << "true)\n"; 2425 return true; 2426 } 2427 return false; 2428 } 2429 2430 static void emitSingleCondition(const FlattenedSpellingInfo &FSI, 2431 raw_ostream &OS) { 2432 OS << "(Syntax==AttributeCommonInfo::AS_" << FSI.Syntax << " && "; 2433 if (!FSI.Scope.empty()) 2434 OS << "ScopeName && ScopeName->getName()==\"" << FSI.Scope << "\""; 2435 else 2436 OS << "!ScopeName"; 2437 if (!FSI.TargetTest.empty()) 2438 OS << " && " << FSI.TargetTest; 2439 OS << ")"; 2440 } 2441 2442 static void emitStringSwitchCases(std::map<StringRef, FSIVecTy> &Map, 2443 raw_ostream &OS) { 2444 for (const auto &[Name, Vec] : Map) { 2445 if (emitIfSimpleValue(Name, Vec[0].ArgMask, OS)) 2446 continue; 2447 2448 // Not simple, build expressions for each case. 2449 OS << ".Case(\"" << Name << "\", "; 2450 for (unsigned I = 0, E = Vec.size(); I < E; ++I) { 2451 emitSingleCondition(Vec[I], OS); 2452 uint32_t ArgMask = Vec[I].ArgMask; 2453 if (E == 1 && ArgMask == 0) 2454 continue; 2455 2456 // More than one or it's the Mask form. Create a conditional expression. 2457 uint32_t SuccessValue = ArgMask != 0 ? ArgMask : 1; 2458 OS << " ? " << SuccessValue << " : "; 2459 if (I == E - 1) 2460 OS << 0; 2461 } 2462 OS << ")\n"; 2463 } 2464 } 2465 2466 static bool isTypeArgument(const Record *Arg) { 2467 return !Arg->getDirectSuperClasses().empty() && 2468 Arg->getDirectSuperClasses().back().first->getName() == "TypeArgument"; 2469 } 2470 2471 /// Emits the first-argument-is-type property for attributes. 2472 static void emitClangAttrTypeArgList(const RecordKeeper &Records, 2473 raw_ostream &OS) { 2474 OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\n"; 2475 std::map<StringRef, FSIVecTy> FSIMap; 2476 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 2477 // Determine whether the first argument is a type. 2478 std::vector<const Record *> Args = Attr->getValueAsListOfDefs("Args"); 2479 if (Args.empty()) 2480 continue; 2481 2482 if (!isTypeArgument(Args[0])) 2483 continue; 2484 generateFlattenedSpellingInfo(*Attr, FSIMap); 2485 } 2486 emitStringSwitchCases(FSIMap, OS); 2487 OS << "#endif // CLANG_ATTR_TYPE_ARG_LIST\n\n"; 2488 } 2489 2490 /// Emits the parse-arguments-in-unevaluated-context property for 2491 /// attributes. 2492 static void emitClangAttrArgContextList(const RecordKeeper &Records, 2493 raw_ostream &OS) { 2494 OS << "#if defined(CLANG_ATTR_ARG_CONTEXT_LIST)\n"; 2495 std::map<StringRef, FSIVecTy> FSIMap; 2496 ParsedAttrMap Attrs = getParsedAttrList(Records); 2497 for (const auto &I : Attrs) { 2498 const Record &Attr = *I.second; 2499 2500 if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated")) 2501 continue; 2502 generateFlattenedSpellingInfo(Attr, FSIMap); 2503 } 2504 emitStringSwitchCases(FSIMap, OS); 2505 OS << "#endif // CLANG_ATTR_ARG_CONTEXT_LIST\n\n"; 2506 } 2507 2508 static bool isIdentifierArgument(const Record *Arg) { 2509 return !Arg->getDirectSuperClasses().empty() && 2510 StringSwitch<bool>( 2511 Arg->getDirectSuperClasses().back().first->getName()) 2512 .Case("IdentifierArgument", true) 2513 .Case("EnumArgument", true) 2514 .Case("VariadicEnumArgument", true) 2515 .Default(false); 2516 } 2517 2518 static bool isVariadicIdentifierArgument(const Record *Arg) { 2519 return !Arg->getDirectSuperClasses().empty() && 2520 StringSwitch<bool>( 2521 Arg->getDirectSuperClasses().back().first->getName()) 2522 .Case("VariadicIdentifierArgument", true) 2523 .Case("VariadicParamOrParamIdxArgument", true) 2524 .Default(false); 2525 } 2526 2527 static bool isVariadicExprArgument(const Record *Arg) { 2528 return !Arg->getDirectSuperClasses().empty() && 2529 StringSwitch<bool>( 2530 Arg->getDirectSuperClasses().back().first->getName()) 2531 .Case("VariadicExprArgument", true) 2532 .Default(false); 2533 } 2534 2535 static bool isStringLiteralArgument(const Record *Arg) { 2536 if (Arg->getDirectSuperClasses().empty()) 2537 return false; 2538 StringRef ArgKind = Arg->getDirectSuperClasses().back().first->getName(); 2539 if (ArgKind == "EnumArgument") 2540 return Arg->getValueAsBit("IsString"); 2541 return ArgKind == "StringArgument"; 2542 } 2543 2544 static bool isVariadicStringLiteralArgument(const Record *Arg) { 2545 if (Arg->getDirectSuperClasses().empty()) 2546 return false; 2547 StringRef ArgKind = Arg->getDirectSuperClasses().back().first->getName(); 2548 if (ArgKind == "VariadicEnumArgument") 2549 return Arg->getValueAsBit("IsString"); 2550 return ArgKind == "VariadicStringArgument"; 2551 } 2552 2553 static void emitClangAttrVariadicIdentifierArgList(const RecordKeeper &Records, 2554 raw_ostream &OS) { 2555 OS << "#if defined(CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST)\n"; 2556 std::map<StringRef, FSIVecTy> FSIMap; 2557 for (const auto *A : Records.getAllDerivedDefinitions("Attr")) { 2558 // Determine whether the first argument is a variadic identifier. 2559 std::vector<const Record *> Args = A->getValueAsListOfDefs("Args"); 2560 if (Args.empty() || !isVariadicIdentifierArgument(Args[0])) 2561 continue; 2562 generateFlattenedSpellingInfo(*A, FSIMap); 2563 } 2564 emitStringSwitchCases(FSIMap, OS); 2565 OS << "#endif // CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST\n\n"; 2566 } 2567 2568 // Emits the list of arguments that should be parsed as unevaluated string 2569 // literals for each attribute. 2570 static void 2571 emitClangAttrUnevaluatedStringLiteralList(const RecordKeeper &Records, 2572 raw_ostream &OS) { 2573 OS << "#if defined(CLANG_ATTR_STRING_LITERAL_ARG_LIST)\n"; 2574 2575 auto MakeMask = [](ArrayRef<const Record *> Args) { 2576 uint32_t Bits = 0; 2577 assert(Args.size() <= 32 && "unsupported number of arguments in attribute"); 2578 for (uint32_t N = 0; N < Args.size(); ++N) { 2579 Bits |= (isStringLiteralArgument(Args[N]) << N); 2580 // If we have a variadic string argument, set all the remaining bits to 1 2581 if (isVariadicStringLiteralArgument(Args[N])) { 2582 Bits |= maskTrailingZeros<decltype(Bits)>(N); 2583 break; 2584 } 2585 } 2586 return Bits; 2587 }; 2588 2589 std::map<StringRef, FSIVecTy> FSIMap; 2590 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 2591 // Determine whether there are any string arguments. 2592 uint32_t ArgMask = MakeMask(Attr->getValueAsListOfDefs("Args")); 2593 if (!ArgMask) 2594 continue; 2595 generateFlattenedSpellingInfo(*Attr, FSIMap, ArgMask); 2596 } 2597 emitStringSwitchCases(FSIMap, OS); 2598 OS << "#endif // CLANG_ATTR_STRING_LITERAL_ARG_LIST\n\n"; 2599 } 2600 2601 // Emits the first-argument-is-identifier property for attributes. 2602 static void emitClangAttrIdentifierArgList(const RecordKeeper &Records, 2603 raw_ostream &OS) { 2604 OS << "#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)\n"; 2605 std::map<StringRef, FSIVecTy> FSIMap; 2606 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 2607 // Determine whether the first argument is an identifier. 2608 std::vector<const Record *> Args = Attr->getValueAsListOfDefs("Args"); 2609 if (Args.empty() || !isIdentifierArgument(Args[0])) 2610 continue; 2611 generateFlattenedSpellingInfo(*Attr, FSIMap); 2612 } 2613 emitStringSwitchCases(FSIMap, OS); 2614 OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n"; 2615 } 2616 2617 // Emits the list for attributes having StrictEnumParameters. 2618 static void emitClangAttrStrictIdentifierArgList(const RecordKeeper &Records, 2619 raw_ostream &OS) { 2620 OS << "#if defined(CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST)\n"; 2621 std::map<StringRef, FSIVecTy> FSIMap; 2622 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 2623 if (!Attr->getValueAsBit("StrictEnumParameters")) 2624 continue; 2625 // Check that there is really an identifier argument. 2626 std::vector<const Record *> Args = Attr->getValueAsListOfDefs("Args"); 2627 if (none_of(Args, [&](const Record *R) { return isIdentifierArgument(R); })) 2628 continue; 2629 generateFlattenedSpellingInfo(*Attr, FSIMap); 2630 } 2631 emitStringSwitchCases(FSIMap, OS); 2632 OS << "#endif // CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST\n\n"; 2633 } 2634 2635 static bool keywordThisIsaIdentifierInArgument(const Record *Arg) { 2636 return !Arg->getDirectSuperClasses().empty() && 2637 StringSwitch<bool>( 2638 Arg->getDirectSuperClasses().back().first->getName()) 2639 .Case("VariadicParamOrParamIdxArgument", true) 2640 .Default(false); 2641 } 2642 2643 static void emitClangAttrThisIsaIdentifierArgList(const RecordKeeper &Records, 2644 raw_ostream &OS) { 2645 OS << "#if defined(CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST)\n"; 2646 std::map<StringRef, FSIVecTy> FSIMap; 2647 for (const auto *A : Records.getAllDerivedDefinitions("Attr")) { 2648 // Determine whether the first argument is a variadic identifier. 2649 std::vector<const Record *> Args = A->getValueAsListOfDefs("Args"); 2650 if (Args.empty() || !keywordThisIsaIdentifierInArgument(Args[0])) 2651 continue; 2652 generateFlattenedSpellingInfo(*A, FSIMap); 2653 } 2654 emitStringSwitchCases(FSIMap, OS); 2655 OS << "#endif // CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST\n\n"; 2656 } 2657 2658 static void emitClangAttrAcceptsExprPack(const RecordKeeper &Records, 2659 raw_ostream &OS) { 2660 OS << "#if defined(CLANG_ATTR_ACCEPTS_EXPR_PACK)\n"; 2661 ParsedAttrMap Attrs = getParsedAttrList(Records); 2662 std::map<StringRef, FSIVecTy> FSIMap; 2663 for (const auto &I : Attrs) { 2664 const Record &Attr = *I.second; 2665 2666 if (!Attr.getValueAsBit("AcceptsExprPack")) 2667 continue; 2668 generateFlattenedSpellingInfo(Attr, FSIMap); 2669 } 2670 emitStringSwitchCases(FSIMap, OS); 2671 OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n"; 2672 } 2673 2674 static bool isRegularKeywordAttribute(const FlattenedSpelling &S) { 2675 return (S.variety() == "Keyword" && 2676 !S.getSpellingRecord().getValueAsBit("HasOwnParseRules")); 2677 } 2678 2679 static void emitFormInitializer(raw_ostream &OS, 2680 const FlattenedSpelling &Spelling, 2681 StringRef SpellingIndex) { 2682 bool IsAlignas = 2683 (Spelling.variety() == "Keyword" && Spelling.name() == "alignas"); 2684 OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", " 2685 << SpellingIndex << ", " << (IsAlignas ? "true" : "false") 2686 << " /*IsAlignas*/, " 2687 << (isRegularKeywordAttribute(Spelling) ? "true" : "false") 2688 << " /*IsRegularKeywordAttribute*/}"; 2689 } 2690 2691 static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS, 2692 bool Header) { 2693 ParsedAttrMap AttrMap = getParsedAttrList(Records); 2694 2695 // Helper to print the starting character of an attribute argument. If there 2696 // hasn't been an argument yet, it prints an opening parenthese; otherwise it 2697 // prints a comma. 2698 OS << "static inline void DelimitAttributeArgument(" 2699 << "raw_ostream& OS, bool& IsFirst) {\n" 2700 << " if (IsFirst) {\n" 2701 << " IsFirst = false;\n" 2702 << " OS << \"(\";\n" 2703 << " } else\n" 2704 << " OS << \", \";\n" 2705 << "}\n"; 2706 2707 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 2708 const Record &R = *Attr; 2709 2710 // FIXME: Currently, documentation is generated as-needed due to the fact 2711 // that there is no way to allow a generated project "reach into" the docs 2712 // directory (for instance, it may be an out-of-tree build). However, we want 2713 // to ensure that every attribute has a Documentation field, and produce an 2714 // error if it has been neglected. Otherwise, the on-demand generation which 2715 // happens server-side will fail. This code is ensuring that functionality, 2716 // even though this Emitter doesn't technically need the documentation. 2717 // When attribute documentation can be generated as part of the build 2718 // itself, this code can be removed. 2719 (void)R.getValueAsListOfDefs("Documentation"); 2720 2721 if (!R.getValueAsBit("ASTNode")) 2722 continue; 2723 2724 std::vector<const Record *> Supers = R.getSuperClasses(); 2725 assert(!Supers.empty() && "Forgot to specify a superclass for the attr"); 2726 std::string SuperName; 2727 bool Inheritable = false; 2728 for (const Record *R : reverse(Supers)) { 2729 if (R->getName() != "TargetSpecificAttr" && 2730 R->getName() != "DeclOrTypeAttr" && SuperName.empty()) 2731 SuperName = R->getName().str(); 2732 if (R->getName() == "InheritableAttr") 2733 Inheritable = true; 2734 } 2735 2736 if (Header) 2737 OS << "class CLANG_ABI " << R.getName() << "Attr : public " << SuperName 2738 << " {\n"; 2739 else 2740 OS << "\n// " << R.getName() << "Attr implementation\n\n"; 2741 2742 std::vector<const Record *> ArgRecords = R.getValueAsListOfDefs("Args"); 2743 std::vector<std::unique_ptr<Argument>> Args; 2744 Args.reserve(ArgRecords.size()); 2745 2746 bool AttrAcceptsExprPack = Attr->getValueAsBit("AcceptsExprPack"); 2747 if (AttrAcceptsExprPack) { 2748 for (size_t I = 0; I < ArgRecords.size(); ++I) { 2749 const Record *ArgR = ArgRecords[I]; 2750 if (isIdentifierArgument(ArgR) || isVariadicIdentifierArgument(ArgR) || 2751 isTypeArgument(ArgR)) 2752 PrintFatalError(Attr->getLoc(), 2753 "Attributes accepting packs cannot also " 2754 "have identifier or type arguments."); 2755 // When trying to determine if value-dependent expressions can populate 2756 // the attribute without prior instantiation, the decision is made based 2757 // on the assumption that only the last argument is ever variadic. 2758 if (I < (ArgRecords.size() - 1) && isVariadicExprArgument(ArgR)) 2759 PrintFatalError(Attr->getLoc(), 2760 "Attributes accepting packs can only have the last " 2761 "argument be variadic."); 2762 } 2763 } 2764 2765 bool HasOptArg = false; 2766 bool HasFakeArg = false; 2767 for (const auto *ArgRecord : ArgRecords) { 2768 Args.emplace_back(createArgument(*ArgRecord, R.getName())); 2769 if (Header) { 2770 Args.back()->writeDeclarations(OS); 2771 OS << "\n\n"; 2772 } 2773 2774 // For these purposes, fake takes priority over optional. 2775 if (Args.back()->isFake()) { 2776 HasFakeArg = true; 2777 } else if (Args.back()->isOptional()) { 2778 HasOptArg = true; 2779 } 2780 } 2781 2782 std::unique_ptr<VariadicExprArgument> DelayedArgs = nullptr; 2783 if (AttrAcceptsExprPack) { 2784 DelayedArgs = 2785 std::make_unique<VariadicExprArgument>("DelayedArgs", R.getName()); 2786 if (Header) { 2787 DelayedArgs->writeDeclarations(OS); 2788 OS << "\n\n"; 2789 } 2790 } 2791 2792 if (Header) 2793 OS << "public:\n"; 2794 2795 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R); 2796 2797 // If there are zero or one spellings, all spelling-related functionality 2798 // can be elided. If all of the spellings share the same name, the spelling 2799 // functionality can also be elided. 2800 bool ElideSpelling = (Spellings.size() <= 1) || 2801 SpellingNamesAreCommon(Spellings); 2802 2803 // This maps spelling index values to semantic Spelling enumerants. 2804 SemanticSpellingMap SemanticToSyntacticMap; 2805 2806 std::string SpellingEnum; 2807 if (Spellings.size() > 1) 2808 SpellingEnum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap); 2809 if (Header) 2810 OS << SpellingEnum; 2811 2812 const auto &ParsedAttrSpellingItr = 2813 find_if(AttrMap, [R](const std::pair<std::string, const Record *> &P) { 2814 return &R == P.second; 2815 }); 2816 2817 // Emit CreateImplicit factory methods. 2818 auto emitCreate = [&](bool Implicit, bool DelayedArgsOnly, bool emitFake) { 2819 if (Header) 2820 OS << " static "; 2821 OS << R.getName() << "Attr *"; 2822 if (!Header) 2823 OS << R.getName() << "Attr::"; 2824 OS << "Create"; 2825 if (Implicit) 2826 OS << "Implicit"; 2827 if (DelayedArgsOnly) 2828 OS << "WithDelayedArgs"; 2829 OS << "("; 2830 OS << "ASTContext &Ctx"; 2831 if (!DelayedArgsOnly) { 2832 for (auto const &ai : Args) { 2833 if (ai->isFake() && !emitFake) 2834 continue; 2835 OS << ", "; 2836 ai->writeCtorParameters(OS); 2837 } 2838 } else { 2839 OS << ", "; 2840 DelayedArgs->writeCtorParameters(OS); 2841 } 2842 OS << ", const AttributeCommonInfo &CommonInfo"; 2843 OS << ")"; 2844 if (Header) { 2845 OS << ";\n"; 2846 return; 2847 } 2848 2849 OS << " {\n"; 2850 OS << " auto *A = new (Ctx) " << R.getName(); 2851 OS << "Attr(Ctx, CommonInfo"; 2852 2853 if (!DelayedArgsOnly) { 2854 for (auto const &ai : Args) { 2855 if (ai->isFake() && !emitFake) 2856 continue; 2857 OS << ", "; 2858 ai->writeImplicitCtorArgs(OS); 2859 } 2860 } 2861 OS << ");\n"; 2862 if (Implicit) { 2863 OS << " A->setImplicit(true);\n"; 2864 } 2865 if (Implicit || ElideSpelling) { 2866 OS << " if (!A->isAttributeSpellingListCalculated() && " 2867 "!A->getAttrName())\n"; 2868 OS << " A->setAttributeSpellingListIndex(0);\n"; 2869 } 2870 if (DelayedArgsOnly) { 2871 OS << " A->setDelayedArgs(Ctx, "; 2872 DelayedArgs->writeImplicitCtorArgs(OS); 2873 OS << ");\n"; 2874 } 2875 OS << " return A;\n}\n\n"; 2876 }; 2877 2878 auto emitCreateNoCI = [&](bool Implicit, bool DelayedArgsOnly, 2879 bool emitFake) { 2880 if (Header) 2881 OS << " static "; 2882 OS << R.getName() << "Attr *"; 2883 if (!Header) 2884 OS << R.getName() << "Attr::"; 2885 OS << "Create"; 2886 if (Implicit) 2887 OS << "Implicit"; 2888 if (DelayedArgsOnly) 2889 OS << "WithDelayedArgs"; 2890 OS << "("; 2891 OS << "ASTContext &Ctx"; 2892 if (!DelayedArgsOnly) { 2893 for (auto const &ai : Args) { 2894 if (ai->isFake() && !emitFake) 2895 continue; 2896 OS << ", "; 2897 ai->writeCtorParameters(OS); 2898 } 2899 } else { 2900 OS << ", "; 2901 DelayedArgs->writeCtorParameters(OS); 2902 } 2903 OS << ", SourceRange Range"; 2904 if (Header) 2905 OS << " = {}"; 2906 if (Spellings.size() > 1) { 2907 OS << ", Spelling S"; 2908 if (Header) 2909 OS << " = " << SemanticToSyntacticMap[0]; 2910 } 2911 OS << ")"; 2912 if (Header) { 2913 OS << ";\n"; 2914 return; 2915 } 2916 2917 OS << " {\n"; 2918 OS << " AttributeCommonInfo I(Range, "; 2919 2920 if (ParsedAttrSpellingItr != std::end(AttrMap)) 2921 OS << "AT_" << ParsedAttrSpellingItr->first; 2922 else 2923 OS << "NoSemaHandlerAttribute"; 2924 2925 if (Spellings.size() == 0) { 2926 OS << ", AttributeCommonInfo::Form::Implicit()"; 2927 } else if (Spellings.size() == 1) { 2928 OS << ", "; 2929 emitFormInitializer(OS, Spellings[0], "0"); 2930 } else { 2931 OS << ", [&]() {\n"; 2932 OS << " switch (S) {\n"; 2933 std::set<std::string> Uniques; 2934 unsigned Idx = 0; 2935 for (auto I = Spellings.begin(), E = Spellings.end(); I != E; 2936 ++I, ++Idx) { 2937 const FlattenedSpelling &S = *I; 2938 const auto &Name = SemanticToSyntacticMap[Idx]; 2939 if (Uniques.insert(Name).second) { 2940 OS << " case " << Name << ":\n"; 2941 OS << " return AttributeCommonInfo::Form"; 2942 emitFormInitializer(OS, S, Name); 2943 OS << ";\n"; 2944 } 2945 } 2946 OS << " default:\n"; 2947 OS << " llvm_unreachable(\"Unknown attribute spelling!\");\n" 2948 << " return AttributeCommonInfo::Form"; 2949 emitFormInitializer(OS, Spellings[0], "0"); 2950 OS << ";\n" 2951 << " }\n" 2952 << " }()"; 2953 } 2954 2955 OS << ");\n"; 2956 OS << " return Create"; 2957 if (Implicit) 2958 OS << "Implicit"; 2959 if (DelayedArgsOnly) 2960 OS << "WithDelayedArgs"; 2961 OS << "(Ctx"; 2962 if (!DelayedArgsOnly) { 2963 for (auto const &ai : Args) { 2964 if (ai->isFake() && !emitFake) 2965 continue; 2966 OS << ", "; 2967 ai->writeImplicitCtorArgs(OS); 2968 } 2969 } else { 2970 OS << ", "; 2971 DelayedArgs->writeImplicitCtorArgs(OS); 2972 } 2973 OS << ", I);\n"; 2974 OS << "}\n\n"; 2975 }; 2976 2977 auto emitCreates = [&](bool DelayedArgsOnly, bool emitFake) { 2978 emitCreate(true, DelayedArgsOnly, emitFake); 2979 emitCreate(false, DelayedArgsOnly, emitFake); 2980 emitCreateNoCI(true, DelayedArgsOnly, emitFake); 2981 emitCreateNoCI(false, DelayedArgsOnly, emitFake); 2982 }; 2983 2984 if (Header) 2985 OS << " // Factory methods\n"; 2986 2987 // Emit a CreateImplicit that takes all the arguments. 2988 emitCreates(false, true); 2989 2990 // Emit a CreateImplicit that takes all the non-fake arguments. 2991 if (HasFakeArg) 2992 emitCreates(false, false); 2993 2994 // Emit a CreateWithDelayedArgs that takes only the dependent argument 2995 // expressions. 2996 if (DelayedArgs) 2997 emitCreates(true, false); 2998 2999 // Emit constructors. 3000 auto emitCtor = [&](bool emitOpt, bool emitFake, bool emitNoArgs) { 3001 auto shouldEmitArg = [=](const std::unique_ptr<Argument> &arg) { 3002 if (emitNoArgs) 3003 return false; 3004 if (arg->isFake()) 3005 return emitFake; 3006 if (arg->isOptional()) 3007 return emitOpt; 3008 return true; 3009 }; 3010 if (Header) 3011 OS << " "; 3012 else 3013 OS << R.getName() << "Attr::"; 3014 OS << R.getName() 3015 << "Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo"; 3016 OS << '\n'; 3017 for (auto const &ai : Args) { 3018 if (!shouldEmitArg(ai)) 3019 continue; 3020 OS << " , "; 3021 ai->writeCtorParameters(OS); 3022 OS << "\n"; 3023 } 3024 3025 OS << " )"; 3026 if (Header) { 3027 OS << ";\n"; 3028 return; 3029 } 3030 OS << "\n : " << SuperName << "(Ctx, CommonInfo, "; 3031 OS << "attr::" << R.getName() << ", "; 3032 3033 // Handle different late parsing modes. 3034 OS << "/*IsLateParsed=*/"; 3035 switch (getLateAttrParseKind(&R)) { 3036 case LateAttrParseKind::Never: 3037 OS << "false"; 3038 break; 3039 case LateAttrParseKind::ExperimentalExt: 3040 // Currently no clients need to know the distinction between `Standard` 3041 // and `ExperimentalExt` so treat `ExperimentalExt` just like 3042 // `Standard` for now. 3043 case LateAttrParseKind::Standard: 3044 // Note: This is misleading. `IsLateParsed` doesn't mean the 3045 // attribute was actually late parsed. Instead it means the attribute in 3046 // `Attr.td` is marked as being late parsed. Maybe it should be called 3047 // `IsLateParseable`? 3048 OS << "true"; 3049 break; 3050 } 3051 3052 if (Inheritable) { 3053 OS << ", " 3054 << (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true" 3055 : "false"); 3056 } 3057 OS << ")\n"; 3058 3059 for (auto const &ai : Args) { 3060 OS << " , "; 3061 if (!shouldEmitArg(ai)) { 3062 ai->writeCtorDefaultInitializers(OS); 3063 } else { 3064 ai->writeCtorInitializers(OS); 3065 } 3066 OS << "\n"; 3067 } 3068 if (DelayedArgs) { 3069 OS << " , "; 3070 DelayedArgs->writeCtorDefaultInitializers(OS); 3071 OS << "\n"; 3072 } 3073 3074 OS << " {\n"; 3075 3076 for (auto const &ai : Args) { 3077 if (!shouldEmitArg(ai)) 3078 continue; 3079 ai->writeCtorBody(OS); 3080 } 3081 OS << "}\n\n"; 3082 }; 3083 3084 if (Header) 3085 OS << "\n // Constructors\n"; 3086 3087 // Emit a constructor that includes all the arguments. 3088 // This is necessary for cloning. 3089 emitCtor(true, true, false); 3090 3091 // Emit a constructor that takes all the non-fake arguments. 3092 if (HasFakeArg) 3093 emitCtor(true, false, false); 3094 3095 // Emit a constructor that takes all the non-fake, non-optional arguments. 3096 if (HasOptArg) 3097 emitCtor(false, false, false); 3098 3099 // Emit constructors that takes no arguments if none already exists. 3100 // This is used for delaying arguments. 3101 bool HasRequiredArgs = 3102 count_if(Args, [=](const std::unique_ptr<Argument> &arg) { 3103 return !arg->isFake() && !arg->isOptional(); 3104 }); 3105 if (DelayedArgs && HasRequiredArgs) 3106 emitCtor(false, false, true); 3107 3108 if (Header) { 3109 OS << '\n'; 3110 OS << " " << R.getName() << "Attr *clone(ASTContext &C) const;\n"; 3111 OS << " void printPretty(raw_ostream &OS,\n" 3112 << " const PrintingPolicy &Policy) const;\n"; 3113 OS << " const char *getSpelling() const;\n"; 3114 } 3115 3116 if (!ElideSpelling) { 3117 assert(!SemanticToSyntacticMap.empty() && "Empty semantic mapping list"); 3118 if (Header) 3119 OS << " Spelling getSemanticSpelling() const;\n"; 3120 else { 3121 OS << R.getName() << "Attr::Spelling " << R.getName() 3122 << "Attr::getSemanticSpelling() const {\n"; 3123 WriteSemanticSpellingSwitch("getAttributeSpellingListIndex()", 3124 SemanticToSyntacticMap, OS); 3125 OS << "}\n"; 3126 } 3127 } 3128 3129 if (Header) 3130 writeAttrAccessorDefinition(R, OS); 3131 3132 for (auto const &ai : Args) { 3133 if (Header) { 3134 ai->writeAccessors(OS); 3135 } else { 3136 ai->writeAccessorDefinitions(OS); 3137 } 3138 OS << "\n\n"; 3139 3140 // Don't write conversion routines for fake arguments. 3141 if (ai->isFake()) continue; 3142 3143 if (ai->isEnumArg()) 3144 static_cast<const EnumArgument *>(ai.get())->writeConversion(OS, 3145 Header); 3146 else if (ai->isVariadicEnumArg()) 3147 static_cast<const VariadicEnumArgument *>(ai.get())->writeConversion( 3148 OS, Header); 3149 } 3150 3151 if (Header) { 3152 if (DelayedArgs) { 3153 DelayedArgs->writeAccessors(OS); 3154 DelayedArgs->writeSetter(OS); 3155 } 3156 3157 OS << R.getValueAsString("AdditionalMembers"); 3158 OS << "\n\n"; 3159 3160 OS << " static bool classof(const Attr *A) { return A->getKind() == " 3161 << "attr::" << R.getName() << "; }\n"; 3162 3163 OS << "};\n\n"; 3164 } else { 3165 if (DelayedArgs) 3166 DelayedArgs->writeAccessorDefinitions(OS); 3167 3168 OS << R.getName() << "Attr *" << R.getName() 3169 << "Attr::clone(ASTContext &C) const {\n"; 3170 OS << " auto *A = new (C) " << R.getName() << "Attr(C, *this"; 3171 for (auto const &ai : Args) { 3172 OS << ", "; 3173 ai->writeCloneArgs(OS); 3174 } 3175 OS << ");\n"; 3176 OS << " A->Inherited = Inherited;\n"; 3177 OS << " A->IsPackExpansion = IsPackExpansion;\n"; 3178 OS << " A->setImplicit(Implicit);\n"; 3179 if (DelayedArgs) { 3180 OS << " A->setDelayedArgs(C, "; 3181 DelayedArgs->writeCloneArgs(OS); 3182 OS << ");\n"; 3183 } 3184 OS << " return A;\n}\n\n"; 3185 3186 writePrettyPrintFunction(R, Args, OS); 3187 writeGetSpellingFunction(R, OS); 3188 } 3189 } 3190 } 3191 // Emits the class definitions for attributes. 3192 void clang::EmitClangAttrClass(const RecordKeeper &Records, raw_ostream &OS) { 3193 emitSourceFileHeader("Attribute classes' definitions", OS, Records); 3194 3195 OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; 3196 OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n"; 3197 3198 emitAttributes(Records, OS, true); 3199 3200 OS << "#endif // LLVM_CLANG_ATTR_CLASSES_INC\n"; 3201 } 3202 3203 // Emits the class method definitions for attributes. 3204 void clang::EmitClangAttrImpl(const RecordKeeper &Records, raw_ostream &OS) { 3205 emitSourceFileHeader("Attribute classes' member function definitions", OS, 3206 Records); 3207 3208 emitAttributes(Records, OS, false); 3209 3210 // Instead of relying on virtual dispatch we just create a huge dispatch 3211 // switch. This is both smaller and faster than virtual functions. 3212 auto EmitFunc = [&](const char *Method) { 3213 OS << " switch (getKind()) {\n"; 3214 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 3215 const Record &R = *Attr; 3216 if (!R.getValueAsBit("ASTNode")) 3217 continue; 3218 3219 OS << " case attr::" << R.getName() << ":\n"; 3220 OS << " return cast<" << R.getName() << "Attr>(this)->" << Method 3221 << ";\n"; 3222 } 3223 OS << " }\n"; 3224 OS << " llvm_unreachable(\"Unexpected attribute kind!\");\n"; 3225 OS << "}\n\n"; 3226 }; 3227 3228 OS << "const char *Attr::getSpelling() const {\n"; 3229 EmitFunc("getSpelling()"); 3230 3231 OS << "Attr *Attr::clone(ASTContext &C) const {\n"; 3232 EmitFunc("clone(C)"); 3233 3234 OS << "void Attr::printPretty(raw_ostream &OS, " 3235 "const PrintingPolicy &Policy) const {\n"; 3236 EmitFunc("printPretty(OS, Policy)"); 3237 } 3238 3239 static void emitAttrList(raw_ostream &OS, StringRef Class, 3240 ArrayRef<const Record *> AttrList) { 3241 for (auto Cur : AttrList) { 3242 OS << Class << "(" << Cur->getName() << ")\n"; 3243 } 3244 } 3245 3246 // Determines if an attribute has a Pragma spelling. 3247 static bool AttrHasPragmaSpelling(const Record *R) { 3248 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R); 3249 return any_of(Spellings, [](const FlattenedSpelling &S) { 3250 return S.variety() == "Pragma"; 3251 }); 3252 } 3253 3254 namespace { 3255 3256 struct AttrClassDescriptor { 3257 const char * const MacroName; 3258 const char * const TableGenName; 3259 }; 3260 3261 } // end anonymous namespace 3262 3263 static const AttrClassDescriptor AttrClassDescriptors[] = { 3264 {"ATTR", "Attr"}, 3265 {"TYPE_ATTR", "TypeAttr"}, 3266 {"STMT_ATTR", "StmtAttr"}, 3267 {"DECL_OR_STMT_ATTR", "DeclOrStmtAttr"}, 3268 {"INHERITABLE_ATTR", "InheritableAttr"}, 3269 {"DECL_OR_TYPE_ATTR", "DeclOrTypeAttr"}, 3270 {"INHERITABLE_PARAM_ATTR", "InheritableParamAttr"}, 3271 {"INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr"}, 3272 {"PARAMETER_ABI_ATTR", "ParameterABIAttr"}, 3273 {"HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"}}; 3274 3275 static void emitDefaultDefine(raw_ostream &OS, StringRef name, 3276 const char *superName) { 3277 OS << "#ifndef " << name << "\n"; 3278 OS << "#define " << name << "(NAME) "; 3279 if (superName) OS << superName << "(NAME)"; 3280 OS << "\n#endif\n\n"; 3281 } 3282 3283 namespace { 3284 3285 /// A class of attributes. 3286 struct AttrClass { 3287 const AttrClassDescriptor &Descriptor; 3288 const Record *TheRecord; 3289 AttrClass *SuperClass = nullptr; 3290 std::vector<AttrClass*> SubClasses; 3291 std::vector<const Record *> Attrs; 3292 3293 AttrClass(const AttrClassDescriptor &Descriptor, const Record *R) 3294 : Descriptor(Descriptor), TheRecord(R) {} 3295 3296 void emitDefaultDefines(raw_ostream &OS) const { 3297 // Default the macro unless this is a root class (i.e. Attr). 3298 if (SuperClass) { 3299 emitDefaultDefine(OS, Descriptor.MacroName, 3300 SuperClass->Descriptor.MacroName); 3301 } 3302 } 3303 3304 void emitUndefs(raw_ostream &OS) const { 3305 OS << "#undef " << Descriptor.MacroName << "\n"; 3306 } 3307 3308 void emitAttrList(raw_ostream &OS) const { 3309 for (auto SubClass : SubClasses) { 3310 SubClass->emitAttrList(OS); 3311 } 3312 3313 ::emitAttrList(OS, Descriptor.MacroName, Attrs); 3314 } 3315 3316 void classifyAttrOnRoot(const Record *Attr) { 3317 bool result = classifyAttr(Attr); 3318 assert(result && "failed to classify on root"); (void) result; 3319 } 3320 3321 void emitAttrRange(raw_ostream &OS) const { 3322 OS << "ATTR_RANGE(" << Descriptor.TableGenName 3323 << ", " << getFirstAttr()->getName() 3324 << ", " << getLastAttr()->getName() << ")\n"; 3325 } 3326 3327 private: 3328 bool classifyAttr(const Record *Attr) { 3329 // Check all the subclasses. 3330 for (auto SubClass : SubClasses) { 3331 if (SubClass->classifyAttr(Attr)) 3332 return true; 3333 } 3334 3335 // It's not more specific than this class, but it might still belong here. 3336 if (Attr->isSubClassOf(TheRecord)) { 3337 Attrs.push_back(Attr); 3338 return true; 3339 } 3340 3341 return false; 3342 } 3343 3344 const Record *getFirstAttr() const { 3345 if (!SubClasses.empty()) 3346 return SubClasses.front()->getFirstAttr(); 3347 return Attrs.front(); 3348 } 3349 3350 const Record *getLastAttr() const { 3351 if (!Attrs.empty()) 3352 return Attrs.back(); 3353 return SubClasses.back()->getLastAttr(); 3354 } 3355 }; 3356 3357 /// The entire hierarchy of attribute classes. 3358 class AttrClassHierarchy { 3359 std::vector<std::unique_ptr<AttrClass>> Classes; 3360 3361 public: 3362 AttrClassHierarchy(const RecordKeeper &Records) { 3363 // Find records for all the classes. 3364 for (auto &Descriptor : AttrClassDescriptors) { 3365 const Record *ClassRecord = Records.getClass(Descriptor.TableGenName); 3366 AttrClass *Class = new AttrClass(Descriptor, ClassRecord); 3367 Classes.emplace_back(Class); 3368 } 3369 3370 // Link up the hierarchy. 3371 for (auto &Class : Classes) { 3372 if (AttrClass *SuperClass = findSuperClass(Class->TheRecord)) { 3373 Class->SuperClass = SuperClass; 3374 SuperClass->SubClasses.push_back(Class.get()); 3375 } 3376 } 3377 3378 #ifndef NDEBUG 3379 for (auto i = Classes.begin(), e = Classes.end(); i != e; ++i) { 3380 assert((i == Classes.begin()) == ((*i)->SuperClass == nullptr) && 3381 "only the first class should be a root class!"); 3382 } 3383 #endif 3384 } 3385 3386 void emitDefaultDefines(raw_ostream &OS) const { 3387 for (auto &Class : Classes) { 3388 Class->emitDefaultDefines(OS); 3389 } 3390 } 3391 3392 void emitUndefs(raw_ostream &OS) const { 3393 for (auto &Class : Classes) { 3394 Class->emitUndefs(OS); 3395 } 3396 } 3397 3398 void emitAttrLists(raw_ostream &OS) const { 3399 // Just start from the root class. 3400 Classes[0]->emitAttrList(OS); 3401 } 3402 3403 void emitAttrRanges(raw_ostream &OS) const { 3404 for (auto &Class : Classes) 3405 Class->emitAttrRange(OS); 3406 } 3407 3408 void classifyAttr(const Record *Attr) { 3409 // Add the attribute to the root class. 3410 Classes[0]->classifyAttrOnRoot(Attr); 3411 } 3412 3413 private: 3414 AttrClass *findClassByRecord(const Record *R) const { 3415 for (auto &Class : Classes) { 3416 if (Class->TheRecord == R) 3417 return Class.get(); 3418 } 3419 return nullptr; 3420 } 3421 3422 AttrClass *findSuperClass(const Record *R) const { 3423 // TableGen flattens the superclass list, so we just need to walk it 3424 // in reverse. 3425 std::vector<const Record *> SuperClasses = R->getSuperClasses(); 3426 for (const Record *R : reverse(SuperClasses)) { 3427 if (AttrClass *SuperClass = findClassByRecord(R)) 3428 return SuperClass; 3429 } 3430 return nullptr; 3431 } 3432 }; 3433 3434 } // end anonymous namespace 3435 3436 namespace clang { 3437 3438 // Emits the enumeration list for attributes. 3439 void EmitClangAttrList(const RecordKeeper &Records, raw_ostream &OS) { 3440 emitSourceFileHeader("List of all attributes that Clang recognizes", OS, 3441 Records); 3442 3443 AttrClassHierarchy Hierarchy(Records); 3444 3445 // Add defaulting macro definitions. 3446 Hierarchy.emitDefaultDefines(OS); 3447 emitDefaultDefine(OS, "PRAGMA_SPELLING_ATTR", nullptr); 3448 3449 std::vector<const Record *> PragmaAttrs; 3450 for (auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 3451 if (!Attr->getValueAsBit("ASTNode")) 3452 continue; 3453 3454 // Add the attribute to the ad-hoc groups. 3455 if (AttrHasPragmaSpelling(Attr)) 3456 PragmaAttrs.push_back(Attr); 3457 3458 // Place it in the hierarchy. 3459 Hierarchy.classifyAttr(Attr); 3460 } 3461 3462 // Emit the main attribute list. 3463 Hierarchy.emitAttrLists(OS); 3464 3465 // Emit the ad hoc groups. 3466 emitAttrList(OS, "PRAGMA_SPELLING_ATTR", PragmaAttrs); 3467 3468 // Emit the attribute ranges. 3469 OS << "#ifdef ATTR_RANGE\n"; 3470 Hierarchy.emitAttrRanges(OS); 3471 OS << "#undef ATTR_RANGE\n"; 3472 OS << "#endif\n"; 3473 3474 Hierarchy.emitUndefs(OS); 3475 OS << "#undef PRAGMA_SPELLING_ATTR\n"; 3476 } 3477 3478 // Emits the enumeration list for attributes. 3479 void EmitClangAttrSubjectMatchRuleList(const RecordKeeper &Records, 3480 raw_ostream &OS) { 3481 emitSourceFileHeader( 3482 "List of all attribute subject matching rules that Clang recognizes", OS, 3483 Records); 3484 PragmaClangAttributeSupport &PragmaAttributeSupport = 3485 getPragmaAttributeSupport(Records); 3486 emitDefaultDefine(OS, "ATTR_MATCH_RULE", nullptr); 3487 PragmaAttributeSupport.emitMatchRuleList(OS); 3488 OS << "#undef ATTR_MATCH_RULE\n"; 3489 } 3490 3491 // Emits the code to read an attribute from a precompiled header. 3492 void EmitClangAttrPCHRead(const RecordKeeper &Records, raw_ostream &OS) { 3493 emitSourceFileHeader("Attribute deserialization code", OS, Records); 3494 3495 const Record *InhClass = Records.getClass("InheritableAttr"); 3496 std::vector<const Record *> ArgRecords; 3497 std::vector<std::unique_ptr<Argument>> Args; 3498 std::unique_ptr<VariadicExprArgument> DelayedArgs; 3499 3500 OS << " switch (Kind) {\n"; 3501 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 3502 const Record &R = *Attr; 3503 if (!R.getValueAsBit("ASTNode")) 3504 continue; 3505 3506 OS << " case attr::" << R.getName() << ": {\n"; 3507 if (R.isSubClassOf(InhClass)) 3508 OS << " bool isInherited = Record.readInt();\n"; 3509 OS << " bool isImplicit = Record.readInt();\n"; 3510 OS << " bool isPackExpansion = Record.readInt();\n"; 3511 DelayedArgs = nullptr; 3512 if (Attr->getValueAsBit("AcceptsExprPack")) { 3513 DelayedArgs = 3514 std::make_unique<VariadicExprArgument>("DelayedArgs", R.getName()); 3515 DelayedArgs->writePCHReadDecls(OS); 3516 } 3517 ArgRecords = R.getValueAsListOfDefs("Args"); 3518 Args.clear(); 3519 for (const auto *Arg : ArgRecords) { 3520 Args.emplace_back(createArgument(*Arg, R.getName())); 3521 Args.back()->writePCHReadDecls(OS); 3522 } 3523 OS << " New = new (Context) " << R.getName() << "Attr(Context, Info"; 3524 for (auto const &ri : Args) { 3525 OS << ", "; 3526 ri->writePCHReadArgs(OS); 3527 } 3528 OS << ");\n"; 3529 if (R.isSubClassOf(InhClass)) 3530 OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n"; 3531 OS << " New->setImplicit(isImplicit);\n"; 3532 OS << " New->setPackExpansion(isPackExpansion);\n"; 3533 if (DelayedArgs) { 3534 OS << " cast<" << R.getName() 3535 << "Attr>(New)->setDelayedArgs(Context, "; 3536 DelayedArgs->writePCHReadArgs(OS); 3537 OS << ");\n"; 3538 } 3539 3540 if (Attr->getValueAsBit("HasCustomSerialization")) 3541 OS << " read" << R.getName() << "Attr(cast<" << R.getName() 3542 << "Attr>(New));\n"; 3543 3544 OS << " break;\n"; 3545 OS << " }\n"; 3546 } 3547 OS << " }\n"; 3548 } 3549 3550 // Emits the code to write an attribute to a precompiled header. 3551 void EmitClangAttrPCHWrite(const RecordKeeper &Records, raw_ostream &OS) { 3552 emitSourceFileHeader("Attribute serialization code", OS, Records); 3553 3554 const Record *InhClass = Records.getClass("InheritableAttr"); 3555 OS << " switch (A->getKind()) {\n"; 3556 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 3557 const Record &R = *Attr; 3558 if (!R.getValueAsBit("ASTNode")) 3559 continue; 3560 OS << " case attr::" << R.getName() << ": {\n"; 3561 std::vector<const Record *> Args = R.getValueAsListOfDefs("Args"); 3562 if (R.isSubClassOf(InhClass) || !Args.empty()) 3563 OS << " const auto *SA = cast<" << R.getName() 3564 << "Attr>(A);\n"; 3565 if (R.isSubClassOf(InhClass)) 3566 OS << " Record.push_back(SA->isInherited());\n"; 3567 OS << " Record.push_back(A->isImplicit());\n"; 3568 OS << " Record.push_back(A->isPackExpansion());\n"; 3569 if (Attr->getValueAsBit("AcceptsExprPack")) 3570 VariadicExprArgument("DelayedArgs", R.getName()).writePCHWrite(OS); 3571 3572 for (const auto *Arg : Args) 3573 createArgument(*Arg, R.getName())->writePCHWrite(OS); 3574 3575 if (Attr->getValueAsBit("HasCustomSerialization")) 3576 OS << " Record.Add" << R.getName() << "Attr(SA);\n"; 3577 3578 OS << " break;\n"; 3579 OS << " }\n"; 3580 } 3581 OS << " }\n"; 3582 } 3583 3584 } // namespace clang 3585 3586 // Helper function for GenerateTargetSpecificAttrChecks that alters the 'Test' 3587 // parameter with only a single check type, if applicable. 3588 static bool GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test, 3589 std::string *FnName, 3590 StringRef ListName, 3591 StringRef CheckAgainst, 3592 StringRef Scope) { 3593 if (!R->isValueUnset(ListName)) { 3594 Test += " && ("; 3595 std::vector<StringRef> Items = R->getValueAsListOfStrings(ListName); 3596 for (auto I = Items.begin(), E = Items.end(); I != E; ++I) { 3597 StringRef Part = *I; 3598 Test += CheckAgainst; 3599 Test += " == "; 3600 Test += Scope; 3601 Test += Part; 3602 if (I + 1 != E) 3603 Test += " || "; 3604 if (FnName) 3605 *FnName += Part; 3606 } 3607 Test += ")"; 3608 return true; 3609 } 3610 return false; 3611 } 3612 3613 // Generate a conditional expression to check if the current target satisfies 3614 // the conditions for a TargetSpecificAttr record, and append the code for 3615 // those checks to the Test string. If the FnName string pointer is non-null, 3616 // append a unique suffix to distinguish this set of target checks from other 3617 // TargetSpecificAttr records. 3618 static bool GenerateTargetSpecificAttrChecks(const Record *R, 3619 std::vector<StringRef> &Arches, 3620 std::string &Test, 3621 std::string *FnName) { 3622 bool AnyTargetChecks = false; 3623 3624 // It is assumed that there will be an Triple object 3625 // named "T" and a TargetInfo object named "Target" within 3626 // scope that can be used to determine whether the attribute exists in 3627 // a given target. 3628 Test += "true"; 3629 // If one or more architectures is specified, check those. Arches are handled 3630 // differently because GenerateTargetRequirements needs to combine the list 3631 // with ParseKind. 3632 if (!Arches.empty()) { 3633 AnyTargetChecks = true; 3634 Test += " && ("; 3635 for (auto I = Arches.begin(), E = Arches.end(); I != E; ++I) { 3636 StringRef Part = *I; 3637 Test += "T.getArch() == llvm::Triple::"; 3638 Test += Part; 3639 if (I + 1 != E) 3640 Test += " || "; 3641 if (FnName) 3642 *FnName += Part; 3643 } 3644 Test += ")"; 3645 } 3646 3647 // If the attribute is specific to particular OSes, check those. 3648 AnyTargetChecks |= GenerateTargetSpecificAttrCheck( 3649 R, Test, FnName, "OSes", "T.getOS()", "llvm::Triple::"); 3650 3651 // If one or more object formats is specified, check those. 3652 AnyTargetChecks |= 3653 GenerateTargetSpecificAttrCheck(R, Test, FnName, "ObjectFormats", 3654 "T.getObjectFormat()", "llvm::Triple::"); 3655 3656 // If custom code is specified, emit it. 3657 StringRef Code = R->getValueAsString("CustomCode"); 3658 if (!Code.empty()) { 3659 AnyTargetChecks = true; 3660 Test += " && ("; 3661 Test += Code; 3662 Test += ")"; 3663 } 3664 3665 return AnyTargetChecks; 3666 } 3667 3668 static void GenerateHasAttrSpellingStringSwitch( 3669 ArrayRef<std::pair<const Record *, FlattenedSpelling>> Attrs, 3670 raw_ostream &OS, StringRef Variety, StringRef Scope = "") { 3671 3672 // It turns out that there are duplicate records for a given spelling. This 3673 // map combines matching test strings using '||'. For example, if there are 3674 // three conditions A, B, and C, the final result will be: A || B || C. 3675 llvm::StringMap<std::string> TestStringMap; 3676 3677 for (const auto &[Attr, Spelling] : Attrs) { 3678 // C++11-style attributes have specific version information associated with 3679 // them. If the attribute has no scope, the version information must not 3680 // have the default value (1), as that's incorrect. Instead, the unscoped 3681 // attribute version information should be taken from the SD-6 standing 3682 // document, which can be found at: 3683 // https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations 3684 // 3685 // C23-style attributes have the same kind of version information 3686 // associated with them. The unscoped attribute version information should 3687 // be taken from the specification of the attribute in the C Standard. 3688 // 3689 // Clang-specific attributes have the same kind of version information 3690 // associated with them. This version is typically the default value (1). 3691 // These version values are clang-specific and should typically be 3692 // incremented once the attribute changes its syntax and/or semantics in a 3693 // a way that is impactful to the end user. 3694 int Version = 1; 3695 3696 assert(Spelling.variety() == Variety); 3697 std::string Name = ""; 3698 if (Spelling.nameSpace().empty() || Scope == Spelling.nameSpace()) { 3699 Name = Spelling.name(); 3700 Version = static_cast<int>( 3701 Spelling.getSpellingRecord().getValueAsInt("Version")); 3702 // Verify that explicitly specified CXX11 and C23 spellings (i.e. 3703 // not inferred from Clang/GCC spellings) have a version that's 3704 // different from the default (1). 3705 bool RequiresValidVersion = 3706 (Variety == "CXX11" || Variety == "C23") && 3707 Spelling.getSpellingRecord().getValueAsString("Variety") == Variety; 3708 if (RequiresValidVersion && Scope.empty() && Version == 1) 3709 PrintError(Spelling.getSpellingRecord().getLoc(), 3710 "Standard attributes must have " 3711 "valid version information."); 3712 } 3713 3714 std::string Test; 3715 if (Attr->isSubClassOf("TargetSpecificAttr")) { 3716 const Record *R = Attr->getValueAsDef("Target"); 3717 std::vector<StringRef> Arches = R->getValueAsListOfStrings("Arches"); 3718 GenerateTargetSpecificAttrChecks(R, Arches, Test, nullptr); 3719 } else if (!Attr->getValueAsListOfDefs("TargetSpecificSpellings").empty()) { 3720 // Add target checks if this spelling is target-specific. 3721 for (const auto &TargetSpelling : 3722 Attr->getValueAsListOfDefs("TargetSpecificSpellings")) { 3723 // Find spelling that matches current scope and name. 3724 for (const auto &Spelling : GetFlattenedSpellings(*TargetSpelling)) { 3725 if (Scope == Spelling.nameSpace() && Name == Spelling.name()) { 3726 const Record *Target = TargetSpelling->getValueAsDef("Target"); 3727 std::vector<StringRef> Arches = 3728 Target->getValueAsListOfStrings("Arches"); 3729 GenerateTargetSpecificAttrChecks(Target, Arches, Test, 3730 /*FnName=*/nullptr); 3731 break; 3732 } 3733 } 3734 } 3735 } 3736 3737 std::string TestStr = 3738 !Test.empty() ? '(' + Test + " ? " + itostr(Version) + " : 0" + ')' 3739 : '(' + itostr(Version) + ')'; 3740 3741 if (Scope.empty() || Scope == Spelling.nameSpace()) { 3742 if (TestStringMap.contains(Spelling.name()) && 3743 TestStringMap[Spelling.name()] != TestStr) 3744 TestStringMap[Spelling.name()] += " || " + TestStr; 3745 else 3746 TestStringMap[Spelling.name()] = TestStr; 3747 } 3748 } 3749 3750 // Create the actual string switch statement after all the attributes have 3751 // been parsed. 3752 for (auto &Entry : TestStringMap) { 3753 OS << " .Case(\"" << Entry.getKey() << "\", " << Entry.getValue() 3754 << ")\n"; 3755 } 3756 3757 OS << " .Default(0);\n"; 3758 } 3759 3760 namespace clang { 3761 3762 // Emits list of regular keyword attributes with info about their arguments. 3763 void EmitClangRegularKeywordAttributeInfo(const RecordKeeper &Records, 3764 raw_ostream &OS) { 3765 emitSourceFileHeader( 3766 "A list of regular keyword attributes generated from the attribute" 3767 " definitions", 3768 OS); 3769 // Assume for now that the same token is not used in multiple regular 3770 // keyword attributes. 3771 for (auto *R : Records.getAllDerivedDefinitions("Attr")) 3772 for (const auto &S : GetFlattenedSpellings(*R)) { 3773 if (!isRegularKeywordAttribute(S)) 3774 continue; 3775 std::vector<const Record *> Args = R->getValueAsListOfDefs("Args"); 3776 bool HasArgs = any_of( 3777 Args, [](const Record *Arg) { return !Arg->getValueAsBit("Fake"); }); 3778 3779 OS << "KEYWORD_ATTRIBUTE(" 3780 << S.getSpellingRecord().getValueAsString("Name") << ", " 3781 << (HasArgs ? "true" : "false") << ", )\n"; 3782 } 3783 OS << "#undef KEYWORD_ATTRIBUTE\n"; 3784 } 3785 3786 void EmitCXX11AttributeInfo(const RecordKeeper &Records, raw_ostream &OS) { 3787 OS << "#if defined(CXX11_ATTR_ARGS_INFO)\n"; 3788 for (auto *R : Records.getAllDerivedDefinitions("Attr")) { 3789 for (const FlattenedSpelling &SI : GetFlattenedSpellings(*R)) { 3790 if (SI.variety() == "CXX11" && SI.nameSpace().empty()) { 3791 unsigned RequiredArgs = 0; 3792 unsigned OptionalArgs = 0; 3793 for (const auto *Arg : R->getValueAsListOfDefs("Args")) { 3794 if (Arg->getValueAsBit("Fake")) 3795 continue; 3796 3797 if (Arg->getValueAsBit("Optional")) 3798 OptionalArgs++; 3799 else 3800 RequiredArgs++; 3801 } 3802 OS << ".Case(\"" << SI.getSpellingRecord().getValueAsString("Name") 3803 << "\"," 3804 << "AttributeCommonInfo::AttrArgsInfo::" 3805 << (RequiredArgs ? "Required" 3806 : OptionalArgs ? "Optional" 3807 : "None") 3808 << ")" 3809 << "\n"; 3810 } 3811 } 3812 } 3813 OS << "#endif // CXX11_ATTR_ARGS_INFO\n"; 3814 } 3815 3816 // Emits the list of spellings for attributes. 3817 void EmitClangAttrHasAttrImpl(const RecordKeeper &Records, raw_ostream &OS) { 3818 emitSourceFileHeader("Code to implement the __has_attribute logic", OS, 3819 Records); 3820 3821 // Separate all of the attributes out into four group: generic, C++11, GNU, 3822 // and declspecs. Then generate a big switch statement for each of them. 3823 using PairTy = std::pair<const Record *, FlattenedSpelling>; 3824 std::vector<PairTy> Declspec, Microsoft, GNU, Pragma, HLSLAnnotation; 3825 std::map<StringRef, std::vector<PairTy>> CXX, C23; 3826 3827 // Walk over the list of all attributes, and split them out based on the 3828 // spelling variety. 3829 for (auto *R : Records.getAllDerivedDefinitions("Attr")) { 3830 for (const FlattenedSpelling &SI : GetFlattenedSpellings(*R)) { 3831 StringRef Variety = SI.variety(); 3832 if (Variety == "GNU") 3833 GNU.emplace_back(R, SI); 3834 else if (Variety == "Declspec") 3835 Declspec.emplace_back(R, SI); 3836 else if (Variety == "Microsoft") 3837 Microsoft.emplace_back(R, SI); 3838 else if (Variety == "CXX11") 3839 CXX[SI.nameSpace()].emplace_back(R, SI); 3840 else if (Variety == "C23") 3841 C23[SI.nameSpace()].emplace_back(R, SI); 3842 else if (Variety == "Pragma") 3843 Pragma.emplace_back(R, SI); 3844 else if (Variety == "HLSLAnnotation") 3845 HLSLAnnotation.emplace_back(R, SI); 3846 } 3847 } 3848 3849 OS << "const llvm::Triple &T = Target.getTriple();\n"; 3850 OS << "switch (Syntax) {\n"; 3851 OS << "case AttributeCommonInfo::Syntax::AS_GNU:\n"; 3852 OS << " return llvm::StringSwitch<int>(Name)\n"; 3853 GenerateHasAttrSpellingStringSwitch(GNU, OS, "GNU"); 3854 OS << "case AttributeCommonInfo::Syntax::AS_Declspec:\n"; 3855 OS << " return llvm::StringSwitch<int>(Name)\n"; 3856 GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec"); 3857 OS << "case AttributeCommonInfo::Syntax::AS_Microsoft:\n"; 3858 OS << " return llvm::StringSwitch<int>(Name)\n"; 3859 GenerateHasAttrSpellingStringSwitch(Microsoft, OS, "Microsoft"); 3860 OS << "case AttributeCommonInfo::Syntax::AS_Pragma:\n"; 3861 OS << " return llvm::StringSwitch<int>(Name)\n"; 3862 GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma"); 3863 OS << "case AttributeCommonInfo::Syntax::AS_HLSLAnnotation:\n"; 3864 OS << " return llvm::StringSwitch<int>(Name)\n"; 3865 GenerateHasAttrSpellingStringSwitch(HLSLAnnotation, OS, "HLSLAnnotation"); 3866 auto fn = [&OS](StringRef Spelling, 3867 const std::map<StringRef, std::vector<PairTy>> &Map) { 3868 OS << "case AttributeCommonInfo::Syntax::AS_" << Spelling << ": {\n"; 3869 // C++11-style attributes are further split out based on the Scope. 3870 ListSeparator LS(" else "); 3871 for (const auto &[Scope, List] : Map) { 3872 OS << LS; 3873 OS << "if (ScopeName == \"" << Scope << "\") {\n"; 3874 OS << " return llvm::StringSwitch<int>(Name)\n"; 3875 GenerateHasAttrSpellingStringSwitch(List, OS, Spelling, Scope); 3876 OS << "}"; 3877 } 3878 OS << "\n} break;\n"; 3879 }; 3880 fn("CXX11", CXX); 3881 fn("C23", C23); 3882 OS << "case AttributeCommonInfo::Syntax::AS_Keyword:\n"; 3883 OS << "case AttributeCommonInfo::Syntax::AS_ContextSensitiveKeyword:\n"; 3884 OS << " llvm_unreachable(\"hasAttribute not supported for keyword\");\n"; 3885 OS << " return 0;\n"; 3886 OS << "case AttributeCommonInfo::Syntax::AS_Implicit:\n"; 3887 OS << " llvm_unreachable (\"hasAttribute not supported for " 3888 "AS_Implicit\");\n"; 3889 OS << " return 0;\n"; 3890 3891 OS << "}\n"; 3892 } 3893 3894 void EmitClangAttrSpellingListIndex(const RecordKeeper &Records, 3895 raw_ostream &OS) { 3896 emitSourceFileHeader("Code to translate different attribute spellings into " 3897 "internal identifiers", 3898 OS, Records); 3899 3900 OS << " switch (getParsedKind()) {\n"; 3901 OS << " case IgnoredAttribute:\n"; 3902 OS << " case UnknownAttribute:\n"; 3903 OS << " case NoSemaHandlerAttribute:\n"; 3904 OS << " llvm_unreachable(\"Ignored/unknown shouldn't get here\");\n"; 3905 3906 ParsedAttrMap Attrs = getParsedAttrList(Records); 3907 for (const auto &I : Attrs) { 3908 const Record &R = *I.second; 3909 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R); 3910 OS << " case AT_" << I.first << ": {\n"; 3911 3912 // If there are none or one spelling to check, resort to the default 3913 // behavior of returning index as 0. 3914 if (Spellings.size() <= 1) { 3915 OS << " return 0;\n" 3916 << " break;\n" 3917 << " }\n"; 3918 continue; 3919 } 3920 3921 std::vector<StringRef> Names; 3922 llvm::transform(Spellings, std::back_inserter(Names), 3923 [](const FlattenedSpelling &FS) { return FS.name(); }); 3924 llvm::sort(Names); 3925 Names.erase(llvm::unique(Names), Names.end()); 3926 3927 for (const auto &[Idx, FS] : enumerate(Spellings)) { 3928 OS << " if ("; 3929 if (Names.size() > 1) { 3930 SmallVector<StringRef, 6> SameLenNames; 3931 StringRef FSName = FS.name(); 3932 llvm::copy_if( 3933 Names, std::back_inserter(SameLenNames), 3934 [&](StringRef N) { return N.size() == FSName.size(); }); 3935 3936 if (SameLenNames.size() == 1) { 3937 OS << "Name.size() == " << FS.name().size() << " && "; 3938 } else { 3939 // FIXME: We currently fall back to comparing entire strings if there 3940 // are 2 or more spelling names with the same length. This can be 3941 // optimized to check only for the the first differing character 3942 // between them instead. 3943 OS << "Name == \"" << FS.name() << "\"" 3944 << " && "; 3945 } 3946 } 3947 3948 OS << "getSyntax() == AttributeCommonInfo::AS_" << FS.variety() 3949 << " && ComputedScope == "; 3950 if (FS.nameSpace() == "") 3951 OS << "AttributeCommonInfo::Scope::NONE"; 3952 else 3953 OS << "AttributeCommonInfo::Scope::" + FS.nameSpace().upper(); 3954 3955 OS << ")\n" 3956 << " return " << Idx << ";\n"; 3957 } 3958 3959 OS << " break;\n" 3960 << " }\n"; 3961 } 3962 3963 OS << " }\n" 3964 << " return 0;\n"; 3965 } 3966 3967 // Emits code used by RecursiveASTVisitor to visit attributes 3968 void EmitClangAttrASTVisitor(const RecordKeeper &Records, raw_ostream &OS) { 3969 emitSourceFileHeader("Used by RecursiveASTVisitor to visit attributes.", OS, 3970 Records); 3971 // Write method declarations for Traverse* methods. 3972 // We emit this here because we only generate methods for attributes that 3973 // are declared as ASTNodes. 3974 OS << "#ifdef ATTR_VISITOR_DECLS_ONLY\n\n"; 3975 ArrayRef<const Record *> Attrs = Records.getAllDerivedDefinitions("Attr"); 3976 for (const auto *Attr : Attrs) { 3977 const Record &R = *Attr; 3978 if (!R.getValueAsBit("ASTNode")) 3979 continue; 3980 OS << " bool Traverse" 3981 << R.getName() << "Attr(" << R.getName() << "Attr *A);\n"; 3982 OS << " bool Visit" 3983 << R.getName() << "Attr(" << R.getName() << "Attr *A) {\n" 3984 << " return true; \n" 3985 << " }\n"; 3986 } 3987 OS << "\n#else // ATTR_VISITOR_DECLS_ONLY\n\n"; 3988 3989 // Write individual Traverse* methods for each attribute class. 3990 for (const auto *Attr : Attrs) { 3991 const Record &R = *Attr; 3992 if (!R.getValueAsBit("ASTNode")) 3993 continue; 3994 3995 OS << "template <typename Derived>\n" 3996 << "bool VISITORCLASS<Derived>::Traverse" 3997 << R.getName() << "Attr(" << R.getName() << "Attr *A) {\n" 3998 << " if (!getDerived().VisitAttr(A))\n" 3999 << " return false;\n" 4000 << " if (!getDerived().Visit" << R.getName() << "Attr(A))\n" 4001 << " return false;\n"; 4002 4003 for (const auto *Arg : R.getValueAsListOfDefs("Args")) 4004 createArgument(*Arg, R.getName())->writeASTVisitorTraversal(OS); 4005 4006 if (Attr->getValueAsBit("AcceptsExprPack")) 4007 VariadicExprArgument("DelayedArgs", R.getName()) 4008 .writeASTVisitorTraversal(OS); 4009 4010 OS << " return true;\n"; 4011 OS << "}\n\n"; 4012 } 4013 4014 // Write generic Traverse routine 4015 OS << "template <typename Derived>\n" 4016 << "bool VISITORCLASS<Derived>::TraverseAttr(Attr *A) {\n" 4017 << " if (!A)\n" 4018 << " return true;\n" 4019 << "\n" 4020 << " switch (A->getKind()) {\n"; 4021 4022 for (const auto *Attr : Attrs) { 4023 const Record &R = *Attr; 4024 if (!R.getValueAsBit("ASTNode")) 4025 continue; 4026 4027 OS << " case attr::" << R.getName() << ":\n" 4028 << " return getDerived().Traverse" << R.getName() << "Attr(" 4029 << "cast<" << R.getName() << "Attr>(A));\n"; 4030 } 4031 OS << " }\n"; // end switch 4032 OS << " llvm_unreachable(\"bad attribute kind\");\n"; 4033 OS << "}\n"; // end function 4034 OS << "#endif // ATTR_VISITOR_DECLS_ONLY\n"; 4035 } 4036 4037 static void 4038 EmitClangAttrTemplateInstantiateHelper(ArrayRef<const Record *> Attrs, 4039 raw_ostream &OS, bool AppliesToDecl) { 4040 4041 OS << " switch (At->getKind()) {\n"; 4042 for (const auto *Attr : Attrs) { 4043 const Record &R = *Attr; 4044 if (!R.getValueAsBit("ASTNode")) 4045 continue; 4046 OS << " case attr::" << R.getName() << ": {\n"; 4047 bool ShouldClone = R.getValueAsBit("Clone") && 4048 (!AppliesToDecl || 4049 R.getValueAsBit("MeaningfulToClassTemplateDefinition")); 4050 4051 if (!ShouldClone) { 4052 OS << " return nullptr;\n"; 4053 OS << " }\n"; 4054 continue; 4055 } 4056 4057 OS << " const auto *A = cast<" 4058 << R.getName() << "Attr>(At);\n"; 4059 bool TDependent = R.getValueAsBit("TemplateDependent"); 4060 4061 if (!TDependent) { 4062 OS << " return A->clone(C);\n"; 4063 OS << " }\n"; 4064 continue; 4065 } 4066 4067 std::vector<const Record *> ArgRecords = R.getValueAsListOfDefs("Args"); 4068 std::vector<std::unique_ptr<Argument>> Args; 4069 Args.reserve(ArgRecords.size()); 4070 4071 for (const auto *ArgRecord : ArgRecords) 4072 Args.emplace_back(createArgument(*ArgRecord, R.getName())); 4073 4074 for (auto const &ai : Args) 4075 ai->writeTemplateInstantiation(OS); 4076 4077 OS << " return new (C) " << R.getName() << "Attr(C, *A"; 4078 for (auto const &ai : Args) { 4079 OS << ", "; 4080 ai->writeTemplateInstantiationArgs(OS); 4081 } 4082 OS << ");\n" 4083 << " }\n"; 4084 } 4085 OS << " } // end switch\n" 4086 << " llvm_unreachable(\"Unknown attribute!\");\n" 4087 << " return nullptr;\n"; 4088 } 4089 4090 // Emits code to instantiate dependent attributes on templates. 4091 void EmitClangAttrTemplateInstantiate(const RecordKeeper &Records, 4092 raw_ostream &OS) { 4093 emitSourceFileHeader("Template instantiation code for attributes", OS, 4094 Records); 4095 4096 ArrayRef<const Record *> Attrs = Records.getAllDerivedDefinitions("Attr"); 4097 4098 OS << "namespace clang {\n" 4099 << "namespace sema {\n\n" 4100 << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, " 4101 << "Sema &S,\n" 4102 << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n"; 4103 EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/false); 4104 OS << "}\n\n" 4105 << "Attr *instantiateTemplateAttributeForDecl(const Attr *At,\n" 4106 << " ASTContext &C, Sema &S,\n" 4107 << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n"; 4108 EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/true); 4109 OS << "}\n\n" 4110 << "} // end namespace sema\n" 4111 << "} // end namespace clang\n"; 4112 } 4113 4114 // Emits the list of parsed attributes. 4115 void EmitClangAttrParsedAttrList(const RecordKeeper &Records, raw_ostream &OS) { 4116 emitSourceFileHeader("List of all attributes that Clang recognizes", OS, 4117 Records); 4118 4119 OS << "#ifndef PARSED_ATTR\n"; 4120 OS << "#define PARSED_ATTR(NAME) NAME\n"; 4121 OS << "#endif\n\n"; 4122 4123 ParsedAttrMap Names = getParsedAttrList(Records); 4124 for (const auto &I : Names) { 4125 OS << "PARSED_ATTR(" << I.first << ")\n"; 4126 } 4127 } 4128 4129 void EmitAttributeSpellingList(const RecordKeeper &Records, raw_ostream &OS) { 4130 emitSourceFileHeader("List of attribute names", OS, Records); 4131 4132 std::set<StringRef> AttrSpellingList; 4133 std::set<StringRef> AttrScopeSpellingList; 4134 4135 for (const auto *A : Records.getAllDerivedDefinitions("Attr")) { 4136 for (const auto &S : GetFlattenedSpellings(*A)) { 4137 AttrSpellingList.insert(S.name()); 4138 if (S.nameSpace().size()) 4139 AttrScopeSpellingList.insert(S.nameSpace()); 4140 } 4141 } 4142 4143 OS << "#ifndef ATTR_NAME" << "\n"; 4144 OS << "#define ATTR_NAME(NAME) NAME" << "\n"; 4145 OS << "#endif" << "\n" << "\n"; 4146 for (const auto &AttrName : AttrSpellingList) { 4147 OS << "ATTR_NAME(\"" << AttrName << "\")\n"; 4148 } 4149 OS << "\n"; 4150 OS << "#undef ATTR_NAME" << "\n"; 4151 OS << "\n"; 4152 4153 OS << "#ifndef ATTR_SCOPE_NAME" << "\n"; 4154 OS << "#define ATTR_SCOPE_NAME(SCOPE_NAME) SCOPE_NAME" << "\n"; 4155 OS << "#endif" << "\n" << "\n"; 4156 for (const auto &AttrScopeName : AttrScopeSpellingList) { 4157 OS << "ATTR_SCOPE_NAME(\"" << AttrScopeName << "\")\n"; 4158 } 4159 OS << "\n"; 4160 OS << "#undef ATTR_SCOPE_NAME" << "\n"; 4161 OS << "\n"; 4162 } 4163 4164 static bool isArgVariadic(const Record &R, StringRef AttrName) { 4165 return createArgument(R, AttrName)->isVariadic(); 4166 } 4167 4168 static void emitArgInfo(const Record &R, raw_ostream &OS) { 4169 // This function will count the number of arguments specified for the 4170 // attribute and emit the number of required arguments followed by the 4171 // number of optional arguments. 4172 unsigned ArgCount = 0, OptCount = 0, ArgMemberCount = 0; 4173 bool HasVariadic = false; 4174 for (const auto *Arg : R.getValueAsListOfDefs("Args")) { 4175 // If the arg is fake, it's the user's job to supply it: general parsing 4176 // logic shouldn't need to know anything about it. 4177 if (Arg->getValueAsBit("Fake")) 4178 continue; 4179 Arg->getValueAsBit("Optional") ? ++OptCount : ++ArgCount; 4180 ++ArgMemberCount; 4181 if (!HasVariadic && isArgVariadic(*Arg, R.getName())) 4182 HasVariadic = true; 4183 } 4184 4185 // If there is a variadic argument, we will set the optional argument count 4186 // to its largest value. Since it's currently a 4-bit number, we set it to 15. 4187 OS << " /*NumArgs=*/" << ArgCount << ",\n"; 4188 OS << " /*OptArgs=*/" << (HasVariadic ? 15 : OptCount) << ",\n"; 4189 OS << " /*NumArgMembers=*/" << ArgMemberCount << ",\n"; 4190 } 4191 4192 static std::string GetDiagnosticSpelling(const Record &R) { 4193 StringRef Ret = R.getValueAsString("DiagSpelling"); 4194 if (!Ret.empty()) 4195 return Ret.str(); 4196 4197 // If we couldn't find the DiagSpelling in this object, we can check to see 4198 // if the object is one that has a base, and if it is, loop up to the Base 4199 // member recursively. 4200 if (auto Base = R.getValueAsOptionalDef(BaseFieldName)) 4201 return GetDiagnosticSpelling(*Base); 4202 4203 return ""; 4204 } 4205 4206 static std::string CalculateDiagnostic(const Record &S) { 4207 // If the SubjectList object has a custom diagnostic associated with it, 4208 // return that directly. 4209 const StringRef CustomDiag = S.getValueAsString("CustomDiag"); 4210 if (!CustomDiag.empty()) 4211 return ("\"" + Twine(CustomDiag) + "\"").str(); 4212 4213 std::vector<std::string> DiagList; 4214 for (const auto *Subject : S.getValueAsListOfDefs("Subjects")) { 4215 const Record &R = *Subject; 4216 // Get the diagnostic text from the Decl or Stmt node given. 4217 std::string V = GetDiagnosticSpelling(R); 4218 if (V.empty()) { 4219 PrintError(R.getLoc(), 4220 "Could not determine diagnostic spelling for the node: " + 4221 R.getName() + "; please add one to DeclNodes.td"); 4222 } else { 4223 // The node may contain a list of elements itself, so split the elements 4224 // by a comma, and trim any whitespace. 4225 SmallVector<StringRef, 2> Frags; 4226 SplitString(V, Frags, ","); 4227 for (auto Str : Frags) { 4228 DiagList.push_back(Str.trim().str()); 4229 } 4230 } 4231 } 4232 4233 if (DiagList.empty()) { 4234 PrintFatalError(S.getLoc(), 4235 "Could not deduce diagnostic argument for Attr subjects"); 4236 return ""; 4237 } 4238 4239 // FIXME: this is not particularly good for localization purposes and ideally 4240 // should be part of the diagnostics engine itself with some sort of list 4241 // specifier. 4242 4243 // A single member of the list can be returned directly. 4244 if (DiagList.size() == 1) 4245 return '"' + DiagList.front() + '"'; 4246 4247 if (DiagList.size() == 2) 4248 return '"' + DiagList[0] + " and " + DiagList[1] + '"'; 4249 4250 // If there are more than two in the list, we serialize the first N - 1 4251 // elements with a comma. This leaves the string in the state: foo, bar, 4252 // baz (but misses quux). We can then add ", and " for the last element 4253 // manually. 4254 std::string Diag = join(DiagList.begin(), DiagList.end() - 1, ", "); 4255 return '"' + Diag + ", and " + *(DiagList.end() - 1) + '"'; 4256 } 4257 4258 static std::string GetSubjectWithSuffix(const Record *R) { 4259 const std::string B = R->getName().str(); 4260 if (B == "DeclBase") 4261 return "Decl"; 4262 return B + "Decl"; 4263 } 4264 4265 static std::string functionNameForCustomAppertainsTo(const Record &Subject) { 4266 return "is" + Subject.getName().str(); 4267 } 4268 4269 static void GenerateCustomAppertainsTo(const Record &Subject, raw_ostream &OS) { 4270 std::string FnName = functionNameForCustomAppertainsTo(Subject); 4271 4272 // If this code has already been generated, we don't need to do anything. 4273 static std::set<std::string> CustomSubjectSet; 4274 auto I = CustomSubjectSet.find(FnName); 4275 if (I != CustomSubjectSet.end()) 4276 return; 4277 4278 // This only works with non-root Decls. 4279 const Record *Base = Subject.getValueAsDef(BaseFieldName); 4280 4281 // Not currently support custom subjects within custom subjects. 4282 if (Base->isSubClassOf("SubsetSubject")) { 4283 PrintFatalError(Subject.getLoc(), 4284 "SubsetSubjects within SubsetSubjects is not supported"); 4285 return; 4286 } 4287 4288 OS << "static bool " << FnName << "(const Decl *D) {\n"; 4289 OS << " if (const auto *S = dyn_cast<"; 4290 OS << GetSubjectWithSuffix(Base); 4291 OS << ">(D))\n"; 4292 OS << " return " << Subject.getValueAsString("CheckCode") << ";\n"; 4293 OS << " return false;\n"; 4294 OS << "}\n\n"; 4295 4296 CustomSubjectSet.insert(FnName); 4297 } 4298 4299 static void GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) { 4300 // If the attribute does not contain a Subjects definition, then use the 4301 // default appertainsTo logic. 4302 if (Attr.isValueUnset("Subjects")) 4303 return; 4304 4305 const Record *SubjectObj = Attr.getValueAsDef("Subjects"); 4306 std::vector<const Record *> Subjects = 4307 SubjectObj->getValueAsListOfDefs("Subjects"); 4308 4309 // If the list of subjects is empty, it is assumed that the attribute 4310 // appertains to everything. 4311 if (Subjects.empty()) 4312 return; 4313 4314 bool Warn = SubjectObj->getValueAsDef("Diag")->getValueAsBit("Warn"); 4315 4316 // Split the subjects into declaration subjects and statement subjects. 4317 // FIXME: subset subjects are added to the declaration list until there are 4318 // enough statement attributes with custom subject needs to warrant 4319 // the implementation effort. 4320 std::vector<const Record *> DeclSubjects, StmtSubjects; 4321 copy_if(Subjects, std::back_inserter(DeclSubjects), [](const Record *R) { 4322 return R->isSubClassOf("SubsetSubject") || !R->isSubClassOf("StmtNode"); 4323 }); 4324 copy_if(Subjects, std::back_inserter(StmtSubjects), 4325 [](const Record *R) { return R->isSubClassOf("StmtNode"); }); 4326 4327 // We should have sorted all of the subjects into two lists. 4328 // FIXME: this assertion will be wrong if we ever add type attribute subjects. 4329 assert(DeclSubjects.size() + StmtSubjects.size() == Subjects.size()); 4330 4331 if (DeclSubjects.empty()) { 4332 // If there are no decl subjects but there are stmt subjects, diagnose 4333 // trying to apply a statement attribute to a declaration. 4334 if (!StmtSubjects.empty()) { 4335 OS << "bool diagAppertainsToDecl(Sema &S, const ParsedAttr &AL, "; 4336 OS << "const Decl *D) const override {\n"; 4337 OS << " S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)\n"; 4338 OS << " << AL << AL.isRegularKeywordAttribute() << " 4339 "D->getLocation();\n"; 4340 OS << " return false;\n"; 4341 OS << "}\n\n"; 4342 } 4343 } else { 4344 // Otherwise, generate an appertainsTo check specific to this attribute 4345 // which checks all of the given subjects against the Decl passed in. 4346 OS << "bool diagAppertainsToDecl(Sema &S, "; 4347 OS << "const ParsedAttr &Attr, const Decl *D) const override {\n"; 4348 OS << " if ("; 4349 for (auto I = DeclSubjects.begin(), E = DeclSubjects.end(); I != E; ++I) { 4350 // If the subject has custom code associated with it, use the generated 4351 // function for it. The function cannot be inlined into this check (yet) 4352 // because it requires the subject to be of a specific type, and were that 4353 // information inlined here, it would not support an attribute with 4354 // multiple custom subjects. 4355 if ((*I)->isSubClassOf("SubsetSubject")) 4356 OS << "!" << functionNameForCustomAppertainsTo(**I) << "(D)"; 4357 else 4358 OS << "!isa<" << GetSubjectWithSuffix(*I) << ">(D)"; 4359 4360 if (I + 1 != E) 4361 OS << " && "; 4362 } 4363 OS << ") {\n"; 4364 OS << " S.Diag(Attr.getLoc(), diag::"; 4365 OS << (Warn ? "warn_attribute_wrong_decl_type_str" 4366 : "err_attribute_wrong_decl_type_str"); 4367 OS << ")\n"; 4368 OS << " << Attr << Attr.isRegularKeywordAttribute() << "; 4369 OS << CalculateDiagnostic(*SubjectObj) << ";\n"; 4370 OS << " return false;\n"; 4371 OS << " }\n"; 4372 OS << " return true;\n"; 4373 OS << "}\n\n"; 4374 } 4375 4376 if (StmtSubjects.empty()) { 4377 // If there are no stmt subjects but there are decl subjects, diagnose 4378 // trying to apply a declaration attribute to a statement. 4379 if (!DeclSubjects.empty()) { 4380 OS << "bool diagAppertainsToStmt(Sema &S, const ParsedAttr &AL, "; 4381 OS << "const Stmt *St) const override {\n"; 4382 OS << " S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n"; 4383 OS << " << AL << AL.isRegularKeywordAttribute() << " 4384 "St->getBeginLoc();\n"; 4385 OS << " return false;\n"; 4386 OS << "}\n\n"; 4387 } 4388 } else { 4389 // Now, do the same for statements. 4390 OS << "bool diagAppertainsToStmt(Sema &S, "; 4391 OS << "const ParsedAttr &Attr, const Stmt *St) const override {\n"; 4392 OS << " if ("; 4393 for (auto I = StmtSubjects.begin(), E = StmtSubjects.end(); I != E; ++I) { 4394 OS << "!isa<" << (*I)->getName() << ">(St)"; 4395 if (I + 1 != E) 4396 OS << " && "; 4397 } 4398 OS << ") {\n"; 4399 OS << " S.Diag(Attr.getLoc(), diag::"; 4400 OS << (Warn ? "warn_attribute_wrong_decl_type_str" 4401 : "err_attribute_wrong_decl_type_str"); 4402 OS << ")\n"; 4403 OS << " << Attr << Attr.isRegularKeywordAttribute() << "; 4404 OS << CalculateDiagnostic(*SubjectObj) << ";\n"; 4405 OS << " return false;\n"; 4406 OS << " }\n"; 4407 OS << " return true;\n"; 4408 OS << "}\n\n"; 4409 } 4410 } 4411 4412 // Generates the mutual exclusion checks. The checks for parsed attributes are 4413 // written into OS and the checks for merging declaration attributes are 4414 // written into MergeOS. 4415 static void GenerateMutualExclusionsChecks(const Record &Attr, 4416 const RecordKeeper &Records, 4417 raw_ostream &OS, 4418 raw_ostream &MergeDeclOS, 4419 raw_ostream &MergeStmtOS) { 4420 // We don't do any of this magic for type attributes yet. 4421 if (Attr.isSubClassOf("TypeAttr")) 4422 return; 4423 4424 // This means the attribute is either a statement attribute, a decl 4425 // attribute, or both; find out which. 4426 bool CurAttrIsStmtAttr = Attr.isSubClassOf("StmtAttr") || 4427 Attr.isSubClassOf("DeclOrStmtAttr") || 4428 Attr.isSubClassOf("InheritableParamOrStmtAttr"); 4429 bool CurAttrIsDeclAttr = !CurAttrIsStmtAttr || 4430 Attr.isSubClassOf("DeclOrStmtAttr") || 4431 Attr.isSubClassOf("InheritableParamOrStmtAttr"); 4432 4433 std::vector<std::string> DeclAttrs, StmtAttrs; 4434 4435 // Find all of the definitions that inherit from MutualExclusions and include 4436 // the given attribute in the list of exclusions to generate the 4437 // diagMutualExclusion() check. 4438 for (const Record *Exclusion : 4439 Records.getAllDerivedDefinitions("MutualExclusions")) { 4440 std::vector<const Record *> MutuallyExclusiveAttrs = 4441 Exclusion->getValueAsListOfDefs("Exclusions"); 4442 auto IsCurAttr = [Attr](const Record *R) { 4443 return R->getName() == Attr.getName(); 4444 }; 4445 if (any_of(MutuallyExclusiveAttrs, IsCurAttr)) { 4446 // This list of exclusions includes the attribute we're looking for, so 4447 // add the exclusive attributes to the proper list for checking. 4448 for (const Record *AttrToExclude : MutuallyExclusiveAttrs) { 4449 if (IsCurAttr(AttrToExclude)) 4450 continue; 4451 4452 if (CurAttrIsStmtAttr) 4453 StmtAttrs.push_back((AttrToExclude->getName() + "Attr").str()); 4454 if (CurAttrIsDeclAttr) 4455 DeclAttrs.push_back((AttrToExclude->getName() + "Attr").str()); 4456 } 4457 } 4458 } 4459 4460 // If there are any decl or stmt attributes, silence -Woverloaded-virtual 4461 // warnings for them both. 4462 if (!DeclAttrs.empty() || !StmtAttrs.empty()) 4463 OS << " using ParsedAttrInfo::diagMutualExclusion;\n\n"; 4464 4465 // If we discovered any decl or stmt attributes to test for, generate the 4466 // predicates for them now. 4467 if (!DeclAttrs.empty()) { 4468 // Generate the ParsedAttrInfo subclass logic for declarations. 4469 OS << " bool diagMutualExclusion(Sema &S, const ParsedAttr &AL, " 4470 << "const Decl *D) const override {\n"; 4471 for (const std::string &A : DeclAttrs) { 4472 OS << " if (const auto *A = D->getAttr<" << A << ">()) {\n"; 4473 OS << " S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)" 4474 << " << AL << A << (AL.isRegularKeywordAttribute() ||" 4475 << " A->isRegularKeywordAttribute());\n"; 4476 OS << " S.Diag(A->getLocation(), diag::note_conflicting_attribute);"; 4477 OS << " \nreturn false;\n"; 4478 OS << " }\n"; 4479 } 4480 OS << " return true;\n"; 4481 OS << " }\n\n"; 4482 4483 // Also generate the declaration attribute merging logic if the current 4484 // attribute is one that can be inheritted on a declaration. It is assumed 4485 // this code will be executed in the context of a function with parameters: 4486 // Sema &S, Decl *D, Attr *A and that returns a bool (false on diagnostic, 4487 // true on success). 4488 if (Attr.isSubClassOf("InheritableAttr")) { 4489 MergeDeclOS << " if (const auto *Second = dyn_cast<" 4490 << (Attr.getName() + "Attr").str() << ">(A)) {\n"; 4491 for (const std::string &A : DeclAttrs) { 4492 MergeDeclOS << " if (const auto *First = D->getAttr<" << A 4493 << ">()) {\n"; 4494 MergeDeclOS << " S.Diag(First->getLocation(), " 4495 << "diag::err_attributes_are_not_compatible) << First << " 4496 << "Second << (First->isRegularKeywordAttribute() || " 4497 << "Second->isRegularKeywordAttribute());\n"; 4498 MergeDeclOS << " S.Diag(Second->getLocation(), " 4499 << "diag::note_conflicting_attribute);\n"; 4500 MergeDeclOS << " return false;\n"; 4501 MergeDeclOS << " }\n"; 4502 } 4503 MergeDeclOS << " return true;\n"; 4504 MergeDeclOS << " }\n"; 4505 } 4506 } 4507 4508 // Statement attributes are a bit different from declarations. With 4509 // declarations, each attribute is added to the declaration as it is 4510 // processed, and so you can look on the Decl * itself to see if there is a 4511 // conflicting attribute. Statement attributes are processed as a group 4512 // because AttributedStmt needs to tail-allocate all of the attribute nodes 4513 // at once. This means we cannot check whether the statement already contains 4514 // an attribute to check for the conflict. Instead, we need to check whether 4515 // the given list of semantic attributes contain any conflicts. It is assumed 4516 // this code will be executed in the context of a function with parameters: 4517 // Sema &S, const SmallVectorImpl<const Attr *> &C. The code will be within a 4518 // loop which loops over the container C with a loop variable named A to 4519 // represent the current attribute to check for conflicts. 4520 // 4521 // FIXME: it would be nice not to walk over the list of potential attributes 4522 // to apply to the statement more than once, but statements typically don't 4523 // have long lists of attributes on them, so re-walking the list should not 4524 // be an expensive operation. 4525 if (!StmtAttrs.empty()) { 4526 MergeStmtOS << " if (const auto *Second = dyn_cast<" 4527 << (Attr.getName() + "Attr").str() << ">(A)) {\n"; 4528 MergeStmtOS << " auto Iter = llvm::find_if(C, [](const Attr *Check) " 4529 << "{ return isa<"; 4530 interleave( 4531 StmtAttrs, [&](StringRef Name) { MergeStmtOS << Name; }, 4532 [&] { MergeStmtOS << ", "; }); 4533 MergeStmtOS << ">(Check); });\n"; 4534 MergeStmtOS << " if (Iter != C.end()) {\n"; 4535 MergeStmtOS << " S.Diag((*Iter)->getLocation(), " 4536 << "diag::err_attributes_are_not_compatible) << *Iter << " 4537 << "Second << ((*Iter)->isRegularKeywordAttribute() || " 4538 << "Second->isRegularKeywordAttribute());\n"; 4539 MergeStmtOS << " S.Diag(Second->getLocation(), " 4540 << "diag::note_conflicting_attribute);\n"; 4541 MergeStmtOS << " return false;\n"; 4542 MergeStmtOS << " }\n"; 4543 MergeStmtOS << " }\n"; 4544 } 4545 } 4546 4547 static void 4548 emitAttributeMatchRules(PragmaClangAttributeSupport &PragmaAttributeSupport, 4549 raw_ostream &OS) { 4550 OS << "static bool checkAttributeMatchRuleAppliesTo(const Decl *D, " 4551 << AttributeSubjectMatchRule::EnumName << " rule) {\n"; 4552 OS << " switch (rule) {\n"; 4553 for (const auto &Rule : PragmaAttributeSupport.Rules) { 4554 if (Rule.isAbstractRule()) { 4555 OS << " case " << Rule.getEnumValue() << ":\n"; 4556 OS << " assert(false && \"Abstract matcher rule isn't allowed\");\n"; 4557 OS << " return false;\n"; 4558 continue; 4559 } 4560 std::vector<const Record *> Subjects = Rule.getSubjects(); 4561 assert(!Subjects.empty() && "Missing subjects"); 4562 OS << " case " << Rule.getEnumValue() << ":\n"; 4563 OS << " return "; 4564 for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) { 4565 // If the subject has custom code associated with it, use the function 4566 // that was generated for GenerateAppertainsTo to check if the declaration 4567 // is valid. 4568 if ((*I)->isSubClassOf("SubsetSubject")) 4569 OS << functionNameForCustomAppertainsTo(**I) << "(D)"; 4570 else 4571 OS << "isa<" << GetSubjectWithSuffix(*I) << ">(D)"; 4572 4573 if (I + 1 != E) 4574 OS << " || "; 4575 } 4576 OS << ";\n"; 4577 } 4578 OS << " }\n"; 4579 OS << " llvm_unreachable(\"Invalid match rule\");\nreturn false;\n"; 4580 OS << "}\n\n"; 4581 } 4582 4583 static void GenerateLangOptRequirements(const Record &R, 4584 raw_ostream &OS) { 4585 // If the attribute has an empty or unset list of language requirements, 4586 // use the default handler. 4587 std::vector<const Record *> LangOpts = R.getValueAsListOfDefs("LangOpts"); 4588 if (LangOpts.empty()) 4589 return; 4590 4591 OS << "bool acceptsLangOpts(const LangOptions &LangOpts) const override {\n"; 4592 OS << " return " << GenerateTestExpression(LangOpts) << ";\n"; 4593 OS << "}\n\n"; 4594 } 4595 4596 static void GenerateTargetRequirements(const Record &Attr, 4597 const ParsedAttrMap &Dupes, 4598 raw_ostream &OS) { 4599 // If the attribute is not a target specific attribute, use the default 4600 // target handler. 4601 if (!Attr.isSubClassOf("TargetSpecificAttr")) 4602 return; 4603 4604 // Get the list of architectures to be tested for. 4605 const Record *R = Attr.getValueAsDef("Target"); 4606 std::vector<StringRef> Arches = R->getValueAsListOfStrings("Arches"); 4607 4608 // If there are other attributes which share the same parsed attribute kind, 4609 // such as target-specific attributes with a shared spelling, collapse the 4610 // duplicate architectures. This is required because a shared target-specific 4611 // attribute has only one ParsedAttr::Kind enumeration value, but it 4612 // applies to multiple target architectures. In order for the attribute to be 4613 // considered valid, all of its architectures need to be included. 4614 if (!Attr.isValueUnset("ParseKind")) { 4615 const StringRef APK = Attr.getValueAsString("ParseKind"); 4616 for (const auto &I : Dupes) { 4617 if (I.first == APK) { 4618 std::vector<StringRef> DA = 4619 I.second->getValueAsDef("Target")->getValueAsListOfStrings( 4620 "Arches"); 4621 llvm::append_range(Arches, DA); 4622 } 4623 } 4624 } 4625 4626 std::string FnName = "isTarget"; 4627 std::string Test; 4628 bool UsesT = GenerateTargetSpecificAttrChecks(R, Arches, Test, &FnName); 4629 4630 OS << "bool existsInTarget(const TargetInfo &Target) const override {\n"; 4631 if (UsesT) 4632 OS << " const llvm::Triple &T = Target.getTriple(); (void)T;\n"; 4633 OS << " return " << Test << ";\n"; 4634 OS << "}\n\n"; 4635 } 4636 4637 static void 4638 GenerateSpellingTargetRequirements(const Record &Attr, 4639 ArrayRef<const Record *> TargetSpellings, 4640 raw_ostream &OS) { 4641 // If there are no target specific spellings, use the default target handler. 4642 if (TargetSpellings.empty()) 4643 return; 4644 4645 std::string Test; 4646 bool UsesT = false; 4647 const std::vector<FlattenedSpelling> SpellingList = 4648 GetFlattenedSpellings(Attr); 4649 for (unsigned TargetIndex = 0; TargetIndex < TargetSpellings.size(); 4650 ++TargetIndex) { 4651 const auto &TargetSpelling = TargetSpellings[TargetIndex]; 4652 std::vector<FlattenedSpelling> Spellings = 4653 GetFlattenedSpellings(*TargetSpelling); 4654 4655 Test += "((SpellingListIndex == "; 4656 for (unsigned Index = 0; Index < Spellings.size(); ++Index) { 4657 Test += itostr(getSpellingListIndex(SpellingList, Spellings[Index])); 4658 if (Index != Spellings.size() - 1) 4659 Test += " ||\n SpellingListIndex == "; 4660 else 4661 Test += ") && "; 4662 } 4663 4664 const Record *Target = TargetSpelling->getValueAsDef("Target"); 4665 std::vector<StringRef> Arches = Target->getValueAsListOfStrings("Arches"); 4666 std::string FnName = "isTargetSpelling"; 4667 UsesT |= GenerateTargetSpecificAttrChecks(Target, Arches, Test, &FnName); 4668 Test += ")"; 4669 if (TargetIndex != TargetSpellings.size() - 1) 4670 Test += " || "; 4671 } 4672 4673 OS << "bool spellingExistsInTarget(const TargetInfo &Target,\n"; 4674 OS << " const unsigned SpellingListIndex) const " 4675 "override {\n"; 4676 if (UsesT) 4677 OS << " const llvm::Triple &T = Target.getTriple(); (void)T;\n"; 4678 OS << " return " << Test << ";\n", OS << "}\n\n"; 4679 } 4680 4681 static void GenerateSpellingIndexToSemanticSpelling(const Record &Attr, 4682 raw_ostream &OS) { 4683 // If the attribute does not have a semantic form, we can bail out early. 4684 if (!Attr.getValueAsBit("ASTNode")) 4685 return; 4686 4687 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr); 4688 4689 // If there are zero or one spellings, or all of the spellings share the same 4690 // name, we can also bail out early. 4691 if (Spellings.size() <= 1 || SpellingNamesAreCommon(Spellings)) 4692 return; 4693 4694 // Generate the enumeration we will use for the mapping. 4695 SemanticSpellingMap SemanticToSyntacticMap; 4696 std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap); 4697 4698 OS << "unsigned spellingIndexToSemanticSpelling("; 4699 OS << "const ParsedAttr &Attr) const override {\n"; 4700 OS << Enum; 4701 OS << " unsigned Idx = Attr.getAttributeSpellingListIndex();\n"; 4702 WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS); 4703 OS << "}\n\n"; 4704 } 4705 4706 static void GenerateHandleDeclAttribute(const Record &Attr, raw_ostream &OS) { 4707 // Only generate if Attr can be handled simply. 4708 if (!Attr.getValueAsBit("SimpleHandler")) 4709 return; 4710 4711 // Generate a function which just converts from ParsedAttr to the Attr type. 4712 OS << "AttrHandling handleDeclAttribute(Sema &S, Decl *D,"; 4713 OS << "const ParsedAttr &Attr) const override {\n"; 4714 OS << " D->addAttr(::new (S.Context) " << Attr.getName(); 4715 OS << "Attr(S.Context, Attr));\n"; 4716 OS << " return AttributeApplied;\n"; 4717 OS << "}\n\n"; 4718 } 4719 4720 static bool isParamExpr(const Record *Arg) { 4721 return !Arg->getDirectSuperClasses().empty() && 4722 StringSwitch<bool>( 4723 Arg->getDirectSuperClasses().back().first->getName()) 4724 .Case("ExprArgument", true) 4725 .Case("VariadicExprArgument", true) 4726 .Default(false); 4727 } 4728 4729 static void GenerateIsParamExpr(const Record &Attr, raw_ostream &OS) { 4730 OS << "bool isParamExpr(size_t N) const override {\n"; 4731 OS << " return "; 4732 auto Args = Attr.getValueAsListOfDefs("Args"); 4733 for (size_t I = 0; I < Args.size(); ++I) 4734 if (isParamExpr(Args[I])) 4735 OS << "(N == " << I << ") || "; 4736 OS << "false;\n"; 4737 OS << "}\n\n"; 4738 } 4739 4740 static void GenerateHandleAttrWithDelayedArgs(const RecordKeeper &Records, 4741 raw_ostream &OS) { 4742 OS << "static void handleAttrWithDelayedArgs(Sema &S, Decl *D, "; 4743 OS << "const ParsedAttr &Attr) {\n"; 4744 OS << " SmallVector<Expr *, 4> ArgExprs;\n"; 4745 OS << " ArgExprs.reserve(Attr.getNumArgs());\n"; 4746 OS << " for (unsigned I = 0; I < Attr.getNumArgs(); ++I) {\n"; 4747 OS << " assert(!Attr.isArgIdent(I));\n"; 4748 OS << " ArgExprs.push_back(Attr.getArgAsExpr(I));\n"; 4749 OS << " }\n"; 4750 OS << " clang::Attr *CreatedAttr = nullptr;\n"; 4751 OS << " switch (Attr.getKind()) {\n"; 4752 OS << " default:\n"; 4753 OS << " llvm_unreachable(\"Attribute cannot hold delayed arguments.\");\n"; 4754 ParsedAttrMap Attrs = getParsedAttrList(Records); 4755 for (const auto &I : Attrs) { 4756 const Record &R = *I.second; 4757 if (!R.getValueAsBit("AcceptsExprPack")) 4758 continue; 4759 OS << " case ParsedAttr::AT_" << I.first << ": {\n"; 4760 OS << " CreatedAttr = " << R.getName() << "Attr::CreateWithDelayedArgs"; 4761 OS << "(S.Context, ArgExprs.data(), ArgExprs.size(), Attr);\n"; 4762 OS << " break;\n"; 4763 OS << " }\n"; 4764 } 4765 OS << " }\n"; 4766 OS << " D->addAttr(CreatedAttr);\n"; 4767 OS << "}\n\n"; 4768 } 4769 4770 static bool IsKnownToGCC(const Record &Attr) { 4771 // Look at the spellings for this subject; if there are any spellings which 4772 // claim to be known to GCC, the attribute is known to GCC. 4773 return any_of(GetFlattenedSpellings(Attr), 4774 [](const FlattenedSpelling &S) { return S.knownToGCC(); }); 4775 } 4776 4777 /// Emits the parsed attribute helpers 4778 void EmitClangAttrParsedAttrImpl(const RecordKeeper &Records, raw_ostream &OS) { 4779 emitSourceFileHeader("Parsed attribute helpers", OS, Records); 4780 4781 OS << "#if !defined(WANT_DECL_MERGE_LOGIC) && " 4782 << "!defined(WANT_STMT_MERGE_LOGIC)\n"; 4783 PragmaClangAttributeSupport &PragmaAttributeSupport = 4784 getPragmaAttributeSupport(Records); 4785 4786 // Get the list of parsed attributes, and accept the optional list of 4787 // duplicates due to the ParseKind. 4788 ParsedAttrMap Dupes; 4789 ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes); 4790 4791 // Generate all of the custom appertainsTo functions that the attributes 4792 // will be using. 4793 for (const auto &I : Attrs) { 4794 const Record &Attr = *I.second; 4795 if (Attr.isValueUnset("Subjects")) 4796 continue; 4797 const Record *SubjectObj = Attr.getValueAsDef("Subjects"); 4798 for (const Record *Subject : SubjectObj->getValueAsListOfDefs("Subjects")) 4799 if (Subject->isSubClassOf("SubsetSubject")) 4800 GenerateCustomAppertainsTo(*Subject, OS); 4801 } 4802 4803 // This stream is used to collect all of the declaration attribute merging 4804 // logic for performing mutual exclusion checks. This gets emitted at the 4805 // end of the file in a helper function of its own. 4806 std::string DeclMergeChecks, StmtMergeChecks; 4807 raw_string_ostream MergeDeclOS(DeclMergeChecks), MergeStmtOS(StmtMergeChecks); 4808 4809 // Generate a ParsedAttrInfo struct for each of the attributes. 4810 for (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { 4811 // TODO: If the attribute's kind appears in the list of duplicates, that is 4812 // because it is a target-specific attribute that appears multiple times. 4813 // It would be beneficial to test whether the duplicates are "similar 4814 // enough" to each other to not cause problems. For instance, check that 4815 // the spellings are identical, and custom parsing rules match, etc. 4816 4817 // We need to generate struct instances based off ParsedAttrInfo from 4818 // ParsedAttr.cpp. 4819 const std::string &AttrName = I->first; 4820 const Record &Attr = *I->second; 4821 auto Spellings = GetFlattenedSpellings(Attr); 4822 if (!Spellings.empty()) { 4823 OS << "static constexpr ParsedAttrInfo::Spelling " << I->first 4824 << "Spellings[] = {\n"; 4825 for (const auto &S : Spellings) { 4826 StringRef RawSpelling = S.name(); 4827 std::string Spelling; 4828 if (!S.nameSpace().empty()) 4829 Spelling += S.nameSpace().str() + "::"; 4830 if (S.variety() == "GNU") 4831 Spelling += NormalizeGNUAttrSpelling(RawSpelling); 4832 else 4833 Spelling += RawSpelling; 4834 OS << " {AttributeCommonInfo::AS_" << S.variety(); 4835 OS << ", \"" << Spelling << "\"},\n"; 4836 } 4837 OS << "};\n"; 4838 } 4839 4840 std::vector<std::string> ArgNames; 4841 for (const auto *Arg : Attr.getValueAsListOfDefs("Args")) { 4842 bool UnusedUnset; 4843 if (Arg->getValueAsBitOrUnset("Fake", UnusedUnset)) 4844 continue; 4845 ArgNames.push_back(Arg->getValueAsString("Name").str()); 4846 for (const Record *Class : Arg->getSuperClasses()) { 4847 if (Class->getName().starts_with("Variadic")) { 4848 ArgNames.back().append("..."); 4849 break; 4850 } 4851 } 4852 } 4853 if (!ArgNames.empty()) { 4854 OS << "static constexpr const char *" << I->first << "ArgNames[] = {\n"; 4855 for (const auto &N : ArgNames) 4856 OS << '"' << N << "\","; 4857 OS << "};\n"; 4858 } 4859 4860 OS << "struct ParsedAttrInfo" << I->first 4861 << " final : public ParsedAttrInfo {\n"; 4862 OS << " constexpr ParsedAttrInfo" << I->first << "() : ParsedAttrInfo(\n"; 4863 OS << " /*AttrKind=*/ParsedAttr::AT_" << AttrName << ",\n"; 4864 emitArgInfo(Attr, OS); 4865 OS << " /*HasCustomParsing=*/"; 4866 OS << Attr.getValueAsBit("HasCustomParsing") << ",\n"; 4867 OS << " /*AcceptsExprPack=*/"; 4868 OS << Attr.getValueAsBit("AcceptsExprPack") << ",\n"; 4869 OS << " /*IsTargetSpecific=*/"; 4870 OS << Attr.isSubClassOf("TargetSpecificAttr") << ",\n"; 4871 OS << " /*IsType=*/"; 4872 OS << (Attr.isSubClassOf("TypeAttr") || Attr.isSubClassOf("DeclOrTypeAttr")) 4873 << ",\n"; 4874 OS << " /*IsStmt=*/"; 4875 OS << (Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr")) 4876 << ",\n"; 4877 OS << " /*IsKnownToGCC=*/"; 4878 OS << IsKnownToGCC(Attr) << ",\n"; 4879 OS << " /*IsSupportedByPragmaAttribute=*/"; 4880 OS << PragmaAttributeSupport.isAttributedSupported(*I->second) << ",\n"; 4881 if (!Spellings.empty()) 4882 OS << " /*Spellings=*/" << I->first << "Spellings,\n"; 4883 else 4884 OS << " /*Spellings=*/{},\n"; 4885 if (!ArgNames.empty()) 4886 OS << " /*ArgNames=*/" << I->first << "ArgNames"; 4887 else 4888 OS << " /*ArgNames=*/{}"; 4889 OS << ") {}\n"; 4890 GenerateAppertainsTo(Attr, OS); 4891 GenerateMutualExclusionsChecks(Attr, Records, OS, MergeDeclOS, MergeStmtOS); 4892 GenerateLangOptRequirements(Attr, OS); 4893 GenerateTargetRequirements(Attr, Dupes, OS); 4894 GenerateSpellingTargetRequirements( 4895 Attr, Attr.getValueAsListOfDefs("TargetSpecificSpellings"), OS); 4896 GenerateSpellingIndexToSemanticSpelling(Attr, OS); 4897 PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS); 4898 GenerateHandleDeclAttribute(Attr, OS); 4899 GenerateIsParamExpr(Attr, OS); 4900 OS << "static const ParsedAttrInfo" << I->first << " Instance;\n"; 4901 OS << "};\n"; 4902 OS << "const ParsedAttrInfo" << I->first << " ParsedAttrInfo" << I->first 4903 << "::Instance;\n"; 4904 } 4905 4906 OS << "static const ParsedAttrInfo *AttrInfoMap[] = {\n"; 4907 for (const auto &Attr : Attrs) 4908 OS << "&ParsedAttrInfo" << Attr.first << "::Instance,\n"; 4909 OS << "};\n\n"; 4910 4911 // Generate function for handling attributes with delayed arguments 4912 GenerateHandleAttrWithDelayedArgs(Records, OS); 4913 4914 // Generate the attribute match rules. 4915 emitAttributeMatchRules(PragmaAttributeSupport, OS); 4916 4917 OS << "#elif defined(WANT_DECL_MERGE_LOGIC)\n\n"; 4918 4919 // Write out the declaration merging check logic. 4920 OS << "static bool DiagnoseMutualExclusions(Sema &S, const NamedDecl *D, " 4921 << "const Attr *A) {\n"; 4922 OS << DeclMergeChecks; 4923 OS << " return true;\n"; 4924 OS << "}\n\n"; 4925 4926 OS << "#elif defined(WANT_STMT_MERGE_LOGIC)\n\n"; 4927 4928 // Write out the statement merging check logic. 4929 OS << "static bool DiagnoseMutualExclusions(Sema &S, " 4930 << "const SmallVectorImpl<const Attr *> &C) {\n"; 4931 OS << " for (const Attr *A : C) {\n"; 4932 OS << StmtMergeChecks; 4933 OS << " }\n"; 4934 OS << " return true;\n"; 4935 OS << "}\n\n"; 4936 4937 OS << "#endif\n"; 4938 } 4939 4940 // Emits the kind list of parsed attributes 4941 void EmitClangAttrParsedAttrKinds(const RecordKeeper &Records, 4942 raw_ostream &OS) { 4943 emitSourceFileHeader("Attribute name matcher", OS, Records); 4944 4945 std::vector<StringMatcher::StringPair> GNU, Declspec, Microsoft, CXX11, 4946 Keywords, Pragma, C23, HLSLAnnotation; 4947 std::set<StringRef> Seen; 4948 for (const auto *A : Records.getAllDerivedDefinitions("Attr")) { 4949 const Record &Attr = *A; 4950 4951 bool SemaHandler = Attr.getValueAsBit("SemaHandler"); 4952 bool Ignored = Attr.getValueAsBit("Ignored"); 4953 if (SemaHandler || Ignored) { 4954 // Attribute spellings can be shared between target-specific attributes, 4955 // and can be shared between syntaxes for the same attribute. For 4956 // instance, an attribute can be spelled GNU<"interrupt"> for an ARM- 4957 // specific attribute, or MSP430-specific attribute. Additionally, an 4958 // attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport"> 4959 // for the same semantic attribute. Ultimately, we need to map each of 4960 // these to a single AttributeCommonInfo::Kind value, but the 4961 // StringMatcher class cannot handle duplicate match strings. So we 4962 // generate a list of string to match based on the syntax, and emit 4963 // multiple string matchers depending on the syntax used. 4964 std::string AttrName; 4965 if (Attr.isSubClassOf("TargetSpecificAttr") && 4966 !Attr.isValueUnset("ParseKind")) { 4967 StringRef ParseKind = Attr.getValueAsString("ParseKind"); 4968 if (!Seen.insert(ParseKind).second) 4969 continue; 4970 AttrName = ParseKind.str(); 4971 } else { 4972 AttrName = NormalizeAttrName(Attr.getName()).str(); 4973 } 4974 4975 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr); 4976 for (const auto &S : Spellings) { 4977 StringRef RawSpelling = S.name(); 4978 std::vector<StringMatcher::StringPair> *Matches = nullptr; 4979 std::string Spelling; 4980 StringRef Variety = S.variety(); 4981 if (Variety == "CXX11") { 4982 Matches = &CXX11; 4983 if (!S.nameSpace().empty()) 4984 Spelling += S.nameSpace().str() + "::"; 4985 } else if (Variety == "C23") { 4986 Matches = &C23; 4987 if (!S.nameSpace().empty()) 4988 Spelling += S.nameSpace().str() + "::"; 4989 } else if (Variety == "GNU") { 4990 Matches = &GNU; 4991 } else if (Variety == "Declspec") { 4992 Matches = &Declspec; 4993 } else if (Variety == "Microsoft") { 4994 Matches = &Microsoft; 4995 } else if (Variety == "Keyword") { 4996 Matches = &Keywords; 4997 } else if (Variety == "Pragma") { 4998 Matches = &Pragma; 4999 } else if (Variety == "HLSLAnnotation") { 5000 Matches = &HLSLAnnotation; 5001 if (RawSpelling.compare(RawSpelling.lower()) != 0) 5002 PrintError(S.getSpellingRecord().getLoc(), 5003 "HLSLAnnotation Attribute must be lower case."); 5004 } 5005 5006 assert(Matches && "Unsupported spelling variety found"); 5007 5008 if (Variety == "GNU") 5009 Spelling += NormalizeGNUAttrSpelling(RawSpelling); 5010 else 5011 Spelling += RawSpelling; 5012 5013 if (SemaHandler) 5014 Matches->push_back(StringMatcher::StringPair( 5015 Spelling, "return AttributeCommonInfo::AT_" + AttrName + ";")); 5016 else 5017 Matches->push_back(StringMatcher::StringPair( 5018 Spelling, "return AttributeCommonInfo::IgnoredAttribute;")); 5019 } 5020 } 5021 } 5022 5023 OS << "static AttributeCommonInfo::Kind getAttrKind(StringRef Name, "; 5024 OS << "AttributeCommonInfo::Syntax Syntax) {\n"; 5025 OS << " if (AttributeCommonInfo::AS_GNU == Syntax) {\n"; 5026 StringMatcher("Name", GNU, OS).Emit(); 5027 OS << " } else if (AttributeCommonInfo::AS_Declspec == Syntax) {\n"; 5028 StringMatcher("Name", Declspec, OS).Emit(); 5029 OS << " } else if (AttributeCommonInfo::AS_Microsoft == Syntax) {\n"; 5030 StringMatcher("Name", Microsoft, OS).Emit(); 5031 OS << " } else if (AttributeCommonInfo::AS_CXX11 == Syntax) {\n"; 5032 StringMatcher("Name", CXX11, OS).Emit(); 5033 OS << " } else if (AttributeCommonInfo::AS_C23 == Syntax) {\n"; 5034 StringMatcher("Name", C23, OS).Emit(); 5035 OS << " } else if (AttributeCommonInfo::AS_Keyword == Syntax || "; 5036 OS << "AttributeCommonInfo::AS_ContextSensitiveKeyword == Syntax) {\n"; 5037 StringMatcher("Name", Keywords, OS).Emit(); 5038 OS << " } else if (AttributeCommonInfo::AS_Pragma == Syntax) {\n"; 5039 StringMatcher("Name", Pragma, OS).Emit(); 5040 OS << " } else if (AttributeCommonInfo::AS_HLSLAnnotation == Syntax) {\n"; 5041 StringMatcher("Name", HLSLAnnotation, OS).Emit(); 5042 OS << " }\n"; 5043 OS << " return AttributeCommonInfo::UnknownAttribute;\n" 5044 << "}\n"; 5045 } 5046 5047 // Emits the code to dump an attribute. 5048 void EmitClangAttrTextNodeDump(const RecordKeeper &Records, raw_ostream &OS) { 5049 emitSourceFileHeader("Attribute text node dumper", OS, Records); 5050 5051 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 5052 const Record &R = *Attr; 5053 if (!R.getValueAsBit("ASTNode")) 5054 continue; 5055 5056 // If the attribute has a semantically-meaningful name (which is determined 5057 // by whether there is a Spelling enumeration for it), then write out the 5058 // spelling used for the attribute. 5059 5060 std::string FunctionContent; 5061 raw_string_ostream SS(FunctionContent); 5062 5063 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R); 5064 if (Spellings.size() > 1 && !SpellingNamesAreCommon(Spellings)) 5065 SS << " OS << \" \" << A->getSpelling();\n"; 5066 5067 std::vector<const Record *> Args = R.getValueAsListOfDefs("Args"); 5068 for (const auto *Arg : Args) 5069 createArgument(*Arg, R.getName())->writeDump(SS); 5070 5071 if (Attr->getValueAsBit("AcceptsExprPack")) 5072 VariadicExprArgument("DelayedArgs", R.getName()).writeDump(OS); 5073 5074 if (SS.tell()) { 5075 OS << " void Visit" << R.getName() << "Attr(const " << R.getName() 5076 << "Attr *A) {\n"; 5077 if (!Args.empty()) 5078 OS << " const auto *SA = cast<" << R.getName() 5079 << "Attr>(A); (void)SA;\n"; 5080 OS << FunctionContent; 5081 OS << " }\n"; 5082 } 5083 } 5084 } 5085 5086 void EmitClangAttrNodeTraverse(const RecordKeeper &Records, raw_ostream &OS) { 5087 emitSourceFileHeader("Attribute text node traverser", OS, Records); 5088 5089 for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) { 5090 const Record &R = *Attr; 5091 if (!R.getValueAsBit("ASTNode")) 5092 continue; 5093 5094 std::string FunctionContent; 5095 raw_string_ostream SS(FunctionContent); 5096 5097 std::vector<const Record *> Args = R.getValueAsListOfDefs("Args"); 5098 for (const auto *Arg : Args) 5099 createArgument(*Arg, R.getName())->writeDumpChildren(SS); 5100 if (Attr->getValueAsBit("AcceptsExprPack")) 5101 VariadicExprArgument("DelayedArgs", R.getName()).writeDumpChildren(SS); 5102 if (SS.tell()) { 5103 OS << " void Visit" << R.getName() << "Attr(const " << R.getName() 5104 << "Attr *A) {\n"; 5105 if (!Args.empty()) 5106 OS << " const auto *SA = cast<" << R.getName() 5107 << "Attr>(A); (void)SA;\n"; 5108 OS << FunctionContent; 5109 OS << " }\n"; 5110 } 5111 } 5112 } 5113 5114 void EmitClangAttrParserStringSwitches(const RecordKeeper &Records, 5115 raw_ostream &OS) { 5116 generateNameToAttrsMap(Records); 5117 emitSourceFileHeader("Parser-related llvm::StringSwitch cases", OS, Records); 5118 emitClangAttrArgContextList(Records, OS); 5119 emitClangAttrIdentifierArgList(Records, OS); 5120 emitClangAttrUnevaluatedStringLiteralList(Records, OS); 5121 emitClangAttrVariadicIdentifierArgList(Records, OS); 5122 emitClangAttrThisIsaIdentifierArgList(Records, OS); 5123 emitClangAttrAcceptsExprPack(Records, OS); 5124 emitClangAttrTypeArgList(Records, OS); 5125 emitClangAttrLateParsedList(Records, OS); 5126 emitClangAttrLateParsedExperimentalList(Records, OS); 5127 emitClangAttrStrictIdentifierArgList(Records, OS); 5128 } 5129 5130 void EmitClangAttrSubjectMatchRulesParserStringSwitches( 5131 const RecordKeeper &Records, raw_ostream &OS) { 5132 getPragmaAttributeSupport(Records).generateParsingHelpers(OS); 5133 } 5134 5135 void EmitClangAttrDocTable(const RecordKeeper &Records, raw_ostream &OS) { 5136 emitSourceFileHeader("Clang attribute documentation", OS, Records); 5137 5138 for (const auto *A : Records.getAllDerivedDefinitions("Attr")) { 5139 if (!A->getValueAsBit("ASTNode")) 5140 continue; 5141 std::vector<const Record *> Docs = A->getValueAsListOfDefs("Documentation"); 5142 assert(!Docs.empty()); 5143 // Only look at the first documentation if there are several. 5144 // (Currently there's only one such attr, revisit if this becomes common). 5145 StringRef Text = 5146 Docs.front()->getValueAsOptionalString("Content").value_or(""); 5147 OS << "\nstatic const char AttrDoc_" << A->getName() << "[] = " 5148 << "R\"reST(" << Text.trim() << ")reST\";\n"; 5149 } 5150 } 5151 5152 enum class SpellingKind : size_t { 5153 GNU, 5154 CXX11, 5155 C23, 5156 Declspec, 5157 Microsoft, 5158 Keyword, 5159 Pragma, 5160 HLSLAnnotation, 5161 NumSpellingKinds 5162 }; 5163 static const size_t NumSpellingKinds = (size_t)SpellingKind::NumSpellingKinds; 5164 5165 class SpellingList { 5166 std::vector<std::string> Spellings[NumSpellingKinds]; 5167 5168 public: 5169 ArrayRef<std::string> operator[](SpellingKind K) const { 5170 return Spellings[(size_t)K]; 5171 } 5172 5173 void add(const Record &Attr, FlattenedSpelling Spelling) { 5174 SpellingKind Kind = 5175 StringSwitch<SpellingKind>(Spelling.variety()) 5176 .Case("GNU", SpellingKind::GNU) 5177 .Case("CXX11", SpellingKind::CXX11) 5178 .Case("C23", SpellingKind::C23) 5179 .Case("Declspec", SpellingKind::Declspec) 5180 .Case("Microsoft", SpellingKind::Microsoft) 5181 .Case("Keyword", SpellingKind::Keyword) 5182 .Case("Pragma", SpellingKind::Pragma) 5183 .Case("HLSLAnnotation", SpellingKind::HLSLAnnotation); 5184 std::string Name; 5185 StringRef NameSpace = Spelling.nameSpace(); 5186 if (!NameSpace.empty()) { 5187 Name = NameSpace; 5188 switch (Kind) { 5189 case SpellingKind::CXX11: 5190 case SpellingKind::C23: 5191 Name += "::"; 5192 break; 5193 case SpellingKind::Pragma: 5194 Name = " "; 5195 break; 5196 default: 5197 PrintFatalError(Attr.getLoc(), "Unexpected namespace in spelling"); 5198 } 5199 } 5200 Name += Spelling.name(); 5201 5202 Spellings[(size_t)Kind].push_back(Name); 5203 } 5204 5205 void merge(const SpellingList &Other) { 5206 for (size_t Kind = 0; Kind < NumSpellingKinds; ++Kind) { 5207 Spellings[Kind].insert(Spellings[Kind].end(), 5208 Other.Spellings[Kind].begin(), 5209 Other.Spellings[Kind].end()); 5210 } 5211 } 5212 }; 5213 5214 class DocumentationData { 5215 public: 5216 const Record *Documentation; 5217 const Record *Attribute; 5218 std::string Heading; 5219 SpellingList SupportedSpellings; 5220 5221 DocumentationData(const Record &Documentation, const Record &Attribute, 5222 std::pair<std::string, SpellingList> HeadingAndSpellings) 5223 : Documentation(&Documentation), Attribute(&Attribute), 5224 Heading(std::move(HeadingAndSpellings.first)), 5225 SupportedSpellings(std::move(HeadingAndSpellings.second)) {} 5226 }; 5227 5228 static void WriteCategoryHeader(const Record *DocCategory, 5229 raw_ostream &OS) { 5230 const StringRef Name = DocCategory->getValueAsString("Name"); 5231 OS << Name << "\n" << std::string(Name.size(), '=') << "\n"; 5232 5233 // If there is content, print that as well. 5234 const StringRef ContentStr = DocCategory->getValueAsString("Content"); 5235 // Trim leading and trailing newlines and spaces. 5236 OS << ContentStr.trim(); 5237 5238 OS << "\n\n"; 5239 } 5240 5241 static std::pair<std::string, SpellingList> 5242 GetAttributeHeadingAndSpellings(const Record &Documentation, 5243 const Record &Attribute, 5244 StringRef Cat) { 5245 // FIXME: there is no way to have a per-spelling category for the attribute 5246 // documentation. This may not be a limiting factor since the spellings 5247 // should generally be consistently applied across the category. 5248 5249 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute); 5250 if (Spellings.empty()) 5251 PrintFatalError(Attribute.getLoc(), 5252 "Attribute has no supported spellings; cannot be " 5253 "documented"); 5254 5255 // Determine the heading to be used for this attribute. 5256 std::string Heading = Documentation.getValueAsString("Heading").str(); 5257 if (Heading.empty()) { 5258 // If there's only one spelling, we can simply use that. 5259 if (Spellings.size() == 1) 5260 Heading = Spellings.begin()->name(); 5261 else { 5262 std::set<std::string> Uniques; 5263 for (const FlattenedSpelling &FS : Spellings) { 5264 std::string Spelling = 5265 NormalizeNameForSpellingComparison(FS.name()).str(); 5266 Uniques.insert(Spelling); 5267 } 5268 // If the semantic map has only one spelling, that is sufficient for our 5269 // needs. 5270 if (Uniques.size() == 1) 5271 Heading = *Uniques.begin(); 5272 // If it's in the undocumented category, just construct a header by 5273 // concatenating all the spellings. Might not be great, but better than 5274 // nothing. 5275 else if (Cat == "Undocumented") 5276 Heading = join(Uniques.begin(), Uniques.end(), ", "); 5277 } 5278 } 5279 5280 // If the heading is still empty, it is an error. 5281 if (Heading.empty()) 5282 PrintFatalError(Attribute.getLoc(), 5283 "This attribute requires a heading to be specified"); 5284 5285 SpellingList SupportedSpellings; 5286 for (const auto &I : Spellings) 5287 SupportedSpellings.add(Attribute, I); 5288 5289 return std::make_pair(std::move(Heading), std::move(SupportedSpellings)); 5290 } 5291 5292 static void WriteDocumentation(const RecordKeeper &Records, 5293 const DocumentationData &Doc, raw_ostream &OS) { 5294 if (StringRef Label = Doc.Documentation->getValueAsString("Label"); 5295 !Label.empty()) 5296 OS << ".. _" << Label << ":\n\n"; 5297 OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n"; 5298 5299 // List what spelling syntaxes the attribute supports. 5300 // Note: "#pragma clang attribute" is handled outside the spelling kinds loop 5301 // so it must be last. 5302 OS << ".. csv-table:: Supported Syntaxes\n"; 5303 OS << " :header: \"GNU\", \"C++11\", \"C23\", \"``__declspec``\","; 5304 OS << " \"Keyword\", \"``#pragma``\", \"HLSL Annotation\", \"``#pragma " 5305 "clang "; 5306 OS << "attribute``\"\n\n \""; 5307 for (size_t Kind = 0; Kind != NumSpellingKinds; ++Kind) { 5308 SpellingKind K = (SpellingKind)Kind; 5309 // TODO: List Microsoft (IDL-style attribute) spellings once we fully 5310 // support them. 5311 if (K == SpellingKind::Microsoft) 5312 continue; 5313 5314 bool PrintedAny = false; 5315 for (StringRef Spelling : Doc.SupportedSpellings[K]) { 5316 if (PrintedAny) 5317 OS << " |br| "; 5318 OS << "``" << Spelling << "``"; 5319 PrintedAny = true; 5320 } 5321 5322 OS << "\",\""; 5323 } 5324 5325 if (getPragmaAttributeSupport(Records).isAttributedSupported( 5326 *Doc.Attribute)) 5327 OS << "Yes"; 5328 OS << "\"\n\n"; 5329 5330 // If the attribute is deprecated, print a message about it, and possibly 5331 // provide a replacement attribute. 5332 if (!Doc.Documentation->isValueUnset("Deprecated")) { 5333 OS << "This attribute has been deprecated, and may be removed in a future " 5334 << "version of Clang."; 5335 const Record &Deprecated = *Doc.Documentation->getValueAsDef("Deprecated"); 5336 const StringRef Replacement = Deprecated.getValueAsString("Replacement"); 5337 if (!Replacement.empty()) 5338 OS << " This attribute has been superseded by ``" << Replacement 5339 << "``."; 5340 OS << "\n\n"; 5341 } 5342 5343 const StringRef ContentStr = Doc.Documentation->getValueAsString("Content"); 5344 // Trim leading and trailing newlines and spaces. 5345 OS << ContentStr.trim(); 5346 5347 OS << "\n\n\n"; 5348 } 5349 5350 void EmitClangAttrDocs(const RecordKeeper &Records, raw_ostream &OS) { 5351 // Get the documentation introduction paragraph. 5352 const Record *Documentation = Records.getDef("GlobalDocumentation"); 5353 if (!Documentation) { 5354 PrintFatalError("The Documentation top-level definition is missing, " 5355 "no documentation will be generated."); 5356 return; 5357 } 5358 5359 OS << Documentation->getValueAsString("Intro") << "\n"; 5360 5361 // Gather the Documentation lists from each of the attributes, based on the 5362 // category provided. 5363 struct CategoryLess { 5364 bool operator()(const Record *L, const Record *R) const { 5365 return L->getValueAsString("Name") < R->getValueAsString("Name"); 5366 } 5367 }; 5368 5369 std::map<const Record *, std::map<uint32_t, DocumentationData>, CategoryLess> 5370 MergedDocs; 5371 5372 std::vector<DocumentationData> UndocumentedDocs; 5373 const Record *UndocumentedCategory = nullptr; 5374 5375 // Collect documentation data, grouping by category and heading. 5376 for (const auto *A : Records.getAllDerivedDefinitions("Attr")) { 5377 const Record &Attr = *A; 5378 std::vector<const Record *> Docs = 5379 Attr.getValueAsListOfDefs("Documentation"); 5380 5381 for (const auto *D : Docs) { 5382 const Record &Doc = *D; 5383 const Record *Category = Doc.getValueAsDef("Category"); 5384 // If the category is "InternalOnly", then there cannot be any other 5385 // documentation categories (otherwise, the attribute would be 5386 // emitted into the docs). 5387 StringRef Cat = Category->getValueAsString("Name"); 5388 if (Cat == "InternalOnly" && Docs.size() > 1) 5389 PrintFatalError(Doc.getLoc(), 5390 "Attribute is \"InternalOnly\", but has multiple " 5391 "documentation categories"); 5392 5393 if (Cat == "InternalOnly") 5394 continue; 5395 5396 // Track the Undocumented category Record for later grouping 5397 if (Cat == "Undocumented" && !UndocumentedCategory) 5398 UndocumentedCategory = Category; 5399 5400 // Generate Heading and Spellings. 5401 auto HeadingAndSpellings = 5402 GetAttributeHeadingAndSpellings(Doc, Attr, Cat); 5403 5404 // Handle Undocumented category separately - no content merging 5405 if (Cat == "Undocumented" && UndocumentedCategory) { 5406 UndocumentedDocs.push_back( 5407 DocumentationData(Doc, Attr, std::move(HeadingAndSpellings))); 5408 continue; 5409 } 5410 5411 auto &CategoryDocs = MergedDocs[Category]; 5412 5413 std::string key = Doc.getValueAsString("Content").str(); 5414 uint32_t keyHash = llvm::hash_value(key); 5415 5416 // If the content already exists, merge the documentation. 5417 auto It = CategoryDocs.find(keyHash); 5418 if (It != CategoryDocs.end()) { 5419 // Merge heading 5420 if (It->second.Heading != HeadingAndSpellings.first) 5421 It->second.Heading += ", " + HeadingAndSpellings.first; 5422 // Merge spellings 5423 It->second.SupportedSpellings.merge(HeadingAndSpellings.second); 5424 // Merge content 5425 It->second.Documentation = &Doc; // Update reference 5426 } else { 5427 // Create new entry for unique content 5428 CategoryDocs.emplace(keyHash, 5429 DocumentationData(Doc, Attr, HeadingAndSpellings)); 5430 } 5431 } 5432 } 5433 5434 std::map<const Record *, std::vector<DocumentationData>, CategoryLess> 5435 SplitDocs; 5436 5437 for (auto &CategoryPair : MergedDocs) { 5438 5439 std::vector<DocumentationData> MD; 5440 for (auto &DocPair : CategoryPair.second) 5441 MD.push_back(std::move(DocPair.second)); 5442 5443 SplitDocs.emplace(CategoryPair.first, MD); 5444 } 5445 5446 // Append Undocumented category entries 5447 if (!UndocumentedDocs.empty() && UndocumentedCategory) { 5448 SplitDocs.emplace(UndocumentedCategory, UndocumentedDocs); 5449 } 5450 5451 // Having split the attributes out based on what documentation goes where, 5452 // we can begin to generate sections of documentation. 5453 for (auto &I : SplitDocs) { 5454 WriteCategoryHeader(I.first, OS); 5455 5456 sort(I.second, 5457 [](const DocumentationData &D1, const DocumentationData &D2) { 5458 return D1.Heading < D2.Heading; 5459 }); 5460 5461 // Walk over each of the attributes in the category and write out their 5462 // documentation. 5463 for (const auto &Doc : I.second) 5464 WriteDocumentation(Records, Doc, OS); 5465 } 5466 } 5467 5468 void EmitTestPragmaAttributeSupportedAttributes(const RecordKeeper &Records, 5469 raw_ostream &OS) { 5470 PragmaClangAttributeSupport Support = getPragmaAttributeSupport(Records); 5471 ParsedAttrMap Attrs = getParsedAttrList(Records); 5472 OS << "#pragma clang attribute supports the following attributes:\n"; 5473 for (const auto &I : Attrs) { 5474 if (!Support.isAttributedSupported(*I.second)) 5475 continue; 5476 OS << I.first; 5477 if (I.second->isValueUnset("Subjects")) { 5478 OS << " ()\n"; 5479 continue; 5480 } 5481 const Record *SubjectObj = I.second->getValueAsDef("Subjects"); 5482 OS << " ("; 5483 ListSeparator LS; 5484 for (const auto &Subject : 5485 enumerate(SubjectObj->getValueAsListOfDefs("Subjects"))) { 5486 if (!isSupportedPragmaClangAttributeSubject(*Subject.value())) 5487 continue; 5488 OS << LS; 5489 PragmaClangAttributeSupport::RuleOrAggregateRuleSet &RuleSet = 5490 Support.SubjectsToRules.find(Subject.value())->getSecond(); 5491 if (RuleSet.isRule()) { 5492 OS << RuleSet.getRule().getEnumValueName(); 5493 continue; 5494 } 5495 OS << "("; 5496 for (const auto &Rule : enumerate(RuleSet.getAggregateRuleSet())) { 5497 if (Rule.index()) 5498 OS << ", "; 5499 OS << Rule.value().getEnumValueName(); 5500 } 5501 OS << ")"; 5502 } 5503 OS << ")\n"; 5504 } 5505 OS << "End of supported attributes.\n"; 5506 } 5507 5508 } // end namespace clang 5509