forked from OSchip/llvm-project
[AST] Only store the needed data in SwitchStmt
Don't store the data for the init statement and condition variable if not needed. This cuts the size of SwitchStmt by up to 2 pointers. The order of the children is intentionally kept the same. Also use the newly available space in the bit-fields of Stmt to store the bit representing whether all enums have been covered instead of using a PointerIntPair. Differential Revision: https://reviews.llvm.org/D53714 Reviewed By: rjmccall llvm-svn: 345510
This commit is contained in:
parent
e92567601b
commit
e2806f857b
|
@ -177,6 +177,17 @@ protected:
|
|||
|
||||
unsigned : NumStmtBits;
|
||||
|
||||
/// True if the SwitchStmt has storage for an init statement.
|
||||
unsigned HasInit : 1;
|
||||
|
||||
/// True if the SwitchStmt has storage for a condition variable.
|
||||
unsigned HasVar : 1;
|
||||
|
||||
/// If the SwitchStmt is a switch on an enum value, records whether all
|
||||
/// the enum values were covered by CaseStmts. The coverage information
|
||||
/// value is meant to be a hint for possible clients.
|
||||
unsigned AllEnumCasesCovered : 1;
|
||||
|
||||
/// The location of the "switch".
|
||||
SourceLocation SwitchLoc;
|
||||
};
|
||||
|
@ -1427,21 +1438,102 @@ public:
|
|||
};
|
||||
|
||||
/// SwitchStmt - This represents a 'switch' stmt.
|
||||
class SwitchStmt : public Stmt {
|
||||
enum { INIT, VAR, COND, BODY, END_EXPR };
|
||||
Stmt* SubExprs[END_EXPR];
|
||||
class SwitchStmt final : public Stmt,
|
||||
private llvm::TrailingObjects<SwitchStmt, Stmt *> {
|
||||
friend TrailingObjects;
|
||||
|
||||
// This points to a linked list of case and default statements and, if the
|
||||
// SwitchStmt is a switch on an enum value, records whether all the enum
|
||||
// values were covered by CaseStmts. The coverage information value is meant
|
||||
// to be a hint for possible clients.
|
||||
llvm::PointerIntPair<SwitchCase *, 1, bool> FirstCase;
|
||||
/// Points to a linked list of case and default statements.
|
||||
SwitchCase *FirstCase;
|
||||
|
||||
public:
|
||||
SwitchStmt(const ASTContext &C, Stmt *Init, VarDecl *Var, Expr *cond);
|
||||
// SwitchStmt is followed by several trailing objects,
|
||||
// some of which optional. Note that it would be more convenient to
|
||||
// put the optional trailing objects at the end but this would change
|
||||
// the order in children().
|
||||
// The trailing objects are in order:
|
||||
//
|
||||
// * A "Stmt *" for the init statement.
|
||||
// Present if and only if hasInitStorage().
|
||||
//
|
||||
// * A "Stmt *" for the condition variable.
|
||||
// Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
|
||||
//
|
||||
// * A "Stmt *" for the condition.
|
||||
// Always present. This is in fact an "Expr *".
|
||||
//
|
||||
// * A "Stmt *" for the body.
|
||||
// Always present.
|
||||
enum { InitOffset = 0, BodyOffsetFromCond = 1 };
|
||||
enum { NumMandatoryStmtPtr = 2 };
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
|
||||
return NumMandatoryStmtPtr + hasInitStorage() + hasVarStorage();
|
||||
}
|
||||
|
||||
unsigned initOffset() const { return InitOffset; }
|
||||
unsigned varOffset() const { return InitOffset + hasInitStorage(); }
|
||||
unsigned condOffset() const {
|
||||
return InitOffset + hasInitStorage() + hasVarStorage();
|
||||
}
|
||||
unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
|
||||
|
||||
/// Build a switch statement.
|
||||
SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond);
|
||||
|
||||
/// Build a empty switch statement.
|
||||
explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) {}
|
||||
explicit SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar);
|
||||
|
||||
public:
|
||||
/// Create a switch statement.
|
||||
static SwitchStmt *Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
|
||||
Expr *Cond);
|
||||
|
||||
/// Create an empty switch statement optionally with storage for
|
||||
/// an init expression and a condition variable.
|
||||
static SwitchStmt *CreateEmpty(const ASTContext &Ctx, bool HasInit,
|
||||
bool HasVar);
|
||||
|
||||
/// True if this SwitchStmt has storage for an init statement.
|
||||
bool hasInitStorage() const { return SwitchStmtBits.HasInit; }
|
||||
|
||||
/// True if this SwitchStmt has storage for a condition variable.
|
||||
bool hasVarStorage() const { return SwitchStmtBits.HasVar; }
|
||||
|
||||
Expr *getCond() {
|
||||
return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
|
||||
}
|
||||
|
||||
const Expr *getCond() const {
|
||||
return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
|
||||
}
|
||||
|
||||
void setCond(Expr *Cond) {
|
||||
getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
|
||||
}
|
||||
|
||||
Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
|
||||
const Stmt *getBody() const {
|
||||
return getTrailingObjects<Stmt *>()[bodyOffset()];
|
||||
}
|
||||
|
||||
void setBody(Stmt *Body) {
|
||||
getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
|
||||
}
|
||||
|
||||
Stmt *getInit() {
|
||||
return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
const Stmt *getInit() const {
|
||||
return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void setInit(Stmt *Init) {
|
||||
assert(hasInitStorage() &&
|
||||
"This switch statement has no storage for an init statement!");
|
||||
getTrailingObjects<Stmt *>()[initOffset()] = Init;
|
||||
}
|
||||
|
||||
/// Retrieve the variable declared in this "switch" statement, if any.
|
||||
///
|
||||
|
@ -1452,64 +1544,69 @@ public:
|
|||
/// // ...
|
||||
/// }
|
||||
/// \endcode
|
||||
VarDecl *getConditionVariable() const;
|
||||
void setConditionVariable(const ASTContext &C, VarDecl *V);
|
||||
VarDecl *getConditionVariable();
|
||||
const VarDecl *getConditionVariable() const {
|
||||
return const_cast<SwitchStmt *>(this)->getConditionVariable();
|
||||
}
|
||||
|
||||
/// Set the condition variable in this switch statement.
|
||||
/// The switch statement must have storage for it.
|
||||
void setConditionVariable(const ASTContext &Ctx, VarDecl *VD);
|
||||
|
||||
/// If this SwitchStmt has a condition variable, return the faux DeclStmt
|
||||
/// associated with the creation of that condition variable.
|
||||
const DeclStmt *getConditionVariableDeclStmt() const {
|
||||
return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
|
||||
DeclStmt *getConditionVariableDeclStmt() {
|
||||
return hasVarStorage() ? static_cast<DeclStmt *>(
|
||||
getTrailingObjects<Stmt *>()[varOffset()])
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
Stmt *getInit() { return SubExprs[INIT]; }
|
||||
const Stmt *getInit() const { return SubExprs[INIT]; }
|
||||
void setInit(Stmt *S) { SubExprs[INIT] = S; }
|
||||
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
|
||||
const Stmt *getBody() const { return SubExprs[BODY]; }
|
||||
const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); }
|
||||
const DeclStmt *getConditionVariableDeclStmt() const {
|
||||
return hasVarStorage() ? static_cast<DeclStmt *>(
|
||||
getTrailingObjects<Stmt *>()[varOffset()])
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
|
||||
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
|
||||
Stmt *getBody() { return SubExprs[BODY]; }
|
||||
void setBody(Stmt *S) { SubExprs[BODY] = S; }
|
||||
SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); }
|
||||
|
||||
/// Set the case list for this switch statement.
|
||||
void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); }
|
||||
SwitchCase *getSwitchCaseList() { return FirstCase; }
|
||||
const SwitchCase *getSwitchCaseList() const { return FirstCase; }
|
||||
void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
|
||||
|
||||
SourceLocation getSwitchLoc() const { return SwitchStmtBits.SwitchLoc; }
|
||||
void setSwitchLoc(SourceLocation L) { SwitchStmtBits.SwitchLoc = L; }
|
||||
|
||||
void setBody(Stmt *S, SourceLocation SL) {
|
||||
SubExprs[BODY] = S;
|
||||
SwitchStmtBits.SwitchLoc = SL;
|
||||
setBody(S);
|
||||
setSwitchLoc(SL);
|
||||
}
|
||||
|
||||
void addSwitchCase(SwitchCase *SC) {
|
||||
assert(!SC->getNextSwitchCase()
|
||||
&& "case/default already added to a switch");
|
||||
SC->setNextSwitchCase(FirstCase.getPointer());
|
||||
FirstCase.setPointer(SC);
|
||||
assert(!SC->getNextSwitchCase() &&
|
||||
"case/default already added to a switch");
|
||||
SC->setNextSwitchCase(FirstCase);
|
||||
FirstCase = SC;
|
||||
}
|
||||
|
||||
/// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
|
||||
/// switch over an enum value then all cases have been explicitly covered.
|
||||
void setAllEnumCasesCovered() { FirstCase.setInt(true); }
|
||||
void setAllEnumCasesCovered() { SwitchStmtBits.AllEnumCasesCovered = true; }
|
||||
|
||||
/// Returns true if the SwitchStmt is a switch of an enum value and all cases
|
||||
/// have been explicitly covered.
|
||||
bool isAllEnumCasesCovered() const { return FirstCase.getInt(); }
|
||||
bool isAllEnumCasesCovered() const {
|
||||
return SwitchStmtBits.AllEnumCasesCovered;
|
||||
}
|
||||
|
||||
SourceLocation getBeginLoc() const { return getSwitchLoc(); }
|
||||
|
||||
SourceLocation getEndLoc() const {
|
||||
return SubExprs[BODY] ? SubExprs[BODY]->getEndLoc()
|
||||
: SubExprs[COND]->getEndLoc();
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return getBody() ? getBody()->getEndLoc()
|
||||
: reinterpret_cast<const Stmt *>(getCond())->getEndLoc();
|
||||
}
|
||||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
|
||||
return child_range(getTrailingObjects<Stmt *>(),
|
||||
getTrailingObjects<Stmt *>() +
|
||||
numTrailingObjects(OverloadToken<Stmt *>()));
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
|
|
|
@ -512,6 +512,7 @@ namespace {
|
|||
void VisitDeclStmt(const DeclStmt *Node);
|
||||
void VisitAttributedStmt(const AttributedStmt *Node);
|
||||
void VisitIfStmt(const IfStmt *Node);
|
||||
void VisitSwitchStmt(const SwitchStmt *Node);
|
||||
void VisitLabelStmt(const LabelStmt *Node);
|
||||
void VisitGotoStmt(const GotoStmt *Node);
|
||||
void VisitCXXCatchStmt(const CXXCatchStmt *Node);
|
||||
|
@ -2032,6 +2033,14 @@ void ASTDumper::VisitIfStmt(const IfStmt *Node) {
|
|||
OS << " has_else";
|
||||
}
|
||||
|
||||
void ASTDumper::VisitSwitchStmt(const SwitchStmt *Node) {
|
||||
VisitStmt(Node);
|
||||
if (Node->hasInitStorage())
|
||||
OS << " has_init";
|
||||
if (Node->hasVarStorage())
|
||||
OS << " has_var";
|
||||
}
|
||||
|
||||
void ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
|
||||
VisitStmt(Node);
|
||||
OS << " '" << Node->getName() << "'";
|
||||
|
|
|
@ -5790,8 +5790,8 @@ ExpectedStmt ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
|
|||
SourceLocation ToSwitchLoc;
|
||||
std::tie(ToInit, ToConditionVariable, ToCond, ToBody, ToSwitchLoc) = *Imp;
|
||||
|
||||
auto *ToStmt = new (Importer.getToContext()) SwitchStmt(
|
||||
Importer.getToContext(), ToInit, ToConditionVariable, ToCond);
|
||||
auto *ToStmt = SwitchStmt::Create(Importer.getToContext(), ToInit,
|
||||
ToConditionVariable, ToCond);
|
||||
ToStmt->setBody(ToBody);
|
||||
ToStmt->setSwitchLoc(ToSwitchLoc);
|
||||
|
||||
|
|
|
@ -913,33 +913,69 @@ void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
|
|||
VarRange.getEnd());
|
||||
}
|
||||
|
||||
SwitchStmt::SwitchStmt(const ASTContext &C, Stmt *init, VarDecl *Var,
|
||||
Expr *cond)
|
||||
: Stmt(SwitchStmtClass), FirstCase(nullptr, false) {
|
||||
setConditionVariable(C, Var);
|
||||
SubExprs[INIT] = init;
|
||||
SubExprs[COND] = cond;
|
||||
SubExprs[BODY] = nullptr;
|
||||
SwitchStmtBits.SwitchLoc = SourceLocation{};
|
||||
SwitchStmt::SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
|
||||
Expr *Cond)
|
||||
: Stmt(SwitchStmtClass), FirstCase(nullptr) {
|
||||
bool HasInit = Init != nullptr;
|
||||
bool HasVar = Var != nullptr;
|
||||
SwitchStmtBits.HasInit = HasInit;
|
||||
SwitchStmtBits.HasVar = HasVar;
|
||||
SwitchStmtBits.AllEnumCasesCovered = false;
|
||||
|
||||
setCond(Cond);
|
||||
setBody(nullptr);
|
||||
if (HasInit)
|
||||
setInit(Init);
|
||||
if (HasVar)
|
||||
setConditionVariable(Ctx, Var);
|
||||
|
||||
setSwitchLoc(SourceLocation{});
|
||||
}
|
||||
|
||||
VarDecl *SwitchStmt::getConditionVariable() const {
|
||||
if (!SubExprs[VAR])
|
||||
return nullptr;
|
||||
SwitchStmt::SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar)
|
||||
: Stmt(SwitchStmtClass, Empty) {
|
||||
SwitchStmtBits.HasInit = HasInit;
|
||||
SwitchStmtBits.HasVar = HasVar;
|
||||
SwitchStmtBits.AllEnumCasesCovered = false;
|
||||
}
|
||||
|
||||
auto *DS = cast<DeclStmt>(SubExprs[VAR]);
|
||||
SwitchStmt *SwitchStmt::Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
|
||||
Expr *Cond) {
|
||||
bool HasInit = Init != nullptr;
|
||||
bool HasVar = Var != nullptr;
|
||||
void *Mem = Ctx.Allocate(
|
||||
totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
|
||||
alignof(SwitchStmt));
|
||||
return new (Mem) SwitchStmt(Ctx, Init, Var, Cond);
|
||||
}
|
||||
|
||||
SwitchStmt *SwitchStmt::CreateEmpty(const ASTContext &Ctx, bool HasInit,
|
||||
bool HasVar) {
|
||||
void *Mem = Ctx.Allocate(
|
||||
totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasInit + HasVar),
|
||||
alignof(SwitchStmt));
|
||||
return new (Mem) SwitchStmt(EmptyShell(), HasInit, HasVar);
|
||||
}
|
||||
|
||||
VarDecl *SwitchStmt::getConditionVariable() {
|
||||
auto *DS = getConditionVariableDeclStmt();
|
||||
if (!DS)
|
||||
return nullptr;
|
||||
return cast<VarDecl>(DS->getSingleDecl());
|
||||
}
|
||||
|
||||
void SwitchStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
|
||||
void SwitchStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {
|
||||
assert(hasVarStorage() &&
|
||||
"This switch statement has no storage for a condition variable!");
|
||||
|
||||
if (!V) {
|
||||
SubExprs[VAR] = nullptr;
|
||||
getTrailingObjects<Stmt *>()[varOffset()] = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
SourceRange VarRange = V->getSourceRange();
|
||||
SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
|
||||
VarRange.getEnd());
|
||||
getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx)
|
||||
DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
|
||||
}
|
||||
|
||||
WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
|
||||
|
|
|
@ -727,8 +727,7 @@ StmtResult Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
|
|||
|
||||
setFunctionHasBranchIntoScope();
|
||||
|
||||
SwitchStmt *SS = new (Context)
|
||||
SwitchStmt(Context, InitStmt, Cond.get().first, CondExpr);
|
||||
auto *SS = SwitchStmt::Create(Context, InitStmt, Cond.get().first, CondExpr);
|
||||
getCurFunction()->SwitchStack.push_back(
|
||||
FunctionScopeInfo::SwitchInfo(SS, false));
|
||||
return SS;
|
||||
|
|
|
@ -240,13 +240,21 @@ void ASTStmtReader::VisitIfStmt(IfStmt *S) {
|
|||
|
||||
void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
|
||||
VisitStmt(S);
|
||||
S->setInit(Record.readSubStmt());
|
||||
S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
|
||||
|
||||
bool HasInit = Record.readInt();
|
||||
bool HasVar = Record.readInt();
|
||||
bool AllEnumCasesCovered = Record.readInt();
|
||||
if (AllEnumCasesCovered)
|
||||
S->setAllEnumCasesCovered();
|
||||
|
||||
S->setCond(Record.readSubExpr());
|
||||
S->setBody(Record.readSubStmt());
|
||||
if (HasInit)
|
||||
S->setInit(Record.readSubStmt());
|
||||
if (HasVar)
|
||||
S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
|
||||
|
||||
S->setSwitchLoc(ReadSourceLocation());
|
||||
if (Record.readInt())
|
||||
S->setAllEnumCasesCovered();
|
||||
|
||||
SwitchCase *PrevSC = nullptr;
|
||||
for (auto E = Record.size(); Record.getIdx() != E; ) {
|
||||
|
@ -2310,7 +2318,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
|||
break;
|
||||
|
||||
case STMT_SWITCH:
|
||||
S = new (Context) SwitchStmt(Empty);
|
||||
S = SwitchStmt::CreateEmpty(
|
||||
Context,
|
||||
/* HasInit=*/Record[ASTStmtReader::NumStmtFields + 0],
|
||||
/* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1]);
|
||||
break;
|
||||
|
||||
case STMT_WHILE:
|
||||
|
|
|
@ -159,12 +159,22 @@ void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
|
|||
|
||||
void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
|
||||
VisitStmt(S);
|
||||
Record.AddStmt(S->getInit());
|
||||
Record.AddDeclRef(S->getConditionVariable());
|
||||
|
||||
bool HasInit = S->getInit() != nullptr;
|
||||
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
||||
Record.push_back(HasInit);
|
||||
Record.push_back(HasVar);
|
||||
Record.push_back(S->isAllEnumCasesCovered());
|
||||
|
||||
Record.AddStmt(S->getCond());
|
||||
Record.AddStmt(S->getBody());
|
||||
if (HasInit)
|
||||
Record.AddStmt(S->getInit());
|
||||
if (HasVar)
|
||||
Record.AddDeclRef(S->getConditionVariable());
|
||||
|
||||
Record.AddSourceLocation(S->getSwitchLoc());
|
||||
Record.push_back(S->isAllEnumCasesCovered());
|
||||
|
||||
for (SwitchCase *SC = S->getSwitchCaseList(); SC;
|
||||
SC = SC->getNextSwitchCase())
|
||||
Record.push_back(Writer.RecordSwitchCaseID(SC));
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
|
||||
|
||||
// CHECK: SwitchStmt
|
||||
// CHECK-NEXT: <<NULL>>
|
||||
// CHECK-NEXT: <<NULL>>
|
||||
// CHECK-NEXT: IntegerLiteral
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CaseStmt
|
||||
|
@ -22,7 +20,6 @@
|
|||
// CHECK-NEXT: DeclStmt
|
||||
// CHECK-NEXT: VarDecl
|
||||
// CHECK-SAME: varname
|
||||
// CHECK-NEXT: <<NULL>>
|
||||
// CHECK-NEXT: IntegerLiteral
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CaseStmt
|
||||
|
@ -37,15 +34,11 @@
|
|||
// CHECK-NEXT: BreakStmt
|
||||
|
||||
// CHECK: SwitchStmt
|
||||
// CHECK-NEXT: <<NULL>>
|
||||
// CHECK-NEXT: <<NULL>>
|
||||
// CHECK-NEXT: IntegerLiteral
|
||||
// CHECK-NEXT: DefaultStmt
|
||||
// CHECK-NEXT: BreakStmt
|
||||
|
||||
// CHECK: SwitchStmt
|
||||
// CHECK-NEXT: <<NULL>>
|
||||
// CHECK-NEXT: <<NULL>>
|
||||
// CHECK-NEXT: IntegerLiteral
|
||||
// CHECK-NEXT: NullStmt
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ struct Invalid {
|
|||
//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]> [[Yellow]]line:9:6[[RESET]][[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void ()'[[RESET]]{{$}}
|
||||
//CHECK: {{^}}[[Blue]]| |-[[RESET]][[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}}
|
||||
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]SwitchStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:3[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
|
||||
//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[Blue:.\[0;34m]]<<<NULL>>>[[RESET]]{{$}}
|
||||
//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
|
||||
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
|
||||
//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}}
|
||||
|
|
Loading…
Reference in New Issue