[cfe-commits] r103301 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclBase.h include/clang/AST/DeclCXX.h include/clang/Frontend/PCHBitCodes.h include/clang/Frontend/PCHReader.h include/clang/Frontend/PCHWriter.h lib/AST/DeclCXX.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriter.cpp lib/Frontend/PCHWriterDecl.cpp test/PCH/Inputs/namespaces.h test/PCH/namespaces.cpp test/SemaCXX/namespace-alias.cpp

Chris Lattner sabre at nondot.org
Fri May 7 14:43:38 PDT 2010


Author: lattner
Date: Fri May  7 16:43:38 2010
New Revision: 103301

URL: http://llvm.org/viewvc/llvm-project?rev=103301&view=rev
Log:
add PCH support for a bunch of C++ Decls, patch by
Andrew Sutton!

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/include/clang/Frontend/PCHReader.h
    cfe/trunk/include/clang/Frontend/PCHWriter.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
    cfe/trunk/test/PCH/Inputs/namespaces.h
    cfe/trunk/test/PCH/namespaces.cpp
    cfe/trunk/test/SemaCXX/namespace-alias.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri May  7 16:43:38 2010
@@ -267,18 +267,25 @@
   // \brief Returns true if this is an anonymous namespace declaration.
   //
   // For example:
+  /// \code
   //   namespace {
   //     ...
   //   };
+  // \endcode
   // q.v. C++ [namespace.unnamed]
   bool isAnonymousNamespace() const {
     return !getIdentifier();
   }
 
+  /// \brief Return the next extended namespace declaration or null if this
+  /// is none.
   NamespaceDecl *getNextNamespace() { return NextNamespace; }
   const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
+
+  /// \brief Set the next extended namespace declaration.
   void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
 
+  /// \brief Get the original (first) namespace declaration.
   NamespaceDecl *getOriginalNamespace() const {
     if (OrigOrAnonNamespace.getInt())
       return const_cast<NamespaceDecl *>(this);
@@ -286,6 +293,14 @@
     return OrigOrAnonNamespace.getPointer();
   }
 
+  /// \brief Return true if this declaration is an original (first) declaration
+  /// of the namespace. This is false for non-original (subsequent) namespace
+  /// declarations and anonymous namespaces.
+  bool isOriginalNamespace() const {
+    return getOriginalNamespace() == this;
+  }
+
+  /// \brief Set the original (first) namespace declaration.
   void setOriginalNamespace(NamespaceDecl *ND) { 
     if (ND != this) {
       OrigOrAnonNamespace.setPointer(ND);

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri May  7 16:43:38 2010
@@ -76,6 +76,11 @@
 #include "clang/AST/DeclNodes.def"
   };
 
+  /// \brief A placeholder type used to construct an empty shell of a
+  /// decl-derived type that will be filled in later (e.g., by some
+  /// deserialization method).
+  struct EmptyShell { };
+
   /// IdentifierNamespace - The different namespaces in which
   /// declarations may appear.  According to C99 6.2.3, there are
   /// four namespaces, labels, tags, members and ordinary

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri May  7 16:43:38 2010
@@ -1244,6 +1244,7 @@
   virtual void Destroy(ASTContext& C);
 
 public:
+  static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
   static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
                                     SourceLocation L, DeclarationName N,
                                     QualType T, TypeSourceInfo *TInfo,
@@ -1386,6 +1387,7 @@
   }
 
 public:
+  static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
   static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
                                    SourceLocation L, DeclarationName N,
                                    QualType T, bool isInline,
@@ -1441,6 +1443,7 @@
       IsExplicitSpecified(isExplicitSpecified) { }
 
 public:
+  static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
   static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
                                    SourceLocation L, DeclarationName N,
                                    QualType T, TypeSourceInfo *TInfo,
@@ -1481,8 +1484,10 @@
   /// ASTs and cannot be changed without altering that abi.  To help
   /// ensure a stable abi for this, we choose the DW_LANG_ encodings
   /// from the dwarf standard.
-  enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002,
-  lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 };
+  enum LanguageIDs {
+    lang_c = /* DW_LANG_C */ 0x0002,
+    lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
+  };
 private:
   /// Language - The language for this linkage specification.
   LanguageIDs Language;
@@ -1500,12 +1505,20 @@
                                  SourceLocation L, LanguageIDs Lang,
                                  bool Braces);
 
+  /// \brief Return the language specified by this linkage specification.
   LanguageIDs getLanguage() const { return Language; }
 
-  /// hasBraces - Determines whether this linkage specification had
-  /// braces in its syntactic form.
+  /// \brief Set the language specified by this linkage specification.
+  void setLanguage(LanguageIDs L) { Language = L; }
+
+  /// \brief Determines whether this linkage specification had braces in
+  /// its syntactic form.
   bool hasBraces() const { return HadBraces; }
 
+  /// \brief Set whether this linkage specification has braces in its
+  /// syntactic form.
+  void setHasBraces(bool B) { HadBraces = B; }
+
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const LinkageSpecDecl *D) { return true; }
   static bool classofKind(Kind K) { return K == LinkageSpec; }
@@ -1571,13 +1584,21 @@
 
 public:
   /// \brief Retrieve the source range of the nested-name-specifier
-  /// that qualifiers the namespace name.
+  /// that qualifies the namespace name.
   SourceRange getQualifierRange() const { return QualifierRange; }
 
+  /// \brief Set the source range of the nested-name-specifier that
+  /// qualifies the namespace name.
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
+
   /// \brief Retrieve the nested-name-specifier that qualifies the
   /// name of the namespace.
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
 
+  /// \brief Set the nested-name-specifier that qualifes the name of the
+  /// namespace.
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+
   NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
   const NamedDecl *getNominatedNamespaceAsWritten() const {
     return NominatedNamespace;
@@ -1590,17 +1611,32 @@
     return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
   }
 
-  /// getCommonAncestor - returns common ancestor context of using-directive,
-  /// and nominated by it namespace.
+  /// setNominatedNamespace - Set the namespace nominataed by the
+  /// using-directive.
+  void setNominatedNamespace(NamedDecl* NS);
+
+  /// \brief Returns the common ancestor context of this using-directive and
+  /// its nominated namespace.
   DeclContext *getCommonAncestor() { return CommonAncestor; }
   const DeclContext *getCommonAncestor() const { return CommonAncestor; }
 
