1 //===--- Stmt.cpp - Statement AST Node Implementation ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Stmt class and statement subclasses. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/ASTDiagnostic.h" 16 #include "clang/AST/ExprCXX.h" 17 #include "clang/AST/ExprObjC.h" 18 #include "clang/AST/Stmt.h" 19 #include "clang/AST/StmtCXX.h" 20 #include "clang/AST/StmtObjC.h" 21 #include "clang/AST/StmtOpenMP.h" 22 #include "clang/AST/Type.h" 23 #include "clang/Basic/CharInfo.h" 24 #include "clang/Basic/TargetInfo.h" 25 #include "clang/Lex/Token.h" 26 #include "llvm/ADT/StringExtras.h" 27 #include "llvm/Support/raw_ostream.h" 28 using namespace clang; 29 30 static struct StmtClassNameTable { 31 const char *Name; 32 unsigned Counter; 33 unsigned Size; 34 } StmtClassInfo[Stmt::lastStmtConstant+1]; 35 36 static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) { 37 static bool Initialized = false; 38 if (Initialized) 39 return StmtClassInfo[E]; 40 41 // Intialize the table on the first use. 42 Initialized = true; 43 #define ABSTRACT_STMT(STMT) 44 #define STMT(CLASS, PARENT) \ 45 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \ 46 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS); 47 #include "clang/AST/StmtNodes.inc" 48 49 return StmtClassInfo[E]; 50 } 51 52 void *Stmt::operator new(size_t bytes, ASTContext& C, 53 unsigned alignment) throw() { 54 return ::operator new(bytes, C, alignment); 55 } 56 57 void *Stmt::operator new(size_t bytes, ASTContext* C, 58 unsigned alignment) throw() { 59 return ::operator new(bytes, *C, alignment); 60 } 61 62 const char *Stmt::getStmtClassName() const { 63 return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name; 64 } 65 66 void Stmt::PrintStats() { 67 // Ensure the table is primed. 68 getStmtInfoTableEntry(Stmt::NullStmtClass); 69 70 unsigned sum = 0; 71 llvm::errs() << "\n*** Stmt/Expr Stats:\n"; 72 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { 73 if (StmtClassInfo[i].Name == 0) continue; 74 sum += StmtClassInfo[i].Counter; 75 } 76 llvm::errs() << " " << sum << " stmts/exprs total.\n"; 77 sum = 0; 78 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { 79 if (StmtClassInfo[i].Name == 0) continue; 80 if (StmtClassInfo[i].Counter == 0) continue; 81 llvm::errs() << " " << StmtClassInfo[i].Counter << " " 82 << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size 83 << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size 84 << " bytes)\n"; 85 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size; 86 } 87 88 llvm::errs() << "Total bytes = " << sum << "\n"; 89 } 90 91 void Stmt::addStmtClass(StmtClass s) { 92 ++getStmtInfoTableEntry(s).Counter; 93 } 94 95 bool Stmt::StatisticsEnabled = false; 96 void Stmt::EnableStatistics() { 97 StatisticsEnabled = true; 98 } 99 100 Stmt *Stmt::IgnoreImplicit() { 101 Stmt *s = this; 102 103 if (ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(s)) 104 s = ewc->getSubExpr(); 105 106 while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(s)) 107 s = ice->getSubExpr(); 108 109 return s; 110 } 111 112 /// \brief Strip off all label-like statements. 113 /// 114 /// This will strip off label statements, case statements, attributed 115 /// statements and default statements recursively. 116 const Stmt *Stmt::stripLabelLikeStatements() const { 117 const Stmt *S = this; 118 while (true) { 119 if (const LabelStmt *LS = dyn_cast<LabelStmt>(S)) 120 S = LS->getSubStmt(); 121 else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) 122 S = SC->getSubStmt(); 123 else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S)) 124 S = AS->getSubStmt(); 125 else 126 return S; 127 } 128 } 129 130 namespace { 131 struct good {}; 132 struct bad {}; 133 134 // These silly little functions have to be static inline to suppress 135 // unused warnings, and they have to be defined to suppress other 136 // warnings. 137 static inline good is_good(good) { return good(); } 138 139 typedef Stmt::child_range children_t(); 140 template <class T> good implements_children(children_t T::*) { 141 return good(); 142 } 143 static inline bad implements_children(children_t Stmt::*) { 144 return bad(); 145 } 146 147 typedef SourceLocation getLocStart_t() const; 148 template <class T> good implements_getLocStart(getLocStart_t T::*) { 149 return good(); 150 } 151 static inline bad implements_getLocStart(getLocStart_t Stmt::*) { 152 return bad(); 153 } 154 155 typedef SourceLocation getLocEnd_t() const; 156 template <class T> good implements_getLocEnd(getLocEnd_t T::*) { 157 return good(); 158 } 159 static inline bad implements_getLocEnd(getLocEnd_t Stmt::*) { 160 return bad(); 161 } 162 163 #define ASSERT_IMPLEMENTS_children(type) \ 164 (void) sizeof(is_good(implements_children(&type::children))) 165 #define ASSERT_IMPLEMENTS_getLocStart(type) \ 166 (void) sizeof(is_good(implements_getLocStart(&type::getLocStart))) 167 #define ASSERT_IMPLEMENTS_getLocEnd(type) \ 168 (void) sizeof(is_good(implements_getLocEnd(&type::getLocEnd))) 169 } 170 171 /// Check whether the various Stmt classes implement their member 172 /// functions. 173 static inline void check_implementations() { 174 #define ABSTRACT_STMT(type) 175 #define STMT(type, base) \ 176 ASSERT_IMPLEMENTS_children(type); \ 177 ASSERT_IMPLEMENTS_getLocStart(type); \ 178 ASSERT_IMPLEMENTS_getLocEnd(type); 179 #include "clang/AST/StmtNodes.inc" 180 } 181 182 Stmt::child_range Stmt::children() { 183 switch (getStmtClass()) { 184 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 185 #define ABSTRACT_STMT(type) 186 #define STMT(type, base) \ 187 case Stmt::type##Class: \ 188 return static_cast<type*>(this)->children(); 189 #include "clang/AST/StmtNodes.inc" 190 } 191 llvm_unreachable("unknown statement kind!"); 192 } 193 194 // Amusing macro metaprogramming hack: check whether a class provides 195 // a more specific implementation of getSourceRange. 196 // 197 // See also Expr.cpp:getExprLoc(). 198 namespace { 199 /// This implementation is used when a class provides a custom 200 /// implementation of getSourceRange. 201 template <class S, class T> 202 SourceRange getSourceRangeImpl(const Stmt *stmt, 203 SourceRange (T::*v)() const) { 204 return static_cast<const S*>(stmt)->getSourceRange(); 205 } 206 207 /// This implementation is used when a class doesn't provide a custom 208 /// implementation of getSourceRange. Overload resolution should pick it over 209 /// the implementation above because it's more specialized according to 210 /// function template partial ordering. 211 template <class S> 212 SourceRange getSourceRangeImpl(const Stmt *stmt, 213 SourceRange (Stmt::*v)() const) { 214 return SourceRange(static_cast<const S*>(stmt)->getLocStart(), 215 static_cast<const S*>(stmt)->getLocEnd()); 216 } 217 } 218 219 SourceRange Stmt::getSourceRange() const { 220 switch (getStmtClass()) { 221 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 222 #define ABSTRACT_STMT(type) 223 #define STMT(type, base) \ 224 case Stmt::type##Class: \ 225 return getSourceRangeImpl<type>(this, &type::getSourceRange); 226 #include "clang/AST/StmtNodes.inc" 227 } 228 llvm_unreachable("unknown statement kind!"); 229 } 230 231 SourceLocation Stmt::getLocStart() const { 232 // llvm::errs() << "getLocStart() for " << getStmtClassName() << "\n"; 233 switch (getStmtClass()) { 234 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 235 #define ABSTRACT_STMT(type) 236 #define STMT(type, base) \ 237 case Stmt::type##Class: \ 238 return static_cast<const type*>(this)->getLocStart(); 239 #include "clang/AST/StmtNodes.inc" 240 } 241 llvm_unreachable("unknown statement kind"); 242 } 243 244 SourceLocation Stmt::getLocEnd() const { 245 switch (getStmtClass()) { 246 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 247 #define ABSTRACT_STMT(type) 248 #define STMT(type, base) \ 249 case Stmt::type##Class: \ 250 return static_cast<const type*>(this)->getLocEnd(); 251 #include "clang/AST/StmtNodes.inc" 252 } 253 llvm_unreachable("unknown statement kind"); 254 } 255 256 CompoundStmt::CompoundStmt(ASTContext &C, ArrayRef<Stmt*> Stmts, 257 SourceLocation LB, SourceLocation RB) 258 : Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) { 259 CompoundStmtBits.NumStmts = Stmts.size(); 260 assert(CompoundStmtBits.NumStmts == Stmts.size() && 261 "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!"); 262 263 if (Stmts.size() == 0) { 264 Body = 0; 265 return; 266 } 267 268 Body = new (C) Stmt*[Stmts.size()]; 269 std::copy(Stmts.begin(), Stmts.end(), Body); 270 } 271 272 void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) { 273 if (this->Body) 274 C.Deallocate(Body); 275 this->CompoundStmtBits.NumStmts = NumStmts; 276 277 Body = new (C) Stmt*[NumStmts]; 278 memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts); 279 } 280 281 const char *LabelStmt::getName() const { 282 return getDecl()->getIdentifier()->getNameStart(); 283 } 284 285 AttributedStmt *AttributedStmt::Create(ASTContext &C, SourceLocation Loc, 286 ArrayRef<const Attr*> Attrs, 287 Stmt *SubStmt) { 288 void *Mem = C.Allocate(sizeof(AttributedStmt) + 289 sizeof(Attr*) * (Attrs.size() - 1), 290 llvm::alignOf<AttributedStmt>()); 291 return new (Mem) AttributedStmt(Loc, Attrs, SubStmt); 292 } 293 294 AttributedStmt *AttributedStmt::CreateEmpty(ASTContext &C, unsigned NumAttrs) { 295 assert(NumAttrs > 0 && "NumAttrs should be greater than zero"); 296 void *Mem = C.Allocate(sizeof(AttributedStmt) + 297 sizeof(Attr*) * (NumAttrs - 1), 298 llvm::alignOf<AttributedStmt>()); 299 return new (Mem) AttributedStmt(EmptyShell(), NumAttrs); 300 } 301 302 std::string AsmStmt::generateAsmString(ASTContext &C) const { 303 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 304 return gccAsmStmt->generateAsmString(C); 305 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 306 return msAsmStmt->generateAsmString(C); 307 llvm_unreachable("unknown asm statement kind!"); 308 } 309 310 StringRef AsmStmt::getOutputConstraint(unsigned i) const { 311 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 312 return gccAsmStmt->getOutputConstraint(i); 313 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 314 return msAsmStmt->getOutputConstraint(i); 315 llvm_unreachable("unknown asm statement kind!"); 316 } 317 318 const Expr *AsmStmt::getOutputExpr(unsigned i) const { 319 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 320 return gccAsmStmt->getOutputExpr(i); 321 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 322 return msAsmStmt->getOutputExpr(i); 323 llvm_unreachable("unknown asm statement kind!"); 324 } 325 326 StringRef AsmStmt::getInputConstraint(unsigned i) const { 327 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 328 return gccAsmStmt->getInputConstraint(i); 329 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 330 return msAsmStmt->getInputConstraint(i); 331 llvm_unreachable("unknown asm statement kind!"); 332 } 333 334 const Expr *AsmStmt::getInputExpr(unsigned i) const { 335 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 336 return gccAsmStmt->getInputExpr(i); 337 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 338 return msAsmStmt->getInputExpr(i); 339 llvm_unreachable("unknown asm statement kind!"); 340 } 341 342 StringRef AsmStmt::getClobber(unsigned i) const { 343 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 344 return gccAsmStmt->getClobber(i); 345 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 346 return msAsmStmt->getClobber(i); 347 llvm_unreachable("unknown asm statement kind!"); 348 } 349 350 /// getNumPlusOperands - Return the number of output operands that have a "+" 351 /// constraint. 352 unsigned AsmStmt::getNumPlusOperands() const { 353 unsigned Res = 0; 354 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) 355 if (isOutputPlusConstraint(i)) 356 ++Res; 357 return Res; 358 } 359 360 StringRef GCCAsmStmt::getClobber(unsigned i) const { 361 return getClobberStringLiteral(i)->getString(); 362 } 363 364 Expr *GCCAsmStmt::getOutputExpr(unsigned i) { 365 return cast<Expr>(Exprs[i]); 366 } 367 368 /// getOutputConstraint - Return the constraint string for the specified 369 /// output operand. All output constraints are known to be non-empty (either 370 /// '=' or '+'). 371 StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const { 372 return getOutputConstraintLiteral(i)->getString(); 373 } 374 375 Expr *GCCAsmStmt::getInputExpr(unsigned i) { 376 return cast<Expr>(Exprs[i + NumOutputs]); 377 } 378 void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) { 379 Exprs[i + NumOutputs] = E; 380 } 381 382 /// getInputConstraint - Return the specified input constraint. Unlike output 383 /// constraints, these can be empty. 384 StringRef GCCAsmStmt::getInputConstraint(unsigned i) const { 385 return getInputConstraintLiteral(i)->getString(); 386 } 387 388 void GCCAsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C, 389 IdentifierInfo **Names, 390 StringLiteral **Constraints, 391 Stmt **Exprs, 392 unsigned NumOutputs, 393 unsigned NumInputs, 394 StringLiteral **Clobbers, 395 unsigned NumClobbers) { 396 this->NumOutputs = NumOutputs; 397 this->NumInputs = NumInputs; 398 this->NumClobbers = NumClobbers; 399 400 unsigned NumExprs = NumOutputs + NumInputs; 401 402 C.Deallocate(this->Names); 403 this->Names = new (C) IdentifierInfo*[NumExprs]; 404 std::copy(Names, Names + NumExprs, this->Names); 405 406 C.Deallocate(this->Exprs); 407 this->Exprs = new (C) Stmt*[NumExprs]; 408 std::copy(Exprs, Exprs + NumExprs, this->Exprs); 409 410 C.Deallocate(this->Constraints); 411 this->Constraints = new (C) StringLiteral*[NumExprs]; 412 std::copy(Constraints, Constraints + NumExprs, this->Constraints); 413 414 C.Deallocate(this->Clobbers); 415 this->Clobbers = new (C) StringLiteral*[NumClobbers]; 416 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers); 417 } 418 419 /// getNamedOperand - Given a symbolic operand reference like %[foo], 420 /// translate this into a numeric value needed to reference the same operand. 421 /// This returns -1 if the operand name is invalid. 422 int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const { 423 unsigned NumPlusOperands = 0; 424 425 // Check if this is an output operand. 426 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) { 427 if (getOutputName(i) == SymbolicName) 428 return i; 429 } 430 431 for (unsigned i = 0, e = getNumInputs(); i != e; ++i) 432 if (getInputName(i) == SymbolicName) 433 return getNumOutputs() + NumPlusOperands + i; 434 435 // Not found. 436 return -1; 437 } 438 439 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing 440 /// it into pieces. If the asm string is erroneous, emit errors and return 441 /// true, otherwise return false. 442 unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces, 443 ASTContext &C, unsigned &DiagOffs) const { 444 StringRef Str = getAsmString()->getString(); 445 const char *StrStart = Str.begin(); 446 const char *StrEnd = Str.end(); 447 const char *CurPtr = StrStart; 448 449 // "Simple" inline asms have no constraints or operands, just convert the asm 450 // string to escape $'s. 451 if (isSimple()) { 452 std::string Result; 453 for (; CurPtr != StrEnd; ++CurPtr) { 454 switch (*CurPtr) { 455 case '$': 456 Result += "$$"; 457 break; 458 default: 459 Result += *CurPtr; 460 break; 461 } 462 } 463 Pieces.push_back(AsmStringPiece(Result)); 464 return 0; 465 } 466 467 // CurStringPiece - The current string that we are building up as we scan the 468 // asm string. 469 std::string CurStringPiece; 470 471 bool HasVariants = !C.getTargetInfo().hasNoAsmVariants(); 472 473 while (1) { 474 // Done with the string? 475 if (CurPtr == StrEnd) { 476 if (!CurStringPiece.empty()) 477 Pieces.push_back(AsmStringPiece(CurStringPiece)); 478 return 0; 479 } 480 481 char CurChar = *CurPtr++; 482 switch (CurChar) { 483 case '$': CurStringPiece += "$$"; continue; 484 case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue; 485 case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue; 486 case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue; 487 case '%': 488 break; 489 default: 490 CurStringPiece += CurChar; 491 continue; 492 } 493 494 // Escaped "%" character in asm string. 495 if (CurPtr == StrEnd) { 496 // % at end of string is invalid (no escape). 497 DiagOffs = CurPtr-StrStart-1; 498 return diag::err_asm_invalid_escape; 499 } 500 501 char EscapedChar = *CurPtr++; 502 if (EscapedChar == '%') { // %% -> % 503 // Escaped percentage sign. 504 CurStringPiece += '%'; 505 continue; 506 } 507 508 if (EscapedChar == '=') { // %= -> Generate an unique ID. 509 CurStringPiece += "${:uid}"; 510 continue; 511 } 512 513 // Otherwise, we have an operand. If we have accumulated a string so far, 514 // add it to the Pieces list. 515 if (!CurStringPiece.empty()) { 516 Pieces.push_back(AsmStringPiece(CurStringPiece)); 517 CurStringPiece.clear(); 518 } 519 520 // Handle %x4 and %x[foo] by capturing x as the modifier character. 521 char Modifier = '\0'; 522 if (isLetter(EscapedChar)) { 523 if (CurPtr == StrEnd) { // Premature end. 524 DiagOffs = CurPtr-StrStart-1; 525 return diag::err_asm_invalid_escape; 526 } 527 Modifier = EscapedChar; 528 EscapedChar = *CurPtr++; 529 } 530 531 if (isDigit(EscapedChar)) { 532 // %n - Assembler operand n 533 unsigned N = 0; 534 535 --CurPtr; 536 while (CurPtr != StrEnd && isDigit(*CurPtr)) 537 N = N*10 + ((*CurPtr++)-'0'); 538 539 unsigned NumOperands = 540 getNumOutputs() + getNumPlusOperands() + getNumInputs(); 541 if (N >= NumOperands) { 542 DiagOffs = CurPtr-StrStart-1; 543 return diag::err_asm_invalid_operand_number; 544 } 545 546 Pieces.push_back(AsmStringPiece(N, Modifier)); 547 continue; 548 } 549 550 // Handle %[foo], a symbolic operand reference. 551 if (EscapedChar == '[') { 552 DiagOffs = CurPtr-StrStart-1; 553 554 // Find the ']'. 555 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr); 556 if (NameEnd == 0) 557 return diag::err_asm_unterminated_symbolic_operand_name; 558 if (NameEnd == CurPtr) 559 return diag::err_asm_empty_symbolic_operand_name; 560 561 StringRef SymbolicName(CurPtr, NameEnd - CurPtr); 562 563 int N = getNamedOperand(SymbolicName); 564 if (N == -1) { 565 // Verify that an operand with that name exists. 566 DiagOffs = CurPtr-StrStart; 567 return diag::err_asm_unknown_symbolic_operand_name; 568 } 569 Pieces.push_back(AsmStringPiece(N, Modifier)); 570 571 CurPtr = NameEnd+1; 572 continue; 573 } 574 575 DiagOffs = CurPtr-StrStart-1; 576 return diag::err_asm_invalid_escape; 577 } 578 } 579 580 /// Assemble final IR asm string (GCC-style). 581 std::string GCCAsmStmt::generateAsmString(ASTContext &C) const { 582 // Analyze the asm string to decompose it into its pieces. We know that Sema 583 // has already done this, so it is guaranteed to be successful. 584 SmallVector<GCCAsmStmt::AsmStringPiece, 4> Pieces; 585 unsigned DiagOffs; 586 AnalyzeAsmString(Pieces, C, DiagOffs); 587 588 std::string AsmString; 589 for (unsigned i = 0, e = Pieces.size(); i != e; ++i) { 590 if (Pieces[i].isString()) 591 AsmString += Pieces[i].getString(); 592 else if (Pieces[i].getModifier() == '\0') 593 AsmString += '$' + llvm::utostr(Pieces[i].getOperandNo()); 594 else 595 AsmString += "${" + llvm::utostr(Pieces[i].getOperandNo()) + ':' + 596 Pieces[i].getModifier() + '}'; 597 } 598 return AsmString; 599 } 600 601 /// Assemble final IR asm string (MS-style). 602 std::string MSAsmStmt::generateAsmString(ASTContext &C) const { 603 // FIXME: This needs to be translated into the IR string representation. 604 return AsmStr; 605 } 606 607 Expr *MSAsmStmt::getOutputExpr(unsigned i) { 608 return cast<Expr>(Exprs[i]); 609 } 610 611 Expr *MSAsmStmt::getInputExpr(unsigned i) { 612 return cast<Expr>(Exprs[i + NumOutputs]); 613 } 614 void MSAsmStmt::setInputExpr(unsigned i, Expr *E) { 615 Exprs[i + NumOutputs] = E; 616 } 617 618 QualType CXXCatchStmt::getCaughtType() const { 619 if (ExceptionDecl) 620 return ExceptionDecl->getType(); 621 return QualType(); 622 } 623 624 //===----------------------------------------------------------------------===// 625 // Constructors 626 //===----------------------------------------------------------------------===// 627 628 GCCAsmStmt::GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, 629 bool isvolatile, unsigned numoutputs, unsigned numinputs, 630 IdentifierInfo **names, StringLiteral **constraints, 631 Expr **exprs, StringLiteral *asmstr, 632 unsigned numclobbers, StringLiteral **clobbers, 633 SourceLocation rparenloc) 634 : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs, 635 numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) { 636 637 unsigned NumExprs = NumOutputs + NumInputs; 638 639 Names = new (C) IdentifierInfo*[NumExprs]; 640 std::copy(names, names + NumExprs, Names); 641 642 Exprs = new (C) Stmt*[NumExprs]; 643 std::copy(exprs, exprs + NumExprs, Exprs); 644 645 Constraints = new (C) StringLiteral*[NumExprs]; 646 std::copy(constraints, constraints + NumExprs, Constraints); 647 648 Clobbers = new (C) StringLiteral*[NumClobbers]; 649 std::copy(clobbers, clobbers + NumClobbers, Clobbers); 650 } 651 652 MSAsmStmt::MSAsmStmt(ASTContext &C, SourceLocation asmloc, 653 SourceLocation lbraceloc, bool issimple, bool isvolatile, 654 ArrayRef<Token> asmtoks, unsigned numoutputs, 655 unsigned numinputs, 656 ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs, 657 StringRef asmstr, ArrayRef<StringRef> clobbers, 658 SourceLocation endloc) 659 : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs, 660 numinputs, clobbers.size()), LBraceLoc(lbraceloc), 661 EndLoc(endloc), NumAsmToks(asmtoks.size()) { 662 663 initialize(C, asmstr, asmtoks, constraints, exprs, clobbers); 664 } 665 666 static StringRef copyIntoContext(ASTContext &C, StringRef str) { 667 size_t size = str.size(); 668 char *buffer = new (C) char[size]; 669 memcpy(buffer, str.data(), size); 670 return StringRef(buffer, size); 671 } 672 673 void MSAsmStmt::initialize(ASTContext &C, 674 StringRef asmstr, 675 ArrayRef<Token> asmtoks, 676 ArrayRef<StringRef> constraints, 677 ArrayRef<Expr*> exprs, 678 ArrayRef<StringRef> clobbers) { 679 assert(NumAsmToks == asmtoks.size()); 680 assert(NumClobbers == clobbers.size()); 681 682 unsigned NumExprs = exprs.size(); 683 assert(NumExprs == NumOutputs + NumInputs); 684 assert(NumExprs == constraints.size()); 685 686 AsmStr = copyIntoContext(C, asmstr); 687 688 Exprs = new (C) Stmt*[NumExprs]; 689 for (unsigned i = 0, e = NumExprs; i != e; ++i) 690 Exprs[i] = exprs[i]; 691 692 AsmToks = new (C) Token[NumAsmToks]; 693 for (unsigned i = 0, e = NumAsmToks; i != e; ++i) 694 AsmToks[i] = asmtoks[i]; 695 696 Constraints = new (C) StringRef[NumExprs]; 697 for (unsigned i = 0, e = NumExprs; i != e; ++i) { 698 Constraints[i] = copyIntoContext(C, constraints[i]); 699 } 700 701 Clobbers = new (C) StringRef[NumClobbers]; 702 for (unsigned i = 0, e = NumClobbers; i != e; ++i) { 703 // FIXME: Avoid the allocation/copy if at all possible. 704 Clobbers[i] = copyIntoContext(C, clobbers[i]); 705 } 706 } 707 708 ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, 709 Stmt *Body, SourceLocation FCL, 710 SourceLocation RPL) 711 : Stmt(ObjCForCollectionStmtClass) { 712 SubExprs[ELEM] = Elem; 713 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect); 714 SubExprs[BODY] = Body; 715 ForLoc = FCL; 716 RParenLoc = RPL; 717 } 718 719 ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 720 Stmt **CatchStmts, unsigned NumCatchStmts, 721 Stmt *atFinallyStmt) 722 : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc), 723 NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0) 724 { 725 Stmt **Stmts = getStmts(); 726 Stmts[0] = atTryStmt; 727 for (unsigned I = 0; I != NumCatchStmts; ++I) 728 Stmts[I + 1] = CatchStmts[I]; 729 730 if (HasFinally) 731 Stmts[NumCatchStmts + 1] = atFinallyStmt; 732 } 733 734 ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context, 735 SourceLocation atTryLoc, 736 Stmt *atTryStmt, 737 Stmt **CatchStmts, 738 unsigned NumCatchStmts, 739 Stmt *atFinallyStmt) { 740 unsigned Size = sizeof(ObjCAtTryStmt) + 741 (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *); 742 void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>()); 743 return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts, 744 atFinallyStmt); 745 } 746 747 ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context, 748 unsigned NumCatchStmts, 749 bool HasFinally) { 750 unsigned Size = sizeof(ObjCAtTryStmt) + 751 (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *); 752 void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>()); 753 return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally); 754 } 755 756 SourceLocation ObjCAtTryStmt::getLocEnd() const { 757 if (HasFinally) 758 return getFinallyStmt()->getLocEnd(); 759 if (NumCatchStmts) 760 return getCatchStmt(NumCatchStmts - 1)->getLocEnd(); 761 return getTryBody()->getLocEnd(); 762 } 763 764 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc, 765 Stmt *tryBlock, ArrayRef<Stmt*> handlers) { 766 std::size_t Size = sizeof(CXXTryStmt); 767 Size += ((handlers.size() + 1) * sizeof(Stmt)); 768 769 void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>()); 770 return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers); 771 } 772 773 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty, 774 unsigned numHandlers) { 775 std::size_t Size = sizeof(CXXTryStmt); 776 Size += ((numHandlers + 1) * sizeof(Stmt)); 777 778 void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>()); 779 return new (Mem) CXXTryStmt(Empty, numHandlers); 780 } 781 782 CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, 783 ArrayRef<Stmt*> handlers) 784 : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) { 785 Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1); 786 Stmts[0] = tryBlock; 787 std::copy(handlers.begin(), handlers.end(), Stmts + 1); 788 } 789 790 CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt, 791 Expr *Cond, Expr *Inc, DeclStmt *LoopVar, 792 Stmt *Body, SourceLocation FL, 793 SourceLocation CL, SourceLocation RPL) 794 : Stmt(CXXForRangeStmtClass), ForLoc(FL), ColonLoc(CL), RParenLoc(RPL) { 795 SubExprs[RANGE] = Range; 796 SubExprs[BEGINEND] = BeginEndStmt; 797 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 798 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 799 SubExprs[LOOPVAR] = LoopVar; 800 SubExprs[BODY] = Body; 801 } 802 803 Expr *CXXForRangeStmt::getRangeInit() { 804 DeclStmt *RangeStmt = getRangeStmt(); 805 VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl()); 806 assert(RangeDecl &&& "for-range should have a single var decl"); 807 return RangeDecl->getInit(); 808 } 809 810 const Expr *CXXForRangeStmt::getRangeInit() const { 811 return const_cast<CXXForRangeStmt*>(this)->getRangeInit(); 812 } 813 814 VarDecl *CXXForRangeStmt::getLoopVariable() { 815 Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl(); 816 assert(LV && "No loop variable in CXXForRangeStmt"); 817 return cast<VarDecl>(LV); 818 } 819 820 const VarDecl *CXXForRangeStmt::getLoopVariable() const { 821 return const_cast<CXXForRangeStmt*>(this)->getLoopVariable(); 822 } 823 824 IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 825 Stmt *then, SourceLocation EL, Stmt *elsev) 826 : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL) 827 { 828 setConditionVariable(C, var); 829 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 830 SubExprs[THEN] = then; 831 SubExprs[ELSE] = elsev; 832 } 833 834 VarDecl *IfStmt::getConditionVariable() const { 835 if (!SubExprs[VAR]) 836 return 0; 837 838 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]); 839 return cast<VarDecl>(DS->getSingleDecl()); 840 } 841 842 void IfStmt::setConditionVariable(ASTContext &C, VarDecl *V) { 843 if (!V) { 844 SubExprs[VAR] = 0; 845 return; 846 } 847 848 SourceRange VarRange = V->getSourceRange(); 849 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), 850 VarRange.getEnd()); 851 } 852 853 ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, 854 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, 855 SourceLocation RP) 856 : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP) 857 { 858 SubExprs[INIT] = Init; 859 setConditionVariable(C, condVar); 860 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 861 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 862 SubExprs[BODY] = Body; 863 } 864 865 VarDecl *ForStmt::getConditionVariable() const { 866 if (!SubExprs[CONDVAR]) 867 return 0; 868 869 DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]); 870 return cast<VarDecl>(DS->getSingleDecl()); 871 } 872 873 void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) { 874 if (!V) { 875 SubExprs[CONDVAR] = 0; 876 return; 877 } 878 879 SourceRange VarRange = V->getSourceRange(); 880 SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), 881 VarRange.getEnd()); 882 } 883 884 SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond) 885 : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0) 886 { 887 setConditionVariable(C, Var); 888 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 889 SubExprs[BODY] = NULL; 890 } 891 892 VarDecl *SwitchStmt::getConditionVariable() const { 893 if (!SubExprs[VAR]) 894 return 0; 895 896 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]); 897 return cast<VarDecl>(DS->getSingleDecl()); 898 } 899 900 void SwitchStmt::setConditionVariable(ASTContext &C, VarDecl *V) { 901 if (!V) { 902 SubExprs[VAR] = 0; 903 return; 904 } 905 906 SourceRange VarRange = V->getSourceRange(); 907 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), 908 VarRange.getEnd()); 909 } 910 911 Stmt *SwitchCase::getSubStmt() { 912 if (isa<CaseStmt>(this)) 913 return cast<CaseStmt>(this)->getSubStmt(); 914 return cast<DefaultStmt>(this)->getSubStmt(); 915 } 916 917 WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 918 SourceLocation WL) 919 : Stmt(WhileStmtClass) { 920 setConditionVariable(C, Var); 921 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 922 SubExprs[BODY] = body; 923 WhileLoc = WL; 924 } 925 926 VarDecl *WhileStmt::getConditionVariable() const { 927 if (!SubExprs[VAR]) 928 return 0; 929 930 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]); 931 return cast<VarDecl>(DS->getSingleDecl()); 932 } 933 934 void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) { 935 if (!V) { 936 SubExprs[VAR] = 0; 937 return; 938 } 939 940 SourceRange VarRange = V->getSourceRange(); 941 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), 942 VarRange.getEnd()); 943 } 944 945 // IndirectGotoStmt 946 LabelDecl *IndirectGotoStmt::getConstantTarget() { 947 if (AddrLabelExpr *E = 948 dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts())) 949 return E->getLabel(); 950 return 0; 951 } 952 953 // ReturnStmt 954 const Expr* ReturnStmt::getRetValue() const { 955 return cast_or_null<Expr>(RetExpr); 956 } 957 Expr* ReturnStmt::getRetValue() { 958 return cast_or_null<Expr>(RetExpr); 959 } 960 961 SEHTryStmt::SEHTryStmt(bool IsCXXTry, 962 SourceLocation TryLoc, 963 Stmt *TryBlock, 964 Stmt *Handler) 965 : Stmt(SEHTryStmtClass), 966 IsCXXTry(IsCXXTry), 967 TryLoc(TryLoc) 968 { 969 Children[TRY] = TryBlock; 970 Children[HANDLER] = Handler; 971 } 972 973 SEHTryStmt* SEHTryStmt::Create(ASTContext &C, 974 bool IsCXXTry, 975 SourceLocation TryLoc, 976 Stmt *TryBlock, 977 Stmt *Handler) { 978 return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler); 979 } 980 981 SEHExceptStmt* SEHTryStmt::getExceptHandler() const { 982 return dyn_cast<SEHExceptStmt>(getHandler()); 983 } 984 985 SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const { 986 return dyn_cast<SEHFinallyStmt>(getHandler()); 987 } 988 989 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, 990 Expr *FilterExpr, 991 Stmt *Block) 992 : Stmt(SEHExceptStmtClass), 993 Loc(Loc) 994 { 995 Children[FILTER_EXPR] = reinterpret_cast<Stmt*>(FilterExpr); 996 Children[BLOCK] = Block; 997 } 998 999 SEHExceptStmt* SEHExceptStmt::Create(ASTContext &C, 1000 SourceLocation Loc, 1001 Expr *FilterExpr, 1002 Stmt *Block) { 1003 return new(C) SEHExceptStmt(Loc,FilterExpr,Block); 1004 } 1005 1006 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, 1007 Stmt *Block) 1008 : Stmt(SEHFinallyStmtClass), 1009 Loc(Loc), 1010 Block(Block) 1011 {} 1012 1013 SEHFinallyStmt* SEHFinallyStmt::Create(ASTContext &C, 1014 SourceLocation Loc, 1015 Stmt *Block) { 1016 return new(C)SEHFinallyStmt(Loc,Block); 1017 } 1018 1019 CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const { 1020 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1); 1021 1022 // Offset of the first Capture object. 1023 unsigned FirstCaptureOffset = 1024 llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); 1025 1026 return reinterpret_cast<Capture *>( 1027 reinterpret_cast<char *>(const_cast<CapturedStmt *>(this)) 1028 + FirstCaptureOffset); 1029 } 1030 1031 CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind, 1032 ArrayRef<Capture> Captures, 1033 ArrayRef<Expr *> CaptureInits, 1034 CapturedDecl *CD, 1035 RecordDecl *RD) 1036 : Stmt(CapturedStmtClass), NumCaptures(Captures.size()), 1037 CapDeclAndKind(CD, Kind), TheRecordDecl(RD) { 1038 assert( S && "null captured statement"); 1039 assert(CD && "null captured declaration for captured statement"); 1040 assert(RD && "null record declaration for captured statement"); 1041 1042 // Copy initialization expressions. 1043 Stmt **Stored = getStoredStmts(); 1044 for (unsigned I = 0, N = NumCaptures; I != N; ++I) 1045 *Stored++ = CaptureInits[I]; 1046 1047 // Copy the statement being captured. 1048 *Stored = S; 1049 1050 // Copy all Capture objects. 1051 Capture *Buffer = getStoredCaptures(); 1052 std::copy(Captures.begin(), Captures.end(), Buffer); 1053 } 1054 1055 CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures) 1056 : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures), 1057 CapDeclAndKind(0, CR_Default), TheRecordDecl(0) { 1058 getStoredStmts()[NumCaptures] = 0; 1059 } 1060 1061 CapturedStmt *CapturedStmt::Create(ASTContext &Context, Stmt *S, 1062 CapturedRegionKind Kind, 1063 ArrayRef<Capture> Captures, 1064 ArrayRef<Expr *> CaptureInits, 1065 CapturedDecl *CD, 1066 RecordDecl *RD) { 1067 // The layout is 1068 // 1069 // ----------------------------------------------------------- 1070 // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture | 1071 // ----------------^-------------------^---------------------- 1072 // getStoredStmts() getStoredCaptures() 1073 // 1074 // where S is the statement being captured. 1075 // 1076 assert(CaptureInits.size() == Captures.size() && "wrong number of arguments"); 1077 1078 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1); 1079 if (!Captures.empty()) { 1080 // Realign for the following Capture array. 1081 Size = llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); 1082 Size += sizeof(Capture) * Captures.size(); 1083 } 1084 1085 void *Mem = Context.Allocate(Size); 1086 return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD); 1087 } 1088 1089 CapturedStmt *CapturedStmt::CreateDeserialized(ASTContext &Context, 1090 unsigned NumCaptures) { 1091 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1); 1092 if (NumCaptures > 0) { 1093 // Realign for the following Capture array. 1094 Size = llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); 1095 Size += sizeof(Capture) * NumCaptures; 1096 } 1097 1098 void *Mem = Context.Allocate(Size); 1099 return new (Mem) CapturedStmt(EmptyShell(), NumCaptures); 1100 } 1101 1102 Stmt::child_range CapturedStmt::children() { 1103 // Children are captured field initilizers. 1104 return child_range(getStoredStmts(), getStoredStmts() + NumCaptures); 1105 } 1106 1107 bool CapturedStmt::capturesVariable(const VarDecl *Var) const { 1108 for (const_capture_iterator I = capture_begin(), 1109 E = capture_end(); I != E; ++I) { 1110 if (!I->capturesVariable()) 1111 continue; 1112 1113 // This does not handle variable redeclarations. This should be 1114 // extended to capture variables with redeclarations, for example 1115 // a thread-private variable in OpenMP. 1116 if (I->getCapturedVar() == Var) 1117 return true; 1118 } 1119 1120 return false; 1121 } 1122 1123 OMPPrivateClause *OMPPrivateClause::Create(ASTContext &C, 1124 SourceLocation StartLoc, 1125 SourceLocation LParenLoc, 1126 SourceLocation EndLoc, 1127 ArrayRef<Expr *> VL) { 1128 void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * VL.size(), 1129 llvm::alignOf<OMPPrivateClause>()); 1130 OMPPrivateClause *Clause = new (Mem) OMPPrivateClause(StartLoc, LParenLoc, 1131 EndLoc, VL.size()); 1132 Clause->setVarRefs(VL); 1133 return Clause; 1134 } 1135 1136 OMPPrivateClause *OMPPrivateClause::CreateEmpty(ASTContext &C, 1137 unsigned N) { 1138 void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * N, 1139 llvm::alignOf<OMPPrivateClause>()); 1140 return new (Mem) OMPPrivateClause(N); 1141 } 1142 1143 void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) { 1144 assert(Clauses.size() == this->Clauses.size() && 1145 "Number of clauses is not the same as the preallocated buffer"); 1146 std::copy(Clauses.begin(), Clauses.end(), this->Clauses.begin()); 1147 } 1148 1149 OMPParallelDirective *OMPParallelDirective::Create( 1150 ASTContext &C, 1151 SourceLocation StartLoc, 1152 SourceLocation EndLoc, 1153 ArrayRef<OMPClause *> Clauses, 1154 Stmt *AssociatedStmt) { 1155 void *Mem = C.Allocate(sizeof(OMPParallelDirective) + 1156 sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *), 1157 llvm::alignOf<OMPParallelDirective>()); 1158 OMPParallelDirective *Dir = new (Mem) OMPParallelDirective(StartLoc, EndLoc, 1159 Clauses.size()); 1160 Dir->setClauses(Clauses); 1161 Dir->setAssociatedStmt(AssociatedStmt); 1162 return Dir; 1163 } 1164 1165 OMPParallelDirective *OMPParallelDirective::CreateEmpty(ASTContext &C, 1166 unsigned N, 1167 EmptyShell) { 1168 void *Mem = C.Allocate(sizeof(OMPParallelDirective) + 1169 sizeof(OMPClause *) * N + sizeof(Stmt *), 1170 llvm::alignOf<OMPParallelDirective>()); 1171 return new (Mem) OMPParallelDirective(N); 1172 } 1173