diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
commit | 461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch) | |
tree | 6942083d7d56bba40ec790a453ca58ad3baf6832 /lib/Serialization | |
parent | 75c3240472ba6ac2669ee72ca67eb72d4e2851fc (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.cpp | 3 | ||||
-rw-r--r-- | lib/Serialization/ASTCommon.h | 3 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 688 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 90 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderInternals.h | 92 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 46 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 250 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 83 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 26 | ||||
-rw-r--r-- | lib/Serialization/GlobalModuleIndex.cpp | 4 | ||||
-rw-r--r-- | lib/Serialization/ModuleManager.cpp | 59 | ||||
-rw-r--r-- | lib/Serialization/MultiOnDiskHashTable.h | 69 |
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 |