+  /// \brief Set the common ancestor context of this using-directive and its
+  /// nominated namespace.
+  void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; }
+
+  // FIXME: Could omit 'Key' in name.
   /// getNamespaceKeyLocation - Returns location of namespace keyword.
   SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
 
+  /// setNamespaceKeyLocation - Set the the location of the namespacekeyword.
+  void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; }
+
   /// getIdentLocation - Returns location of identifier.
   SourceLocation getIdentLocation() const { return IdentLoc; }
 
+  /// setIdentLocation - set the location of the identifier.
+  void setIdentLocation(SourceLocation L) { IdentLoc = L; }
+
   static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
                                     SourceLocation L,
                                     SourceLocation NamespaceLoc,
@@ -1634,7 +1670,7 @@
   /// name, if any.
   NestedNameSpecifier *Qualifier;
 
-  /// IdentLoc - Location of namespace identifier.
+  /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
   SourceLocation IdentLoc;
 
   /// Namespace - The Decl that this alias points to. Can either be a
@@ -1655,10 +1691,19 @@
   /// that qualifiers the namespace name.
   SourceRange getQualifierRange() const { return QualifierRange; }
 
+  /// \brief Set the source range of the nested-name-specifier that qualifies
+  /// the namespace name.
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
+
   /// \brief Retrieve the nested-name-specifier that qualifies the
   /// name of the namespace.
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
 
+  /// \brief Set the nested-name-specifier that qualifies the name of the
+  /// namespace.
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
+
+  /// \brief Retrieve the namespace declaration aliased by this directive.
   NamespaceDecl *getNamespace() {
     if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
       return AD->getNamespace();
@@ -1674,16 +1719,31 @@
   /// "namespace foo = ns::bar;".
   SourceLocation getAliasLoc() const { return AliasLoc; }
 
+  /// Set the location o;f the alias name, e.e., 'foo' in
+  /// "namespace foo = ns::bar;".
+  void setAliasLoc(SourceLocation L) { AliasLoc = L; }
+
   /// Returns the location of the 'namespace' keyword.
   SourceLocation getNamespaceLoc() const { return getLocation(); }
 
   /// Returns the location of the identifier in the named namespace.
   SourceLocation getTargetNameLoc() const { return IdentLoc; }
 
+  /// Set the location of the identifier in the named namespace.
+  void setTargetNameLoc(SourceLocation L) { IdentLoc = L; }
+
   /// \brief Retrieve the namespace that this alias refers to, which
   /// may either be a NamespaceDecl or a NamespaceAliasDecl.
   NamedDecl *getAliasedNamespace() const { return Namespace; }
 
+  /// \brief Set the namespace or namespace alias pointed to by this
+  /// alias decl.
+  void setAliasedNamespace(NamedDecl *ND) {
+    assert((isa<NamespaceAliasDecl>(ND) || isa<NamespaceDecl>(ND)) &&
+      "expecting namespace or namespace alias decl");
+      Namespace = ND;
+  }
+
   static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
                                     SourceLocation L, SourceLocation AliasLoc,
                                     IdentifierInfo *Alias,
@@ -1730,16 +1790,20 @@
     return new (C) UsingShadowDecl(DC, Loc, Using, Target);
   }
 
-  /// Gets the underlying declaration which has been brought into the
+  /// \brief Gets the underlying declaration which has been brought into the
   /// local scope.
-  NamedDecl *getTargetDecl() const {
-    return Underlying;
-  }
+  NamedDecl *getTargetDecl() const { return Underlying; }
 
-  /// Gets the using declaration to which this declaration is tied.
-  UsingDecl *getUsingDecl() const {
-    return Using;
-  }
+  /// \brief Sets the underlying declaration which has been brought into the
+  /// local scope.
+  void setTargetDecl(NamedDecl* ND) { Underlying = ND; }
+
+  /// \brief Gets the using declaration to which this declaration is tied.
+  UsingDecl *getUsingDecl() const { return Using; }
+
+  /// \brief Sets the using declaration that introduces this target
+  /// declaration.
+  void setUsingDecl(UsingDecl* UD) { Using = UD; }
 
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const UsingShadowDecl *D) { return true; }
@@ -1776,21 +1840,39 @@
   }
 
 public:
+  // FIXME: Should be const?
   /// \brief Returns the source range that covers the nested-name-specifier
   /// preceding the namespace name.
   SourceRange getNestedNameRange() { return NestedNameRange; }
 
-  /// \brief Returns the source location of the "using" location itself.
+  /// \brief Set the source range of the nested-name-specifier.
+  void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
+
+  // FIXME; Should be const?
+  // FIXME: Naming is inconsistent with other get*Loc functions.
+  /// \brief Returns the source location of the "using" keyword.
   SourceLocation getUsingLocation() { return UsingLocation; }
 
-  /// \brief Get target nested name declaration.
+  /// \brief Set the source location of the 'using' keyword.
+  void setUsingLocation(SourceLocation L) { UsingLocation = L; }
+
+
+  /// \brief Get the target nested name declaration.
   NestedNameSpecifier* getTargetNestedNameDecl() {
     return TargetNestedName;
   }
 
-  /// isTypeName - Return true if using decl has 'typename'.
+  /// \brief Set the target nested name declaration.
+  void setTargetNestedNameDecl(NestedNameSpecifier *NNS) {
+    TargetNestedName = NNS;
+  }
+
+  /// \brief Return true if the using declaration has 'typename'.
   bool isTypeName() const { return IsTypeName; }
 
+  /// \brief Sets whether the using declaration has 'typename'.
+  void setTypeName(bool TN) { IsTypeName = TN; }
+
   typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
   shadow_iterator shadow_begin() const { return Shadows.begin(); }
   shadow_iterator shadow_end() const { return Shadows.end(); }
@@ -1808,6 +1890,12 @@
     }
   }
 
