r209046 - If a declaration is loaded, and then a module import adds a redeclaration, then

Richard Smith richard-llvm at metafoo.co.uk
Fri May 16 16:01:31 PDT 2014


Author: rsmith
Date: Fri May 16 18:01:30 2014
New Revision: 209046

URL: http://llvm.org/viewvc/llvm-project?rev=209046&view=rev
Log:
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.

This works as follows:
 * The 'most recent' pointer on a canonical declaration grows a pointer to the
   external AST source and a generation number (space- and time-optimized for
   the case where there is no external source).
 * Each time the 'most recent' pointer is queried, if it has an external source,
   we check whether it's up to date, and update it if not.
 * The ancillary data stored on the canonical declaration is allocated lazily
   to avoid filling it in for declarations that end up being non-canonical.
   We'll still perform a redundant (ASTContext) allocation if someone asks for
   the most recent declaration from a decl before setPreviousDecl is called,
   but such cases are probably all bugs, and are now easy to find.

Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.

Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.

Early performance benchmarks show that this makes no measurable difference to 
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.

Added:
    cfe/trunk/test/Modules/Inputs/redecl-add-after-load.h
    cfe/trunk/test/Modules/redecl-add-after-load.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/include/clang/AST/ExternalASTSource.h
    cfe/trunk/include/clang/AST/Redeclarable.h
    cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/AST/ExternalASTSource.cpp
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/Frontend/FrontendAction.cpp
    cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Modules/Inputs/module.map
    cfe/trunk/test/Modules/decldef.mm

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri May 16 18:01:30 2014
@@ -19,6 +19,7 @@
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RawCommentList.h"
@@ -51,7 +52,6 @@ namespace clang {
   class CharUnits;
   class DiagnosticsEngine;
   class Expr;
-  class ExternalASTSource;
   class ASTMutationListener;
   class IdentifierTable;
   class MaterializeTemporaryExpr;
@@ -849,7 +849,7 @@ public:
 
   /// \brief Retrieve the declaration for a 128-bit float stub type.
   TypeDecl *getFloat128StubType() const;
-  
+
   //===--------------------------------------------------------------------===//
   //                           Type Constructors
   //===--------------------------------------------------------------------===//
@@ -2395,4 +2395,18 @@ inline void operator delete[](void *Ptr,
   C.Deallocate(Ptr);
 }
 
+/// \brief Create the representation of a LazyGenerationalUpdatePtr.
+template <typename Owner, typename T,
+          void (clang::ExternalASTSource::*Update)(Owner)>
+typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
+    clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue(
+        const clang::ASTContext &Ctx, T Value) {
+  // Note, this is implemented here so that ExternalASTSource.h doesn't need to
+  // include ASTContext.h. We explicitly instantiate it for all relevant types
+  // in ASTContext.cpp.
+  if (auto *Source = Ctx.getExternalSource())
+    return new (Ctx) LazyData(Source, Value);
+  return Value;
+}
+
 #endif

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri May 16 18:01:30 2014
@@ -355,9 +355,9 @@ class NamespaceDecl : public NamedDecl,
   /// 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;
   NamespaceDecl *getNextRedeclarationImpl() override;
@@ -769,7 +769,7 @@ 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);
 
@@ -1214,10 +1214,10 @@ public:
                                    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,
+    : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
               /*tinfo*/ nullptr, SC_None) {
     setImplicit();
   }
@@ -1234,11 +1234,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);
@@ -1535,7 +1534,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,
@@ -1543,6 +1542,7 @@ protected:
     : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
                      StartLoc),
       DeclContext(DK),
+      redeclarable_base(C),
       ParamInfo(nullptr), Body(),
       SClass(S),
       IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
@@ -2405,10 +2405,11 @@ class TypedefNameDecl : public TypeDecl,
   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;
   TypedefNameDecl *getNextRedeclarationImpl() override {
@@ -2464,9 +2465,9 @@ 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,
@@ -2484,9 +2485,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,
@@ -2582,10 +2583,11 @@ 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 *)nullptr) {
@@ -2632,8 +2634,8 @@ public:
   SourceLocation getOuterLocStart() const;
   SourceRange getSourceRange() const override LLVM_READONLY;
 
-  TagDecl* getCanonicalDecl() override;
-  const TagDecl* getCanonicalDecl() const {
+  TagDecl *getCanonicalDecl() override;
+  const TagDecl *getCanonicalDecl() const {
     return const_cast<TagDecl*>(this)->getCanonicalDecl();
   }
 
@@ -2828,11 +2830,11 @@ 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(nullptr) {
+      : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc),
+        SpecializationInfo(nullptr) {
     assert(Scoped || !ScopedUsingClassTag);
     IntegerType = (const Type *)nullptr;
     NumNegativeBits = 0;
@@ -3061,7 +3063,7 @@ 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);
 
@@ -3582,6 +3584,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;
 
@@ -3591,7 +3595,7 @@ void Redeclarable<decl_type>::setPreviou
     // 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
@@ -3605,7 +3609,8 @@ void Redeclarable<decl_type>::setPreviou
   }
 
   // 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());
 }

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri May 16 18:01:30 2014
@@ -494,7 +494,13 @@ class CXXRecordDecl : public RecordDecl
   private:
     CXXBaseSpecifier *getBasesSlowCase() const;
     CXXBaseSpecifier *getVBasesSlowCase() const;
-  } *DefinitionData;
+  };
+
+  typedef LazyGenerationalUpdatePtr<const Decl*, struct DefinitionData*,
+                                    &ExternalASTSource::CompleteRedeclChain>
+      DefinitionDataPtr;
+
+  mutable DefinitionDataPtr DefinitionData;
 
   /// \brief Describes a C++ closure type (generated by a lambda expression).
   struct LambdaDefinitionData : public DefinitionData {
@@ -551,21 +557,16 @@ class CXXRecordDecl : public RecordDecl
        
   };
 
-  struct DefinitionData &data() {
-    assert(DefinitionData && "queried property of class with no definition");
-    return *DefinitionData;
-  }
-
-  const struct DefinitionData &data() const {
-    assert(DefinitionData && "queried property of class with no definition");
-    return *DefinitionData;
+  struct DefinitionData &data() const {
+    auto *DD = DefinitionData.get(this);
+    assert(DD && "queried property of class with no definition");
+    return *DD;
   }
 
   struct LambdaDefinitionData &getLambdaData() const {
-    assert(DefinitionData && "queried property of lambda with no definition");
-    assert(DefinitionData->IsLambda && 
-           "queried lambda property of non-lambda class");
-    return static_cast<LambdaDefinitionData &>(*DefinitionData);
+    auto &DD = data();
+    assert(DD.IsLambda && "queried lambda property of non-lambda class");
+    return static_cast<LambdaDefinitionData&>(DD);
   }
   
   /// \brief The template or declaration that this declaration
@@ -604,7 +605,7 @@ class CXXRecordDecl : public RecordDecl
   FriendDecl *getFirstFriend() const;
 
 protected:
-  CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
+  CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC,
                 SourceLocation StartLoc, SourceLocation IdLoc,
                 IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
 
@@ -640,11 +641,11 @@ public:
   }
 
   CXXRecordDecl *getDefinition() const {
-    if (!DefinitionData) return nullptr;
-    return data().Definition;
+    auto *DD = DefinitionData.get(this);
+    return DD ? DD->Definition : nullptr;
   }
 
-  bool hasDefinition() const { return DefinitionData != nullptr; }
+  bool hasDefinition() const { return DefinitionData.get(this); }
 
   static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
                                SourceLocation StartLoc, SourceLocation IdLoc,
@@ -653,7 +654,7 @@ public:
                                bool DelayTypeCreation = false);
   static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
                                      TypeSourceInfo *Info, SourceLocation Loc,
-                                     bool DependentLambda, bool IsGeneric, 
+                                     bool DependentLambda, bool IsGeneric,
                                      LambdaCaptureDefault CaptureDefault);
   static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
 
@@ -1658,12 +1659,12 @@ public:
 class CXXMethodDecl : public FunctionDecl {
   void anchor() override;
 protected:
-  CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
-                const DeclarationNameInfo &NameInfo,
+  CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
+                SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
                 QualType T, TypeSourceInfo *TInfo,
                 StorageClass SC, bool isInline,
                 bool isConstexpr, SourceLocation EndLocation)
-    : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
+    : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo,
                    SC, isInline, isConstexpr) {
     if (EndLocation.isValid())
       setRangeEnd(EndLocation);
@@ -2098,12 +2099,12 @@ class CXXConstructorDecl : public CXXMet
   unsigned NumCtorInitializers;
   /// \}
 
-  CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+  CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
                      const DeclarationNameInfo &NameInfo,
                      QualType T, TypeSourceInfo *TInfo,
                      bool isExplicitSpecified, bool isInline,
                      bool isImplicitlyDeclared, bool isConstexpr)
-    : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo,
+    : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
                     SC_None, isInline, isConstexpr, SourceLocation()),
       IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
       NumCtorInitializers(0) {
@@ -2298,11 +2299,11 @@ class CXXDestructorDecl : public CXXMeth
 
   FunctionDecl *OperatorDelete;
 
-  CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+  CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
                     const DeclarationNameInfo &NameInfo,
                     QualType T, TypeSourceInfo *TInfo,
                     bool isInline, bool isImplicitlyDeclared)
