Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit aaaa0b6

Browse files
committed
[modules] Switch from inferring owning modules based on source location to
inferring based on the current module at the point of creation. This should result in no functional change except when building a preprocessed module (or more generally when using #pragma clang module begin/end to switch module in the middle of a file), in which case it allows us to correctly track the owning module for declarations. We can't map from FileID to module in the preprocessed module case, since all modules would have the same FileID. There are still a couple of remaining places that try to infer a module from a source location; I'll clean those up in follow-up changes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303322 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d665e95 commit aaaa0b6

File tree

13 files changed

+123
-125
lines changed

13 files changed

+123
-125
lines changed

include/clang/AST/ASTContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
935935

936936
/// \brief Get the additional modules in which the definition \p Def has
937937
/// been merged.
938-
ArrayRef<Module*> getModulesWithMergedDefinition(NamedDecl *Def) {
938+
ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def) {
939939
auto MergedIt = MergedDefModules.find(Def);
940940
if (MergedIt == MergedDefModules.end())
941941
return None;

include/clang/AST/DeclBase.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -332,15 +332,15 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
332332
bool AccessDeclContextSanity() const;
333333

334334
protected:
335-
336335
Decl(Kind DK, DeclContext *DC, SourceLocation L)
337-
: NextInContextAndBits(), DeclCtx(DC),
338-
Loc(L), DeclKind(DK), InvalidDecl(0),
339-
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
340-
Access(AS_none), FromASTFile(0), Hidden(DC && cast<Decl>(DC)->Hidden),
341-
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
342-
CacheValidAndLinkage(0)
343-
{
336+
: NextInContextAndBits(), DeclCtx(DC), Loc(L), DeclKind(DK),
337+
InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false),
338+
Referenced(false), Access(AS_none), FromASTFile(0),
339+
Hidden(DC && cast<Decl>(DC)->Hidden &&
340+
(!cast<Decl>(DC)->isFromASTFile() ||
341+
hasLocalOwningModuleStorage())),
342+
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
343+
CacheValidAndLinkage(0) {
344344
if (StatisticsEnabled) add(DK);
345345
}
346346

@@ -698,6 +698,9 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
698698
Module *getLocalOwningModule() const {
699699
if (isFromASTFile() || !Hidden)
700700
return nullptr;
701+
702+
assert(hasLocalOwningModuleStorage() &&
703+
"hidden local decl but no local module storage");
701704
return reinterpret_cast<Module *const *>(this)[-1];
702705
}
703706
void setLocalOwningModule(Module *M) {

include/clang/Basic/LangOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class LangOptions : public LangOptionsBase {
168168

169169
/// Do we need to track the owning module for a local declaration?
170170
bool trackLocalOwningModule() const {
171-
return ModulesLocalVisibility;
171+
return isCompilingModule() || ModulesLocalVisibility || ModulesTS;
172172
}
173173

174174
bool isSignedOverflowDefined() const {

include/clang/Sema/Sema.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,12 @@ class Sema {
15071507
hasVisibleDefaultArgument(const NamedDecl *D,
15081508
llvm::SmallVectorImpl<Module *> *Modules = nullptr);
15091509

1510+
/// Determine if there is a visible declaration of \p D that is an explicit
1511+
/// specialization declaration for a specialization of a template. (For a
1512+
/// member specialization, use hasVisibleMemberSpecialization.)
1513+
bool hasVisibleExplicitSpecialization(
1514+
const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr);
1515+
15101516
/// Determine if there is a visible declaration of \p D that is a member
15111517
/// specialization declaration (as opposed to an instantiated declaration).
15121518
bool hasVisibleMemberSpecialization(
@@ -2360,7 +2366,7 @@ class Sema {
23602366
void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
23612367
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
23622368
bool checkVarDeclRedefinition(VarDecl *OldDefn, VarDecl *NewDefn);
2363-
void notePreviousDefinition(SourceLocation Old, SourceLocation New);
2369+
void notePreviousDefinition(const NamedDecl *Old, SourceLocation New);
23642370
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
23652371

23662372
// AssignmentAction - This is used by all the assignment diagnostic functions

include/clang/Serialization/ASTWriter.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -627,10 +627,6 @@ class ASTWriter : public ASTDeserializationListener,
627627
/// \brief Add a version tuple to the given record
628628
void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
629629

630-
/// \brief Infer the submodule ID that contains an entity at the given
631-
/// source location.
632-
serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
633-
634630
/// \brief Retrieve or create a submodule ID for this module, or return 0 if
635631
/// the submodule is neither local (a submodle of the currently-written module)
636632
/// nor from an imported module.

lib/CodeGen/CGDebugInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2613,7 +2613,7 @@ llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) {
26132613
// best to make this behavior a command line or debugger tuning
26142614
// option.
26152615
FullSourceLoc Loc(D->getLocation(), CGM.getContext().getSourceManager());
2616-
if (Module *M = ClangModuleMap->inferModuleFromLocation(Loc)) {
2616+
if (Module *M = D->getOwningModule()) {
26172617
// This is a (sub-)module.
26182618
auto Info = ExternalASTSource::ASTSourceDescriptor(*M);
26192619
return getOrCreateModuleRef(Info, /*SkeletonCU=*/false);

lib/Sema/SemaDecl.cpp

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,7 +2021,7 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
20212021
Diag(New->getLocation(), diag::err_redefinition_variably_modified_typedef)
20222022
<< Kind << NewType;
20232023
if (Old->getLocation().isValid())
2024-
notePreviousDefinition(Old->getLocation(), New->getLocation());
2024+
notePreviousDefinition(Old, New->getLocation());
20252025
New->setInvalidDecl();
20262026
return true;
20272027
}
@@ -2034,7 +2034,7 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
20342034
Diag(New->getLocation(), diag::err_redefinition_different_typedef)
20352035
<< Kind << NewType << OldType;
20362036
if (Old->getLocation().isValid())
2037-
notePreviousDefinition(Old->getLocation(), New->getLocation());
2037+
notePreviousDefinition(Old, New->getLocation());
20382038
New->setInvalidDecl();
20392039
return true;
20402040
}
@@ -2101,7 +2101,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
21012101

21022102
NamedDecl *OldD = OldDecls.getRepresentativeDecl();
21032103
if (OldD->getLocation().isValid())
2104-
notePreviousDefinition(OldD->getLocation(), New->getLocation());
2104+
notePreviousDefinition(OldD, New->getLocation());
21052105

21062106
return New->setInvalidDecl();
21072107
}
@@ -2193,7 +2193,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
21932193

21942194
Diag(New->getLocation(), diag::err_redefinition)
21952195
<< New->getDeclName();
2196-
notePreviousDefinition(Old->getLocation(), New->getLocation());
2196+
notePreviousDefinition(Old, New->getLocation());
21972197
return New->setInvalidDecl();
21982198
}
21992199

@@ -2214,7 +2214,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
22142214

22152215
Diag(New->getLocation(), diag::ext_redefinition_of_typedef)
22162216
<< New->getDeclName();
2217-
notePreviousDefinition(Old->getLocation(), New->getLocation());
2217+
notePreviousDefinition(Old, New->getLocation());
22182218
}
22192219

22202220
/// DeclhasAttr - returns true if decl Declaration already has the target
@@ -2448,7 +2448,7 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
24482448
return false;
24492449
}
24502450

2451-
static const Decl *getDefinition(const Decl *D) {
2451+
static const NamedDecl *getDefinition(const Decl *D) {
24522452
if (const TagDecl *TD = dyn_cast<TagDecl>(D))
24532453
return TD->getDefinition();
24542454
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
@@ -2475,7 +2475,7 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
24752475
if (!New->hasAttrs())
24762476
return;
24772477

2478-
const Decl *Def = getDefinition(Old);
2478+
const NamedDecl *Def = getDefinition(Old);
24792479
if (!Def || Def == New)
24802480
return;
24812481

@@ -2502,7 +2502,7 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
25022502
: diag::err_redefinition;
25032503
S.Diag(VD->getLocation(), Diag) << VD->getDeclName();
25042504
if (Diag == diag::err_redefinition)
2505-
S.notePreviousDefinition(Def->getLocation(), VD->getLocation());
2505+
S.notePreviousDefinition(Def, VD->getLocation());
25062506
else
25072507
S.Diag(Def->getLocation(), diag::note_previous_definition);
25082508
VD->setInvalidDecl();
@@ -2891,7 +2891,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
28912891
} else {
28922892
Diag(New->getLocation(), diag::err_redefinition_different_kind)
28932893
<< New->getDeclName();
2894-
notePreviousDefinition(OldD->getLocation(), New->getLocation());
2894+
notePreviousDefinition(OldD, New->getLocation());
28952895
return true;
28962896
}
28972897
}
@@ -2928,7 +2928,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
29282928
!Old->hasAttr<InternalLinkageAttr>()) {
29292929
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
29302930
<< New->getDeclName();
2931-
notePreviousDefinition(Old->getLocation(), New->getLocation());
2931+
notePreviousDefinition(Old, New->getLocation());
29322932
New->dropAttr<InternalLinkageAttr>();
29332933
}
29342934

@@ -3657,7 +3657,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
36573657
if (!Old) {
36583658
Diag(New->getLocation(), diag::err_redefinition_different_kind)
36593659
<< New->getDeclName();
3660-
notePreviousDefinition(Previous.getRepresentativeDecl()->getLocation(),
3660+
notePreviousDefinition(Previous.getRepresentativeDecl(),
36613661
New->getLocation());
36623662
return New->setInvalidDecl();
36633663
}
@@ -3687,7 +3687,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
36873687
Old->getStorageClass() == SC_None &&
36883688
!Old->hasAttr<WeakImportAttr>()) {
36893689
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
3690-
notePreviousDefinition(Old->getLocation(), New->getLocation());
3690+
notePreviousDefinition(Old, New->getLocation());
36913691
// Remove weak_import attribute on new declaration.
36923692
New->dropAttr<WeakImportAttr>();
36933693
}
@@ -3696,7 +3696,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
36963696
!Old->hasAttr<InternalLinkageAttr>()) {
36973697
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
36983698
<< New->getDeclName();
3699-
notePreviousDefinition(Old->getLocation(), New->getLocation());
3699+
notePreviousDefinition(Old, New->getLocation());
37003700
New->dropAttr<InternalLinkageAttr>();
37013701
}
37023702

@@ -3853,29 +3853,22 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
38533853
New->setImplicitlyInline();
38543854
}
38553855

3856-
void Sema::notePreviousDefinition(SourceLocation Old, SourceLocation New) {
3856+
void Sema::notePreviousDefinition(const NamedDecl *Old, SourceLocation New) {
38573857
SourceManager &SrcMgr = getSourceManager();
38583858
auto FNewDecLoc = SrcMgr.getDecomposedLoc(New);
3859-
auto FOldDecLoc = SrcMgr.getDecomposedLoc(Old);
3859+
auto FOldDecLoc = SrcMgr.getDecomposedLoc(Old->getLocation());
38603860
auto *FNew = SrcMgr.getFileEntryForID(FNewDecLoc.first);
38613861
auto *FOld = SrcMgr.getFileEntryForID(FOldDecLoc.first);
38623862
auto &HSI = PP.getHeaderSearchInfo();
3863-
StringRef HdrFilename = SrcMgr.getFilename(SrcMgr.getSpellingLoc(Old));
3863+
StringRef HdrFilename =
3864+
SrcMgr.getFilename(SrcMgr.getSpellingLoc(Old->getLocation()));
38643865

3865-
auto noteFromModuleOrInclude = [&](SourceLocation &Loc,
3866-
SourceLocation &IncLoc) -> bool {
3867-
Module *Mod = nullptr;
3866+
auto noteFromModuleOrInclude = [&](Module *Mod,
3867+
SourceLocation IncLoc) -> bool {
38683868
// Redefinition errors with modules are common with non modular mapped
38693869
// headers, example: a non-modular header H in module A that also gets
38703870
// included directly in a TU. Pointing twice to the same header/definition
38713871
// is confusing, try to get better diagnostics when modules is on.
3872-
if (getLangOpts().Modules) {
3873-
auto ModLoc = SrcMgr.getModuleImportLoc(Old);
3874-
if (!ModLoc.first.isInvalid())
3875-
Mod = HSI.getModuleMap().inferModuleFromLocation(
3876-
FullSourceLoc(Loc, SrcMgr));
3877-
}
3878-
38793872
if (IncLoc.isValid()) {
38803873
if (Mod) {
38813874
Diag(IncLoc, diag::note_redefinition_modules_same_file)
@@ -3899,19 +3892,19 @@ void Sema::notePreviousDefinition(SourceLocation Old, SourceLocation New) {
38993892
if (FNew == FOld && FNewDecLoc.second == FOldDecLoc.second) {
39003893
SourceLocation OldIncLoc = SrcMgr.getIncludeLoc(FOldDecLoc.first);
39013894
SourceLocation NewIncLoc = SrcMgr.getIncludeLoc(FNewDecLoc.first);
3902-
EmittedDiag = noteFromModuleOrInclude(Old, OldIncLoc);
3903-
EmittedDiag |= noteFromModuleOrInclude(New, NewIncLoc);
3895+
EmittedDiag = noteFromModuleOrInclude(Old->getOwningModule(), OldIncLoc);
3896+
EmittedDiag |= noteFromModuleOrInclude(getCurrentModule(), NewIncLoc);
39043897

39053898
// If the header has no guards, emit a note suggesting one.
39063899
if (FOld && !HSI.isFileMultipleIncludeGuarded(FOld))
3907-
Diag(Old, diag::note_use_ifdef_guards);
3900+
Diag(Old->getLocation(), diag::note_use_ifdef_guards);
39083901

39093902
if (EmittedDiag)
39103903
return;
39113904
}
39123905

39133906
// Redefinition coming from different files or couldn't do better above.
3914-
Diag(Old, diag::note_previous_definition);
3907+
Diag(Old->getLocation(), diag::note_previous_definition);
39153908
}
39163909

39173910
/// We've just determined that \p Old and \p New both appear to be definitions
@@ -3934,7 +3927,7 @@ bool Sema::checkVarDeclRedefinition(VarDecl *Old, VarDecl *New) {
39343927
return false;
39353928
} else {
39363929
Diag(New->getLocation(), diag::err_redefinition) << New;
3937-
notePreviousDefinition(Old->getLocation(), New->getLocation());
3930+
notePreviousDefinition(Old, New->getLocation());
39383931
New->setInvalidDecl();
39393932
return true;
39403933
}
@@ -13503,9 +13496,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
1350313496
} else if (TUK == TUK_Reference &&
1350413497
(PrevTagDecl->getFriendObjectKind() ==
1350513498
Decl::FOK_Undeclared ||
13506-
PP.getModuleContainingLocation(
13507-
PrevDecl->getLocation()) !=
13508-
PP.getModuleContainingLocation(KWLoc)) &&
13499+
PrevDecl->getOwningModule() != getCurrentModule()) &&
1350913500
SS.isEmpty()) {
1351013501
// This declaration is a reference to an existing entity, but
1351113502
// has different visibility from that entity: it either makes
@@ -13561,7 +13552,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
1356113552
Diag(NameLoc, diag::warn_redefinition_in_param_list) << Name;
1356213553
else
1356313554
Diag(NameLoc, diag::err_redefinition) << Name;
13564-
notePreviousDefinition(Def->getLocation(),
13555+
notePreviousDefinition(Def,
1356513556
NameLoc.isValid() ? NameLoc : KWLoc);
1356613557
// If this is a redefinition, recover by making this
1356713558
// struct be anonymous, which will make any later
@@ -13652,7 +13643,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
1365213643
// The tag name clashes with something else in the target scope,
1365313644
// issue an error and recover by making this tag be anonymous.
1365413645
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
13655-
notePreviousDefinition(PrevDecl->getLocation(), NameLoc);
13646+
notePreviousDefinition(PrevDecl, NameLoc);
1365613647
Name = nullptr;
1365713648
Invalid = true;
1365813649
}
@@ -15356,7 +15347,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
1535615347
Diag(IdLoc, diag::err_redefinition_of_enumerator) << Id;
1535715348
else
1535815349
Diag(IdLoc, diag::err_redefinition) << Id;
15359-
notePreviousDefinition(PrevDecl->getLocation(), IdLoc);
15350+
notePreviousDefinition(PrevDecl, IdLoc);
1536015351
return nullptr;
1536115352
}
1536215353
}

0 commit comments

Comments
 (0)