+  /// \brief Return the number of shadowed declarations associated with this
+  /// using declaration.
+  unsigned getNumShadowDecls() const {
+    return Shadows.size();
+  }
+
   static UsingDecl *Create(ASTContext &C, DeclContext *DC,
       SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
       NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
@@ -1850,14 +1938,26 @@
   /// preceding the namespace name.
   SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
 
+  /// \brief Set the source range coverting the nested-name-specifier preceding
+  /// the namespace name.
+  void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
+
   /// \brief Get target nested name declaration.
   NestedNameSpecifier* getTargetNestedNameSpecifier() {
     return TargetNestedNameSpecifier;
   }
 
+  /// \brief Set the nested name declaration.
+  void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
+    TargetNestedNameSpecifier = NNS;
+  }
+
   /// \brief Returns the source location of the 'using' keyword.
   SourceLocation getUsingLoc() const { return UsingLocation; }
 
+  /// \brief Set the source location of the 'using' keyword.
+  void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+
   static UnresolvedUsingValueDecl *
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
            SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
@@ -1904,17 +2004,32 @@
   /// preceding the namespace name.
   SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
 
+  /// \brief Set the source range coverting the nested-name-specifier preceding
+  /// the namespace name.
+  void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
+
   /// \brief Get target nested name declaration.
   NestedNameSpecifier* getTargetNestedNameSpecifier() {
     return TargetNestedNameSpecifier;
   }
 
+  /// \brief Set the nested name declaration.
+  void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
+    TargetNestedNameSpecifier = NNS;
+  }
+
   /// \brief Returns the source location of the 'using' keyword.
   SourceLocation getUsingLoc() const { return UsingLocation; }
 
+  /// \brief Set the source location of the 'using' keyword.
+  void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+
   /// \brief Returns the source location of the 'typename' keyword.
   SourceLocation getTypenameLoc() const { return TypenameLocation; }
 
+  /// \brief Set the source location of the 'typename' keyword.
+  void setTypenameLoc(SourceLocation L) { TypenameLocation = L; }
+
   static UnresolvedUsingTypenameDecl *
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
            SourceLocation TypenameLoc,

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Fri May  7 16:43:38 2010
@@ -534,8 +534,46 @@
       /// IDs. This data is used when performing qualified name lookup
       /// into a DeclContext via DeclContext::lookup.
       DECL_CONTEXT_VISIBLE,
-      /// \brief A NamespaceDecl record.
-      DECL_NAMESPACE
+      /// \brief A NamespaceDecl rcord.
+      DECL_NAMESPACE,
+      /// \brief A NamespaceAliasDecl record.
+      DECL_NAMESPACE_ALIAS,
+      /// \brief A UsingDecl record.
+      DECL_USING,
+      /// \brief A UsingShadowDecl record.
+      DECL_USING_SHADOW,
+      /// \brief A UsingDirecitveDecl record.
+      DECL_USING_DIRECTIVE,
+      /// \brief An UnresolvedUsingValueDecl record.
+      DECL_UNRESOLVED_USING_VALUE,
+      /// \brief An UnresolvedUsingTypenameDecl record.
+      DECL_UNRESOLVED_USING_TYPENAME,
+      /// \brief A LinkageSpecDecl record.
+      DECL_LINKAGE_SPEC,
+      /// \brief A CXXRecordDecl record.
+      DECL_CXX_RECORD,
+      /// \brief A CXXMethodDecl record.
+      DECL_CXX_METHOD,
+      /// \brief A CXXConstructorDecl record.
+      DECL_CXX_CONSTRUCTOR,
+      /// \brief A CXXDestructorDecl record.
+      DECL_CXX_DESTRUCTOR,
+      /// \brief A CXXConversionDecl record.
+      DECL_CXX_CONVERSION,
+
+      // FIXME: Implement serialization for these decl types. This just
+      // allocates the order in which
+      DECL_FRIEND,
+      DECL_FRIEND_TEMPLATE,
+      DECL_TEMPLATE,
+      DECL_CLASS_TEMPLATE,
+      DECL_CLASS_TEMPLATE_SPECIALIZATION,
+      DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
+      DECL_FUNCTION_TEMPLATE,
+      DECL_TEMPLATE_TYPE_PARM,
+      DECL_NON_TYPE_TEMPLATE_PARM,
+      DECL_TEMPLATE_TEMPLATE_PARM,
+      DECL_STATIC_ASSERT
     };
 
     /// \brief Record codes for each kind of statement or expression.

Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHReader.h Fri May  7 16:43:38 2010
@@ -52,6 +52,9 @@
 class Attr;
 class Decl;
 class DeclContext;
+class NestedNameSpecifier;
+class CXXBaseSpecifier;
+class CXXBaseOrMemberInitializer;
 class GotoStmt;
 class LabelStmt;
 class MacroDefinition;
@@ -694,8 +697,21 @@
   Selector GetSelector(const RecordData &Record, unsigned &Idx) {
     return DecodeSelector(Record[Idx++]);
   }
+
+  /// \brief Read a declaration name.
   DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx);
 
+  NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
+                                               unsigned &Idx);
+
+  /// \brief Read a source location.
+  SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
+    return SourceLocation::getFromRawEncoding(Record[Idx++]);
+  }
+
+  /// \brief Read a source range.
+  SourceRange ReadSourceRange(const RecordData &Record, unsigned& Idx);
+
   /// \brief Read an integral value
   llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
 

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Fri May  7 16:43:38 2010
@@ -32,6 +32,9 @@
 namespace clang {
 
 class ASTContext;
+class NestedNameSpecifier;
+class CXXBaseSpecifier;
+class CXXBaseOrMemberInitializer;
 class LabelStmt;
 class MacroDefinition;
 class MemorizeStatCalls;
@@ -251,6 +254,9 @@
   /// \brief Emit a source location.
   void AddSourceLocation(SourceLocation Loc, RecordData &Record);
 
+  /// \brief Emit a source range.
+  void AddSourceRange(SourceRange Range, RecordData &Record);
+
   /// \brief Emit an integral value.
   void AddAPInt(const llvm::APInt &Value, RecordData &Record);
 
@@ -304,6 +310,9 @@
   /// \brief Emit a declaration name.
   void AddDeclarationName(DeclarationName Name, RecordData &Record);
 
+  /// \brief Emit a nested name specifier.
+  void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record);
+
   /// \brief Add a string to the given record.
   void AddString(const std::string &Str, RecordData &Record);
 

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Fri May  7 16:43:38 2010
@@ -785,6 +785,12 @@
 }
 
 CXXConstructorDecl *
+CXXConstructorDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) CXXConstructorDecl(0, SourceLocation(), DeclarationName(),
+                                    QualType(), 0, false, false, false);
+}
+
+CXXConstructorDecl *
 CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                            SourceLocation L, DeclarationName N,
                            QualType T, TypeSourceInfo *TInfo,
@@ -887,6 +893,12 @@
 }
 
 CXXDestructorDecl *
+CXXDestructorDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) CXXDestructorDecl(0, SourceLocation(), DeclarationName(),
+                                   QualType(), false, false);
+}
+
+CXXDestructorDecl *
 CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                           SourceLocation L, DeclarationName N,
                           QualType T, bool isInline,
@@ -903,6 +915,12 @@
 }
 
 CXXConversionDecl *
+CXXConversionDecl::Create(ASTContext &C, EmptyShell Empty) {
+  return new (C) CXXConversionDecl(0, SourceLocation(), DeclarationName(),
+                                   QualType(), 0, false, false);
+}
+
+CXXConversionDecl *
 CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                           SourceLocation L, DeclarationName N,
                           QualType T, TypeSourceInfo *TInfo,
@@ -940,6 +958,12 @@
   return cast_or_null<NamespaceDecl>(NominatedNamespace);
 }
 
+void UsingDirectiveDecl::setNominatedNamespace(NamedDecl* ND) {
+  assert((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
+    "expected a NamespaceDecl or NamespaceAliasDecl");
+  NominatedNamespace = ND;
+}
+
 NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
                                                SourceLocation L,
                                                SourceLocation AliasLoc,

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Fri May  7 16:43:38 2010
@@ -2901,6 +2901,51 @@
   return DeclarationName();
 }
 
+NestedNameSpecifier *
+PCHReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
+  unsigned N = Record[Idx++];
+  NestedNameSpecifier *NNS = 0, *Prev = 0;
+  for (unsigned I = 0; I != N; ++I) {
+    NestedNameSpecifier::SpecifierKind Kind
+      = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
+    switch (Kind) {
+    case NestedNameSpecifier::Identifier: {
+      IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
+      NNS = NestedNameSpecifier::Create(*Context, Prev, II);
+      break;
+    }
+
+    case NestedNameSpecifier::Namespace: {
+      NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
+      NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
+      break;
+    }
+
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate: {
+      Type *T = GetType(Record[Idx++]).getTypePtr();
+      bool Template = Record[Idx++];
+      NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
+      break;
+    }
+
+    case NestedNameSpecifier::Global: {
+      NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
+      // No associated value, and there can't be a prefix.
+      break;
+    }
+    Prev = NNS;
+    }
+  }
+  return NNS;
+}
+
+SourceRange
+PCHReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) {
+  return SourceRange(SourceLocation::getFromRawEncoding(Record[Idx++]),
+                     SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
 /// \brief Read an integral value
 llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
   unsigned BitWidth = Record[Idx++];

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Fri May  7 16:43:38 2010
@@ -17,6 +17,8 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 using namespace clang;
 
@@ -40,22 +42,49 @@
     void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
     void VisitNamedDecl(NamedDecl *ND);
     void VisitNamespaceDecl(NamespaceDecl *D);
+    void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+    void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
     void VisitTypeDecl(TypeDecl *TD);
     void VisitTypedefDecl(TypedefDecl *TD);
+    void VisitUnresolvedUsingTypename(UnresolvedUsingTypenameDecl *D);
     void VisitTagDecl(TagDecl *TD);
     void VisitEnumDecl(EnumDecl *ED);
     void VisitRecordDecl(RecordDecl *RD);
+    void VisitCXXRecordDecl(CXXRecordDecl *D);
+    void VisitClassTemplateSpecializationDecl(
+                                            ClassTemplateSpecializationDecl *D);
+    void VisitClassTemplatePartialSpecializationDecl(
+                                     ClassTemplatePartialSpecializationDecl *D);
+    void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
     void VisitValueDecl(ValueDecl *VD);
     void VisitEnumConstantDecl(EnumConstantDecl *ECD);
+    void VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D);
     void VisitDeclaratorDecl(DeclaratorDecl *DD);
     void VisitFunctionDecl(FunctionDecl *FD);
+    void VisitCXXMethodDecl(CXXMethodDecl *D);
+    void VisitCXXConstructorDecl(CXXConstructorDecl *D);
+    void VisitCXXDestructorDecl(CXXDestructorDecl *D);
+    void VisitCXXConversionDecl(CXXConversionDecl *D);
     void VisitFieldDecl(FieldDecl *FD);
     void VisitVarDecl(VarDecl *VD);
     void VisitImplicitParamDecl(ImplicitParamDecl *PD);
     void VisitParmVarDecl(ParmVarDecl *PD);
+    void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+    void VisitTemplateDecl(TemplateDecl *D);
+    void VisitClassTemplateDecl(ClassTemplateDecl *D);
+    void visitFunctionTemplateDecl(FunctionTemplateDecl *D);
+    void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+    void VisitUsing(UsingDecl *D);
+    void VisitUsingShadow(UsingShadowDecl *D);
+    void VisitLinkageSpecDecl(LinkageSpecDecl *D);
     void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
+    void VisitFriendTemplateDecl(FriendTemplateDecl *D);
+    void VisitStaticAssertDecl(StaticAssertDecl *D);
     void VisitBlockDecl(BlockDecl *BD);
+
     std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
+
+    // FIXME: Reorder according to DeclNodes.def?
     void VisitObjCMethodDecl(ObjCMethodDecl *D);
     void VisitObjCContainerDecl(ObjCContainerDecl *D);
     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
@@ -90,6 +119,8 @@
 
 void PCHDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
   VisitDecl(TU);
+  TU->setAnonymousNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
 }
 
 void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
@@ -97,18 +128,6 @@
   ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
 }
 
