aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:11:37 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:11:37 +0000
commit461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch)
tree6942083d7d56bba40ec790a453ca58ad3baf6832 /lib/Serialization
parent75c3240472ba6ac2669ee72ca67eb72d4e2851fc (diff)
Vendor import of clang trunk r321017:vendor/clang/clang-trunk-r321017
Notes
Notes: svn path=/vendor/clang/dist/; revision=326941 svn path=/vendor/clang/clang-trunk-r321017/; revision=326942; tag=vendor/clang/clang-trunk-r321017
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTCommon.cpp3
-rw-r--r--lib/Serialization/ASTCommon.h3
-rw-r--r--lib/Serialization/ASTReader.cpp688
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp90
-rw-r--r--lib/Serialization/ASTReaderInternals.h92
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp46
-rw-r--r--lib/Serialization/ASTWriter.cpp250
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp83
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp26
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp4
-rw-r--r--lib/Serialization/ModuleManager.cpp59
-rw-r--r--lib/Serialization/MultiOnDiskHashTable.h69
12 files changed, 1066 insertions, 347 deletions
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index 684ec243035e..9c6f03cd0bb7 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -91,6 +91,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
case BuiltinType::LongDouble:
ID = PREDEF_TYPE_LONGDOUBLE_ID;
break;
+ case BuiltinType::Float16:
+ ID = PREDEF_TYPE_FLOAT16_ID;
+ break;
case BuiltinType::Float128:
ID = PREDEF_TYPE_FLOAT128_ID;
break;
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index cbc5f04738b1..6aca453bbb89 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/lib/Serialization/ASTCommon.h
@@ -27,7 +27,8 @@ enum DeclUpdateKind {
UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
UPD_CXX_ADDED_FUNCTION_DEFINITION,
- UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
+ UPD_CXX_ADDED_VAR_DEFINITION,
+ UPD_CXX_POINT_OF_INSTANTIATION,
UPD_CXX_INSTANTIATED_CLASS_DEFINITION,
UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT,
UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER,
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 50be74f6bf6e..111ac4fcdaa4 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1,4 +1,4 @@
-//===-- ASTReader.cpp - AST File Reader -----------------------------------===//
+//===- ASTReader.cpp - AST File Reader ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,28 +19,41 @@
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/ASTUnresolvedSet.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/ODRHash.h"
#include "clang/AST/RawCommentList.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/MemoryBufferCache.h"
+#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PragmaKinds.h"
#include "clang/Basic/Sanitizers.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
#include "clang/Basic/Specifiers.h"
@@ -57,41 +70,61 @@
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Lex/Token.h"
+#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/Weak.h"
+#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTDeserializationListener.h"
+#include "clang/Serialization/ContinuousRangeMap.h"
#include "clang/Serialization/GlobalModuleIndex.h"
+#include "clang/Serialization/Module.h"
+#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Serialization/ModuleManager.h"
#include "clang/Serialization/SerializationDiagnostic.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
+#include <cstddef>
#include <cstdint>
#include <cstdio>
-#include <cstring>
#include <ctime>
#include <iterator>
#include <limits>
#include <map>
#include <memory>
-#include <new>
#include <string>
#include <system_error>
#include <tuple>
@@ -171,19 +204,23 @@ bool ChainedASTReaderListener::ReadPreprocessorOptions(
SuggestedPredefines) ||
Second->ReadPreprocessorOptions(PPOpts, Complain, SuggestedPredefines);
}
+
void ChainedASTReaderListener::ReadCounter(const serialization::ModuleFile &M,
unsigned Value) {
First->ReadCounter(M, Value);
Second->ReadCounter(M, Value);
}
+
bool ChainedASTReaderListener::needsInputFileVisitation() {
return First->needsInputFileVisitation() ||
Second->needsInputFileVisitation();
}
+
bool ChainedASTReaderListener::needsSystemInputFileVisitation() {
return First->needsSystemInputFileVisitation() ||
Second->needsSystemInputFileVisitation();
}
+
void ChainedASTReaderListener::visitModuleFile(StringRef Filename,
ModuleKind Kind) {
First->visitModuleFile(Filename, Kind);
@@ -216,7 +253,7 @@ void ChainedASTReaderListener::readModuleFileExtension(
// PCH validator implementation
//===----------------------------------------------------------------------===//
-ASTReaderListener::~ASTReaderListener() {}
+ASTReaderListener::~ASTReaderListener() = default;
/// \brief Compare the given set of language options against an existing set of
/// language options.
@@ -409,17 +446,16 @@ bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,
namespace {
- typedef llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >
- MacroDefinitionsMap;
- typedef llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> >
- DeclsMap;
+using MacroDefinitionsMap =
+ llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>;
+using DeclsMap = llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8>>;
-} // end anonymous namespace
+} // namespace
static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags,
DiagnosticsEngine &Diags,
bool Complain) {
- typedef DiagnosticsEngine::Level Level;
+ using Level = DiagnosticsEngine::Level;
// Check current mappings for new -Werror mappings, and the stored mappings
// for cases that were explicitly mapped to *not* be errors that are now
@@ -603,8 +639,8 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
std::pair<StringRef, bool> Existing = ExistingMacros[MacroName];
// Check whether we know anything about this macro name or not.
- llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >::iterator Known
- = ASTFileMacros.find(MacroName);
+ llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>::iterator Known =
+ ASTFileMacros.find(MacroName);
if (!Validate || Known == ASTFileMacros.end()) {
// FIXME: Check whether this identifier was referenced anywhere in the
// AST file. If so, we should reject the AST file. Unfortunately, this
@@ -770,6 +806,7 @@ unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
std::pair<unsigned, unsigned>
ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
using namespace llvm::support;
+
unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
return std::make_pair(KeyLen, DataLen);
@@ -778,6 +815,7 @@ ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
ASTSelectorLookupTrait::internal_key_type
ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
using namespace llvm::support;
+
SelectorTable &SelTable = Reader.getContext().Selectors;
unsigned N = endian::readNext<uint16_t, little, unaligned>(d);
IdentifierInfo *FirstII = Reader.getLocalIdentifier(
@@ -838,6 +876,7 @@ unsigned ASTIdentifierLookupTraitBase::ComputeHash(const internal_key_type& a) {
std::pair<unsigned, unsigned>
ASTIdentifierLookupTraitBase::ReadKeyDataLength(const unsigned char*& d) {
using namespace llvm::support;
+
unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
return std::make_pair(KeyLen, DataLen);
@@ -868,6 +907,7 @@ static bool readBit(unsigned &Bits) {
IdentID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) {
using namespace llvm::support;
+
unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d);
return Reader.getGlobalIdentifierID(F, RawID >> 1);
}
@@ -885,6 +925,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
const unsigned char* d,
unsigned DataLen) {
using namespace llvm::support;
+
unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d);
bool IsInteresting = RawID & 0x01;
@@ -1027,6 +1068,7 @@ unsigned DeclarationNameKey::getHash() const {
ModuleFile *
ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) {
using namespace llvm::support;
+
uint32_t ModuleFileID = endian::readNext<uint32_t, little, unaligned>(d);
return Reader.getLocalModuleFile(F, ModuleFileID);
}
@@ -1034,6 +1076,7 @@ ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) {
std::pair<unsigned, unsigned>
ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char *&d) {
using namespace llvm::support;
+
unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
return std::make_pair(KeyLen, DataLen);
@@ -1079,6 +1122,7 @@ void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type,
unsigned DataLen,
data_type_builder &Val) {
using namespace llvm::support;
+
for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls) {
uint32_t LocalID = endian::readNext<uint32_t, little, unaligned>(d);
Val.insert(Reader.getGlobalDeclID(F, LocalID));
@@ -1176,6 +1220,7 @@ bool ASTReader::ParseLineTable(ModuleFile &F,
// Parse the file names
std::map<int, int> FileIDs;
+ FileIDs[-1] = -1; // For unspecified filenames.
for (unsigned I = 0; Record[Idx]; ++I) {
// Extract the file name
auto Filename = ReadPath(F, Record, Idx);
@@ -1278,7 +1323,9 @@ resolveFileRelativeToOriginalDir(const std::string &Filename,
const std::string &CurrDir) {
assert(OriginalDir != CurrDir &&
"No point trying to resolve the file if the PCH dir didn't change");
+
using namespace llvm::sys;
+
SmallString<128> filePath(Filename);
fs::make_absolute(filePath);
assert(path::is_absolute(OriginalDir));
@@ -1672,6 +1719,7 @@ bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) {
std::pair<unsigned, unsigned>
HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
using namespace llvm::support;
+
unsigned KeyLen = (unsigned) endian::readNext<uint16_t, little, unaligned>(d);
unsigned DataLen = (unsigned) *d++;
return std::make_pair(KeyLen, DataLen);
@@ -1680,6 +1728,7 @@ HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
HeaderFileInfoTrait::internal_key_type
HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) {
using namespace llvm::support;
+
internal_key_type ikey;
ikey.Size = off_t(endian::readNext<uint64_t, little, unaligned>(d));
ikey.ModTime = time_t(endian::readNext<uint64_t, little, unaligned>(d));
@@ -1691,8 +1740,9 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) {
HeaderFileInfoTrait::data_type
HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
unsigned DataLen) {
- const unsigned char *End = d + DataLen;
using namespace llvm::support;
+
+ const unsigned char *End = d + DataLen;
HeaderFileInfo HFI;
unsigned Flags = *d++;
// FIXME: Refactor with mergeHeaderFileInfo in HeaderSearch.cpp.
@@ -1813,7 +1863,7 @@ namespace {
unsigned PriorGeneration;
unsigned &NumIdentifierLookups;
unsigned &NumIdentifierLookupHits;
- IdentifierInfo *Found;
+ IdentifierInfo *Found = nullptr;
public:
IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration,
@@ -1822,10 +1872,7 @@ namespace {
: Name(Name), NameHash(ASTIdentifierLookupTrait::ComputeHash(Name)),
PriorGeneration(PriorGeneration),
NumIdentifierLookups(NumIdentifierLookups),
- NumIdentifierLookupHits(NumIdentifierLookupHits),
- Found()
- {
- }
+ NumIdentifierLookupHits(NumIdentifierLookupHits) {}
bool operator()(ModuleFile &M) {
// If we've already searched this module file, skip it now.
@@ -1858,7 +1905,7 @@ namespace {
IdentifierInfo *getIdentifierInfo() const { return Found; }
};
-} // end anonymous namespace
+} // namespace
void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
// Note that we are loading an identifier.
@@ -1985,10 +2032,9 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
MD = PP.AllocateDefMacroDirective(MI, Loc);
break;
}
- case MacroDirective::MD_Undefine: {
+ case MacroDirective::MD_Undefine:
MD = PP.AllocateUndefMacroDirective(Loc);
break;
- }
case MacroDirective::MD_Visibility:
bool isPublic = Record[Idx++];
MD = PP.AllocateVisibilityMacroDirective(Loc, isPublic);
@@ -2060,14 +2106,12 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
StringRef Filename = FI.Filename;
const FileEntry *File = FileMgr.getFile(Filename, /*OpenFile=*/false);
-
// If we didn't find the file, resolve it relative to the
// original directory from which this AST file was created.
- if (File == nullptr && !F.OriginalDir.empty() && !CurrentDir.empty() &&
- F.OriginalDir != CurrentDir) {
- std::string Resolved = resolveFileRelativeToOriginalDir(Filename,
- F.OriginalDir,
- CurrentDir);
+ if (File == nullptr && !F.OriginalDir.empty() && !F.BaseDirectory.empty() &&
+ F.OriginalDir != F.BaseDirectory) {
+ std::string Resolved = resolveFileRelativeToOriginalDir(
+ Filename, F.OriginalDir, F.BaseDirectory);
if (!Resolved.empty())
File = FileMgr.getFile(Resolved);
}
@@ -2126,7 +2170,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
if (Complain) {
// Build a list of the PCH imports that got us here (in reverse).
SmallVector<ModuleFile *, 4> ImportStack(1, &F);
- while (ImportStack.back()->ImportedBy.size() > 0)
+ while (!ImportStack.back()->ImportedBy.empty())
ImportStack.push_back(ImportStack.back()->ImportedBy[0]);
// The top-level PCH is stale.
@@ -2487,7 +2531,23 @@ ASTReader::ReadControlBlock(ModuleFile &F,
{{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
(uint32_t)Record[Idx++]}}};
- auto ImportedFile = ReadPath(F, Record, Idx);
+
+ std::string ImportedName = ReadString(Record, Idx);
+ std::string ImportedFile;
+
+ // For prebuilt and explicit modules first consult the file map for
+ // an override. Note that here we don't search prebuilt module
+ // directories, only the explicit name to file mappings. Also, we will
+ // still verify the size/signature making sure it is essentially the
+ // same file but perhaps in a different location.
+ if (ImportedKind == MK_PrebuiltModule || ImportedKind == MK_ExplicitModule)
+ ImportedFile = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(
+ ImportedName, /*FileMapOnly*/ true);
+
+ if (ImportedFile.empty())
+ ImportedFile = ReadPath(F, Record, Idx);
+ else
+ SkipPath(Record, Idx);
// If our client can't cope with us being out of date, we can't cope with
// our dependency being missing.
@@ -2608,7 +2668,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
case llvm::BitstreamEntry::Error:
Error("error at end of module block in AST file");
return Failure;
- case llvm::BitstreamEntry::EndBlock: {
+ case llvm::BitstreamEntry::EndBlock:
// Outside of C++, we do not store a lookup map for the translation unit.
// Instead, mark it as needing a lookup map to be built if this module
// contains any declarations lexically within it (which it always does!).
@@ -2621,7 +2681,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
}
return Success;
- }
case llvm::BitstreamEntry::SubBlock:
switch (Entry.ID) {
case DECLTYPES_BLOCK_ID:
@@ -2981,8 +3040,20 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
case PP_CONDITIONAL_STACK:
if (!Record.empty()) {
+ unsigned Idx = 0, End = Record.size() - 1;
+ bool ReachedEOFWhileSkipping = Record[Idx++];
+ llvm::Optional<Preprocessor::PreambleSkipInfo> SkipInfo;
+ if (ReachedEOFWhileSkipping) {
+ SourceLocation HashToken = ReadSourceLocation(F, Record, Idx);
+ SourceLocation IfTokenLoc = ReadSourceLocation(F, Record, Idx);
+ bool FoundNonSkipPortion = Record[Idx++];
+ bool FoundElse = Record[Idx++];
+ SourceLocation ElseLoc = ReadSourceLocation(F, Record, Idx);
+ SkipInfo.emplace(HashToken, IfTokenLoc, FoundNonSkipPortion,
+ FoundElse, ElseLoc);
+ }
SmallVector<PPConditionalInfo, 4> ConditionalStack;
- for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) {
+ while (Idx < End) {
auto Loc = ReadSourceLocation(F, Record, Idx);
bool WasSkipping = Record[Idx++];
bool FoundNonSkip = Record[Idx++];
@@ -2990,7 +3061,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
ConditionalStack.push_back(
{Loc, WasSkipping, FoundNonSkip, FoundElse});
}
- PP.setReplayablePreambleConditionalStack(ConditionalStack);
+ PP.setReplayablePreambleConditionalStack(ConditionalStack, SkipInfo);
}
break;
@@ -3144,7 +3215,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
break;
}
- case DECL_UPDATE_OFFSETS: {
+ case DECL_UPDATE_OFFSETS:
if (Record.size() % 2 != 0) {
Error("invalid DECL_UPDATE_OFFSETS block in AST file");
return Failure;
@@ -3160,9 +3231,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
}
break;
- }
- case OBJC_CATEGORIES_MAP: {
+ case OBJC_CATEGORIES_MAP:
if (F.LocalNumObjCCategoriesInMap != 0) {
Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
return Failure;
@@ -3171,7 +3241,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
F.LocalNumObjCCategoriesInMap = Record[0];
F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)Blob.data();
break;
- }
case OBJC_CATEGORIES:
F.ObjCCategories.swap(Record);
@@ -3185,7 +3254,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
break;
- case HEADER_SEARCH_TABLE: {
+ case HEADER_SEARCH_TABLE:
F.HeaderFileInfoTableData = Blob.data();
F.LocalNumHeaderFileInfos = Record[1];
if (Record[0]) {
@@ -3202,7 +3271,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
PP.getHeaderSearchInfo().SetExternalLookup(this);
}
break;
- }
case FP_PRAGMA_OPTIONS:
// Later tables overwrite earlier ones.
@@ -3270,6 +3338,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
ReadSourceLocation(F, Record, I).getRawEncoding());
}
break;
+
case DELETE_EXPRS_TO_ANALYZE:
for (unsigned I = 0, N = Record.size(); I != N;) {
DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++]));
@@ -3283,7 +3352,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
}
break;
- case IMPORTED_MODULES: {
+ case IMPORTED_MODULES:
if (!F.isModule()) {
// If we aren't loading a module (which has its own exports), make
// all of the imported modules visible.
@@ -3299,7 +3368,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
}
}
break;
- }
case MACRO_OFFSET: {
if (F.LocalNumMacros != 0) {
@@ -3325,10 +3393,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
break;
}
- case LATE_PARSED_TEMPLATE: {
+ case LATE_PARSED_TEMPLATE:
LateParsedTemplates.append(Record.begin(), Record.end());
break;
- }
case OPTIMIZE_PRAGMA_OPTIONS:
if (Record.size() != 1) {
@@ -3384,6 +3451,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
PragmaPackStackEntry Entry;
Entry.Value = Record[Idx++];
Entry.Location = ReadSourceLocation(F, Record[Idx++]);
+ Entry.PushLocation = ReadSourceLocation(F, Record[Idx++]);
PragmaPackStrings.push_back(ReadString(Record, Idx));
Entry.SlotLabel = PragmaPackStrings.back();
PragmaPackStack.push_back(Entry);
@@ -3409,8 +3477,7 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
}
// Continuous range maps we may be updating in our module.
- typedef ContinuousRangeMap<uint32_t, int, 2>::Builder
- RemapBuilder;
+ using RemapBuilder = ContinuousRangeMap<uint32_t, int, 2>::Builder;
RemapBuilder SLocRemap(F.SLocRemap);
RemapBuilder IdentifierRemap(F.IdentifierRemap);
RemapBuilder MacroRemap(F.MacroRemap);
@@ -3421,12 +3488,18 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
RemapBuilder TypeRemap(F.TypeRemap);
while (Data < DataEnd) {
- // FIXME: Looking up dependency modules by filename is horrible.
+ // FIXME: Looking up dependency modules by filename is horrible. Let's
+ // start fixing this with prebuilt and explicit modules and see how it
+ // goes...
using namespace llvm::support;
+ ModuleKind Kind = static_cast<ModuleKind>(
+ endian::readNext<uint8_t, little, unaligned>(Data));
uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data);
StringRef Name = StringRef((const char*)Data, Len);
Data += Len;
- ModuleFile *OM = ModuleMgr.lookup(Name);
+ ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule
+ ? ModuleMgr.lookupByModuleName(Name)
+ : ModuleMgr.lookupByFileName(Name));
if (!OM) {
std::string Msg =
"SourceLocation remap refers to unknown module, cannot find ";
@@ -3497,15 +3570,22 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
if (!ModMap) {
assert(ImportedBy && "top-level import should be verified");
if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) {
- if (auto *ASTFE = M ? M->getASTFile() : nullptr)
+ if (auto *ASTFE = M ? M->getASTFile() : nullptr) {
// This module was defined by an imported (explicit) module.
Diag(diag::err_module_file_conflict) << F.ModuleName << F.FileName
<< ASTFE->getName();
- else
+ } else {
// This module was built with a different module map.
Diag(diag::err_imported_module_not_found)
<< F.ModuleName << F.FileName << ImportedBy->FileName
<< F.ModuleMapPath;
+ // In case it was imported by a PCH, there's a chance the user is
+ // just missing to include the search path to the directory containing
+ // the modulemap.
+ if (ImportedBy->Kind == MK_PCH)
+ Diag(diag::note_imported_by_pch_module_not_found)
+ << llvm::sys::path::parent_path(F.ModuleMapPath);
+ }
}
return OutOfDate;
}
@@ -3568,7 +3648,6 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
return Success;
}
-
/// \brief Move the given method to the back of the global list of methods.
static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {
// Find the entry for this selector in the method pool.
@@ -4065,13 +4144,6 @@ ASTReader::ReadASTCore(StringRef FileName,
assert(M && "Missing module file");
- // FIXME: This seems rather a hack. Should CurrentDir be part of the
- // module?
- if (FileName != "-") {
- CurrentDir = llvm::sys::path::parent_path(FileName);
- if (CurrentDir.empty()) CurrentDir = ".";
- }
-
ModuleFile &F = *M;
BitstreamCursor &Stream = F.Stream;
Stream = BitstreamCursor(PCHContainerRdr.ExtractPCH(*F.Buffer));
@@ -4228,7 +4300,7 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
// Read all of the records in the options block.
RecordData Record;
ASTReadResult Result = Success;
- while (1) {
+ while (true) {
llvm::BitstreamEntry Entry = Stream.advance();
switch (Entry.Kind) {
@@ -4248,11 +4320,10 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
Record.clear();
switch (
(UnhashedControlBlockRecordTypes)Stream.readRecord(Entry.ID, Record)) {
- case SIGNATURE: {
+ case SIGNATURE:
if (F)
std::copy(Record.begin(), Record.end(), F->Signature.data());
break;
- }
case DIAGNOSTIC_OPTIONS: {
bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
if (Listener && ValidateDiagnosticOptions &&
@@ -4581,9 +4652,7 @@ namespace {
ExistingTargetOpts(ExistingTargetOpts),
ExistingPPOpts(ExistingPPOpts),
ExistingModuleCachePath(ExistingModuleCachePath),
- FileMgr(FileMgr)
- {
- }
+ FileMgr(FileMgr) {}
bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
bool AllowCompatibleDifferences) override {
@@ -4613,7 +4682,7 @@ namespace {
}
};
-} // end anonymous namespace
+} // namespace
bool ASTReader::readASTFileControlBlock(
StringRef Filename, FileManager &FileMgr,
@@ -4697,15 +4766,12 @@ bool ASTReader::readASTFileControlBlock(
StringRef Blob;
unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
switch ((ControlRecordTypes)RecCode) {
- case METADATA: {
+ case METADATA:
if (Record[0] != VERSION_MAJOR)
return true;
-
if (Listener.ReadFullVersionInformation(Blob))
return true;
-
break;
- }
case MODULE_NAME:
Listener.ReadModuleName(Blob);
break;
@@ -4764,6 +4830,7 @@ bool ASTReader::readASTFileControlBlock(
while (Idx < N) {
// Read information about the AST file.
Idx += 5; // ImportLoc, Size, ModTime, Signature
+ SkipString(Record, Idx); // Module name; FIXME: pass to listener?
std::string Filename = ReadString(Record, Idx);
ResolveImportedPath(Filename, ModuleDir);
Listener.visitImport(Filename);
@@ -4856,7 +4923,6 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
bool First = true;
Module *CurrentModule = nullptr;
- Module::ModuleKind ModuleKind = Module::ModuleMapModule;
RecordData Record;
while (true) {
llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
@@ -4904,6 +4970,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
unsigned Idx = 0;
SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[Idx++]);
SubmoduleID Parent = getGlobalSubmoduleID(F, Record[Idx++]);
+ Module::ModuleKind Kind = (Module::ModuleKind)Record[Idx++];
bool IsFramework = Record[Idx++];
bool IsExplicit = Record[Idx++];
bool IsSystem = Record[Idx++];
@@ -4950,7 +5017,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
CurrentModule->PresumedModuleMapFile = F.ModuleMapPath;
}
- CurrentModule->Kind = ModuleKind;
+ CurrentModule->Kind = Kind;
CurrentModule->Signature = F.Signature;
CurrentModule->IsFromModuleFile = true;
CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
@@ -5012,10 +5079,9 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
// them here.
break;
- case SUBMODULE_TOPHEADER: {
+ case SUBMODULE_TOPHEADER:
CurrentModule->addTopHeaderFilename(Blob);
break;
- }
case SUBMODULE_UMBRELLA_DIR: {
std::string Dirname = Blob;
@@ -5049,11 +5115,10 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules);
}
- ModuleKind = (Module::ModuleKind)Record[2];
break;
}
- case SUBMODULE_IMPORTS: {
+ case SUBMODULE_IMPORTS:
for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {
UnresolvedModuleRef Unresolved;
Unresolved.File = &F;
@@ -5064,9 +5129,8 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
UnresolvedModuleRefs.push_back(Unresolved);
}
break;
- }
- case SUBMODULE_EXPORTS: {
+ case SUBMODULE_EXPORTS:
for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
UnresolvedModuleRef Unresolved;
Unresolved.File = &F;
@@ -5081,12 +5145,11 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
// the parsed, unresolved exports around.
CurrentModule->UnresolvedExports.clear();
break;
- }
- case SUBMODULE_REQUIRES: {
+
+ case SUBMODULE_REQUIRES:
CurrentModule->addRequirement(Blob, Record[0], PP.getLangOpts(),
PP.getTargetInfo());
break;
- }
case SUBMODULE_LINK_LIBRARY:
CurrentModule->LinkLibraries.push_back(
@@ -5109,7 +5172,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
break;
}
- case SUBMODULE_INITIALIZERS:
+ case SUBMODULE_INITIALIZERS: {
if (!ContextObj)
break;
SmallVector<uint32_t, 16> Inits;
@@ -5118,6 +5181,11 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
ContextObj->addLazyModuleInitializers(CurrentModule, Inits);
break;
}
+
+ case SUBMODULE_EXPORT_AS:
+ CurrentModule->ExportAsModule = Blob.str();
+ break;
+ }
}
}
@@ -5406,10 +5474,12 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
llvm_unreachable("Invalid PreprocessorDetailRecordTypes");
}
-/// \brief \arg SLocMapI points at a chunk of a module that contains no
-/// preprocessed entities or the entities it contains are not the ones we are
-/// looking for. Find the next module that contains entities and return the ID
+/// \brief Find the next module that contains entities and return the ID
/// of the first entry.
+///
+/// \param SLocMapI points at a chunk of a module that contains no
+/// preprocessed entities or the entities it contains are not the ones we are
+/// looking for.
PreprocessedEntityID ASTReader::findNextPreprocessedEntity(
GlobalSLocOffsetMapType::const_iterator SLocMapI) const {
++SLocMapI;
@@ -5429,7 +5499,7 @@ struct PPEntityComp {
const ASTReader &Reader;
ModuleFile &M;
- PPEntityComp(const ASTReader &Reader, ModuleFile &M) : Reader(Reader), M(M) { }
+ PPEntityComp(const ASTReader &Reader, ModuleFile &M) : Reader(Reader), M(M) {}
bool operator()(const PPEntityOffset &L, const PPEntityOffset &R) const {
SourceLocation LHS = getLoc(L);
@@ -5452,7 +5522,7 @@ struct PPEntityComp {
}
};
-} // end anonymous namespace
+} // namespace
PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc,
bool EndsAfter) const {
@@ -5468,7 +5538,9 @@ PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc,
return findNextPreprocessedEntity(SLocMapI);
ModuleFile &M = *SLocMapI->second;
- typedef const PPEntityOffset *pp_iterator;
+
+ using pp_iterator = const PPEntityOffset *;
+
pp_iterator pp_begin = M.PreprocessedEntityOffsets;
pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
@@ -5546,12 +5618,10 @@ namespace {
/// \brief Visitor used to search for information about a header file.
class HeaderFileInfoVisitor {
const FileEntry *FE;
-
Optional<HeaderFileInfo> HFI;
public:
- explicit HeaderFileInfoVisitor(const FileEntry *FE)
- : FE(FE) { }
+ explicit HeaderFileInfoVisitor(const FileEntry *FE) : FE(FE) {}
bool operator()(ModuleFile &M) {
HeaderFileInfoLookupTable *Table
@@ -5571,7 +5641,7 @@ namespace {
Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }
};
-} // end anonymous namespace
+} // namespace
HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) {
HeaderFileInfoVisitor Visitor(FE);
@@ -5709,7 +5779,8 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
// Preserve the property that the imaginary root file describes the
// current state.
- auto &T = Diag.DiagStatesByLoc.Files[FileID()].StateTransitions;
+ FileID NullFile;
+ auto &T = Diag.DiagStatesByLoc.Files[NullFile].StateTransitions;
if (T.empty())
T.push_back({CurState, 0});
else
@@ -6091,6 +6162,7 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
return Context.getObjCTypeParamType(Decl, Protos);
}
+
case TYPE_OBJC_OBJECT: {
unsigned Idx = 0;
QualType Base = readType(*Loc.F, Record, Idx);
@@ -6250,6 +6322,18 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
return Context.getDependentSizedExtVectorType(ElementType, SizeExpr,
AttrLoc);
}
+
+ case TYPE_DEPENDENT_ADDRESS_SPACE: {
+ unsigned Idx = 0;
+
+ // DependentAddressSpaceType
+ QualType PointeeType = readType(*Loc.F, Record, Idx);
+ Expr *AddrSpaceExpr = ReadExpr(*Loc.F);
+ SourceLocation AttrLoc = ReadSourceLocation(*Loc.F, Record, Idx);
+
+ return Context.getDependentAddressSpaceType(PointeeType, AddrSpaceExpr,
+ AttrLoc);
+ }
}
llvm_unreachable("Invalid TypeCode!");
}
@@ -6275,7 +6359,9 @@ void ASTReader::readExceptionSpec(ModuleFile &ModuleFile,
}
}
-class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
+namespace clang {
+
+class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
ModuleFile *F;
ASTReader *Reader;
const ASTReader::RecordData &Record;
@@ -6310,6 +6396,8 @@ public:
void VisitArrayTypeLoc(ArrayTypeLoc);
};
+} // namespace clang
+
void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
// nothing to do
}
@@ -6383,6 +6471,17 @@ void TypeLocReader::VisitDependentSizedArrayTypeLoc(
VisitArrayTypeLoc(TL);
}
+void TypeLocReader::VisitDependentAddressSpaceTypeLoc(
+ DependentAddressSpaceTypeLoc TL) {
+
+ TL.setAttrNameLoc(ReadSourceLocation());
+ SourceRange range;
+ range.setBegin(ReadSourceLocation());
+ range.setEnd(ReadSourceLocation());
+ TL.setAttrOperandParensRange(range);
+ TL.setAttrExprOperand(Reader->ReadExpr(*F));
+}
+
void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
DependentSizedExtVectorTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
@@ -6415,23 +6514,28 @@ void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
VisitFunctionTypeLoc(TL);
}
+
void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
+
void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
+
void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
TL.setTypeofLoc(ReadSourceLocation());
TL.setLParenLoc(ReadSourceLocation());
TL.setRParenLoc(ReadSourceLocation());
}
+
void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
TL.setTypeofLoc(ReadSourceLocation());
TL.setLParenLoc(ReadSourceLocation());
TL.setRParenLoc(ReadSourceLocation());
TL.setUnderlyingTInfo(GetTypeSourceInfo());
}
+
void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
@@ -6485,10 +6589,12 @@ void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
SubstTemplateTypeParmTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
+
void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(
SubstTemplateTypeParmPackTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation());
}
+
void TypeLocReader::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
TL.setTemplateKeywordLoc(ReadSourceLocation());
@@ -6501,6 +6607,7 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc(
Reader->GetTemplateArgumentLocInfo(
*F, TL.getTypePtr()->getArg(i).getKind(), Record, Idx));
}
+
void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
TL.setLParenLoc(ReadSourceLocation());
TL.setRParenLoc(ReadSourceLocation());
@@ -6611,13 +6718,11 @@ QualType ASTReader::GetType(TypeID ID) {
case PREDEF_TYPE_BOOL_ID:
T = Context.BoolTy;
break;
-
case PREDEF_TYPE_CHAR_U_ID:
case PREDEF_TYPE_CHAR_S_ID:
// FIXME: Check that the signedness of CharTy is correct!
T = Context.CharTy;
break;
-
case PREDEF_TYPE_UCHAR_ID:
T = Context.UnsignedCharTy;
break;
@@ -6669,6 +6774,9 @@ QualType ASTReader::GetType(TypeID ID) {
case PREDEF_TYPE_LONGDOUBLE_ID:
T = Context.LongDoubleTy;
break;
+ case PREDEF_TYPE_FLOAT16_ID:
+ T = Context.Float16Ty;
+ break;
case PREDEF_TYPE_FLOAT128_ID:
T = Context.Float128Ty;
break;
@@ -6728,19 +6836,15 @@ QualType ASTReader::GetType(TypeID ID) {
case PREDEF_TYPE_AUTO_DEDUCT:
T = Context.getAutoDeductType();
break;
-
case PREDEF_TYPE_AUTO_RREF_DEDUCT:
T = Context.getAutoRRefDeductType();
break;
-
case PREDEF_TYPE_ARC_UNBRIDGED_CAST:
T = Context.ARCUnbridgedCastTy;
break;
-
case PREDEF_TYPE_BUILTIN_FN:
T = Context.BuiltinFnTy;
break;
-
case PREDEF_TYPE_OMP_ARRAY_SECTION:
T = Context.OMPArraySectionTy;
break;
@@ -7227,7 +7331,7 @@ public:
}
};
-} // end anonymous namespace
+} // namespace
void ASTReader::FindFileRegionDecls(FileID File,
unsigned Offset, unsigned Length,
@@ -7423,30 +7527,25 @@ void ASTReader::PrintStats() {
NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
* 100));
- if (TotalNumMethodPoolEntries) {
+ if (TotalNumMethodPoolEntries)
std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
* 100));
- }
- if (NumMethodPoolLookups) {
+ if (NumMethodPoolLookups)
std::fprintf(stderr, " %u/%u method pool lookups succeeded (%f%%)\n",
NumMethodPoolHits, NumMethodPoolLookups,
((float)NumMethodPoolHits/NumMethodPoolLookups * 100.0));
- }
- if (NumMethodPoolTableLookups) {
+ if (NumMethodPoolTableLookups)
std::fprintf(stderr, " %u/%u method pool table lookups succeeded (%f%%)\n",
NumMethodPoolTableHits, NumMethodPoolTableLookups,
((float)NumMethodPoolTableHits/NumMethodPoolTableLookups
* 100.0));
- }
-
- if (NumIdentifierLookupHits) {
+ if (NumIdentifierLookupHits)
std::fprintf(stderr,
" %u / %u identifier table lookups succeeded (%f%%)\n",
NumIdentifierLookupHits, NumIdentifierLookups,
(double)NumIdentifierLookupHits*100.0/NumIdentifierLookups);
- }
if (GlobalIndex) {
std::fprintf(stderr, "\n");
@@ -7466,7 +7565,8 @@ dumpModuleIDMap(StringRef Name,
if (Map.begin() == Map.end())
return;
- typedef ContinuousRangeMap<Key, ModuleFile *, InitialCapacity> MapType;
+ using MapType = ContinuousRangeMap<Key, ModuleFile *, InitialCapacity>;
+
llvm::errs() << Name << ":\n";
for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
I != IEnd; ++I) {
@@ -7579,13 +7679,14 @@ void ASTReader::UpdateSema() {
"Expected a default alignment value");
SemaObj->PackStack.Stack.emplace_back(
PragmaPackStack.front().SlotLabel, SemaObj->PackStack.CurrentValue,
- SemaObj->PackStack.CurrentPragmaLocation);
+ SemaObj->PackStack.CurrentPragmaLocation,
+ PragmaPackStack.front().PushLocation);
DropFirst = true;
}
for (const auto &Entry :
llvm::makeArrayRef(PragmaPackStack).drop_front(DropFirst ? 1 : 0))
SemaObj->PackStack.Stack.emplace_back(Entry.SlotLabel, Entry.Value,
- Entry.Location);
+ Entry.Location, Entry.PushLocation);
if (PragmaPackCurrentLocation.isInvalid()) {
assert(*PragmaPackCurrentValue == SemaObj->PackStack.DefaultValue &&
"Expected a default alignment value");
@@ -7662,7 +7763,7 @@ namespace clang {
StringRef Next() override;
};
-} // end namespace clang
+} // namespace clang
ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader,
bool SkipModules)
@@ -7720,7 +7821,7 @@ public:
}
};
-} // end anonymous namespace.
+} // namespace
IdentifierIterator *ASTReader::getIdentifiers() {
if (!loadGlobalIndex()) {
@@ -7742,19 +7843,17 @@ namespace serialization {
ASTReader &Reader;
Selector Sel;
unsigned PriorGeneration;
- unsigned InstanceBits;
- unsigned FactoryBits;
- bool InstanceHasMoreThanOneDecl;
- bool FactoryHasMoreThanOneDecl;
+ unsigned InstanceBits = 0;
+ unsigned FactoryBits = 0;
+ bool InstanceHasMoreThanOneDecl = false;
+ bool FactoryHasMoreThanOneDecl = false;
SmallVector<ObjCMethodDecl *, 4> InstanceMethods;
SmallVector<ObjCMethodDecl *, 4> FactoryMethods;
public:
ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel,
unsigned PriorGeneration)
- : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration),
- InstanceBits(0), FactoryBits(0), InstanceHasMoreThanOneDecl(false),
- FactoryHasMoreThanOneDecl(false) {}
+ : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration) {}
bool operator()(ModuleFile &M) {
if (!M.SelectorLookupTable)
@@ -7802,14 +7901,16 @@ namespace serialization {
unsigned getInstanceBits() const { return InstanceBits; }
unsigned getFactoryBits() const { return FactoryBits; }
+
bool instanceHasMoreThanOneDecl() const {
return InstanceHasMoreThanOneDecl;
}
+
bool factoryHasMoreThanOneDecl() const { return FactoryHasMoreThanOneDecl; }
};
-} // end namespace serialization
-} // end namespace clang
+} // namespace serialization
+} // namespace clang
/// \brief Add the given set of methods to the method list.
static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods,
@@ -7952,7 +8053,7 @@ void ASTReader::ReadUnusedLocalTypedefNameCandidates(
}
void ASTReader::ReadReferencedSelectors(
- SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
+ SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) {
if (ReferencedSelectorsData.empty())
return;
@@ -7970,7 +8071,7 @@ void ASTReader::ReadReferencedSelectors(
}
void ASTReader::ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WeakIDs) {
+ SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WeakIDs) {
if (WeakUndeclaredIdentifiers.empty())
return;
@@ -8002,7 +8103,7 @@ void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {
}
void ASTReader::ReadPendingInstantiations(
- SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending) {
+ SmallVectorImpl<std::pair<ValueDecl *, SourceLocation>> &Pending) {
for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {
ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
SourceLocation Loc
@@ -8276,8 +8377,8 @@ ASTReader::getSourceDescriptor(unsigned ID) {
}
ExternalASTSource::ExtKind ASTReader::hasExternalDefinitions(const Decl *FD) {
- auto I = BodySource.find(FD);
- if (I == BodySource.end())
+ auto I = DefinitionSource.find(FD);
+ if (I == DefinitionSource.end())
return EK_ReplyHazy;
return I->second ? EK_Never : EK_Always;
}
@@ -8714,11 +8815,10 @@ ASTReader::ReadNestedNameSpecifier(ModuleFile &F,
break;
}
- case NestedNameSpecifier::Global: {
+ case NestedNameSpecifier::Global:
NNS = NestedNameSpecifier::GlobalSpecifier(Context);
// No associated value, and there can't be a prefix.
break;
- }
case NestedNameSpecifier::Super: {
CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(F, Record, Idx);
@@ -8895,7 +8995,7 @@ void ASTReader::ReadComments() {
ASTContext &Context = getContext();
std::vector<RawComment *> Comments;
for (SmallVectorImpl<std::pair<BitstreamCursor,
- serialization::ModuleFile *> >::iterator
+ serialization::ModuleFile *>>::iterator
I = CommentsCursors.begin(),
E = CommentsCursors.end();
I != E; ++I) {
@@ -8985,7 +9085,7 @@ std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
return M->ModuleName;
// Not from a module.
- return "";
+ return {};
}
void ASTReader::finishPendingActions() {
@@ -8995,8 +9095,8 @@ void ASTReader::finishPendingActions() {
!PendingUpdateRecords.empty()) {
// If any identifiers with corresponding top-level declarations have
// been loaded, load those declarations now.
- typedef llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> >
- TopLevelDeclsMap;
+ using TopLevelDeclsMap =
+ llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2>>;
TopLevelDeclsMap TopLevelDecls;
while (!PendingIdentifierInfos.empty()) {
@@ -9167,7 +9267,8 @@ void ASTReader::diagnoseOdrViolations() {
Merge.first->decls_begin();
Merge.first->bases_begin();
Merge.first->vbases_begin();
- for (auto *RD : Merge.second) {
+ for (auto &RecordPair : Merge.second) {
+ auto *RD = RecordPair.first;
RD->decls_begin();
RD->bases_begin();
RD->vbases_begin();
@@ -9273,14 +9374,326 @@ void ASTReader::diagnoseOdrViolations() {
bool Diagnosed = false;
CXXRecordDecl *FirstRecord = Merge.first;
std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
- for (CXXRecordDecl *SecondRecord : Merge.second) {
+ for (auto &RecordPair : Merge.second) {
+ CXXRecordDecl *SecondRecord = RecordPair.first;
// Multiple different declarations got merged together; tell the user
// where they came from.
if (FirstRecord == SecondRecord)
continue;
std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
+
+ auto *FirstDD = FirstRecord->DefinitionData;
+ auto *SecondDD = RecordPair.second;
+
+ assert(FirstDD && SecondDD && "Definitions without DefinitionData");
+
+ // Diagnostics from DefinitionData are emitted here.
+ if (FirstDD != SecondDD) {
+ enum ODRDefinitionDataDifference {
+ NumBases,
+ NumVBases,
+ BaseType,
+ BaseVirtual,
+ BaseAccess,
+ };
+ auto ODRDiagError = [FirstRecord, &FirstModule,
+ this](SourceLocation Loc, SourceRange Range,
+ ODRDefinitionDataDifference DiffType) {
+ return Diag(Loc, diag::err_module_odr_violation_definition_data)
+ << FirstRecord << FirstModule.empty() << FirstModule << Range
+ << DiffType;
+ };
+ auto ODRDiagNote = [&SecondModule,
+ this](SourceLocation Loc, SourceRange Range,
+ ODRDefinitionDataDifference DiffType) {
+ return Diag(Loc, diag::note_module_odr_violation_definition_data)
+ << SecondModule << Range << DiffType;
+ };
+
+ ODRHash Hash;
+ auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {
+ Hash.clear();
+ Hash.AddQualType(Ty);
+ return Hash.CalculateHash();
+ };
+
+ unsigned FirstNumBases = FirstDD->NumBases;
+ unsigned FirstNumVBases = FirstDD->NumVBases;
+ unsigned SecondNumBases = SecondDD->NumBases;
+ unsigned SecondNumVBases = SecondDD->NumVBases;
+
+ auto GetSourceRange = [](struct CXXRecordDecl::DefinitionData *DD) {
+ unsigned NumBases = DD->NumBases;
+ if (NumBases == 0) return SourceRange();
+ auto bases = DD->bases();
+ return SourceRange(bases[0].getLocStart(),
+ bases[NumBases - 1].getLocEnd());
+ };
+
+ if (FirstNumBases != SecondNumBases) {
+ ODRDiagError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
+ NumBases)
+ << FirstNumBases;
+ ODRDiagNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
+ NumBases)
+ << SecondNumBases;
+ Diagnosed = true;
+ break;
+ }
+
+ if (FirstNumVBases != SecondNumVBases) {
+ ODRDiagError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
+ NumVBases)
+ << FirstNumVBases;
+ ODRDiagNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
+ NumVBases)
+ << SecondNumVBases;
+ Diagnosed = true;
+ break;
+ }
+
+ auto FirstBases = FirstDD->bases();
+ auto SecondBases = SecondDD->bases();
+ unsigned i = 0;
+ for (i = 0; i < FirstNumBases; ++i) {
+ auto FirstBase = FirstBases[i];
+ auto SecondBase = SecondBases[i];
+ if (ComputeQualTypeODRHash(FirstBase.getType()) !=
+ ComputeQualTypeODRHash(SecondBase.getType())) {
+ ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
+ BaseType)
+ << (i + 1) << FirstBase.getType();
+ ODRDiagNote(SecondRecord->getLocation(),
+ SecondBase.getSourceRange(), BaseType)
+ << (i + 1) << SecondBase.getType();
+ break;
+ }
+
+ if (FirstBase.isVirtual() != SecondBase.isVirtual()) {
+ ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
+ BaseVirtual)
+ << (i + 1) << FirstBase.isVirtual() << FirstBase.getType();
+ ODRDiagNote(SecondRecord->getLocation(),
+ SecondBase.getSourceRange(), BaseVirtual)
+ << (i + 1) << SecondBase.isVirtual() << SecondBase.getType();
+ break;
+ }
+
+ if (FirstBase.getAccessSpecifierAsWritten() !=
+ SecondBase.getAccessSpecifierAsWritten()) {
+ ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
+ BaseAccess)
+ << (i + 1) << FirstBase.getType()
+ << (int)FirstBase.getAccessSpecifierAsWritten();
+ ODRDiagNote(SecondRecord->getLocation(),
+ SecondBase.getSourceRange(), BaseAccess)
+ << (i + 1) << SecondBase.getType()
+ << (int)SecondBase.getAccessSpecifierAsWritten();
+ break;
+ }
+ }
+
+ if (i != FirstNumBases) {
+ Diagnosed = true;
+ break;
+ }
+ }
+
using DeclHashes = llvm::SmallVector<std::pair<Decl *, unsigned>, 4>;
+
+ const ClassTemplateDecl *FirstTemplate =
+ FirstRecord->getDescribedClassTemplate();
+ const ClassTemplateDecl *SecondTemplate =
+ SecondRecord->getDescribedClassTemplate();
+
+ assert(!FirstTemplate == !SecondTemplate &&
+ "Both pointers should be null or non-null");
+
+ enum ODRTemplateDifference {
+ ParamEmptyName,
+ ParamName,
+ ParamSingleDefaultArgument,
+ ParamDifferentDefaultArgument,
+ };
+
+ if (FirstTemplate && SecondTemplate) {
+ DeclHashes FirstTemplateHashes;
+ DeclHashes SecondTemplateHashes;
+ ODRHash Hash;
+
+ auto PopulateTemplateParameterHashs =
+ [&Hash](DeclHashes &Hashes, const ClassTemplateDecl *TD) {
+ for (auto *D : TD->getTemplateParameters()->asArray()) {
+ Hash.clear();
+ Hash.AddSubDecl(D);
+ Hashes.emplace_back(D, Hash.CalculateHash());
+ }
+ };
+
+ PopulateTemplateParameterHashs(FirstTemplateHashes, FirstTemplate);
+ PopulateTemplateParameterHashs(SecondTemplateHashes, SecondTemplate);
+
+ assert(FirstTemplateHashes.size() == SecondTemplateHashes.size() &&
+ "Number of template parameters should be equal.");
+
+ auto FirstIt = FirstTemplateHashes.begin();
+ auto FirstEnd = FirstTemplateHashes.end();
+ auto SecondIt = SecondTemplateHashes.begin();
+ for (; FirstIt != FirstEnd; ++FirstIt, ++SecondIt) {
+ if (FirstIt->second == SecondIt->second)
+ continue;
+
+ auto ODRDiagError = [FirstRecord, &FirstModule,
+ this](SourceLocation Loc, SourceRange Range,
+ ODRTemplateDifference DiffType) {
+ return Diag(Loc, diag::err_module_odr_violation_template_parameter)
+ << FirstRecord << FirstModule.empty() << FirstModule << Range
+ << DiffType;
+ };
+ auto ODRDiagNote = [&SecondModule,
+ this](SourceLocation Loc, SourceRange Range,
+ ODRTemplateDifference DiffType) {
+ return Diag(Loc, diag::note_module_odr_violation_template_parameter)
+ << SecondModule << Range << DiffType;
+ };
+
+ const NamedDecl* FirstDecl = cast<NamedDecl>(FirstIt->first);
+ const NamedDecl* SecondDecl = cast<NamedDecl>(SecondIt->first);
+
+ assert(FirstDecl->getKind() == SecondDecl->getKind() &&
+ "Parameter Decl's should be the same kind.");
+
+ DeclarationName FirstName = FirstDecl->getDeclName();
+ DeclarationName SecondName = SecondDecl->getDeclName();
+
+ if (FirstName != SecondName) {
+ const bool FirstNameEmpty =
+ FirstName.isIdentifier() && !FirstName.getAsIdentifierInfo();
+ const bool SecondNameEmpty =
+ SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo();
+ assert((!FirstNameEmpty || !SecondNameEmpty) &&
+ "Both template parameters cannot be unnamed.");
+ ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(),
+ FirstNameEmpty ? ParamEmptyName : ParamName)
+ << FirstName;
+ ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(),
+ SecondNameEmpty ? ParamEmptyName : ParamName)
+ << SecondName;
+ break;
+ }
+
+ switch (FirstDecl->getKind()) {
+ default:
+ llvm_unreachable("Invalid template parameter type.");
+ case Decl::TemplateTypeParm: {
+ const auto *FirstParam = cast<TemplateTypeParmDecl>(FirstDecl);
+ const auto *SecondParam = cast<TemplateTypeParmDecl>(SecondDecl);
+ const bool HasFirstDefaultArgument =
+ FirstParam->hasDefaultArgument() &&
+ !FirstParam->defaultArgumentWasInherited();
+ const bool HasSecondDefaultArgument =
+ SecondParam->hasDefaultArgument() &&
+ !SecondParam->defaultArgumentWasInherited();
+
+ if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
+ ODRDiagError(FirstDecl->getLocation(),
+ FirstDecl->getSourceRange(),
+ ParamSingleDefaultArgument)
+ << HasFirstDefaultArgument;
+ ODRDiagNote(SecondDecl->getLocation(),
+ SecondDecl->getSourceRange(),
+ ParamSingleDefaultArgument)
+ << HasSecondDefaultArgument;
+ break;
+ }
+
+ assert(HasFirstDefaultArgument && HasSecondDefaultArgument &&
+ "Expecting default arguments.");
+
+ ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(),
+ ParamDifferentDefaultArgument);
+ ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(),
+ ParamDifferentDefaultArgument);
+
+ break;
+ }
+ case Decl::NonTypeTemplateParm: {
+ const auto *FirstParam = cast<NonTypeTemplateParmDecl>(FirstDecl);
+ const auto *SecondParam = cast<NonTypeTemplateParmDecl>(SecondDecl);
+ const bool HasFirstDefaultArgument =
+ FirstParam->hasDefaultArgument() &&
+ !FirstParam->defaultArgumentWasInherited();
+ const bool HasSecondDefaultArgument =
+ SecondParam->hasDefaultArgument() &&
+ !SecondParam->defaultArgumentWasInherited();
+
+ if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
+ ODRDiagError(FirstDecl->getLocation(),
+ FirstDecl->getSourceRange(),
+ ParamSingleDefaultArgument)
+ << HasFirstDefaultArgument;
+ ODRDiagNote(SecondDecl->getLocation(),
+ SecondDecl->getSourceRange(),
+ ParamSingleDefaultArgument)
+ << HasSecondDefaultArgument;
+ break;
+ }
+
+ assert(HasFirstDefaultArgument && HasSecondDefaultArgument &&
+ "Expecting default arguments.");
+
+ ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(),
+ ParamDifferentDefaultArgument);
+ ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(),
+ ParamDifferentDefaultArgument);
+
+ break;
+ }
+ case Decl::TemplateTemplateParm: {
+ const auto *FirstParam = cast<TemplateTemplateParmDecl>(FirstDecl);
+ const auto *SecondParam =
+ cast<TemplateTemplateParmDecl>(SecondDecl);
+ const bool HasFirstDefaultArgument =
+ FirstParam->hasDefaultArgument() &&
+ !FirstParam->defaultArgumentWasInherited();
+ const bool HasSecondDefaultArgument =
+ SecondParam->hasDefaultArgument() &&
+ !SecondParam->defaultArgumentWasInherited();
+
+ if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
+ ODRDiagError(FirstDecl->getLocation(),
+ FirstDecl->getSourceRange(),
+ ParamSingleDefaultArgument)
+ << HasFirstDefaultArgument;
+ ODRDiagNote(SecondDecl->getLocation(),
+ SecondDecl->getSourceRange(),
+ ParamSingleDefaultArgument)
+ << HasSecondDefaultArgument;
+ break;
+ }
+
+ assert(HasFirstDefaultArgument && HasSecondDefaultArgument &&
+ "Expecting default arguments.");
+
+ ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(),
+ ParamDifferentDefaultArgument);
+ ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(),
+ ParamDifferentDefaultArgument);
+
+ break;
+ }
+ }
+
+ break;
+ }
+
+ if (FirstIt != FirstEnd) {
+ Diagnosed = true;
+ break;
+ }
+ }
+
DeclHashes FirstHashes;
DeclHashes SecondHashes;
ODRHash Hash;
@@ -10050,7 +10463,7 @@ void ASTReader::diagnoseOdrViolations() {
}
}
- if (Diagnosed == true)
+ if (Diagnosed)
continue;
Diag(FirstDecl->getLocation(),
@@ -10160,7 +10573,8 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
ContextObj(Context),
- ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr),
+ ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr,
+ PP.getHeaderSearchInfo()),
PCMCache(PP.getPCMCache()), DummyIdResolver(PP),
ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
DisableValidation(DisableValidation),
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 085341571ced..a3bf0d971267 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -453,7 +453,7 @@ uint64_t ASTDeclReader::GetCurrentCursorOffset() {
void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
if (Record.readInt())
- Reader.BodySource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
+ Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
CD->NumCtorInitializers = Record.readInt();
if (CD->NumCtorInitializers)
@@ -1219,16 +1219,17 @@ void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
VisitDeclaratorDecl(FD);
FD->Mutable = Record.readInt();
- if (int BitWidthOrInitializer = Record.readInt()) {
- FD->InitStorage.setInt(
- static_cast<FieldDecl::InitStorageKind>(BitWidthOrInitializer - 1));
- if (FD->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) {
- // Read captured variable length array.
- FD->InitStorage.setPointer(Record.readType().getAsOpaquePtr());
- } else {
- FD->InitStorage.setPointer(Record.readExpr());
- }
+
+ if (auto ISK = static_cast<FieldDecl::InitStorageKind>(Record.readInt())) {
+ FD->InitStorage.setInt(ISK);
+ FD->InitStorage.setPointer(ISK == FieldDecl::ISK_CapturedVLAType
+ ? Record.readType().getAsOpaquePtr()
+ : Record.readExpr());
}
+
+ if (auto *BW = Record.readExpr())
+ FD->setBitWidth(BW);
+
if (!FD->getDeclName()) {
if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>())
Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
@@ -1293,6 +1294,9 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
}
}
+ if (VD->getStorageDuration() == SD_Static && Record.readInt())
+ Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile;
+
enum VarKind {
VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
};
@@ -1587,11 +1591,8 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.ODRHash = Record.readInt();
Data.HasODRHash = true;
- if (Record.readInt()) {
- Reader.BodySource[D] = Loc.F->Kind == ModuleKind::MK_MainFile
- ? ExternalASTSource::EK_Never
- : ExternalASTSource::EK_Always;
- }
+ if (Record.readInt())
+ Reader.DefinitionSource[D] = Loc.F->Kind == ModuleKind::MK_MainFile;
Data.NumBases = Record.readInt();
if (Data.NumBases)
@@ -1754,7 +1755,8 @@ void ASTDeclReader::MergeDefinitionData(
}
if (DetectedOdrViolation)
- Reader.PendingOdrMergeFailures[DD.Definition].push_back(MergeDD.Definition);
+ Reader.PendingOdrMergeFailures[DD.Definition].push_back(
+ {MergeDD.Definition, &MergeDD});
}
void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update) {
@@ -1861,6 +1863,7 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
VisitFunctionDecl(D);
+ D->IsCopyDeductionCandidate = Record.readInt();
}
void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
@@ -1899,9 +1902,12 @@ void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
if (auto *OperatorDelete = ReadDeclAs<FunctionDecl>()) {
auto *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl());
+ auto *ThisArg = Record.readExpr();
// FIXME: Check consistency if we have an old and new operator delete.
- if (!Canon->OperatorDelete)
+ if (!Canon->OperatorDelete) {
Canon->OperatorDelete = OperatorDelete;
+ Canon->OperatorDeleteThisArg = ThisArg;
+ }
}
}
@@ -2192,6 +2198,7 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
D->PointOfInstantiation = ReadSourceLocation();
D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
+ D->IsCompleteDefinition = Record.readInt();
bool writtenAsCanonicalDecl = Record.readInt();
if (writtenAsCanonicalDecl) {
@@ -2514,7 +2521,9 @@ void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
VisitValueDecl(D);
D->setLocation(ReadSourceLocation());
D->setCombiner(Record.readExpr());
- D->setInitializer(Record.readExpr());
+ D->setInitializer(
+ Record.readExpr(),
+ static_cast<OMPDeclareReductionDecl::InitKind>(Record.readInt()));
D->PrevDeclInScope = ReadDeclID();
}
@@ -2567,11 +2576,14 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
// An ObjCMethodDecl is never considered as "interesting" because its
// implementation container always is.
- // An ImportDecl or VarDecl imported from a module will get emitted when
- // we import the relevant module.
- if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && D->getImportedOwningModule() &&
- Ctx.DeclMustBeEmitted(D))
- return false;
+ // An ImportDecl or VarDecl imported from a module map module will get
+ // emitted when we import the relevant module.
+ if (isa<ImportDecl>(D) || isa<VarDecl>(D)) {
+ auto *M = D->getImportedOwningModule();
+ if (M && M->Kind == Module::ModuleMapModule &&
+ Ctx.DeclMustBeEmitted(D))
+ return false;
+ }
if (isa<FileScopeAsmDecl>(D) ||
isa<ObjCProtocolDecl>(D) ||
@@ -2810,7 +2822,7 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
// FIXME: Do we need to check for C++14 deduced return types here too?
auto *XFPT = FuncX->getType()->getAs<FunctionProtoType>();
auto *YFPT = FuncY->getType()->getAs<FunctionProtoType>();
- if (C.getLangOpts().CPlusPlus1z && XFPT && YFPT &&
+ if (C.getLangOpts().CPlusPlus17 && XFPT && YFPT &&
(isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) ||
isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) &&
C.hasSameFunctionTypeIgnoringExceptionSpec(FuncX->getType(),
@@ -3972,10 +3984,10 @@ void ASTDeclReader::UpdateDecl(Decl *D,
break;
}
- case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER: {
+ case UPD_CXX_ADDED_VAR_DEFINITION: {
VarDecl *VD = cast<VarDecl>(D);
- VD->getMemberSpecializationInfo()->setPointOfInstantiation(
- ReadSourceLocation());
+ VD->NonParmVarDeclBits.IsInline = Record.readInt();
+ VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt();
uint64_t Val = Record.readInt();
if (Val && !VD->getInit()) {
VD->setInit(Record.readExpr());
@@ -3988,6 +4000,25 @@ void ASTDeclReader::UpdateDecl(Decl *D,
break;
}
+ case UPD_CXX_POINT_OF_INSTANTIATION: {
+ SourceLocation POI = Record.readSourceLocation();
+ if (VarTemplateSpecializationDecl *VTSD =
+ dyn_cast<VarTemplateSpecializationDecl>(D)) {
+ VTSD->setPointOfInstantiation(POI);
+ } else if (auto *VD = dyn_cast<VarDecl>(D)) {
+ VD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
+ } else {
+ auto *FD = cast<FunctionDecl>(D);
+ if (auto *FTSInfo = FD->TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo *>())
+ FTSInfo->setPointOfInstantiation(POI);
+ else
+ FD->TemplateOrSpecialization.get<MemberSpecializationInfo *>()
+ ->setPointOfInstantiation(POI);
+ }
+ break;
+ }
+
case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT: {
auto Param = cast<ParmVarDecl>(D);
@@ -4106,9 +4137,12 @@ void ASTDeclReader::UpdateDecl(Decl *D,
// record.
auto *Del = ReadDeclAs<FunctionDecl>();
auto *First = cast<CXXDestructorDecl>(D->getCanonicalDecl());
+ auto *ThisArg = Record.readExpr();
// FIXME: Check consistency if we have an old and new operator delete.
- if (!First->OperatorDelete)
+ if (!First->OperatorDelete) {
First->OperatorDelete = Del;
+ First->OperatorDeleteThisArg = ThisArg;
+ }
break;
}
diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h
index 6cb4d662e338..2b92ae65ea84 100644
--- a/lib/Serialization/ASTReaderInternals.h
+++ b/lib/Serialization/ASTReaderInternals.h
@@ -1,4 +1,4 @@
-//===--- ASTReaderInternals.h - AST Reader Internals ------------*- C++ -*-===//
+//===- ASTReaderInternals.h - AST Reader Internals --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,23 +10,29 @@
// This file provides internal definitions used in the AST reader.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
#define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
#include "MultiOnDiskHashTable.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/Support/Endian.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/OnDiskHashTable.h"
+#include <ctime>
#include <utility>
namespace clang {
class ASTReader;
-class HeaderSearch;
-struct HeaderFileInfo;
class FileEntry;
+struct HeaderFileInfo;
+class HeaderSearch;
+class IdentifierTable;
+class ObjCMethodDecl;
namespace serialization {
@@ -45,12 +51,14 @@ public:
static const int MaxTables = 4;
/// The lookup result is a list of global declaration IDs.
- typedef llvm::SmallVector<DeclID, 4> data_type;
+ using data_type = SmallVector<DeclID, 4>;
+
struct data_type_builder {
data_type &Data;
llvm::DenseSet<DeclID> Found;
data_type_builder(data_type &D) : Data(D) {}
+
void insert(DeclID ID) {
// Just use a linear scan unless we have more than a few IDs.
if (Found.empty() && !Data.empty()) {
@@ -70,15 +78,15 @@ public:
Data.push_back(ID);
}
};
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
- typedef ModuleFile *file_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
+ using file_type = ModuleFile *;
- typedef DeclarationName external_key_type;
- typedef DeclarationNameKey internal_key_type;
+ using external_key_type = DeclarationName;
+ using internal_key_type = DeclarationNameKey;
explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
- : Reader(Reader), F(F) { }
+ : Reader(Reader), F(F) {}
static bool EqualKey(const internal_key_type &a, const internal_key_type &b) {
return a == b;
@@ -87,6 +95,7 @@ public:
static hash_value_type ComputeHash(const internal_key_type &Key) {
return Key.getHash();
}
+
static internal_key_type GetInternalKey(const external_key_type &Name) {
return Name;
}
@@ -119,14 +128,13 @@ struct DeclContextLookupTable {
/// functionality for accessing the on-disk hash table of identifiers
/// in an AST file. Different subclasses customize that functionality
/// based on what information they are interested in. Those subclasses
-/// must provide the \c data_type typedef and the ReadData operation,
-/// only.
+/// must provide the \c data_type type and the ReadData operation, only.
class ASTIdentifierLookupTraitBase {
public:
- typedef StringRef external_key_type;
- typedef StringRef internal_key_type;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using external_key_type = StringRef;
+ using internal_key_type = StringRef;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
return a == b;
@@ -159,11 +167,11 @@ class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
IdentifierInfo *KnownII;
public:
- typedef IdentifierInfo * data_type;
+ using data_type = IdentifierInfo *;
ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
IdentifierInfo *II = nullptr)
- : Reader(Reader), F(F), KnownII(II) { }
+ : Reader(Reader), F(F), KnownII(II) {}
data_type ReadData(const internal_key_type& k,
const unsigned char* d,
@@ -176,8 +184,8 @@ public:
/// \brief The on-disk hash table used to contain information about
/// all of the identifiers in the program.
-typedef llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>
- ASTIdentifierLookupTable;
+using ASTIdentifierLookupTable =
+ llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>;
/// \brief Class that performs lookup for a selector's entries in the global
/// method pool stored in an AST file.
@@ -196,13 +204,13 @@ public:
SmallVector<ObjCMethodDecl *, 2> Factory;
};
- typedef Selector external_key_type;
- typedef external_key_type internal_key_type;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using external_key_type = Selector;
+ using internal_key_type = external_key_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
- ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
- : Reader(Reader), F(F) { }
+ ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
+ : Reader(Reader), F(F) {}
static bool EqualKey(const internal_key_type& a,
const internal_key_type& b) {
@@ -222,8 +230,8 @@ public:
};
/// \brief The on-disk hash table used for the global method pool.
-typedef llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>
- ASTSelectorLookupTable;
+using ASTSelectorLookupTable =
+ llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>;
/// \brief Trait class used to search the on-disk hash table containing all of
/// the header search information.
@@ -241,7 +249,7 @@ class HeaderFileInfoTrait {
const char *FrameworkStrings;
public:
- typedef const FileEntry *external_key_type;
+ using external_key_type = const FileEntry *;
struct internal_key_type {
off_t Size;
@@ -249,15 +257,16 @@ public:
StringRef Filename;
bool Imported;
};
- typedef const internal_key_type &internal_key_ref;
+
+ using internal_key_ref = const internal_key_type &;
- typedef HeaderFileInfo data_type;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using data_type = HeaderFileInfo;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
const char *FrameworkStrings)
- : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) { }
+ : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {}
static hash_value_type ComputeHash(internal_key_ref ikey);
internal_key_type GetInternalKey(const FileEntry *FE);
@@ -272,12 +281,13 @@ public:
};
/// \brief The on-disk hash table used for known header files.
-typedef llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>
- HeaderFileInfoLookupTable;
+using HeaderFileInfoLookupTable =
+ llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>;
-} // end namespace clang::serialization::reader
-} // end namespace clang::serialization
-} // end namespace clang
+} // namespace reader
+
+} // namespace serialization
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 3f5da029947c..8ef1491eb2da 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1854,6 +1854,9 @@ OMPClause *OMPClauseReader::readClause() {
case OMPC_task_reduction:
C = OMPTaskReductionClause::CreateEmpty(Context, Reader->Record.readInt());
break;
+ case OMPC_in_reduction:
+ C = OMPInReductionClause::CreateEmpty(Context, Reader->Record.readInt());
+ break;
case OMPC_linear:
C = OMPLinearClause::CreateEmpty(Context, Reader->Record.readInt());
break;
@@ -2192,6 +2195,44 @@ void OMPClauseReader::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
C->setReductionOps(Vars);
}
+void OMPClauseReader::VisitOMPInReductionClause(OMPInReductionClause *C) {
+ VisitOMPClauseWithPostUpdate(C);
+ C->setLParenLoc(Reader->ReadSourceLocation());
+ C->setColonLoc(Reader->ReadSourceLocation());
+ NestedNameSpecifierLoc NNSL = Reader->Record.readNestedNameSpecifierLoc();
+ DeclarationNameInfo DNI;
+ Reader->ReadDeclarationNameInfo(DNI);
+ C->setQualifierLoc(NNSL);
+ C->setNameInfo(DNI);
+
+ unsigned NumVars = C->varlist_size();
+ SmallVector<Expr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setVarRefs(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setPrivates(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setLHSExprs(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setRHSExprs(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setReductionOps(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setTaskgroupDescriptors(Vars);
+}
+
void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) {
VisitOMPClauseWithPostUpdate(C);
C->setLParenLoc(Reader->ReadSourceLocation());
@@ -2306,6 +2347,7 @@ void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) {
}
void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) {
+ VisitOMPClauseWithPreInit(C);
C->setDevice(Reader->Record.readSubExpr());
C->setLParenLoc(Reader->ReadSourceLocation());
}
@@ -2766,6 +2808,7 @@ void ASTStmtReader::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
// The NumClauses field was read in ReadStmtFromStream.
Record.skipInts(1);
VisitOMPExecutableDirective(D);
+ D->setReductionRef(Record.readSubExpr());
}
void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
@@ -2877,6 +2920,7 @@ void ASTStmtReader::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
void ASTStmtReader::VisitOMPDistributeParallelForDirective(
OMPDistributeParallelForDirective *D) {
VisitOMPLoopDirective(D);
+ D->setHasCancel(Record.readInt());
}
void ASTStmtReader::VisitOMPDistributeParallelForSimdDirective(
@@ -2916,6 +2960,7 @@ void ASTStmtReader::VisitOMPTeamsDistributeParallelForSimdDirective(
void ASTStmtReader::VisitOMPTeamsDistributeParallelForDirective(
OMPTeamsDistributeParallelForDirective *D) {
VisitOMPLoopDirective(D);
+ D->setHasCancel(Record.readInt());
}
void ASTStmtReader::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
@@ -2933,6 +2978,7 @@ void ASTStmtReader::VisitOMPTargetTeamsDistributeDirective(
void ASTStmtReader::VisitOMPTargetTeamsDistributeParallelForDirective(
OMPTargetTeamsDistributeParallelForDirective *D) {
VisitOMPLoopDirective(D);
+ D->setHasCancel(Record.readInt());
}
void ASTStmtReader::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 128e53b91b1d..1e72ced2ee36 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1,4 +1,4 @@
-//===--- ASTWriter.cpp - AST File Writer ------------------------*- C++ -*-===//
+//===- ASTWriter.cpp - AST File Writer ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,11 +17,15 @@
#include "MultiOnDiskHashTable.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/LambdaCapture.h"
@@ -30,16 +34,22 @@
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Lambda.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/OpenCLOptions.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/Version.h"
@@ -62,24 +72,30 @@
#include "clang/Serialization/SerializationDiagnostic.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitCodes.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/OnDiskHashTable.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
#include "llvm/Support/SHA1.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -87,11 +103,14 @@
#include <cstdint>
#include <cstdlib>
#include <cstring>
+#include <ctime>
#include <deque>
#include <limits>
-#include <new>
+#include <memory>
+#include <queue>
#include <tuple>
#include <utility>
+#include <vector>
using namespace clang;
using namespace clang::serialization;
@@ -120,13 +139,14 @@ namespace clang {
ASTRecordWriter Record;
/// \brief Type code that corresponds to the record generated.
- TypeCode Code;
+ TypeCode Code = static_cast<TypeCode>(0);
+
/// \brief Abbreviation to use for the record, if any.
- unsigned AbbrevToUse;
+ unsigned AbbrevToUse = 0;
public:
ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
- : Writer(Writer), Record(Writer, Record), Code((TypeCode)0), AbbrevToUse(0) { }
+ : Writer(Writer), Record(Writer, Record) {}
uint64_t Emit() {
return Record.Emit(Code, AbbrevToUse);
@@ -160,7 +180,7 @@ namespace clang {
#include "clang/AST/TypeNodes.def"
};
-} // end namespace clang
+} // namespace clang
void ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) {
llvm_unreachable("Built-in types are never serialized");
@@ -433,6 +453,15 @@ ASTTypeWriter::VisitDependentSizedExtVectorType(
Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR;
}
+void
+ASTTypeWriter::VisitDependentAddressSpaceType(
+ const DependentAddressSpaceType *T) {
+ Record.AddTypeRef(T->getPointeeType());
+ Record.AddStmt(T->getAddrSpaceExpr());
+ Record.AddSourceLocation(T->getAttributeLoc());
+ Code = TYPE_DEPENDENT_ADDRESS_SPACE;
+}
+
void
ASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
Record.push_back(T->getDepth());
@@ -541,8 +570,7 @@ class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
ASTRecordWriter &Record;
public:
- TypeLocWriter(ASTRecordWriter &Record)
- : Record(Record) { }
+ TypeLocWriter(ASTRecordWriter &Record) : Record(Record) {}
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
@@ -553,7 +581,7 @@ public:
void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
};
-} // end anonymous namespace
+} // namespace
void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
// nothing to do
@@ -627,6 +655,15 @@ void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
VisitArrayTypeLoc(TL);
}
+void TypeLocWriter::VisitDependentAddressSpaceTypeLoc(
+ DependentAddressSpaceTypeLoc TL) {
+ Record.AddSourceLocation(TL.getAttrNameLoc());
+ SourceRange range = TL.getAttrOperandParensRange();
+ Record.AddSourceLocation(range.getBegin());
+ Record.AddSourceLocation(range.getEnd());
+ Record.AddStmt(TL.getAttrExprOperand());
+}
+
void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
DependentSizedExtVectorTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
@@ -649,18 +686,23 @@ void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i)
Record.AddDeclRef(TL.getParam(i));
}
+
void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
VisitFunctionTypeLoc(TL);
}
+
void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
VisitFunctionTypeLoc(TL);
}
+
void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
+
void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
+
void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
if (TL.getNumProtocols()) {
Record.AddSourceLocation(TL.getProtocolLAngleLoc());
@@ -669,6 +711,7 @@ void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
Record.AddSourceLocation(TL.getProtocolLoc(i));
}
+
void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
Record.AddSourceLocation(TL.getTypeofLoc());
Record.AddSourceLocation(TL.getLParenLoc());
@@ -1130,6 +1173,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(SUBMODULE_TEXTUAL_HEADER);
RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
RECORD(SUBMODULE_INITIALIZERS);
+ RECORD(SUBMODULE_EXPORT_AS);
// Comments Block.
BLOCK(COMMENTS_BLOCK);
@@ -1397,6 +1441,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot,
const std::string &OutputFile) {
using namespace llvm;
+
Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
RecordData Record;
@@ -1505,6 +1550,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
for (auto I : M.Signature)
Record.push_back(I);
+ AddString(M.ModuleName, Record);
AddPath(M.FileName, Record);
}
Stream.EmitRecord(IMPORTS, Record);
@@ -1686,21 +1732,22 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
namespace {
- /// \brief An input file.
- struct InputFileEntry {
- const FileEntry *File;
- bool IsSystemFile;
- bool IsTransient;
- bool BufferOverridden;
- bool IsTopLevelModuleMap;
- };
+/// \brief An input file.
+struct InputFileEntry {
+ const FileEntry *File;
+ bool IsSystemFile;
+ bool IsTransient;
+ bool BufferOverridden;
+ bool IsTopLevelModuleMap;
+};
-} // end anonymous namespace
+} // namespace
void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
HeaderSearchOptions &HSOpts,
bool Modules) {
using namespace llvm;
+
Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4);
// Create input-file abbreviation.
@@ -1877,7 +1924,7 @@ namespace {
off_t Size;
time_t ModTime;
};
- typedef const key_type &key_type_ref;
+ using key_type_ref = const key_type &;
using UnresolvedModule =
llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>;
@@ -1887,10 +1934,10 @@ namespace {
ArrayRef<ModuleMap::KnownHeader> KnownHeaders;
UnresolvedModule Unresolved;
};
- typedef const data_type &data_type_ref;
+ using data_type_ref = const data_type &;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
hash_value_type ComputeHash(key_type_ref key) {
// The hash is based only on size/time of the file, so that the reader can
@@ -1899,9 +1946,10 @@ namespace {
return llvm::hash_combine(key.Size, key.ModTime);
}
- std::pair<unsigned,unsigned>
+ std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
LE.write<uint16_t>(KeyLen);
@@ -1917,6 +1965,7 @@ namespace {
void EmitKey(raw_ostream& Out, key_type_ref key, unsigned KeyLen) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
LE.write<uint64_t>(key.Size);
KeyLen -= 8;
@@ -1928,6 +1977,7 @@ namespace {
void EmitData(raw_ostream &Out, key_type_ref key,
data_type_ref Data, unsigned DataLen) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell(); (void)Start;
@@ -1982,7 +2032,7 @@ namespace {
const char *strings_end() const { return FrameworkStringData.end(); }
};
-} // end anonymous namespace
+} // namespace
/// \brief Write the header search block for the list of files that
///
@@ -2095,6 +2145,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
uint32_t BucketOffset;
{
using namespace llvm::support;
+
llvm::raw_svector_ostream Out(TableData);
// Make sure that no bucket is at offset 0
endian::Writer<little>(Out).write<uint32_t>(0);
@@ -2126,7 +2177,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
unsigned SLocBufferBlobCompressedAbbrv,
unsigned SLocBufferBlobAbbrv) {
- typedef ASTWriter::RecordData::value_type RecordDataType;
+ using RecordDataType = ASTWriter::RecordData::value_type;
// Compress the buffer if possible. We expect that almost all PCM
// consumers will not want its contents.
@@ -2312,12 +2363,13 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// Emit the needed file names.
llvm::DenseMap<int, int> FilenameMap;
+ FilenameMap[-1] = -1; // For unspecified filenames.
for (const auto &L : LineTable) {
if (L.first.ID < 0)
continue;
for (auto &LE : L.second) {
if (FilenameMap.insert(std::make_pair(LE.FilenameID,
- FilenameMap.size())).second)
+ FilenameMap.size() - 1)).second)
AddPath(LineTable.getFilename(LE.FilenameID), Record);
}
}
@@ -2370,7 +2422,6 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
/// \brief Writes the block containing the serialized form of the
/// preprocessor.
-///
void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
if (PPRec)
@@ -2387,6 +2438,17 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) {
assert(!IsModule);
+ auto SkipInfo = PP.getPreambleSkipInfo();
+ if (SkipInfo.hasValue()) {
+ Record.push_back(true);
+ AddSourceLocation(SkipInfo->HashTokenLoc, Record);
+ AddSourceLocation(SkipInfo->IfTokenLoc, Record);
+ Record.push_back(SkipInfo->FoundNonSkipPortion);
+ Record.push_back(SkipInfo->FoundElse);
+ AddSourceLocation(SkipInfo->ElseLoc, Record);
+ } else {
+ Record.push_back(false);
+ }
for (const auto &Cond : PP.getPreambleConditionalStack()) {
AddSourceLocation(Cond.IfLoc, Record);
Record.push_back(Cond.WasSkipping);
@@ -2715,6 +2777,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Kind
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
@@ -2789,11 +2852,15 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Message
unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
+ Abbrev = std::make_shared<BitCodeAbbrev>();
+ Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXPORT_AS));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name
+ unsigned ExportAsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
+
// Write the submodule metadata block.
RecordData::value_type Record[] = {
getNumberOfModules(WritingModule),
- FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS,
- (unsigned)WritingModule->Kind};
+ FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS};
Stream.EmitRecord(SUBMODULE_METADATA, Record);
// Write all of the submodules.
@@ -2815,6 +2882,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
RecordData::value_type Record[] = {SUBMODULE_DEFINITION,
ID,
ParentID,
+ (RecordData::value_type)Mod->Kind,
Mod->IsFramework,
Mod->IsExplicit,
Mod->IsSystem,
@@ -2923,6 +2991,12 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
if (!Inits.empty())
Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
+ // Emit the name of the re-exported module, if any.
+ if (!Mod->ExportAsModule.empty()) {
+ RecordData::value_type Record[] = {SUBMODULE_EXPORT_AS};
+ Stream.EmitRecordWithBlob(ExportAsAbbrev, Record, Mod->ExportAsModule);
+ }
+
// Queue up the submodules of this module.
for (auto *M : Mod->submodules())
Q.push(M);
@@ -3164,28 +3238,29 @@ class ASTMethodPoolTrait {
ASTWriter &Writer;
public:
- typedef Selector key_type;
- typedef key_type key_type_ref;
+ using key_type = Selector;
+ using key_type_ref = key_type;
struct data_type {
SelectorID ID;
ObjCMethodList Instance, Factory;
};
- typedef const data_type& data_type_ref;
+ using data_type_ref = const data_type &;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
- explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { }
+ explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) {}
static hash_value_type ComputeHash(Selector Sel) {
return serialization::ComputeHash(Sel);
}
- std::pair<unsigned,unsigned>
+ std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, Selector Sel,
data_type_ref Methods) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
LE.write<uint16_t>(KeyLen);
@@ -3204,6 +3279,7 @@ public:
void EmitKey(raw_ostream& Out, Selector Sel, unsigned) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell();
assert((Start >> 32) == 0 && "Selector key offset too large");
@@ -3220,6 +3296,7 @@ public:
void EmitData(raw_ostream& Out, key_type_ref,
data_type_ref Methods, unsigned DataLen) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell(); (void)Start;
LE.write<uint32_t>(Methods.ID);
@@ -3264,7 +3341,7 @@ public:
}
};
-} // end anonymous namespace
+} // namespace
/// \brief Write ObjC data: selectors and the method pool.
///
@@ -3328,6 +3405,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
uint32_t BucketOffset;
{
using namespace llvm::support;
+
ASTMethodPoolTrait Trait(*this);
llvm::raw_svector_ostream Out(MethodPool);
// Make sure that no bucket is at offset 0
@@ -3372,6 +3450,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
/// \brief Write the selectors referenced in @selector expression into AST file.
void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {
using namespace llvm;
+
if (SemaRef.ReferencedSelectors.empty())
return;
@@ -3460,14 +3539,14 @@ class ASTIdentifierTableTrait {
}
public:
- typedef IdentifierInfo* key_type;
- typedef key_type key_type_ref;
+ using key_type = IdentifierInfo *;
+ using key_type_ref = key_type;
- typedef IdentID data_type;
- typedef data_type data_type_ref;
+ using data_type = IdentID;
+ using data_type_ref = data_type;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP,
IdentifierResolver &IdResolver, bool IsModule,
@@ -3491,7 +3570,7 @@ public:
return isInterestingIdentifier(II, 0);
}
- std::pair<unsigned,unsigned>
+ std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
unsigned KeyLen = II->getLength() + 1;
unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
@@ -3509,7 +3588,9 @@ public:
DataLen += 4;
}
}
+
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
assert((uint16_t)DataLen == DataLen && (uint16_t)KeyLen == KeyLen);
@@ -3538,6 +3619,7 @@ public:
void EmitData(raw_ostream& Out, IdentifierInfo* II,
IdentID ID, unsigned) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
auto MacroOffset = Writer.getMacroDirectivesOffset(II);
@@ -3581,7 +3663,7 @@ public:
}
};
-} // end anonymous namespace
+} // namespace
/// \brief Write the identifier table into the AST file.
///
@@ -3639,6 +3721,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,
uint32_t BucketOffset;
{
using namespace llvm::support;
+
llvm::raw_svector_ostream Out(IdentifierTable);
// Make sure that no bucket is at offset 0
endian::Writer<little>(Out).write<uint32_t>(0);
@@ -3694,17 +3777,17 @@ class ASTDeclContextNameLookupTrait {
llvm::SmallVector<DeclID, 64> DeclIDs;
public:
- typedef DeclarationNameKey key_type;
- typedef key_type key_type_ref;
+ using key_type = DeclarationNameKey;
+ using key_type_ref = key_type;
/// A start and end index into DeclIDs, representing a sequence of decls.
- typedef std::pair<unsigned, unsigned> data_type;
- typedef const data_type& data_type_ref;
+ using data_type = std::pair<unsigned, unsigned>;
+ using data_type_ref = const data_type &;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
- explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { }
+ explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) {}
template<typename Coll>
data_type getData(const Coll &Decls) {
@@ -3736,6 +3819,7 @@ public:
"have reference to loaded module file but no chain?");
using namespace llvm::support;
+
endian::Writer<little>(Out)
.write<uint32_t>(Writer.getChain()->getModuleFileID(F));
}
@@ -3744,6 +3828,7 @@ public:
DeclarationNameKey Name,
data_type_ref Lookup) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
unsigned KeyLen = 1;
switch (Name.getKind()) {
@@ -3777,6 +3862,7 @@ public:
void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
LE.write<uint8_t>(Name.getKind());
switch (Name.getKind()) {
@@ -3808,6 +3894,7 @@ public:
void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
unsigned DataLen) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell(); (void)Start;
for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
@@ -3816,7 +3903,7 @@ public:
}
};
-} // end anonymous namespace
+} // namespace
bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
@@ -4295,6 +4382,7 @@ void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) {
for (const auto &StackEntry : SemaRef.PackStack.Stack) {
Record.push_back(StackEntry.Value);
AddSourceLocation(StackEntry.PragmaLocation, Record);
+ AddSourceLocation(StackEntry.PragmaPushLocation, Record);
AddString(StackEntry.StackSlotLabel, Record);
}
Stream.EmitRecord(PACK_PRAGMA_OPTIONS, Record);
@@ -4348,7 +4436,6 @@ void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) {
Record.AddSourceRange(A->getRange());
#include "clang/Serialization/AttrPCHWrite.inc"
-
}
}
@@ -4778,7 +4865,8 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
// each of those modules were mapped into our own offset/ID space, so that
// the reader can build the appropriate mapping to its own offset/ID space.
// The map consists solely of a blob with the following format:
- // *(module-name-len:i16 module-name:len*i8
+ // *(module-kind:i8
+ // module-name-len:i16 module-name:len*i8
// source-location-offset:i32
// identifier-id:i32
// preprocessed-entity-id:i32
@@ -4789,6 +4877,9 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
// c++-base-specifiers-id:i32
// type-id:i32)
//
+ // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule or
+ // MK_ExplicitModule, then the module-name is the module name. Otherwise,
+ // it is the module file name.
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
@@ -4798,10 +4889,15 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
llvm::raw_svector_ostream Out(Buffer);
for (ModuleFile &M : Chain->ModuleMgr) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
- StringRef FileName = M.FileName;
- LE.write<uint16_t>(FileName.size());
- Out.write(FileName.data(), FileName.size());
+ LE.write<uint8_t>(static_cast<uint8_t>(M.Kind));
+ StringRef Name =
+ M.Kind == MK_PrebuiltModule || M.Kind == MK_ExplicitModule
+ ? M.ModuleName
+ : M.FileName;
+ LE.write<uint16_t>(Name.size());
+ Out.write(Name.data(), Name.size());
// Note: if a base ID was uint max, it would not be possible to load
// another module after it or have more than one entity inside it.
@@ -5039,9 +5135,15 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
case UPD_CXX_ADDED_FUNCTION_DEFINITION:
break;
- case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER: {
- const VarDecl *VD = cast<VarDecl>(D);
+ case UPD_CXX_POINT_OF_INSTANTIATION:
+ // FIXME: Do we need to also save the template specialization kind here?
Record.AddSourceLocation(Update.getLoc());
+ break;
+
+ case UPD_CXX_ADDED_VAR_DEFINITION: {
+ const VarDecl *VD = cast<VarDecl>(D);
+ Record.push_back(VD->isInline());
+ Record.push_back(VD->isInlineSpecified());
if (VD->getInit()) {
Record.push_back(!VD->isInitKnownICE() ? 1
: (VD->isInitICE() ? 3 : 2));
@@ -5109,6 +5211,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
case UPD_CXX_RESOLVED_DTOR_DELETE:
Record.AddDeclRef(Update.getDecl());
+ Record.AddStmt(cast<CXXDestructorDecl>(D)->getOperatorDeleteThisArg());
break;
case UPD_CXX_RESOLVED_EXCEPTION_SPEC:
@@ -6136,7 +6239,8 @@ void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
}
void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
- const FunctionDecl *Delete) {
+ const FunctionDecl *Delete,
+ Expr *ThisArg) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
assert(Delete && "Not given an operator delete");
@@ -6156,6 +6260,15 @@ void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
}
+void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
+ assert(!WritingAST && "Already writing the AST!");
+ if (!D->isFromASTFile())
+ return;
+
+ DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_VAR_DEFINITION));
+}
+
void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
@@ -6165,7 +6278,7 @@ void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
}
-void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
+void ASTWriter::InstantiationRequested(const ValueDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
@@ -6173,9 +6286,12 @@ void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
// Since the actual instantiation is delayed, this really means that we need
// to update the instantiation location.
- DeclUpdates[D].push_back(
- DeclUpdate(UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
- D->getMemberSpecializationInfo()->getPointOfInstantiation()));
+ SourceLocation POI;
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ POI = VD->getPointOfInstantiation();
+ else
+ POI = cast<FunctionDecl>(D)->getPointOfInstantiation();
+ DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_POINT_OF_INSTANTIATION, POI));
}
void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index ec21ca2276c1..3dac3a48297a 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -612,6 +612,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
VisitFunctionDecl(D);
+ Record.push_back(D->IsCopyDeductionCandidate);
Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
}
@@ -849,17 +850,16 @@ void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
VisitDeclaratorDecl(D);
Record.push_back(D->isMutable());
- if (D->InitStorage.getInt() == FieldDecl::ISK_BitWidthOrNothing &&
- D->InitStorage.getPointer() == nullptr) {
- Record.push_back(0);
- } else if (D->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) {
- Record.push_back(D->InitStorage.getInt() + 1);
- Record.AddTypeRef(
- QualType(static_cast<Type *>(D->InitStorage.getPointer()), 0));
- } else {
- Record.push_back(D->InitStorage.getInt() + 1);
- Record.AddStmt(static_cast<Expr *>(D->InitStorage.getPointer()));
- }
+
+ FieldDecl::InitStorageKind ISK = D->InitStorage.getInt();
+ Record.push_back(ISK);
+ if (ISK == FieldDecl::ISK_CapturedVLAType)
+ Record.AddTypeRef(QualType(D->getCapturedVLAType(), 0));
+ else if (ISK)
+ Record.AddStmt(D->getInClassInitializer());
+
+ Record.AddStmt(D->getBitWidth());
+
if (!D->getDeclName())
Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
@@ -873,6 +873,7 @@ void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
!D->isModulePrivate() &&
!D->getBitWidth() &&
!D->hasInClassInitializer() &&
+ !D->hasCapturedVLAType() &&
!D->hasExtInfo() &&
!ObjCIvarDecl::classofKind(D->getKind()) &&
!ObjCAtDefsFieldDecl::classofKind(D->getKind()) &&
@@ -928,6 +929,24 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
} else {
Record.push_back(0);
}
+
+ if (D->getStorageDuration() == SD_Static) {
+ bool ModulesCodegen = false;
+ if (Writer.WritingModule &&
+ !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
+ !isa<VarTemplateSpecializationDecl>(D)) {
+ // When building a C++ Modules TS module interface unit, a strong
+ // definition in the module interface is provided by the compilation of
+ // that module interface unit, not by its users. (Inline variables are
+ // still emitted in module users.)
+ ModulesCodegen =
+ (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit &&
+ Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal);
+ }
+ Record.push_back(ModulesCodegen);
+ if (ModulesCodegen)
+ Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D));
+ }
enum {
VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
@@ -963,6 +982,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
!D->isConstexpr() &&
!D->isInitCapture() &&
!D->isPreviousDeclInSameBlockScope() &&
+ D->getStorageDuration() != SD_Static &&
!D->getMemberSpecializationInfo())
AbbrevToUse = Writer.getDeclVarAbbrev();
@@ -1247,10 +1267,8 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
VisitFunctionDecl(D);
if (D->isCanonicalDecl()) {
Record.push_back(D->size_overridden_methods());
- for (CXXMethodDecl::method_iterator
- I = D->begin_overridden_methods(), E = D->end_overridden_methods();
- I != E; ++I)
- Record.AddDeclRef(*I);
+ for (const CXXMethodDecl *MD : D->overridden_methods())
+ Record.AddDeclRef(MD);
} else {
// We only need to record overridden methods once for the canonical decl.
Record.push_back(0);
@@ -1290,6 +1308,8 @@ void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
VisitCXXMethodDecl(D);
Record.AddDeclRef(D->getOperatorDelete());
+ if (D->getOperatorDelete())
+ Record.AddStmt(D->getOperatorDeleteThisArg());
Code = serialization::DECL_CXX_DESTRUCTOR;
}
@@ -1472,6 +1492,7 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
Record.AddTemplateArgumentList(&D->getTemplateArgs());
Record.AddSourceLocation(D->getPointOfInstantiation());
Record.push_back(D->getSpecializationKind());
+ Record.push_back(D->IsCompleteDefinition);
Record.push_back(D->isCanonicalDecl());
if (D->isCanonicalDecl()) {
@@ -1697,6 +1718,7 @@ void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
Record.AddSourceLocation(D->getLocStart());
Record.AddStmt(D->getCombiner());
Record.AddStmt(D->getInitializer());
+ Record.push_back(D->getInitializerKind());
Record.AddDeclRef(D->getPrevDeclInScope());
Code = serialization::DECL_OMP_DECLARE_REDUCTION;
}
@@ -1741,7 +1763,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
// FieldDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
- Abv->Add(BitCodeAbbrevOp(0)); //getBitWidth
+ Abv->Add(BitCodeAbbrevOp(0)); // InitStyle
// Type Source Info
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
@@ -1774,7 +1796,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
// FieldDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
- Abv->Add(BitCodeAbbrevOp(0)); //getBitWidth
+ Abv->Add(BitCodeAbbrevOp(0)); // InitStyle
// ObjC Ivar
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
@@ -2235,15 +2257,24 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
assert(FD->doesThisDeclarationHaveABody());
bool ModulesCodegen = false;
if (Writer->WritingModule && !FD->isDependentContext()) {
- // Under -fmodules-codegen, codegen is performed for all defined functions.
- // When building a C++ Modules TS module interface unit, a strong definition
- // in the module interface is provided by the compilation of that module
- // interface unit, not by its users. (Inline functions are still emitted
- // in module users.)
- ModulesCodegen =
- Writer->Context->getLangOpts().ModulesCodegen ||
- (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit &&
- Writer->Context->GetGVALinkageForFunction(FD) == GVA_StrongExternal);
+ Optional<GVALinkage> Linkage;
+ if (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) {
+ // When building a C++ Modules TS module interface unit, a strong
+ // definition in the module interface is provided by the compilation of
+ // that module interface unit, not by its users. (Inline functions are
+ // still emitted in module users.)
+ Linkage = Writer->Context->GetGVALinkageForFunction(FD);
+ ModulesCodegen = *Linkage == GVA_StrongExternal;
+ }
+ if (Writer->Context->getLangOpts().ModulesCodegen) {
+ // Under -fmodules-codegen, codegen is performed for all non-internal,
+ // non-always_inline functions.
+ if (!FD->hasAttr<AlwaysInlineAttr>()) {
+ if (!Linkage)
+ Linkage = Writer->Context->GetGVALinkageForFunction(FD);
+ ModulesCodegen = *Linkage != GVA_Internal;
+ }
+ }
}
Record->push_back(ModulesCodegen);
if (ModulesCodegen)
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 6971339663f0..c5f4495d2f01 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -2001,6 +2001,27 @@ void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
Record.AddStmt(E);
}
+void OMPClauseWriter::VisitOMPInReductionClause(OMPInReductionClause *C) {
+ Record.push_back(C->varlist_size());
+ VisitOMPClauseWithPostUpdate(C);
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getColonLoc());
+ Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
+ Record.AddDeclarationNameInfo(C->getNameInfo());
+ for (auto *VE : C->varlists())
+ Record.AddStmt(VE);
+ for (auto *VE : C->privates())
+ Record.AddStmt(VE);
+ for (auto *E : C->lhs_exprs())
+ Record.AddStmt(E);
+ for (auto *E : C->rhs_exprs())
+ Record.AddStmt(E);
+ for (auto *E : C->reduction_ops())
+ Record.AddStmt(E);
+ for (auto *E : C->taskgroup_descriptors())
+ Record.AddStmt(E);
+}
+
void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
Record.push_back(C->varlist_size());
VisitOMPClauseWithPostUpdate(C);
@@ -2081,6 +2102,7 @@ void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) {
}
void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) {
+ VisitOMPClauseWithPreInit(C);
Record.AddStmt(C->getDevice());
Record.AddSourceLocation(C->getLParenLoc());
}
@@ -2480,6 +2502,7 @@ void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
VisitStmt(D);
Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D);
+ Record.AddStmt(D->getReductionRef());
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
}
@@ -2545,6 +2568,7 @@ void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
void ASTStmtWriter::VisitOMPDistributeParallelForDirective(
OMPDistributeParallelForDirective *D) {
VisitOMPLoopDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
}
@@ -2592,6 +2616,7 @@ void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective(
void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective(
OMPTeamsDistributeParallelForDirective *D) {
VisitOMPLoopDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
}
@@ -2611,6 +2636,7 @@ void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective(
OMPTargetTeamsDistributeParallelForDirective *D) {
VisitOMPLoopDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
}
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index 6978e7e09774..20c114297b99 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -619,6 +619,10 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
(uint32_t)Record[Idx++]}}};
+ // Skip the module name (currently this is only used for prebuilt
+ // modules while here we are only dealing with cached).
+ Idx += Record[Idx] + 1;
+
// Retrieve the imported file name.
unsigned Length = Record[Idx++];
SmallString<128> ImportedFile(Record.begin() + Idx,
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 1dee4d069861..b512fa452cc1 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -1,4 +1,4 @@
-//===--- ModuleManager.cpp - Module Manager ---------------------*- C++ -*-===//
+//===- ModuleManager.cpp - Module Manager ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,24 +11,38 @@
// modules for the ASTReader.
//
//===----------------------------------------------------------------------===//
+
#include "clang/Serialization/ModuleManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/MemoryBufferCache.h"
+#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Serialization/GlobalModuleIndex.h"
+#include "clang/Serialization/Module.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/Support/Chrono.h"
+#include "llvm/Support/DOTGraphTraits.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
+#include <algorithm>
+#include <cassert>
+#include <memory>
+#include <string>
#include <system_error>
-#ifndef NDEBUG
-#include "llvm/Support/GraphWriter.h"
-#endif
-
using namespace clang;
using namespace serialization;
-ModuleFile *ModuleManager::lookup(StringRef Name) const {
+ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const {
const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
/*cacheFailure=*/false);
if (Entry)
@@ -37,6 +51,14 @@ ModuleFile *ModuleManager::lookup(StringRef Name) const {
return nullptr;
}
+ModuleFile *ModuleManager::lookupByModuleName(StringRef Name) const {
+ if (const Module *Mod = HeaderSearchInfo.getModuleMap().findModule(Name))
+ if (const FileEntry *File = Mod->getASTFile())
+ return lookup(File);
+
+ return nullptr;
+}
+
ModuleFile *ModuleManager::lookup(const FileEntry *File) const {
auto Known = Modules.find(File);
if (Known == Modules.end())
@@ -200,7 +222,6 @@ void ModuleManager::removeModules(
if (First == Last)
return;
-
// Explicitly clear VisitOrder since we might not notice it is stale.
VisitOrder.clear();
@@ -259,7 +280,6 @@ void ModuleManager::removeModules(
void
ModuleManager::addInMemoryBuffer(StringRef FileName,
std::unique_ptr<llvm::MemoryBuffer> Buffer) {
-
const FileEntry *Entry =
FileMgr.getVirtualFile(FileName, Buffer->getBufferSize(), 0);
InMemoryBuffers[Entry] = std::move(Buffer);
@@ -306,9 +326,10 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
}
ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
- const PCHContainerReader &PCHContainerRdr)
+ const PCHContainerReader &PCHContainerRdr,
+ const HeaderSearch& HeaderSearchInfo)
: FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr),
- GlobalIndex(), FirstVisitState(nullptr) {}
+ HeaderSearchInfo(HeaderSearchInfo) {}
ModuleManager::~ModuleManager() { delete FirstVisitState; }
@@ -442,11 +463,12 @@ bool ModuleManager::lookupModuleFile(StringRef FileName,
#ifndef NDEBUG
namespace llvm {
+
template<>
struct GraphTraits<ModuleManager> {
- typedef ModuleFile *NodeRef;
- typedef llvm::SetVector<ModuleFile *>::const_iterator ChildIteratorType;
- typedef pointer_iterator<ModuleManager::ModuleConstIterator> nodes_iterator;
+ using NodeRef = ModuleFile *;
+ using ChildIteratorType = llvm::SetVector<ModuleFile *>::const_iterator;
+ using nodes_iterator = pointer_iterator<ModuleManager::ModuleConstIterator>;
static ChildIteratorType child_begin(NodeRef Node) {
return Node->Imports.begin();
@@ -468,17 +490,16 @@ namespace llvm {
template<>
struct DOTGraphTraits<ModuleManager> : public DefaultDOTGraphTraits {
explicit DOTGraphTraits(bool IsSimple = false)
- : DefaultDOTGraphTraits(IsSimple) { }
+ : DefaultDOTGraphTraits(IsSimple) {}
- static bool renderGraphFromBottomUp() {
- return true;
- }
+ static bool renderGraphFromBottomUp() { return true; }
std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {
return M->ModuleName;
}
};
-}
+
+} // namespace llvm
void ModuleManager::viewGraph() {
llvm::ViewGraph(*this, "Modules");
diff --git a/lib/Serialization/MultiOnDiskHashTable.h b/lib/Serialization/MultiOnDiskHashTable.h
index fdbbb602b537..44d1616a0110 100644
--- a/lib/Serialization/MultiOnDiskHashTable.h
+++ b/lib/Serialization/MultiOnDiskHashTable.h
@@ -1,4 +1,4 @@
-//===--- MultiOnDiskHashTable.h - Merged set of hash tables -----*- C++ -*-===//
+//===- MultiOnDiskHashTable.h - Merged set of hash tables -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,6 +15,7 @@
// files.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H
#define LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H
@@ -22,33 +23,43 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/OnDiskHashTable.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstdint>
+#include <vector>
namespace clang {
namespace serialization {
-class ModuleFile;
-
/// \brief A collection of on-disk hash tables, merged when relevant for performance.
template<typename Info> class MultiOnDiskHashTable {
public:
/// A handle to a file, used when overriding tables.
- typedef typename Info::file_type file_type;
+ using file_type = typename Info::file_type;
+
/// A pointer to an on-disk representation of the hash table.
- typedef const unsigned char *storage_type;
+ using storage_type = const unsigned char *;
- typedef typename Info::external_key_type external_key_type;
- typedef typename Info::internal_key_type internal_key_type;
- typedef typename Info::data_type data_type;
- typedef typename Info::data_type_builder data_type_builder;
- typedef unsigned hash_value_type;
+ using external_key_type = typename Info::external_key_type;
+ using internal_key_type = typename Info::internal_key_type;
+ using data_type = typename Info::data_type;
+ using data_type_builder = typename Info::data_type_builder;
+ using hash_value_type = unsigned;
private:
+ /// The generator is permitted to read our merged table.
+ template<typename ReaderInfo, typename WriterInfo>
+ friend class MultiOnDiskHashTableGenerator;
+
/// \brief A hash table stored on disk.
struct OnDiskTable {
- typedef llvm::OnDiskIterableChainedHashTable<Info> HashTable;
+ using HashTable = llvm::OnDiskIterableChainedHashTable<Info>;
file_type File;
HashTable Table;
@@ -65,8 +76,8 @@ private:
llvm::DenseMap<internal_key_type, data_type> Data;
};
- typedef llvm::PointerUnion<OnDiskTable*, MergedTable*> Table;
- typedef llvm::TinyPtrVector<void*> TableVector;
+ using Table = llvm::PointerUnion<OnDiskTable *, MergedTable *>;
+ using TableVector = llvm::TinyPtrVector<void *>;
/// \brief The current set of on-disk and merged tables.
/// We manually store the opaque value of the Table because TinyPtrVector
@@ -80,14 +91,16 @@ private:
llvm::TinyPtrVector<file_type> PendingOverrides;
struct AsOnDiskTable {
- typedef OnDiskTable *result_type;
+ using result_type = OnDiskTable *;
+
result_type operator()(void *P) const {
return Table::getFromOpaqueValue(P).template get<OnDiskTable *>();
}
};
- typedef llvm::mapped_iterator<TableVector::iterator, AsOnDiskTable>
- table_iterator;
- typedef llvm::iterator_range<table_iterator> table_range;
+
+ using table_iterator =
+ llvm::mapped_iterator<TableVector::iterator, AsOnDiskTable>;
+ using table_range = llvm::iterator_range<table_iterator>;
/// \brief The current set of on-disk tables.
table_range tables() {
@@ -160,17 +173,15 @@ private:
Tables.push_back(Table(Merged).getOpaqueValue());
}
- /// The generator is permitted to read our merged table.
- template<typename ReaderInfo, typename WriterInfo>
- friend class MultiOnDiskHashTableGenerator;
-
public:
- MultiOnDiskHashTable() {}
+ MultiOnDiskHashTable() = default;
+
MultiOnDiskHashTable(MultiOnDiskHashTable &&O)
: Tables(std::move(O.Tables)),
PendingOverrides(std::move(O.PendingOverrides)) {
O.Tables.clear();
}
+
MultiOnDiskHashTable &operator=(MultiOnDiskHashTable &&O) {
if (&O == this)
return *this;
@@ -180,11 +191,13 @@ public:
PendingOverrides = std::move(O.PendingOverrides);
return *this;
}
+
~MultiOnDiskHashTable() { clear(); }
/// \brief Add the table \p Data loaded from file \p File.
void add(file_type File, storage_type Data, Info InfoObj = Info()) {
using namespace llvm::support;
+
storage_type Ptr = Data;
uint32_t BucketOffset = endian::readNext<uint32_t, little, unaligned>(Ptr);
@@ -278,8 +291,8 @@ public:
/// \brief Writer for the on-disk hash table.
template<typename ReaderInfo, typename WriterInfo>
class MultiOnDiskHashTableGenerator {
- typedef MultiOnDiskHashTable<ReaderInfo> BaseTable;
- typedef llvm::OnDiskChainedHashTableGenerator<WriterInfo> Generator;
+ using BaseTable = MultiOnDiskHashTable<ReaderInfo>;
+ using Generator = llvm::OnDiskChainedHashTableGenerator<WriterInfo>;
Generator Gen;
@@ -294,6 +307,7 @@ public:
void emit(llvm::SmallVectorImpl<char> &Out, WriterInfo &Info,
const BaseTable *Base) {
using namespace llvm::support;
+
llvm::raw_svector_ostream OutStream(Out);
// Write our header information.
@@ -327,8 +341,7 @@ public:
}
};
-} // end namespace clang::serialization
-} // end namespace clang
-
+} // namespace serialization
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H