-    : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo,
+    : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
                     SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
       OperatorDelete(nullptr) {
     setImplicit(isImplicitlyDeclared);
@@ -2349,12 +2350,12 @@ class CXXConversionDecl : public CXXMeth
   /// explicitly wrote a cast. This is a C++0x feature.
   bool IsExplicitSpecified : 1;
 
-  CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+  CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
                     const DeclarationNameInfo &NameInfo,
                     QualType T, TypeSourceInfo *TInfo,
                     bool isInline, bool isExplicitSpecified,
                     bool isConstexpr, SourceLocation EndLocation)
-    : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo,
+    : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
                     SC_None, isInline, isConstexpr, EndLocation),
       IsExplicitSpecified(isExplicitSpecified) { }
 
@@ -2706,10 +2707,10 @@ class UsingShadowDecl : public NamedDecl
   NamedDecl *UsingOrNextShadow;
   friend class UsingDecl;
 
-  UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
-                  NamedDecl *Target)
+  UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
+                  UsingDecl *Using, NamedDecl *Target)
     : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
-      Underlying(Target),
+      redeclarable_base(C), Underlying(Target),
       UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
     if (Target) {
       setDeclName(Target->getDeclName());
@@ -2733,7 +2734,7 @@ public:
   static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation Loc, UsingDecl *Using,
                                  NamedDecl *Target) {
-    return new (C, DC) UsingShadowDecl(DC, Loc, Using, Target);
+    return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
   }
 
   static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Fri May 16 18:01:30 2014
@@ -734,9 +734,9 @@ class ObjCInterfaceDecl : public ObjCCon
                        InheritedDesignatedInitializers(IDI_Unknown) { }
   };
 
-  ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                    SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
-                    bool isInternal);
+  ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
+                    IdentifierInfo *Id, SourceLocation CLoc,
+                    ObjCInterfaceDecl *PrevDecl, bool IsInternal);
 
   void LoadExternalDefinition() const;
 
@@ -774,7 +774,7 @@ public:
                                    SourceLocation ClassLoc = SourceLocation(),
                                    bool isInternal = false);
 
-  static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
 
   SourceRange getSourceRange() const override LLVM_READONLY {
     if (isThisDeclarationADefinition())
@@ -1524,7 +1524,7 @@ class ObjCProtocolDecl : public ObjCCont
     return *Data.getPointer();
   }
   
-  ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
+  ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
                    SourceLocation nameLoc, SourceLocation atStartLoc,
                    ObjCProtocolDecl *PrevDecl);
 
@@ -1549,7 +1549,7 @@ public:
                                   ObjCProtocolDecl *PrevDecl);
 
   static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-                           
+
   const ObjCProtocolList &getReferencedProtocols() const {
     assert(hasDefinition() && "No definition available!");
     return data().ReferencedProtocols;

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Fri May 16 18:01:30 2014
@@ -624,10 +624,11 @@ protected:
   virtual CommonBase *newCommon(ASTContext &C) const = 0;
 
   // Construct a template decl with name, parameters, and templated element.
-  RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
-                           DeclarationName Name, TemplateParameterList *Params,
-                           NamedDecl *Decl)
-    : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { }
+  RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
+                           SourceLocation L, DeclarationName Name,
+                           TemplateParameterList *Params, NamedDecl *Decl)
+      : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
+        Common() {}
 
 public:
   template <class decl_type> friend class RedeclarableTemplate;
@@ -775,9 +776,11 @@ protected:
     uint32_t *LazySpecializations;
   };
 
-  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                       TemplateParameterList *Params, NamedDecl *Decl)
-    : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+  FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                       DeclarationName Name, TemplateParameterList *Params,
+                       NamedDecl *Decl)
+      : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
+                                 Decl) {}
 
   CommonBase *newCommon(ASTContext &C) const override;
 
@@ -1438,7 +1441,7 @@ protected:
                                   unsigned NumArgs,
                                   ClassTemplateSpecializationDecl *PrevDecl);
 
-  explicit ClassTemplateSpecializationDecl(Kind DK);
+  explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
 
 public:
   static ClassTemplateSpecializationDecl *
@@ -1676,8 +1679,8 @@ class ClassTemplatePartialSpecialization
                                const ASTTemplateArgumentListInfo *ArgsAsWritten,
                                ClassTemplatePartialSpecializationDecl *PrevDecl);
 
-  ClassTemplatePartialSpecializationDecl()
-    : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
+  ClassTemplatePartialSpecializationDecl(ASTContext &C)
+    : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
       TemplateParams(nullptr), ArgsAsWritten(nullptr),
       InstantiatedFromMember(nullptr, false) {}
 
@@ -1838,13 +1841,10 @@ protected:
   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
   getPartialSpecializations();
 
-  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                    TemplateParameterList *Params, NamedDecl *Decl)
-    : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
-
-  ClassTemplateDecl(EmptyShell Empty)
-    : RedeclarableTemplateDecl(ClassTemplate, nullptr, SourceLocation(),
-                               DeclarationName(), nullptr, nullptr) { }
+  ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                    DeclarationName Name, TemplateParameterList *Params,
+                    NamedDecl *Decl)
+      : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
 
   CommonBase *newCommon(ASTContext &C) const override;
 
@@ -2105,9 +2105,11 @@ class TypeAliasTemplateDecl : public Red
 protected:
   typedef CommonBase Common;
 
-  TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                        TemplateParameterList *Params, NamedDecl *Decl)
-    : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
+  TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                        DeclarationName Name, TemplateParameterList *Params,
+                        NamedDecl *Decl)
+      : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
+                                 Decl) {}
 
   CommonBase *newCommon(ASTContext &C) const override;
 
@@ -2297,14 +2299,14 @@ class VarTemplateSpecializationDecl : pu
   unsigned SpecializationKind : 3;
 
 protected:
-  VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC,
+  VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
                                 SourceLocation StartLoc, SourceLocation IdLoc,
                                 VarTemplateDecl *SpecializedTemplate,
                                 QualType T, TypeSourceInfo *TInfo,
                                 StorageClass S, const TemplateArgument *Args,
                                 unsigned NumArgs);
 
-  explicit VarTemplateSpecializationDecl(Kind DK);
+  explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
 
 public:
   static VarTemplateSpecializationDecl *
@@ -2532,8 +2534,8 @@ class VarTemplatePartialSpecializationDe
       StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
       const ASTTemplateArgumentListInfo *ArgInfos);
 
-  VarTemplatePartialSpecializationDecl()
-    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization),
+  VarTemplatePartialSpecializationDecl(ASTContext &Context)
+    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
       TemplateParams(nullptr), ArgsAsWritten(nullptr),
       InstantiatedFromMember(nullptr, false) {}
 
@@ -2676,13 +2678,10 @@ protected:
   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
   getPartialSpecializations();
 
-  VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                  TemplateParameterList *Params, NamedDecl *Decl)
-      : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {}
-
-  VarTemplateDecl(EmptyShell Empty)
-      : RedeclarableTemplateDecl(VarTemplate, nullptr, SourceLocation(),
-                                 DeclarationName(), nullptr, nullptr) {}
+  VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                  DeclarationName Name, TemplateParameterList *Params,
+                  NamedDecl *Decl)
+      : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
 
   CommonBase *newCommon(ASTContext &C) const override;
 

Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExternalASTSource.h (original)
+++ cfe/trunk/include/clang/AST/ExternalASTSource.h Fri May 16 18:01:30 2014
@@ -45,7 +45,7 @@ enum ExternalLoadResult {
   /// no additional processing is required.
   ELR_AlreadyLoaded
 };
-  
+
 /// \brief Abstract interface for external sources of AST nodes.
 ///
 /// External AST sources provide AST nodes constructed from some
@@ -54,6 +54,10 @@ enum ExternalLoadResult {
 /// actual type and declaration nodes, and read parts of declaration
 /// contexts.
 class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
+  /// Generation number for this external AST source. Must be increased
+  /// whenever we might have added new redeclarations for existing decls.
+  uint32_t CurrentGeneration;
+
   /// \brief Whether this AST source also provides information for
   /// semantic analysis.
   bool SemaSource;
@@ -61,7 +65,7 @@ class ExternalASTSource : public RefCoun
   friend class ExternalSemaSource;
 
 public:
-  ExternalASTSource() : SemaSource(false) { }
+  ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
 
   virtual ~ExternalASTSource();
 
@@ -79,6 +83,11 @@ public:
     }
   };
 
+  /// \brief Get the current generation of this AST source. This number
+  /// is incremented each time the AST source lazily extends an existing
+  /// entity.
+  uint32_t getGeneration() const { return CurrentGeneration; }
+
   /// \brief Resolve a declaration ID into a declaration, potentially
   /// building a new declaration.
   ///
@@ -176,6 +185,12 @@ public:
                                    SmallVectorImpl<Decl *> &Decls) {}
 
   /// \brief Gives the external AST source an opportunity to complete
+  /// the redeclaration chain for a declaration. Called each time we
+  /// need the most recent declaration of a declaration after the
+  /// generation count is incremented.
+  virtual void CompleteRedeclChain(const Decl *D) {}
+
+  /// \brief Gives the external AST source an opportunity to complete
   /// an incomplete type.
   virtual void CompleteType(TagDecl *Tag) {}
 
@@ -284,6 +299,9 @@ protected:
   static DeclContextLookupResult
   SetNoExternalVisibleDeclsForName(const DeclContext *DC,
                                    DeclarationName Name);
+
+  /// \brief Increment the current generation.
+  uint32_t incrementGeneration(ASTContext &C);
 };
 
 /// \brief A lazy pointer to an AST node (of base type T) that resides
@@ -354,6 +372,97 @@ public:
   }
 };
 