-void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
-  VisitNamedDecl(D);
-  D->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  D->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  D->setNextNamespace(
-                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
-  D->setOriginalNamespace(
-                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
-  D->setAnonymousNamespace(
-                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
-}
-
 void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
   VisitNamedDecl(TD);
   TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
@@ -193,6 +212,8 @@
   FD->setHasImplicitReturnZero(Record[Idx++]);
   FD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
   // FIXME: C++ TemplateOrInstantiation
+
+  // Read in the parameters.
   unsigned NumParams = Record[Idx++];
   llvm::SmallVector<ParmVarDecl *, 16> Params;
   Params.reserve(NumParams);
@@ -446,6 +467,155 @@
   BD->setParams(Params.data(), NumParams);
 }
 
+void PCHDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+  VisitDecl(D);
+  D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]);
+  D->setHasBraces(Record[Idx++]);
+}
+
+void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
+  VisitNamedDecl(D);
+  D->setLBracLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setRBracLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setNextNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+
+  // Only read one reference--the original or anonymous namespace.
+  bool IsOriginal = Record[Idx++];
+  if (IsOriginal)
+    D->setAnonymousNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+  else
+    D->setOriginalNamespace(
+                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+  VisitNamedDecl(D);
+
+  D->setAliasLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  D->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  D->setTargetNameLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setAliasedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitUsing(UsingDecl *D) {
+  VisitNamedDecl(D);
+  D->setUsingLocation(Reader.ReadSourceLocation(Record, Idx));
+  D->setNestedNameRange(Reader.ReadSourceRange(Record, Idx));
+  D->setTargetNestedNameDecl(Reader.ReadNestedNameSpecifier(Record, Idx));
+
+  // FIXME: It would probably be more efficient to read these into a vector
+  // and then re-cosntruct the shadow decl set over that vector since it
+  // would avoid existence checks.
+  unsigned NumShadows = Record[Idx++];
+  for(unsigned I = 0; I != NumShadows; ++I) {
+    D->addShadowDecl(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])));
+  }
+  D->setTypeName(Record[Idx++]);
+}
+
+void PCHDeclReader::VisitUsingShadow(UsingShadowDecl *D) {
+  VisitNamedDecl(D);
+  D->setTargetDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setUsingDecl(cast<UsingDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+  VisitNamedDecl(D);
+  D->setNamespaceKeyLocation(Reader.ReadSourceLocation(Record, Idx));
+  D->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  D->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  D->setIdentLocation(Reader.ReadSourceLocation(Record, Idx));
+  D->setNominatedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+  D->setCommonAncestor(cast_or_null<DeclContext>(
+                                                Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D) {
+  VisitValueDecl(D);
+  D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));
+  D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+}
+
+void PCHDeclReader::VisitUnresolvedUsingTypename(
+                                               UnresolvedUsingTypenameDecl *D) {
+  VisitTypeDecl(D);
+  D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));
+  D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setTypenameLoc(Reader.ReadSourceLocation(Record, Idx));
+  D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+}
+
+void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  // assert(false && "cannot read CXXRecordDecl");
+  VisitRecordDecl(D);
+}
+
+void PCHDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
+  // assert(false && "cannot read CXXMethodDecl");
+  VisitFunctionDecl(D);
+}
+
+void PCHDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+  // assert(false && "cannot read CXXConstructorDecl");
+  VisitCXXMethodDecl(D);
+}
+
+void PCHDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+  // assert(false && "cannot read CXXDestructorDecl");
+  VisitCXXMethodDecl(D);
+}
+
+void PCHDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
+  // assert(false && "cannot read CXXConversionDecl");
+  VisitCXXMethodDecl(D);
+}
+
+void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
+  assert(false && "cannot read FriendTemplateDecl");
+}
+
+void PCHDeclReader::VisitTemplateDecl(TemplateDecl *D) {
+  assert(false && "cannot read TemplateDecl");
+}
+
+void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+  assert(false && "cannot read ClassTemplateDecl");
+}
+
+void PCHDeclReader::VisitClassTemplateSpecializationDecl(
+                                           ClassTemplateSpecializationDecl *D) {
+  assert(false && "cannot read ClassTemplateSpecializationDecl");
+}
+
+void PCHDeclReader::VisitClassTemplatePartialSpecializationDecl(
+                                    ClassTemplatePartialSpecializationDecl *D) {
+  assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
+}
+
+void PCHDeclReader::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  assert(false && "cannot read FunctionTemplateDecl");
+}
+
+void PCHDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  assert(false && "cannot read TemplateTypeParmDecl");
+}
+
+void PCHDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+  assert(false && "cannot read NonTypeTemplateParmDecl");
+}
+
+void PCHDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+  assert(false && "cannot read TemplateTemplateParmDecl");
+}
+
+void PCHDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
+  assert(false && "cannot read StaticAssertDecl");
+}
+
 std::pair<uint64_t, uint64_t>
 PCHDeclReader::VisitDeclContext(DeclContext *DC) {
   uint64_t LexicalOffset = Record[Idx++];
@@ -706,6 +876,94 @@
     D = FunctionDecl::Create(*Context, 0, SourceLocation(), DeclarationName(),
                              QualType(), 0);
     break;
+  case pch::DECL_LINKAGE_SPEC:
+    D = LinkageSpecDecl::Create(*Context, 0, SourceLocation(),
+                                (LinkageSpecDecl::LanguageIDs)0,
+                                false);
+    break;
+  case pch::DECL_NAMESPACE:
+    D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
+  case pch::DECL_NAMESPACE_ALIAS:
+    D = NamespaceAliasDecl::Create(*Context, 0, SourceLocation(),
+                                   SourceLocation(), 0, SourceRange(), 0,
+                                   SourceLocation(), 0);
+    break;
+  case pch::DECL_USING:
+    D = UsingDecl::Create(*Context, 0, SourceLocation(), SourceRange(),
+                          SourceLocation(), 0, DeclarationName(), false);
+    break;
+  case pch::DECL_USING_SHADOW:
+    D = UsingShadowDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+    break;
+  case pch::DECL_USING_DIRECTIVE:
+    D = UsingDirectiveDecl::Create(*Context, 0, SourceLocation(),
+                                   SourceLocation(), SourceRange(), 0,
+                                   SourceLocation(), 0, 0);
+    break;
+  case pch::DECL_UNRESOLVED_USING_VALUE:
+    D = UnresolvedUsingValueDecl::Create(*Context, 0, SourceLocation(),
+                                         SourceRange(), 0, SourceLocation(),
+                                         DeclarationName());
+    break;
+  case pch::DECL_UNRESOLVED_USING_TYPENAME:
+    D = UnresolvedUsingTypenameDecl::Create(*Context, 0, SourceLocation(),
+                                            SourceLocation(), SourceRange(),
+                                            0, SourceLocation(),
+                                            DeclarationName());
+    break;
+  case pch::DECL_CXX_RECORD:
+    D = CXXRecordDecl::Create(*Context, TagDecl::TK_struct, 0,
+                              SourceLocation(), 0, SourceLocation(), 0);
+    break;
+  case pch::DECL_CXX_METHOD:
+    D = CXXMethodDecl::Create(*Context, 0, SourceLocation(), DeclarationName(),
+                              QualType(), 0);
+    break;
+  case pch::DECL_CXX_CONSTRUCTOR:
+    D = CXXConstructorDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case pch::DECL_CXX_DESTRUCTOR:
+    D = CXXDestructorDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case pch::DECL_CXX_CONVERSION:
+    D = CXXConversionDecl::Create(*Context, Decl::EmptyShell());
+    break;
+  case pch::DECL_FRIEND:
+    assert(false && "cannot read FriendDecl");
+    break;
+  case pch::DECL_FRIEND_TEMPLATE:
+    assert(false && "cannot read FriendTemplateDecl");
+    break;
+  case pch::DECL_TEMPLATE:
+    // FIXME: Should TemplateDecl be ABSTRACT_DECL???
+    assert(false && "TemplateDecl should be abstract!");
+    break;
+  case pch::DECL_CLASS_TEMPLATE:
+    assert(false && "cannot read ClassTemplateDecl");
+    break;
+  case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION:
+    assert(false && "cannot read ClasstemplateSpecializationDecl");
+    break;
+  case pch::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
+    assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
+    break;
+  case pch::DECL_FUNCTION_TEMPLATE:
+    assert(false && "cannot read FunctionTemplateDecl");
+    break;
+  case pch::DECL_TEMPLATE_TYPE_PARM:
+    assert(false && "cannot read TemplateTypeParmDecl");
+    break;
+  case pch::DECL_NON_TYPE_TEMPLATE_PARM:
+    assert(false && "cannot read NonTypeTemplateParmDecl");
+    break;
+  case pch::DECL_TEMPLATE_TEMPLATE_PARM:
+    assert(false && "cannot read TemplateTemplateParmDecl");
+    break;
+  case pch::DECL_STATIC_ASSERT:
+    assert(false && "cannot read StaticAssertDecl");
+    break;
+
   case pch::DECL_OBJC_METHOD:
     D = ObjCMethodDecl::Create(*Context, SourceLocation(), SourceLocation(),
                                Selector(), QualType(), 0, 0);
@@ -775,10 +1033,6 @@
   case pch::DECL_BLOCK:
     D = BlockDecl::Create(*Context, 0, SourceLocation());
     break;
-      
-  case pch::DECL_NAMESPACE:
-    D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
-    break;
   }
 
   assert(D && "Unknown declaration reading PCH file");

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Fri May  7 16:43:38 2010
@@ -2181,6 +2181,11 @@
   Record.push_back(Loc.getRawEncoding());
 }
 
