32 #include "llvm/ADT/SmallVector.h" 33 #include "llvm/ADT/StringExtras.h" 34 #include "llvm/ADT/StringRef.h" 35 #include "llvm/Support/Casting.h" 36 #include "llvm/Support/Compiler.h" 37 #include "llvm/Support/ErrorHandling.h" 38 #include "llvm/Support/MathExtras.h" 39 #include "llvm/Support/raw_ostream.h" 46 using namespace clang;
61 #define ABSTRACT_STMT(STMT) 62 #define STMT(CLASS, PARENT) \ 63 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \ 64 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS); 65 #include "clang/AST/StmtNodes.inc" 72 return ::operator
new(
bytes,
C, alignment);
82 #define STMT(CLASS, PARENT) \ 83 static_assert(!std::is_polymorphic<CLASS>::value, \ 84 #CLASS " should not be polymorphic!"); 85 #include "clang/AST/StmtNodes.inc" 92 llvm::errs() <<
"\n*** Stmt/Expr Stats:\n";
93 for (
int i = 0; i != Stmt::lastStmtConstant+1; i++) {
97 llvm::errs() <<
" " << sum <<
" stmts/exprs total.\n";
99 for (
int i = 0; i != Stmt::lastStmtConstant+1; i++) {
109 llvm::errs() <<
"Total bytes = " << sum <<
"\n";
116 bool Stmt::StatisticsEnabled =
false;
118 StatisticsEnabled =
true;
124 Stmt *lasts =
nullptr;
129 if (
auto *fe = dyn_cast<FullExpr>(s))
130 s = fe->getSubExpr();
132 if (
auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
133 s = mte->GetTemporaryExpr();
135 if (
auto *bte = dyn_cast<CXXBindTemporaryExpr>(s))
136 s = bte->getSubExpr();
138 if (
auto *ice = dyn_cast<ImplicitCastExpr>(s))
139 s = ice->getSubExpr();
150 if (
auto CapS = dyn_cast_or_null<CapturedStmt>(S))
151 S = CapS->getCapturedStmt();
153 if (
auto AS = dyn_cast_or_null<AttributedStmt>(S))
154 S = AS->getSubStmt();
155 else if (
auto CS = dyn_cast_or_null<CompoundStmt>(S)) {
170 const Stmt *S =
this;
172 if (
const auto *LS = dyn_cast<LabelStmt>(S))
173 S = LS->getSubStmt();
174 else if (
const auto *SC = dyn_cast<SwitchCase>(S))
175 S = SC->getSubStmt();
176 else if (
const auto *AS = dyn_cast<AttributedStmt>(S))
177 S = AS->getSubStmt();
191 static good is_good(good) {
return good(); }
194 template <
class T> good implements_children(children_t T::*) {
197 LLVM_ATTRIBUTE_UNUSED
198 static bad implements_children(children_t
Stmt::*) {
203 template <
class T> good implements_getBeginLoc(getBeginLoc_t T::*) {
206 LLVM_ATTRIBUTE_UNUSED
207 static bad implements_getBeginLoc(getBeginLoc_t
Stmt::*) {
return bad(); }
210 template <
class T> good implements_getEndLoc(getLocEnd_t T::*) {
213 LLVM_ATTRIBUTE_UNUSED
214 static bad implements_getEndLoc(getLocEnd_t
Stmt::*) {
return bad(); }
216 #define ASSERT_IMPLEMENTS_children(type) \ 217 (void) is_good(implements_children(&type::children)) 218 #define ASSERT_IMPLEMENTS_getBeginLoc(type) \ 219 (void)is_good(implements_getBeginLoc(&type::getBeginLoc)) 220 #define ASSERT_IMPLEMENTS_getEndLoc(type) \ 221 (void)is_good(implements_getEndLoc(&type::getEndLoc)) 227 LLVM_ATTRIBUTE_UNUSED
229 #define ABSTRACT_STMT(type) 230 #define STMT(type, base) \ 231 ASSERT_IMPLEMENTS_children(type); \ 232 ASSERT_IMPLEMENTS_getBeginLoc(type); \ 233 ASSERT_IMPLEMENTS_getEndLoc(type); 234 #include "clang/AST/StmtNodes.inc" 238 switch (getStmtClass()) {
240 #define ABSTRACT_STMT(type) 241 #define STMT(type, base) \ 242 case Stmt::type##Class: \ 243 return static_cast<type*>(this)->children(); 244 #include "clang/AST/StmtNodes.inc" 246 llvm_unreachable(
"unknown statement kind!");
257 template <
class S,
class T>
270 return SourceRange(static_cast<const S *>(stmt)->getBeginLoc(),
271 static_cast<const S *>(stmt)->getEndLoc());
277 switch (getStmtClass()) {
279 #define ABSTRACT_STMT(type) 280 #define STMT(type, base) \ 281 case Stmt::type##Class: \ 282 return getSourceRangeImpl<type>(this, &type::getSourceRange); 283 #include "clang/AST/StmtNodes.inc" 285 llvm_unreachable(
"unknown statement kind!");
290 switch (getStmtClass()) {
292 #define ABSTRACT_STMT(type) 293 #define STMT(type, base) \ 294 case Stmt::type##Class: \ 295 return static_cast<const type *>(this)->getBeginLoc(); 296 #include "clang/AST/StmtNodes.inc" 298 llvm_unreachable(
"unknown statement kind");
302 switch (getStmtClass()) {
304 #define ABSTRACT_STMT(type) 305 #define STMT(type, base) \ 306 case Stmt::type##Class: \ 307 return static_cast<const type *>(this)->getEndLoc(); 308 #include "clang/AST/StmtNodes.inc" 310 llvm_unreachable(
"unknown statement kind");
319 :
Stmt(CompoundStmtClass), RBraceLoc(RB) {
320 CompoundStmtBits.NumStmts = Stmts.size();
322 CompoundStmtBits.LBraceLoc = LB;
326 assert(CompoundStmtBits.NumStmts == Stmts.size() &&
327 "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
329 std::copy(Stmts.begin(), Stmts.end(), body_begin());
349 return getDecl()->getIdentifier()->getNameStart();
355 assert(!Attrs.empty() &&
"Attrs should not be empty");
356 void *Mem = C.
Allocate(totalSizeToAlloc<const Attr *>(Attrs.size()),
363 assert(NumAttrs > 0 &&
"NumAttrs should be greater than zero");
364 void *Mem = C.
Allocate(totalSizeToAlloc<const Attr *>(NumAttrs),
370 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
371 return gccAsmStmt->generateAsmString(C);
372 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
373 return msAsmStmt->generateAsmString(C);
374 llvm_unreachable(
"unknown asm statement kind!");
378 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
379 return gccAsmStmt->getOutputConstraint(i);
380 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
381 return msAsmStmt->getOutputConstraint(i);
382 llvm_unreachable(
"unknown asm statement kind!");
386 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
387 return gccAsmStmt->getOutputExpr(i);
388 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
389 return msAsmStmt->getOutputExpr(i);
390 llvm_unreachable(
"unknown asm statement kind!");
394 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
395 return gccAsmStmt->getInputConstraint(i);
396 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
397 return msAsmStmt->getInputConstraint(i);
398 llvm_unreachable(
"unknown asm statement kind!");
402 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
403 return gccAsmStmt->getInputExpr(i);
404 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
405 return msAsmStmt->getInputExpr(i);
406 llvm_unreachable(
"unknown asm statement kind!");
410 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
411 return gccAsmStmt->getClobber(i);
412 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
413 return msAsmStmt->getClobber(i);
414 llvm_unreachable(
"unknown asm statement kind!");
421 for (
unsigned i = 0, e = getNumOutputs(); i != e; ++i)
422 if (isOutputPlusConstraint(i))
428 assert(isOperand() &&
"Only Operands can have modifiers.");
429 return isLetter(Str[0]) ? Str[0] :
'\0';
433 return getClobberStringLiteral(i)->getString();
437 return cast<Expr>(Exprs[i]);
444 return getOutputConstraintLiteral(i)->getString();
448 return cast<Expr>(Exprs[i + NumOutputs]);
452 Exprs[i + NumOutputs] = E;
458 return getInputConstraintLiteral(i)->getString();
461 void GCCAsmStmt::setOutputsAndInputsAndClobbers(
const ASTContext &
C,
468 unsigned NumClobbers) {
469 this->NumOutputs = NumOutputs;
470 this->NumInputs = NumInputs;
471 this->NumClobbers = NumClobbers;
473 unsigned NumExprs = NumOutputs + NumInputs;
477 std::copy(Names, Names + NumExprs, this->Names);
480 this->Exprs =
new (
C)
Stmt*[NumExprs];
481 std::copy(Exprs, Exprs + NumExprs, this->Exprs);
485 std::copy(Constraints, Constraints + NumExprs, this->Constraints);
489 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
496 unsigned NumPlusOperands = 0;
499 for (
unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
500 if (getOutputName(i) == SymbolicName)
504 for (
unsigned i = 0, e = getNumInputs(); i != e; ++i)
505 if (getInputName(i) == SymbolicName)
506 return getNumOutputs() + NumPlusOperands + i;
516 const ASTContext &C,
unsigned &DiagOffs)
const {
517 StringRef Str = getAsmString()->getString();
518 const char *StrStart = Str.begin();
519 const char *StrEnd = Str.end();
520 const char *CurPtr = StrStart;
526 for (; CurPtr != StrEnd; ++CurPtr) {
542 std::string CurStringPiece;
546 unsigned LastAsmStringToken = 0;
547 unsigned LastAsmStringOffset = 0;
551 if (CurPtr == StrEnd) {
552 if (!CurStringPiece.empty())
557 char CurChar = *CurPtr++;
559 case '$': CurStringPiece +=
"$$";
continue;
560 case '{': CurStringPiece += (HasVariants ?
"$(" :
"{");
continue;
561 case '|': CurStringPiece += (HasVariants ?
"$|" :
"|");
continue;
562 case '}': CurStringPiece += (HasVariants ?
"$)" :
"}");
continue;
566 CurStringPiece += CurChar;
571 if (CurPtr == StrEnd) {
573 DiagOffs = CurPtr-StrStart-1;
574 return diag::err_asm_invalid_escape;
577 char EscapedChar = *CurPtr++;
578 switch (EscapedChar) {
584 CurStringPiece += EscapedChar;
587 CurStringPiece +=
"${:uid}";
593 if (!CurStringPiece.empty()) {
595 CurStringPiece.clear();
601 const char *
Begin = CurPtr - 1;
602 const char *Percent = Begin - 1;
605 if (CurPtr == StrEnd) {
606 DiagOffs = CurPtr-StrStart-1;
607 return diag::err_asm_invalid_escape;
609 EscapedChar = *CurPtr++;
622 while (CurPtr != StrEnd &&
isDigit(*CurPtr))
623 N = N*10 + ((*CurPtr++)-
'0');
625 unsigned NumOperands =
626 getNumOutputs() + getNumPlusOperands() + getNumInputs();
627 if (N >= NumOperands) {
628 DiagOffs = CurPtr-StrStart-1;
629 return diag::err_asm_invalid_operand_number;
633 std::string Str(Begin, CurPtr - Begin);
638 Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
639 &LastAsmStringOffset);
641 CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
642 &LastAsmStringOffset);
644 Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
649 if (EscapedChar ==
'[') {
650 DiagOffs = CurPtr-StrStart-1;
653 const char *NameEnd = (
const char*)memchr(CurPtr,
']', StrEnd-CurPtr);
654 if (NameEnd ==
nullptr)
655 return diag::err_asm_unterminated_symbolic_operand_name;
656 if (NameEnd == CurPtr)
657 return diag::err_asm_empty_symbolic_operand_name;
659 StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
661 int N = getNamedOperand(SymbolicName);
664 DiagOffs = CurPtr-StrStart;
665 return diag::err_asm_unknown_symbolic_operand_name;
669 std::string Str(Begin, NameEnd + 1 - Begin);
674 Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
675 &LastAsmStringOffset);
677 NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
678 &LastAsmStringOffset);
680 Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
686 DiagOffs = CurPtr-StrStart-1;
687 return diag::err_asm_invalid_escape;
697 AnalyzeAsmString(Pieces, C, DiagOffs);
699 std::string AsmString;
700 for (
const auto &Piece : Pieces) {
701 if (Piece.isString())
702 AsmString += Piece.getString();
703 else if (Piece.getModifier() ==
'\0')
704 AsmString +=
'$' + llvm::utostr(Piece.getOperandNo());
706 AsmString +=
"${" + llvm::utostr(Piece.getOperandNo()) +
':' +
707 Piece.getModifier() +
'}';
719 return cast<Expr>(Exprs[i]);
723 return cast<Expr>(Exprs[i + NumOutputs]);
727 Exprs[i + NumOutputs] = E;
735 bool issimple,
bool isvolatile,
unsigned numoutputs,
740 :
AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
741 numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) {
745 std::copy(names, names + NumExprs, Names);
747 Exprs =
new (
C)
Stmt*[NumExprs];
748 std::copy(exprs, exprs + NumExprs, Exprs);
751 std::copy(constraints, constraints + NumExprs, Constraints);
754 std::copy(clobbers, clobbers +
NumClobbers, Clobbers);
764 :
AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
765 numinputs, clobbers.size()), LBraceLoc(lbraceloc),
766 EndLoc(endloc), NumAsmToks(asmtoks.size()) {
767 initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
774 void MSAsmStmt::initialize(
const ASTContext &C, StringRef asmstr,
779 assert(NumAsmToks == asmtoks.size());
783 assert(exprs.size() == constraints.size());
787 Exprs =
new (
C)
Stmt*[exprs.size()];
788 std::copy(exprs.begin(), exprs.end(),
Exprs);
790 AsmToks =
new (
C)
Token[asmtoks.size()];
791 std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
793 Constraints =
new (
C) StringRef[exprs.size()];
794 std::transform(constraints.begin(), constraints.end(), Constraints,
795 [&](StringRef Constraint) {
801 std::transform(clobbers.begin(), clobbers.end(), Clobbers,
802 [&](StringRef Clobber) {
810 :
Stmt(IfStmtClass) {
811 bool HasElse = Else !=
nullptr;
812 bool HasVar = Var !=
nullptr;
813 bool HasInit = Init !=
nullptr;
818 setConstexpr(IsConstexpr);
825 setConditionVariable(Ctx, Var);
834 IfStmt::IfStmt(EmptyShell Empty,
bool HasElse,
bool HasVar,
bool HasInit)
835 :
Stmt(IfStmtClass, Empty) {
844 bool HasElse = Else !=
nullptr;
845 bool HasVar = Var !=
nullptr;
846 bool HasInit = Init !=
nullptr;
848 totalSizeToAlloc<Stmt *, SourceLocation>(
849 NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
852 IfStmt(Ctx, IL, IsConstexpr, Init, Var, Cond, Then, EL, Else);
858 totalSizeToAlloc<Stmt *, SourceLocation>(
859 NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
865 auto *DS = getConditionVariableDeclStmt();
868 return cast<VarDecl>(DS->getSingleDecl());
872 assert(hasVarStorage() &&
873 "This if statement has no storage for a condition variable!");
876 getTrailingObjects<Stmt *>()[varOffset()] =
nullptr;
881 getTrailingObjects<Stmt *>()[varOffset()] =
new (Ctx)
886 return isa<ObjCAvailabilityCheckExpr>(getCond());
892 :
Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
894 SubExprs[INIT] = Init;
896 SubExprs[COND] = Cond;
898 SubExprs[BODY] = Body;
903 if (!SubExprs[CONDVAR])
906 auto *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
907 return cast<VarDecl>(DS->getSingleDecl());
912 SubExprs[CONDVAR] =
nullptr;
923 :
Stmt(SwitchStmtClass), FirstCase(
nullptr) {
924 bool HasInit = Init !=
nullptr;
925 bool HasVar = Var !=
nullptr;
940 SwitchStmt::SwitchStmt(
EmptyShell Empty,
bool HasInit,
bool HasVar)
941 :
Stmt(SwitchStmtClass, Empty) {
949 bool HasInit = Init !=
nullptr;
950 bool HasVar = Var !=
nullptr;
952 totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
954 return new (Mem)
SwitchStmt(Ctx, Init, Var, Cond);
960 totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
969 return cast<VarDecl>(DS->getSingleDecl());
973 assert(hasVarStorage() &&
974 "This switch statement has no storage for a condition variable!");
977 getTrailingObjects<Stmt *>()[varOffset()] =
nullptr;
982 getTrailingObjects<Stmt *>()[varOffset()] =
new (Ctx)
988 :
Stmt(WhileStmtClass) {
989 bool HasVar = Var !=
nullptr;
1000 WhileStmt::WhileStmt(
EmptyShell Empty,
bool HasVar)
1001 :
Stmt(WhileStmtClass, Empty) {
1007 bool HasVar = Var !=
nullptr;
1009 Ctx.
Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1011 return new (Mem)
WhileStmt(Ctx, Var, Cond, Body, WL);
1016 Ctx.
Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1025 return cast<VarDecl>(DS->getSingleDecl());
1029 assert(hasVarStorage() &&
1030 "This while statement has no storage for a condition variable!");
1033 getTrailingObjects<Stmt *>()[varOffset()] =
nullptr;
1038 getTrailingObjects<Stmt *>()[varOffset()] =
new (Ctx)
1044 if (
auto *E = dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
1045 return E->getLabel();
1051 :
Stmt(ReturnStmtClass), RetExpr(E) {
1052 bool HasNRVOCandidate = NRVOCandidate !=
nullptr;
1054 if (HasNRVOCandidate)
1055 setNRVOCandidate(NRVOCandidate);
1059 ReturnStmt::ReturnStmt(
EmptyShell Empty,
bool HasNRVOCandidate)
1060 :
Stmt(ReturnStmtClass, Empty) {
1066 bool HasNRVOCandidate = NRVOCandidate !=
nullptr;
1067 void *Mem = Ctx.
Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1069 return new (Mem)
ReturnStmt(RL, E, NRVOCandidate);
1073 bool HasNRVOCandidate) {
1074 void *Mem = Ctx.
Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1083 bool CaseStmtIsGNURange = rhs !=
nullptr;
1085 totalSizeToAlloc<Stmt *, SourceLocation>(
1086 NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1088 return new (Mem)
CaseStmt(lhs, rhs, caseLoc, ellipsisLoc, colonLoc);
1092 bool CaseStmtIsGNURange) {
1094 totalSizeToAlloc<Stmt *, SourceLocation>(
1095 NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1102 :
Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
1103 Children[TRY] = TryBlock;
1104 Children[HANDLER] = Handler;
1110 return new(
C)
SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
1122 :
Stmt(SEHExceptStmtClass), Loc(Loc) {
1123 Children[FILTER_EXPR] = FilterExpr;
1124 Children[
BLOCK] = Block;
1133 :
Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
1142 : VarAndKind(Var, Kind), Loc(Loc) {
1145 assert(!Var &&
"'this' capture cannot have a variable!");
1148 assert(Var &&
"capturing by reference must have a variable!");
1151 assert(Var &&
"capturing by copy must have a variable!");
1158 "captures by copy are expected to have a scalar type!");
1162 "Variable-length array type capture cannot have a variable!");
1169 return VarAndKind.getInt();
1174 "No variable available for 'this' or VAT capture");
1175 return VarAndKind.getPointer();
1182 unsigned FirstCaptureOffset = llvm::alignTo(Size,
alignof(
Capture));
1184 return reinterpret_cast<Capture *
>(
1185 reinterpret_cast<char *
>(
const_cast<CapturedStmt *
>(
this))
1186 + FirstCaptureOffset);
1194 :
Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
1195 CapDeclAndKind(CD,
Kind), TheRecordDecl(RD) {
1196 assert( S &&
"null captured statement");
1197 assert(CD &&
"null captured declaration for captured statement");
1198 assert(RD &&
"null record declaration for captured statement");
1201 Stmt **Stored = getStoredStmts();
1202 for (
unsigned I = 0, N = NumCaptures; I != N; ++I)
1203 *Stored++ = CaptureInits[I];
1209 Capture *Buffer = getStoredCaptures();
1210 std::copy(Captures.begin(), Captures.end(), Buffer);
1213 CapturedStmt::CapturedStmt(
EmptyShell Empty,
unsigned NumCaptures)
1214 :
Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
1216 getStoredStmts()[NumCaptures] =
nullptr;
1234 assert(CaptureInits.size() == Captures.size() &&
"wrong number of arguments");
1236 unsigned Size =
sizeof(
CapturedStmt) +
sizeof(
Stmt *) * (Captures.size() + 1);
1237 if (!Captures.empty()) {
1239 Size = llvm::alignTo(Size,
alignof(
Capture));
1240 Size +=
sizeof(
Capture) * Captures.size();
1243 void *Mem = Context.
Allocate(Size);
1244 return new (Mem)
CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
1248 unsigned NumCaptures) {
1250 if (NumCaptures > 0) {
1252 Size = llvm::alignTo(Size,
alignof(
Capture));
1253 Size +=
sizeof(
Capture) * NumCaptures;
1256 void *Mem = Context.
Allocate(Size);
1262 return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1266 return CapDeclAndKind.getPointer();
1270 return CapDeclAndKind.getPointer();
1275 assert(D &&
"null CapturedDecl");
1276 CapDeclAndKind.setPointer(D);
1281 return CapDeclAndKind.getInt();
1286 CapDeclAndKind.setInt(Kind);
1291 if (!I.capturesVariable() && !I.capturesVariableByCopy())
static AttributedStmt * CreateEmpty(const ASTContext &C, unsigned NumAttrs)
void setConditionVariable(const ASTContext &C, VarDecl *V)
Defines the clang::ASTContext interface.
Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var=nullptr)
Create a new capture.
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
const DeclStmt * getConditionVariableDeclStmt() const
If this ForStmt has a condition variable, return the faux DeclStmt associated with the creation of th...
Stmt - This represents one statement.
IfStmt - This represents an if/then/else.
VarDecl * getCapturedVar() const
Retrieve the declaration of the variable being captured.
C Language Family Type Representation.
Represents an attribute applied to a statement.
GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, StringLiteral **clobbers, SourceLocation rparenloc)
llvm::iterator_range< child_iterator > child_range
const TargetInfo & getTargetInfo() const
Stmt * IgnoreImplicit()
Skip past any implicit AST nodes which might surround this statement, such as ExprWithCleanups or Imp...
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr *> Attrs, Stmt *SubStmt)
static void addStmtClass(const StmtClass s)
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
void setInputExpr(unsigned i, Expr *E)
void setInputExpr(unsigned i, Expr *E)
Represents a variable declaration or definition.
unsigned AnalyzeAsmString(SmallVectorImpl< AsmStringPiece > &Pieces, const ASTContext &C, unsigned &DiagOffs) const
AnalyzeAsmString - Analyze the asm string of the current asm, decomposing it into pieces...
const char * getName() const
Defines the Objective-C statement AST node classes.
static StringRef bytes(const std::vector< T, Allocator > &v)
int getNamedOperand(StringRef SymbolicName) const
getNamedOperand - Given a symbolic operand reference like %[foo], translate this into a numeric value...
Defines the clang::Expr interface and subclasses for C++ expressions.
Stmt(StmtClass SC, EmptyShell)
Construct an empty statement.
static struct StmtClassNameTable StmtClassInfo[Stmt::lastStmtConstant+1]
const char * getStmtClassName() const
Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
SourceLocation getBeginLoc() const LLVM_READONLY
bool isReferenceType() const
Token - This structure provides full information about a lexed token.
void setCapturedDecl(CapturedDecl *D)
Set the outlined function declaration.
bool hasNoAsmVariants() const
Return true if {|} are normal characters in the asm string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
WhileStmtBitfields WhileStmtBits
static CapturedStmt * Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef< Capture > Captures, ArrayRef< Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD)
static IfStmt * Create(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond, Stmt *Then, SourceLocation EL=SourceLocation(), Stmt *Else=nullptr)
Create an IfStmt.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
const Expr * getOutputExpr(unsigned i) const
static CaseStmt * Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc)
Build a case statement.
Expr * getOutputExpr(unsigned i)
SwitchStmtBitfields SwitchStmtBits
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt *> Stmts, SourceLocation LB, SourceLocation RB)
CaseStmt - Represent a case statement.
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
ReturnStmtBitfields ReturnStmtBits
unsigned getNumPlusOperands() const
getNumPlusOperands - Return the number of output operands that have a "+" constraint.
bool isScalarType() const
Represents the body of a CapturedStmt, and serves as its DeclContext.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
MSAsmStmt(const ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, bool issimple, bool isvolatile, ArrayRef< Token > asmtoks, unsigned numoutputs, unsigned numinputs, ArrayRef< StringRef > constraints, ArrayRef< Expr *> exprs, StringRef asmstr, ArrayRef< StringRef > clobbers, SourceLocation endloc)
static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
StringRef getClobber(unsigned i) const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Describes the capture of either a variable, or 'this', or variable-length array type.
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
void setConditionVariable(const ASTContext &Ctx, VarDecl *V)
Set the condition variable for this if statement.
Exposes information about the current target.
This represents one expression.
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
const T * castAs() const
Member-template castAs<specific type>.
static ReturnStmt * CreateEmpty(const ASTContext &Ctx, bool HasNRVOCandidate)
Create an empty return statement, optionally with storage for an NRVO candidate.
AsmStringPiece - this is part of a decomposed asm string specification (for use with the AnalyzeAsmSt...
VariableCaptureKind getCaptureKind() const
Determine the kind of capture.
LabelDecl * getConstantTarget()
getConstantTarget - Returns the fixed target of this indirect goto, if one exists.
CompoundStmtBitfields CompoundStmtBits
static StringRef copyIntoContext(const ASTContext &C, StringRef str)
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
StringRef getInputConstraint(unsigned i) const
getInputConstraint - Return the specified input constraint.
SourceLocation getEnd() const
Expr * getInputExpr(unsigned i)
Expr * getOutputExpr(unsigned i)
StringRef getClobber(unsigned i) const
static WhileStmt * Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body, SourceLocation WL)
Create a while statement.
The result type of a method or function.
void setConditionVariable(const ASTContext &Ctx, VarDecl *V)
Set the condition variable of this while statement.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
SourceLocation getEndLoc() const LLVM_READONLY
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
void setConditionVariable(const ASTContext &Ctx, VarDecl *VD)
Set the condition variable in this switch statement.
static SwitchStmt * Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond)
Create a switch statement.
StringRef getInputConstraint(unsigned i) const
getInputConstraint - Return the specified input constraint.
This captures a statement into a function.
StringRef getOutputConstraint(unsigned i) const
getOutputConstraint - Return the constraint string for the specified output operand.
Encodes a location in the source.
IfStmtBitfields IfStmtBits
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Represents the declaration of a label.
bool capturesVariable() const
Determine whether this capture handles a variable (by reference).
ForStmtBitfields ForStmtBits
int64_t getID(const ASTContext &Context) const
StringRef getOutputConstraint(unsigned i) const
getOutputConstraint - Return the constraint string for the specified output operand.
static WhileStmt * CreateEmpty(const ASTContext &Ctx, bool HasVar)
Create an empty while statement optionally with storage for a condition variable. ...
Expr * getInputExpr(unsigned i)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
A placeholder type used to construct an empty shell of a type, that will be filled in later (e...
void * Allocate(size_t Size, unsigned Align=8) const
Dataflow Directional Tag Classes.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
static CapturedStmt * CreateDeserialized(const ASTContext &Context, unsigned NumCaptures)
const Stmt * stripLabelLikeStatements() const
Strip off all label-like statements.
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
SEHExceptStmt * getExceptHandler() const
Returns 0 if not defined.
static LLVM_ATTRIBUTE_UNUSED void check_implementations()
Check whether the various Stmt classes implement their member functions.
char getModifier() const
getModifier - Get the modifier for this operand, if present.
bool isObjCAvailabilityCheck() const
llvm::BumpPtrAllocator & getAllocator() const
static CompoundStmt * CreateEmpty(const ASTContext &C, unsigned NumStmts)
bool capturesVariableByCopy() const
Determine whether this capture handles a variable by copy.
SwitchStmt - This represents a 'switch' stmt.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
This file defines OpenMP AST classes for executable directives and clauses.
Base for LValueReferenceType and RValueReferenceType.
const Expr * getInputExpr(unsigned i) const
ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP)
SourceManager & getSourceManager()
SEHFinallyStmt * getFinallyHandler() const
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
void Deallocate(void *Ptr) const
Defines the clang::SourceLocation class and associated facilities.
WhileStmt - This represents a 'while' stmt.
static IfStmt * CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar, bool HasInit)
Create an empty IfStmt optionally with storage for an else statement, condition variable and init exp...
VariableCaptureKind
The different capture forms: by 'this', by reference, capture for variable-length array type etc...
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
static CaseStmt * CreateEmpty(const ASTContext &Ctx, bool CaseStmtIsGNURange)
Build an empty case statement.
CapturedRegionKind
The different kinds of captured statement.
static SwitchStmt * CreateEmpty(const ASTContext &Ctx, bool HasInit, bool HasVar)
Create an empty switch statement optionally with storage for an init expression and a condition varia...
static StmtClassNameTable & getStmtInfoTableEntry(Stmt::StmtClass E)
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
static SEHExceptStmt * Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block)
This class handles loading and caching of source files into memory.
void setCapturedRegionKind(CapturedRegionKind Kind)
Set the captured region kind.
CapturedRegionKind getCapturedRegionKind() const
Retrieve the captured region kind.
static void EnableStatistics()
#define BLOCK(DERIVED, BASE)