+/// \brief A lazy value (of type T) that is within an AST node of type Owner,
+/// where the value might change in later generations of the external AST
+/// source.
+template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
+struct LazyGenerationalUpdatePtr {
+  /// A cache of the value of this pointer, in the most recent generation in
+  /// which we queried it.
+  struct LazyData {
+    LazyData(ExternalASTSource *Source, T Value)
+        : ExternalSource(Source), LastGeneration(Source->getGeneration()),
+          LastValue(Value) {}
+    ExternalASTSource *ExternalSource;
+    uint32_t LastGeneration;
+    T LastValue;
+  };
+
+  // Our value is represented as simply T if there is no external AST source.
+  typedef llvm::PointerUnion<T, LazyData*> ValueType;
+  ValueType Value;
+
+  LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
+
+  // Defined in ASTContext.h
+  static ValueType makeValue(const ASTContext &Ctx, T Value);
+
+public:
+  explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
+      : Value(makeValue(Ctx, Value)) {}
+
+  /// Create a pointer that is not potentially updated by later generations of
+  /// the external AST source.
+  enum NotUpdatedTag { NotUpdated };
+  LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
+      : Value(Value) {}
+
+  /// Set the value of this pointer, in the current generation.
+  void set(T NewValue) {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+      LazyVal->LastValue = NewValue;
+      LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
+      return;
+    }
+    Value = NewValue;
+  }
+
+  /// Set the value of this pointer, for this and all future generations.
+  void setNotUpdated(T NewValue) { Value = NewValue; }
+
+  /// Get the value of this pointer, updating its owner if necessary.
+  T get(Owner O) {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+      if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
+        LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
+        (LazyVal->ExternalSource->*Update)(O);
+      }
+      return LazyVal->LastValue;
+    }
+    return Value.template get<T>();
+  }
+
+  /// Get the most recently computed value of this pointer without updating it.
+  T getNotUpdated() const {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
+      return LazyVal->LastValue;
+    return Value.template get<T>();
+  }
+
+  void *getOpaqueValue() { return Value.getOpaqueValue(); }
+  static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
+    return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
+  }
+};
+} // end namespace clang
+
+/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
+/// placed into a PointerUnion.
+namespace llvm {
+template<typename Owner, typename T,
+         void (clang::ExternalASTSource::*Update)(Owner)>
+struct PointerLikeTypeTraits<
+    clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
+  typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
+  static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
+  static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
+  enum {
+    NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
+  };
+};
+}
+
+namespace clang {
 /// \brief Represents a lazily-loaded vector of data.
 ///
 /// The lazily-loaded vector of data contains data that is partially loaded

Modified: cfe/trunk/include/clang/AST/Redeclarable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Redeclarable.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Redeclarable.h (original)
+++ cfe/trunk/include/clang/AST/Redeclarable.h Fri May 16 18:01:30 2014
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_REDECLARABLE_H
 #define LLVM_CLANG_AST_REDECLARABLE_H
 
+#include "clang/AST/ExternalASTSource.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/Support/Casting.h"
 #include <iterator>
@@ -25,23 +26,78 @@ template<typename decl_type>
 class Redeclarable {
 protected:
   class DeclLink {
-    llvm::PointerIntPair<decl_type *, 1, bool> NextAndIsPrevious;
+    /// A pointer to a known latest declaration, either statically known or
+    /// generationally updated as decls are added by an external source.
+    typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
+                                      &ExternalASTSource::CompleteRedeclChain>
+                                          KnownLatest;
+
+    typedef const ASTContext *UninitializedLatest;
+    typedef Decl *Previous;
+
+    /// A pointer to either an uninitialized latest declaration (where either
+    /// we've not yet set the previous decl or there isn't one), or to a known
+    /// previous declaration.
+    typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
+
+    mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
+
   public:
-    DeclLink(decl_type *D, bool isLatest)
-      : NextAndIsPrevious(D, isLatest) { }
+    enum PreviousTag { PreviousLink };
+    enum LatestTag { LatestLink };
 
-    bool NextIsPrevious() const { return !NextAndIsPrevious.getInt(); }
-    bool NextIsLatest() const { return NextAndIsPrevious.getInt(); }
-    decl_type *getNext() const { return NextAndIsPrevious.getPointer(); }
-    void setNext(decl_type *D) { NextAndIsPrevious.setPointer(D); }
+    DeclLink(LatestTag, const ASTContext &Ctx)
+        : Next(NotKnownLatest(&Ctx)) {}
+    DeclLink(PreviousTag, decl_type *D)
+        : Next(NotKnownLatest(Previous(D))) {}
+
+    bool NextIsPrevious() const {
+      return Next.is<NotKnownLatest>() &&
+             // FIXME: 'template' is required on the next line due to an
+             // apparent clang bug.
+             Next.get<NotKnownLatest>().template is<Previous>();
+    }
+
+    bool NextIsLatest() const { return !NextIsPrevious(); }
+
+    decl_type *getNext(const decl_type *D) const {
+      if (Next.is<NotKnownLatest>()) {
+        NotKnownLatest NKL = Next.get<NotKnownLatest>();
+        if (NKL.is<Previous>())
+          return static_cast<decl_type*>(NKL.get<Previous>());
+
+        // Allocate the generational 'most recent' cache now, if needed.
+        Next = KnownLatest(*NKL.get<UninitializedLatest>(),
+                           const_cast<decl_type *>(D));
+      }
+
+      return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
+    }
+
+    void setPrevious(decl_type *D) {
+      assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
+      Next = Previous(D);
+    }
+
+    void setLatest(decl_type *D) {
+      assert(NextIsLatest() && "decl became canonical unexpectedly");
+      if (Next.is<NotKnownLatest>()) {
+        NotKnownLatest NKL = Next.get<NotKnownLatest>();
+        Next = KnownLatest(*NKL.get<UninitializedLatest>(), D);
+      } else {
+        auto Latest = Next.get<KnownLatest>();
+        Latest.set(D);
+        Next = Latest;
+      }
+    }
   };
 
   static DeclLink PreviousDeclLink(decl_type *D) {
-    return DeclLink(D, false);
+    return DeclLink(DeclLink::PreviousLink, D);
   }
 
-  static DeclLink LatestDeclLink(decl_type *D) {
-    return DeclLink(D, true);
+  static DeclLink LatestDeclLink(const ASTContext &Ctx) {
+    return DeclLink(DeclLink::LatestLink, Ctx);
   }
 
   /// \brief Points to the next redeclaration in the chain.
@@ -58,11 +114,12 @@ protected:
   DeclLink RedeclLink;
 
   decl_type *getNextRedeclaration() const {
-    return RedeclLink.getNext();
+    return RedeclLink.getNext(static_cast<const decl_type *>(this));
   }
 
 public:
-  Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { }
+  Redeclarable(const ASTContext &Ctx)
+      : RedeclLink(LatestDeclLink(Ctx)) {}
 
   /// \brief Return the previous declaration of this declaration or NULL if this
   /// is the first declaration.
@@ -106,7 +163,7 @@ public:
   const decl_type *getMostRecentDecl() const {
     return getFirstDecl()->getNextRedeclaration();
   }
-  
+
   /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
   /// first and only declaration.
   void setPreviousDecl(decl_type *PrevDecl);

Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Fri May 16 18:01:30 2014
@@ -67,6 +67,10 @@ public:
   /// building a new declaration.
   Decl *GetExternalDecl(uint32_t ID) override;
 
+  /// \brief Complete the redeclaration chain if it's been extended since the
+  /// previous generation of the AST source.
+  void CompleteRedeclChain(const Decl *D) override;
+
   /// \brief Resolve a selector ID into a selector.
   Selector GetExternalSelector(uint32_t ID) override;
 

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri May 16 18:01:30 2014
@@ -821,10 +821,6 @@ private:
   /// \brief Whether we have tried loading the global module index yet.
   bool TriedLoadingGlobalIndex;
 
-  /// \brief The current "generation" of the module file import stack, which 
-  /// indicates how many separate module file load operations have occurred.
-  unsigned CurrentGeneration;
-
   typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy;
   /// \brief Mapping from switch-case IDs in the chain to switch-case statements
   ///
@@ -1641,6 +1637,11 @@ public:
     return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I)));
   }
 
+  /// \brief If any redeclarations of \p D have been imported since it was
+  /// last checked, this digs out those redeclarations and adds them to the
+  /// redeclaration chain for \p D.
+  void CompleteRedeclChain(const Decl *D) override;
+
   /// \brief Read a CXXBaseSpecifiers ID form the given record and
   /// return its global bit offset.
   uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record,

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri May 16 18:01:30 2014
@@ -8239,3 +8239,12 @@ ASTContext::ObjCMethodsAreEqual(const Ob
   return (MethodDecl->isVariadic() == MethodImpl->isVariadic());
   
 }
+
+// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
+// doesn't include ASTContext.h
+template
+clang::LazyGenerationalUpdatePtr<
+    const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::ValueType
+clang::LazyGenerationalUpdatePtr<
+    const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue(
+        const clang::ASTContext &Ctx, Decl *Value);

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri May 16 18:01:30 2014
@@ -1616,10 +1616,12 @@ const char *VarDecl::getStorageClassSpec
   llvm_unreachable("Invalid storage class");
 }
 
-VarDecl::VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
-                 SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
-                 TypeSourceInfo *TInfo, StorageClass SC)
-    : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
+VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC,
+                 SourceLocation StartLoc, SourceLocation IdLoc,
+                 IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+                 StorageClass SC)
+    : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
+      redeclarable_base(C), Init() {
   static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned),
                 "VarDeclBitfields too large!");
   static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned),
