Skip to content

Commit f3f8461

Browse files
committed
Track the set of module maps read while building a .pcm file and reload those when preprocessing from that .pcm file.
llvm-svn: 306628
1 parent 72c24da commit f3f8461

File tree

15 files changed

+127
-54
lines changed

15 files changed

+127
-54
lines changed

clang/include/clang/Basic/SourceManager.h

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,19 @@ namespace SrcMgr {
8080
/// system_header is seen or in various other cases.
8181
///
8282
enum CharacteristicKind {
83-
C_User, C_System, C_ExternCSystem
83+
C_User, C_System, C_ExternCSystem, C_User_ModuleMap, C_System_ModuleMap
8484
};
8585

86+
/// Determine whether a file / directory characteristic is for system code.
87+
inline bool isSystem(CharacteristicKind CK) {
88+
return CK != C_User && CK != C_User_ModuleMap;
89+
}
90+
91+
/// Determine whether a file characteristic is for a module map.
92+
inline bool isModuleMap(CharacteristicKind CK) {
93+
return CK == C_User_ModuleMap || CK == C_System_ModuleMap;
94+
}
95+
8696
/// \brief One instance of this struct is kept for every file loaded or used.
8797
///
8898
/// This object owns the MemoryBuffer object.
@@ -251,12 +261,14 @@ namespace SrcMgr {
251261
/// preprocessing of this \#include, including this SLocEntry.
252262
///
253263
/// Zero means the preprocessor didn't provide such info for this SLocEntry.
254-
unsigned NumCreatedFIDs;
264+
unsigned NumCreatedFIDs : 31;
265+
266+
/// \brief Whether this FileInfo has any \#line directives.
267+
unsigned HasLineDirectives : 1;
255268

256-
/// \brief Contains the ContentCache* and the bits indicating the
257-
/// characteristic of the file and whether it has \#line info, all
258-
/// bitmangled together.
259-
uintptr_t Data;
269+
/// \brief The content cache and the characteristic of the file.
270+
llvm::PointerIntPair<const ContentCache*, 3, CharacteristicKind>
271+
ContentAndKind;
260272

261273
friend class clang::SourceManager;
262274
friend class clang::ASTWriter;
@@ -269,33 +281,32 @@ namespace SrcMgr {
269281
FileInfo X;
270282
X.IncludeLoc = IL.getRawEncoding();
271283
X.NumCreatedFIDs = 0;
272-
X.Data = (uintptr_t)Con;
273-
assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
274-
assert((unsigned)FileCharacter < 4 && "invalid file character");
275-
X.Data |= (unsigned)FileCharacter;
284+
X.HasLineDirectives = false;
285+
X.ContentAndKind.setPointer(Con);
286+
X.ContentAndKind.setInt(FileCharacter);
276287
return X;
277288
}
278289

279290
SourceLocation getIncludeLoc() const {
280291
return SourceLocation::getFromRawEncoding(IncludeLoc);
281292
}
282293

283-
const ContentCache* getContentCache() const {
284-
return reinterpret_cast<const ContentCache*>(Data & ~uintptr_t(7));
294+
const ContentCache *getContentCache() const {
295+
return ContentAndKind.getPointer();
285296
}
286297

287298
/// \brief Return whether this is a system header or not.
288299
CharacteristicKind getFileCharacteristic() const {
289-
return (CharacteristicKind)(Data & 3);
300+
return ContentAndKind.getInt();
290301
}
291302

292303
/// \brief Return true if this FileID has \#line directives in it.
293-
bool hasLineDirectives() const { return (Data & 4) != 0; }
304+
bool hasLineDirectives() const { return HasLineDirectives; }
294305

295306
/// \brief Set the flag that indicates that this FileID has
296307
/// line table entries associated with it.
297308
void setHasLineDirectives() {
298-
Data |= 4;
309+
HasLineDirectives = true;
299310
}
300311
};
301312

@@ -407,6 +418,8 @@ namespace SrcMgr {
407418
};
408419

409420
public:
421+
SLocEntry() : Offset(), IsExpansion(), File() {}
422+
410423
unsigned getOffset() const { return Offset; }
411424

412425
bool isExpansion() const { return IsExpansion; }
@@ -789,9 +802,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
789802
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
790803
SrcMgr::CharacteristicKind FileCharacter,
791804
int LoadedID = 0, unsigned LoadedOffset = 0) {
792-
const SrcMgr::ContentCache *
793-
IR = getOrCreateContentCache(SourceFile,
794-
/*isSystemFile=*/FileCharacter != SrcMgr::C_User);
805+
const SrcMgr::ContentCache *IR =
806+
getOrCreateContentCache(SourceFile, isSystem(FileCharacter));
795807
assert(IR && "getOrCreateContentCache() cannot return NULL");
796808
return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset);
797809
}
@@ -1360,7 +1372,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
13601372

