diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2015-04-02 15:29:07 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2015-04-02 15:29:07 +0000 |
commit | 475386d688796883cf52cd9a84a81a5ecda19247 (patch) | |
tree | 3d7a2f30facba3f1b93f75a59a60304a6c348ccb /clang/include | |
parent | 45324cec5f3f00e75d4c641a19c0b547ed639728 (diff) | |
download | bcm5719-llvm-475386d688796883cf52cd9a84a81a5ecda19247.tar.gz bcm5719-llvm-475386d688796883cf52cd9a84a81a5ecda19247.zip |
[ast] Put the Stmt hierarchy on a diet for 64 bit targets.
Previously we would waste 32 bits on alignment, use LLVM_ALIGNAS to
free that space for derived classes an place. Sadly still have to #ifdef
out MSVC 2013 because it can't align based on a sizeof expr.
No intended functionality change. New byte counts:
sizeof(before) | sizeof(after)
LabelStmt: 32 | LabelStmt: 24
SwitchStmt: 48 | SwitchStmt: 40
WhileStmt: 40 | WhileStmt: 32
DoStmt: 40 | DoStmt: 32
ForStmt: 64 | ForStmt: 56
ContinueStmt: 16 | ContinueStmt: 8
BreakStmt: 16 | BreakStmt: 8
ReturnStmt: 32 | ReturnStmt: 24
AsmStmt: 40 | AsmStmt: 32
GCCAsmStmt: 80 | GCCAsmStmt: 72
MSAsmStmt: 96 | MSAsmStmt: 88
SEHExceptStmt: 32 | SEHExceptStmt: 24
SEHFinallyStmt: 24 | SEHFinallyStmt: 16
SEHLeaveStmt: 16 | SEHLeaveStmt: 8
CapturedStmt: 32 | CapturedStmt: 24
CXXCatchStmt: 32 | CXXCatchStmt: 24
CXXForRangeStmt: 72 | CXXForRangeStmt: 64
ObjCAtFinallyStmt: 24 | ObjCAtFinallyStmt: 16
ObjCAtSynchronizedStmt: 32 | ObjCAtSynchronizedStmt: 24
ObjCAtThrowStmt: 24 | ObjCAtThrowStmt: 16
ObjCAutoreleasePoolStmt: 24 | ObjCAutoreleasePoolStmt: 16
llvm-svn: 233921
Diffstat (limited to 'clang/include')
-rw-r--r-- | clang/include/clang/AST/Stmt.h | 64 | ||||
-rw-r--r-- | clang/include/clang/AST/StmtCXX.h | 2 | ||||
-rw-r--r-- | clang/include/clang/AST/StmtObjC.h | 21 |
3 files changed, 44 insertions, 43 deletions
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index a55cba9d1a4..9a0fa8a8dd6 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -101,7 +101,13 @@ namespace clang { /// Stmt - This represents one statement. /// +#if !defined(_MSC_VER) || LLVM_MSC_PREREQ(1900) +class LLVM_ALIGNAS(sizeof(void *)) Stmt { +#else +// Old MSVC has issues to align this. Drop when we retire MSVC 2013. When GCC +// 4.7 is also gone this can be just alignof(void *). class Stmt { +#endif public: enum StmtClass { NoStmtClass = 0, @@ -287,8 +293,10 @@ protected: }; union { +#if !(!defined(_MSC_VER) || LLVM_MSC_PREREQ(1900)) // FIXME: this is wasteful on 64-bit platforms. void *Aligner; +#endif StmtBitfields StmtBits; CompoundStmtBitfields CompoundStmtBits; @@ -688,10 +696,10 @@ public: }; class CaseStmt : public SwitchCase { + SourceLocation EllipsisLoc; enum { LHS, RHS, SUBSTMT, END_EXPR }; Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for // GNU "case 1 ... 4" extension - SourceLocation EllipsisLoc; public: CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc) @@ -788,13 +796,13 @@ inline SourceLocation SwitchCase::getLocEnd() const { /// foo: return; /// class LabelStmt : public Stmt { + SourceLocation IdentLoc; LabelDecl *TheDecl; Stmt *SubStmt; - SourceLocation IdentLoc; + public: LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt) - : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt), IdentLoc(IL) { - } + : Stmt(LabelStmtClass), IdentLoc(IL), TheDecl(D), SubStmt(substmt) {} // \brief Build an empty label statement. explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { } @@ -943,16 +951,14 @@ public: /// SwitchStmt - This represents a 'switch' stmt. /// class SwitchStmt : public Stmt { + SourceLocation SwitchLoc; enum { VAR, COND, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; - // This points to a linked list of case and default statements. - SwitchCase *FirstCase; - SourceLocation SwitchLoc; - - /// If the SwitchStmt is a switch on an enum value, this records whether - /// all the enum values were covered by CaseStmts. This value is meant to - /// be a hint for possible clients. - unsigned AllEnumCasesCovered : 1; + // 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; public: SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond); @@ -980,16 +986,16 @@ public: const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} const Stmt *getBody() const { return SubExprs[BODY]; } - const SwitchCase *getSwitchCaseList() const { return FirstCase; } + const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); } 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; } + SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); } /// \brief Set the case list for this switch statement. - void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } + void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); } SourceLocation getSwitchLoc() const { return SwitchLoc; } void setSwitchLoc(SourceLocation L) { SwitchLoc = L; } @@ -1001,21 +1007,17 @@ public: void addSwitchCase(SwitchCase *SC) { assert(!SC->getNextSwitchCase() && "case/default already added to a switch"); - SC->setNextSwitchCase(FirstCase); - FirstCase = SC; + SC->setNextSwitchCase(FirstCase.getPointer()); + FirstCase.setPointer(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() { - AllEnumCasesCovered = 1; - } + void setAllEnumCasesCovered() { FirstCase.setInt(true); } /// Returns true if the SwitchStmt is a switch of an enum value and all cases /// have been explicitly covered. - bool isAllEnumCasesCovered() const { - return (bool) AllEnumCasesCovered; - } + bool isAllEnumCasesCovered() const { return FirstCase.getInt(); } SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; } SourceLocation getLocEnd() const LLVM_READONLY { @@ -1036,9 +1038,9 @@ public: /// WhileStmt - This represents a 'while' stmt. /// class WhileStmt : public Stmt { + SourceLocation WhileLoc; enum { VAR, COND, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; - SourceLocation WhileLoc; public: WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL); @@ -1091,9 +1093,9 @@ public: /// DoStmt - This represents a 'do/while' stmt. /// class DoStmt : public Stmt { + SourceLocation DoLoc; enum { BODY, COND, END_EXPR }; Stmt* SubExprs[END_EXPR]; - SourceLocation DoLoc; SourceLocation WhileLoc; SourceLocation RParenLoc; // Location of final ')' in do stmt condition. @@ -1142,9 +1144,9 @@ public: /// specified in the source. /// class ForStmt : public Stmt { + SourceLocation ForLoc; enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. - SourceLocation ForLoc; SourceLocation LParenLoc, RParenLoc; public: @@ -1345,18 +1347,16 @@ public: /// depend on the return type of the function and the presence of an argument. /// class ReturnStmt : public Stmt { - Stmt *RetExpr; SourceLocation RetLoc; + Stmt *RetExpr; const VarDecl *NRVOCandidate; public: - ReturnStmt(SourceLocation RL) - : Stmt(ReturnStmtClass), RetExpr(nullptr), RetLoc(RL), - NRVOCandidate(nullptr) {} + explicit ReturnStmt(SourceLocation RL) : ReturnStmt(RL, nullptr, nullptr) {} ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate) - : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL), - NRVOCandidate(NRVOCandidate) {} + : Stmt(ReturnStmtClass), RetLoc(RL), RetExpr((Stmt *)E), + NRVOCandidate(NRVOCandidate) {} /// \brief Build an empty return expression. explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { } diff --git a/clang/include/clang/AST/StmtCXX.h b/clang/include/clang/AST/StmtCXX.h index 837dc45d122..567a7728843 100644 --- a/clang/include/clang/AST/StmtCXX.h +++ b/clang/include/clang/AST/StmtCXX.h @@ -126,11 +126,11 @@ public: /// analysis of the constituent components. The original syntactic components /// can be extracted using getLoopVariable and getRangeInit. class CXXForRangeStmt : public Stmt { + SourceLocation ForLoc; enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; // SubExprs[RANGE] is an expression or declstmt. // SubExprs[COND] and SubExprs[INC] are expressions. Stmt *SubExprs[END]; - SourceLocation ForLoc; SourceLocation ColonLoc; SourceLocation RParenLoc; public: diff --git a/clang/include/clang/AST/StmtObjC.h b/clang/include/clang/AST/StmtObjC.h index d0527e2d8b6..68fe3ef697b 100644 --- a/clang/include/clang/AST/StmtObjC.h +++ b/clang/include/clang/AST/StmtObjC.h @@ -118,12 +118,13 @@ public: /// \brief Represents Objective-C's \@finally statement class ObjCAtFinallyStmt : public Stmt { - Stmt *AtFinallyStmt; SourceLocation AtFinallyLoc; + Stmt *AtFinallyStmt; + public: ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) - : Stmt(ObjCAtFinallyStmtClass), - AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} + : Stmt(ObjCAtFinallyStmtClass), AtFinallyLoc(atFinallyLoc), + AtFinallyStmt(atFinallyStmt) {} explicit ObjCAtFinallyStmt(EmptyShell Empty) : Stmt(ObjCAtFinallyStmtClass, Empty) { } @@ -260,9 +261,9 @@ public: /// \endcode class ObjCAtSynchronizedStmt : public Stmt { private: + SourceLocation AtSynchronizedLoc; enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; Stmt* SubStmts[END_EXPR]; - SourceLocation AtSynchronizedLoc; public: ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, @@ -310,8 +311,9 @@ public: /// \brief Represents Objective-C's \@throw statement. class ObjCAtThrowStmt : public Stmt { - Stmt *Throw; SourceLocation AtThrowLoc; + Stmt *Throw; + public: ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { @@ -341,13 +343,12 @@ public: /// \brief Represents Objective-C's \@autoreleasepool Statement class ObjCAutoreleasePoolStmt : public Stmt { - Stmt *SubStmt; SourceLocation AtLoc; + Stmt *SubStmt; + public: - ObjCAutoreleasePoolStmt(SourceLocation atLoc, - Stmt *subStmt) - : Stmt(ObjCAutoreleasePoolStmtClass), - SubStmt(subStmt), AtLoc(atLoc) {} + ObjCAutoreleasePoolStmt(SourceLocation atLoc, Stmt *subStmt) + : Stmt(ObjCAutoreleasePoolStmtClass), AtLoc(atLoc), SubStmt(subStmt) {} explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) : Stmt(ObjCAutoreleasePoolStmtClass, Empty) { } |