@@ -1633,12 +1635,13 @@ VarDecl *VarDecl::Create(ASTContext &C,
                          SourceLocation StartL, SourceLocation IdL,
                          IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
                          StorageClass S) {
-  return new (C, DC) VarDecl(Var, DC, StartL, IdL, Id, T, TInfo, S);
+  return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S);
 }
 
 VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) VarDecl(Var, nullptr, SourceLocation(), SourceLocation(),
-                             nullptr, QualType(), nullptr, SC_None);
+  return new (C, ID)
+      VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
+              QualType(), nullptr, SC_None);
 }
 
 void VarDecl::setStorageClass(StorageClass SC) {
@@ -2114,7 +2117,7 @@ ParmVarDecl *ParmVarDecl::Create(ASTCont
                                  SourceLocation IdLoc, IdentifierInfo *Id,
                                  QualType T, TypeSourceInfo *TInfo,
                                  StorageClass S, Expr *DefArg) {
-  return new (C, DC) ParmVarDecl(ParmVar, DC, StartLoc, IdLoc, Id, T, TInfo,
+  return new (C, DC) ParmVarDecl(ParmVar, C, DC, StartLoc, IdLoc, Id, T, TInfo,
                                  S, DefArg);
 }
 
@@ -2127,9 +2130,9 @@ QualType ParmVarDecl::getOriginalType()
 }
 
 ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) ParmVarDecl(ParmVar, nullptr, SourceLocation(),
-                                 SourceLocation(), nullptr, QualType(),
-                                 nullptr, SC_None, nullptr);
+  return new (C, ID)
+      ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(),
+                  nullptr, QualType(), nullptr, SC_None, nullptr);
 }
 
 SourceRange ParmVarDecl::getSourceRange() const {
@@ -3234,10 +3237,10 @@ void TagDecl::startDefinition() {
   IsBeingDefined = true;
 
   if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) {
-    struct CXXRecordDecl::DefinitionData *Data = 
+    struct CXXRecordDecl::DefinitionData *Data =
       new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
     for (auto I : redecls())
-      cast<CXXRecordDecl>(I)->DefinitionData = Data;
+      cast<CXXRecordDecl>(I)->DefinitionData.setNotUpdated(Data);
   }
 }
 
@@ -3319,7 +3322,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C
                            IdentifierInfo *Id,
                            EnumDecl *PrevDecl, bool IsScoped,
                            bool IsScopedUsingClassTag, bool IsFixed) {
-  EnumDecl *Enum = new (C, DC) EnumDecl(DC, StartLoc, IdLoc, Id, PrevDecl,
+  EnumDecl *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
                                         IsScoped, IsScopedUsingClassTag,
                                         IsFixed);
   Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
@@ -3328,9 +3331,9 @@ EnumDecl *EnumDecl::Create(ASTContext &C
 }
 
 EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  EnumDecl *Enum = new (C, ID) EnumDecl(nullptr, SourceLocation(),
-                                        SourceLocation(), nullptr, nullptr,
-                                        false, false, false);
+  EnumDecl *Enum =
+      new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(),
+                           nullptr, nullptr, false, false, false);
   Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
   return Enum;
 }
@@ -3389,10 +3392,11 @@ void EnumDecl::setInstantiationOfMemberE
 // RecordDecl Implementation
 //===----------------------------------------------------------------------===//
 
-RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
-                       SourceLocation StartLoc, SourceLocation IdLoc,
-                       IdentifierInfo *Id, RecordDecl *PrevDecl)
-  : TagDecl(DK, TK, DC, IdLoc, Id, PrevDecl, StartLoc) {
+RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
+                       DeclContext *DC, SourceLocation StartLoc,
+                       SourceLocation IdLoc, IdentifierInfo *Id,
+                       RecordDecl *PrevDecl)
+    : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
   HasFlexibleArrayMember = false;
   AnonymousStructOrUnion = false;
   HasObjectMember = false;
@@ -3404,8 +3408,8 @@ RecordDecl::RecordDecl(Kind DK, TagKind
 RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
                                SourceLocation StartLoc, SourceLocation IdLoc,
                                IdentifierInfo *Id, RecordDecl* PrevDecl) {
-  RecordDecl* R = new (C, DC) RecordDecl(Record, TK, DC, StartLoc, IdLoc, Id,
-                                         PrevDecl);
+  RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC,
+                                         StartLoc, IdLoc, Id, PrevDecl);
   R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
 
   C.getTypeDeclType(R, PrevDecl);
@@ -3413,9 +3417,9 @@ RecordDecl *RecordDecl::Create(const AST
 }
 
 RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
-  RecordDecl *R = new (C, ID) RecordDecl(Record, TTK_Struct, nullptr,
-                                         SourceLocation(), SourceLocation(),
-                                         nullptr, nullptr);
+  RecordDecl *R =
+      new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(),
+                             SourceLocation(), nullptr, nullptr);
   R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
   return R;
 }
@@ -3577,12 +3581,12 @@ ImplicitParamDecl *ImplicitParamDecl::Cr
                                              SourceLocation IdLoc,
                                              IdentifierInfo *Id,
                                              QualType Type) {
-  return new (C, DC) ImplicitParamDecl(DC, IdLoc, Id, Type);
+  return new (C, DC) ImplicitParamDecl(C, DC, IdLoc, Id, Type);
 }
 
 ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
                                                          unsigned ID) {
-  return new (C, ID) ImplicitParamDecl(nullptr, SourceLocation(), nullptr,
+  return new (C, ID) ImplicitParamDecl(C, nullptr, SourceLocation(), nullptr,
                                        QualType());
 }
 
@@ -3595,14 +3599,14 @@ FunctionDecl *FunctionDecl::Create(ASTCo
                                    bool hasWrittenPrototype,
                                    bool isConstexprSpecified) {
   FunctionDecl *New =
-      new (C, DC) FunctionDecl(Function, DC, StartLoc, NameInfo, T, TInfo, SC,
-                               isInlineSpecified, isConstexprSpecified);
+      new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo,
+                               SC, isInlineSpecified, isConstexprSpecified);
   New->HasWrittenPrototype = hasWrittenPrototype;
   return New;
 }
 
 FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) FunctionDecl(Function, nullptr, SourceLocation(),
+  return new (C, ID) FunctionDecl(Function, C, nullptr, SourceLocation(),
                                   DeclarationNameInfo(), QualType(), nullptr,
                                   SC_None, false, false);
 }
@@ -3668,13 +3672,13 @@ void TypeDecl::anchor() { }
 TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation StartLoc, SourceLocation IdLoc,
                                  IdentifierInfo *Id, TypeSourceInfo *TInfo) {
-  return new (C, DC) TypedefDecl(DC, StartLoc, IdLoc, Id, TInfo);
+  return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
 }
 
 void TypedefNameDecl::anchor() { }
 
 TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) TypedefDecl(nullptr, SourceLocation(), SourceLocation(),
+  return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(),
                                  nullptr, nullptr);
 }
 
@@ -3682,12 +3686,12 @@ TypeAliasDecl *TypeAliasDecl::Create(AST
                                      SourceLocation StartLoc,
                                      SourceLocation IdLoc, IdentifierInfo *Id,
                                      TypeSourceInfo *TInfo) {
-  return new (C, DC) TypeAliasDecl(DC, StartLoc, IdLoc, Id, TInfo);
+  return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
 }
 
 TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) TypeAliasDecl(nullptr, SourceLocation(), SourceLocation(),
-                                   nullptr, nullptr);
+  return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(),
+                                   SourceLocation(), nullptr, nullptr);
 }
 
 SourceRange TypedefDecl::getSourceRange() const {

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Fri May 16 18:01:30 2014
@@ -82,19 +82,21 @@ CXXBaseSpecifier *CXXRecordDecl::Definit
   return VBases.get(Definition->getASTContext().getExternalSource());
 }
 
-CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
-                             SourceLocation StartLoc, SourceLocation IdLoc,
-                             IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
-  : RecordDecl(K, TK, DC, StartLoc, IdLoc, Id, PrevDecl),
-    DefinitionData(PrevDecl ? PrevDecl->DefinitionData : nullptr),
-    TemplateOrInstantiation() { }
+CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
+                             DeclContext *DC, SourceLocation StartLoc,
+                             SourceLocation IdLoc, IdentifierInfo *Id,
+                             CXXRecordDecl *PrevDecl)
+    : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
+      DefinitionData(PrevDecl ? PrevDecl->DefinitionData
+                              : DefinitionDataPtr(C)),
+      TemplateOrInstantiation() {}
 
 CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
                                      DeclContext *DC, SourceLocation StartLoc,
                                      SourceLocation IdLoc, IdentifierInfo *Id,
                                      CXXRecordDecl* PrevDecl,
                                      bool DelayTypeCreation) {
-  CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, DC, StartLoc,
+  CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc,
                                                IdLoc, Id, PrevDecl);
   R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
 
@@ -104,18 +106,18 @@ CXXRecordDecl *CXXRecordDecl::Create(con
   return R;
 }
 
-CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
-                                           TypeSourceInfo *Info, SourceLocation Loc,
-                                           bool Dependent, bool IsGeneric, 
-                                           LambdaCaptureDefault CaptureDefault) {
+CXXRecordDecl *
+CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
+                            TypeSourceInfo *Info, SourceLocation Loc,
+                            bool Dependent, bool IsGeneric,
+                            LambdaCaptureDefault CaptureDefault) {
   CXXRecordDecl *R =
-      new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc, nullptr,
-                                nullptr);
+      new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc,
+                                nullptr, nullptr);
   R->IsBeingDefined = true;