13611373
/// \brief Returns if a SourceLocation is in a system header.
13621374
bool isInSystemHeader(SourceLocation Loc) const {
1363-
return getFileCharacteristic(Loc) != SrcMgr::C_User;
1375+
return isSystem(getFileCharacteristic(Loc));
13641376
}
13651377

13661378
/// \brief Returns if a SourceLocation is in an "extern C" system header.

clang/include/clang/Lex/HeaderSearch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct HeaderFileInfo {
4747
/// whether it is C++ clean or not. This can be set by the include paths or
4848
/// by \#pragma gcc system_header. This is an instance of
4949
/// SrcMgr::CharacteristicKind.
50-
unsigned DirInfo : 2;
50+
unsigned DirInfo : 3;
5151

5252
/// \brief Whether this header file info was supplied by an external source,
5353
/// and has not changed since.

clang/include/clang/Serialization/ASTReader.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,7 @@ class ASTReader
11461146
time_t StoredTime;
11471147
bool Overridden;
11481148
bool Transient;
1149+
bool TopLevelModuleMap;
11491150
};
11501151

11511152
/// \brief Reads the stored information about an input file.
@@ -2249,6 +2250,12 @@ class ASTReader
22492250
llvm::function_ref<void(const serialization::InputFile &IF,
22502251
bool isSystem)> Visitor);
22512252