+void PCHWriter::AddSourceRange(SourceRange Range, RecordData &Record) {
+  AddSourceLocation(Range.getBegin(), Record);
+  AddSourceLocation(Range.getEnd(), Record);
+}
+
 void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
   Record.push_back(Value.getBitWidth());
   unsigned N = Value.getNumWords();
@@ -2407,3 +2412,42 @@
     break;
   }
 }
+
+void PCHWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
+                                       RecordData &Record) {
+  // Nested name specifiers usually aren't too long. I think that 8 would
+  // typically accomodate the vast majority.
+  llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames;
+
+  // Push each of the NNS's onto a stack for serialization in reverse order.
+  while (NNS) {
+    NestedNames.push_back(NNS);
+    NNS = NNS->getPrefix();
+  }
+
+  Record.push_back(NestedNames.size());
+  while(!NestedNames.empty()) {
+    NNS = NestedNames.pop_back_val();
+    NestedNameSpecifier::SpecifierKind Kind = NNS->getKind();
+    Record.push_back(Kind);
+    switch (Kind) {
+    case NestedNameSpecifier::Identifier:
+      AddIdentifierRef(NNS->getAsIdentifier(), Record);
+      break;
+
+    case NestedNameSpecifier::Namespace:
+      AddDeclRef(NNS->getAsNamespace(), Record);
+      break;
+
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate:
+      AddTypeRef(QualType(NNS->getAsType(), 0), Record);
+      Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
+      break;
+
+    case NestedNameSpecifier::Global:
+      // Don't need to write an associated value.
+      break;
+    }
+  }
+}

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Fri May  7 16:43:38 2010
@@ -13,6 +13,8 @@
 
 #include "clang/Frontend/PCHWriter.h"
 #include "clang/AST/DeclVisitor.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
@@ -43,23 +45,51 @@
     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
     void VisitNamedDecl(NamedDecl *D);
     void VisitNamespaceDecl(NamespaceDecl *D);
+    void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+    void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
     void VisitTypeDecl(TypeDecl *D);
     void VisitTypedefDecl(TypedefDecl *D);
+    void VisitUnresolvedUsingTypename(UnresolvedUsingTypenameDecl *D);
     void VisitTagDecl(TagDecl *D);
     void VisitEnumDecl(EnumDecl *D);
     void VisitRecordDecl(RecordDecl *D);
+    void VisitCXXRecordDecl(CXXRecordDecl *D);
+    void VisitClassTemplateSpecializationDecl(
+                                            ClassTemplateSpecializationDecl *D);
+    void VisitClassTemplatePartialSpecializationDecl(
+                                     ClassTemplatePartialSpecializationDecl *D);
+    void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
     void VisitValueDecl(ValueDecl *D);
     void VisitEnumConstantDecl(EnumConstantDecl *D);
