From 467dc88512b4ba4bb16e274ea3771dc1415d31da Mon Sep 17 00:00:00 2001 From: Douglas Gregor <dgregor@apple.com> Date: Thu, 25 Aug 2011 22:30:56 +0000 Subject: [PATCH] Introduce a -cc1 option "-emit-module", that creates a binary module from the given source. -emit-module behaves similarly to -emit-pch, except that Sema is somewhat more strict about the contents of -emit-module. In the future, there are likely to be more interesting differences. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138595 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/LangOptions.h | 12 ++++++++++++ include/clang/Driver/CC1Options.td | 2 ++ include/clang/Frontend/ASTUnit.h | 15 ++++++--------- include/clang/Frontend/CompilerInstance.h | 2 +- include/clang/Frontend/FrontendAction.h | 8 ++++---- include/clang/Frontend/FrontendActions.h | 11 +++++++++-- include/clang/Frontend/FrontendOptions.h | 1 + include/clang/Parse/ParseAST.h | 8 ++++---- include/clang/Sema/Sema.h | 14 ++++++-------- include/clang/Serialization/ASTWriter.h | 2 +- lib/Frontend/ASTMerge.cpp | 4 ++-- lib/Frontend/ASTUnit.cpp | 19 +++++++++---------- lib/Frontend/CompilerInstance.cpp | 4 ++-- lib/Frontend/CompilerInvocation.cpp | 3 +++ lib/Frontend/FrontendAction.cpp | 6 +++--- lib/Frontend/FrontendActions.cpp | 5 +++-- .../ExecuteCompilerInvocation.cpp | 3 ++- lib/Parse/ParseAST.cpp | 4 ++-- lib/Sema/Sema.cpp | 19 +++++++++++++------ lib/Serialization/ChainedIncludesSource.cpp | 2 +- lib/Serialization/GeneratePCH.cpp | 2 +- test/Modules/Inputs/lookup_left.hpp | 4 ++++ test/Modules/lookup.cpp | 5 ++--- test/Modules/lookup.m | 4 ++-- tools/libclang/CIndex.cpp | 7 ++++--- 25 files changed, 99 insertions(+), 67 deletions(-) diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index dc77d4c1496..5cdeda3877d 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -296,6 +296,18 @@ public: } }; +/// \brief Describes the kind of translation unit being processed. +enum TranslationUnitKind { + /// \brief The translation unit is a complete translation unit. + TU_Complete, + /// \brief The translation unit is a prefix to a translation unit, and is + /// not complete. + TU_Prefix, + /// \brief The translation unit is a module. + TU_Module +}; + + /// \brief } // end namespace clang #endif diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 3edd436b7ef..2c3bfc07a09 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -360,6 +360,8 @@ def ast_view : Flag<"-ast-view">, HelpText<"Build ASTs and view them with GraphViz">; def print_decl_contexts : Flag<"-print-decl-contexts">, HelpText<"Print DeclContexts and their Decls">; +def emit_module : Flag<"-emit-module">, + HelpText<"Generate pre-compiled module file">; def emit_pth : Flag<"-emit-pth">, HelpText<"Generate pre-tokenized header file">; def emit_pch : Flag<"-emit-pch">, diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index db3f7ee01c1..08b626facc8 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -112,8 +112,8 @@ private: /// \brief Track whether the main file was loaded from an AST or not. bool MainFileIsAST; - /// \brief Whether this AST represents a complete translation unit. - bool CompleteTranslationUnit; + /// \brief What kind of translation unit this AST represents. + TranslationUnitKind TUKind; /// \brief Whether we should time each operation. bool WantTiming; @@ -548,11 +548,8 @@ public: llvm::MemoryBuffer *getBufferForFile(StringRef Filename, std::string *ErrorStr = 0); - /// \brief Whether this AST represents a complete translation unit. - /// - /// If false, this AST is only a partial translation unit, e.g., one - /// that might still be used as a precompiled header or preamble. - bool isCompleteTranslationUnit() const { return CompleteTranslationUnit; } + /// \brief Determine what kind of translation unit this AST represents. + TranslationUnitKind getTranslationUnitKind() const { return TUKind; } typedef llvm::PointerUnion<const char *, const llvm::MemoryBuffer *> FilenameOrMemBuf; @@ -624,7 +621,7 @@ public: bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, bool PrecompilePreamble = false, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, bool NestedMacroExpansions = true); @@ -652,7 +649,7 @@ public: unsigned NumRemappedFiles = 0, bool RemappedFilesKeepOriginalName = true, bool PrecompilePreamble = false, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, bool CXXPrecompilePreamble = false, bool CXXChainedPCH = false, diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 425f2e7241d..3f97f1addbc 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -548,7 +548,7 @@ public: raw_ostream &OS); /// \brief Create the Sema object to be used for parsing. - void createSema(bool CompleteTranslationUnit, + void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer); /// Create the frontend timer and replace any existing one with it. diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h index 4762e093cf4..f85cc7ec913 100644 --- a/include/clang/Frontend/FrontendAction.h +++ b/include/clang/Frontend/FrontendAction.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H #include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/OwningPtr.h" #include <string> @@ -160,9 +161,8 @@ public: /// file inputs. virtual bool usesPreprocessorOnly() const = 0; - /// usesCompleteTranslationUnit - For AST based actions, should the - /// translation unit be completed? - virtual bool usesCompleteTranslationUnit() { return true; } + /// \brief For AST-based actions, the kind of translation unit we're handling. + virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } /// hasPCHSupport - Does this action support use with PCH? virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); } @@ -282,7 +282,7 @@ public: WrapperFrontendAction(FrontendAction *WrappedAction); virtual bool usesPreprocessorOnly() const; - virtual bool usesCompleteTranslationUnit(); + virtual TranslationUnitKind getTranslationUnitKind(); virtual bool hasPCHSupport() const; virtual bool hasASTFileSupport() const; virtual bool hasIRSupport() const; diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index 646ee2552a4..ef204312c44 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -67,15 +67,22 @@ protected: }; class GeneratePCHAction : public ASTFrontendAction { + bool MakeModule; + protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef InFile); - virtual bool usesCompleteTranslationUnit() { return false; } + virtual TranslationUnitKind getTranslationUnitKind() { + return MakeModule? TU_Module : TU_Prefix; + } virtual bool hasASTFileSupport() const { return false; } public: + /// \brief Create a new action + explicit GeneratePCHAction(bool MakeModule) : MakeModule(MakeModule) { } + /// \brief Compute the AST consumer arguments that will be used to /// create the PCHGenerator instance returned by CreateASTConsumer. /// @@ -128,7 +135,7 @@ public: virtual ~ASTMergeAction(); virtual bool usesPreprocessorOnly() const; - virtual bool usesCompleteTranslationUnit(); + virtual TranslationUnitKind getTranslationUnitKind(); virtual bool hasPCHSupport() const; virtual bool hasASTFileSupport() const; virtual bool hasCodeCompletionSupport() const; diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index e7c2ac4002a..75e3eba80cd 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -35,6 +35,7 @@ namespace frontend { EmitCodeGenOnly, ///< Generate machine code, but don't emit anything. EmitObj, ///< Emit a .o file. FixIt, ///< Parse and apply any fixits to the source. + GenerateModule, ///< Generate pre-compiled module. GeneratePCH, ///< Generate pre-compiled header. GeneratePTH, ///< Generate pre-tokenized header. InitOnly, ///< Only execute frontend initialization. diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h index 0d37e21becd..725387024e1 100644 --- a/include/clang/Parse/ParseAST.h +++ b/include/clang/Parse/ParseAST.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_PARSE_PARSEAST_H #define LLVM_CLANG_PARSE_PARSEAST_H +#include "clang/Basic/LangOptions.h" + namespace clang { class Preprocessor; class ASTConsumer; @@ -27,15 +29,13 @@ namespace clang { /// This operation inserts the parsed decls into the translation /// unit held by Ctx. /// - /// \param CompleteTranslationUnit When true, the parsed file is - /// considered to be a complete translation unit, and any - /// end-of-translation-unit wrapup will be performed. + /// \param TUKind The kind of translation unit being parsed. /// /// \param CompletionConsumer If given, an object to consume code completion /// results. void ParseAST(Preprocessor &pp, ASTConsumer *C, ASTContext &Ctx, bool PrintStats = false, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, CodeCompleteConsumer *CompletionConsumer = 0); /// \brief Parse the main file known to the preprocessor, producing an diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 07bbd18bee8..adf2702cce8 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -630,16 +630,14 @@ public: /// for C++ records. llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache; - /// \brief Whether the code handled by Sema should be considered a - /// complete translation unit or not. + /// \brief The kind of translation unit we are processing. /// - /// When true (which is generally the case), Sema will perform + /// When we're processing a complete translation unit, Sema will perform /// end-of-translation-unit semantic tasks (such as creating /// initializers for tentative definitions in C) once parsing has - /// completed. This flag will be false when building PCH files, - /// since a PCH file is by definition not a complete translation - /// unit. - bool CompleteTranslationUnit; + /// completed. Modules and precompiled headers perform different kinds of + /// checks. + TranslationUnitKind TUKind; llvm::BumpPtrAllocator BumpAlloc; @@ -685,7 +683,7 @@ public: bool isSelfExpr(Expr *RExpr); public: Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, CodeCompleteConsumer *CompletionConsumer = 0); ~Sema(); diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 0bc8e29f8ed..1bb8edb0735 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -641,7 +641,7 @@ protected: const ASTWriter &getWriter() const { return Writer; } public: - PCHGenerator(const Preprocessor &PP, const std::string &OutputFile, + PCHGenerator(const Preprocessor &PP, StringRef OutputFile, bool Chaining, StringRef isysroot, raw_ostream *Out); ~PCHGenerator(); virtual void InitializeSema(Sema &S) { SemaPtr = &S; } diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp index df4650e68f6..74aa5a64a49 100644 --- a/lib/Frontend/ASTMerge.cpp +++ b/lib/Frontend/ASTMerge.cpp @@ -93,8 +93,8 @@ bool ASTMergeAction::usesPreprocessorOnly() const { return AdaptedAction->usesPreprocessorOnly(); } -bool ASTMergeAction::usesCompleteTranslationUnit() { - return AdaptedAction->usesCompleteTranslationUnit(); +TranslationUnitKind ASTMergeAction::getTranslationUnitKind() { + return AdaptedAction->getTranslationUnitKind(); } bool ASTMergeAction::hasPCHSupport() const { diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 71f9c0dada8..b8d9f2f8c20 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -97,7 +97,7 @@ static llvm::sys::cas_flag ActiveASTUnitObjects; ASTUnit::ASTUnit(bool _MainFileIsAST) : OnlyLocalDecls(false), CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST), - CompleteTranslationUnit(true), WantTiming(getenv("LIBCLANG_TIMING")), + TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")), OwnsRemappedFileBuffers(true), NumStoredDiagnosticsFromDriver(0), ConcurrencyCheckValue(CheckUnlocked), @@ -759,8 +759,8 @@ public: TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} virtual bool hasCodeCompletionSupport() const { return false; } - virtual bool usesCompleteTranslationUnit() { - return Unit.isCompleteTranslationUnit(); + virtual TranslationUnitKind getTranslationUnitKind() { + return Unit.getTranslationUnitKind(); } }; @@ -844,7 +844,7 @@ public: virtual bool hasCodeCompletionSupport() const { return false; } virtual bool hasASTFileSupport() const { return false; } - virtual bool usesCompleteTranslationUnit() { return false; } + virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; } }; } @@ -1592,8 +1592,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, AST->Diagnostics = Diags; AST->OnlyLocalDecls = false; AST->CaptureDiagnostics = false; - AST->CompleteTranslationUnit = Action ? Action->usesCompleteTranslationUnit() - : true; + AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete; AST->ShouldCacheCodeCompletionResults = false; AST->Invocation = CI; @@ -1727,7 +1726,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble, - bool CompleteTranslationUnit, + TranslationUnitKind TUKind, bool CacheCodeCompletionResults, bool NestedMacroExpansions) { // Create the AST unit. @@ -1737,7 +1736,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, AST->Diagnostics = Diags; AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; - AST->CompleteTranslationUnit = CompleteTranslationUnit; + AST->TUKind = TUKind; AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; AST->Invocation = CI; AST->NestedMacroExpansions = NestedMacroExpansions; @@ -1762,7 +1761,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, unsigned NumRemappedFiles, bool RemappedFilesKeepOriginalName, bool PrecompilePreamble, - bool CompleteTranslationUnit, + TranslationUnitKind TUKind, bool CacheCodeCompletionResults, bool CXXPrecompilePreamble, bool CXXChainedPCH, @@ -1828,7 +1827,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, AST->FileMgr = new FileManager(AST->FileSystemOpts); AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; - AST->CompleteTranslationUnit = CompleteTranslationUnit; + AST->TUKind = TUKind; AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size(); AST->StoredDiagnostics.swap(StoredDiagnostics); diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 026cb5a3d51..ec8b6dc9105 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -382,10 +382,10 @@ CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, ShowGlobals, OS); } -void CompilerInstance::createSema(bool CompleteTranslationUnit, +void CompilerInstance::createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer) { TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), - CompleteTranslationUnit, CompletionConsumer)); + TUKind, CompletionConsumer)); } // Output Files diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index bc6b08d686a..763c8a1e8bd 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -372,6 +372,7 @@ static const char *getActionName(frontend::ActionKind Kind) { case frontend::EmitCodeGenOnly: return "-emit-codegen-only"; case frontend::EmitObj: return "-emit-obj"; case frontend::FixIt: return "-fixit"; + case frontend::GenerateModule: return "-emit-module"; case frontend::GeneratePCH: return "-emit-pch"; case frontend::GeneratePTH: return "-emit-pth"; case frontend::InitOnly: return "-init-only"; @@ -1205,6 +1206,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, // fall-through! case OPT_fixit: Opts.ProgramAction = frontend::FixIt; break; + case OPT_emit_module: + Opts.ProgramAction = frontend::GenerateModule; break; case OPT_emit_pch: Opts.ProgramAction = frontend::GeneratePCH; break; case OPT_emit_pth: diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp index 0753686a347..b92f75ba43e 100644 --- a/lib/Frontend/FrontendAction.cpp +++ b/lib/Frontend/FrontendAction.cpp @@ -398,7 +398,7 @@ void ASTFrontendAction::ExecuteAction() { CompletionConsumer = &CI.getCodeCompletionConsumer(); if (!CI.hasSema()) - CI.createSema(usesCompleteTranslationUnit(), CompletionConsumer); + CI.createSema(getTranslationUnitKind(), CompletionConsumer); ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats); } @@ -432,8 +432,8 @@ void WrapperFrontendAction::EndSourceFileAction() { bool WrapperFrontendAction::usesPreprocessorOnly() const { return WrappedAction->usesPreprocessorOnly(); } -bool WrapperFrontendAction::usesCompleteTranslationUnit() { - return WrappedAction->usesCompleteTranslationUnit(); +TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() { + return WrappedAction->getTranslationUnitKind(); } bool WrapperFrontendAction::hasPCHSupport() const { return WrappedAction->hasPCHSupport(); diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index d6df141905a..5e2b9c473f0 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -79,12 +79,13 @@ ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, std::string OutputFile; raw_ostream *OS = 0; bool Chaining; - if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS, Chaining)) + if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS, + Chaining)) return 0; if (!CI.getFrontendOpts().RelocatablePCH) Sysroot.clear(); - return new PCHGenerator(CI.getPreprocessor(), OutputFile, Chaining, Sysroot, + return new PCHGenerator(CI.getPreprocessor(), OutputFile, Chaining, Sysroot, OS); } diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp index ed081923f36..a506b410c5c 100644 --- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -50,7 +50,8 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); case EmitObj: return new EmitObjAction(); case FixIt: return new FixItAction(); - case GeneratePCH: return new GeneratePCHAction(); + case GenerateModule: return new GeneratePCHAction(true); + case GeneratePCH: return new GeneratePCHAction(false); case GeneratePTH: return new GeneratePTHAction(); case InitOnly: return new InitOnlyAction(); case ParseSyntaxOnly: return new SyntaxOnlyAction(); diff --git a/lib/Parse/ParseAST.cpp b/lib/Parse/ParseAST.cpp index 5c2c2f785fe..fdd7d0f151a 100644 --- a/lib/Parse/ParseAST.cpp +++ b/lib/Parse/ParseAST.cpp @@ -37,11 +37,11 @@ using namespace clang; /// void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, ASTContext &Ctx, bool PrintStats, - bool CompleteTranslationUnit, + TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer) { llvm::OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer, - CompleteTranslationUnit, + TUKind, CompletionConsumer)); // Recover resources if we crash before exiting this method. diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index f9da82dbb3b..d3ace9dc69e 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -74,7 +74,7 @@ void Sema::ActOnTranslationUnitScope(Scope *S) { } Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, - bool CompleteTranslationUnit, + TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter) : TheTargetAttributesSema(0), FPFeatures(pp.getLangOptions()), LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer), @@ -85,7 +85,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0), GlobalNewDeleteDeclared(false), ObjCShouldCallSuperDealloc(false), - CompleteTranslationUnit(CompleteTranslationUnit), + TUKind(TUKind), NumSFINAEErrors(0), SuppressAccessChecking(false), AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1), @@ -391,9 +391,9 @@ void Sema::LoadExternalWeakUndeclaredIdentifiers() { /// translation unit when EOF is reached and all but the top-level scope is /// popped. void Sema::ActOnEndOfTranslationUnit() { - // At PCH writing, implicit instantiations and VTable handling info are - // stored and performed when the PCH is included. - if (CompleteTranslationUnit) { + // Only complete translation units define vtables and perform implicit + // instantiations. + if (TUKind == TU_Complete) { // If any dynamic classes have their key function defined within // this translation unit, then those vtables are considered "used" and must // be emitted. @@ -435,7 +435,8 @@ void Sema::ActOnEndOfTranslationUnit() { this)), UnusedFileScopedDecls.end()); - if (!CompleteTranslationUnit) { + if (TUKind == TU_Prefix) { + // Translation unit prefixes don't need any of the checking below. TUScope = 0; return; } @@ -453,6 +454,12 @@ void Sema::ActOnEndOfTranslationUnit() { << I->first; } + if (TUKind == TU_Module) { + // Modules don't need any of the checking below. + TUScope = 0; + return; + } + // C99 6.9.2p2: // A declaration of an identifier for an object that has file // scope without an initializer, and without a storage-class diff --git a/lib/Serialization/ChainedIncludesSource.cpp b/lib/Serialization/ChainedIncludesSource.cpp index 454e4194abd..4ee1c1667fd 100644 --- a/lib/Serialization/ChainedIncludesSource.cpp +++ b/lib/Serialization/ChainedIncludesSource.cpp @@ -111,7 +111,7 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) { Clang->getASTContext().setASTMutationListener( consumer->GetASTMutationListener()); Clang->setASTConsumer(consumer.take()); - Clang->createSema(/*CompleteTranslationUnit=*/false, 0); + Clang->createSema(TU_Prefix, 0); if (firstInclude) { Preprocessor &PP = Clang->getPreprocessor(); diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp index 3f3674e6166..ac395bb2d6f 100644 --- a/lib/Serialization/GeneratePCH.cpp +++ b/lib/Serialization/GeneratePCH.cpp @@ -27,7 +27,7 @@ using namespace clang; PCHGenerator::PCHGenerator(const Preprocessor &PP, - const std::string &OutputFile, + StringRef OutputFile, bool Chaining, StringRef isysroot, raw_ostream *OS) diff --git a/test/Modules/Inputs/lookup_left.hpp b/test/Modules/Inputs/lookup_left.hpp index b5b1e729a9c..66d6206137b 100644 --- a/test/Modules/Inputs/lookup_left.hpp +++ b/test/Modules/Inputs/lookup_left.hpp @@ -1 +1,5 @@ int *f0(int*); + +#pragma weak weak_identifier // expected-warning{{weak identifier 'weak_identifier' never declared}} + + diff --git a/test/Modules/lookup.cpp b/test/Modules/lookup.cpp index ca12a281af8..e9f52b7c669 100644 --- a/test/Modules/lookup.cpp +++ b/test/Modules/lookup.cpp @@ -1,4 +1,3 @@ - void test(int i, float f) { // unqualified lookup f0(&i); @@ -9,8 +8,8 @@ void test(int i, float f) { ::f0(&f); } -// RUN: %clang_cc1 -emit-pch -x c++ -o %t_lookup_left.h.pch %S/Inputs/lookup_left.hpp -// RUN: %clang_cc1 -emit-pch -x c++ -o %t_lookup_right.h.pch %S/Inputs/lookup_right.hpp +// RUN: %clang_cc1 -emit-module -x c++ -verify -o %t_lookup_left.h.pch %S/Inputs/lookup_left.hpp +// RUN: %clang_cc1 -emit-module -x c++ -o %t_lookup_right.h.pch %S/Inputs/lookup_right.hpp // RUN: %clang_cc1 -x c++ -import-module %t_lookup_left.h.pch -import-module %t_lookup_right.h.pch -verify %s // RUN: %clang_cc1 -ast-print -x c++ -import-module %t_lookup_left.h.pch -import-module %t_lookup_right.h.pch %s | FileCheck -check-prefix=CHECK-PRINT %s diff --git a/test/Modules/lookup.m b/test/Modules/lookup.m index bdffd44b910..85f1dd95d75 100644 --- a/test/Modules/lookup.m +++ b/test/Modules/lookup.m @@ -6,8 +6,8 @@ void test(id x) { [x method]; // expected-warning{{multiple methods named 'method' found}} } -// RUN: %clang_cc1 -emit-pch -x objective-c -o %t_lookup_left.h.pch %S/Inputs/lookup_left.h -// RUN: %clang_cc1 -emit-pch -x objective-c -o %t_lookup_right.h.pch %S/Inputs/lookup_right.h +// RUN: %clang_cc1 -emit-module -x objective-c -o %t_lookup_left.h.pch %S/Inputs/lookup_left.h +// RUN: %clang_cc1 -emit-module -x objective-c -o %t_lookup_right.h.pch %S/Inputs/lookup_right.h // RUN: %clang_cc1 -x objective-c -import-module %t_lookup_left.h.pch -import-module %t_lookup_right.h.pch -verify %s // RUN: %clang_cc1 -ast-print -x objective-c -import-module %t_lookup_left.h.pch -import-module %t_lookup_right.h.pch %s | FileCheck -check-prefix=CHECK-PRINT %s diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index f1f2cb10adf..5837e0412d9 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2462,8 +2462,9 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble; - bool CompleteTranslationUnit - = ((options & CXTranslationUnit_Incomplete) == 0); + // FIXME: Add a flag for modules. + TranslationUnitKind TUKind + = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete; bool CacheCodeCompetionResults = options & CXTranslationUnit_CacheCompletionResults; bool CXXPrecompilePreamble @@ -2553,7 +2554,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { RemappedFiles->size(), /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, - CompleteTranslationUnit, + TUKind, CacheCodeCompetionResults, CXXPrecompilePreamble, CXXChainedPCH, -- GitLab