[cfe-commits] r132572 - in /cfe/trunk: include/clang/AST/Type.h include/clang/Sema/Sema.h lib/Sema/SemaLookup.cpp
Chandler Carruth
chandlerc at google.com
Fri Jun 3 13:16:50 PDT 2011
Comments inline.
On Fri, Jun 3, 2011 at 11:36 AM, Sean Hunt <scshunt at csclub.uwaterloo.ca>wrote:
> Author: coppro
> Date: Fri Jun 3 13:36:49 2011
> New Revision: 132572
>
> URL: http://llvm.org/viewvc/llvm-project?rev=132572&view=rev
> Log:
> Begin implementing a cache of special member lookups. Currently only
> destructors are implemented but other special members are on the way,
> which is where the real benefits of this will be visible.
>
> Modified:
> cfe/trunk/include/clang/AST/Type.h
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/Sema/SemaLookup.cpp
>
> Modified: cfe/trunk/include/clang/AST/Type.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=132572&r1=132571&r2=132572&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Type.h (original)
> +++ cfe/trunk/include/clang/AST/Type.h Fri Jun 3 13:36:49 2011
> @@ -538,6 +538,14 @@
> return withFastQualifiers(Qualifiers::Const);
> }
>
> + /// addVolatile - add the specified type qualifier to this QualType.
> + void addVolatile() {
> + addFastQualifiers(Qualifiers::Volatile);
> + }
>
I didn't think we wanted to keep adding setters to the AST nodes... But
maybe this one isn't so bad.
+ QualType withVolatile() const {
> + return withFastQualifiers(Qualifiers::Volatile);
> + }
> +
> void addFastQualifiers(unsigned TQs) {
> assert(!(TQs & ~Qualifiers::FastMask)
> && "non-fast qualifier bits set in mask!");
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=132572&r1=132571&r2=132572&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Fri Jun 3 13:36:49 2011
> @@ -198,6 +198,52 @@
> typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*,
> NamedDecl*>,
> SourceLocation> UnexpandedParameterPack;
>
> +// Holds some information about special member function overloads
> +// Defined outside Sema so it can be used as a key in a DenseMap.
> +struct SpecialMemberID {
> + CXXRecordDecl *D;
> + unsigned SM : 3; //CXXSpecialMember
>
SM seems like a really unfortunate name here, and the comment doesn't help
much. SM usually refers to the Source Manager. Is this maybe the
"MemberKind"?
> + bool ConstArg : 1;
> + bool VolatileArg : 1;
> + bool RValueThis : 1;
> + bool ConstThis : 1;
> + bool VolatileThis : 1;
> +};
> +
> +} // namespace clang
> +
> +namespace llvm {
> +template <> struct DenseMapInfo<clang::SpecialMemberID> {
> + static inline clang::SpecialMemberID getEmptyKey() {
> + clang::SpecialMemberID SMI =
> + {DenseMapInfo<clang::CXXRecordDecl*>::getEmptyKey(), 0,0,0,0,0,0};
> + return SMI;
> + }
> + static inline clang::SpecialMemberID getTombstoneKey() {
> + clang::SpecialMemberID SMI =
> + {DenseMapInfo<clang::CXXRecordDecl*>::getTombstoneKey(),
> 0,0,0,0,0,0};
> + return SMI;
> + }
> + static unsigned getHashValue (const clang::SpecialMemberID SMI) {
> + // Vary higher bits of the pointer for hashing. Attempt to match the
> + // bit-field representation to reduce masking if the optimizer is
> awake.
> + // Note that the LLVM optimizer sleeps through this one.
> + return (uintptr_t)SMI.D ^
> + ((SMI.SM << 24) + (SMI.ConstArg << 27) + (SMI.VolatileArg << 28) +
> + (SMI.RValueThis << 29) + (SMI.ConstThis << 30) +
> + (SMI.VolatileThis << 31));
> + }
> + static bool isEqual(const clang::SpecialMemberID LHS,
> + const clang::SpecialMemberID RHS) {
> + return LHS.D == RHS.D && LHS.SM == RHS.SM && LHS.ConstArg ==
> RHS.ConstArg &&
> + LHS.VolatileArg == RHS.VolatileArg &&
> + LHS.RValueThis == RHS.RValueThis && LHS.ConstThis ==
> RHS.ConstThis &&
> + LHS.VolatileThis == RHS.VolatileThis;
> + }
> +};
> +} // namespace llvm
> +
> +namespace clang {
> /// Sema - This implements semantic analysis and AST building for C.
> class Sema {
> Sema(const Sema&); // DO NOT IMPLEMENT
> @@ -600,6 +646,47 @@
> /// A stack of expression evaluation contexts.
> llvm::SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
>
> + /// SpecialMemberOverloadResult - The overloading result for a special
> member
> + /// function.
> + ///
> + /// This is basically a wrapper around PointerIntPair. The lowest bit of
> the
> + /// integer is used to determine whether we have a parameter
> qualification
> + /// match, the second-lowest is whether we had success in resolving the
> + /// overload to a unique non-deleted function.
> + ///
> + /// The ConstParamMatch bit represents whether, when looking up a copy
> + /// constructor or assignment operator, we found a potential copy
> + /// constructor/assignment operator whose first parameter is
> const-qualified.
> + /// This is used for determining parameter types of other objects and is
> + /// utterly meaningless on other types of special members.
> + class SpecialMemberOverloadResult {
> + llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
> + public:
> + SpecialMemberOverloadResult(CXXMethodDecl *MD, bool Success,
> + bool ConstParamMatch)
> + : Pair(MD, Success | ConstParamMatch << 1)
> + {}
> + SpecialMemberOverloadResult() {}
> +
> + CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
> + void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
> +
> + bool hasSuccess() const { return Pair.getInt() & 0x1; }
> + void setSuccess(bool B) { Pair.setInt(B | hasConstParamMatch() << 1);
> }
> +
> + bool hasConstParamMatch() const { return Pair.getInt() & 0x2; }
> + void setConstParamMatch(bool B) { Pair.setInt(B << 1 | hasSuccess());
> }
> + };
> +
> + /// \brief A cache of special member function overload resolution
> results
> + /// for C++ records.
> + ///
> + /// In C++, special member functions of records (such as the copy
> constructor)
> + /// are used a lot. As a result, we cache the lookups here so as to make
> the
> + /// lookups far easier to perform.
> + llvm::DenseMap<SpecialMemberID, SpecialMemberOverloadResult>
> + SpecialMemberCache;
> +
> /// \brief Whether the code handled by Sema should be considered a
> /// complete translation unit or not.
> ///
> @@ -1594,6 +1681,14 @@
> private:
> bool CppLookupName(LookupResult &R, Scope *S);
>
> + SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D,
> + CXXSpecialMember SM,
> + bool ConstArg,
> + bool VolatileArg,
> + bool RValueThis,
> + bool ConstThis,
> + bool VolatileThis);
> +
> public:
> /// \brief Look up a name, looking for a single declaration. Return
> /// null if the results were absent, ambiguous, or overloaded.
>
> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=132572&r1=132571&r2=132572&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Jun 3 13:36:49 2011
> @@ -14,6 +14,7 @@
> #include "clang/Sema/Sema.h"
> #include "clang/Sema/SemaInternal.h"
> #include "clang/Sema/Lookup.h"
> +#include "clang/Sema/Overload.h"
> #include "clang/Sema/DeclSpec.h"
> #include "clang/Sema/Scope.h"
> #include "clang/Sema/ScopeInfo.h"
> @@ -2136,6 +2137,51 @@
> }
> }
>
> +Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl
> *D,
> +
> CXXSpecialMember SM,
> + bool ConstArg,
> + bool
> VolatileArg,
> + bool
> RValueThis,
> + bool
> ConstThis,
> + bool
> VolatileThis) {
> + D = D->getDefinition();
> + assert((D && !D->isBeingDefined()) &&
> + "doing special member lookup into record that isn't fully
> complete");
> + if (RValueThis || ConstThis || VolatileThis)
> + assert((SM == CXXCopyAssignment || SM == CXXMoveAssignment) &&
> + "constructors and destructors always have unqualified lvalue
> this");
> + if (ConstArg || VolatileArg)
> + assert((SM != CXXDefaultConstructor && SM != CXXDestructor) &&
> + "parameter-less special members can't have qualified
> arguments");
> +
> + // Check the cache for this member
> + SpecialMemberID ID = {D, SM, ConstArg, VolatileArg, RValueThis,
> ConstThis,
> + VolatileThis};
> + SpecialMemberOverloadResult Blank;
> + llvm::DenseMap<SpecialMemberID, SpecialMemberOverloadResult>::iterator
> It;
> + bool New;
> +
> + llvm::tie(It, New) = SpecialMemberCache.insert(std::make_pair(ID,
> Blank));
> + SpecialMemberOverloadResult &Result = It->second;
> +
> + // This was already cached
> + if (!New)
> + return Result;
> +
> + if (SM == CXXDestructor) {
> + if (!D->hasDeclaredDestructor())
> + DeclareImplicitDestructor(D);
> + CXXDestructorDecl *DD = D->getDestructor();
> + assert(DD && "record without a destructor");
> + Result.setMethod(DD);
> + Result.setSuccess(DD->isDeleted());
> + Result.setConstParamMatch(false);
> + return Result;
> + }
> +
> + llvm_unreachable("haven't implemented this for non-destructors yet");
> +}
> +
> /// \brief Look up the constructors for the given class.
> DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class)
> {
> // If the copy constructor has not yet been declared, do so now.
> @@ -2153,17 +2199,13 @@
>
> /// \brief Look for the destructor of the given class.
> ///
> -/// During semantic analysis, this routine should be used in lieu of
> -/// CXXRecordDecl::getDestructor().
> +/// The destructor will be declared if necessary.
> ///
> /// \returns The destructor for this class.
> CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) {
> - // If the destructor has not yet been declared, do so now.
> - if (CanDeclareSpecialMemberFunction(Context, Class) &&
> - !Class->hasDeclaredDestructor())
> - DeclareImplicitDestructor(Class);
> -
> - return Class->getDestructor();
> + return cast<CXXDestructorDecl>(LookupSpecialMember(Class, CXXDestructor,
> + false, false, false,
> + false,
> false).getMethod());
> }
>
> void ADLResult::insert(NamedDecl *New) {
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110603/7f5a646c/attachment.html>
More information about the cfe-commits
mailing list