diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
commit | 9f4dbff6669c8037f3b036bcf580d14f1a4f12a5 (patch) | |
tree | 47df2c12b57214af6c31e47404b005675b8b7ffc /include/clang/AST/Decl.h | |
parent | f73d5f23a889b93d89ddef61ac0995df40286bb8 (diff) |
Notes
Diffstat (limited to 'include/clang/AST/Decl.h')
-rw-r--r-- | include/clang/AST/Decl.h | 474 |
1 files changed, 286 insertions, 188 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 244a7b8d400c2..ce8b8b7dbcd6f 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -21,6 +21,7 @@ #include "clang/AST/Redeclarable.h" #include "clang/AST/Type.h" #include "clang/Basic/Linkage.h" +#include "clang/Basic/OperatorKinds.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" @@ -51,8 +52,7 @@ class VarTemplateDecl; /// A client can read the relevant info using TypeLoc wrappers, e.g: /// @code /// TypeLoc TL = TypeSourceInfo->getTypeLoc(); -/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL)) -/// PL->getStarLoc().print(OS, SrcMgr); +/// TL.getStartLoc().print(OS, SrcMgr); /// @endcode /// class TypeSourceInfo { @@ -79,9 +79,9 @@ class TranslationUnitDecl : public Decl, public DeclContext { NamespaceDecl *AnonymousNamespace; explicit TranslationUnitDecl(ASTContext &ctx) - : Decl(TranslationUnit, 0, SourceLocation()), + : Decl(TranslationUnit, nullptr, SourceLocation()), DeclContext(TranslationUnit), - Ctx(ctx), AnonymousNamespace(0) {} + Ctx(ctx), AnonymousNamespace(nullptr) {} public: ASTContext &getASTContext() const { return Ctx; } @@ -110,7 +110,7 @@ class NamedDecl : public Decl { DeclarationName Name; private: - NamedDecl *getUnderlyingDeclImpl(); + NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY; protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) @@ -161,9 +161,8 @@ public: void printQualifiedName(raw_ostream &OS) const; void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const; - // FIXME: Remove string versions. + // FIXME: Remove string version. std::string getQualifiedNameAsString() const; - std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const; /// getNameForDiagnostic - Appends a human-readable name for this /// declaration into the given stream. @@ -204,9 +203,8 @@ public: // C++0x [class.mem]p1: // The enumerators of an unscoped enumeration defined in // the class are members of the class. - // FIXME: support C++0x scoped enumerations. if (isa<EnumDecl>(DC)) - DC = DC->getParent(); + DC = DC->getRedeclContext(); return DC->isRecord(); } @@ -259,6 +257,16 @@ public: /// checking. Should always return true. bool isLinkageValid() const; + /// \brief True if something has required us to compute the linkage + /// of this declaration. + /// + /// Language features which can retroactively change linkage (like a + /// typedef name for linkage purposes) may need to consider this, + /// but hopefully only in transitory ways during parsing. + bool hasLinkageBeenComputed() const { + return hasCachedLinkage(); + } + /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for /// the underlying named decl. NamedDecl *getUnderlyingDecl() { @@ -295,7 +303,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) { /// location of the statement. For GNU local labels (__label__), the decl /// location is where the __label__ is. class LabelDecl : public NamedDecl { - virtual void anchor(); + void anchor() override; LabelStmt *TheStmt; /// LocStart - For normal labels, this is the same as the main declaration /// label, i.e., the location of the identifier; for GNU local labels, @@ -320,7 +328,7 @@ public: bool isGnuLocal() const { return LocStart != getLocation(); } void setLocStart(SourceLocation L) { LocStart = L; } - SourceRange getSourceRange() const LLVM_READONLY { + SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(LocStart, getLocation()); } @@ -333,8 +341,6 @@ public: class NamespaceDecl : public NamedDecl, public DeclContext, public Redeclarable<NamespaceDecl> { - virtual void anchor(); - /// LocStart - The starting location of the source range, pointing /// to either the namespace or the inline keyword. SourceLocation LocStart; @@ -347,21 +353,15 @@ class NamespaceDecl : public NamedDecl, public DeclContext, /// boolean value indicating whether this is an inline namespace. llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline; - NamespaceDecl(DeclContext *DC, bool Inline, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - NamespaceDecl *PrevDecl); - + NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, NamespaceDecl *PrevDecl); + typedef Redeclarable<NamespaceDecl> redeclarable_base; - virtual NamespaceDecl *getNextRedeclaration() { - return RedeclLink.getNext(); - } - virtual NamespaceDecl *getPreviousDeclImpl() { - return getPreviousDecl(); - } - virtual NamespaceDecl *getMostRecentDeclImpl() { - return getMostRecentDecl(); - } - + NamespaceDecl *getNextRedeclarationImpl() override; + NamespaceDecl *getPreviousDeclImpl() override; + NamespaceDecl *getMostRecentDeclImpl() override; + public: static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, @@ -370,9 +370,11 @@ public: static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); + typedef redeclarable_base::redecl_range redecl_range; typedef redeclarable_base::redecl_iterator redecl_iterator; using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; + using redeclarable_base::redecls; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; @@ -432,14 +434,14 @@ public: } /// Retrieves the canonical declaration of this namespace. - NamespaceDecl *getCanonicalDecl() { + NamespaceDecl *getCanonicalDecl() override { return getOriginalNamespace(); } const NamespaceDecl *getCanonicalDecl() const { return getOriginalNamespace(); } - - virtual SourceRange getSourceRange() const LLVM_READONLY { + + SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(LocStart, RBraceLoc); } @@ -466,7 +468,7 @@ public: /// an lvalue) a function (in which case it is a function designator) or /// an enum constant. class ValueDecl : public NamedDecl { - virtual void anchor(); + void anchor() override; QualType DeclType; protected: @@ -505,7 +507,8 @@ struct QualifierInfo { TemplateParameterList** TemplParamLists; /// Default constructor. - QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {} + QualifierInfo() + : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {} /// setTemplateParameterListsInfo - Sets info about "outer" template /// parameter lists. @@ -567,7 +570,7 @@ public: /// range taking into account any outer template declarations. SourceLocation getOuterLocStart() const; - virtual SourceRange getSourceRange() const LLVM_READONLY; + SourceRange getSourceRange() const override LLVM_READONLY; SourceLocation getLocStart() const LLVM_READONLY { return getOuterLocStart(); } @@ -576,7 +579,7 @@ public: /// declaration, if it was present in the source. NestedNameSpecifier *getQualifier() const { return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier() - : 0; + : nullptr; } /// \brief Retrieve the nested-name-specifier (with source-location @@ -764,23 +767,27 @@ protected: ParmVarDeclBitfields ParmVarDeclBits; }; - VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass SC); typedef Redeclarable<VarDecl> redeclarable_base; - virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); } - virtual VarDecl *getPreviousDeclImpl() { + VarDecl *getNextRedeclarationImpl() override { + return getNextRedeclaration(); + } + VarDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } - virtual VarDecl *getMostRecentDeclImpl() { + VarDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } public: + typedef redeclarable_base::redecl_range redecl_range; typedef redeclarable_base::redecl_iterator redecl_iterator; using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; + using redeclarable_base::redecls; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; @@ -791,8 +798,8 @@ public: StorageClass S); static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - virtual SourceRange getSourceRange() const LLVM_READONLY; + + SourceRange getSourceRange() const override LLVM_READONLY; /// \brief Returns the storage class as written in the source. For the /// computed linkage of symbol, see getLinkage. @@ -803,22 +810,12 @@ public: void setTSCSpec(ThreadStorageClassSpecifier TSC) { VarDeclBits.TSCSpec = TSC; + assert(VarDeclBits.TSCSpec == TSC && "truncation"); } ThreadStorageClassSpecifier getTSCSpec() const { return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec); } - TLSKind getTLSKind() const { - switch (VarDeclBits.TSCSpec) { - case TSCS_unspecified: - return TLS_None; - case TSCS___thread: // Fall through. - case TSCS__Thread_local: - return TLS_Static; - case TSCS_thread_local: - return TLS_Dynamic; - } - llvm_unreachable("Unknown thread storage class specifier!"); - } + TLSKind getTLSKind() const; /// hasLocalStorage - Returns true if a variable with function scope /// is a non-static local variable. @@ -827,6 +824,10 @@ public: // Second check is for C++11 [dcl.stc]p4. return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified; + // Global Named Register (GNU extension) + if (getStorageClass() == SC_Register && !isLocalVarDecl()) + return false; + // Return true for: Auto, Register. // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal. @@ -913,7 +914,7 @@ public: return getKind() != Decl::ParmVar && getDeclContext()->isRecord(); } - virtual VarDecl *getCanonicalDecl(); + VarDecl *getCanonicalDecl() override; const VarDecl *getCanonicalDecl() const { return const_cast<VarDecl*>(this)->getCanonicalDecl(); } @@ -960,7 +961,7 @@ public: /// \brief Determine whether this is or was instantiated from an out-of-line /// definition of a static data member. - virtual bool isOutOfLine() const; + bool isOutOfLine() const override; /// \brief If this is a static data member, find its out-of-line definition. VarDecl *getOutOfLineDefinition(); @@ -996,7 +997,7 @@ public: } const Expr *getInit() const { if (Init.isNull()) - return 0; + return nullptr; const Stmt *S = Init.dyn_cast<Stmt *>(); if (!S) { @@ -1007,7 +1008,7 @@ public: } Expr *getInit() { if (Init.isNull()) - return 0; + return nullptr; Stmt *S = Init.dyn_cast<Stmt *>(); if (!S) { @@ -1058,7 +1059,7 @@ public: if (Eval->WasEvaluated) return &Eval->Evaluated; - return 0; + return nullptr; } /// \brief Determines whether it is already known whether the @@ -1208,18 +1209,18 @@ public: }; class ImplicitParamDecl : public VarDecl { - virtual void anchor(); + void anchor() override; public: static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T); static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc, + + ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType Type) - : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type, - /*tinfo*/ 0, SC_None) { + : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type, + /*tinfo*/ nullptr, SC_None) { setImplicit(); } @@ -1235,11 +1236,10 @@ public: enum { MaxFunctionScopeIndex = 255 }; protected: - ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, - StorageClass S, Expr *DefArg) - : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) { + ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) + : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) { assert(ParmVarDeclBits.HasInheritedDefaultArg == false); assert(ParmVarDeclBits.IsKNRPromoted == false); assert(ParmVarDeclBits.IsObjCMethodParam == false); @@ -1254,8 +1254,8 @@ public: StorageClass S, Expr *DefArg); static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - virtual SourceRange getSourceRange() const LLVM_READONLY; + + SourceRange getSourceRange() const override LLVM_READONLY; void setObjCMethodScopeInfo(unsigned parameterIndex) { ParmVarDeclBits.IsObjCMethodParam = true; @@ -1362,9 +1362,7 @@ public: /// real default argument via setDefaultArg when the class /// definition enclosing the function declaration that owns this /// default argument is completed. - void setUnparsedDefaultArg() { - Init = (UnparsedDefaultArgument *)0; - } + void setUnparsedDefaultArg() { Init = (UnparsedDefaultArgument *)nullptr; } bool hasInheritedDefaultArg() const { return ParmVarDeclBits.HasInheritedDefaultArg; @@ -1538,7 +1536,7 @@ private: void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo); protected: - FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, @@ -1546,7 +1544,8 @@ protected: : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, StartLoc), DeclContext(DK), - ParamInfo(0), Body(), + redeclarable_base(C), + ParamInfo(nullptr), Body(), SClass(S), IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), @@ -1559,18 +1558,22 @@ protected: DNLoc(NameInfo.getInfo()) {} typedef Redeclarable<FunctionDecl> redeclarable_base; - virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); } - virtual FunctionDecl *getPreviousDeclImpl() { + FunctionDecl *getNextRedeclarationImpl() override { + return getNextRedeclaration(); + } + FunctionDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } - virtual FunctionDecl *getMostRecentDeclImpl() { + FunctionDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } public: + typedef redeclarable_base::redecl_range redecl_range; typedef redeclarable_base::redecl_iterator redecl_iterator; using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; + using redeclarable_base::redecls; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; @@ -1605,13 +1608,12 @@ public: return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } - virtual void getNameForDiagnostic(raw_ostream &OS, - const PrintingPolicy &Policy, - bool Qualified) const; + void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, + bool Qualified) const override; void setRangeEnd(SourceLocation E) { EndRangeLoc = E; } - virtual SourceRange getSourceRange() const LLVM_READONLY; + SourceRange getSourceRange() const override LLVM_READONLY; /// \brief Returns true if the function has a body (definition). The /// function body might be in any of the (re-)declarations of this @@ -1620,7 +1622,7 @@ public: /// containing the body (if there is one). bool hasBody(const FunctionDecl *&Definition) const; - virtual bool hasBody() const { + bool hasBody() const override { const FunctionDecl* Definition; return hasBody(Definition); } @@ -1648,7 +1650,7 @@ public: /// unnecessary AST de-serialization of the body. Stmt *getBody(const FunctionDecl *&Definition) const; - virtual Stmt *getBody() const { + Stmt *getBody() const override { const FunctionDecl* Definition; return getBody(Definition); } @@ -1828,7 +1830,7 @@ public: void setPreviousDeclaration(FunctionDecl * PrevDecl); virtual const FunctionDecl *getCanonicalDecl() const; - virtual FunctionDecl *getCanonicalDecl(); + FunctionDecl *getCanonicalDecl() override; unsigned getBuiltinID() const; @@ -1836,12 +1838,24 @@ public: unsigned param_size() const { return getNumParams(); } typedef ParmVarDecl **param_iterator; typedef ParmVarDecl * const *param_const_iterator; + typedef llvm::iterator_range<param_iterator> param_range; + typedef llvm::iterator_range<param_const_iterator> param_const_range; - param_iterator param_begin() { return ParamInfo; } - param_iterator param_end() { return ParamInfo+param_size(); } + param_iterator param_begin() { return param_iterator(ParamInfo); } + param_iterator param_end() { + return param_iterator(ParamInfo + param_size()); + } + param_range params() { return param_range(param_begin(), param_end()); } - param_const_iterator param_begin() const { return ParamInfo; } - param_const_iterator param_end() const { return ParamInfo+param_size(); } + param_const_iterator param_begin() const { + return param_const_iterator(ParamInfo); + } + param_const_iterator param_end() const { + return param_const_iterator(ParamInfo + param_size()); + } + param_const_range params() const { + return param_const_range(param_begin(), param_end()); + } /// getNumParams - Return the number of parameters this function must have /// based on its FunctionType. This is the length of the ParamInfo array @@ -1860,6 +1874,12 @@ public: setParams(getASTContext(), NewParamInfo); } + // ArrayRef iterface to parameters. + // FIXME: Should one day replace iterator interface. + ArrayRef<ParmVarDecl*> parameters() const { + return llvm::makeArrayRef(ParamInfo, getNumParams()); + } + const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const { return DeclsInPrototypeScope; } @@ -1871,10 +1891,15 @@ public: /// arguments (in C++). unsigned getMinRequiredArguments() const; - QualType getResultType() const { - return getType()->getAs<FunctionType>()->getResultType(); + QualType getReturnType() const { + return getType()->getAs<FunctionType>()->getReturnType(); } + /// \brief Attempt to compute an informative source range covering the + /// function return type. This may omit qualifiers and other information with + /// limited representation in the AST. + SourceRange getReturnTypeSourceRange() const; + /// \brief Determine the type of an expression that calls this function. QualType getCallResultType() const { return getType()->getAs<FunctionType>()->getCallResultType(getASTContext()); @@ -1906,6 +1931,8 @@ public: bool isInlineDefinitionExternallyVisible() const; + bool isMSExternInline() const; + bool doesDeclarationForceExternallyVisibleDefinition() const; /// isOverloadedOperator - Whether this function declaration @@ -1981,7 +2008,7 @@ public: /// \brief Determine whether this function is a function template /// specialization. bool isFunctionTemplateSpecialization() const { - return getPrimaryTemplate() != 0; + return getPrimaryTemplate() != nullptr; } /// \brief Retrieve the class scope template pattern that this function @@ -2054,11 +2081,11 @@ public: /// \param PointOfInstantiation point at which the function template /// specialization was first instantiated. void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, - const TemplateArgumentList *TemplateArgs, - void *InsertPos, - TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, - const TemplateArgumentListInfo *TemplateArgsAsWritten = 0, - SourceLocation PointOfInstantiation = SourceLocation()) { + const TemplateArgumentList *TemplateArgs, + void *InsertPos, + TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, + const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr, + SourceLocation PointOfInstantiation = SourceLocation()) { setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs, InsertPos, TSK, TemplateArgsAsWritten, PointOfInstantiation); @@ -2095,7 +2122,7 @@ public: /// \brief Determine whether this is or was instantiated from an out-of-line /// definition of a member function. - virtual bool isOutOfLine() const; + bool isOutOfLine() const override; /// \brief Identify a memory copying or setting function. /// If the given function is a memory copy or setting function, returns @@ -2181,7 +2208,7 @@ public: bool isAnonymousStructOrUnion() const; Expr *getBitWidth() const { - return isBitField() ? InitializerOrBitWidth.getPointer() : 0; + return isBitField() ? InitializerOrBitWidth.getPointer() : nullptr; } unsigned getBitWidthValue(const ASTContext &Ctx) const; @@ -2192,7 +2219,7 @@ public: // Note: used by some clients (i.e., do not remove it). void removeBitWidth() { assert(isBitField() && "no bitfield width to remove"); - InitializerOrBitWidth.setPointer(0); + InitializerOrBitWidth.setPointer(nullptr); } /// getInClassInitStyle - Get the kind of (C++11) in-class initializer which @@ -2211,7 +2238,8 @@ public: /// in-class initializer, but this returns null, then we have not parsed and /// attached it yet. Expr *getInClassInitializer() const { - return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0; + return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() + : nullptr; } /// setInClassInitializer - Set the C++11 in-class initializer for this /// member. @@ -2220,7 +2248,7 @@ public: /// member. void removeInClassInitializer() { assert(hasInClassInitializer() && "no initializer to remove"); - InitializerOrBitWidth.setPointer(0); + InitializerOrBitWidth.setPointer(nullptr); InitializerOrBitWidth.setInt(ICIS_NoInit); } @@ -2234,10 +2262,10 @@ public: return cast<RecordDecl>(getDeclContext()); } - SourceRange getSourceRange() const LLVM_READONLY; + SourceRange getSourceRange() const override LLVM_READONLY; /// Retrieves the canonical declaration of this field. - FieldDecl *getCanonicalDecl() { return getFirstDecl(); } + FieldDecl *getCanonicalDecl() override { return getFirstDecl(); } const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); } // Implement isa/cast/dyncast/etc. @@ -2276,10 +2304,10 @@ public: void setInitExpr(Expr *E) { Init = (Stmt*) E; } void setInitVal(const llvm::APSInt &V) { Val = V; } - SourceRange getSourceRange() const LLVM_READONLY; + SourceRange getSourceRange() const override LLVM_READONLY; /// Retrieves the canonical declaration of this enumerator. - EnumConstantDecl *getCanonicalDecl() { return getFirstDecl(); } + EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); } const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); } // Implement isa/cast/dyncast/etc. @@ -2293,7 +2321,7 @@ public: /// field injected from an anonymous union/struct into the parent scope. /// IndirectFieldDecl are always implicit. class IndirectFieldDecl : public ValueDecl { - virtual void anchor(); + void anchor() override; NamedDecl **Chaining; unsigned ChainingSize; @@ -2310,8 +2338,13 @@ public: static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); typedef NamedDecl * const *chain_iterator; - chain_iterator chain_begin() const { return Chaining; } - chain_iterator chain_end() const { return Chaining+ChainingSize; } + typedef llvm::iterator_range<chain_iterator> chain_range; + + chain_range chain() const { return chain_range(chain_begin(), chain_end()); } + chain_iterator chain_begin() const { return chain_iterator(Chaining); } + chain_iterator chain_end() const { + return chain_iterator(Chaining + ChainingSize); + } unsigned getChainingSize() const { return ChainingSize; } @@ -2334,7 +2367,7 @@ public: /// TypeDecl - Represents a declaration of a type. /// class TypeDecl : public NamedDecl { - virtual void anchor(); + void anchor() override; /// TypeForDecl - This indicates the Type object that represents /// this TypeDecl. It is a cache maintained by /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and @@ -2343,16 +2376,11 @@ class TypeDecl : public NamedDecl { /// LocStart - The start of the source range for this declaration. SourceLocation LocStart; friend class ASTContext; - friend class DeclContext; - friend class TagDecl; - friend class TemplateTypeParmDecl; - friend class TagType; - friend class ASTReader; protected: TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, SourceLocation StartL = SourceLocation()) - : NamedDecl(DK, DC, L, Id), TypeForDecl(0), LocStart(StartL) {} + : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {} public: // Low-level accessor. If you just want the type defined by this node, @@ -2364,7 +2392,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return LocStart; } void setLocStart(SourceLocation L) { LocStart = L; } - virtual SourceRange getSourceRange() const LLVM_READONLY { + SourceRange getSourceRange() const override LLVM_READONLY { if (LocStart.isValid()) return SourceRange(LocStart, getLocation()); else @@ -2379,31 +2407,34 @@ public: /// Base class for declarations which introduce a typedef-name. class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { - virtual void anchor(); + void anchor() override; typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo; llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo; protected: - TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - TypeSourceInfo *TInfo) - : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {} + TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C), + MaybeModedTInfo(TInfo) {} typedef Redeclarable<TypedefNameDecl> redeclarable_base; - virtual TypedefNameDecl *getNextRedeclaration() { - return RedeclLink.getNext(); + TypedefNameDecl *getNextRedeclarationImpl() override { + return getNextRedeclaration(); } - virtual TypedefNameDecl *getPreviousDeclImpl() { + TypedefNameDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } - virtual TypedefNameDecl *getMostRecentDeclImpl() { + TypedefNameDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } public: + typedef redeclarable_base::redecl_range redecl_range; typedef redeclarable_base::redecl_iterator redecl_iterator; using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; + using redeclarable_base::redecls; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; @@ -2428,7 +2459,7 @@ public: } /// Retrieves the canonical declaration of this typedef-name. - TypedefNameDecl *getCanonicalDecl() { return getFirstDecl(); } + TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); } const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); } // Implement isa/cast/dyncast/etc. @@ -2441,17 +2472,17 @@ public: /// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef' /// type specifier. class TypedefDecl : public TypedefNameDecl { - TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {} + TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {} public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo); static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - SourceRange getSourceRange() const LLVM_READONLY; + + SourceRange getSourceRange() const override LLVM_READONLY; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2461,9 +2492,9 @@ public: /// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x /// alias-declaration. class TypeAliasDecl : public TypedefNameDecl { - TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {} + TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {} public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, @@ -2471,7 +2502,7 @@ public: IdentifierInfo *Id, TypeSourceInfo *TInfo); static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); - SourceRange getSourceRange() const LLVM_READONLY; + SourceRange getSourceRange() const override LLVM_READONLY; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2559,24 +2590,27 @@ private: } protected: - TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL) - : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK), - IsCompleteDefinition(false), IsBeingDefined(false), + TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl, + SourceLocation StartL) + : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C), + TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false), IsEmbeddedInDeclarator(false), IsFreeStanding(false), IsCompleteDefinitionRequired(false), - NamedDeclOrQualifier((NamedDecl *)0) { + NamedDeclOrQualifier((NamedDecl *)nullptr) { assert((DK != Enum || TK == TTK_Enum) && "EnumDecl not matched with TTK_Enum"); setPreviousDecl(PrevDecl); } typedef Redeclarable<TagDecl> redeclarable_base; - virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); } - virtual TagDecl *getPreviousDeclImpl() { + TagDecl *getNextRedeclarationImpl() override { + return getNextRedeclaration(); + } + TagDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } - virtual TagDecl *getMostRecentDeclImpl() { + TagDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } @@ -2586,9 +2620,11 @@ protected: void completeDefinition(); public: + typedef redeclarable_base::redecl_range redecl_range; typedef redeclarable_base::redecl_iterator redecl_iterator; using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; + using redeclarable_base::redecls; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; @@ -2603,10 +2639,10 @@ public: /// getOuterLocStart - Return SourceLocation representing start of source /// range taking into account any outer template declarations. SourceLocation getOuterLocStart() const; - virtual SourceRange getSourceRange() const LLVM_READONLY; + SourceRange getSourceRange() const override LLVM_READONLY; - virtual TagDecl* getCanonicalDecl(); - const TagDecl* getCanonicalDecl() const { + TagDecl *getCanonicalDecl() override; + const TagDecl *getCanonicalDecl() const { return const_cast<TagDecl*>(this)->getCanonicalDecl(); } @@ -2673,8 +2709,7 @@ public: IsCompleteDefinitionRequired = V; } - // FIXME: Return StringRef; - const char *getKindName() const { + StringRef getKindName() const { return TypeWithKeyword::getTagTypeKindName(getTagKind()); } @@ -2714,12 +2749,12 @@ public: NamedDeclOrQualifier.get<NamedDecl *>()); } DeclaratorDecl *getDeclaratorForAnonDecl() const { - return hasExtInfo() ? 0 : dyn_cast_or_null<DeclaratorDecl>( + return hasExtInfo() ? nullptr : dyn_cast_or_null<DeclaratorDecl>( NamedDeclOrQualifier.get<NamedDecl *>()); } TypedefNameDecl *getTypedefNameForAnonDecl() const { - return hasExtInfo() ? 0 : dyn_cast_or_null<TypedefNameDecl>( + return hasExtInfo() ? nullptr : dyn_cast_or_null<TypedefNameDecl>( NamedDeclOrQualifier.get<NamedDecl *>()); } @@ -2731,7 +2766,7 @@ public: /// declaration, if it was present in the source. NestedNameSpecifier *getQualifier() const { return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier() - : 0; + : nullptr; } /// \brief Retrieve the nested-name-specifier (with source-location @@ -2773,7 +2808,7 @@ public: /// with a fixed underlying type, and in C we allow them to be forward-declared /// with no underlying type as an extension. class EnumDecl : public TagDecl { - virtual void anchor(); + void anchor() override; /// IntegerType - This represent the integer type that the enum corresponds /// to for code generation purposes. Note that the enumerator constants may /// have a different type than this does. @@ -2802,13 +2837,13 @@ class EnumDecl : public TagDecl { /// information. MemberSpecializationInfo *SpecializationInfo; - EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, EnumDecl *PrevDecl, + EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, bool Scoped, bool ScopedUsingClassTag, bool Fixed) - : TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc), - SpecializationInfo(0) { + : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc), + SpecializationInfo(nullptr) { assert(Scoped || !ScopedUsingClassTag); - IntegerType = (const Type*)0; + IntegerType = (const Type *)nullptr; NumNegativeBits = 0; NumPositiveBits = 0; IsScoped = Scoped; @@ -2819,7 +2854,7 @@ class EnumDecl : public TagDecl { void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, TemplateSpecializationKind TSK); public: - EnumDecl *getCanonicalDecl() { + EnumDecl *getCanonicalDecl() override { return cast<EnumDecl>(TagDecl::getCanonicalDecl()); } const EnumDecl *getCanonicalDecl() const { @@ -2865,6 +2900,12 @@ public: // enumerator_iterator - Iterates through the enumerators of this // enumeration. typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator; + typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>> + enumerator_range; + + enumerator_range enumerators() const { + return enumerator_range(enumerator_begin(), enumerator_end()); + } enumerator_iterator enumerator_begin() const { const EnumDecl *E = getDefinition(); @@ -2888,27 +2929,32 @@ public: void setPromotionType(QualType T) { PromotionType = T; } /// getIntegerType - Return the integer type this enum decl corresponds to. - /// This returns a null qualtype for an enum forward definition. + /// This returns a null QualType for an enum forward definition with no fixed + /// underlying type. QualType getIntegerType() const { if (!IntegerType) return QualType(); - if (const Type* T = IntegerType.dyn_cast<const Type*>()) + if (const Type *T = IntegerType.dyn_cast<const Type*>()) return QualType(T, 0); - return IntegerType.get<TypeSourceInfo*>()->getType(); + return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType(); } /// \brief Set the underlying integer type. void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); } /// \brief Set the underlying integer type source info. - void setIntegerTypeSourceInfo(TypeSourceInfo* TInfo) { IntegerType = TInfo; } + void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; } /// \brief Return the type source info for the underlying integer type, /// if no type source info exists, return 0. - TypeSourceInfo* getIntegerTypeSourceInfo() const { + TypeSourceInfo *getIntegerTypeSourceInfo() const { return IntegerType.dyn_cast<TypeSourceInfo*>(); } + /// \brief Retrieve the source range that covers the underlying type if + /// specified. + SourceRange getIntegerTypeRange() const LLVM_READONLY; + /// \brief Returns the width in bits required to store all the /// non-negative enumerators of this enum. unsigned getNumPositiveBits() const { @@ -3024,14 +3070,14 @@ class RecordDecl : public TagDecl { friend class DeclContext; protected: - RecordDecl(Kind DK, TagKind TK, DeclContext *DC, + RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl); public: static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, RecordDecl* PrevDecl = 0); + IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr); static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); RecordDecl *getPreviousDecl() { @@ -3106,7 +3152,9 @@ public: // the non-static data members of this class, ignoring any static // data members, functions, constructors, destructors, etc. typedef specific_decl_iterator<FieldDecl> field_iterator; + typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range; + field_range fields() const { return field_range(field_begin(), field_end()); } field_iterator field_begin() const; field_iterator field_end() const { @@ -3155,7 +3203,7 @@ public: SourceLocation getAsmLoc() const { return getLocation(); } SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { + SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getAsmLoc(), getRParenLoc()); } @@ -3206,7 +3254,7 @@ public: /// is not from outside the immediately enclosing function/block. bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; } - bool hasCopyExpr() const { return CopyExpr != 0; } + bool hasCopyExpr() const { return CopyExpr != nullptr; } Expr *getCopyExpr() const { return CopyExpr; } void setCopyExpr(Expr *e) { CopyExpr = e; } }; @@ -3237,9 +3285,9 @@ protected: : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false), CapturesCXXThis(false), BlockMissingReturnType(true), IsConversionFromLambda(false), - ParamInfo(0), NumParams(0), Body(0), - SignatureAsWritten(0), Captures(0), NumCaptures(0), - ManglingNumber(0), ManglingContextDecl(0) {} + ParamInfo(nullptr), NumParams(0), Body(nullptr), + SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0), + ManglingNumber(0), ManglingContextDecl(nullptr) {} public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); @@ -3251,7 +3299,7 @@ public: void setIsVariadic(bool value) { IsVariadic = value; } CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; } - Stmt *getBody() const { return (Stmt*) Body; } + Stmt *getBody() const override { return (Stmt*) Body; } void setBody(CompoundStmt *B) { Body = (Stmt*) B; } void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; } @@ -3261,13 +3309,31 @@ public: unsigned param_size() const { return getNumParams(); } typedef ParmVarDecl **param_iterator; typedef ParmVarDecl * const *param_const_iterator; + typedef llvm::iterator_range<param_iterator> param_range; + typedef llvm::iterator_range<param_const_iterator> param_const_range; + + // ArrayRef access to formal parameters. + // FIXME: Should eventual replace iterator access. + ArrayRef<ParmVarDecl*> parameters() const { + return llvm::makeArrayRef(ParamInfo, param_size()); + } bool param_empty() const { return NumParams == 0; } - param_iterator param_begin() { return ParamInfo; } - param_iterator param_end() { return ParamInfo+param_size(); } + param_range params() { return param_range(param_begin(), param_end()); } + param_iterator param_begin() { return param_iterator(ParamInfo); } + param_iterator param_end() { + return param_iterator(ParamInfo + param_size()); + } - param_const_iterator param_begin() const { return ParamInfo; } - param_const_iterator param_end() const { return ParamInfo+param_size(); } + param_const_range params() const { + return param_const_range(param_begin(), param_end()); + } + param_const_iterator param_begin() const { + return param_const_iterator(ParamInfo); + } + param_const_iterator param_end() const { + return param_const_iterator(ParamInfo + param_size()); + } unsigned getNumParams() const { return NumParams; } const ParmVarDecl *getParamDecl(unsigned i) const { @@ -3290,6 +3356,16 @@ public: typedef const Capture *capture_iterator; typedef const Capture *capture_const_iterator; + typedef llvm::iterator_range<capture_iterator> capture_range; + typedef llvm::iterator_range<capture_const_iterator> capture_const_range; + + capture_range captures() { + return capture_range(capture_begin(), capture_end()); + } + capture_const_range captures() const { + return capture_const_range(capture_begin(), capture_end()); + } + capture_iterator capture_begin() { return Captures; } capture_iterator capture_end() { return Captures + NumCaptures; } capture_const_iterator capture_begin() const { return Captures; } @@ -3321,7 +3397,7 @@ public: ManglingContextDecl = Ctx; } - virtual SourceRange getSourceRange() const LLVM_READONLY; + SourceRange getSourceRange() const override LLVM_READONLY; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -3340,12 +3416,14 @@ class CapturedDecl : public Decl, public DeclContext { private: /// \brief The number of parameters to the outlined function. unsigned NumParams; + /// \brief The position of context parameter in list of parameters. + unsigned ContextParam; /// \brief The body of the outlined function. - Stmt *Body; + llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow; explicit CapturedDecl(DeclContext *DC, unsigned NumParams) : Decl(Captured, DC, SourceLocation()), DeclContext(Captured), - NumParams(NumParams), Body(0) { } + NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) { } ImplicitParamDecl **getParams() const { return reinterpret_cast<ImplicitParamDecl **>( @@ -3353,12 +3431,16 @@ private: } public: - static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); + static CapturedDecl *Create(ASTContext &C, DeclContext *DC, + unsigned NumParams); static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumParams); - Stmt *getBody() const { return Body; } - void setBody(Stmt *B) { Body = B; } + Stmt *getBody() const override { return BodyAndNothrow.getPointer(); } + void setBody(Stmt *B) { BodyAndNothrow.setPointer(B); } + + bool isNothrow() const { return BodyAndNothrow.getInt(); } + void setNothrow(bool Nothrow = true) { BodyAndNothrow.setInt(Nothrow); } unsigned getNumParams() const { return NumParams; } @@ -3372,15 +3454,28 @@ public: } /// \brief Retrieve the parameter containing captured variables. - ImplicitParamDecl *getContextParam() const { return getParam(0); } - void setContextParam(ImplicitParamDecl *P) { setParam(0, P); } + ImplicitParamDecl *getContextParam() const { + assert(ContextParam < NumParams); + return getParam(ContextParam); + } + void setContextParam(unsigned i, ImplicitParamDecl *P) { + assert(i < NumParams); + ContextParam = i; + setParam(i, P); + } + unsigned getContextParamPosition() const { return ContextParam; } typedef ImplicitParamDecl **param_iterator; + typedef llvm::iterator_range<param_iterator> param_range; + /// \brief Retrieve an iterator pointing to the first parameter decl. param_iterator param_begin() const { return getParams(); } /// \brief Retrieve an iterator one past the last parameter decl. param_iterator param_end() const { return getParams() + NumParams; } + /// \brief Retrieve an iterator range for the parameter declarations. + param_range params() const { return param_range(param_begin(), param_end()); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Captured; } @@ -3455,9 +3550,9 @@ public: /// This will return an empty array if the locations of the individual /// identifiers aren't available. ArrayRef<SourceLocation> getIdentifierLocs() const; - - virtual SourceRange getSourceRange() const LLVM_READONLY; - + + SourceRange getSourceRange() const override LLVM_READONLY; + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Import; } }; @@ -3496,6 +3591,8 @@ template<typename decl_type> void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { // Note: This routine is implemented here because we need both NamedDecl // and Redeclarable to be defined. + assert(RedeclLink.NextIsLatest() && + "setPreviousDecl on a decl already in a redeclaration chain"); decl_type *First; @@ -3505,7 +3602,7 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. First = PrevDecl->getFirstDecl(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); - decl_type *MostRecent = First->RedeclLink.getNext(); + decl_type *MostRecent = First->getNextRedeclaration(); RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent)); // If the declaration was previously visible, a redeclaration of it remains @@ -3519,7 +3616,8 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { } // First one will point to this one as latest. - First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this)); + First->RedeclLink.setLatest(static_cast<decl_type*>(this)); + assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) || cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid()); } |