-  R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, 
-                                                          Dependent, 
-                                                          IsGeneric, 
-                                                          CaptureDefault);
+  R->DefinitionData.setNotUpdated(
+      new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric,
+                                          CaptureDefault));
   R->MayHaveOutOfDateDef = false;
   R->setImplicit(true);
   C.getTypeDeclType(R, /*PrevDecl=*/nullptr);
@@ -125,7 +127,7 @@ CXXRecordDecl *CXXRecordDecl::CreateLamb
 CXXRecordDecl *
 CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
   CXXRecordDecl *R = new (C, ID) CXXRecordDecl(
-      CXXRecord, TTK_Struct, nullptr, SourceLocation(), SourceLocation(),
+      CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(),
       nullptr, nullptr);
   R->MayHaveOutOfDateDef = false;
   return R;
@@ -1410,12 +1412,13 @@ CXXMethodDecl::Create(ASTContext &C, CXX
                       QualType T, TypeSourceInfo *TInfo,
                       StorageClass SC, bool isInline,
                       bool isConstexpr, SourceLocation EndLocation) {
-  return new (C, RD) CXXMethodDecl(CXXMethod, RD, StartLoc, NameInfo, T, TInfo,
-                                   SC, isInline, isConstexpr, EndLocation);
+  return new (C, RD) CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo,
+                                   T, TInfo, SC, isInline, isConstexpr,
+                                   EndLocation);
 }
 
 CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) CXXMethodDecl(CXXMethod, nullptr, SourceLocation(),
+  return new (C, ID) CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(),
                                    DeclarationNameInfo(), QualType(), nullptr,
                                    SC_None, false, false, SourceLocation());
 }
@@ -1680,7 +1683,7 @@ void CXXConstructorDecl::anchor() { }
 
 CXXConstructorDecl *
 CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) CXXConstructorDecl(nullptr, SourceLocation(),
+  return new (C, ID) CXXConstructorDecl(C, nullptr, SourceLocation(),
                                         DeclarationNameInfo(), QualType(),
                                         nullptr, false, false, false, false);
 }
@@ -1695,7 +1698,7 @@ CXXConstructorDecl::Create(ASTContext &C
   assert(NameInfo.getName().getNameKind()
          == DeclarationName::CXXConstructorName &&
          "Name must refer to a constructor");
-  return new (C, RD) CXXConstructorDecl(RD, StartLoc, NameInfo, T, TInfo,
+  return new (C, RD) CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo,
                                         isExplicit, isInline,
                                         isImplicitlyDeclared, isConstexpr);
 }
@@ -1830,9 +1833,9 @@ void CXXDestructorDecl::anchor() { }
 
 CXXDestructorDecl *
 CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) CXXDestructorDecl(
-      nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
-      false, false);
+  return new (C, ID)
+      CXXDestructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(),
+                        QualType(), nullptr, false, false);
 }
 
 CXXDestructorDecl *
@@ -1844,7 +1847,7 @@ CXXDestructorDecl::Create(ASTContext &C,
   assert(NameInfo.getName().getNameKind()
          == DeclarationName::CXXDestructorName &&
          "Name must refer to a destructor");
-  return new (C, RD) CXXDestructorDecl(RD, StartLoc, NameInfo, T, TInfo,
+  return new (C, RD) CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo,
                                        isInline, isImplicitlyDeclared);
 }
 
@@ -1852,7 +1855,7 @@ void CXXConversionDecl::anchor() { }
 
 CXXConversionDecl *
 CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) CXXConversionDecl(nullptr, SourceLocation(),
+  return new (C, ID) CXXConversionDecl(C, nullptr, SourceLocation(),
                                        DeclarationNameInfo(), QualType(),
                                        nullptr, false, false, false,
                                        SourceLocation());
@@ -1868,7 +1871,7 @@ CXXConversionDecl::Create(ASTContext &C,
   assert(NameInfo.getName().getNameKind()
          == DeclarationName::CXXConversionFunctionName &&
          "Name must refer to a conversion function");
-  return new (C, RD) CXXConversionDecl(RD, StartLoc, NameInfo, T, TInfo,
+  return new (C, RD) CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo,
                                        isInline, isExplicit, isConstexpr,
                                        EndLocation);
 }
@@ -1925,15 +1928,14 @@ NamespaceDecl *UsingDirectiveDecl::getNo
   return cast_or_null<NamespaceDecl>(NominatedNamespace);
 }
 
-NamespaceDecl::NamespaceDecl(DeclContext *DC, bool Inline, 
-                             SourceLocation StartLoc,
-                             SourceLocation IdLoc, IdentifierInfo *Id,
-                             NamespaceDecl *PrevDecl)
-  : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
-    LocStart(StartLoc), RBraceLoc(),
-    AnonOrFirstNamespaceAndInline(nullptr, Inline) {
+NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
+                             SourceLocation StartLoc, SourceLocation IdLoc,
+                             IdentifierInfo *Id, NamespaceDecl *PrevDecl)
+    : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
+      redeclarable_base(C), LocStart(StartLoc), RBraceLoc(),
+      AnonOrFirstNamespaceAndInline(nullptr, Inline) {
   setPreviousDecl(PrevDecl);
-  
+
   if (PrevDecl)
     AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace());
 }
@@ -1942,11 +1944,12 @@ NamespaceDecl *NamespaceDecl::Create(AST
                                      bool Inline, SourceLocation StartLoc,
                                      SourceLocation IdLoc, IdentifierInfo *Id,
                                      NamespaceDecl *PrevDecl) {
-  return new (C, DC) NamespaceDecl(DC, Inline, StartLoc, IdLoc, Id, PrevDecl);
+  return new (C, DC) NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id,
+                                   PrevDecl);
 }
 
 NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) NamespaceDecl(nullptr, false, SourceLocation(),
+  return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(),
                                    SourceLocation(), nullptr, nullptr);
 }
 
@@ -1987,8 +1990,8 @@ void UsingShadowDecl::anchor() { }
 
 UsingShadowDecl *
 UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) UsingShadowDecl(nullptr, SourceLocation(), nullptr,
-                                     nullptr);
+  return new (C, ID) UsingShadowDecl(C, nullptr, SourceLocation(),
+                                     nullptr, nullptr);
 }
 
 UsingDecl *UsingShadowDecl::getUsingDecl() const {

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri May 16 18:01:30 2014
@@ -1134,15 +1134,15 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Cr
                                              SourceLocation ClassLoc,
                                              bool isInternal){
   ObjCInterfaceDecl *Result = new (C, DC)
-      ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, PrevDecl, isInternal);
+      ObjCInterfaceDecl(C, DC, atLoc, Id, ClassLoc, PrevDecl, isInternal);
   Result->Data.setInt(!C.getLangOpts().Modules);
   C.getObjCInterfaceType(Result, PrevDecl);
   return Result;
 }
 
-ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C,
+ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
                                                          unsigned ID) {
-  ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(nullptr,
+  ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr,
                                                             SourceLocation(),
                                                             nullptr,
                                                             SourceLocation(),
@@ -1151,20 +1151,20 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Cr
   return Result;
 }
 
-ObjCInterfaceDecl::
-ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                  SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
-                  bool isInternal)
-  : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
-    TypeForDecl(nullptr), Data()
-{
+ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
+                                     SourceLocation AtLoc, IdentifierInfo *Id,
+                                     SourceLocation CLoc,
+                                     ObjCInterfaceDecl *PrevDecl,
+                                     bool IsInternal)
+    : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
+      redeclarable_base(C), TypeForDecl(nullptr), Data() {
   setPreviousDecl(PrevDecl);
   
   // Copy the 'data' pointer over.
   if (PrevDecl)
     Data = PrevDecl->Data;
   
-  setImplicit(isInternal);
+  setImplicit(IsInternal);
 }
 
 void ObjCInterfaceDecl::LoadExternalDefinition() const {
@@ -1487,12 +1487,12 @@ ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl
 
 void ObjCProtocolDecl::anchor() { }
 
-ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
-                                   SourceLocation nameLoc, 
+ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
+                                   IdentifierInfo *Id, SourceLocation nameLoc,
                                    SourceLocation atStartLoc,
                                    ObjCProtocolDecl *PrevDecl)
-  : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
-{
+    : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
+      redeclarable_base(C), Data() {
   setPreviousDecl(PrevDecl);
   if (PrevDecl)
     Data = PrevDecl->Data;
@@ -1504,7 +1504,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Crea
                                            SourceLocation atStartLoc,
                                            ObjCProtocolDecl *PrevDecl) {
   ObjCProtocolDecl *Result =
-      new (C, DC) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
+      new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
   Result->Data.setInt(!C.getLangOpts().Modules);
   return Result;
 }
@@ -1512,7 +1512,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Crea
 ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
                                                        unsigned ID) {
   ObjCProtocolDecl *Result =
-      new (C, ID) ObjCProtocolDecl(nullptr, nullptr, SourceLocation(),
+      new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
                                    SourceLocation(), nullptr);
   Result->Data.setInt(!C.getLangOpts().Modules);
   return Result;

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Fri May 16 18:01:30 2014
@@ -229,12 +229,12 @@ FunctionTemplateDecl *FunctionTemplateDe
                                                TemplateParameterList *Params,
                                                    NamedDecl *Decl) {
   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
-  return new (C, DC) FunctionTemplateDecl(DC, L, Name, Params, Decl);
+  return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
 }
 
 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
                                                                unsigned ID) {
-  return new (C, ID) FunctionTemplateDecl(nullptr, SourceLocation(),
+  return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
                                           DeclarationName(), nullptr, nullptr);
 }
 
