aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ASTContext.h53
-rw-r--r--include/clang/AST/Decl.h7
-rw-r--r--lib/AST/ASTContext.cpp16
-rw-r--r--lib/AST/Decl.cpp6
-rw-r--r--lib/AST/DeclBase.cpp7
5 files changed, 85 insertions, 4 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 7d5d1f55ee..9f207823f2 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -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; }
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index c3f5bd0acf..adb06cda51 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -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.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 22b5ed803d..47994f495f 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 1ed149b68f..34eefc0dcc 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -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;
}
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index f4507e3603..37e0892c5c 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -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) {