Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
When we treat an #include or #import as a module import, create an
implicit ImportDecl in the translation unit to record the presence of
the import.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145727 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
DougGregor committed Dec 2, 2011
1 parent 15de72c commit 93ebfa6
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 12 deletions.
3 changes: 2 additions & 1 deletion include/clang/Frontend/ASTUnit.h
Expand Up @@ -782,7 +782,8 @@ class ASTUnit : public ModuleLoader {
bool serialize(raw_ostream &OS);

virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
Module::NameVisibilityKind Visibility) {
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective) {
// ASTUnit doesn't know how to load modules (not that this matters).
return 0;
}
Expand Down
3 changes: 2 additions & 1 deletion include/clang/Frontend/CompilerInstance.h
Expand Up @@ -642,7 +642,8 @@ class CompilerInstance : public ModuleLoader {
/// }

virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
Module::NameVisibilityKind Visibility);
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective);
};

} // end namespace clang
Expand Down
7 changes: 6 additions & 1 deletion include/clang/Lex/ModuleLoader.h
Expand Up @@ -48,10 +48,15 @@ class ModuleLoader {
/// \param Visibility The visibility provided for the names in the loaded
/// module.
///
/// \param IsInclusionDirective Indicates that this module is being loaded
/// implicitly, due to the presence of an inclusion directive. Otherwise,
/// it is being loaded due to an import declaration.
///
/// \returns If successful, returns the loaded module. Otherwise, returns
/// NULL to indicate that the module could not be loaded.
virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
Module::NameVisibilityKind Visibility) = 0;
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective) = 0;
};

}
Expand Down
4 changes: 1 addition & 3 deletions lib/AST/Decl.cpp
Expand Up @@ -2657,9 +2657,7 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC,
Module *Imported,
SourceLocation EndLoc) {
void *Mem = C.Allocate(sizeof(ImportDecl) + sizeof(SourceLocation));
ImportDecl *Import
= new (Mem) ImportDecl(DC, ImportLoc, Imported,
ArrayRef<SourceLocation>(&EndLoc, 1));
ImportDecl *Import = new (Mem) ImportDecl(DC, ImportLoc, Imported, EndLoc);
Import->setImplicit();
return Import;
}
Expand Down
16 changes: 13 additions & 3 deletions lib/Frontend/CompilerInstance.cpp
Expand Up @@ -11,6 +11,7 @@
#include "clang/Sema/Sema.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
Expand Down Expand Up @@ -1070,7 +1071,8 @@ static void compileModule(CompilerInstance &ImportingInstance,

Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
ModuleIdPath Path,
Module::NameVisibilityKind Visibility) {
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective) {
// If we've already handled this import, just return the cached result.
// This one-element cache is important to eliminate redundant diagnostics
// when both the preprocessor and parser see the same import declaration.
Expand Down Expand Up @@ -1259,8 +1261,16 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
}

// Make the named module visible.
if (Module)
ModuleManager->makeModuleVisible(Module, Visibility);
ModuleManager->makeModuleVisible(Module, Visibility);

// If this module import was due to an inclusion directive, create an
// implicit import declaration to capture it in the AST.
if (IsInclusionDirective && hasASTContext()) {
TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
TU->addDecl(ImportDecl::CreateImplicit(getASTContext(), TU,
ImportLoc, Module,
Path.back().second));
}

LastModuleImportLoc = ImportLoc;
LastModuleImportResult = Module;
Expand Down
3 changes: 2 additions & 1 deletion lib/Lex/PPDirectives.cpp
Expand Up @@ -1363,7 +1363,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// If this was an #__include_macros directive, only make macros visible.
Module::NameVisibilityKind Visibility
= (IncludeKind == 3)? Module::MacrosVisible : Module::AllVisible;
TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility);
TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility,
/*IsIncludeDirective=*/true);
return;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/Lex/Preprocessor.cpp
Expand Up @@ -599,7 +599,8 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
// If we have a non-empty module path, load the named module.
if (!ModuleImportPath.empty())
(void)TheModuleLoader.loadModule(ModuleImportLoc, ModuleImportPath,
Module::MacrosVisible);
Module::MacrosVisible,
/*IsIncludeDirective=*/false);
}

void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
Expand Down
3 changes: 2 additions & 1 deletion lib/Sema/SemaDecl.cpp
Expand Up @@ -9893,7 +9893,8 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,

DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc, ModuleIdPath Path) {
Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path,
Module::AllVisible);
Module::AllVisible,
/*IsIncludeDirective=*/false);
if (!Mod)
return true;

Expand Down

0 comments on commit 93ebfa6

Please sign in to comment.