@@ -307,15 +307,16 @@ ClassTemplateDecl *ClassTemplateDecl::Cr
                                              NamedDecl *Decl,
                                              ClassTemplateDecl *PrevDecl) {
   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
-  ClassTemplateDecl *New =
-      new (C, DC) ClassTemplateDecl(DC, L, Name, Params, Decl);
+  ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
+                                                         Params, Decl);
   New->setPreviousDecl(PrevDecl);
   return New;
 }
 
-ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 
+ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
                                                          unsigned ID) {
-  return new (C, ID) ClassTemplateDecl(EmptyShell());
+  return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
+                                       DeclarationName(), nullptr, nullptr);
 }
 
 void ClassTemplateDecl::LoadLazySpecializations() const {
@@ -695,7 +696,7 @@ ClassTemplateSpecializationDecl(ASTConte
                                 const TemplateArgument *Args,
                                 unsigned NumArgs,
                                 ClassTemplateSpecializationDecl *PrevDecl)
-  : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
+  : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
                   SpecializedTemplate->getIdentifier(),
                   PrevDecl),
     SpecializedTemplate(SpecializedTemplate),
@@ -704,12 +705,11 @@ ClassTemplateSpecializationDecl(ASTConte
     SpecializationKind(TSK_Undeclared) {
 }
 
-ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
-  : CXXRecordDecl(DK, TTK_Struct, nullptr, SourceLocation(), SourceLocation(),
-                  nullptr, nullptr),
-    ExplicitInfo(nullptr),
-    SpecializationKind(TSK_Undeclared) {
-}
+ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
+                                                                 Kind DK)
+    : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
+                    SourceLocation(), nullptr, nullptr),
+      ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
 
 ClassTemplateSpecializationDecl *
 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
@@ -734,7 +734,7 @@ ClassTemplateSpecializationDecl *
 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
                                                     unsigned ID) {
   ClassTemplateSpecializationDecl *Result =
-    new (C, ID) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
+    new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
   Result->MayHaveOutOfDateDef = false;
   return Result;
 }
@@ -851,7 +851,7 @@ ClassTemplatePartialSpecializationDecl *
 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
                                                            unsigned ID) {
   ClassTemplatePartialSpecializationDecl *Result =
-      new (C, ID) ClassTemplatePartialSpecializationDecl();
+      new (C, ID) ClassTemplatePartialSpecializationDecl(C);
   Result->MayHaveOutOfDateDef = false;
   return Result;
 }
@@ -889,12 +889,12 @@ TypeAliasTemplateDecl *TypeAliasTemplate
                                                   TemplateParameterList *Params,
                                                      NamedDecl *Decl) {
   AdoptTemplateParameterList(Params, DC);
-  return new (C, DC) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
+  return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
 }
 
 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
                                                                  unsigned ID) {
-  return new (C, ID) TypeAliasTemplateDecl(nullptr, SourceLocation(),
+  return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
                                            DeclarationName(), nullptr, nullptr);
 }
 
@@ -943,12 +943,13 @@ VarTemplateDecl *VarTemplateDecl::Create
                                          SourceLocation L, DeclarationName Name,
                                          TemplateParameterList *Params,
                                          VarDecl *Decl) {
-  return new (C, DC) VarTemplateDecl(DC, L, Name, Params, Decl);
+  return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
 }
 
 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
                                                      unsigned ID) {
-  return new (C, ID) VarTemplateDecl(EmptyShell());
+  return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
+                                     DeclarationName(), nullptr, nullptr);
 }
 
 // TODO: Unify across class, function and variable templates?
@@ -1057,18 +1058,19 @@ VarTemplateDecl::findPartialSpecInstanti
 // VarTemplateSpecializationDecl Implementation
 //===----------------------------------------------------------------------===//
 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
-    ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc,
+    Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
     unsigned NumArgs)
-    : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T,
-              TInfo, S),
+    : VarDecl(DK, Context, DC, StartLoc, IdLoc,
+              SpecializedTemplate->getIdentifier(), T, TInfo, S),
       SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
       SpecializationKind(TSK_Undeclared) {}
 
-VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
-    : VarDecl(DK, nullptr, SourceLocation(), SourceLocation(), nullptr,
+VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
+                                                             ASTContext &C)
+    : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
               QualType(), nullptr, SC_None),
       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
 
@@ -1078,13 +1080,14 @@ VarTemplateSpecializationDecl *VarTempla
     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
     unsigned NumArgs) {
   return new (Context, DC) VarTemplateSpecializationDecl(
-      Context, VarTemplateSpecialization, DC, StartLoc, IdLoc,
+      VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
       SpecializedTemplate, T, TInfo, S, Args, NumArgs);
 }
 
 VarTemplateSpecializationDecl *
 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization);
+  return new (C, ID)
+      VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
 }
 
 void VarTemplateSpecializationDecl::getNameForDiagnostic(
@@ -1123,7 +1126,7 @@ VarTemplatePartialSpecializationDecl::Va
     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
     const ASTTemplateArgumentListInfo *ArgInfos)
-    : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
+    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
                                     TInfo, S, Args, NumArgs),
       TemplateParams(Params), ArgsAsWritten(ArgInfos),
@@ -1153,5 +1156,5 @@ VarTemplatePartialSpecializationDecl::Cr
 VarTemplatePartialSpecializationDecl *
 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
                                                          unsigned ID) {
-  return new (C, ID) VarTemplatePartialSpecializationDecl();
+  return new (C, ID) VarTemplatePartialSpecializationDecl(C);
 }

Modified: cfe/trunk/lib/AST/ExternalASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExternalASTSource.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExternalASTSource.cpp (original)
+++ cfe/trunk/lib/AST/ExternalASTSource.cpp Fri May 16 18:01:30 2014
@@ -14,7 +14,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclarationName.h"
+#include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
 
@@ -60,3 +62,21 @@ ExternalASTSource::FindExternalLexicalDe
 }
 
 void ExternalASTSource::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { }
+
+uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) {
+  uint32_t OldGeneration = CurrentGeneration;
+
+  // Make sure the generation of the topmost external source for the context is
+  // incremented. That might not be us.
+  auto *P = C.getExternalSource();
+  if (P && P != this)
+    CurrentGeneration = P->incrementGeneration(C);
+  else {
+    // FIXME: Only bump the generation counter if the current generation number
+    // has been observed?
+    if (!++CurrentGeneration)
+      llvm::report_fatal_error("generation counter overflowed", false);
+  }
+
+  return OldGeneration;
+}

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Fri May 16 18:01:30 2014
@@ -841,8 +841,8 @@ llvm::Value *CodeGenFunction::EmitBlockL
     } else {
       // Fake up a new variable so that EmitScalarInit doesn't think
       // we're referring to the variable in its own initializer.
-      ImplicitParamDecl blockFieldPseudoVar(/*DC*/ 0, SourceLocation(),
-                                            /*name*/ 0, type);
+      ImplicitParamDecl blockFieldPseudoVar(getContext(), /*DC*/ 0,
+                                            SourceLocation(), /*name*/ 0, type);
 
       // We use one of these or the other depending on whether the
       // reference is nested.
@@ -1108,7 +1108,7 @@ CodeGenFunction::GenerateBlockFunction(G
   QualType selfTy = getContext().VoidPtrTy;
   IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
 
-  ImplicitParamDecl selfDecl(const_cast<BlockDecl*>(blockDecl),
+  ImplicitParamDecl selfDecl(getContext(), const_cast<BlockDecl*>(blockDecl),
                              SourceLocation(), II, selfTy);
   args.push_back(&selfDecl);
 
@@ -1279,9 +1279,9 @@ CodeGenFunction::GenerateCopyHelperFunct
   ASTContext &C = getContext();
 
   FunctionArgList args;
-  ImplicitParamDecl dstDecl(0, SourceLocation(), 0, C.VoidPtrTy);
+  ImplicitParamDecl dstDecl(getContext(), 0, SourceLocation(), 0, C.VoidPtrTy);
   args.push_back(&dstDecl);
-  ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy);
+  ImplicitParamDecl srcDecl(getContext(), 0, SourceLocation(), 0, C.VoidPtrTy);
   args.push_back(&srcDecl);
 
   const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
@@ -1453,7 +1453,7 @@ CodeGenFunction::GenerateDestroyHelperFu
   ASTContext &C = getContext();
 
   FunctionArgList args;
-  ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy);
+  ImplicitParamDecl srcDecl(getContext(), 0, SourceLocation(), 0, C.VoidPtrTy);
   args.push_back(&srcDecl);
 
   const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
@@ -1738,10 +1738,12 @@ generateByrefCopyHelper(CodeGenFunction
   QualType R = Context.VoidTy;
 
   FunctionArgList args;
-  ImplicitParamDecl dst(0, SourceLocation(), 0, Context.VoidPtrTy);
+  ImplicitParamDecl dst(CGF.getContext(), 0, SourceLocation(), 0,
+                        Context.VoidPtrTy);
   args.push_back(&dst);
 
-  ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy);
+  ImplicitParamDecl src(CGF.getContext(), 0, SourceLocation(), 0,
+                        Context.VoidPtrTy);
   args.push_back(&src);
 
   const CGFunctionInfo &FI = CGF.CGM.getTypes().arrangeFreeFunctionDeclaration(
@@ -1810,7 +1812,8 @@ generateByrefDisposeHelper(CodeGenFuncti
   QualType R = Context.VoidTy;
 
   FunctionArgList args;
-  ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy);
+  ImplicitParamDecl src(CGF.getContext(), 0, SourceLocation(), 0,
+                        Context.VoidPtrTy);
   args.push_back(&src);
 
   const CGFunctionInfo &FI = CGF.CGM.getTypes().arrangeFreeFunctionDeclaration(

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Fri May 16 18:01:30 2014
@@ -522,7 +522,8 @@ llvm::Function *CodeGenFunction::generat
     llvm::Constant *addr, QualType type, Destroyer *destroyer,
     bool useEHCleanupForArray, const VarDecl *VD) {
   FunctionArgList args;
-  ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy);
+  ImplicitParamDecl dst(getContext(), 0, SourceLocation(), 0,
+                        getContext().VoidPtrTy);
   args.push_back(&dst);
 
   const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Fri May 16 18:01:30 2014
@@ -2901,9 +2901,9 @@ CodeGenFunction::GenerateObjCAtomicSette
   SrcTy = C.getPointerType(SrcTy);
   
   FunctionArgList args;
-  ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
+  ImplicitParamDecl dstDecl(getContext(), FD, SourceLocation(), 0, DestTy);
   args.push_back(&dstDecl);
-  ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
+  ImplicitParamDecl srcDecl(getContext(), FD, SourceLocation(), 0, SrcTy);
   args.push_back(&srcDecl);
 
   const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
@@ -2980,9 +2980,9 @@ CodeGenFunction::GenerateObjCAtomicGette
   SrcTy = C.getPointerType(SrcTy);
   
   FunctionArgList args;
-  ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
+  ImplicitParamDecl dstDecl(getContext(), FD, SourceLocation(), 0, DestTy);
   args.push_back(&dstDecl);
-  ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
+  ImplicitParamDecl srcDecl(getContext(), FD, SourceLocation(), 0, SrcTy);
   args.push_back(&srcDecl);
 
   const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(

Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp Fri May 16 18:01:30 2014
@@ -358,8 +358,21 @@ bool FrontendAction::BeginSourceFile(Com
   // source.
   if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
     Preprocessor &PP = CI.getPreprocessor();
+
+    // If modules are enabled, create the module manager before creating
+    // any builtins, so that all declarations know that they might be
+    // extended by an external source.
+    if (CI.getLangOpts().Modules)
+      CI.createModuleManager();
+
     PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                            PP.getLangOpts());
+  } else {
+    // FIXME: If this is a problem, recover from it by creating a multiplex
+    // source.
+    assert((!CI.getLangOpts().Modules || CI.getModuleManager()) &&
+           "modules enabled but created an external source that "
+           "doesn't support modules");
   }
 
   // If there is a layout overrides file, attach an external AST source that
@@ -371,7 +384,7 @@ bool FrontendAction::BeginSourceFile(Com
                      CI.getFrontendOpts().OverrideRecordLayoutsFile));
     CI.getASTContext().setExternalSource(Override);
   }
