diff options
25 files changed, 313 insertions, 69 deletions
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 4b5de366cb..62d852572a 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -59,7 +59,8 @@ def err_friends_define_only_namespace_scope : Error< "cannot define a function with non-namespace scope in a friend declaration">; def err_deleted_non_function : Error< "only functions can have deleted definitions">; - +def warn_module_not_found : Warning<"module '%0' not found">, DefaultFatal; + // Sema && Lex def ext_longlong : Extension< "'long long' is an extension when C99 mode is not enabled">, diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 27b4f850ee..9a6e7545b4 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -569,5 +569,11 @@ def err_seh___except_filter : Error< def err_seh___finally_block : Error< "%0 only allowed in __finally block">; +// Modules +def err_module_expected_ident : Error< + "expected a module name after '__import__'">; +def err_module_expected_semi : Error< + "expected a semicolon name after module name">; + } // end of Parse Issue category. } // end of Parser diagnostics diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 017af5caee..9238d3daa7 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -252,7 +252,7 @@ private: void RecomputeNeedsHandleIdentifier() { NeedsHandleIdentifier = (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | - isExtensionToken()); + isExtensionToken() | getTokenID() == tok::kw___import__); } }; diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index e0b22b7b24..ccc2e612b2 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -397,6 +397,7 @@ KEYWORD(__array_extent , KEYCXX) // Apple Extension. KEYWORD(__private_extern__ , KEYALL) +KEYWORD(__import__ , KEYALL) // Microsoft Extension. KEYWORD(__declspec , KEYALL) diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 190ab85713..731ce383fc 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -18,6 +18,7 @@ #include "clang/Serialization/ASTBitCodes.h" #include "clang/Sema/Sema.h" #include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Lex/ModuleLoader.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" @@ -66,7 +67,7 @@ class GlobalCodeCompletionAllocator /// \brief Utility class for loading a ASTContext from an AST file. /// -class ASTUnit { +class ASTUnit : public ModuleLoader { public: typedef std::map<FileID, std::vector<PreprocessedEntity *> > PreprocessedEntitiesByFileMap; @@ -696,6 +697,13 @@ public: /// /// \returns True if an error occurred, false otherwise. bool serialize(raw_ostream &OS); + + virtual ModuleKey loadModule(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc) { + // ASTUnit doesn't know how to load modules (not that this matters). + return 0; + } }; } // namespace clang diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 3f97f1addb..88f8976b67 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ #include "clang/Frontend/CompilerInvocation.h" +#include "clang/Lex/ModuleLoader.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/OwningPtr.h" @@ -56,7 +57,7 @@ class TargetInfo; /// in to the compiler instance for everything. When possible, utility functions /// come in two forms; a short form that reuses the CompilerInstance objects, /// and a long form that takes explicit instances of any required objects. -class CompilerInstance { +class CompilerInstance : public ModuleLoader { /// The options used in this compiler instance. llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation; @@ -498,20 +499,6 @@ public: /// and replace any existing one with it. void createPreprocessor(); - /// Create a Preprocessor object. - /// - /// Note that this also creates a new HeaderSearch object which will be owned - /// by the resulting Preprocessor. - /// - /// \return The new object on success, or null on failure. - static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &, - const PreprocessorOptions &, - const HeaderSearchOptions &, - const DependencyOutputOptions &, - const TargetInfo &, - const FrontendOptions &, - SourceManager &, FileManager &); - /// Create the AST context. void createASTContext(); @@ -626,6 +613,10 @@ public: const FrontendOptions &Opts); /// } + + virtual ModuleKey loadModule(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc); }; } // end namespace clang diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h index e69de29bb2..72ec0e3ebc 100644 --- a/include/clang/Lex/ModuleLoader.h +++ b/include/clang/Lex/ModuleLoader.h @@ -0,0 +1,55 @@ +//===--- ModuleLoader.h - Module Loader Interface ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ModuleLoader interface, which is responsible for +// loading named modules. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LEX_MODULE_LOADER_H +#define LLVM_CLANG_LEX_MODULE_LOADER_H + +#include "clang/Basic/SourceLocation.h" + +namespace clang { + +class IdentifierInfo; + +/// \brief An opaque key that is used to describe the module and can be +/// interpreted by the module loader itself. +typedef void *ModuleKey; + +/// \brief Abstract interface for a module loader. +/// +/// This abstract interface describes a module loader, which is responsible +/// for resolving a module name (e.g., "std") to an actual module file, and +/// then loading that module. +class ModuleLoader { +public: + virtual ~ModuleLoader(); + + /// \brief Attempt to load the given module. + /// + /// This routine attempts to load the module described by the given + /// parameters. + /// + /// \param ImportLoc The location of the 'import' keyword. + /// \param ModuleName The name of the module to be loaded. + /// \param ModuleNameLoc The location of the module name. + /// + /// \returns If successful, a non-NULL module key describing this module. + /// Otherwise, returns NULL to indicate that the module could not be + /// loaded. + virtual ModuleKey loadModule(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc) = 0; +}; + +} + +#endif diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index a95645451e..1ab6411e98 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -49,6 +49,7 @@ class PPCallbacks; class CodeCompletionHandler; class DirectoryLookup; class PreprocessingRecord; +class ModuleLoader; /// Preprocessor - This object engages in a tight little dance with the lexer to /// efficiently preprocess tokens. Lexers know only about tokens within a @@ -63,10 +64,12 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { SourceManager &SourceMgr; ScratchBuffer *ScratchBuf; HeaderSearch &HeaderInfo; + ModuleLoader &TheModuleLoader; /// \brief External source of macros. ExternalPreprocessorSource *ExternalSource; + /// PTH - An optional PTHManager object used for getting tokens from /// a token cache rather than lexing the original source file. llvm::OwningPtr<PTHManager> PTH; @@ -294,6 +297,7 @@ public: Preprocessor(Diagnostic &diags, const LangOptions &opts, const TargetInfo &target, SourceManager &SM, HeaderSearch &Headers, + ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup = 0, bool OwnsHeaderSearch = false); @@ -325,6 +329,9 @@ public: return ExternalSource; } + /// \brief Retrieve the module loader associated with this preprocessor. + ModuleLoader &getModuleLoader() const { return TheModuleLoader; } + /// SetCommentRetentionState - Control whether or not the preprocessor retains /// comments in output. void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) { @@ -1008,6 +1015,9 @@ private: /// the macro should not be expanded return true, otherwise return false. bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI); + /// \brief Handle a module import directive. + void HandleModuleImport(Token &Import); + /// \brief Cache macro expanded tokens for TokenLexers. // /// Works like a stack; a TokenLexer adds the macro expanded tokens that is diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 1215e2daa7..e5a129beb3 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -1916,6 +1916,10 @@ bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, SourceLocation &DeclEnd); //===--------------------------------------------------------------------===// + // Modules + DeclGroupPtrTy ParseModuleImport(); + + //===--------------------------------------------------------------------===// // GNU G++: Type Traits [Type-Traits.html in the GCC manual] ExprResult ParseUnaryTypeTrait(); ExprResult ParseBinaryTypeTrait(); diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index adf2702cce..2e49840d0e 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1073,6 +1073,17 @@ public: SourceLocation AsmLoc, SourceLocation RParenLoc); + /// \brief The parser has processed a module import declaration. + /// + /// \param ImportLoc The location of the '__import__' keyword. + /// + /// \param ModuleName The name of the module. + /// + /// \param ModuleNameLoc The location of the module name. + DeclResult ActOnModuleImport(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc); + /// Scope actions. void ActOnPopScope(SourceLocation Loc, Scope *S); void ActOnTranslationUnitScope(Scope *S); diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 4a5a29a9c9..7f25a0045e 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -616,7 +616,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, AST->Target = TargetInfo::CreateTargetInfo(AST->getDiagnostics(), TargetOpts); AST->PP = new Preprocessor(AST->getDiagnostics(), LangInfo, *AST->Target, - AST->getSourceManager(), HeaderInfo); + AST->getSourceManager(), HeaderInfo, *AST); Preprocessor &PP = *AST->PP; PP.setPredefines(Reader->getSuggestedPredefines()); diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index ec8b6dc910..f53d0b064c 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -191,52 +191,38 @@ void CompilerInstance::createSourceManager(FileManager &FileMgr) { // Preprocessor void CompilerInstance::createPreprocessor() { - PP = createPreprocessor(getDiagnostics(), getLangOpts(), - getPreprocessorOpts(), getHeaderSearchOpts(), - getDependencyOutputOpts(), getTarget(), - getFrontendOpts(), getSourceManager(), - getFileManager()); -} - -Preprocessor * -CompilerInstance::createPreprocessor(Diagnostic &Diags, - const LangOptions &LangInfo, - const PreprocessorOptions &PPOpts, - const HeaderSearchOptions &HSOpts, - const DependencyOutputOptions &DepOpts, - const TargetInfo &Target, - const FrontendOptions &FEOpts, - SourceManager &SourceMgr, - FileManager &FileMgr) { + const PreprocessorOptions &PPOpts = getPreprocessorOpts(); + // Create a PTH manager if we are using some form of a token cache. PTHManager *PTHMgr = 0; if (!PPOpts.TokenCache.empty()) - PTHMgr = PTHManager::Create(PPOpts.TokenCache, Diags); - + PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); + // Create the Preprocessor. - HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr); - Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target, - SourceMgr, *HeaderInfo, PTHMgr, - /*OwnsHeaderSearch=*/true); - + HeaderSearch *HeaderInfo = new HeaderSearch(getFileManager()); + PP = new Preprocessor(getDiagnostics(), getLangOpts(), getTarget(), + getSourceManager(), *HeaderInfo, *this, PTHMgr, + /*OwnsHeaderSearch=*/true); + // Note that this is different then passing PTHMgr to Preprocessor's ctor. // That argument is used as the IdentifierInfoLookup argument to // IdentifierTable's ctor. if (PTHMgr) { - PTHMgr->setPreprocessor(PP); + PTHMgr->setPreprocessor(&*PP); PP->setPTHManager(PTHMgr); } - + if (PPOpts.DetailedRecord) PP->createPreprocessingRecord( - PPOpts.DetailedRecordIncludesNestedMacroExpansions); + PPOpts.DetailedRecordIncludesNestedMacroExpansions); + + InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts()); - InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts); - // Handle generating dependencies, if requested. + const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); if (!DepOpts.OutputFile.empty()) AttachDependencyFileGen(*PP, DepOpts); - + // Handle generating header include information, if requested. if (DepOpts.ShowHeaderIncludes) AttachHeaderIncludeGen(*PP); @@ -247,8 +233,6 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags, AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath, /*ShowDepth=*/false); } - - return PP; } // ASTContext @@ -640,4 +624,68 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { return !getDiagnostics().getClient()->getNumErrors(); } +ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc) { + // Determine what file we're searching from. + SourceManager &SourceMgr = getSourceManager(); + SourceLocation ExpandedImportLoc = SourceMgr.getExpansionLoc(ImportLoc); + const FileEntry *CurFile + = SourceMgr.getFileEntryForID(SourceMgr.getFileID(ExpandedImportLoc)); + if (!CurFile) + CurFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); + + // Search for a module with the given name. + std::string Filename = ModuleName.getName().str(); + Filename += ".pcm"; + const DirectoryLookup *CurDir = 0; + const FileEntry *ModuleFile + = PP->getHeaderSearchInfo().LookupFile(Filename, /*isAngled=*/false, + /*FromDir=*/0, CurDir, CurFile, + /*SearchPath=*/0, + /*RelativePath=*/0); + if (!ModuleFile) { + getDiagnostics().Report(ModuleNameLoc, diag::warn_module_not_found) + << ModuleName.getName() + << SourceRange(ImportLoc, ModuleNameLoc); + return 0; + } + + // If we don't already have an ASTReader, create one now. + if (!ModuleManager) { + std::string Sysroot = getHeaderSearchOpts().Sysroot; + const PreprocessorOptions &PPOpts = getPreprocessorOpts(); + ModuleManager = new ASTReader(getPreprocessor(), &*Context, + Sysroot.empty() ? "" : Sysroot.c_str(), + PPOpts.DisablePCHValidation, + PPOpts.DisableStatCache); + ModuleManager->setDeserializationListener( + getASTConsumer().GetASTDeserializationListener()); + getASTContext().setASTMutationListener( + getASTConsumer().GetASTMutationListener()); + llvm::OwningPtr<ExternalASTSource> Source; + Source.reset(ModuleManager); + getASTContext().setExternalSource(Source); + ModuleManager->InitializeSema(getSema()); + } + + // Try to load the module we found. + switch (ModuleManager->ReadAST(ModuleFile->getName(), + serialization::MK_Module)) { + case ASTReader::Success: + break; + + case ASTReader::IgnorePCH: + // FIXME: The ASTReader will already have complained, but can we showhorn + // that diagnostic information into a more useful form? + return 0; + + case ASTReader::Failure: + // Already complained. + return 0; + } + + // FIXME: The module file's FileEntry makes a poor key indeed! + return (ModuleKey)ModuleFile; +} diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index 1ec50cd2c5..64b8744922 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -1277,6 +1277,7 @@ FinishIdentifier: // preprocessor, which may macro expand it or something. if (II->isHandleIdentifierCase()) PP->HandleIdentifier(Result); + return; } diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 24d36cdb25..1d1687d84b 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -35,6 +35,7 @@ #include "clang/Lex/ScratchBuffer.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/CodeCompletionHandler.h" +#include "clang/Lex/ModuleLoader.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/TargetInfo.h" @@ -50,12 +51,12 @@ ExternalPreprocessorSource::~ExternalPreprocessorSource() { } Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, const TargetInfo &target, SourceManager &SM, - HeaderSearch &Headers, + HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup* IILookup, bool OwnsHeaders) : Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()), - SourceMgr(SM), - HeaderInfo(Headers), ExternalSource(0), + SourceMgr(SM), HeaderInfo(Headers), TheModuleLoader(TheModuleLoader), + ExternalSource(0), Identifiers(opts, IILookup), BuiltinInfo(Target), CodeComplete(0), CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0), CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0), @@ -483,7 +484,7 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) { if (MI->isEnabled()) { if (!HandleMacroExpandedIdentifier(Identifier, MI)) - return; + goto finish; } else { // C99 6.10.3.4p2 says that a disabled macro may never again be // expanded, even if it's in a context where it could be expanded in the @@ -505,6 +506,33 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { // like "#define TY typeof", "TY(1) x". if (II.isExtensionToken() && !DisableMacroExpansion) Diag(Identifier, diag::ext_token_used); + +finish: + // If we have the start of a module import, handle it now. + if (Identifier.is(tok::kw___import__) && + !InMacroArgs && !DisableMacroExpansion) + HandleModuleImport(Identifier); +} + +void Preprocessor::HandleModuleImport(Token &Import) { + // The token sequence + // + // __import__ identifier + // + // indicates a module import directive. We load the module and then + // leave the token sequence for the parser. + Token ModuleNameTok = LookAhead(0); + if (ModuleNameTok.getKind() != tok::identifier) + return; + + (void)TheModuleLoader.loadModule(Import.getLocation(), + *ModuleNameTok.getIdentifierInfo(), + ModuleNameTok.getLocation()); + + // FIXME: Transmogrify __import__ into some kind of AST-only __import__ that + // is not recognized by the preprocessor but is recognized by the parser. + // It would also be useful to stash the ModuleKey somewhere, so we don't try + // to load the module twice. } void Preprocessor::AddCommentHandler(CommentHandler *Handler) { @@ -535,6 +563,8 @@ bool Preprocessor::HandleComment(Token &result, SourceRange Comment) { return true; } +ModuleLoader::~ModuleLoader() { } + CommentHandler::~CommentHandler() { } CodeCompletionHandler::~CodeCompletionHandler() { } diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 0da2b4302c..39edab1911 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -679,6 +679,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, ParseMicrosoftIfExistsExternalDeclaration(); return DeclGroupPtrTy(); + case tok::kw___import__: + return ParseModuleImport(); + default: dont_know: // We can't tell whether this is a function-definition or declaration yet. @@ -1541,3 +1544,24 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() { } ConsumeBrace(); } + +Parser::DeclGroupPtrTy Parser::ParseModuleImport() { + assert(Tok.is(tok::kw___import__) && "Improper start to module import"); + SourceLocation ImportLoc = ConsumeToken(); + + // Parse the module name. + if (!Tok.is(tok::identifier)) { + Diag(Tok, diag::err_module_expected_ident); + SkipUntil(tok::semi); + return DeclGroupPtrTy(); + } + + IdentifierInfo &ModuleName = *Tok.getIdentifierInfo(); + SourceLocation ModuleNameLoc = ConsumeToken(); + DeclResult Import = Actions.ActOnModuleImport(ImportLoc, ModuleName, ModuleNameLoc); + ExpectAndConsumeSemi(diag::err_module_expected_semi); + if (Import.isInvalid()) + return DeclGroupPtrTy(); + + return Actions.ConvertDeclToDeclGroup(Import.get()); +} diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9f43aa2f05..8f08af4778 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -38,6 +38,7 @@ // FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's) #include "clang/Lex/Preprocessor.h" #include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/ModuleLoader.h" #include "llvm/ADT/Triple.h" #include <algorithm> #include <cstring> @@ -9294,6 +9295,19 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, return New; } +DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc) { + ModuleKey Module = PP.getModuleLoader().loadModule(ImportLoc, + ModuleName, ModuleNameLoc); + if (!Module) + return true; + + // FIXME: Actually create a declaration to describe the module import. + (void)Module; + return DeclResult((Decl *)0); +} + void Sema::ActOnPragmaWeakID(IdentifierInfo* Name, SourceLocation PragmaLoc, SourceLocation NameLoc) { diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c index b89ce41032..e29fbeadf9 100644 --- a/test/Misc/warning-flags.c +++ b/test/Misc/warning-flags.c @@ -17,7 +17,7 @@ This test serves two purposes: The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (312): +CHECK: Warnings without flags (313): CHECK-NEXT: auto_storage_class CHECK-NEXT: backslash_newline_space CHECK-NEXT: charize_microsoft_ext @@ -230,6 +230,7 @@ CHECK-NEXT: warn_missing_case_for_condition CHECK-NEXT: warn_missing_dependent_template_keyword CHECK-NEXT: warn_missing_exception_specification CHECK-NEXT: warn_missing_whitespace_after_macro_name +CHECK-NEXT: warn_module_not_found CHECK-NEXT: warn_multiple_method_decl CHECK-NEXT: warn_no_constructor_for_refconst CHECK-NEXT: warn_nonnull_pointers_only diff --git a/test/Modules/Inputs/diamond_bottom.h b/test/Modules/Inputs/diamond_bottom.h index 40afc9b152..6351d028fb 100644 --- a/test/Modules/Inputs/diamond_bottom.h +++ b/test/Modules/Inputs/diamond_bottom.h @@ -1 +1,4 @@ +__import__ diamond_left; +__import__ diamond_right; + char bottom(char *x); diff --git a/test/Modules/Inputs/diamond_left.h b/test/Modules/Inputs/diamond_left.h index 9758b85d97..8da494ccca 100644 --- a/test/Modules/Inputs/diamond_left.h +++ b/test/Modules/Inputs/diamond_left.h @@ -1,3 +1,5 @@ +__import__ diamond_top; + float left(float *); int top_left(char *c); diff --git a/test/Modules/Inputs/diamond_right.h b/test/Modules/Inputs/diamond_right.h index 9adeb6a9a8..2efa277b1a 100644 --- a/test/Modules/Inputs/diamond_right.h +++ b/test/Modules/Inputs/diamond_right.h @@ -1,3 +1,5 @@ +__import__ diamond_top; + double right(double *); struct left_and_right { diff --git a/test/Modules/Inputs/load_failure.h b/test/Modules/Inputs/load_failure.h new file mode 100644 index 0000000000..5bcb44dcb3 --- /dev/null +++ b/test/Modules/Inputs/load_failure.h @@ -0,0 +1 @@ +int fail(int); diff --git a/test/Modules/diamond.c b/test/Modules/diamond.c index f9b283a9d2..94381f2033 100644 --- a/test/Modules/diamond.c +++ b/test/Modules/diamond.c @@ -1,4 +1,10 @@ + + + // in diamond-bottom.h: expected-note{{passing argument to parameter 'x' here}} + +__import__ diamond_bottom; + void test_diamond(int i, float f, double d, char c) { top(&i); left(&f); @@ -14,8 +20,8 @@ void test_diamond(int i, float f, double d, char c) { lr.left = 17; } -// RUN: %clang_cc1 -emit-pch -o %t_top.h.pch %S/Inputs/diamond_top.h -// RUN: %clang_cc1 -import-module %t_top.h.pch -emit-pch -o %t_left.h.pch %S/Inputs/diamond_left.h -// RUN: %clang_cc1 -import-module %t_top.h.pch -emit-pch -o %t_right.h.pch %S/Inputs/diamond_right.h -// RUN: %clang_cc1 -import-module %t_left.h.pch -import-module %t_right.h.pch -emit-pch -o %t_bottom.h.pch %S/Inputs/diamond_bottom.h -// RUN: %clang_cc1 -import-module %t_bottom.h.pch -verify %s +// RUN: %clang_cc1 -emit-module -o %T/diamond_top.pcm %S/Inputs/diamond_top.h |