Stmt.cpp revision 263508
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" 28using namespace clang; 29 30static struct StmtClassNameTable { 31 const char *Name; 32 unsigned Counter; 33 unsigned Size; 34} StmtClassInfo[Stmt::lastStmtConstant+1]; 35 36static 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 52void *Stmt::operator new(size_t bytes, const ASTContext& C, 53 unsigned alignment) { 54 return ::operator new(bytes, C, alignment); 55} 56 57const char *Stmt::getStmtClassName() const { 58 return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name; 59} 60 61void Stmt::PrintStats() { 62 // Ensure the table is primed. 63 getStmtInfoTableEntry(Stmt::NullStmtClass); 64 65 unsigned sum = 0; 66 llvm::errs() << "\n*** Stmt/Expr Stats:\n"; 67 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { 68 if (StmtClassInfo[i].Name == 0) continue; 69 sum += StmtClassInfo[i].Counter; 70 } 71 llvm::errs() << " " << sum << " stmts/exprs total.\n"; 72 sum = 0; 73 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { 74 if (StmtClassInfo[i].Name == 0) continue; 75 if (StmtClassInfo[i].Counter == 0) continue; 76 llvm::errs() << " " << StmtClassInfo[i].Counter << " " 77 << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size 78 << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size 79 << " bytes)\n"; 80 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size; 81 } 82 83 llvm::errs() << "Total bytes = " << sum << "\n"; 84} 85 86void Stmt::addStmtClass(StmtClass s) { 87 ++getStmtInfoTableEntry(s).Counter; 88} 89 90bool Stmt::StatisticsEnabled = false; 91void Stmt::EnableStatistics() { 92 StatisticsEnabled = true; 93} 94 95Stmt *Stmt::IgnoreImplicit() { 96 Stmt *s = this; 97 98 if (ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(s)) 99 s = ewc->getSubExpr(); 100 101 while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(s)) 102 s = ice->getSubExpr(); 103 104 return s; 105} 106 107/// \brief Strip off all label-like statements. 108/// 109/// This will strip off label statements, case statements, attributed 110/// statements and default statements recursively. 111const Stmt *Stmt::stripLabelLikeStatements() const { 112 const Stmt *S = this; 113 while (true) { 114 if (const LabelStmt *LS = dyn_cast<LabelStmt>(S)) 115 S = LS->getSubStmt(); 116 else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) 117 S = SC->getSubStmt(); 118 else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S)) 119 S = AS->getSubStmt(); 120 else 121 return S; 122 } 123} 124 125namespace { 126 struct good {}; 127 struct bad {}; 128 129 // These silly little functions have to be static inline to suppress 130 // unused warnings, and they have to be defined to suppress other 131 // warnings. 132 static inline good is_good(good) { return good(); } 133 134 typedef Stmt::child_range children_t(); 135 template <class T> good implements_children(children_t T::*) { 136 return good(); 137 } 138 LLVM_ATTRIBUTE_UNUSED 139 static inline bad implements_children(children_t Stmt::*) { 140 return bad(); 141 } 142 143 typedef SourceLocation getLocStart_t() const; 144 template <class T> good implements_getLocStart(getLocStart_t T::*) { 145 return good(); 146 } 147 LLVM_ATTRIBUTE_UNUSED 148 static inline bad implements_getLocStart(getLocStart_t Stmt::*) { 149 return bad(); 150 } 151 152 typedef SourceLocation getLocEnd_t() const; 153 template <class T> good implements_getLocEnd(getLocEnd_t T::*) { 154 return good(); 155 } 156 LLVM_ATTRIBUTE_UNUSED 157 static inline bad implements_getLocEnd(getLocEnd_t Stmt::*) { 158 return bad(); 159 } 160 161#define ASSERT_IMPLEMENTS_children(type) \ 162 (void) is_good(implements_children(&type::children)) 163#define ASSERT_IMPLEMENTS_getLocStart(type) \ 164 (void) is_good(implements_getLocStart(&type::getLocStart)) 165#define ASSERT_IMPLEMENTS_getLocEnd(type) \ 166 (void) is_good(implements_getLocEnd(&type::getLocEnd)) 167} 168 169/// Check whether the various Stmt classes implement their member 170/// functions. 171LLVM_ATTRIBUTE_UNUSED 172static inline void check_implementations() { 173#define ABSTRACT_STMT(type) 174#define STMT(type, base) \ 175 ASSERT_IMPLEMENTS_children(type); \ 176 ASSERT_IMPLEMENTS_getLocStart(type); \ 177 ASSERT_IMPLEMENTS_getLocEnd(type); 178#include "clang/AST/StmtNodes.inc" 179} 180 181Stmt::child_range Stmt::children() { 182 switch (getStmtClass()) { 183 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 184#define ABSTRACT_STMT(type) 185#define STMT(type, base) \ 186 case Stmt::type##Class: \ 187 return static_cast<type*>(this)->children(); 188#include "clang/AST/StmtNodes.inc" 189 } 190 llvm_unreachable("unknown statement kind!"); 191} 192 193// Amusing macro metaprogramming hack: check whether a class provides 194// a more specific implementation of getSourceRange. 195// 196// See also Expr.cpp:getExprLoc(). 197namespace { 198 /// This implementation is used when a class provides a custom 199 /// implementation of getSourceRange. 200 template <class S, class T> 201 SourceRange getSourceRangeImpl(const Stmt *stmt, 202 SourceRange (T::*v)() const) { 203 return static_cast<const S*>(stmt)->getSourceRange(); 204 } 205 206 /// This implementation is used when a class doesn't provide a custom 207 /// implementation of getSourceRange. Overload resolution should pick it over 208 /// the implementation above because it's more specialized according to 209 /// function template partial ordering. 210 template <class S> 211 SourceRange getSourceRangeImpl(const Stmt *stmt, 212 SourceRange (Stmt::*v)() const) { 213 return SourceRange(static_cast<const S*>(stmt)->getLocStart(), 214 static_cast<const S*>(stmt)->getLocEnd()); 215 } 216} 217 218SourceRange Stmt::getSourceRange() const { 219 switch (getStmtClass()) { 220 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 221#define ABSTRACT_STMT(type) 222#define STMT(type, base) \ 223 case Stmt::type##Class: \ 224 return getSourceRangeImpl<type>(this, &type::getSourceRange); 225#include "clang/AST/StmtNodes.inc" 226 } 227 llvm_unreachable("unknown statement kind!"); 228} 229 230SourceLocation Stmt::getLocStart() const { 231// llvm::errs() << "getLocStart() for " << getStmtClassName() << "\n"; 232 switch (getStmtClass()) { 233 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 234#define ABSTRACT_STMT(type) 235#define STMT(type, base) \ 236 case Stmt::type##Class: \ 237 return static_cast<const type*>(this)->getLocStart(); 238#include "clang/AST/StmtNodes.inc" 239 } 240 llvm_unreachable("unknown statement kind"); 241} 242 243SourceLocation Stmt::getLocEnd() const { 244 switch (getStmtClass()) { 245 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 246#define ABSTRACT_STMT(type) 247#define STMT(type, base) \ 248 case Stmt::type##Class: \ 249 return static_cast<const type*>(this)->getLocEnd(); 250#include "clang/AST/StmtNodes.inc" 251 } 252 llvm_unreachable("unknown statement kind"); 253} 254 255CompoundStmt::CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts, 256 SourceLocation LB, SourceLocation RB) 257 : Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) { 258 CompoundStmtBits.NumStmts = Stmts.size(); 259 assert(CompoundStmtBits.NumStmts == Stmts.size() && 260 "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!"); 261 262 if (Stmts.size() == 0) { 263 Body = 0; 264 return; 265 } 266 267 Body = new (C) Stmt*[Stmts.size()]; 268 std::copy(Stmts.begin(), Stmts.end(), Body); 269} 270 271void CompoundStmt::setStmts(const ASTContext &C, Stmt **Stmts, 272 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 281const char *LabelStmt::getName() const { 282 return getDecl()->getIdentifier()->getNameStart(); 283} 284 285AttributedStmt *AttributedStmt::Create(const 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 294AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C, 295 unsigned NumAttrs) { 296 assert(NumAttrs > 0 && "NumAttrs should be greater than zero"); 297 void *Mem = C.Allocate(sizeof(AttributedStmt) + 298 sizeof(Attr*) * (NumAttrs - 1), 299 llvm::alignOf<AttributedStmt>()); 300 return new (Mem) AttributedStmt(EmptyShell(), NumAttrs); 301} 302 303std::string AsmStmt::generateAsmString(const ASTContext &C) const { 304 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 305 return gccAsmStmt->generateAsmString(C); 306 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 307 return msAsmStmt->generateAsmString(C); 308 llvm_unreachable("unknown asm statement kind!"); 309} 310 311StringRef AsmStmt::getOutputConstraint(unsigned i) const { 312 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 313 return gccAsmStmt->getOutputConstraint(i); 314 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 315 return msAsmStmt->getOutputConstraint(i); 316 llvm_unreachable("unknown asm statement kind!"); 317} 318 319const Expr *AsmStmt::getOutputExpr(unsigned i) const { 320 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 321 return gccAsmStmt->getOutputExpr(i); 322 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 323 return msAsmStmt->getOutputExpr(i); 324 llvm_unreachable("unknown asm statement kind!"); 325} 326 327StringRef AsmStmt::getInputConstraint(unsigned i) const { 328 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 329 return gccAsmStmt->getInputConstraint(i); 330 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 331 return msAsmStmt->getInputConstraint(i); 332 llvm_unreachable("unknown asm statement kind!"); 333} 334 335const Expr *AsmStmt::getInputExpr(unsigned i) const { 336 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 337 return gccAsmStmt->getInputExpr(i); 338 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 339 return msAsmStmt->getInputExpr(i); 340 llvm_unreachable("unknown asm statement kind!"); 341} 342 343StringRef AsmStmt::getClobber(unsigned i) const { 344 if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(this)) 345 return gccAsmStmt->getClobber(i); 346 if (const MSAsmStmt *msAsmStmt = dyn_cast<MSAsmStmt>(this)) 347 return msAsmStmt->getClobber(i); 348 llvm_unreachable("unknown asm statement kind!"); 349} 350 351/// getNumPlusOperands - Return the number of output operands that have a "+" 352/// constraint. 353unsigned AsmStmt::getNumPlusOperands() const { 354 unsigned Res = 0; 355 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) 356 if (isOutputPlusConstraint(i)) 357 ++Res; 358 return Res; 359} 360 361StringRef GCCAsmStmt::getClobber(unsigned i) const { 362 return getClobberStringLiteral(i)->getString(); 363} 364 365Expr *GCCAsmStmt::getOutputExpr(unsigned i) { 366 return cast<Expr>(Exprs[i]); 367} 368 369/// getOutputConstraint - Return the constraint string for the specified 370/// output operand. All output constraints are known to be non-empty (either 371/// '=' or '+'). 372StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const { 373 return getOutputConstraintLiteral(i)->getString(); 374} 375 376Expr *GCCAsmStmt::getInputExpr(unsigned i) { 377 return cast<Expr>(Exprs[i + NumOutputs]); 378} 379void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) { 380 Exprs[i + NumOutputs] = E; 381} 382 383/// getInputConstraint - Return the specified input constraint. Unlike output 384/// constraints, these can be empty. 385StringRef GCCAsmStmt::getInputConstraint(unsigned i) const { 386 return getInputConstraintLiteral(i)->getString(); 387} 388 389void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C, 390 IdentifierInfo **Names, 391 StringLiteral **Constraints, 392 Stmt **Exprs, 393 unsigned NumOutputs, 394 unsigned NumInputs, 395 StringLiteral **Clobbers, 396 unsigned NumClobbers) { 397 this->NumOutputs = NumOutputs; 398 this->NumInputs = NumInputs; 399 this->NumClobbers = NumClobbers; 400 401 unsigned NumExprs = NumOutputs + NumInputs; 402 403 C.Deallocate(this->Names); 404 this->Names = new (C) IdentifierInfo*[NumExprs]; 405 std::copy(Names, Names + NumExprs, this->Names); 406 407 C.Deallocate(this->Exprs); 408 this->Exprs = new (C) Stmt*[NumExprs]; 409 std::copy(Exprs, Exprs + NumExprs, this->Exprs); 410 411 C.Deallocate(this->Constraints); 412 this->Constraints = new (C) StringLiteral*[NumExprs]; 413 std::copy(Constraints, Constraints + NumExprs, this->Constraints); 414 415 C.Deallocate(this->Clobbers); 416 this->Clobbers = new (C) StringLiteral*[NumClobbers]; 417 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers); 418} 419 420/// getNamedOperand - Given a symbolic operand reference like %[foo], 421/// translate this into a numeric value needed to reference the same operand. 422/// This returns -1 if the operand name is invalid. 423int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const { 424 unsigned NumPlusOperands = 0; 425 426 // Check if this is an output operand. 427 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) { 428 if (getOutputName(i) == SymbolicName) 429 return i; 430 } 431 432 for (unsigned i = 0, e = getNumInputs(); i != e; ++i) 433 if (getInputName(i) == SymbolicName) 434 return getNumOutputs() + NumPlusOperands + i; 435 436 // Not found. 437 return -1; 438} 439 440/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing 441/// it into pieces. If the asm string is erroneous, emit errors and return 442/// true, otherwise return false. 443unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces, 444 const ASTContext &C, unsigned &DiagOffs) const { 445 StringRef Str = getAsmString()->getString(); 446 const char *StrStart = Str.begin(); 447 const char *StrEnd = Str.end(); 448 const char *CurPtr = StrStart; 449 450 // "Simple" inline asms have no constraints or operands, just convert the asm 451 // string to escape $'s. 452 if (isSimple()) { 453 std::string Result; 454 for (; CurPtr != StrEnd; ++CurPtr) { 455 switch (*CurPtr) { 456 case '$': 457 Result += "$$"; 458 break; 459 default: 460 Result += *CurPtr; 461 break; 462 } 463 } 464 Pieces.push_back(AsmStringPiece(Result)); 465 return 0; 466 } 467 468 // CurStringPiece - The current string that we are building up as we scan the 469 // asm string. 470 std::string CurStringPiece; 471 472 bool HasVariants = !C.getTargetInfo().hasNoAsmVariants(); 473 474 while (1) { 475 // Done with the string? 476 if (CurPtr == StrEnd) { 477 if (!CurStringPiece.empty()) 478 Pieces.push_back(AsmStringPiece(CurStringPiece)); 479 return 0; 480 } 481 482 char CurChar = *CurPtr++; 483 switch (CurChar) { 484 case '$': CurStringPiece += "$$"; continue; 485 case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue; 486 case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue; 487 case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue; 488 case '%': 489 break; 490 default: 491 CurStringPiece += CurChar; 492 continue; 493 } 494 495 // Escaped "%" character in asm string. 496 if (CurPtr == StrEnd) { 497 // % at end of string is invalid (no escape). 498 DiagOffs = CurPtr-StrStart-1; 499 return diag::err_asm_invalid_escape; 500 } 501 502 char EscapedChar = *CurPtr++; 503 if (EscapedChar == '%') { // %% -> % 504 // Escaped percentage sign. 505 CurStringPiece += '%'; 506 continue; 507 } 508 509 if (EscapedChar == '=') { // %= -> Generate an unique ID. 510 CurStringPiece += "${:uid}"; 511 continue; 512 } 513 514 // Otherwise, we have an operand. If we have accumulated a string so far, 515 // add it to the Pieces list. 516 if (!CurStringPiece.empty()) { 517 Pieces.push_back(AsmStringPiece(CurStringPiece)); 518 CurStringPiece.clear(); 519 } 520 521 // Handle %x4 and %x[foo] by capturing x as the modifier character. 522 char Modifier = '\0'; 523 if (isLetter(EscapedChar)) { 524 if (CurPtr == StrEnd) { // Premature end. 525 DiagOffs = CurPtr-StrStart-1; 526 return diag::err_asm_invalid_escape; 527 } 528 Modifier = EscapedChar; 529 EscapedChar = *CurPtr++; 530 } 531 532 if (isDigit(EscapedChar)) { 533 // %n - Assembler operand n 534 unsigned N = 0; 535 536 --CurPtr; 537 while (CurPtr != StrEnd && isDigit(*CurPtr)) 538 N = N*10 + ((*CurPtr++)-'0'); 539 540 unsigned NumOperands = 541 getNumOutputs() + getNumPlusOperands() + getNumInputs(); 542 if (N >= NumOperands) { 543 DiagOffs = CurPtr-StrStart-1; 544 return diag::err_asm_invalid_operand_number; 545 } 546 547 Pieces.push_back(AsmStringPiece(N, Modifier)); 548 continue; 549 } 550 551 // Handle %[foo], a symbolic operand reference. 552 if (EscapedChar == '[') { 553 DiagOffs = CurPtr-StrStart-1; 554 555 // Find the ']'. 556 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr); 557 if (NameEnd == 0) 558 return diag::err_asm_unterminated_symbolic_operand_name; 559 if (NameEnd == CurPtr) 560 return diag::err_asm_empty_symbolic_operand_name; 561 562 StringRef SymbolicName(CurPtr, NameEnd - CurPtr); 563 564 int N = getNamedOperand(SymbolicName); 565 if (N == -1) { 566 // Verify that an operand with that name exists. 567 DiagOffs = CurPtr-StrStart; 568 return diag::err_asm_unknown_symbolic_operand_name; 569 } 570 Pieces.push_back(AsmStringPiece(N, Modifier)); 571 572 CurPtr = NameEnd+1; 573 continue; 574 } 575 576 DiagOffs = CurPtr-StrStart-1; 577 return diag::err_asm_invalid_escape; 578 } 579} 580 581/// Assemble final IR asm string (GCC-style). 582std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const { 583 // Analyze the asm string to decompose it into its pieces. We know that Sema 584 // has already done this, so it is guaranteed to be successful. 585 SmallVector<GCCAsmStmt::AsmStringPiece, 4> Pieces; 586 unsigned DiagOffs; 587 AnalyzeAsmString(Pieces, C, DiagOffs); 588 589 std::string AsmString; 590 for (unsigned i = 0, e = Pieces.size(); i != e; ++i) { 591 if (Pieces[i].isString()) 592 AsmString += Pieces[i].getString(); 593 else if (Pieces[i].getModifier() == '\0') 594 AsmString += '$' + llvm::utostr(Pieces[i].getOperandNo()); 595 else 596 AsmString += "${" + llvm::utostr(Pieces[i].getOperandNo()) + ':' + 597 Pieces[i].getModifier() + '}'; 598 } 599 return AsmString; 600} 601 602/// Assemble final IR asm string (MS-style). 603std::string MSAsmStmt::generateAsmString(const ASTContext &C) const { 604 // FIXME: This needs to be translated into the IR string representation. 605 return AsmStr; 606} 607 608Expr *MSAsmStmt::getOutputExpr(unsigned i) { 609 return cast<Expr>(Exprs[i]); 610} 611 612Expr *MSAsmStmt::getInputExpr(unsigned i) { 613 return cast<Expr>(Exprs[i + NumOutputs]); 614} 615void MSAsmStmt::setInputExpr(unsigned i, Expr *E) { 616 Exprs[i + NumOutputs] = E; 617} 618 619QualType CXXCatchStmt::getCaughtType() const { 620 if (ExceptionDecl) 621 return ExceptionDecl->getType(); 622 return QualType(); 623} 624 625//===----------------------------------------------------------------------===// 626// Constructors 627//===----------------------------------------------------------------------===// 628 629GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, 630 bool issimple, bool isvolatile, unsigned numoutputs, 631 unsigned numinputs, IdentifierInfo **names, 632 StringLiteral **constraints, Expr **exprs, 633 StringLiteral *asmstr, unsigned numclobbers, 634 StringLiteral **clobbers, SourceLocation rparenloc) 635 : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs, 636 numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) { 637 638 unsigned NumExprs = NumOutputs + NumInputs; 639 640 Names = new (C) IdentifierInfo*[NumExprs]; 641 std::copy(names, names + NumExprs, Names); 642 643 Exprs = new (C) Stmt*[NumExprs]; 644 std::copy(exprs, exprs + NumExprs, Exprs); 645 646 Constraints = new (C) StringLiteral*[NumExprs]; 647 std::copy(constraints, constraints + NumExprs, Constraints); 648 649 Clobbers = new (C) StringLiteral*[NumClobbers]; 650 std::copy(clobbers, clobbers + NumClobbers, Clobbers); 651} 652 653MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc, 654 SourceLocation lbraceloc, bool issimple, bool isvolatile, 655 ArrayRef<Token> asmtoks, unsigned numoutputs, 656 unsigned numinputs, 657 ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs, 658 StringRef asmstr, ArrayRef<StringRef> clobbers, 659 SourceLocation endloc) 660 : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs, 661 numinputs, clobbers.size()), LBraceLoc(lbraceloc), 662 EndLoc(endloc), NumAsmToks(asmtoks.size()) { 663 664 initialize(C, asmstr, asmtoks, constraints, exprs, clobbers); 665} 666 667static StringRef copyIntoContext(const ASTContext &C, StringRef str) { 668 size_t size = str.size(); 669 char *buffer = new (C) char[size]; 670 memcpy(buffer, str.data(), size); 671 return StringRef(buffer, size); 672} 673 674void MSAsmStmt::initialize(const ASTContext &C, 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 708ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, 709 Stmt *Body, SourceLocation FCL, 710 SourceLocation RPL) 711: Stmt(ObjCForCollectionStmtClass) { 712 SubExprs[ELEM] = Elem; 713 SubExprs[COLLECTION] = Collect; 714 SubExprs[BODY] = Body; 715 ForLoc = FCL; 716 RParenLoc = RPL; 717} 718 719ObjCAtTryStmt::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 734ObjCAtTryStmt *ObjCAtTryStmt::Create(const 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 747ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(const 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 756SourceLocation 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 764CXXTryStmt *CXXTryStmt::Create(const 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 773CXXTryStmt *CXXTryStmt::Create(const 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 782CXXTryStmt::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 790CXXForRangeStmt::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] = Cond; 798 SubExprs[INC] = Inc; 799 SubExprs[LOOPVAR] = LoopVar; 800 SubExprs[BODY] = Body; 801} 802 803Expr *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 810const Expr *CXXForRangeStmt::getRangeInit() const { 811 return const_cast<CXXForRangeStmt*>(this)->getRangeInit(); 812} 813 814VarDecl *CXXForRangeStmt::getLoopVariable() { 815 Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl(); 816 assert(LV && "No loop variable in CXXForRangeStmt"); 817 return cast<VarDecl>(LV); 818} 819 820const VarDecl *CXXForRangeStmt::getLoopVariable() const { 821 return const_cast<CXXForRangeStmt*>(this)->getLoopVariable(); 822} 823 824IfStmt::IfStmt(const 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] = cond; 830 SubExprs[THEN] = then; 831 SubExprs[ELSE] = elsev; 832} 833 834VarDecl *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 842void IfStmt::setConditionVariable(const 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 853ForStmt::ForStmt(const 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] = Cond; 861 SubExprs[INC] = Inc; 862 SubExprs[BODY] = Body; 863} 864 865VarDecl *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 873void ForStmt::setConditionVariable(const 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 884SwitchStmt::SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond) 885 : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0) 886{ 887 setConditionVariable(C, Var); 888 SubExprs[COND] = cond; 889 SubExprs[BODY] = NULL; 890} 891 892VarDecl *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 900void SwitchStmt::setConditionVariable(const 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 911Stmt *SwitchCase::getSubStmt() { 912 if (isa<CaseStmt>(this)) 913 return cast<CaseStmt>(this)->getSubStmt(); 914 return cast<DefaultStmt>(this)->getSubStmt(); 915} 916 917WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 918 SourceLocation WL) 919 : Stmt(WhileStmtClass) { 920 setConditionVariable(C, Var); 921 SubExprs[COND] = cond; 922 SubExprs[BODY] = body; 923 WhileLoc = WL; 924} 925 926VarDecl *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 934void WhileStmt::setConditionVariable(const 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 946LabelDecl *IndirectGotoStmt::getConstantTarget() { 947 if (AddrLabelExpr *E = 948 dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts())) 949 return E->getLabel(); 950 return 0; 951} 952 953// ReturnStmt 954const Expr* ReturnStmt::getRetValue() const { 955 return cast_or_null<Expr>(RetExpr); 956} 957Expr* ReturnStmt::getRetValue() { 958 return cast_or_null<Expr>(RetExpr); 959} 960 961SEHTryStmt::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 973SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry, 974 SourceLocation TryLoc, Stmt *TryBlock, 975 Stmt *Handler) { 976 return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler); 977} 978 979SEHExceptStmt* SEHTryStmt::getExceptHandler() const { 980 return dyn_cast<SEHExceptStmt>(getHandler()); 981} 982 983SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const { 984 return dyn_cast<SEHFinallyStmt>(getHandler()); 985} 986 987SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, 988 Expr *FilterExpr, 989 Stmt *Block) 990 : Stmt(SEHExceptStmtClass), 991 Loc(Loc) 992{ 993 Children[FILTER_EXPR] = FilterExpr; 994 Children[BLOCK] = Block; 995} 996 997SEHExceptStmt* SEHExceptStmt::Create(const ASTContext &C, SourceLocation Loc, 998 Expr *FilterExpr, Stmt *Block) { 999 return new(C) SEHExceptStmt(Loc,FilterExpr,Block); 1000} 1001 1002SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, 1003 Stmt *Block) 1004 : Stmt(SEHFinallyStmtClass), 1005 Loc(Loc), 1006 Block(Block) 1007{} 1008 1009SEHFinallyStmt* SEHFinallyStmt::Create(const ASTContext &C, SourceLocation Loc, 1010 Stmt *Block) { 1011 return new(C)SEHFinallyStmt(Loc,Block); 1012} 1013 1014CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const { 1015 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1); 1016 1017 // Offset of the first Capture object. 1018 unsigned FirstCaptureOffset = 1019 llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); 1020 1021 return reinterpret_cast<Capture *>( 1022 reinterpret_cast<char *>(const_cast<CapturedStmt *>(this)) 1023 + FirstCaptureOffset); 1024} 1025 1026CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind, 1027 ArrayRef<Capture> Captures, 1028 ArrayRef<Expr *> CaptureInits, 1029 CapturedDecl *CD, 1030 RecordDecl *RD) 1031 : Stmt(CapturedStmtClass), NumCaptures(Captures.size()), 1032 CapDeclAndKind(CD, Kind), TheRecordDecl(RD) { 1033 assert( S && "null captured statement"); 1034 assert(CD && "null captured declaration for captured statement"); 1035 assert(RD && "null record declaration for captured statement"); 1036 1037 // Copy initialization expressions. 1038 Stmt **Stored = getStoredStmts(); 1039 for (unsigned I = 0, N = NumCaptures; I != N; ++I) 1040 *Stored++ = CaptureInits[I]; 1041 1042 // Copy the statement being captured. 1043 *Stored = S; 1044 1045 // Copy all Capture objects. 1046 Capture *Buffer = getStoredCaptures(); 1047 std::copy(Captures.begin(), Captures.end(), Buffer); 1048} 1049 1050CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures) 1051 : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures), 1052 CapDeclAndKind(0, CR_Default), TheRecordDecl(0) { 1053 getStoredStmts()[NumCaptures] = 0; 1054} 1055 1056CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S, 1057 CapturedRegionKind Kind, 1058 ArrayRef<Capture> Captures, 1059 ArrayRef<Expr *> CaptureInits, 1060 CapturedDecl *CD, 1061 RecordDecl *RD) { 1062 // The layout is 1063 // 1064 // ----------------------------------------------------------- 1065 // | CapturedStmt, Init, ..., Init, S, Capture, ..., Capture | 1066 // ----------------^-------------------^---------------------- 1067 // getStoredStmts() getStoredCaptures() 1068 // 1069 // where S is the statement being captured. 1070 // 1071 assert(CaptureInits.size() == Captures.size() && "wrong number of arguments"); 1072 1073 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (Captures.size() + 1); 1074 if (!Captures.empty()) { 1075 // Realign for the following Capture array. 1076 Size = llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); 1077 Size += sizeof(Capture) * Captures.size(); 1078 } 1079 1080 void *Mem = Context.Allocate(Size); 1081 return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD); 1082} 1083 1084CapturedStmt *CapturedStmt::CreateDeserialized(const ASTContext &Context, 1085 unsigned NumCaptures) { 1086 unsigned Size = sizeof(CapturedStmt) + sizeof(Stmt *) * (NumCaptures + 1); 1087 if (NumCaptures > 0) { 1088 // Realign for the following Capture array. 1089 Size = llvm::RoundUpToAlignment(Size, llvm::alignOf<Capture>()); 1090 Size += sizeof(Capture) * NumCaptures; 1091 } 1092 1093 void *Mem = Context.Allocate(Size); 1094 return new (Mem) CapturedStmt(EmptyShell(), NumCaptures); 1095} 1096 1097Stmt::child_range CapturedStmt::children() { 1098 // Children are captured field initilizers. 1099 return child_range(getStoredStmts(), getStoredStmts() + NumCaptures); 1100} 1101 1102bool CapturedStmt::capturesVariable(const VarDecl *Var) const { 1103 for (const_capture_iterator I = capture_begin(), 1104 E = capture_end(); I != E; ++I) { 1105 if (!I->capturesVariable()) 1106 continue; 1107 1108 // This does not handle variable redeclarations. This should be 1109 // extended to capture variables with redeclarations, for example 1110 // a thread-private variable in OpenMP. 1111 if (I->getCapturedVar() == Var) 1112 return true; 1113 } 1114 1115 return false; 1116} 1117 1118StmtRange OMPClause::children() { 1119 switch(getClauseKind()) { 1120 default : break; 1121#define OPENMP_CLAUSE(Name, Class) \ 1122 case OMPC_ ## Name : return static_cast<Class *>(this)->children(); 1123#include "clang/Basic/OpenMPKinds.def" 1124 } 1125 llvm_unreachable("unknown OMPClause"); 1126} 1127 1128OMPPrivateClause *OMPPrivateClause::Create(const ASTContext &C, 1129 SourceLocation StartLoc, 1130 SourceLocation LParenLoc, 1131 SourceLocation EndLoc, 1132 ArrayRef<Expr *> VL) { 1133 void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * VL.size(), 1134 llvm::alignOf<OMPPrivateClause>()); 1135 OMPPrivateClause *Clause = new (Mem) OMPPrivateClause(StartLoc, LParenLoc, 1136 EndLoc, VL.size()); 1137 Clause->setVarRefs(VL); 1138 return Clause; 1139} 1140 1141OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C, 1142 unsigned N) { 1143 void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * N, 1144 llvm::alignOf<OMPPrivateClause>()); 1145 return new (Mem) OMPPrivateClause(N); 1146} 1147 1148OMPFirstprivateClause *OMPFirstprivateClause::Create(const ASTContext &C, 1149 SourceLocation StartLoc, 1150 SourceLocation LParenLoc, 1151 SourceLocation EndLoc, 1152 ArrayRef<Expr *> VL) { 1153 void *Mem = C.Allocate(sizeof(OMPFirstprivateClause) + 1154 sizeof(Expr *) * VL.size(), 1155 llvm::alignOf<OMPFirstprivateClause>()); 1156 OMPFirstprivateClause *Clause = new (Mem) OMPFirstprivateClause(StartLoc, 1157 LParenLoc, 1158 EndLoc, 1159 VL.size()); 1160 Clause->setVarRefs(VL); 1161 return Clause; 1162} 1163 1164OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C, 1165 unsigned N) { 1166 void *Mem = C.Allocate(sizeof(OMPFirstprivateClause) + sizeof(Expr *) * N, 1167 llvm::alignOf<OMPFirstprivateClause>()); 1168 return new (Mem) OMPFirstprivateClause(N); 1169} 1170 1171OMPSharedClause *OMPSharedClause::Create(const ASTContext &C, 1172 SourceLocation StartLoc, 1173 SourceLocation LParenLoc, 1174 SourceLocation EndLoc, 1175 ArrayRef<Expr *> VL) { 1176 void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *) * VL.size(), 1177 llvm::alignOf<OMPSharedClause>()); 1178 OMPSharedClause *Clause = new (Mem) OMPSharedClause(StartLoc, LParenLoc, 1179 EndLoc, VL.size()); 1180 Clause->setVarRefs(VL); 1181 return Clause; 1182} 1183 1184OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, 1185 unsigned N) { 1186 void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *) * N, 1187 llvm::alignOf<OMPSharedClause>()); 1188 return new (Mem) OMPSharedClause(N); 1189} 1190 1191void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) { 1192 assert(Clauses.size() == this->Clauses.size() && 1193 "Number of clauses is not the same as the preallocated buffer"); 1194 std::copy(Clauses.begin(), Clauses.end(), this->Clauses.begin()); 1195} 1196 1197OMPParallelDirective *OMPParallelDirective::Create( 1198 const ASTContext &C, 1199 SourceLocation StartLoc, 1200 SourceLocation EndLoc, 1201 ArrayRef<OMPClause *> Clauses, 1202 Stmt *AssociatedStmt) { 1203 void *Mem = C.Allocate(sizeof(OMPParallelDirective) + 1204 sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *), 1205 llvm::alignOf<OMPParallelDirective>()); 1206 OMPParallelDirective *Dir = new (Mem) OMPParallelDirective(StartLoc, EndLoc, 1207 Clauses.size()); 1208 Dir->setClauses(Clauses); 1209 Dir->setAssociatedStmt(AssociatedStmt); 1210 return Dir; 1211} 1212 1213OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C, 1214 unsigned N, 1215 EmptyShell) { 1216 void *Mem = C.Allocate(sizeof(OMPParallelDirective) + 1217 sizeof(OMPClause *) * N + sizeof(Stmt *), 1218 llvm::alignOf<OMPParallelDirective>()); 1219 return new (Mem) OMPParallelDirective(N); 1220} 1221