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" 45 #include <type_traits> 47 using namespace clang;
62 #define ABSTRACT_STMT(STMT) 63 #define STMT(CLASS, PARENT) \ 64 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \ 65 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS); 66 #include "clang/AST/StmtNodes.inc" 73 return ::operator
new(
bytes,
C, alignment);
83 #define STMT(CLASS, PARENT) \ 84 static_assert(!std::is_polymorphic<CLASS>::value, \ 85 #CLASS " should not be polymorphic!"); 86 #include "clang/AST/StmtNodes.inc" 91 #define STMT(CLASS, PARENT) \ 92 static_assert(std::is_trivially_destructible<CLASS>::value, \ 93 #CLASS " should be trivially destructible!"); 95 #define INITLISTEXPR(CLASS, PARENT) 96 #include "clang/AST/StmtNodes.inc" 103 llvm::errs() <<
"\n*** Stmt/Expr Stats:\n";
104 for (
int i = 0; i != Stmt::lastStmtConstant+1; i++) {
108 llvm::errs() <<
" " << sum <<
" stmts/exprs total.\n";
110 for (
int i = 0; i != Stmt::lastStmtConstant+1; i++) {
120 llvm::errs() <<
"Total bytes = " << sum <<
"\n";
127 bool Stmt::StatisticsEnabled =
false;
129 StatisticsEnabled =
true;
137 if (
auto CapS = dyn_cast_or_null<CapturedStmt>(S))
138 S = CapS->getCapturedStmt();
140 if (
auto AS = dyn_cast_or_null<AttributedStmt>(S))
141 S = AS->getSubStmt();
142 else if (
auto CS = dyn_cast_or_null<CompoundStmt>(S)) {
157 const Stmt *S =
this;
159 if (
const auto *LS = dyn_cast<LabelStmt>(S))
160 S = LS->getSubStmt();
161 else if (
const auto *SC = dyn_cast<SwitchCase>(S))
162 S = SC->getSubStmt();
163 else if (
const auto *AS = dyn_cast<AttributedStmt>(S))
164 S = AS->getSubStmt();
178 static good is_good(good) {
return good(); }
181 template <
class T> good implements_children(children_t T::*) {
184 LLVM_ATTRIBUTE_UNUSED
185 static bad implements_children(children_t
Stmt::*) {
190 template <
class T> good implements_getBeginLoc(getBeginLoc_t T::*) {
193 LLVM_ATTRIBUTE_UNUSED
194 static bad implements_getBeginLoc(getBeginLoc_t
Stmt::*) {
return bad(); }
197 template <
class T> good implements_getEndLoc(getLocEnd_t T::*) {
200 LLVM_ATTRIBUTE_UNUSED
201 static bad implements_getEndLoc(getLocEnd_t
Stmt::*) {
return bad(); }
203 #define ASSERT_IMPLEMENTS_children(type) \ 204 (void) is_good(implements_children(&type::children)) 205 #define ASSERT_IMPLEMENTS_getBeginLoc(type) \ 206 (void)is_good(implements_getBeginLoc(&type::getBeginLoc)) 207 #define ASSERT_IMPLEMENTS_getEndLoc(type) \ 208 (void)is_good(implements_getEndLoc(&type::getEndLoc)) 214 LLVM_ATTRIBUTE_UNUSED
216 #define ABSTRACT_STMT(type) 217 #define STMT(type, base) \ 218 ASSERT_IMPLEMENTS_children(type); \ 219 ASSERT_IMPLEMENTS_getBeginLoc(type); \ 220 ASSERT_IMPLEMENTS_getEndLoc(type); 221 #include "clang/AST/StmtNodes.inc" 225 switch (getStmtClass()) {
227 #define ABSTRACT_STMT(type) 228 #define STMT(type, base) \ 229 case Stmt::type##Class: \ 230 return static_cast<type*>(this)->children(); 231 #include "clang/AST/StmtNodes.inc" 233 llvm_unreachable(
"unknown statement kind!");
244 template <
class S,
class T>
257 return SourceRange(static_cast<const S *>(stmt)->getBeginLoc(),
258 static_cast<const S *>(stmt)->getEndLoc());
264 switch (getStmtClass()) {
266 #define ABSTRACT_STMT(type) 267 #define STMT(type, base) \ 268 case Stmt::type##Class: \ 269 return getSourceRangeImpl<type>(this, &type::getSourceRange); 270 #include "clang/AST/StmtNodes.inc" 272 llvm_unreachable(
"unknown statement kind!");
277 switch (getStmtClass()) {
279 #define ABSTRACT_STMT(type) 280 #define STMT(type, base) \ 281 case Stmt::type##Class: \ 282 return static_cast<const type *>(this)->getBeginLoc(); 283 #include "clang/AST/StmtNodes.inc" 285 llvm_unreachable(
"unknown statement kind");
289 switch (getStmtClass()) {
291 #define ABSTRACT_STMT(type) 292 #define STMT(type, base) \ 293 case Stmt::type##Class: \ 294 return static_cast<const type *>(this)->getEndLoc(); 295 #include "clang/AST/StmtNodes.inc" 297 llvm_unreachable(
"unknown statement kind");
306 :
Stmt(CompoundStmtClass), RBraceLoc(RB) {
307 CompoundStmtBits.NumStmts = Stmts.size();
309 CompoundStmtBits.LBraceLoc = LB;
313 assert(CompoundStmtBits.NumStmts == Stmts.size() &&
314 "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
316 std::copy(Stmts.begin(), Stmts.end(), body_begin());
336 const Stmt *S =
this;
338 if (
const auto *E = dyn_cast<Expr>(S))
341 if (
const auto *LS = dyn_cast<LabelStmt>(S))
342 S = LS->getSubStmt();
343 else if (
const auto *AS = dyn_cast<AttributedStmt>(S))
344 S = AS->getSubStmt();
346 llvm_unreachable(
"unknown kind of ValueStmt");
347 }
while (isa<ValueStmt>(S));
353 return getDecl()->getIdentifier()->getNameStart();
359 assert(!Attrs.empty() &&
"Attrs should not be empty");
360 void *Mem = C.
Allocate(totalSizeToAlloc<const Attr *>(Attrs.size()),
367 assert(NumAttrs > 0 &&
"NumAttrs should be greater than zero");
368 void *Mem = C.
Allocate(totalSizeToAlloc<const Attr *>(NumAttrs),
374 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
375 return gccAsmStmt->generateAsmString(C);
376 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
377 return msAsmStmt->generateAsmString(C);
378 llvm_unreachable(
"unknown asm statement kind!");
382 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
383 return gccAsmStmt->getOutputConstraint(i);
384 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
385 return msAsmStmt->getOutputConstraint(i);
386 llvm_unreachable(
"unknown asm statement kind!");
390 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
391 return gccAsmStmt->getOutputExpr(i);
392 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
393 return msAsmStmt->getOutputExpr(i);
394 llvm_unreachable(
"unknown asm statement kind!");
398 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
399 return gccAsmStmt->getInputConstraint(i);
400 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
401 return msAsmStmt->getInputConstraint(i);
402 llvm_unreachable(
"unknown asm statement kind!");
406 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
407 return gccAsmStmt->getInputExpr(i);
408 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
409 return msAsmStmt->getInputExpr(i);
410 llvm_unreachable(
"unknown asm statement kind!");
414 if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(
this))
415 return gccAsmStmt->getClobber(i);
416 if (
const auto *msAsmStmt = dyn_cast<MSAsmStmt>(
this))
417 return msAsmStmt->getClobber(i);
418 llvm_unreachable(
"unknown asm statement kind!");
425 for (
unsigned i = 0, e = getNumOutputs(); i != e; ++i)
426 if (isOutputPlusConstraint(i))
432 assert(isOperand() &&
"Only Operands can have modifiers.");
433 return isLetter(Str[0]) ? Str[0] :
'\0';
437 return getClobberStringLiteral(i)->getString();
441 return cast<Expr>(Exprs[i]);
448 return getOutputConstraintLiteral(i)->getString();
452 return cast<Expr>(Exprs[i + NumOutputs]);
456 Exprs[i + NumOutputs] = E;
460 return cast<AddrLabelExpr>(Exprs[i + NumInputs]);
464 return getLabelExpr(i)->getLabel()->getName();
470 return getInputConstraintLiteral(i)->getString();
473 void GCCAsmStmt::setOutputsAndInputsAndClobbers(
const ASTContext &
C,
481 unsigned NumClobbers) {
482 this->NumOutputs = NumOutputs;
483 this->NumInputs = NumInputs;
484 this->NumClobbers = NumClobbers;
485 this->NumLabels = NumLabels;
486 assert(!(NumOutputs && NumLabels) &&
"asm goto cannot have outputs");
488 unsigned NumExprs = NumOutputs + NumInputs + NumLabels;
492 std::copy(Names, Names + NumExprs, this->Names);
495 this->Exprs =
new (
C)
Stmt*[NumExprs];
496 std::copy(Exprs, Exprs + NumExprs, this->Exprs);
501 std::copy(Constraints, Constraints + NumConstraints, this->Constraints);
505 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
512 unsigned NumPlusOperands = 0;
515 for (
unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
516 if (getOutputName(i) == SymbolicName)
520 for (
unsigned i = 0, e = getNumInputs(); i != e; ++i)
521 if (getInputName(i) == SymbolicName)
522 return getNumOutputs() + NumPlusOperands + i;
524 for (
unsigned i = 0, e = getNumLabels(); i != e; ++i)
525 if (getLabelName(i) == SymbolicName)
526 return i + getNumInputs();
536 const ASTContext &C,
unsigned &DiagOffs)
const {
537 StringRef Str = getAsmString()->getString();
538 const char *StrStart = Str.begin();
539 const char *StrEnd = Str.end();
540 const char *CurPtr = StrStart;
546 for (; CurPtr != StrEnd; ++CurPtr) {
562 std::string CurStringPiece;
566 unsigned LastAsmStringToken = 0;
567 unsigned LastAsmStringOffset = 0;
571 if (CurPtr == StrEnd) {
572 if (!CurStringPiece.empty())
577 char CurChar = *CurPtr++;
579 case '$': CurStringPiece +=
"$$";
continue;
580 case '{': CurStringPiece += (HasVariants ?
"$(" :
"{");
continue;
581 case '|': CurStringPiece += (HasVariants ?
"$|" :
"|");
continue;
582 case '}': CurStringPiece += (HasVariants ?
"$)" :
"}");
continue;
586 CurStringPiece += CurChar;
591 if (CurPtr == StrEnd) {
593 DiagOffs = CurPtr-StrStart-1;
594 return diag::err_asm_invalid_escape;
597 char EscapedChar = *CurPtr++;
598 switch (EscapedChar) {
604 CurStringPiece += EscapedChar;
607 CurStringPiece +=
"${:uid}";
613 if (!CurStringPiece.empty()) {
615 CurStringPiece.clear();
621 const char *
Begin = CurPtr - 1;
622 const char *Percent = Begin - 1;
625 if (CurPtr == StrEnd) {
626 DiagOffs = CurPtr-StrStart-1;
627 return diag::err_asm_invalid_escape;
629 EscapedChar = *CurPtr++;
642 while (CurPtr != StrEnd &&
isDigit(*CurPtr))
643 N = N*10 + ((*CurPtr++)-
'0');
645 unsigned NumOperands = getNumOutputs() + getNumPlusOperands() +
646 getNumInputs() + getNumLabels();
647 if (N >= NumOperands) {
648 DiagOffs = CurPtr-StrStart-1;
649 return diag::err_asm_invalid_operand_number;
653 std::string Str(Begin, CurPtr - Begin);
658 Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
659 &LastAsmStringOffset);
661 CurPtr - StrStart, SM, LO, TI, &LastAsmStringToken,
662 &LastAsmStringOffset);
664 Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
669 if (EscapedChar ==
'[') {
670 DiagOffs = CurPtr-StrStart-1;
673 const char *NameEnd = (
const char*)memchr(CurPtr,
']', StrEnd-CurPtr);
674 if (NameEnd ==
nullptr)
675 return diag::err_asm_unterminated_symbolic_operand_name;
676 if (NameEnd == CurPtr)
677 return diag::err_asm_empty_symbolic_operand_name;
679 StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
681 int N = getNamedOperand(SymbolicName);
684 DiagOffs = CurPtr-StrStart;
685 return diag::err_asm_unknown_symbolic_operand_name;
689 std::string Str(Begin, NameEnd + 1 - Begin);
694 Percent - StrStart, SM, LO, TI, &LastAsmStringToken,
695 &LastAsmStringOffset);
697 NameEnd + 1 - StrStart, SM, LO, TI, &LastAsmStringToken,
698 &LastAsmStringOffset);
700 Pieces.emplace_back(N, std::move(Str), BeginLoc, EndLoc);
706 DiagOffs = CurPtr-StrStart-1;
707 return diag::err_asm_invalid_escape;
717 AnalyzeAsmString(Pieces, C, DiagOffs);
719 std::string AsmString;
720 for (
const auto &Piece : Pieces) {
721 if (Piece.isString())
722 AsmString += Piece.getString();
723 else if (Piece.getModifier() ==
'\0')
724 AsmString +=
'$' + llvm::utostr(Piece.getOperandNo());
726 AsmString +=
"${" + llvm::utostr(Piece.getOperandNo()) +
':' +
727 Piece.getModifier() +
'}';
739 return cast<Expr>(Exprs[i]);
743 return cast<Expr>(Exprs[i + NumOutputs]);
747 Exprs[i + NumOutputs] = E;
755 bool issimple,
bool isvolatile,
unsigned numoutputs,
761 :
AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
762 numinputs, numclobbers),
763 RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) {
767 std::copy(names, names + NumExprs, Names);
769 Exprs =
new (
C)
Stmt*[NumExprs];
770 std::copy(exprs, exprs + NumExprs, Exprs);
774 std::copy(constraints, constraints + NumConstraints, Constraints);
777 std::copy(clobbers, clobbers +
NumClobbers, Clobbers);
787 :
AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
788 numinputs, clobbers.size()), LBraceLoc(lbraceloc),
789 EndLoc(endloc), NumAsmToks(asmtoks.size()) {
790 initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
797 void MSAsmStmt::initialize(
const ASTContext &C, StringRef asmstr,
802 assert(NumAsmToks == asmtoks.size());
806 assert(exprs.size() == constraints.size());
810 Exprs =
new (
C)
Stmt*[exprs.size()];
811 std::copy(exprs.begin(), exprs.end(),
Exprs);
813 AsmToks =
new (
C)
Token[asmtoks.size()];
814 std::copy(asmtoks.begin(), asmtoks.end(), AsmToks);
816 Constraints =
new (
C) StringRef[exprs.size()];
817 std::transform(constraints.begin(), constraints.end(), Constraints,
818 [&](StringRef Constraint) {
824 std::transform(clobbers.begin(), clobbers.end(), Clobbers,
825 [&](StringRef Clobber) {
833 :
Stmt(IfStmtClass) {
834 bool HasElse = Else !=
nullptr;
835 bool HasVar = Var !=
nullptr;
836 bool HasInit = Init !=
nullptr;
841 setConstexpr(IsConstexpr);
848 setConditionVariable(Ctx, Var);
857 IfStmt::IfStmt(EmptyShell Empty,
bool HasElse,
bool HasVar,
bool HasInit)
858 :
Stmt(IfStmtClass, Empty) {
867 bool HasElse = Else !=
nullptr;
868 bool HasVar = Var !=
nullptr;
869 bool HasInit = Init !=
nullptr;
871 totalSizeToAlloc<Stmt *, SourceLocation>(
872 NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
875 IfStmt(Ctx, IL, IsConstexpr, Init, Var, Cond, Then, EL, Else);
881 totalSizeToAlloc<Stmt *, SourceLocation>(
882 NumMandatoryStmtPtr + HasElse + HasVar + HasInit, HasElse),
888 auto *DS = getConditionVariableDeclStmt();
891 return cast<VarDecl>(DS->getSingleDecl());
895 assert(hasVarStorage() &&
896 "This if statement has no storage for a condition variable!");
899 getTrailingObjects<Stmt *>()[varOffset()] =
nullptr;
904 getTrailingObjects<Stmt *>()[varOffset()] =
new (Ctx)
909 return isa<ObjCAvailabilityCheckExpr>(getCond());
913 if (!isConstexpr() || getCond()->isValueDependent())
915 return !getCond()->EvaluateKnownConstInt(Ctx) ? getElse() : getThen();
921 :
Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
923 SubExprs[INIT] = Init;
925 SubExprs[COND] = Cond;
927 SubExprs[BODY] = Body;
932 if (!SubExprs[CONDVAR])
935 auto *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
936 return cast<VarDecl>(DS->getSingleDecl());
941 SubExprs[CONDVAR] =
nullptr;
952 :
Stmt(SwitchStmtClass), FirstCase(
nullptr) {
953 bool HasInit = Init !=
nullptr;
954 bool HasVar = Var !=
nullptr;
969 SwitchStmt::SwitchStmt(
EmptyShell Empty,
bool HasInit,
bool HasVar)
970 :
Stmt(SwitchStmtClass, Empty) {
978 bool HasInit = Init !=
nullptr;
979 bool HasVar = Var !=
nullptr;
981 totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
983 return new (Mem)
SwitchStmt(Ctx, Init, Var, Cond);
989 totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
998 return cast<VarDecl>(DS->getSingleDecl());
1002 assert(hasVarStorage() &&
1003 "This switch statement has no storage for a condition variable!");
1006 getTrailingObjects<Stmt *>()[varOffset()] =
nullptr;
1011 getTrailingObjects<Stmt *>()[varOffset()] =
new (Ctx)
1017 :
Stmt(WhileStmtClass) {
1018 bool HasVar = Var !=
nullptr;
1029 WhileStmt::WhileStmt(
EmptyShell Empty,
bool HasVar)
1030 :
Stmt(WhileStmtClass, Empty) {
1036 bool HasVar = Var !=
nullptr;
1038 Ctx.
Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1040 return new (Mem)
WhileStmt(Ctx, Var, Cond, Body, WL);
1045 Ctx.
Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar),
1054 return cast<VarDecl>(DS->getSingleDecl());
1058 assert(hasVarStorage() &&
1059 "This while statement has no storage for a condition variable!");
1062 getTrailingObjects<Stmt *>()[varOffset()] =
nullptr;
1067 getTrailingObjects<Stmt *>()[varOffset()] =
new (Ctx)
1073 if (
auto *E = dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
1074 return E->getLabel();
1080 :
Stmt(ReturnStmtClass), RetExpr(E) {
1081 bool HasNRVOCandidate = NRVOCandidate !=
nullptr;
1083 if (HasNRVOCandidate)
1084 setNRVOCandidate(NRVOCandidate);
1088 ReturnStmt::ReturnStmt(
EmptyShell Empty,
bool HasNRVOCandidate)
1089 :
Stmt(ReturnStmtClass, Empty) {
1095 bool HasNRVOCandidate = NRVOCandidate !=
nullptr;
1096 void *Mem = Ctx.
Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1098 return new (Mem)
ReturnStmt(RL, E, NRVOCandidate);
1102 bool HasNRVOCandidate) {
1103 void *Mem = Ctx.
Allocate(totalSizeToAlloc<const VarDecl *>(HasNRVOCandidate),
1112 bool CaseStmtIsGNURange = rhs !=
nullptr;
1114 totalSizeToAlloc<Stmt *, SourceLocation>(
1115 NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1117 return new (Mem)
CaseStmt(lhs, rhs, caseLoc, ellipsisLoc, colonLoc);
1121 bool CaseStmtIsGNURange) {
1123 totalSizeToAlloc<Stmt *, SourceLocation>(
1124 NumMandatoryStmtPtr + CaseStmtIsGNURange, CaseStmtIsGNURange),
1131 :
Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
1132 Children[TRY] = TryBlock;
1133 Children[HANDLER] = Handler;
1139 return new(
C)
SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
1151 :
Stmt(SEHExceptStmtClass), Loc(Loc) {
1152 Children[FILTER_EXPR] = FilterExpr;
1153 Children[
BLOCK] = Block;
1162 :
Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
1171 : VarAndKind(Var, Kind), Loc(Loc) {
1174 assert(!Var &&
"'this' capture cannot have a variable!");
1177 assert(Var &&
"capturing by reference must have a variable!");
1180 assert(Var &&
"capturing by copy must have a variable!");
1187 "captures by copy are expected to have a scalar type!");
1191 "Variable-length array type capture cannot have a variable!");
1198 return VarAndKind.getInt();
1203 "No variable available for 'this' or VAT capture");
1204 return VarAndKind.getPointer();
1211 unsigned FirstCaptureOffset = llvm::alignTo(Size,
alignof(
Capture));
1213 return reinterpret_cast<Capture *
>(
1214 reinterpret_cast<char *
>(
const_cast<CapturedStmt *
>(
this))
1215 + FirstCaptureOffset);
1223 :
Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
1224 CapDeclAndKind(CD,
Kind), TheRecordDecl(RD) {
1225 assert( S &&
"null captured statement");
1226 assert(CD &&
"null captured declaration for captured statement");
1227 assert(RD &&
"null record declaration for captured statement");
1230 Stmt **Stored = getStoredStmts();
1231 for (
unsigned I = 0, N = NumCaptures; I != N; ++I)
1232 *Stored++ = CaptureInits[I];
1238 Capture *Buffer = getStoredCaptures();
1239 std::copy(Captures.begin(), Captures.end(), Buffer);
1242 CapturedStmt::CapturedStmt(
EmptyShell Empty,
unsigned NumCaptures)
1243 :
Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
1245 getStoredStmts()[NumCaptures] =
nullptr;
1263 assert(CaptureInits.size() == Captures.size() &&
"wrong number of arguments");
1265 unsigned Size =
sizeof(
CapturedStmt) +
sizeof(
Stmt *) * (Captures.size() + 1);
1266 if (!Captures.empty()) {
1268 Size = llvm::alignTo(Size,
alignof(
Capture));
1269 Size +=
sizeof(
Capture) * Captures.size();
1272 void *Mem = Context.
Allocate(Size);
1273 return new (Mem)
CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
1277 unsigned NumCaptures) {
1279 if (NumCaptures > 0) {
1281 Size = llvm::alignTo(Size,
alignof(
Capture));
1282 Size +=
sizeof(
Capture) * NumCaptures;
1285 void *Mem = Context.
Allocate(Size);
1291 return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
1299 return CapDeclAndKind.getPointer();
1303 return CapDeclAndKind.getPointer();
1308 assert(D &&
"null CapturedDecl");
1309 CapDeclAndKind.setPointer(D);
1314 return CapDeclAndKind.getInt();
1319 CapDeclAndKind.setInt(Kind);
1324 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.
llvm::iterator_range< child_iterator > child_range
const TargetInfo & getTargetInfo() const
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
const Expr * getExprStmt() 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.
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
llvm::iterator_range< const_child_iterator > const_child_range
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.
StringRef getLabelName(unsigned i) const
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
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, unsigned numlabels, SourceLocation rparenloc)
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
AddrLabelExpr - The GNU address of label extension, representing &&label.
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.
AddrLabelExpr * getLabelExpr(unsigned i) const
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.
Defines Expressions and AST nodes for C++2a concepts.
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.
Optional< const Stmt * > getNondiscardedCase(const ASTContext &Ctx) const
If this is an 'if constexpr', determine which substatement will be taken.
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)