-  
+
   return true;
 
   // If we failed, reset state since the client will not end up calling the

Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original)
+++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Fri May 16 18:01:30 2014
@@ -49,6 +49,11 @@ Decl *MultiplexExternalSemaSource::GetEx
   return 0;
 }
 
+void MultiplexExternalSemaSource::CompleteRedeclChain(const Decl *D) {
+  for (size_t i = 0; i < Sources.size(); ++i)
+    Sources[i]->CompleteRedeclChain(D);
+}
+
 Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) {
   Selector Sel;
   for(size_t i = 0; i < Sources.size(); ++i) {

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri May 16 18:01:30 2014
@@ -1707,7 +1707,7 @@ void ASTReader::markIdentifierUpToDate(I
 
   // Update the generation for this identifier.
   if (getContext().getLangOpts().Modules)
-    IdentifierGeneration[II] = CurrentGeneration;
+    IdentifierGeneration[II] = getGeneration();
 }
 
 struct ASTReader::ModuleMacroInfo {
@@ -3435,7 +3435,7 @@ ASTReader::ASTReadResult ASTReader::Read
   Deserializing AnASTFile(this);
 
   // Bump the generation number.
-  unsigned PreviousGeneration = CurrentGeneration++;
+  unsigned PreviousGeneration = incrementGeneration(Context);
 
   unsigned NumModules = ModuleMgr.size();
   SmallVector<ImportedModule, 4> Loaded;
@@ -3615,7 +3615,7 @@ ASTReader::ReadASTCore(StringRef FileNam
   std::string ErrorStr;
   ModuleManager::AddModuleResult AddResult
     = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy,
-                          CurrentGeneration, ExpectedSize, ExpectedModTime,
+                          getGeneration(), ExpectedSize, ExpectedModTime,
                           M, ErrorStr);
 
   switch (AddResult) {
@@ -5939,6 +5939,37 @@ Decl *ASTReader::GetExternalDecl(uint32_
   return GetDecl(ID);
 }
 
+void ASTReader::CompleteRedeclChain(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
+
+  // Recursively ensure that the decl context itself is complete
+  // (in particular, this matters if the decl context is a namespace).
+  //
+  // FIXME: This should be performed by lookup instead of here.
+  cast<Decl>(DC)->getMostRecentDecl();
+
+  // If this is a named declaration, complete it by looking it up
+  // within its context.
+  //
+  // FIXME: We don't currently handle the cases where we can't do this;
+  // merging a class definition that contains unnamed entities should merge
+  // those entities. Likewise, merging a function definition should merge
+  // all mergeable entities within it.
+  if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) ||
+      isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) {
+    if (DeclarationName Name = cast<NamedDecl>(D)->getDeclName()) {
+      auto *II = Name.getAsIdentifierInfo();
+      if (isa<TranslationUnitDecl>(DC) && II) {
+        // Outside of C++, we don't have a lookup table for the TU, so update
+        // the identifier instead. In C++, either way should work fine.
+        if (II->isOutOfDate())
+          updateOutOfDateIdentifier(*II);
+      } else
+        DC->lookup(Name);
+    }
+  }
+}
+
 uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M,
                                           const RecordData &Record,
                                           unsigned &Idx) {
@@ -6926,7 +6957,7 @@ void ASTReader::ReadMethodPool(Selector
   // Get the selector generation and update it to the current generation.
   unsigned &Generation = SelectorGeneration[Sel];
   unsigned PriorGeneration = Generation;
-  Generation = CurrentGeneration;
+  Generation = getGeneration();
   
   // Search for methods defined with this selector.
   ++NumMethodPoolLookups;
@@ -8114,7 +8145,6 @@ void ASTReader::finishPendingActions() {
       if (auto RD = dyn_cast<CXXRecordDecl>(*D)) {
         for (auto R : RD->redecls())
           cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData;
-        
       }
 
       continue;
@@ -8250,7 +8280,7 @@ ASTReader::ASTReader(Preprocessor &PP, A
       AllowConfigurationMismatch(AllowConfigurationMismatch),
       ValidateSystemInputs(ValidateSystemInputs),
       UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
-      CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts),
+      CurrSwitchCaseStmts(&SwitchCaseStmts),
       NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0),
       TotalNumStatements(0), NumMacrosRead(0), TotalNumMacros(0),
       NumIdentifierLookups(0), NumIdentifierLookupHits(0), NumSelectorsRead(0),

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri May 16 18:01:30 2014
@@ -1289,8 +1289,9 @@ void ASTDeclReader::ReadCXXDefinitionDat
 
 void ASTDeclReader::MergeDefinitionData(
     CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &MergeDD) {
-  assert(D->DefinitionData && "merging class definition into non-definition");
-  auto &DD = *D->DefinitionData;
+  assert(D->DefinitionData.getNotUpdated() &&
+         "merging class definition into non-definition");
+  auto &DD = *D->DefinitionData.getNotUpdated();
 
   // If the new definition has new special members, let the name lookup
   // code know that it needs to look in the new definition too.
@@ -1390,7 +1391,7 @@ void ASTDeclReader::ReadCXXRecordDefinit
 
   // If we're reading an update record, we might already have a definition for
   // this record. If so, just merge into it.
-  if (D->DefinitionData) {
+  if (D->DefinitionData.getNotUpdated()) {
     MergeDefinitionData(D, *DD);
     return;
   }
@@ -1399,25 +1400,26 @@ void ASTDeclReader::ReadCXXRecordDefinit
   // that all other deserialized declarations will see it.
   CXXRecordDecl *Canon = D->getCanonicalDecl();
   if (Canon == D) {
-    D->DefinitionData = DD;
+    D->DefinitionData.setNotUpdated(DD);
     D->IsCompleteDefinition = true;
-  } else if (!Canon->DefinitionData) {
-    Canon->DefinitionData = D->DefinitionData = DD;
-    D->IsCompleteDefinition = true;
-
-    // Note that we have deserialized a definition. Any declarations
-    // deserialized before this one will be be given the DefinitionData
-    // pointer at the end.
-    Reader.PendingDefinitions.insert(D);
-  } else {
+  } else if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) {
     // We have already deserialized a definition of this record. This
     // definition is no longer really a definition. Note that the pre-existing
     // definition is the *real* definition.
     Reader.MergedDeclContexts.insert(
-        std::make_pair(D, Canon->DefinitionData->Definition));
-    D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
+        std::make_pair(D, CanonDD->Definition));
+    D->DefinitionData = Canon->DefinitionData;
     D->IsCompleteDefinition = false;
     MergeDefinitionData(D, *DD);
+  } else {
+    Canon->DefinitionData.setNotUpdated(DD);
+    D->DefinitionData = Canon->DefinitionData;
+    D->IsCompleteDefinition = true;
+
+    // Note that we have deserialized a definition. Any declarations
+    // deserialized before this one will be be given the DefinitionData
+    // pointer at the end.
+    Reader.PendingDefinitions.insert(D);
   }
 }
 
@@ -1741,16 +1743,16 @@ ASTDeclReader::VisitClassTemplateSpecial
 
         // This declaration might be a definition. Merge with any existing
         // definition.
-        if (D->DefinitionData) {
-          if (!CanonSpec->DefinitionData) {
-            CanonSpec->DefinitionData = D->DefinitionData;
-          } else {
-            MergeDefinitionData(CanonSpec, *D->DefinitionData);
+        if (auto *DDD = D->DefinitionData.getNotUpdated()) {
+          if (auto *CanonDD = CanonSpec->DefinitionData.getNotUpdated()) {
+            MergeDefinitionData(CanonSpec, *DDD);
             Reader.PendingDefinitions.erase(D);
             Reader.MergedDeclContexts.insert(
-                std::make_pair(D, CanonSpec->DefinitionData->Definition));
+                std::make_pair(D, CanonDD->Definition));
             D->IsCompleteDefinition = false;
             D->DefinitionData = CanonSpec->DefinitionData;
+          } else {
+            CanonSpec->DefinitionData = D->DefinitionData;
           }
         }
       }
@@ -2459,7 +2461,7 @@ ASTDeclReader::FindExistingResult ASTDec
 template<typename DeclT>
 void ASTDeclReader::attachPreviousDeclImpl(Redeclarable<DeclT> *D,
                                            Decl *Previous) {
-  D->RedeclLink.setNext(cast<DeclT>(Previous));
+  D->RedeclLink.setPrevious(cast<DeclT>(Previous));
 }
 void ASTDeclReader::attachPreviousDeclImpl(...) {
   llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
@@ -2489,7 +2491,7 @@ void ASTDeclReader::attachPreviousDecl(D
 
 template<typename DeclT>
 void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) {
-  D->RedeclLink = Redeclarable<DeclT>::LatestDeclLink(cast<DeclT>(Latest));
+  D->RedeclLink.setLatest(cast<DeclT>(Latest));
 }
 void ASTDeclReader::attachLatestDeclImpl(...) {
   llvm_unreachable("attachLatestDecl on non-redeclarable declaration");
@@ -2500,8 +2502,8 @@ void ASTDeclReader::attachLatestDecl(Dec
 
   switch (D->getKind()) {
 #define ABSTRACT_DECL(TYPE)
-#define DECL(TYPE, BASE)                               \
-  case Decl::TYPE:                                     \
+#define DECL(TYPE, BASE)                                  \
+  case Decl::TYPE:                                        \
     attachLatestDeclImpl(cast<TYPE##Decl>(D), Latest); \
     break;
 #include "clang/AST/DeclNodes.inc"

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri May 16 18:01:30 2014
@@ -5301,8 +5301,7 @@ void ASTWriter::AddCXXCtorInitializers(
 }
 
 void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) {
-  assert(D->DefinitionData);
-  struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
+  auto &Data = D->data();
   Record.push_back(Data.IsLambda);
   Record.push_back(Data.UserDeclaredConstructor);
   Record.push_back(Data.UserDeclaredSpecialMembers);
@@ -5361,7 +5360,7 @@ void ASTWriter::AddCXXDefinitionData(con
   
   // Add lambda-specific data.
   if (Data.IsLambda) {
-    CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData();
+    auto &Lambda = D->getLambdaData();
     Record.push_back(Lambda.Dependent);
     Record.push_back(Lambda.IsGenericLambda);
     Record.push_back(Lambda.CaptureDefault);

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Fri May 16 18:01:30 2014
@@ -69,6 +69,8 @@ module redeclarations_left { header "red
 module redeclarations_right { header "redeclarations_right.h" }
 module redecl_namespaces_left { header "redecl_namespaces_left.h" }
 module redecl_namespaces_right { header "redecl_namespaces_right.h" }
+module redecl_add_after_load_top { header "redecl-add-after-load-top.h" }
+module redecl_add_after_load { header "redecl-add-after-load.h" }
 module load_failure { header "load_failure.h" }
 
 module decldef {

Added: cfe/trunk/test/Modules/Inputs/redecl-add-after-load.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/redecl-add-after-load.h?rev=209046&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/redecl-add-after-load.h (added)
+++ cfe/trunk/test/Modules/Inputs/redecl-add-after-load.h Fri May 16 18:01:30 2014
@@ -0,0 +1,23 @@
+struct A {};
+extern const int variable = 0;
+extern constexpr int function() { return 0; }
+
+namespace N {
+  struct A {};
+  extern const int variable = 0;
+  extern constexpr int function() { return 0; }
+}
+
+ at import redecl_add_after_load_top;
+struct C::A {};
+const int C::variable = 0;
+constexpr int C::function() { return 0; }
+
+struct D {
+  struct A;
+  static const int variable;
+  static constexpr int function();
+};
+struct D::A {};
+const int D::variable = 0;
+constexpr int D::function() { return 0; }

Modified: cfe/trunk/test/Modules/decldef.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/decldef.mm?rev=209046&r1=209045&r2=209046&view=diff
==============================================================================
--- cfe/trunk/test/Modules/decldef.mm (original)
+++ cfe/trunk/test/Modules/decldef.mm Fri May 16 18:01:30 2014
@@ -1,14 +1,18 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY
-// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify
-
-// expected-note at Inputs/def.h:5 {{previous}}
+// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_1 -DUSE_2 -DUSE_3 -DUSE_4
+// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_2 -DUSE_3 -DUSE_4
+// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_3 -DUSE_4
+// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_4
+
+// expected-note at Inputs/def.h:5 0-1{{previous}}
+// expected-note at Inputs/def.h:16 0-1{{previous}}
+// expected-note at Inputs/def-include.h:11 0-1{{previous}}
 
 @class Def;
 Def *def;
-class Def2; // expected-note {{forward decl}}
+class Def2; // expected-note 0-1{{forward decl}}
 Def2 *def2;
-namespace Def3NS { class Def3; } // expected-note {{forward decl}}
+namespace Def3NS { class Def3; } // expected-note 0-1{{forward decl}}
 Def3NS::Def3 *def3;
 
 @interface Unrelated
@@ -16,9 +20,10 @@ Def3NS::Def3 *def3;
 @end
 
 @import decldef;
-#ifdef USE_EARLY
+#ifdef USE_1
 A *a1; // expected-error{{declaration of 'A' must be imported from module 'decldef.Def'}}
 B *b1;
+#define USED
 #endif
 @import decldef.Decl;
 
@@ -26,14 +31,23 @@ A *a2;
 B *b;
 
 void testA(A *a) {
+#ifdef USE_2
   a->ivar = 17;
-#ifndef USE_EARLY
+  #ifndef USED
   // expected-error at -2{{definition of 'A' must be imported from module 'decldef.Def' before it is required}}
+  #define USED
+  #endif
 #endif
 }
 
 void testB() {
-  B b; // Note: redundant error silenced
+#ifdef USE_3
+  B b;
+  #ifndef USED
+  // expected-error at -2{{definition of 'B' must be imported from module 'decldef.Def' before it is required}}
+  #define USED
+  #endif
+#endif
 }
 
 void testDef() {
@@ -41,9 +55,12 @@ void testDef() {
 }
 
 void testDef2() {
-  // FIXME: These should both work, since we've (implicitly) imported
-  // decldef.Def here, but they don't, because nothing has triggered the lazy
-  // loading of the definitions of these classes.
-  def2->func(); // expected-error {{incomplete}}
-  def3->func(); // expected-error {{incomplete}}
+#ifdef USE_4
+  def2->func();
+  def3->func();
+  #ifndef USED
+  // expected-error at -3 {{definition of 'Def2' must be imported}}
+  #define USED
+  #endif
+#endif
 }

Added: cfe/trunk/test/Modules/redecl-add-after-load.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecl-add-after-load.cpp?rev=209046&view=auto
==============================================================================
--- cfe/trunk/test/Modules/redecl-add-after-load.cpp (added)
+++ cfe/trunk/test/Modules/redecl-add-after-load.cpp Fri May 16 18:01:30 2014
@@ -0,0 +1,48 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
+
+typedef struct A B;
+extern const int variable;
+extern constexpr int function();
+constexpr int test(bool b) { return b ? variable : function(); }
+
+namespace N {
+  typedef struct A B;
+  extern const int variable;
+  extern constexpr int function();
+}
+typedef N::B NB;
+constexpr int N_test(bool b) { return b ? N::variable : N::function(); }
+
+ at import redecl_add_after_load_top;
+typedef C::A CB;
+constexpr int C_test(bool b) { return b ? C::variable : C::function(); }
+
+struct D {
+  struct A; // expected-note {{forward}}
+  static const int variable;
+  static constexpr int function(); // expected-note {{here}}
+};
+typedef D::A DB;
+constexpr int D_test(bool b) { return b ? D::variable : D::function(); } // expected-note {{subexpression}} expected-note {{undefined}}
+
+ at import redecl_add_after_load;
+
+B tu_struct_test;
+constexpr int tu_variable_test = test(true);
+constexpr int tu_function_test = test(false);
+
+NB ns_struct_test;
+constexpr int ns_variable_test = N_test(true);
+constexpr int ns_function_test = N_test(false);
+
+CB struct_struct_test;
+constexpr int struct_variable_test = C_test(true);
+constexpr int struct_function_test = C_test(false);
+
+// FIXME: We should accept this, but we're currently too lazy when merging class
+// definitions to determine that the definitions in redecl_add_after_load are
+// definitions of these entities.
+DB merged_struct_struct_test; // expected-error {{incomplete}}
+constexpr int merged_struct_variable_test = D_test(true); // expected-error {{constant}} expected-note {{in call to}}
+constexpr int merged_struct_function_test = D_test(false); // expected-error {{constant}} expected-note {{in call to}}





More information about the cfe-commits mailing list