forked from OSchip/llvm-project
Keep track of all of the import declarations that are parsed or
implicitly generated in a translation unit. Modules will need this information to identify the actual imports that occurred. llvm-svn: 145734
This commit is contained in:
parent
934cb05e40
commit
0f2a3607e0
|
@ -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; }
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue