forked from OSchip/llvm-project
[modules] When finding the owning module of an instantiated context in template
instantiation, follow lexical parents not semantic ones: we want to find the module where the pattern was written. llvm-svn: 316055
This commit is contained in:
parent
1fc49627e4
commit
17ad3ac2aa
|
@ -176,7 +176,8 @@ public:
|
|||
: DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
|
||||
Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
|
||||
assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
|
||||
assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
|
||||
assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
|
||||
"DiagnosticLoc is invalid!");
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -416,9 +416,12 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
|
|||
MatchAnyLine = true;
|
||||
ExpectedLoc = SM.translateFileLineCol(FE, 1, 1);
|
||||
}
|
||||
} else if (PH.Next("*")) {
|
||||
MatchAnyLine = true;
|
||||
ExpectedLoc = SourceLocation();
|
||||
}
|
||||
|
||||
if (ExpectedLoc.isInvalid()) {
|
||||
if (ExpectedLoc.isInvalid() && !MatchAnyLine) {
|
||||
Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
|
||||
diag::err_verify_missing_line) << KindStr;
|
||||
continue;
|
||||
|
@ -650,7 +653,10 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags,
|
|||
llvm::raw_svector_ostream OS(Fmt);
|
||||
for (auto *DirPtr : DL) {
|
||||
Directive &D = *DirPtr;
|
||||
OS << "\n File " << SourceMgr.getFilename(D.DiagnosticLoc);
|
||||
if (D.DiagnosticLoc.isInvalid())
|
||||
OS << "\n File *";
|
||||
else
|
||||
OS << "\n File " << SourceMgr.getFilename(D.DiagnosticLoc);
|
||||
if (D.MatchAnyLine)
|
||||
OS << " Line *";
|
||||
else
|
||||
|
@ -708,7 +714,8 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first))
|
||||
if (!D.DiagnosticLoc.isInvalid() &&
|
||||
!IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first))
|
||||
continue;
|
||||
|
||||
const std::string &RightText = II->second;
|
||||
|
|
|
@ -1374,7 +1374,7 @@ static Module *getDefiningModule(Sema &S, Decl *Entity) {
|
|||
|
||||
// Walk up to the containing context. That might also have been instantiated
|
||||
// from a template.
|
||||
DeclContext *Context = Entity->getDeclContext();
|
||||
DeclContext *Context = Entity->getLexicalDeclContext();
|
||||
if (Context->isFileContext())
|
||||
return S.getOwningModule(Entity);
|
||||
return getDefiningModule(S, cast<Decl>(Context));
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// RUN: %clang_cc1 -std=c++11 -fmodules %s -verify
|
||||
|
||||
#pragma clang module build M
|
||||
module M { module A {} module B {} module C {} }
|
||||
#pragma clang module contents
|
||||
|
||||
#pragma clang module begin M.A
|
||||
template<typename U> struct X {
|
||||
template<typename T> void f();
|
||||
};
|
||||
#pragma clang module end
|
||||
|
||||
#pragma clang module begin M.B
|
||||
template<typename T, typename U = void> struct ST { static void f(); };
|
||||
#pragma clang module end
|
||||
|
||||
#pragma clang module begin M.C
|
||||
template<typename U> struct X;
|
||||
void foo(X<int>);
|
||||
#pragma clang module end
|
||||
#pragma clang module endbuild
|
||||
|
||||
#pragma clang module build N
|
||||
module N {}
|
||||
#pragma clang module contents
|
||||
#pragma clang module begin N
|
||||
#pragma clang module import M.B // not re-exported
|
||||
|
||||
template<typename U> struct X {
|
||||
template<typename T> void f();
|
||||
template<typename T> void g();
|
||||
};
|
||||
|
||||
template<typename U> template<typename T>
|
||||
void X<U>::f() {
|
||||
ST<T>::f(); // definition and default argument found in M.B
|
||||
foo(*this); // found by ADL in M.C
|
||||
};
|
||||
|
||||
#pragma clang module import M.C // not re-exported
|
||||
#pragma clang module end
|
||||
#pragma clang module endbuild
|
||||
|
||||
#pragma clang module import N
|
||||
void g() {
|
||||
X<int>().f<int>();
|
||||
|
||||
ST<int>::f(); // expected-error {{must be imported from module 'M.B'}}
|
||||
foo(X<int>()); // expected-error {{must be imported from module 'M.C'}}
|
||||
// expected-note@* 2{{previous declaration is here}}
|
||||
}
|
Loading…
Reference in New Issue