+    void VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D);
     void VisitDeclaratorDecl(DeclaratorDecl *D);
     void VisitFunctionDecl(FunctionDecl *D);
+    void VisitCXXMethodDecl(CXXMethodDecl *D);
+    void VisitCXXConstructorDecl(CXXConstructorDecl *D);
+    void VisitCXXDestructorDecl(CXXDestructorDecl *D);
+    void VisitCXXConversionDecl(CXXConversionDecl *D);
     void VisitFieldDecl(FieldDecl *D);
     void VisitVarDecl(VarDecl *D);
     void VisitImplicitParamDecl(ImplicitParamDecl *D);
     void VisitParmVarDecl(ParmVarDecl *D);
+    void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+    void VisitTemplateDecl(TemplateDecl *D);
+    void VisitClassTemplateDecl(ClassTemplateDecl *D);
+    void visitFunctionTemplateDecl(FunctionTemplateDecl *D);
+    void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+    void VisitUsing(UsingDecl *D);
+    void VisitUsingShadow(UsingShadowDecl *D);
+    void VisitLinkageSpecDecl(LinkageSpecDecl *D);
     void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
+    void VisitFriendTemplateDecl(FriendTemplateDecl *D);
+    void VisitStaticAssertDecl(StaticAssertDecl *D);
     void VisitBlockDecl(BlockDecl *D);
+
     void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
                           uint64_t VisibleOffset);
+
+
+    // FIXME: Put in the same order is DeclNodes.def?
     void VisitObjCMethodDecl(ObjCMethodDecl *D);
     void VisitObjCContainerDecl(ObjCContainerDecl *D);
     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
@@ -92,6 +122,7 @@
 
 void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
   VisitDecl(D);
+  Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
   Code = pch::DECL_TRANSLATION_UNIT;
 }
 
@@ -100,16 +131,6 @@
   Writer.AddDeclarationName(D->getDeclName(), Record);
 }
 
-void PCHDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
-  VisitNamedDecl(D);
-  Writer.AddSourceLocation(D->getLBracLoc(), Record);
-  Writer.AddSourceLocation(D->getRBracLoc(), Record);
-  Writer.AddDeclRef(D->getNextNamespace(), Record);
-  Writer.AddDeclRef(D->getOriginalNamespace(), Record);
-  Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
-  Code = pch::DECL_NAMESPACE;
-}
-
 void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
   VisitNamedDecl(D);
   Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
@@ -173,9 +194,11 @@
 
 void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
   VisitDeclaratorDecl(D);
+
   Record.push_back(D->isThisDeclarationADefinition());
   if (D->isThisDeclarationADefinition())
     Writer.AddStmt(D->getBody());
+
   Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
   Record.push_back(D->getStorageClass()); // FIXME: stable encoding
   Record.push_back(D->getStorageClassAsWritten());
@@ -188,8 +211,9 @@
   Record.push_back(D->isTrivial());
   Record.push_back(D->isCopyAssignment());
   Record.push_back(D->hasImplicitReturnZero());
+  // FIXME: C++ TemplateOrInstantiation???
   Writer.AddSourceLocation(D->getLocEnd(), Record);
-  // FIXME: C++ TemplateOrInstantiation
+
   Record.push_back(D->param_size());
   for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
        P != PEnd; ++P)
@@ -227,9 +251,7 @@
 
 void PCHDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
   VisitNamedDecl(D);
-  SourceRange R = D->getAtEndRange();
-  Writer.AddSourceLocation(R.getBegin(), Record);
-  Writer.AddSourceLocation(R.getEnd(), Record);
+  Writer.AddSourceRange(D->getAtEndRange(), Record);
   // Abstract class (no need to define a stable pch::DECL code).
 }
 
@@ -411,7 +433,6 @@
   Record.push_back(D->hasInheritedDefaultArg());
   Code = pch::DECL_PARM_VAR;
 
-
   // If the assumptions about the DECL_PARM_VAR abbrev are true, use it.  Here
   // we dynamically check for the properties that we optimize for, but don't
   // know are true of all PARM_VAR_DECLs.
@@ -454,6 +475,161 @@
   Code = pch::DECL_BLOCK;
 }
 
