From: Chandler Carruth Date: Sun, 1 May 2011 21:29:53 +0000 (+0000) Subject: Move the state bits in DeclRefExpr out of the pointer union and into X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cb66cff8fdf641f57f85dedb515a5f3240e3a9bb;p=clang Move the state bits in DeclRefExpr out of the pointer union and into a bitfield in the base class. DREs weren't using any bits here past the normal Expr bits, so we have plenty of room. This makes the common case of getting a Decl out of a DRE no longer need to do any masking etc. Also, while here, clean up code to use the accessor methods rather than directly poking these bits, and provide a nice comment for DREs that includes the information previously attached to the bits going into the pointer union. No functionality changed here, but DREs should be a tad faster now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130666 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index f006f0ec6d..9a8ed5ddd4 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -669,41 +669,43 @@ struct ExplicitTemplateArgumentList { static std::size_t sizeFor(unsigned NumTemplateArgs); static std::size_t sizeFor(const TemplateArgumentListInfo &List); }; - -/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function, -/// enum, etc. + +/// \brief A reference to a declared variable, function, enum, etc. +/// [C99 6.5.1p2] +/// +/// This encodes all the information about how a declaration is referenced +/// within an expression. +/// +/// There are several optional constructs attached to DeclRefExprs only when +/// they apply in order to conserve memory. These are laid out past the end of +/// the object, and flags in the DeclRefExprBitfield track whether they exist: +/// +/// DeclRefExprBits.HasQualifier: +/// Specifies when this declaration reference expression has a C++ +/// nested-name-specifier. +/// DeclRefExprBits.HasExplicitTemplateArgs: +/// Specifies when this declaration reference expression has an explicit +/// C++ template argument list. class DeclRefExpr : public Expr { - enum { - // Flag on DecoratedD that specifies when this declaration reference - // expression has a C++ nested-name-specifier. - HasQualifierFlag = 0x01, - // Flag on DecoratedD that specifies when this declaration reference - // expression has an explicit C++ template argument list. - HasExplicitTemplateArgumentListFlag = 0x02 - }; - - // DecoratedD - The declaration that we are referencing, plus two bits to - // indicate whether (1) the declaration's name was explicitly qualified and - // (2) the declaration's name was followed by an explicit template - // argument list. - llvm::PointerIntPair DecoratedD; + /// \brief The declaration that we are referencing. + ValueDecl *D; - // Loc - The location of the declaration name itself. + /// \brief The location of the declaration name itself. SourceLocation Loc; - /// DNLoc - Provides source/type location info for the - /// declaration name embedded in DecoratedD. + /// \brief Provides source/type location info for the declaration name + /// embedded in D. DeclarationNameLoc DNLoc; /// \brief Retrieve the qualifier that preceded the declaration name, if any. NameQualifier *getNameQualifier() { - if ((DecoratedD.getInt() & HasQualifierFlag) == 0) + if (!hasQualifier()) return 0; - + return reinterpret_cast (this + 1); } - - /// \brief Retrieve the qualifier that preceded the member name, if any. + + /// \brief Retrieve the qualifier that preceded the declaration name, if any. const NameQualifier *getNameQualifier() const { return const_cast(this)->getNameQualifier(); } @@ -727,9 +729,11 @@ class DeclRefExpr : public Expr { void computeDependence(); public: - DeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, SourceLocation l) : - Expr(DeclRefExprClass, t, VK, OK_Ordinary, false, false, false), - DecoratedD(d, 0), Loc(l) { + DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L) + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), + D(D), Loc(L) { + DeclRefExprBits.HasQualifier = 0; + DeclRefExprBits.HasExplicitTemplateArgs = 0; computeDependence(); } @@ -753,9 +757,9 @@ public: bool HasExplicitTemplateArgs, unsigned NumTemplateArgs); - ValueDecl *getDecl() { return DecoratedD.getPointer(); } - const ValueDecl *getDecl() const { return DecoratedD.getPointer(); } - void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); } + ValueDecl *getDecl() { return D; } + const ValueDecl *getDecl() const { return D; } + void setDecl(ValueDecl *NewD) { D = NewD; } DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc); @@ -767,7 +771,7 @@ public: /// \brief Determine whether this declaration reference was preceded by a /// C++ nested-name-specifier, e.g., \c N::foo. - bool hasQualifier() const { return DecoratedD.getInt() & HasQualifierFlag; } + bool hasQualifier() const { return DeclRefExprBits.HasQualifier; } /// \brief If the name was qualified, retrieves the nested-name-specifier /// that precedes the name. Otherwise, returns NULL. @@ -788,7 +792,7 @@ public: } bool hasExplicitTemplateArgs() const { - return (DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag); + return DeclRefExprBits.HasExplicitTemplateArgs; } /// \brief Retrieve the explicit template argument list that followed the @@ -796,7 +800,7 @@ public: ExplicitTemplateArgumentList &getExplicitTemplateArgs() { assert(hasExplicitTemplateArgs()); - if ((DecoratedD.getInt() & HasQualifierFlag) == 0) + if (!hasQualifier()) return *reinterpret_cast(this + 1); return *reinterpret_cast( diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index e3301c513a..903096e137 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -158,6 +158,15 @@ protected: }; enum { NumExprBits = 15 }; + class DeclRefExprBitfields { + friend class DeclRefExpr; + friend class ASTStmtReader; // deserialization + unsigned : NumExprBits; + + unsigned HasQualifier : 1; + unsigned HasExplicitTemplateArgs : 1; + }; + class CastExprBitfields { friend class CastExpr; unsigned : NumExprBits; @@ -180,6 +189,7 @@ protected: StmtBitfields StmtBits; CompoundStmtBitfields CompoundStmtBits; ExprBitfields ExprBits; + DeclRefExprBitfields DeclRefExprBits; CastExprBitfields CastExprBits; CallExprBitfields CallExprBits; }; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 2a5917c459..cd5a63aab5 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -279,17 +279,18 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), - DecoratedD(D, - (QualifierLoc? HasQualifierFlag : 0) | - (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), - Loc(NameLoc) { + D(D), Loc(NameLoc) { + DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; if (QualifierLoc) { + DeclRefExprBits.HasQualifier = 1; NameQualifier *NQ = getNameQualifier(); NQ->QualifierLoc = QualifierLoc; } - - if (TemplateArgs) + + DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0; + if (TemplateArgs) { getExplicitTemplateArgs().initializeFrom(*TemplateArgs); + } computeDependence(); } @@ -299,15 +300,14 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), - DecoratedD(D, - (QualifierLoc? HasQualifierFlag : 0) | - (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), - Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { + D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { + DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; if (QualifierLoc) { NameQualifier *NQ = getNameQualifier(); NQ->QualifierLoc = QualifierLoc; } + DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0; if (TemplateArgs) getExplicitTemplateArgs().initializeFrom(*TemplateArgs); diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 83b3907f58..f0b5abaf3b 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -425,21 +425,17 @@ void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) { void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); - bool HasQualifier = Record[Idx++]; - bool HasExplicitTemplateArgs = Record[Idx++]; + E->DeclRefExprBits.HasQualifier = Record[Idx++]; + E->DeclRefExprBits.HasExplicitTemplateArgs = Record[Idx++]; unsigned NumTemplateArgs = 0; - if (HasExplicitTemplateArgs) + if (E->hasExplicitTemplateArgs()) NumTemplateArgs = Record[Idx++]; - E->DecoratedD.setInt((HasQualifier? DeclRefExpr::HasQualifierFlag : 0) | - (HasExplicitTemplateArgs - ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0)); - - if (HasQualifier) + if (E->hasQualifier()) E->getNameQualifier()->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); - if (HasExplicitTemplateArgs) + if (E->hasExplicitTemplateArgs()) ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), NumTemplateArgs);