Skip to content

Commit 49f906a

Browse files
committed
If a module A exports a macro M, and a module B imports that macro and #undef's
it, importers of B should not see the macro. This is complicated by the fact that A's macro could also be visible through a different path. The rules (as hashed out on cfe-commits) are included as a documentation update in this change. With this, the number of regressions in libc++'s testsuite when modules are enabled drops from 47 to 7. Those remaining 7 are also macro-related, and are due to remaining bugs in this change (in particular, the handling of submodules is imperfect). llvm-svn: 202560
1 parent 4913394 commit 49f906a

File tree

17 files changed

+594
-172
lines changed

17 files changed

+594
-172
lines changed

clang/docs/Modules.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,40 @@ Command-line parameters
198198
``-fmodule-map-file=<file>``
199199
Load the given module map file if a header from its directory or one of its subdirectories is loaded.
200200

201+
Module Semantics
202+
================
203+
204+
Modules are modeled as if each submodule were a separate translation unit, and a module import makes names from the other translation unit visible. Each submodule starts with a new preprocessor state and an empty translation unit.
205+
206+
.. note::
207+
208+
This behavior is currently only approximated when building a module. Entities within a submodule that has already been built are visible when building later submodules in that module. This can lead to fragile modules that depend on the build order used for the submodules of the module, and should not be relied upon.
209+
210+
As an example, in C, this implies that if two structs are defined in different submodules with the same name, those two types are distinct types (but may be *compatible* types if their definitions match. In C++, two structs defined with the same name in different submodules are the *same* type, and must be equivalent under C++'s One Definition Rule.
211+
212+
.. note::
213+
214+
Clang currently only performs minimal checking for violations of the One Definition Rule.
215+
216+
Macros
217+
------
218+
219+
The C and C++ preprocessor assumes that the input text is a single linear buffer, but with modules this is not the case. It is possible to import two modules that have conflicting definitions for a macro (or where one ``#define``\s a macro and the other ``#undef``\ines it). The rules for handling macro definitions in the presence of modules are as follows:
220+
221+
* Each definition and undefinition of a macro is considered to be a distinct entity.
222+
* Such entities are *visible* if they are from the current submodule or translation unit, or if they were exported from a submodule that has been imported.
223+
* A ``#define X`` or ``#undef X`` directive *overrides* all definitions of ``X`` that are visible at the point of the directive.
224+
* A ``#define`` or ``#undef`` directive is *active* if it is visible and no visible directive overrides it.
225+
* A set of macro directives is *consistent* if it consists of only ``#undef`` directives, or if all ``#define`` directives in the set define the macro name to the same sequence of tokens (following the usual rules for macro redefinitions).
226+
* If a macro name is used and the set of active directives is not consistent, the program is ill-formed. Otherwise, the (unique) meaning of the macro name is used.
227+
228+
For example, suppose:
229+
230+
* ``<stdio.h>`` defines a macro ``getc`` (and exports its ``#define``)
231+
* ``<cstdio>`` imports the ``<stdio.h>`` module and undefines the macro (and exports its ``#undef``)
232+
233+
The ``#undef`` overrides the ``#define``, and a source file that imports both modules *in any order* will not see ``getc`` defined as a macro.
234+
201235
Module Map Language
202236
===================
203237

clang/include/clang/Basic/Module.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,14 @@ class Module {
160160
MacrosVisible,
161161
/// \brief All of the names in this module are visible.
162162
AllVisible
163-
};
164-
165-
///\ brief The visibility of names within this particular module.
163+
};
164+
165+
/// \brief The visibility of names within this particular module.
166166
NameVisibilityKind NameVisibility;
167167

168+
/// \brief The location at which macros within this module became visible.
169+
SourceLocation MacroVisibilityLoc;
170+
168171
/// \brief The location of the inferred submodule.
169172
SourceLocation InferredSubmoduleLoc;
170173

clang/include/clang/Serialization/ASTReader.h

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class ASTUnit; // FIXME: Layering violation and egregious hack.
6464
class Attr;
6565
class Decl;
6666
class DeclContext;
67+
class DefMacroDirective;
6768
class DiagnosticOptions;
6869
class NestedNameSpecifier;
6970
class CXXBaseSpecifier;
@@ -471,27 +472,31 @@ class ASTReader
471472
/// global submodule ID to produce a local ID.
472473
GlobalSubmoduleMapType GlobalSubmoduleMap;
473474

475+
/// \brief Information on a macro definition or undefinition that is visible
476+
/// at the end of a submodule.
477+
struct ModuleMacroInfo;
478+
474479
/// \brief An entity that has been hidden.
475480
class HiddenName {
476481
public:
477482
enum NameKind {
478483
Declaration,
479-
MacroVisibility
484+
Macro
480485
} Kind;
481486

482487
private:
483488
union {
484489
Decl *D;
485-
MacroDirective *MD;
490+
ModuleMacroInfo *MMI;
486491
};
487492

488493
IdentifierInfo *Id;
489494

490495
public:
491496
HiddenName(Decl *D) : Kind(Declaration), D(D), Id() { }
492497

493-
HiddenName(IdentifierInfo *II, MacroDirective *MD)
494-
: Kind(MacroVisibility), MD(MD), Id(II) { }
498+
HiddenName(IdentifierInfo *II, ModuleMacroInfo *MMI)
499+
: Kind(Macro), MMI(MMI), Id(II) { }
495500

496501
NameKind getKind() const { return Kind; }
497502

@@ -500,15 +505,21 @@ class ASTReader
500505
return D;
501506
}
502507

503-
std::pair<IdentifierInfo *, MacroDirective *> getMacro() const {
504-
assert(getKind() == MacroVisibility && "Hidden name is not a macro!");
505-
return std::make_pair(Id, MD);
508+
std::pair<IdentifierInfo *, ModuleMacroInfo *> getMacro() const {
509+
assert(getKind() == Macro && "Hidden name is not a macro!");
510+
return std::make_pair(Id, MMI);
506511
}
507512
};
508513

514+
typedef llvm::SmallDenseMap<IdentifierInfo*,
515+
ModuleMacroInfo*> HiddenMacrosMap;
516+
509517
/// \brief A set of hidden declarations.
510-
typedef SmallVector<HiddenName, 2> HiddenNames;
511-
518+
struct HiddenNames {
519+
SmallVector<Decl*, 2> HiddenDecls;
520+
HiddenMacrosMap HiddenMacros;
521+
};
522+
512523
typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
513524

514525
/// \brief A mapping from each of the hidden submodules to the deserialized
@@ -564,8 +575,8 @@ class ASTReader
564575
ModuleFile *M;
565576

566577
struct ModuleMacroDataTy {
567-
serialization::GlobalMacroID GMacID;
568-
unsigned ImportLoc;
578+
uint32_t MacID;
579+
serialization::SubmoduleID *Overrides;
569580
};
570581
struct PCHMacroDataTy {
571582
uint64_t MacroDirectivesOffset;
@@ -577,10 +588,10 @@ class ASTReader
577588
};
578589

579590
PendingMacroInfo(ModuleFile *M,
580-
serialization::GlobalMacroID GMacID,
581-
SourceLocation ImportLoc) : M(M) {
582-
ModuleMacroData.GMacID = GMacID;
583-
ModuleMacroData.ImportLoc = ImportLoc.getRawEncoding();
591+
uint32_t MacID,
592+
serialization::SubmoduleID *Overrides) : M(M) {
593+
ModuleMacroData.MacID = MacID;
594+
ModuleMacroData.Overrides = Overrides;
584595
}
585596

586597
PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) : M(M) {
@@ -1253,14 +1264,14 @@ class ASTReader
12531264
/// \param ImportLoc The location at which the import occurs.
12541265
///
12551266
/// \param Complain Whether to complain about conflicting module imports.
1256-
void makeModuleVisible(Module *Mod,
1267+
void makeModuleVisible(Module *Mod,
12571268
Module::NameVisibilityKind NameVisibility,
12581269
SourceLocation ImportLoc,
12591270
bool Complain);
1260-
1271+
12611272
/// \brief Make the names within this set of hidden names visible.
12621273
void makeNamesVisible(const HiddenNames &Names, Module *Owner);
1263-
1274+
12641275
/// \brief Set the AST callbacks listener.
12651276
void setListener(ASTReaderListener *listener) {
12661277
Listener.reset(listener);
@@ -1687,14 +1698,27 @@ class ASTReader
16871698
serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
16881699
unsigned LocalID);
16891700

1701+
ModuleMacroInfo *getModuleMacro(const PendingMacroInfo &PMInfo);
1702+
16901703
void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
16911704

16921705
void installPCHMacroDirectives(IdentifierInfo *II,
16931706
ModuleFile &M, uint64_t Offset);
16941707

1695-
void installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
1708+
void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
16961709
Module *Owner);
16971710

1711+
typedef llvm::SmallVector<DefMacroDirective*, 1> AmbiguousMacros;
1712+
llvm::DenseMap<IdentifierInfo*, AmbiguousMacros> AmbiguousMacroDefs;
1713+
1714+
void
1715+
removeOverriddenMacros(IdentifierInfo *II, AmbiguousMacros &Ambig,
1716+
llvm::ArrayRef<serialization::SubmoduleID> Overrides);
1717+
1718+
AmbiguousMacros *
1719+
removeOverriddenMacros(IdentifierInfo *II,
1720+
llvm::ArrayRef<serialization::SubmoduleID> Overrides);
1721+
16981722
/// \brief Retrieve the macro with the given ID.
16991723
MacroInfo *getMacro(serialization::MacroID ID);
17001724

@@ -1875,7 +1899,7 @@ class ASTReader
18751899
void addPendingMacroFromModule(IdentifierInfo *II,
18761900
ModuleFile *M,
18771901
serialization::GlobalMacroID GMacID,
1878-
SourceLocation ImportLoc);
1902+
llvm::ArrayRef<serialization::SubmoduleID>);
18791903

18801904
/// \brief Add a macro to deserialize its macro directive history from a PCH.
18811905
///

clang/include/clang/Serialization/Module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ class ModuleFile {
171171
/// If module A depends on and imports module B, both modules will have the
172172
/// same DirectImportLoc, but different ImportLoc (B's ImportLoc will be a
173173
/// source location inside module A).
174+
///
175+
/// WARNING: This is largely useless. It doesn't tell you when a module was
176+
/// made visible, just when the first submodule of that module was imported.
174177
SourceLocation DirectImportLoc;
175178

176179
/// \brief The source location where this module was first imported.

clang/lib/Lex/MacroInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ MacroDirective::DefInfo MacroDirective::getDefinition() {
144144
isPublic = VisMD->isPublic();
145145
}
146146

147-
return DefInfo();
147+
return DefInfo(0, UndefLoc, !isPublic.hasValue() || isPublic.getValue());
148148
}
149149

150150
const MacroDirective::DefInfo

clang/lib/Lex/PPMacroExpansion.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,11 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
293293
for (MacroDirective::DefInfo PrevDef = Def.getPreviousDefinition();
294294
PrevDef && !PrevDef.isUndefined();
295295
PrevDef = PrevDef.getPreviousDefinition()) {
296-
if (PrevDef.getDirective()->isAmbiguous()) {
297-
Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
298-
diag::note_pp_ambiguous_macro_other)
299-
<< Identifier.getIdentifierInfo();
300-
}
296+
Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
297+
diag::note_pp_ambiguous_macro_other)
298+
<< Identifier.getIdentifierInfo();
299+
if (!PrevDef.getDirective()->isAmbiguous())
300+
break;
301301
}
302302
}
303303

0 commit comments

Comments
 (0)