Initial support for loading Clang modules into Swift.

From a user's perspective, one imports Clang modules using the normal
Swift syntax for module imports, e.g.,

  import Cocoa

However, to enable importing Clang modules, one needs to point Swift
at a particular SDK with the -sdk= argument, e.g.,

  swift -sdk=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9M.sdk

and, of course, that SDK needs to provide support for modules.

There are a number of moving parts here. The major pieces are:

CMake support for linking Clang into Swift: CMake users will now need
to set the SWIFT_PATH_TO_CLANG_SOURCE and SWIFT_PATH_TO_CLANG_BUILD
to the locations of the Clang source tree (which defaults to
tools/clang under your LLVM source tree) and the Clang build tree.

Makefile support for linking Clang into Swift: Makefile users will
need to have Clang located in tools/clang and Swift located in
tools/swift, and builds should just work.

Module loader abstraction: similar to Clang's module loader,
a module loader is responsible for resolving a module name to an
actual module, loading that module in the process. It will also be
responsible for performing name lookup into that module.

Clang importer: the only implementation of the module loader
abstraction, the importer creates a Clang compiler instance capable of
building and loading Clang modules. The approach we take here is to
parse a dummy .m file in Objective-C ARC mode with modules enabled,
but never tear down that compilation unit. Then, when we get a request
to import a Clang module, we turn that into a module-load request to
Clang's module loader, which will build an appropriate module
on-the-fly or used a cached module file.

Note that name lookup into Clang modules is not yet
implemented. That's the next major step.



Swift SVN r3199
This commit is contained in:
Doug Gregor
2012-11-16 18:17:05 +00:00
parent b1c3995fdc
commit bb26f52585
25 changed files with 664 additions and 31 deletions

View File

@@ -15,7 +15,9 @@
//===----------------------------------------------------------------------===//
#include "swift/AST/Module.h"
#include "swift/AST/ModuleLoader.h"
#include "swift/AST/AST.h"
#include "clang/Basic/Module.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/TinyPtrVector.h"
@@ -201,11 +203,13 @@ ArrayRef<ExtensionDecl*> Module::lookupExtensions(Type T) {
// The builtin module just has free functions, not extensions.
if (isa<BuiltinModule>(this)) return ArrayRef<ExtensionDecl*>();
TUExtensionCache &Cache =
getTUExtensionCachePimpl(ExtensionCachePimpl, *cast<TranslationUnit>(this));
return Cache.getExtensions(T->getCanonicalType());
if (auto tu = dyn_cast<TranslationUnit>(this)) {
TUExtensionCache &Cache = getTUExtensionCachePimpl(ExtensionCachePimpl,*tu);
return Cache.getExtensions(T->getCanonicalType());
}
return Ctx.getModuleLoader().lookupExtensions(cast<ClangModule>(this), T);
}
//===----------------------------------------------------------------------===//
@@ -224,12 +228,15 @@ void Module::lookupValue(AccessPathTy AccessPath, Identifier Name,
return getBuiltinCachePimpl(LookupCachePimpl)
.lookupValue(Name, LookupKind, *BM, Result);
}
// Otherwise must be TranslationUnit. Someday we should generalize this to
// allow modules with multiple translation units.
TranslationUnit &TU = *cast<TranslationUnit>(this);
return getTUCachePimpl(LookupCachePimpl, TU)
.lookupValue(AccessPath, Name, LookupKind, TU, Result);
if (auto TU = dyn_cast<TranslationUnit>(this)) {
// Look in the translation unit.
return getTUCachePimpl(LookupCachePimpl, *TU)
.lookupValue(AccessPath, Name, LookupKind, *TU, Result);
}
return Ctx.getModuleLoader().lookupValue(cast<ClangModule>(this), AccessPath,
Name, LookupKind, Result);
}
//===----------------------------------------------------------------------===//
@@ -240,3 +247,21 @@ void TranslationUnit::clearLookupCache() {
freeTUCachePimpl(LookupCachePimpl);
freeTUExtensionCachePimpl(ExtensionCachePimpl);
}
//===----------------------------------------------------------------------===//
// ClangModule Implementation
//===----------------------------------------------------------------------===//
ClangModule::ClangModule(ASTContext &ctx, Component *comp,
clang::Module *clangModule)
: Module(DeclContextKind::ClangModule,
ctx.getIdentifier(clangModule->getFullModuleName()),
comp, ctx),
clangModule(clangModule)
{
}
//===----------------------------------------------------------------------===//
// ModuleLoader Implementation
//===----------------------------------------------------------------------===//
ModuleLoader::~ModuleLoader() {}