+void PCHDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+  VisitDecl(D);
+  // FIXME: It might be nice to serialize the brace locations for this
+  // declaration, which don't seem to be readily available in the AST.
+  Record.push_back(D->getLanguage());
+  Record.push_back(D->hasBraces());
+  Code = pch::DECL_LINKAGE_SPEC;
+}
+
+void PCHDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getLBracLoc(), Record);
+  Writer.AddSourceLocation(D->getRBracLoc(), Record);
+  Writer.AddDeclRef(D->getNextNamespace(), Record);
+
+  // Only write one reference--original or anonymous
+  Record.push_back(D->isOriginalNamespace());
+  if (D->isOriginalNamespace())
+    Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
+  else
+    Writer.AddDeclRef(D->getOriginalNamespace(), Record);
+  Code = pch::DECL_NAMESPACE;
+}
+
+void PCHDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getAliasLoc(), Record);
+  Writer.AddSourceRange(D->getQualifierRange(), Record);
+  Writer.AddNestedNameSpecifier(D->getQualifier(), Record);
+  Writer.AddSourceLocation(D->getTargetNameLoc(), Record);
+  Writer.AddDeclRef(D->getNamespace(), Record);
+  Code = pch::DECL_NAMESPACE_ALIAS;
+}
+
+void PCHDeclWriter::VisitUsing(UsingDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceRange(D->getNestedNameRange(), Record);
+  Writer.AddSourceLocation(D->getUsingLocation(), Record);
+  Writer.AddNestedNameSpecifier(D->getTargetNestedNameDecl(), Record);
+  Record.push_back(D->getNumShadowDecls());
+  for (UsingDecl::shadow_iterator P = D->shadow_begin(),
+       PEnd = D->shadow_end(); P != PEnd; ++P)
+    Writer.AddDeclRef(*P, Record);
+  Record.push_back(D->isTypeName());
+  Code = pch::DECL_USING;
+}
+
+void PCHDeclWriter::VisitUsingShadow(UsingShadowDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddDeclRef(D->getTargetDecl(), Record);
+  Writer.AddDeclRef(D->getUsingDecl(), Record);
+  Code = pch::DECL_USING_SHADOW;
+}
+
+void PCHDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record);
+  Writer.AddSourceRange(D->getQualifierRange(), Record);
+  Writer.AddNestedNameSpecifier(D->getQualifier(), Record);
+  Writer.AddSourceLocation(D->getIdentLocation(), Record);
+  Writer.AddDeclRef(D->getNominatedNamespace(), Record);
+  Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record);
+  Code = pch::DECL_USING_DIRECTIVE;
+}
+
+void PCHDeclWriter::VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D) {
+  VisitValueDecl(D);
+  Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
+  Writer.AddSourceLocation(D->getUsingLoc(), Record);
+  Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
+  Code = pch::DECL_UNRESOLVED_USING_VALUE;
+}
+
+void PCHDeclWriter::VisitUnresolvedUsingTypename(
+                                               UnresolvedUsingTypenameDecl *D) {
+  VisitTypeDecl(D);
+  Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
+  Writer.AddSourceLocation(D->getUsingLoc(), Record);
+  Writer.AddSourceLocation(D->getTypenameLoc(), Record);
+  Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
+  Code = pch::DECL_UNRESOLVED_USING_TYPENAME;
+}
+
+void PCHDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  // assert(false && "cannot write CXXRecordDecl");
+  VisitRecordDecl(D);
+  Code = pch::DECL_CXX_RECORD;
+}
+
+void PCHDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
+  // assert(false && "cannot write CXXMethodDecl");
+  VisitFunctionDecl(D);
+  Code = pch::DECL_CXX_METHOD;
+}
+
+void PCHDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+  // assert(false && "cannot write CXXConstructorDecl");
+  VisitCXXMethodDecl(D);
+  Code = pch::DECL_CXX_CONSTRUCTOR;
+}
+
+void PCHDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+  // assert(false && "cannot write CXXDestructorDecl");
+  VisitCXXMethodDecl(D);
+  Code = pch::DECL_CXX_DESTRUCTOR;
+}
+
+void PCHDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
+  // assert(false && "cannot write CXXConversionDecl");
+  VisitCXXMethodDecl(D);
+  Code = pch::DECL_CXX_CONVERSION;
+}
+
+void PCHDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
+  assert(false && "cannot write FriendTemplateDecl");
+}
+
+void PCHDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
+  assert(false && "cannot write TemplateDecl");
+}
+
+void PCHDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+  assert(false && "cannot write ClassTemplateDecl");
+}
+
+void PCHDeclWriter::VisitClassTemplateSpecializationDecl(
+                                           ClassTemplateSpecializationDecl *D) {
+  assert(false && "cannot write ClassTemplateSpecializationDecl");
+}
+
+void PCHDeclWriter::VisitClassTemplatePartialSpecializationDecl(
+                                    ClassTemplatePartialSpecializationDecl *D) {
+  assert(false && "cannot write ClassTemplatePartialSpecializationDecl");
+}
+
+void PCHDeclWriter::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+  assert(false && "cannot write FunctionTemplateDecl");
+}
+
+void PCHDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  assert(false && "cannot write TemplateTypeParmDecl");
+}
+
+void PCHDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+  assert(false && "cannot write NonTypeTemplateParmDecl");
+}
+
+void PCHDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+  assert(false && "cannot write TemplateTemplateParmDecl");
+}
+
+void PCHDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
+  assert(false && "cannot write StaticAssertDecl");
+}
+
 /// \brief Emit the DeclContext part of a declaration context decl.
 ///
 /// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL

Modified: cfe/trunk/test/PCH/Inputs/namespaces.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/Inputs/namespaces.h?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/test/PCH/Inputs/namespaces.h (original)
+++ cfe/trunk/test/PCH/Inputs/namespaces.h Fri May  7 16:43:38 2010
@@ -6,8 +6,35 @@
 
 namespace N1 {
   typedef int t2;
+
+  void used_func();
+
+  struct used_cls { };
 }
 
 namespace N2 {
   typedef float t1;
+
+  namespace Inner {
+    typedef int t3;
+  };
+}
+
+namespace {
+  void anon() { }
+  class C;
+}
+
+namespace N3 {
+  namespace {
+    class C;
+  }
+}
+
+namespace Alias1 = N2::Inner;
+
+using namespace N2::Inner;
+
+extern "C" {
+  void ext();
 }

Modified: cfe/trunk/test/PCH/namespaces.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/namespaces.cpp?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/test/PCH/namespaces.cpp (original)
+++ cfe/trunk/test/PCH/namespaces.cpp Fri May  7 16:43:38 2010
@@ -8,7 +8,36 @@
 int int_val;
 N1::t1 *ip1 = &int_val;
 N1::t2 *ip2 = &int_val;
+N2::Inner::t3 *ip3 = &int_val;
 
 float float_val;
 namespace N2 { }
 N2::t1 *fp1 = &float_val;
+
+Alias1::t3 *ip4 = &int_val;
+t3 *ip5 = &int_val;
+
+void(*funp1)() = anon;
+
+namespace {
+  class C;
+}
+C* cp1;
+
+namespace N3 {
+  namespace {
+    class C;
+  }
+}
+
+N3::C *cp2;
+
+void(*funp2)() = ext;
+
+using N1::used_func;
+void (*pused)() = used_func;
+
+// FIXME: Disabled until CXXRecord serialization is re-added.
+// using N1::used_cls;
+// used_cls s1;
+// used_cls* ps1 = &s1;

Modified: cfe/trunk/test/SemaCXX/namespace-alias.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/namespace-alias.cpp?rev=103301&r1=103300&r2=103301&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/namespace-alias.cpp (original)
+++ cfe/trunk/test/SemaCXX/namespace-alias.cpp Fri May  7 16:43:38 2010
@@ -84,6 +84,26 @@
   }
 }
 
+namespace {
+  class C1;
+}
+namespace {
+  class C1;
+}
+C1 *pc1 = 0;
+
+namespace N {
+  namespace {
+    class C2;
+  }
+}
+namespace N {
+  namespace {
+    class C2;
+  }
+}
+N::C2 *pc2 = 0;
+
 // PR6341
 namespace A = N;
 namespace N { }





More information about the cfe-commits mailing list