diff options
author | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | c72c57c9e9b69944e3e009cd5e209634839581d3 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /include/clang/AST/Decl.h | |
parent | 5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff) | |
download | FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz |
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'include/clang/AST/Decl.h')
-rw-r--r-- | include/clang/AST/Decl.h | 327 |
1 files changed, 149 insertions, 178 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 087a585..7927279 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -16,33 +16,34 @@ #include "clang/AST/APValue.h" #include "clang/AST/DeclBase.h" -#include "clang/AST/Redeclarable.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/Redeclarable.h" +#include "clang/AST/Type.h" #include "clang/Basic/Linkage.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" namespace clang { +struct ASTTemplateArgumentListInfo; class CXXTemporary; +class CompoundStmt; +class DependentFunctionTemplateSpecializationInfo; class Expr; class FunctionTemplateDecl; +class FunctionTemplateSpecializationInfo; +class LabelStmt; +class MemberSpecializationInfo; +class Module; +class NestedNameSpecifier; class Stmt; -class CompoundStmt; class StringLiteral; -class NestedNameSpecifier; -class TemplateParameterList; class TemplateArgumentList; -struct ASTTemplateArgumentListInfo; -class MemberSpecializationInfo; -class FunctionTemplateSpecializationInfo; -class DependentFunctionTemplateSpecializationInfo; +class TemplateParameterList; class TypeLoc; class UnresolvedSetImpl; -class LabelStmt; -class Module; - + /// \brief A container of type source information. /// /// A client can read the relevant info using TypeLoc wrappers, e.g: @@ -108,6 +109,7 @@ class NamedDecl : public Decl { private: NamedDecl *getUnderlyingDeclImpl(); + void verifyLinkage() const; protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) @@ -149,32 +151,29 @@ public: /// \brief Set the name of this declaration. void setDeclName(DeclarationName N) { Name = N; } - /// getQualifiedNameAsString - Returns human-readable qualified name for + /// printQualifiedName - Returns human-readable qualified name for /// declaration, like A::B::i, for i being member of namespace A::B. /// If declaration is not member of context which can be named (record, - /// namespace), it will return same result as getNameAsString(). + /// namespace), it will return same result as printName(). /// Creating this name is expensive, so it should be called only when /// performance doesn't matter. + void printQualifiedName(raw_ostream &OS) const; + void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const; + + // FIXME: Remove string versions. std::string getQualifiedNameAsString() const; std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const; /// getNameForDiagnostic - Appends a human-readable name for this - /// declaration into the given string. + /// declaration into the given stream. /// /// This is the method invoked by Sema when displaying a NamedDecl /// in a diagnostic. It does not necessarily produce the same - /// result as getNameAsString(); for example, class template + /// result as printName(); for example, class template /// specializations are printed with their template arguments. - /// - /// TODO: use an API that doesn't require so many temporary strings - virtual void getNameForDiagnostic(std::string &S, + virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, - bool Qualified) const { - if (Qualified) - S += getQualifiedNameAsString(Policy); - else - S += getNameAsString(); - } + bool Qualified) const; /// declarationReplaces - Determine whether this declaration, if /// known to be well-formed within its context, will replace the @@ -212,117 +211,40 @@ public: /// a C++ class. bool isCXXInstanceMember() const; - class LinkageInfo { - uint8_t linkage_ : 2; - uint8_t visibility_ : 2; - uint8_t explicit_ : 1; - - void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } - public: - LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), - explicit_(false) {} - LinkageInfo(Linkage L, Visibility V, bool E) - : linkage_(L), visibility_(V), explicit_(E) { - assert(linkage() == L && visibility() == V && visibilityExplicit() == E && - "Enum truncated!"); - } - - static LinkageInfo external() { - return LinkageInfo(); - } - static LinkageInfo internal() { - return LinkageInfo(InternalLinkage, DefaultVisibility, false); - } - static LinkageInfo uniqueExternal() { - return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); - } - static LinkageInfo none() { - return LinkageInfo(NoLinkage, DefaultVisibility, false); - } - - Linkage linkage() const { return (Linkage)linkage_; } - Visibility visibility() const { return (Visibility)visibility_; } - bool visibilityExplicit() const { return explicit_; } - - void setLinkage(Linkage L) { linkage_ = L; } - void mergeLinkage(Linkage L) { - setLinkage(minLinkage(linkage(), L)); - } - void mergeLinkage(LinkageInfo Other) { - mergeLinkage(Other.linkage()); - } - - // Merge the visibility V giving preference to explicit ones. - // This is used, for example, when merging the visibility of a class - // down to one of its members. If the member has no explicit visibility, - // the class visibility wins. - void mergeVisibility(Visibility V, bool E = false) { - // Never increase the visibility - if (visibility() < V) - return; - - // If we have an explicit visibility, keep it - if (visibilityExplicit()) - return; - - setVisibility(V, E); - } - // Merge the visibility V, keeping the most restrictive one. - // This is used for cases like merging the visibility of a template - // argument to an instantiation. If we already have a hidden class, - // no argument should give it default visibility. - void mergeVisibilityWithMin(Visibility V, bool E = false) { - // Never increase the visibility - if (visibility() < V) - return; - - // FIXME: this - // If this visibility is explicit, keep it. - if (visibilityExplicit() && !E) - return; - - // should be replaced with this - // Don't lose the explicit bit for nothing - // if (visibility() == V && visibilityExplicit()) - // return; - - setVisibility(V, E); - } - void mergeVisibility(LinkageInfo Other) { - mergeVisibility(Other.visibility(), Other.visibilityExplicit()); - } - void mergeVisibilityWithMin(LinkageInfo Other) { - mergeVisibilityWithMin(Other.visibility(), Other.visibilityExplicit()); - } - - void merge(LinkageInfo Other) { - mergeLinkage(Other); - mergeVisibility(Other); - } - void mergeWithMin(LinkageInfo Other) { - mergeLinkage(Other); - mergeVisibilityWithMin(Other); - } - }; - /// \brief Determine what kind of linkage this entity has. Linkage getLinkage() const; + /// \brief True if this decl has external linkage. + bool hasExternalLinkage() const { + return getLinkage() == ExternalLinkage; + } + + /// \brief True if this decl has external linkage. Don't cache the linkage, + /// because we are not finished setting up the redecl chain for the decl. + bool hasExternalLinkageUncached() const; + /// \brief Determines the visibility of this entity. Visibility getVisibility() const { - return getLinkageAndVisibility().visibility(); + return getLinkageAndVisibility().getVisibility(); } /// \brief Determines the linkage and visibility of this entity. LinkageInfo getLinkageAndVisibility() const; + /// Kinds of explicit visibility. + enum ExplicitVisibilityKind { + VisibilityForType, + VisibilityForValue + }; + /// \brief If visibility was explicitly specified for this /// declaration, return that visibility. - llvm::Optional<Visibility> getExplicitVisibility() const; + Optional<Visibility> + getExplicitVisibility(ExplicitVisibilityKind kind) const; - /// \brief Clear the linkage cache in response to a change - /// to the declaration. - void ClearLinkageCache(); + /// \brief True if the computed linkage is valid. Used for consistency + /// checking. Should always return true. + bool isLinkageValid() const; /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for /// the underlying named decl. @@ -538,9 +460,7 @@ public: /// \brief Determine whether this symbol is weakly-imported, /// or declared with the weak or weak-ref attr. - bool isWeak() const { - return hasAttr<WeakAttr>() || hasAttr<WeakRefAttr>() || isWeakImported(); - } + bool isWeak() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -744,7 +664,6 @@ private: friend class ASTDeclReader; unsigned SClass : 3; - unsigned SClassAsWritten : 3; unsigned ThreadSpecified : 1; unsigned InitStyle : 2; @@ -811,14 +730,12 @@ protected: VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, StorageClass SC, - StorageClass SCAsWritten) + QualType T, TypeSourceInfo *TInfo, StorageClass SC) : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() { assert(sizeof(VarDeclBitfields) <= sizeof(unsigned)); assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned)); AllBits = 0; VarDeclBits.SClass = SC; - VarDeclBits.SClassAsWritten = SCAsWritten; // Everything else is implicitly initialized to false. } @@ -841,23 +758,18 @@ public: static VarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten); + StorageClass S); static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID); virtual SourceRange getSourceRange() const LLVM_READONLY; + /// \brief Returns the storage class as written in the source. For the + /// computed linkage of symbol, see getLinkage. StorageClass getStorageClass() const { return (StorageClass) VarDeclBits.SClass; } - StorageClass getStorageClassAsWritten() const { - return (StorageClass) VarDeclBits.SClassAsWritten; - } void setStorageClass(StorageClass SC); - void setStorageClassAsWritten(StorageClass SC) { - assert(isLegalForVariable(SC)); - VarDeclBits.SClassAsWritten = SC; - } void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; } bool isThreadSpecified() const { @@ -882,8 +794,8 @@ public: return getStorageClass() == SC_Static && !isFileVarDecl(); } - /// hasExternStorage - Returns true if a variable has extern or - /// __private_extern__ storage. + /// \brief Returns true if a variable has extern or __private_extern__ + /// storage. bool hasExternalStorage() const { return getStorageClass() == SC_Extern || getStorageClass() == SC_PrivateExtern; @@ -894,6 +806,9 @@ public: /// as static variables declared within a function. bool hasGlobalStorage() const { return !hasLocalStorage(); } + /// Compute the language linkage. + LanguageLinkage getLanguageLinkage() const; + /// \brief Determines whether this variable is a variable with /// external, C linkage. bool isExternC() const; @@ -1087,8 +1002,7 @@ public: /// not a constant expression. Returns a pointer to the value if evaluation /// succeeded, 0 otherwise. APValue *evaluateValue() const; - APValue *evaluateValue( - llvm::SmallVectorImpl<PartialDiagnosticAt> &Notes) const; + APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const; /// \brief Return the already-evaluated value of this variable's /// initializer, or NULL if the value is not yet known. Returns pointer @@ -1220,7 +1134,7 @@ public: ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType Type) : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type, - /*tinfo*/ 0, SC_None, SC_None) { + /*tinfo*/ 0, SC_None) { setImplicit(); } @@ -1239,8 +1153,8 @@ protected: ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten, Expr *DefArg) - : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S, SCAsWritten) { + StorageClass S, Expr *DefArg) + : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) { assert(ParmVarDeclBits.HasInheritedDefaultArg == false); assert(ParmVarDeclBits.IsKNRPromoted == false); assert(ParmVarDeclBits.IsObjCMethodParam == false); @@ -1252,8 +1166,7 @@ public: SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten, - Expr *DefArg); + StorageClass S, Expr *DefArg); static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1451,14 +1364,13 @@ private: /// DeclsInPrototypeScope - Array of pointers to NamedDecls for /// decls defined in the function prototype that are not parameters. E.g. /// 'enum Y' in 'void f(enum Y {AA} x) {}'. - llvm::ArrayRef<NamedDecl*> DeclsInPrototypeScope; + ArrayRef<NamedDecl *> DeclsInPrototypeScope; LazyDeclStmtPtr Body; // FIXME: This can be packed into the bitfields in Decl. // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum unsigned SClass : 2; - unsigned SClassAsWritten : 2; bool IsInline : 1; bool IsInlineSpecified : 1; bool IsVirtualAsWritten : 1; @@ -1473,6 +1385,10 @@ private: bool IsLateTemplateParsed : 1; bool IsConstexpr : 1; + /// \brief Indicates if the function was a definition but its body was + /// skipped. + unsigned HasSkippedBody : 1; + /// \brief End part of this FunctionDecl's source range. /// /// We could compute the full range in getSourceRange(). However, when we're @@ -1538,25 +1454,26 @@ private: void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD, TemplateSpecializationKind TSK); - void setParams(ASTContext &C, llvm::ArrayRef<ParmVarDecl *> NewParamInfo); + void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo); protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified, + StorageClass S, bool isInlineSpecified, bool isConstexprSpecified) : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, StartLoc), DeclContext(DK), ParamInfo(0), Body(), - SClass(S), SClassAsWritten(SCAsWritten), + SClass(S), IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), IsDefaulted(false), IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), - IsConstexpr(isConstexprSpecified), EndRangeLoc(NameInfo.getEndLoc()), + IsConstexpr(isConstexprSpecified), HasSkippedBody(false), + EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), DNLoc(NameInfo.getInfo()) {} @@ -1580,14 +1497,13 @@ public: SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, - StorageClass SC = SC_None, - StorageClass SCAsWritten = SC_None, + StorageClass SC, bool isInlineSpecified = false, bool hasWrittenPrototype = true, bool isConstexprSpecified = false) { DeclarationNameInfo NameInfo(N, NLoc); return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, - SC, SCAsWritten, + SC, isInlineSpecified, hasWrittenPrototype, isConstexprSpecified); } @@ -1596,10 +1512,9 @@ public: SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass SC = SC_None, - StorageClass SCAsWritten = SC_None, - bool isInlineSpecified = false, - bool hasWrittenPrototype = true, + StorageClass SC, + bool isInlineSpecified, + bool hasWrittenPrototype, bool isConstexprSpecified = false); static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1608,7 +1523,7 @@ public: return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } - virtual void getNameForDiagnostic(std::string &S, + virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const; @@ -1732,7 +1647,7 @@ public: /// Whether this is a (C++11) constexpr function or constexpr constructor. bool isConstexpr() const { return IsConstexpr; } - void setConstexpr(bool IC); + void setConstexpr(bool IC) { IsConstexpr = IC; } /// \brief Whether this function has been deleted. /// @@ -1776,6 +1691,9 @@ public: /// This function must be an allocation or deallocation function. bool isReservedGlobalPlacementOperator() const; + /// Compute the language linkage. + LanguageLinkage getLanguageLinkage() const; + /// \brief Determines whether this function is a function with /// external, C linkage. bool isExternC() const; @@ -1783,6 +1701,14 @@ public: /// \brief Determines whether this is a global function. bool isGlobal() const; + /// \brief Determines whether this function is known to be 'noreturn', through + /// an attribute on its declaration or its type. + bool isNoReturn() const; + + /// \brief True if the function was a definition but its body was skipped. + bool hasSkippedBody() const { return HasSkippedBody; } + void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + void setPreviousDeclaration(FunctionDecl * PrevDecl); virtual const FunctionDecl *getCanonicalDecl() const; @@ -1814,14 +1740,14 @@ public: assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } - void setParams(llvm::ArrayRef<ParmVarDecl *> NewParamInfo) { + void setParams(ArrayRef<ParmVarDecl *> NewParamInfo) { setParams(getASTContext(), NewParamInfo); } - const llvm::ArrayRef<NamedDecl*> &getDeclsInPrototypeScope() const { + const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const { return DeclsInPrototypeScope; } - void setDeclsInPrototypeScope(llvm::ArrayRef<NamedDecl *> NewDecls); + void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls); /// getMinRequiredArguments - Returns the minimum number of arguments /// needed to call this function. This may be fewer than the number of @@ -1838,12 +1764,9 @@ public: return getType()->getAs<FunctionType>()->getCallResultType(getASTContext()); } + /// \brief Returns the storage class as written in the source. For the + /// computed linkage of symbol, see getLinkage. StorageClass getStorageClass() const { return StorageClass(SClass); } - void setStorageClass(StorageClass SC); - - StorageClass getStorageClassAsWritten() const { - return StorageClass(SClassAsWritten); - } /// \brief Determine whether the "inline" keyword was specified for this /// function. @@ -1863,7 +1786,7 @@ public: /// \brief Determine whether this function should be inlined, because it is /// either marked "inline" or "constexpr" or is a member function of a class /// that was defined in the class body. - bool isInlined() const; + bool isInlined() const { return IsInline; } bool isInlineDefinitionExternallyVisible() const; @@ -1908,7 +1831,9 @@ public: /// \brief If this function is an instantiation of a member function of a /// class template specialization, retrieves the member specialization /// information. - MemberSpecializationInfo *getMemberSpecializationInfo() const; + MemberSpecializationInfo *getMemberSpecializationInfo() const { + return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); + } /// \brief Specify that this record is an instantiation of the /// member function FD. @@ -2472,6 +2397,12 @@ protected: /// possible in C++11 or Microsoft extensions mode. bool IsFixed : 1; + /// \brief Indicates whether it is possible for declarations of this kind + /// to have an out-of-date definition. + /// + /// This option is only enabled when modules are enabled. + bool MayHaveOutOfDateDef : 1; + private: SourceLocation RBraceLoc; @@ -2616,6 +2547,25 @@ public: bool isUnion() const { return getTagKind() == TTK_Union; } bool isEnum() const { return getTagKind() == TTK_Enum; } + /// Is this tag type named, either directly or via being defined in + /// a typedef of this type? + /// + /// C++11 [basic.link]p8: + /// A type is said to have linkage if and only if: + /// - it is a class or enumeration type that is named (or has a + /// name for linkage purposes) and the name has linkage; ... + /// C++11 [dcl.typedef]p9: + /// If the typedef declaration defines an unnamed class (or enum), + /// the first typedef-name declared by the declaration to be that + /// class type (or enum type) is used to denote the class type (or + /// enum type) for linkage purposes only. + /// + /// C does not have an analogous rule, but the same concept is + /// nonetheless useful in some places. + bool hasNameForLinkage() const { + return (getDeclName() || getTypedefNameForAnonDecl()); + } + TypedefNameDecl *getTypedefNameForAnonDecl() const { return hasExtInfo() ? 0 : TypedefNameDeclOrQualifier.get<TypedefNameDecl*>(); @@ -2906,6 +2856,10 @@ class RecordDecl : public TagDecl { /// HasObjectMember - This is true if this struct has at least one member /// containing an Objective-C object pointer type. bool HasObjectMember : 1; + + /// HasVolatileMember - This is true if struct has at least one member of + /// 'volatile' type. + bool HasVolatileMember : 1; /// \brief Whether the field declarations of this record have been loaded /// from external storage. To avoid unnecessary deserialization of @@ -2962,6 +2916,9 @@ public: bool hasObjectMember() const { return HasObjectMember; } void setHasObjectMember (bool val) { HasObjectMember = val; } + bool hasVolatileMember() const { return HasVolatileMember; } + void setHasVolatileMember (bool val) { HasVolatileMember = val; } + /// \brief Determines whether this declaration represents the /// injected class name. /// @@ -3161,7 +3118,7 @@ public: assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } - void setParams(llvm::ArrayRef<ParmVarDecl *> NewParamInfo); + void setParams(ArrayRef<ParmVarDecl *> NewParamInfo); /// hasCaptures - True if this block (or its nested blocks) captures /// anything of local storage from its enclosing scopes. @@ -3210,7 +3167,7 @@ public: /// /// An import declaration imports the named module (or submodule). For example: /// \code -/// @__experimental_modules_import std.vector; +/// @import std.vector; /// \endcode /// /// Import declarations can also be implicitly generated from @@ -3271,7 +3228,21 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Import; } }; - + +/// \brief Represents an empty-declaration. +class EmptyDecl : public Decl { + virtual void anchor(); + EmptyDecl(DeclContext *DC, SourceLocation L) + : Decl(Empty, DC, L) { } + +public: + static EmptyDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L); + static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Empty; } +}; /// Insertion operator for diagnostics. This allows sending NamedDecl's /// into a diagnostic with <<. @@ -3299,10 +3270,10 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) { // Point to previous. Make sure that this is actually the most recent // redeclaration, or we can build invalid chains. If the most recent // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. - RedeclLink = PreviousDeclLink( - llvm::cast<decl_type>(PrevDecl->getMostRecentDecl())); First = PrevDecl->getFirstDeclaration(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); + decl_type *MostRecent = First->RedeclLink.getNext(); + RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent)); } else { // Make this first. First = static_cast<decl_type*>(this); @@ -3310,8 +3281,8 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) { // First one will point to this one as latest. First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this)); - if (NamedDecl *ND = dyn_cast<NamedDecl>(static_cast<decl_type*>(this))) - ND->ClearLinkageCache(); + assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) || + cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid()); } // Inline function definitions. |