From b11aad8cba67e2aadd9fdaaa219a80cf42ef8d4e Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 19 Feb 2011 18:51:44 +0000 Subject: [PATCH] Revert all of my commits that devirtualized the Decl hierarchy, which lead to a serious slowdown (4%) on parsing of Cocoa.h. This memory optimization should be revisited later, when we have time to look at the generated code. llvm-svn: 126033 --- clang/include/clang/AST/Decl.h | 71 ++++++------ clang/include/clang/AST/DeclBase.h | 21 ++-- clang/include/clang/AST/DeclCXX.h | 12 +- clang/include/clang/AST/DeclObjC.h | 21 ++-- clang/include/clang/AST/DeclTemplate.h | 16 ++- clang/lib/AST/Decl.cpp | 87 +++++---------- clang/lib/AST/DeclBase.cpp | 147 +------------------------ clang/lib/AST/DeclCXX.cpp | 15 ++- clang/lib/AST/DeclTemplate.cpp | 28 +++-- 9 files changed, 133 insertions(+), 285 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 4da6204b690b..dd0401f23e6f 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -158,9 +158,14 @@ public: /// specializations are printed with their template arguments. /// /// TODO: use an API that doesn't require so many temporary strings - void getNameForDiagnostic(std::string &S, - const PrintingPolicy &Policy, - bool Qualified) const; + virtual void getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const { + if (Qualified) + S += getQualifiedNameAsString(Policy); + else + S += getNameAsString(); + } /// declarationReplaces - Determine whether this declaration, if /// known to be well-formed within its context, will replace the @@ -418,12 +423,12 @@ public: getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D); } - NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); } + virtual NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); } const NamespaceDecl *getCanonicalDecl() const { return getOriginalNamespace(); } - SourceRange getSourceRange() const { + virtual SourceRange getSourceRange() const { return SourceRange(getLocation(), RBracLoc); } @@ -531,7 +536,7 @@ public: /// getInnerLocStart - Return SourceLocation representing start of source /// range ignoring outer template declarations. - SourceLocation getInnerLocStart() const; + virtual SourceLocation getInnerLocStart() const { return getLocation(); } /// getOuterLocStart - Return SourceLocation representing start of source /// range taking into account any outer template declarations. @@ -662,9 +667,8 @@ protected: } typedef Redeclarable redeclarable_base; - VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); } - friend class Decl; - + virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + public: typedef redeclarable_base::redecl_iterator redecl_iterator; redecl_iterator redecls_begin() const { @@ -679,7 +683,8 @@ public: QualType T, TypeSourceInfo *TInfo, StorageClass S, StorageClass SCAsWritten); - SourceRange getSourceRange() const; + virtual SourceLocation getInnerLocStart() const; + virtual SourceRange getSourceRange() const; StorageClass getStorageClass() const { return (StorageClass)SClass; } StorageClass getStorageClassAsWritten() const { @@ -767,7 +772,7 @@ public: return getKind() != Decl::ParmVar && getDeclContext()->isRecord(); } - VarDecl *getCanonicalDecl(); + virtual VarDecl *getCanonicalDecl(); const VarDecl *getCanonicalDecl() const { return const_cast(this)->getCanonicalDecl(); } @@ -806,7 +811,7 @@ public: /// \brief Determine whether this is or was instantiated from an out-of-line /// definition of a static data member. - bool isOutOfLine() const; + virtual bool isOutOfLine() const; /// \brief If this is a static data member, find its out-of-line definition. VarDecl *getOutOfLineDefinition(); @@ -1298,12 +1303,9 @@ protected: DNLoc(NameInfo.getInfo()) {} typedef Redeclarable redeclarable_base; - FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); } - friend class Decl; - public: - typedef redeclarable_base::redecl_iterator redecl_iterator; redecl_iterator redecls_begin() const { return redeclarable_base::redecls_begin(); @@ -1336,7 +1338,11 @@ public: return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } - SourceRange getSourceRange() const { + virtual void getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const; + + virtual SourceRange getSourceRange() const { return SourceRange(getOuterLocStart(), EndRangeLoc); } void setLocEnd(SourceLocation E) { @@ -1350,7 +1356,7 @@ public: /// containing the body (if there is one). bool hasBody(const FunctionDecl *&Definition) const; - bool hasBody() const { + virtual bool hasBody() const { const FunctionDecl* Definition; return hasBody(Definition); } @@ -1364,7 +1370,7 @@ public: /// unnecessary AST de-serialization of the body. Stmt *getBody(const FunctionDecl *&Definition) const; - Stmt *getBody() const { + virtual Stmt *getBody() const { const FunctionDecl* Definition; return getBody(Definition); } @@ -1454,8 +1460,8 @@ public: void setPreviousDeclaration(FunctionDecl * PrevDecl); - const FunctionDecl *getCanonicalDecl() const; - FunctionDecl *getCanonicalDecl(); + virtual const FunctionDecl *getCanonicalDecl() const; + virtual FunctionDecl *getCanonicalDecl(); unsigned getBuiltinID() const; @@ -1708,7 +1714,7 @@ public: /// \brief Determine whether this is or was instantiated from an out-of-line /// definition of a member function. - bool isOutOfLine() const; + virtual bool isOutOfLine() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1908,10 +1914,8 @@ class TypedefDecl : public TypeDecl, public Redeclarable { protected: typedef Redeclarable redeclarable_base; - TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); } - friend class Decl; - public: typedef redeclarable_base::redecl_iterator redecl_iterator; redecl_iterator redecls_begin() const { @@ -2031,14 +2035,12 @@ protected: } typedef Redeclarable redeclarable_base; - TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); } + virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); } /// @brief Completes the definition of this tag declaration. /// /// This is a helper function for derived classes. void completeDefinition(); - - friend class Decl; public: typedef redeclarable_base::redecl_iterator redecl_iterator; @@ -2057,14 +2059,14 @@ public: /// getInnerLocStart - Return SourceLocation representing start of source /// range ignoring outer template declarations. - SourceLocation getInnerLocStart() const; + virtual SourceLocation getInnerLocStart() const { return TagKeywordLoc; } /// getOuterLocStart - Return SourceLocation representing start of source /// range taking into account any outer template declarations. SourceLocation getOuterLocStart() const; - SourceRange getSourceRange() const; + virtual SourceRange getSourceRange() const; - TagDecl* getCanonicalDecl(); + virtual TagDecl* getCanonicalDecl(); const TagDecl* getCanonicalDecl() const { return const_cast(this)->getCanonicalDecl(); } @@ -2478,8 +2480,9 @@ public: return field_begin() == field_end(); } - /// \brief Indicates that the definition of this class is now complete. - void completeDefinition(); + /// completeDefinition - Notes that the definition of this type is + /// now complete. + virtual void completeDefinition(); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const RecordDecl *D) { return true; } @@ -2636,7 +2639,7 @@ public: const Capture *end, bool capturesCXXThis); - SourceRange getSourceRange() const; + virtual SourceRange getSourceRange() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 6670d9de12eb..bf249cea9d5f 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -270,10 +270,14 @@ protected: if (Decl::CollectingStats()) add(DK); } + virtual ~Decl(); + public: /// \brief Source range that this declaration covers. - SourceRange getSourceRange() const; + virtual SourceRange getSourceRange() const { + return SourceRange(getLocation(), getLocation()); + } SourceLocation getLocStart() const { return getSourceRange().getBegin(); } SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } @@ -455,10 +459,9 @@ public: return const_cast(this)->getLexicalDeclContext(); } - /// \brief Determine whether this declaration was written out-of-line, which - /// typically indicates that it was written with a qualified name in a scope - /// outside of its semantic scope. - bool isOutOfLine() const; + virtual bool isOutOfLine() const { + return getLexicalDeclContext() != getDeclContext(); + } /// setDeclContext - Set both the semantic and lexical DeclContext /// to DC. @@ -473,7 +476,7 @@ public: bool isDefinedOutsideFunctionOrMethod() const; /// \brief Retrieves the "canonical" declaration of the given declaration. - Decl *getCanonicalDecl(); + virtual Decl *getCanonicalDecl() { return this; } const Decl *getCanonicalDecl() const { return const_cast(this)->getCanonicalDecl(); } @@ -486,7 +489,7 @@ protected: /// /// Decl subclasses that can be redeclared should override this method so that /// Decl::redecl_iterator can iterate over them. - Decl *getNextRedeclaration(); + virtual Decl *getNextRedeclaration() { return this; } public: /// \brief Iterates through all the redeclarations of the same decl. @@ -541,11 +544,11 @@ public: /// getBody - If this Decl represents a declaration for a body of code, /// such as a function or method definition, this method returns the /// top-level Stmt* of that body. Otherwise this method returns null. - Stmt* getBody() const; + virtual Stmt* getBody() const { return 0; } /// \brief Returns true if this Decl represents a declaration for a body of /// code, such as a function or method definition. - bool hasBody() const; + virtual bool hasBody() const { return getBody() != 0; } /// getBodyRBrace - Gets the right brace of the body, if a body exists. /// This works whether the body is a CompoundStmt or a CXXTryStmt. diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 3d730eff6fbf..d11ee8f7fd64 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -447,9 +447,6 @@ class CXXRecordDecl : public RecordDecl { void markedVirtualFunctionPure(); friend void FunctionDecl::setPure(bool); - void completeDefinitionImpl(CXXFinalOverriderMap *FinalOverriders); - friend class RecordDecl; - protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -475,10 +472,10 @@ public: typedef std::reverse_iterator reverse_base_class_const_iterator; - CXXRecordDecl *getCanonicalDecl() { + virtual CXXRecordDecl *getCanonicalDecl() { return cast(RecordDecl::getCanonicalDecl()); } - const CXXRecordDecl *getCanonicalDecl() const { + virtual const CXXRecordDecl *getCanonicalDecl() const { return cast(RecordDecl::getCanonicalDecl()); } @@ -997,6 +994,9 @@ public: return (PathAccess > DeclAccess ? PathAccess : DeclAccess); } + /// \brief Indicates that the definition of this class is now complete. + virtual void completeDefinition(); + /// \brief Indicates that the definition of this class is now complete, /// and provides a final overrider map to help determine /// @@ -1922,7 +1922,7 @@ public: SourceLocation IdentLoc, NamedDecl *Namespace); - SourceRange getSourceRange() const { + virtual SourceRange getSourceRange() const { return SourceRange(NamespaceLoc, IdentLoc); } diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index ddc680fb82f6..b3ca474fcc19 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -182,9 +182,8 @@ private: /// \brief A definition will return its interface declaration. /// An interface declaration will return its definition. /// Otherwise it will return itself. - ObjCMethodDecl *getNextRedeclaration(); - friend class Decl; - + virtual ObjCMethodDecl *getNextRedeclaration(); + public: static ObjCMethodDecl *Create(ASTContext &C, SourceLocation beginLoc, @@ -199,7 +198,7 @@ public: ImplementationControl impControl = None, unsigned numSelectorArgs = 0); - ObjCMethodDecl *getCanonicalDecl(); + virtual ObjCMethodDecl *getCanonicalDecl(); const ObjCMethodDecl *getCanonicalDecl() const { return const_cast(this)->getCanonicalDecl(); } @@ -218,7 +217,7 @@ public: SourceLocation getLocStart() const { return getLocation(); } SourceLocation getLocEnd() const { return EndLoc; } void setEndLoc(SourceLocation Loc) { EndLoc = Loc; } - SourceRange getSourceRange() const { + virtual SourceRange getSourceRange() const { return SourceRange(getLocation(), EndLoc); } @@ -301,7 +300,7 @@ public: return ImplementationControl(DeclImplementation); } - Stmt *getBody() const { + virtual Stmt *getBody() const { return (Stmt*) Body; } CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; } @@ -394,7 +393,7 @@ public: AtEnd = atEnd; } - SourceRange getSourceRange() const { + virtual SourceRange getSourceRange() const { return SourceRange(getLocation(), getAtEndRange().getEnd()); } @@ -887,7 +886,7 @@ public: const SourceLocation *Locs = 0, unsigned nElts = 0); - SourceRange getSourceRange() const; + virtual SourceRange getSourceRange() const; typedef const ObjCClassRef* iterator; iterator begin() const { return ForwardDecls; } @@ -1068,7 +1067,7 @@ public: SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; } - SourceRange getSourceRange() const { + virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, getAtEndRange().getEnd()); } @@ -1479,7 +1478,7 @@ public: return PropertyIvarDecl; } - SourceRange getSourceRange() const { + virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, getLocation()); } @@ -1545,7 +1544,7 @@ public: ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc); - SourceRange getSourceRange() const; + virtual SourceRange getSourceRange() const; SourceLocation getLocStart() const { return AtLoc; } void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 573dd47274c4..176c6badae16 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -561,7 +561,7 @@ protected: /// for the common pointer. CommonBase *getCommonPtr(); - CommonBase *newCommon(ASTContext &C); + virtual CommonBase *newCommon(ASTContext &C) = 0; // Construct a template decl with name, parameters, and templated element. RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -651,7 +651,7 @@ public: return getInstantiatedFromMemberTemplateImpl(); } - RedeclarableTemplateDecl *getNextRedeclaration(); + virtual RedeclarableTemplateDecl *getNextRedeclaration(); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -773,8 +773,7 @@ protected: } friend class FunctionDecl; - friend class RedeclarableTemplateDecl; - + /// \brief Retrieve the set of function template specializations of this /// function template. llvm::FoldingSet &getSpecializations() { @@ -1041,6 +1040,7 @@ public: using TemplateParmPosition::setPosition; using TemplateParmPosition::getIndex; + SourceLocation getInnerLocStart() const; SourceRange getSourceRange() const; /// \brief Determine whether this template parameter has a default @@ -1317,6 +1317,10 @@ public: static ClassTemplateSpecializationDecl * Create(ASTContext &Context, EmptyShell Empty); + virtual void getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const; + ClassTemplateSpecializationDecl *getMostRecentDeclaration() { CXXRecordDecl *Recent = cast(CXXRecordDecl::getMostRecentDeclaration()); @@ -1467,6 +1471,8 @@ public: return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); } + SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); } + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext()); } @@ -1725,8 +1731,6 @@ protected: return static_cast(RedeclarableTemplateDecl::getCommonPtr()); } - friend class RedeclarableTemplateDecl; - public: /// Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 7d4b461f5a7c..56db8c7e330b 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -601,30 +601,6 @@ static void clearLinkageForClass(const CXXRecordDecl *record) { } } -void NamedDecl::getNameForDiagnostic(std::string &S, - const PrintingPolicy &Policy, - bool Qualified) const { - if (Qualified) - S += getQualifiedNameAsString(Policy); - else - S += getNameAsString(); - - const TemplateArgumentList *TemplateArgs = 0; - - if (const FunctionDecl *FD = dyn_cast(this)) - TemplateArgs = FD->getTemplateSpecializationArgs(); - else if (const ClassTemplateSpecializationDecl *Spec - = dyn_cast(this)) - TemplateArgs = &Spec->getTemplateArgs(); - - - if (TemplateArgs) - S += TemplateSpecializationType::PrintTemplateArgumentList( - TemplateArgs->data(), - TemplateArgs->size(), - Policy); -} - void NamedDecl::ClearLinkageCache() { // Note that we can't skip clearing the linkage of children just // because the parent doesn't have cached linkage: we don't cache @@ -981,20 +957,6 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier, } } -SourceLocation DeclaratorDecl::getInnerLocStart() const { - if (const VarDecl *Var = dyn_cast(this)) { - SourceLocation Start = Var->getTypeSpecStartLoc(); - if (Start.isValid()) - return Start; - } else if (const NonTypeTemplateParmDecl *NTTP - = dyn_cast(this)) { - SourceLocation Start = NTTP->getTypeSpecStartLoc(); - if (Start.isValid()) - return Start; - } - return getLocation(); -} - SourceLocation DeclaratorDecl::getOuterLocStart() const { return getTemplateOrInnerLocStart(this); } @@ -1055,6 +1017,13 @@ void VarDecl::setStorageClass(StorageClass SC) { SClass = SC; } +SourceLocation VarDecl::getInnerLocStart() const { + SourceLocation Start = getTypeSpecStartLoc(); + if (Start.isInvalid()) + Start = getLocation(); + return Start; +} + SourceRange VarDecl::getSourceRange() const { if (getInit()) return SourceRange(getOuterLocStart(), getInit()->getLocEnd()); @@ -1202,7 +1171,7 @@ const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const { } bool VarDecl::isOutOfLine() const { - if (getLexicalDeclContext() != getDeclContext()) + if (Decl::isOutOfLine()) return true; if (!isStaticDataMember()) @@ -1326,6 +1295,19 @@ bool ParmVarDecl::isParameterPack() const { // FunctionDecl Implementation //===----------------------------------------------------------------------===// +void FunctionDecl::getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const { + NamedDecl::getNameForDiagnostic(S, Policy, Qualified); + const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs(); + if (TemplateArgs) + S += TemplateSpecializationType::PrintTemplateArgumentList( + TemplateArgs->data(), + TemplateArgs->size(), + Policy); + +} + bool FunctionDecl::isVariadic() const { if (const FunctionProtoType *FT = getType()->getAs()) return FT->isVariadic(); @@ -1913,7 +1895,7 @@ SourceLocation FunctionDecl::getPointOfInstantiation() const { } bool FunctionDecl::isOutOfLine() const { - if (getLexicalDeclContext() != getDeclContext()) + if (Decl::isOutOfLine()) return true; // If this function was instantiated from a member function of a @@ -1978,17 +1960,6 @@ unsigned FieldDecl::getFieldIndex() const { // TagDecl Implementation //===----------------------------------------------------------------------===// -SourceLocation TagDecl::getInnerLocStart() const { - if (const ClassTemplateSpecializationDecl *Spec - = dyn_cast(this)) { - SourceLocation Start = Spec->getTemplateKeywordLoc(); - if (Start.isValid()) - return Start; - } - - return getTagKeywordLoc(); -} - SourceLocation TagDecl::getOuterLocStart() const { return getTemplateOrInnerLocStart(this); } @@ -2140,6 +2111,13 @@ RecordDecl::field_iterator RecordDecl::field_begin() const { return field_iterator(decl_iterator(FirstDecl)); } +/// completeDefinition - Notes that the definition of this type is now +/// complete. +void RecordDecl::completeDefinition() { + assert(!isDefinition() && "Cannot redefine record!"); + TagDecl::completeDefinition(); +} + void RecordDecl::LoadFieldsFromExternalStorage() const { ExternalASTSource *Source = getASTContext().getExternalSource(); assert(hasExternalLexicalStorage() && Source && "No external storage?"); @@ -2165,13 +2143,6 @@ void RecordDecl::LoadFieldsFromExternalStorage() const { llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls); } -void RecordDecl::completeDefinition() { - assert(!isDefinition() && "Cannot redefine record!"); - TagDecl::completeDefinition(); - if (CXXRecordDecl *CXXRecord = dyn_cast(this)) - CXXRecord->completeDefinitionImpl(0); -} - //===----------------------------------------------------------------------===// // BlockDecl Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index be4d82a054ee..be379d522dd4 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -42,30 +42,6 @@ using namespace clang; static bool StatSwitch = false; -namespace { - template - inline SourceRange getSourceRangeImpl(const Decl *D, - SourceRange (Class::*)() const) { - return static_cast(D)->getSourceRange(); - } - - inline SourceRange getSourceRangeImpl(const Decl *D, - SourceRange (Decl::*)() const) { - return D->getLocation(); - } -} - -SourceRange Decl::getSourceRange() const { - switch (getKind()) { -#define ABSTRACT_DECL(Type) -#define DECL(Type, Base) \ - case Type: return getSourceRangeImpl(this, &Type##Decl::getSourceRange); -#include "clang/AST/DeclNodes.inc" - } - - return getLocation(); -} - const char *Decl::getDeclKindName() const { switch (DeclKind) { default: assert(0 && "Declaration not in DeclNodes.inc!"); @@ -167,101 +143,6 @@ bool Decl::isDefinedOutsideFunctionOrMethod() const { return true; } -namespace { - template - inline Result *getCanonicalDeclImpl(Decl *D, Result *(Class::*)()) { - return static_cast(D)->getCanonicalDecl(); - } - - inline Decl *getCanonicalDeclImpl(Decl *D, Decl *(Decl::*)()) { - // No specific implementation. - return D; - } -} - -Decl *Decl::getCanonicalDecl() { - switch (getKind()) { -#define ABSTRACT_DECL(Type) -#define DECL(Type, Base) \ - case Type: \ - return getCanonicalDeclImpl(this, &Type##Decl::getCanonicalDecl); -#include "clang/AST/DeclNodes.inc" - } - - return this; -} - -Decl *Decl::getNextRedeclaration() { - switch (getKind()) { - case Var: - return static_cast(this)->getNextRedeclaration(); - - case Function: - case CXXMethod: - case CXXConstructor: - case CXXDestructor: - case CXXConversion: - return static_cast(this)->getNextRedeclaration(); - - case Typedef: - return static_cast(this)->getNextRedeclaration(); - - case Enum: - case Record: - case CXXRecord: - case ClassTemplateSpecialization: - case ClassTemplatePartialSpecialization: - return static_cast(this)->getNextRedeclaration(); - - case ObjCMethod: - return static_cast(this)->getNextRedeclaration(); - - case FunctionTemplate: - case ClassTemplate: - return static_cast(this) - ->getNextRedeclaration(); - - case Namespace: - case UsingDirective: - case NamespaceAlias: - case Label: - case UnresolvedUsingTypename: - case TemplateTypeParm: - case EnumConstant: - case UnresolvedUsingValue: - case IndirectField: - case Field: - case ObjCIvar: - case ObjCAtDefsField: - case ImplicitParam: - case ParmVar: - case NonTypeTemplateParm: - case TemplateTemplateParm: - case Using: - case UsingShadow: - case ObjCCategory: - case ObjCProtocol: - case ObjCInterface: - case ObjCCategoryImpl: - case ObjCImplementation: - case ObjCProperty: - case ObjCCompatibleAlias: - case LinkageSpec: - case ObjCPropertyImpl: - case ObjCForwardProtocol: - case ObjCClass: - case FileScopeAsm: - case AccessSpec: - case Friend: - case FriendTemplate: - case StaticAssert: - case Block: - case TranslationUnit: - return this; - } - - return this; -} //===----------------------------------------------------------------------===// // PrettyStackTraceDecl Implementation @@ -288,14 +169,8 @@ void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const { // Decl Implementation //===----------------------------------------------------------------------===// -bool Decl::isOutOfLine() const { - if (const VarDecl *VD = dyn_cast(this)) - return VD->isOutOfLine(); - if (const FunctionDecl *FD = dyn_cast(this)) - return FD->isOutOfLine(); - - return getLexicalDeclContext() != getDeclContext(); -} +// Out-of-line virtual method providing a home for Decl. +Decl::~Decl() { } void Decl::setDeclContext(DeclContext *DC) { if (isOutOfSemaDC()) @@ -546,24 +421,6 @@ DeclContext *Decl::castToDeclContext(const Decl *D) { } } -Stmt *Decl::getBody() const { - if (const FunctionDecl *FD = dyn_cast(this)) - return FD->getBody(); - if (const ObjCMethodDecl *MD = dyn_cast(this)) - return MD->getBody(); - if (const BlockDecl *BD = dyn_cast(this)) - return BD->getBody(); - - return 0; -} - -bool Decl::hasBody() const { - if (const FunctionDecl *FD = dyn_cast(this)) - return FD->hasBody(); - - return getBody() != 0; -} - SourceLocation Decl::getBodyRBrace() const { // Special handling of FunctionDecl to avoid de-serializing the body from PCH. // FunctionDecl stores EndRangeLoc for this purpose. diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 1de3cc989ed0..fba73f59d563 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -819,8 +819,13 @@ CXXDestructorDecl *CXXRecordDecl::getDestructor() const { return Dtor; } -void -CXXRecordDecl::completeDefinitionImpl(CXXFinalOverriderMap *FinalOverriders) { +void CXXRecordDecl::completeDefinition() { + completeDefinition(0); +} + +void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) { + RecordDecl::completeDefinition(); + // If the class may be abstract (but hasn't been marked as such), check for // any pure final overriders. if (mayBeAbstract()) { @@ -860,12 +865,6 @@ CXXRecordDecl::completeDefinitionImpl(CXXFinalOverriderMap *FinalOverriders) { data().Conversions.setAccess(I, (*I)->getAccess()); } -void -CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) { - TagDecl::completeDefinition(); - completeDefinitionImpl(FinalOverriders); -} - bool CXXRecordDecl::mayBeAbstract() const { if (data().Abstract || isInvalidDecl() || !data().Polymorphic || isDependentContext()) diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 980a373778fe..a73deeab3a61 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -112,14 +112,6 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() { } -RedeclarableTemplateDecl::CommonBase * -RedeclarableTemplateDecl::newCommon(ASTContext &C) { - if (FunctionTemplateDecl *FunTmpl = dyn_cast(this)) - return FunTmpl->newCommon(C); - - return cast(this)->newCommon(C); -} - RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() { RedeclarableTemplateDecl *Tmpl = this; while (Tmpl->getPreviousDeclaration()) @@ -455,6 +447,13 @@ NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, ExpandedTInfos); } +SourceLocation NonTypeTemplateParmDecl::getInnerLocStart() const { + SourceLocation Start = getTypeSpecStartLoc(); + if (Start.isInvalid()) + Start = getLocation(); + return Start; +} + SourceRange NonTypeTemplateParmDecl::getSourceRange() const { return SourceRange(getOuterLocStart(), getLocation()); } @@ -544,6 +543,19 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, EmptyShell Empty) { new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization); } +void +ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const { + NamedDecl::getNameForDiagnostic(S, Policy, Qualified); + + const TemplateArgumentList &TemplateArgs = getTemplateArgs(); + S += TemplateSpecializationType::PrintTemplateArgumentList( + TemplateArgs.data(), + TemplateArgs.size(), + Policy); +} + ClassTemplateDecl * ClassTemplateSpecializationDecl::getSpecializedTemplate() const { if (SpecializedPartialSpecialization *PartialSpec