]> granicus.if.org Git - clang/commitdiff
Keep track of all of the import declarations that are parsed or
authorDouglas Gregor <dgregor@apple.com>
Sat, 3 Dec 2011 00:30:27 +0000 (00:30 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 3 Dec 2011 00:30:27 +0000 (00:30 +0000)
implicitly generated in a translation unit. Modules will need this
information to identify the actual imports that occurred.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145734 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
include/clang/AST/Decl.h
lib/AST/ASTContext.cpp
lib/AST/Decl.cpp
lib/AST/DeclBase.cpp

index 7d5d1f55ee66c49efb29a13754f09a22dde73ac2..9f207823f27fe7c9c0c848ee9da985383c37a787 100644 (file)
@@ -326,6 +326,9 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
   typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable;
   ParameterIndexTable ParamIndices;  
   
+  ImportDecl *FirstLocalImport;
+  ImportDecl *LastLocalImport;
+  
   TranslationUnitDecl *TUDecl;
 
   /// SourceMgr - The associated SourceManager object.
@@ -481,6 +484,56 @@ public:
   void addOverriddenMethod(const CXXMethodDecl *Method, 
                            const CXXMethodDecl *Overridden);
   
+  /// \brief Notify the AST context that a new import declaration has been
+  /// parsed or implicitly created within this translation unit.
+  void addedLocalImportDecl(ImportDecl *Import);
+
+  static ImportDecl *getNextLocalImport(ImportDecl *Import) {
+    return Import->NextLocalImport;
+  }
+  
+  /// \brief Iterator that visits import declarations.
+  class import_iterator {
+    ImportDecl *Import;
+    
+  public:
+    typedef ImportDecl               *value_type;
+    typedef ImportDecl               *reference;
+    typedef ImportDecl               *pointer;
+    typedef int                       difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+    
+    import_iterator() : Import() { }
+    explicit import_iterator(ImportDecl *Import) : Import(Import) { }
+    
+    reference operator*() const { return Import; }
+    pointer operator->() const { return Import; }
+    
+    import_iterator &operator++() {
+      Import = ASTContext::getNextLocalImport(Import);
+      return *this;
+    }
+
+    import_iterator operator++(int) {
+      import_iterator Other(*this);
+      ++(*this);
+      return Other;
+    }
+    
+    friend bool operator==(import_iterator X, import_iterator Y) {
+      return X.Import == Y.Import;
+    }
+
+    friend bool operator!=(import_iterator X, import_iterator Y) {
+      return X.Import != Y.Import;
+    }
+  };
+  
+  import_iterator local_import_begin() const { 
+    return import_iterator(FirstLocalImport); 
+  }
+  import_iterator local_import_end() const { return import_iterator(); }
+  
   TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
 
 
index c3f5bd0acf8106f947d8dd29a4cd5b307fc42fe0..adb06cda51f0da218e36272bb8b253beb3b3b1d2 100644 (file)
@@ -3095,8 +3095,13 @@ class ImportDecl : public Decl {
   /// end of the import declaration.
   llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete;
   
+  /// \brief The next import in the list of imports local to the translation
+  /// unit being parsed (not loaded from an AST file).
+  ImportDecl *NextLocalImport;
+  
   friend class ASTReader;
   friend class ASTDeclReader;
+  friend class ASTContext;
   
   ImportDecl(DeclContext *DC, SourceLocation ImportLoc, Module *Imported,
              ArrayRef<SourceLocation> IdentifierLocs);
@@ -3104,7 +3109,7 @@ class ImportDecl : public Decl {
   ImportDecl(DeclContext *DC, SourceLocation ImportLoc, Module *Imported,
              SourceLocation EndLoc);
 
-  ImportDecl(EmptyShell Empty) : Decl(Import, Empty) { }
+  ImportDecl(EmptyShell Empty) : Decl(Import, Empty), NextLocalImport() { }
   
 public:
   /// \brief Create a new module import declaration.
index 22b5ed803db48fdfe90fdb499e1fa9ac84716526..47994f495f7c2f30bf4869d05efcd4160fa828b1 100644 (file)
@@ -230,7 +230,8 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,
     jmp_bufDecl(0), sigjmp_bufDecl(0), ucontext_tDecl(0),
     BlockDescriptorType(0), BlockDescriptorExtendedType(0),
     cudaConfigureCallDecl(0),
-    NullTypeSourceInfo(QualType()),
+    NullTypeSourceInfo(QualType()), 
+    FirstLocalImport(), LastLocalImport(),
     SourceMgr(SM), LangOpts(LOpts), 
     AddrSpaceMap(0), Target(t), PrintingPolicy(LOpts),
     Idents(idents), Selectors(sels),
@@ -682,6 +683,19 @@ void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,
   OverriddenMethods[Method].push_back(Overridden);
 }
 
+void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
+  assert(!Import->NextLocalImport && "Import declaration already in the chain");
+  assert(!Import->isFromASTFile() && "Non-local import declaration");
+  if (!FirstLocalImport) {
+    FirstLocalImport = Import;
+    LastLocalImport = Import;
+    return;
+  }
+  
+  LastLocalImport->NextLocalImport = Import;
+  LastLocalImport = Import;
+}
+
 //===----------------------------------------------------------------------===//
 //                         Type Sizing and Analysis
 //===----------------------------------------------------------------------===//
index 1ed149b68f2a077b58ad9358d250c6e51432596a..34eefc0dcc9a00dce9ac5d0265ef2a5e5a82c4e4 100644 (file)
@@ -2629,7 +2629,8 @@ static unsigned getNumModuleIdentifiers(Module *Mod) {
 ImportDecl::ImportDecl(DeclContext *DC, SourceLocation ImportLoc, 
                        Module *Imported,
                        ArrayRef<SourceLocation> IdentifierLocs)
-  : Decl(Import, DC, ImportLoc), ImportedAndComplete(Imported, true)
+  : Decl(Import, DC, ImportLoc), ImportedAndComplete(Imported, true),
+    NextLocalImport()
 {
   assert(getNumModuleIdentifiers(Imported) == IdentifierLocs.size());
   SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(this + 1);
@@ -2639,7 +2640,8 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation ImportLoc,
 
 ImportDecl::ImportDecl(DeclContext *DC, SourceLocation ImportLoc, 
                        Module *Imported, SourceLocation EndLoc)
-  : Decl(Import, DC, ImportLoc), ImportedAndComplete(Imported, false)
+  : Decl(Import, DC, ImportLoc), ImportedAndComplete(Imported, false),
+    NextLocalImport()
 {
   *reinterpret_cast<SourceLocation *>(this + 1) = EndLoc;
 }
index f4507e3603970321546ed72ccfdfe3a1240f1322..37e0892c5ce9b01a2cd6e9f3fa1148af9b0174ee 100644 (file)
@@ -1010,6 +1010,13 @@ void DeclContext::addHiddenDecl(Decl *D) {
   // update it's class-specific state.
   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
     Record->addedMember(D);
+
+  // If this is a newly-created (not de-serialized) import declaration, wire
+  // it in to the list of local import declarations.
+  if (!D->isFromASTFile()) {
+    if (ImportDecl *Import = dyn_cast<ImportDecl>(D))
+      D->getASTContext().addedLocalImportDecl(Import);
+  }
 }
 
 void DeclContext::addDecl(Decl *D) {