r267802 - [modules] When diagnosing a missing module import, suggest adding a #include if
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 27 14:57:06 PDT 2016
Author: rsmith
Date: Wed Apr 27 16:57:05 2016
New Revision: 267802
URL: http://llvm.org/viewvc/llvm-project?rev=267802&view=rev
Log:
[modules] When diagnosing a missing module import, suggest adding a #include if
the current language doesn't have an import syntax and we can figure out a
suitable file to include.
Added:
cfe/trunk/test/Modules/Inputs/suggest-include/
cfe/trunk/test/Modules/Inputs/suggest-include/empty.h
cfe/trunk/test/Modules/Inputs/suggest-include/module.modulemap
cfe/trunk/test/Modules/Inputs/suggest-include/private1.h
cfe/trunk/test/Modules/Inputs/suggest-include/private2.h
cfe/trunk/test/Modules/Inputs/suggest-include/private3.h
cfe/trunk/test/Modules/Inputs/suggest-include/textual1.h
cfe/trunk/test/Modules/Inputs/suggest-include/textual2.h
cfe/trunk/test/Modules/Inputs/suggest-include/textual3.h
cfe/trunk/test/Modules/Inputs/suggest-include/textual4.h
cfe/trunk/test/Modules/Inputs/suggest-include/textual5.h
cfe/trunk/test/Modules/Inputs/suggest-include/useprivate1.h
cfe/trunk/test/Modules/Inputs/suggest-include/useprivate3.h
cfe/trunk/test/Modules/Inputs/suggest-include/usetextual1.h
cfe/trunk/test/Modules/Inputs/suggest-include/usetextual2.h
cfe/trunk/test/Modules/Inputs/suggest-include/usetextual3.h
cfe/trunk/test/Modules/Inputs/suggest-include/usetextual4.h
cfe/trunk/test/Modules/Inputs/suggest-include/usetextual5.h
cfe/trunk/test/Modules/suggest-include.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Lex/HeaderSearch.h
cfe/trunk/include/clang/Lex/ModuleMap.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Lex/HeaderSearch.cpp
cfe/trunk/lib/Lex/ModuleMap.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=267802&r1=267801&r2=267802&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr 27 16:57:05 2016
@@ -8262,6 +8262,10 @@ def err_module_private_local_class : Err
def err_module_unimported_use : Error<
"%select{declaration|definition|default argument}0 of %1 must be imported "
"from module '%2' before it is required">;
+def err_module_unimported_use_header : Error<
+ "missing '#include %3'; "
+ "%select{declaration|definition|default argument}0 of %1 must be imported "
+ "from module '%2' before it is required">;
def err_module_unimported_use_multiple : Error<
"%select{declaration|definition|default argument}0 of %1 must be imported "
"from one of the following modules before it is required:%2">;
Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=267802&r1=267801&r2=267802&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Wed Apr 27 16:57:05 2016
@@ -634,13 +634,18 @@ public:
/// \brief Retrieve a uniqued framework name.
StringRef getUniqueFrameworkName(StringRef Framework);
+ /// \brief Suggest a path by which the specified file could be found, for
+ /// use in diagnostics to suggest a #include.
+ ///
+ /// \param IsSystem If non-null, filled in to indicate whether the suggested
+ /// path is relative to a system header directory.
+ std::string suggestPathToFileForDiagnostics(const FileEntry *File,
+ bool *IsSystem = nullptr);
+
void PrintStats();
size_t getTotalMemory() const;
- static std::string NormalizeDashIncludePath(StringRef File,
- FileManager &FileMgr);
-
private:
/// \brief Describes what happened when we tried to load a module map file.
enum LoadModuleMapResult {
Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=267802&r1=267801&r2=267802&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Wed Apr 27 16:57:05 2016
@@ -130,6 +130,12 @@ public:
return getModule()->isAvailable();
}
+ /// \brief Whether this header is accessible from the specified module.
+ bool isAccessibleFrom(Module *M) const {
+ return !(getRole() & PrivateHeader) ||
+ (M && M->getTopLevelModule() == getModule()->getTopLevelModule());
+ }
+
// \brief Whether this known header is valid (i.e., it has an
// associated module).
explicit operator bool() const {
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=267802&r1=267801&r2=267802&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Wed Apr 27 16:57:05 2016
@@ -1891,6 +1891,19 @@ public:
/// directly or indirectly.
Module *getModuleContainingLocation(SourceLocation Loc);
+ /// \brief We want to produce a diagnostic at location IncLoc concerning a
+ /// missing module import.
+ ///
+ /// \param IncLoc The location at which the missing import was detected.
+ /// \param MLoc A location within the desired module at which some desired
+ /// effect occurred (eg, where a desired entity was declared).
+ ///
+ /// \return A file that can be #included to import a module containing MLoc.
+ /// Null if no such file could be determined or if a #include is not
+ /// appropriate.
+ const FileEntry *getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
+ SourceLocation MLoc);
+
private:
// Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=267802&r1=267801&r2=267802&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Wed Apr 27 16:57:05 2016
@@ -1419,3 +1419,54 @@ void HeaderSearch::loadSubdirectoryModul
SearchDir.setSearchedAllModuleMaps(true);
}
+
+std::string HeaderSearch::suggestPathToFileForDiagnostics(const FileEntry *File,
+ bool *IsSystem) {
+ // FIXME: We assume that the path name currently cached in the FileEntry is
+ // the most appropriate one for this analysis (and that it's spelled the same
+ // way as the corresponding header search path).
+ const char *Name = File->getName();
+
+ unsigned BestPrefixLength = 0;
+ unsigned BestSearchDir;
+
+ for (unsigned I = 0; I != SearchDirs.size(); ++I) {
+ // FIXME: Support this search within frameworks and header maps.
+ if (!SearchDirs[I].isNormalDir())
+ continue;
+
+ const char *Dir = SearchDirs[I].getDir()->getName();
+ for (auto NI = llvm::sys::path::begin(Name),
+ NE = llvm::sys::path::end(Name),
+ DI = llvm::sys::path::begin(Dir),
+ DE = llvm::sys::path::end(Dir);
+ /*termination condition in loop*/; ++NI, ++DI) {
+ // '.' components in Name are ignored.
+ while (NI != NE && *NI == ".")
+ ++NI;
+ if (NI == NE)
+ break;
+
+ // '.' components in Dir are ignored.
+ while (DI != DE && *DI == ".")
+ ++DI;
+ if (DI == DE) {
+ // Dir is a prefix of Name, up to '.' components and choice of path
+ // separators.
+ unsigned PrefixLength = NI - llvm::sys::path::begin(Name);
+ if (PrefixLength > BestPrefixLength) {
+ BestPrefixLength = PrefixLength;
+ BestSearchDir = I;
+ }
+ break;
+ }
+
+ if (*NI != *DI)
+ break;
+ }
+ }
+
+ if (IsSystem)
+ *IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx : false;
+ return Name + BestPrefixLength;
+}
Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=267802&r1=267801&r2=267802&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Wed Apr 27 16:57:05 2016
@@ -209,29 +209,25 @@ ModuleMap::findHeaderInUmbrellaDirs(cons
static bool violatesPrivateInclude(Module *RequestingModule,
const FileEntry *IncFileEnt,
- ModuleMap::ModuleHeaderRole Role,
- Module *RequestedModule) {
- bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
+ ModuleMap::KnownHeader Header) {
#ifndef NDEBUG
- if (IsPrivateRole) {
+ if (Header.getRole() & ModuleMap::PrivateHeader) {
// Check for consistency between the module header role
// as obtained from the lookup and as obtained from the module.
// This check is not cheap, so enable it only for debugging.
bool IsPrivate = false;
SmallVectorImpl<Module::Header> *HeaderList[] = {
- &RequestedModule->Headers[Module::HK_Private],
- &RequestedModule->Headers[Module::HK_PrivateTextual]};
+ &Header.getModule()->Headers[Module::HK_Private],
+ &Header.getModule()->Headers[Module::HK_PrivateTextual]};
for (auto *Hs : HeaderList)
IsPrivate |=
std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
return H.Entry == IncFileEnt;
}) != Hs->end();
- assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
+ assert(IsPrivate && "inconsistent headers and roles");
}
#endif
- return IsPrivateRole && (!RequestingModule ||
- RequestedModule->getTopLevelModule() !=
- RequestingModule->getTopLevelModule());
+ return !Header.isAccessibleFrom(RequestingModule);
}
static Module *getTopLevelOrNull(Module *M) {
@@ -259,8 +255,7 @@ void ModuleMap::diagnoseHeaderInclusion(
if (Known != Headers.end()) {
for (const KnownHeader &Header : Known->second) {
// Remember private headers for later printing of a diagnostic.
- if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
- Header.getModule())) {
+ if (violatesPrivateInclude(RequestingModule, File, Header)) {
Private = Header.getModule();
continue;
}
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=267802&r1=267801&r2=267802&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Wed Apr 27 16:57:05 2016
@@ -597,6 +597,62 @@ Module *Preprocessor::getModuleContainin
FullSourceLoc(Loc, SourceMgr));
}
+const FileEntry *
+Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
+ SourceLocation Loc) {
+ // If we have a module import syntax, we shouldn't include a header to
+ // make a particular module visible.
+ if (getLangOpts().ObjC2)
+ return nullptr;
+
+ // Figure out which module we'd want to import.
+ Module *M = getModuleContainingLocation(Loc);
+ if (!M)
+ return nullptr;
+
+ Module *TopM = M->getTopLevelModule();
+ Module *IncM = getModuleForLocation(IncLoc);
+
+ // Walk up through the include stack, looking through textual headers of M
+ // until we hit a non-textual header that we can #include. (We assume textual
+ // headers of a module with non-textual headers aren't meant to be used to
+ // import entities from the module.)
+ auto &SM = getSourceManager();
+ while (!Loc.isInvalid() && !SM.isInMainFile(Loc)) {
+ auto ID = SM.getFileID(SM.getExpansionLoc(Loc));
+ auto *FE = SM.getFileEntryForID(ID);
+
+ bool InTextualHeader = false;
+ for (auto Header : HeaderInfo.getModuleMap().findAllModulesForHeader(FE)) {
+ if (!Header.getModule()->isSubModuleOf(TopM))
+ continue;
+
+ if (!(Header.getRole() & ModuleMap::TextualHeader)) {
+ // If this is an accessible, non-textual header of M's top-level module
+ // that transitively includes the given location and makes the
+ // corresponding module visible, this is the thing to #include.
+ if (Header.isAccessibleFrom(IncM))
+ return FE;
+
+ // It's in a private header; we can't #include it.
+ // FIXME: If there's a public header in some module that re-exports it,
+ // then we could suggest including that, but it's not clear that's the
+ // expected way to make this entity visible.
+ continue;
+ }
+
+ InTextualHeader = true;
+ }
+
+ if (!InTextualHeader)
+ break;
+
+ Loc = SM.getIncludeLoc(ID);
+ }
+
+ return nullptr;
+}
+
const FileEntry *Preprocessor::LookupFile(
SourceLocation FilenameLoc,
StringRef Filename,
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=267802&r1=267801&r2=267802&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Apr 27 16:57:05 2016
@@ -4929,6 +4929,16 @@ void Sema::diagnoseMissingImport(SourceL
Recover);
}
+/// \brief Get a "quoted.h" or <angled.h> include path to use in a diagnostic
+/// suggesting the addition of a #include of the specified file.
+static std::string getIncludeStringForHeader(Preprocessor &PP,
+ const FileEntry *E) {
+ bool IsSystem;
+ auto Path =
+ PP.getHeaderSearchInfo().suggestPathToFileForDiagnostics(E, &IsSystem);
+ return (IsSystem ? '<' : '"') + Path + (IsSystem ? '>' : '"');
+}
+
void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
SourceLocation DeclLoc,
ArrayRef<Module *> Modules,
@@ -4949,6 +4959,16 @@ void Sema::diagnoseMissingImport(SourceL
Diag(UseLoc, diag::err_module_unimported_use_multiple)
<< (int)MIK << Decl << ModuleList;
+ } else if (const FileEntry *E =
+ PP.getModuleHeaderToIncludeForDiagnostics(UseLoc, DeclLoc)) {
+ // The right way to make the declaration visible is to include a header;
+ // suggest doing so.
+ //
+ // FIXME: Find a smart place to suggest inserting a #include, and add
+ // a FixItHint there.
+ Diag(UseLoc, diag::err_module_unimported_use_header)
+ << (int)MIK << Decl << Modules[0]->getFullModuleName()
+ << getIncludeStringForHeader(PP, E);
} else {
Diag(UseLoc, diag::err_module_unimported_use)
<< (int)MIK << Decl << Modules[0]->getFullModuleName();
Added: cfe/trunk/test/Modules/Inputs/suggest-include/empty.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/empty.h?rev=267802&view=auto
==============================================================================
(empty)
Added: cfe/trunk/test/Modules/Inputs/suggest-include/module.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/module.modulemap?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/module.modulemap (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/module.modulemap Wed Apr 27 16:57:05 2016
@@ -0,0 +1,22 @@
+module X {
+ module Empty { header "empty.h" }
+
+ exclude header "textual1.h"
+ textual header "textual2.h"
+ textual header "textual3.h"
+
+ module A { header "usetextual1.h" }
+ module B { header "usetextual2.h" }
+ module C { header "usetextual3.h" }
+ module D { header "usetextual4.h" }
+ module E { header "usetextual5.h" }
+
+ module P { private header "private1.h" }
+ module Q { private header "private2.h" }
+ module R { private header "private3.h" }
+ module S { header "useprivate1.h" export * }
+ module T { header "useprivate3.h" }
+}
+
+module Other { textual header "textual4.h" }
+
Added: cfe/trunk/test/Modules/Inputs/suggest-include/private1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/private1.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/private1.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/private1.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+extern int private1;
Added: cfe/trunk/test/Modules/Inputs/suggest-include/private2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/private2.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/private2.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/private2.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+extern int private2;
Added: cfe/trunk/test/Modules/Inputs/suggest-include/private3.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/private3.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/private3.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/private3.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+extern int private3;
Added: cfe/trunk/test/Modules/Inputs/suggest-include/textual1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/textual1.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/textual1.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/textual1.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+#define FOO(X) X
Added: cfe/trunk/test/Modules/Inputs/suggest-include/textual2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/textual2.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/textual2.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/textual2.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+EXPAND_MACRO
Added: cfe/trunk/test/Modules/Inputs/suggest-include/textual3.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/textual3.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/textual3.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/textual3.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+extern int textual3;
Added: cfe/trunk/test/Modules/Inputs/suggest-include/textual4.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/textual4.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/textual4.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/textual4.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+extern int textual4;
Added: cfe/trunk/test/Modules/Inputs/suggest-include/textual5.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/textual5.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/textual5.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/textual5.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+extern int textual5;
Added: cfe/trunk/test/Modules/Inputs/suggest-include/useprivate1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/useprivate1.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/useprivate1.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/useprivate1.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+#include "private1.h"
Added: cfe/trunk/test/Modules/Inputs/suggest-include/useprivate3.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/useprivate3.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/useprivate3.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/useprivate3.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+#include "private3.h"
Added: cfe/trunk/test/Modules/Inputs/suggest-include/usetextual1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/usetextual1.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/usetextual1.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/usetextual1.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1,2 @@
+#include "textual1.h"
+FOO(extern int usetextual1;)
Added: cfe/trunk/test/Modules/Inputs/suggest-include/usetextual2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/usetextual2.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/usetextual2.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/usetextual2.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1,2 @@
+#define EXPAND_MACRO extern int usetextual2;
+#include "textual2.h"
Added: cfe/trunk/test/Modules/Inputs/suggest-include/usetextual3.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/usetextual3.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/usetextual3.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/usetextual3.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+#include "textual3.h"
Added: cfe/trunk/test/Modules/Inputs/suggest-include/usetextual4.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/usetextual4.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/usetextual4.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/usetextual4.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+#include "textual4.h"
Added: cfe/trunk/test/Modules/Inputs/suggest-include/usetextual5.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/suggest-include/usetextual5.h?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/suggest-include/usetextual5.h (added)
+++ cfe/trunk/test/Modules/Inputs/suggest-include/usetextual5.h Wed Apr 27 16:57:05 2016
@@ -0,0 +1 @@
+#include "textual5.h"
Added: cfe/trunk/test/Modules/suggest-include.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/suggest-include.cpp?rev=267802&view=auto
==============================================================================
--- cfe/trunk/test/Modules/suggest-include.cpp (added)
+++ cfe/trunk/test/Modules/suggest-include.cpp Wed Apr 27 16:57:05 2016
@@ -0,0 +1,33 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs/suggest-include %s -verify
+
+#include "empty.h" // import the module file
+
+// expected-note at usetextual1.h:2 {{previous}}
+// expected-note at textual2.h:1 {{previous}}
+// expected-note at textual3.h:1 {{previous}}
+// expected-note at textual4.h:1 {{previous}}
+// expected-note at textual5.h:1 {{previous}}
+// expected-note at private1.h:1 {{previous}}
+// expected-note at private2.h:1 {{previous}}
+// expected-note at private3.h:1 {{previous}}
+
+void f() {
+ (void)::usetextual1; // expected-error {{missing '#include "usetextual1.h"'}}
+ (void)::usetextual2; // expected-error {{missing '#include "usetextual2.h"'}}
+ (void)::textual3; // expected-error-re {{{{^}}missing '#include "usetextual3.h"'}}
+ // Don't suggest a #include that includes the entity via a path that leaves
+ // the module. In that case we can't be sure that we've picked the right header.
+ (void)::textual4; // expected-error-re {{{{^}}declaration of 'textual4'}}
+ (void)::textual5; // expected-error-re {{{{^}}declaration of 'textual5'}}
+
+ // Don't suggest #including a private header.
+ // FIXME: We could suggest including "useprivate1.h" here, as it's the only
+ // public way to get at this declaration.
+ (void)::private1; // expected-error-re {{{{^}}declaration of 'private1'}}
+ // FIXME: Should we be suggesting an import at all here? Should declarations
+ // in private headers be visible when the surrounding module is imported?
+ (void)::private2; // expected-error-re {{{{^}}declaration of 'private2'}}
+ // Even if we suggest an include for private1, we should not do so here.
+ (void)::private3; // expected-error-re {{{{^}}declaration of 'private3'}}
+}
More information about the cfe-commits
mailing list