2253+
/// Visit all the top-level module maps loaded when building the given module
2254+
/// file.
2255+
void visitTopLevelModuleMaps(serialization::ModuleFile &MF,
2256+
llvm::function_ref<
2257+
void(const FileEntry *)> Visitor);
2258+
22522259
bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
22532260
};
22542261

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -825,8 +825,11 @@ bool CompilerInstance::InitializeSourceManager(
825825
const FrontendInputFile &Input, DiagnosticsEngine &Diags,
826826
FileManager &FileMgr, SourceManager &SourceMgr, HeaderSearch *HS,
827827
DependencyOutputOptions &DepOpts, const FrontendOptions &Opts) {
828-
SrcMgr::CharacteristicKind
829-
Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
828+
SrcMgr::CharacteristicKind Kind =
829+
Input.getKind().getFormat() == InputKind::ModuleMap
830+
? Input.isSystem() ? SrcMgr::C_System_ModuleMap
831+
: SrcMgr::C_User_ModuleMap
832+
: Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
830833

831834
if (Input.isBuffer()) {
832835
SourceMgr.setMainFileID(SourceMgr.createFileID(

clang/lib/Frontend/DependencyFile.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
5555
llvm::sys::path::remove_leading_dotslash(FE->getName());
5656

5757
DepCollector.maybeAddDependency(Filename, /*FromModule*/false,
58-
FileType != SrcMgr::C_User,
59-
/*IsModuleFile*/false, /*IsMissing*/false);
58+
isSystem(FileType),
59+
/*IsModuleFile*/false, /*IsMissing*/false);
6060
}
6161

6262
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
@@ -265,7 +265,7 @@ bool DFGImpl::FileMatchesDepCriteria(const char *Filename,
265265
if (IncludeSystemHeaders)
266266
return true;
267267

268-
return FileType == SrcMgr::C_User;
268+
return !isSystem(FileType);
269269
}
270270

271271
void DFGImpl::FileChanged(SourceLocation Loc,

clang/lib/Frontend/FrontendAction.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,12 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
200200
///
201201
/// \param CI The compiler instance.
202202
/// \param InputFile Populated with the filename from the line marker.
203-
/// \param AddLineNote If \c true, add a line note corresponding to this line
204-
/// directive. Only use this if the directive will not actually be
205-
/// visited by the preprocessor.
203+
/// \param IsModuleMap If \c true, add a line note corresponding to this line
204+
/// directive. (We need to do this because the directive will not be
205+
/// visited by the preprocessor.)
206206
static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
207207
std::string &InputFile,
208-
bool AddLineNote = false) {
208+
bool IsModuleMap = false) {
209209
auto &SourceMgr = CI.getSourceManager();
210210
auto MainFileID = SourceMgr.getMainFileID();
211211

@@ -231,7 +231,7 @@ static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
231231

232232
unsigned LineNo;
233233
SourceLocation LineNoLoc = T.getLocation();
234-
if (AddLineNote) {
234+
if (IsModuleMap) {
235235
llvm::SmallString<16> Buffer;
236236
if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
237237
.getAsInteger(10, LineNo))
@@ -250,10 +250,10 @@ static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
250250
return SourceLocation();
251251
InputFile = Literal.GetString().str();
252252

253-
if (AddLineNote)
253+
if (IsModuleMap)
254254
CI.getSourceManager().AddLineNote(
255255
LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
256-
false, SrcMgr::C_User);
256+
false, SrcMgr::C_User_ModuleMap);
257257

258258
return T.getLocation();
259259
}
@@ -403,7 +403,7 @@ static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
403403
Offset = 0;
404404
if (IsPreprocessed) {
405405
SourceLocation EndOfLineMarker =
406-
ReadOriginalFileName(CI, PresumedModuleMapFile, /*AddLineNote*/true);
406+
ReadOriginalFileName(CI, PresumedModuleMapFile, /*IsModuleMap*/ true);
407407
if (EndOfLineMarker.isValid())
408408
Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
409409
}
@@ -547,21 +547,29 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
547547
CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
548548
CI.getLangOpts() = AST->getLangOpts();
549549

550-
// Preload all the module files loaded transitively by the AST unit.
551-
if (auto ASTReader = AST->getASTReader()) {
552-
auto &MM = ASTReader->getModuleManager();
553-
for (ModuleFile &MF : MM)
554-
if (&MF != &MM.getPrimaryModule())
555-
CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
556-
}
557-
// FIXME: Preload module maps loaded by the AST unit.
558-
559550
// Set the shared objects, these are reset when we finish processing the
560551
// file, otherwise the CompilerInstance will happily destroy them.
561552
CI.setFileManager(&AST->getFileManager());
562553
CI.createSourceManager(CI.getFileManager());
563554
CI.getSourceManager().initializeForReplay(AST->getSourceManager());
564555

556+
// Preload all the module files loaded transitively by the AST unit. Also
557+
// load all module map files that were parsed as part of building the AST
558+
// unit.
559+
if (auto ASTReader = AST->getASTReader()) {
560+
auto &MM = ASTReader->getModuleManager();
561+
auto &PrimaryModule = MM.getPrimaryModule();
562+
563+
for (ModuleFile &MF : MM)
564+
if (&MF != &PrimaryModule)
565+
CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
566+
567+
ASTReader->visitTopLevelModuleMaps(PrimaryModule,
568+
[&](const FileEntry *FE) {
569+
CI.getFrontendOpts().ModuleMapFiles.push_back(FE->getName());
570+
});
571+
}
572+
565573
// Set up the input file for replay purposes.
566574
auto Kind = AST->getInputKind();
567575
if (Kind.getFormat() == InputKind::ModuleMap) {

clang/lib/Lex/ModuleMap.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2710,7 +2710,8 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
27102710

27112711
// If the module map file wasn't already entered, do so now.
27122712
if (ID.isInvalid()) {
2713-
auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2713+
auto FileCharacter =
2714+
IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
27142715
ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
27152716
}
27162717

clang/lib/Serialization/ASTReader.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,8 +1398,7 @@ bool ASTReader::ReadSLocEntry(int ID) {
13981398
}
13991399

14001400
const SrcMgr::ContentCache *ContentCache
1401-
= SourceMgr.getOrCreateContentCache(File,
1402-
/*isSystemFile=*/FileCharacter != SrcMgr::C_User);
1401+
= SourceMgr.getOrCreateContentCache(File, isSystem(FileCharacter));
14031402
if (OverriddenBuffer && !ContentCache->BufferOverridden &&
14041403
ContentCache->ContentsEntry == ContentCache->OrigEntry &&
14051404
!ContentCache->getRawBuffer()) {
@@ -1697,9 +1696,9 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
16971696
HeaderFileInfo HFI;
16981697
unsigned Flags = *d++;
16991698
// FIXME: Refactor with mergeHeaderFileInfo in HeaderSearch.cpp.
1700-
HFI.isImport |= (Flags >> 4) & 0x01;
1701-
HFI.isPragmaOnce |= (Flags >> 3) & 0x01;
1702-
HFI.DirInfo = (Flags >> 1) & 0x03;
1699+
HFI.isImport |= (Flags >> 5) & 0x01;
1700+
HFI.isPragmaOnce |= (Flags >> 4) & 0x01;
1701+
HFI.DirInfo = (Flags >> 1) & 0x07;
17031702
HFI.IndexHeaderMapHeader = Flags & 0x01;
17041703
// FIXME: Find a better way to handle this. Maybe just store a
17051704
// "has been included" flag?
@@ -2029,6 +2028,7 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {
20292028
R.StoredTime = static_cast<time_t>(Record[2]);
20302029
R.Overridden = static_cast<bool>(Record[3]);
20312030
R.Transient = static_cast<bool>(Record[4]);
2031+
R.TopLevelModuleMap = static_cast<bool>(Record[5]);
20322032
R.Filename = Blob;
20332033
ResolveImportedPath(F, R.Filename);
20342034
return R;
@@ -8909,6 +8909,19 @@ void ASTReader::visitInputFiles(serialization::ModuleFile &MF,
89098909
}
89108910
}
89118911

8912+
void ASTReader::visitTopLevelModuleMaps(
8913+
serialization::ModuleFile &MF,
8914+
llvm::function_ref<void(const FileEntry *FE)> Visitor) {
8915+
unsigned NumInputs = MF.InputFilesLoaded.size();
8916+
for (unsigned I = 0; I < NumInputs; ++I) {
8917+
InputFileInfo IFI = readInputFileInfo(MF, I + 1);
8918+
if (IFI.TopLevelModuleMap)
8919+
// FIXME: This unnecessarily re-reads the InputFileInfo.
8920+
if (auto *FE = getInputFile(MF, I + 1).getFile())
8921+
Visitor(FE);
8922+
}
8923+
}
8924+
89128925
std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
89138926
// If we know the owning module, use it.
89148927
if (Module *M = D->getImportedOwningModule())

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,7 @@ namespace {
16921692
bool IsSystemFile;
16931693
bool IsTransient;
16941694
bool BufferOverridden;
1695+
bool IsTopLevelModuleMap;
16951696
};
16961697

16971698
} // end anonymous namespace
@@ -1710,6 +1711,7 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
17101711
IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time
17111712
IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Overridden
17121713
IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Transient
1714+
IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Module map
17131715
IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
17141716
unsigned IFAbbrevCode = Stream.EmitAbbrev(std::move(IFAbbrev));
17151717

@@ -1724,7 +1726,8 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
17241726
// We only care about file entries that were not overridden.
17251727
if (!SLoc->isFile())
17261728
continue;
1727-
const SrcMgr::ContentCache *Cache = SLoc->getFile().getContentCache();
1729+
const SrcMgr::FileInfo &File = SLoc->getFile();
1730+
const SrcMgr::ContentCache *Cache = File.getContentCache();
17281731
if (!Cache->OrigEntry)
17291732
continue;
17301733

@@ -1733,6 +1736,8 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
17331736
Entry.IsSystemFile = Cache->IsSystemFile;
17341737
Entry.IsTransient = Cache->IsTransient;
17351738
Entry.BufferOverridden = Cache->BufferOverridden;
1739+
Entry.IsTopLevelModuleMap = isModuleMap(File.getFileCharacteristic()) &&
1740+
File.getIncludeLoc().isInvalid();
17361741
if (Cache->IsSystemFile)
17371742
SortedFiles.push_back(Entry);
17381743
else
@@ -1763,7 +1768,8 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
17631768
(uint64_t)Entry.File->getSize(),
17641769
(uint64_t)getTimestampForOutput(Entry.File),
17651770
Entry.BufferOverridden,
1766-
Entry.IsTransient};
1771+
Entry.IsTransient,
1772+
Entry.IsTopLevelModuleMap};
17671773

17681774
EmitRecordWithPath(IFAbbrevCode, Record, Entry.File->getName());
17691775
}
@@ -1798,7 +1804,7 @@ static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
17981804
Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY));
17991805
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
18001806
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
1801-
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
1807+
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Characteristic
18021808
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
18031809
// FileEntry fields.
18041810
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Input File ID
@@ -1817,7 +1823,7 @@ static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) {
18171823
Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY));
18181824
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
18191825
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
1820-
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
1826+
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Characteristic
18211827
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
18221828
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
18231829
return Stream.EmitAbbrev(std::move(Abbrev));
@@ -1925,8 +1931,8 @@ namespace {
19251931
endian::Writer<little> LE(Out);
19261932
uint64_t Start = Out.tell(); (void)Start;
19271933

1928-
unsigned char Flags = (Data.HFI.isImport << 4)
1929-
| (Data.HFI.isPragmaOnce << 3)
1934+
unsigned char Flags = (Data.HFI.isImport << 5)
1935+
| (Data.HFI.isPragmaOnce << 4)
19301936
| (Data.HFI.DirInfo << 1)
19311937
| Data.HFI.IndexHeaderMapHeader;
19321938
LE.write<uint8_t>(Flags);

0 commit comments

Comments
 (0)