diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization')
9 files changed, 3612 insertions, 1545 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp index 77c1aff..5e94f59 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp @@ -12,11 +12,15 @@ //===----------------------------------------------------------------------===// #include "ASTCommon.h" +#include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/StringExtras.h" using namespace clang; +// Give ASTDeserializationListener's VTable a home. +ASTDeserializationListener::~ASTDeserializationListener() { } + serialization::TypeIdx serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { unsigned ID = 0; @@ -32,7 +36,8 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::UInt128: ID = PREDEF_TYPE_UINT128_ID; break; case BuiltinType::Char_S: ID = PREDEF_TYPE_CHAR_S_ID; break; case BuiltinType::SChar: ID = PREDEF_TYPE_SCHAR_ID; break; - case BuiltinType::WChar: ID = PREDEF_TYPE_WCHAR_ID; break; + case BuiltinType::WChar_S: + case BuiltinType::WChar_U: ID = PREDEF_TYPE_WCHAR_ID; break; case BuiltinType::Short: ID = PREDEF_TYPE_SHORT_ID; break; case BuiltinType::Int: ID = PREDEF_TYPE_INT_ID; break; case BuiltinType::Long: ID = PREDEF_TYPE_LONG_ID; break; @@ -49,9 +54,6 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::ObjCId: ID = PREDEF_TYPE_OBJC_ID; break; case BuiltinType::ObjCClass: ID = PREDEF_TYPE_OBJC_CLASS; break; case BuiltinType::ObjCSel: ID = PREDEF_TYPE_OBJC_SEL; break; - case BuiltinType::UndeducedAuto: - assert(0 && "Should not see undeduced auto here"); - break; } return TypeIdx(ID); diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h index a0e2ecd..d416699 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h @@ -20,6 +20,12 @@ namespace clang { namespace serialization { +enum DeclUpdateKind { + UPD_CXX_SET_DEFINITIONDATA, + UPD_CXX_ADDED_IMPLICIT_MEMBER, + UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION +}; + TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT); template <typename IdxForTypeTy> @@ -28,7 +34,7 @@ TypeID MakeTypeID(QualType T, IdxForTypeTy IdxForType) { return PREDEF_TYPE_NULL_ID; unsigned FastQuals = T.getLocalFastQualifiers(); - T.removeFastQualifiers(); + T.removeLocalFastQualifiers(); if (T.hasLocalNonFastQualifiers()) return IdxForType(T).asTypeID(FastQuals); diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp index f07215c..ce87b11 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp @@ -33,17 +33,21 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManagerInternals.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/System/Path.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/system_error.h" #include <algorithm> #include <iterator> #include <cstdio> #include <sys/stat.h> + using namespace clang; using namespace clang::serialization; @@ -74,6 +78,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { PARSE_LANGOPT_BENIGN(HexFloats); PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99); PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions); + PARSE_LANGOPT_BENIGN(MSCVersion); PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus); PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x); PARSE_LANGOPT_BENIGN(CXXOperatorName); @@ -81,7 +86,10 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2); PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi); PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2); - PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings, + PARSE_LANGOPT_IMPORTANT(AppleKext, diag::warn_pch_apple_kext); + PARSE_LANGOPT_IMPORTANT(ObjCDefaultSynthProperties, + diag::warn_pch_objc_auto_properties); + PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings, diag::warn_pch_no_constant_cfstrings); PARSE_LANGOPT_BENIGN(PascalStrings); PARSE_LANGOPT_BENIGN(WritableStrings); @@ -90,6 +98,8 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec); PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions); PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_exceptions); + PARSE_LANGOPT_IMPORTANT(ObjCExceptions, diag::warn_pch_objc_exceptions); + PARSE_LANGOPT_IMPORTANT(MSBitfields, diag::warn_pch_ms_bitfields); PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime); PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding); PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins); @@ -118,6 +128,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control); PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed); PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar); + PARSE_LANGOPT_IMPORTANT(ShortEnums, diag::warn_pch_short_enums); if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) { Reader.Diag(diag::warn_pch_gc_mode) << LangOpts.getGCMode() << PPLangOpts.getGCMode(); @@ -128,9 +139,11 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { diag::warn_pch_stack_protector); PARSE_LANGOPT_BENIGN(InstantiationDepth); PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl); + PARSE_LANGOPT_IMPORTANT(CUDA, diag::warn_pch_cuda); PARSE_LANGOPT_BENIGN(CatchUndefined); PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors); PARSE_LANGOPT_BENIGN(SpellChecking); + PARSE_LANGOPT_BENIGN(DefaultFPContract); #undef PARSE_LANGOPT_IMPORTANT #undef PARSE_LANGOPT_BENIGN @@ -146,12 +159,14 @@ bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) { return true; } -struct EmptyStringRef { - bool operator ()(llvm::StringRef r) const { return r.empty(); } -}; -struct EmptyBlock { - bool operator ()(const PCHPredefinesBlock &r) const { return r.Data.empty(); } -}; +namespace { + struct EmptyStringRef { + bool operator ()(llvm::StringRef r) const { return r.empty(); } + }; + struct EmptyBlock { + bool operator ()(const PCHPredefinesBlock &r) const {return r.Data.empty();} + }; +} static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L, PCHPredefinesBlocks R) { @@ -263,7 +278,36 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, llvm::SmallVector<llvm::StringRef, 8> CmdLineLines; Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false); - Right.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false); + + // Pick out implicit #includes after the PCH and don't consider them for + // validation; we will insert them into SuggestedPredefines so that the + // preprocessor includes them. + std::string IncludesAfterPCH; + llvm::SmallVector<llvm::StringRef, 8> AfterPCHLines; + Right.split(AfterPCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false); + for (unsigned i = 0, e = AfterPCHLines.size(); i != e; ++i) { + if (AfterPCHLines[i].startswith("#include ")) { + IncludesAfterPCH += AfterPCHLines[i]; + IncludesAfterPCH += '\n'; + } else { + CmdLineLines.push_back(AfterPCHLines[i]); + } + } + + // Make sure we add the includes last into SuggestedPredefines before we + // exit this function. + struct AddIncludesRAII { + std::string &SuggestedPredefines; + std::string &IncludesAfterPCH; + + AddIncludesRAII(std::string &SuggestedPredefines, + std::string &IncludesAfterPCH) + : SuggestedPredefines(SuggestedPredefines), + IncludesAfterPCH(IncludesAfterPCH) { } + ~AddIncludesRAII() { + SuggestedPredefines += IncludesAfterPCH; + } + } AddIncludes(SuggestedPredefines, IncludesAfterPCH); // Sort both sets of predefined buffer lines, since we allow some extra // definitions and they may appear at any point in the output. @@ -281,6 +325,11 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, bool ConflictingDefines = false; for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) { llvm::StringRef Missing = MissingPredefines[I]; + if (Missing.startswith("#include ")) { + // An -include was specified when generating the PCH; it is included in + // the PCH, just ignore it. + continue; + } if (!Missing.startswith("#define ")) { Reader.Diag(diag::warn_pch_compiler_options_mismatch); return true; @@ -418,8 +467,6 @@ void PCHValidator::ReadCounter(unsigned Value) { void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) { DeserializationListener = Listener; - if (DeserializationListener) - DeserializationListener->SetReader(this); } @@ -533,10 +580,10 @@ public: typedef OnDiskChainedHashTable<ASTSelectorLookupTrait> ASTSelectorLookupTable; -namespace { +namespace clang { class ASTIdentifierLookupTrait { ASTReader &Reader; - llvm::BitstreamCursor &Stream; + ASTReader::PerFileData &F; // If we know the IdentifierInfo in advance, it is here and we will // not build a new one. Used when deserializing information about an @@ -550,9 +597,9 @@ public: typedef external_key_type internal_key_type; - ASTIdentifierLookupTrait(ASTReader &Reader, llvm::BitstreamCursor &Stream, + ASTIdentifierLookupTrait(ASTReader &Reader, ASTReader::PerFileData &F, IdentifierInfo *II = 0) - : Reader(Reader), Stream(Stream), KnownII(II) { } + : Reader(Reader), F(F), KnownII(II) { } static bool EqualKey(const internal_key_type& a, const internal_key_type& b) { @@ -568,6 +615,10 @@ public: static const internal_key_type& GetInternalKey(const external_key_type& x) { return x; } + // This hopefully will just get inlined and removed by the optimizer. + static const external_key_type& + GetExternalKey(const internal_key_type& x) { return x; } + static std::pair<unsigned, unsigned> ReadKeyDataLength(const unsigned char*& d) { using namespace clang::io; @@ -644,7 +695,7 @@ public: // definition. if (hasMacroDefinition) { uint32_t Offset = ReadUnalignedLE32(d); - Reader.ReadMacroRecord(Stream, Offset); + Reader.SetIdentifierIsMacro(II, F, Offset); DataLen -= 4; } @@ -752,7 +803,7 @@ public: case DeclarationName::CXXUsingDirective: break; } - + return Key; } @@ -814,7 +865,7 @@ public: case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: - Key.Data = + Key.Data = (uint64_t)Reader.DecodeSelector(ReadUnalignedLE32(d)).getAsOpaquePtr(); break; case DeclarationName::CXXConstructorName: @@ -831,7 +882,7 @@ public: case DeclarationName::CXXUsingDirective: break; } - + return Key; } @@ -868,8 +919,8 @@ bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, return true; } - Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob); - Info.NumLexicalDecls = BlobLen / sizeof(DeclID); + Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair*>(Blob); + Info.NumLexicalDecls = BlobLen / sizeof(KindDeclIDPair); } else { Info.LexicalDecls = 0; Info.NumLexicalDecls = 0; @@ -918,8 +969,9 @@ bool ASTReader::CheckPredefinesBuffers() { //===----------------------------------------------------------------------===// /// \brief Read the line table in the source manager block. -/// \returns true if ther was an error. -bool ASTReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) { +/// \returns true if there was an error. +bool ASTReader::ParseLineTable(PerFileData &F, + llvm::SmallVectorImpl<uint64_t> &Record) { unsigned Idx = 0; LineTableInfo &LineTable = SourceMgr.getLineTable(); @@ -965,7 +1017,6 @@ namespace { class ASTStatData { public: - const bool hasStat; const ino_t ino; const dev_t dev; const mode_t mode; @@ -973,10 +1024,7 @@ public: const off_t size; ASTStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s) - : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {} - - ASTStatData() - : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {} + : ino(i), dev(d), mode(mo), mtime(m), size(s) {} }; class ASTStatLookupTrait { @@ -1011,9 +1059,6 @@ class ASTStatLookupTrait { unsigned /*DataLen*/) { using namespace clang::io; - if (*d++ == 1) - return data_type(); - ino_t ino = (ino_t) ReadUnalignedLE32(d); dev_t dev = (dev_t) ReadUnalignedLE32(d); mode_t mode = (mode_t) ReadUnalignedLE16(d); @@ -1027,44 +1072,40 @@ class ASTStatLookupTrait { /// /// This cache is very similar to the stat cache used by pretokenized /// headers. -class ASTStatCache : public StatSysCallCache { +class ASTStatCache : public FileSystemStatCache { typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy; CacheTy *Cache; unsigned &NumStatHits, &NumStatMisses; public: - ASTStatCache(const unsigned char *Buckets, - const unsigned char *Base, - unsigned &NumStatHits, - unsigned &NumStatMisses) + ASTStatCache(const unsigned char *Buckets, const unsigned char *Base, + unsigned &NumStatHits, unsigned &NumStatMisses) : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) { Cache = CacheTy::Create(Buckets, Base); } ~ASTStatCache() { delete Cache; } - int stat(const char *path, struct stat *buf) { + LookupResult getStat(const char *Path, struct stat &StatBuf, + int *FileDescriptor) { // Do the lookup for the file's data in the AST file. - CacheTy::iterator I = Cache->find(path); + CacheTy::iterator I = Cache->find(Path); // If we don't get a hit in the AST file just forward to 'stat'. if (I == Cache->end()) { ++NumStatMisses; - return StatSysCallCache::stat(path, buf); + return statChained(Path, StatBuf, FileDescriptor); } ++NumStatHits; ASTStatData Data = *I; - if (!Data.hasStat) - return 1; - - buf->st_ino = Data.ino; - buf->st_dev = Data.dev; - buf->st_mtime = Data.mtime; - buf->st_mode = Data.mode; - buf->st_size = Data.size; - return 0; + StatBuf.st_ino = Data.ino; + StatBuf.st_dev = Data.dev; + StatBuf.st_mtime = Data.mtime; + StatBuf.st_mode = Data.mode; + StatBuf.st_size = Data.size; + return CacheExists; } }; } // end anonymous namespace @@ -1129,7 +1170,7 @@ ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) { break; case SM_LINE_TABLE: - if (ParseLineTable(Record)) + if (ParseLineTable(F, Record)) return Failure; break; @@ -1142,9 +1183,42 @@ ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) { } } +/// \brief If a header file is not found at the path that we expect it to be +/// and the PCH file was moved from its original location, try to resolve the +/// file by assuming that header+PCH were moved together and the header is in +/// the same place relative to the PCH. +static std::string +resolveFileRelativeToOriginalDir(const std::string &Filename, + const std::string &OriginalDir, + 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; + llvm::SmallString<128> filePath(Filename); + fs::make_absolute(filePath); + assert(path::is_absolute(OriginalDir)); + llvm::SmallString<128> currPCHPath(CurrDir); + + path::const_iterator fileDirI = path::begin(path::parent_path(filePath)), + fileDirE = path::end(path::parent_path(filePath)); + path::const_iterator origDirI = path::begin(OriginalDir), + origDirE = path::end(OriginalDir); + // Skip the common path components from filePath and OriginalDir. + while (fileDirI != fileDirE && origDirI != origDirE && + *fileDirI == *origDirI) { + ++fileDirI; + ++origDirI; + } + for (; origDirI != origDirE; ++origDirI) + path::append(currPCHPath, ".."); + path::append(currPCHPath, fileDirI, fileDirE); + path::append(currPCHPath, path::filename(Filename)); + return currPCHPath.str(); +} + /// \brief Get a cursor that's correctly positioned for reading the source /// location entry with the given ID. -llvm::BitstreamCursor &ASTReader::SLocCursorForID(unsigned ID) { +ASTReader::PerFileData *ASTReader::SLocCursorForID(unsigned ID) { assert(ID != 0 && ID <= TotalNumSLocEntries && "SLocCursorForID should only be called for real IDs."); @@ -1159,7 +1233,7 @@ llvm::BitstreamCursor &ASTReader::SLocCursorForID(unsigned ID) { assert(F && F->LocalNumSLocEntries > ID && "Chain corrupted"); F->SLocEntryCursor.JumpToBit(F->SLocOffsets[ID]); - return F->SLocEntryCursor; + return F; } /// \brief Read in the source location entry with the given ID. @@ -1172,7 +1246,8 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) { return Failure; } - llvm::BitstreamCursor &SLocEntryCursor = SLocCursorForID(ID); + PerFileData *F = SLocCursorForID(ID); + llvm::BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor; ++NumSLocEntriesRead; unsigned Code = SLocEntryCursor.ReadCode(); @@ -1195,6 +1270,17 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) { std::string Filename(BlobStart, BlobStart + BlobLen); MaybeAddSystemRootToFilename(Filename); const FileEntry *File = FileMgr.getFile(Filename); + if (File == 0 && !OriginalDir.empty() && !CurrentDir.empty() && + OriginalDir != CurrentDir) { + std::string resolved = resolveFileRelativeToOriginalDir(Filename, + OriginalDir, + CurrentDir); + if (!resolved.empty()) + File = FileMgr.getFile(resolved); + } + if (File == 0) + File = FileMgr.getVirtualFile(Filename, (off_t)Record[4], + (time_t)Record[5]); if (File == 0) { std::string ErrorStr = "could not find file '"; ErrorStr += Filename; @@ -1203,7 +1289,7 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) { return Failure; } - if (Record.size() < 10) { + if (Record.size() < 6) { Error("source location entry is incorrect"); return Failure; } @@ -1222,22 +1308,13 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) { return Failure; } - FileID FID = SourceMgr.createFileID(File, - SourceLocation::getFromRawEncoding(Record[1]), - (SrcMgr::CharacteristicKind)Record[2], + FileID FID = SourceMgr.createFileID(File, ReadSourceLocation(*F, Record[1]), + (SrcMgr::CharacteristicKind)Record[2], ID, Record[0]); if (Record[3]) const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile()) .setHasLineDirectives(); - - // Reconstruct header-search information for this file. - HeaderFileInfo HFI; - HFI.isImport = Record[6]; - HFI.DirInfo = Record[7]; - HFI.NumIncludes = Record[8]; - HFI.ControllingMacroID = Record[9]; - if (Listener) - Listener->ReadHeaderFileInfo(HFI, File->getUID()); + break; } @@ -1271,11 +1348,10 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) { } case SM_SLOC_INSTANTIATION_ENTRY: { - SourceLocation SpellingLoc - = SourceLocation::getFromRawEncoding(Record[1]); + SourceLocation SpellingLoc = ReadSourceLocation(*F, Record[1]); SourceMgr.createInstantiationLoc(SpellingLoc, - SourceLocation::getFromRawEncoding(Record[2]), - SourceLocation::getFromRawEncoding(Record[3]), + ReadSourceLocation(*F, Record[2]), + ReadSourceLocation(*F, Record[3]), Record[4], ID, Record[0]); @@ -1297,17 +1373,21 @@ bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, } while (true) { + uint64_t Offset = Cursor.GetCurrentBitNo(); unsigned Code = Cursor.ReadCode(); // We expect all abbrevs to be at the start of the block. - if (Code != llvm::bitc::DEFINE_ABBREV) + if (Code != llvm::bitc::DEFINE_ABBREV) { + Cursor.JumpToBit(Offset); return false; + } Cursor.ReadAbbrevRecord(); } } -void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){ +PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) { assert(PP && "Forgot to set Preprocessor ?"); + llvm::BitstreamCursor &Stream = F.MacroCursor; // Keep track of where we are in the stream, then jump back there // after reading this macro. @@ -1322,14 +1402,14 @@ void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){ unsigned Code = Stream.ReadCode(); switch (Code) { case llvm::bitc::END_BLOCK: - return; + return 0; case llvm::bitc::ENTER_SUBBLOCK: // No known subblocks, always skip them. Stream.ReadSubBlockID(); if (Stream.SkipBlock()) { Error("malformed block record in AST file"); - return; + return 0; } continue; @@ -1340,9 +1420,12 @@ void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){ } // Read a record. + const char *BlobStart = 0; + unsigned BlobLen = 0; Record.clear(); PreprocessorRecordTypes RecType = - (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record); + (PreprocessorRecordTypes)Stream.ReadRecord(Code, Record, BlobStart, + BlobLen); switch (RecType) { case PP_MACRO_OBJECT_LIKE: case PP_MACRO_FUNCTION_LIKE: { @@ -1350,14 +1433,14 @@ void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){ // of the definition of the macro we were looking for. We're // done. if (Macro) - return; + return 0; IdentifierInfo *II = DecodeIdentifierInfo(Record[0]); if (II == 0) { Error("macro must have a name in AST file"); - return; + return 0; } - SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]); + SourceLocation Loc = ReadSourceLocation(F, Record[1]); bool isUsed = Record[2]; MacroInfo *MI = PP->AllocateMacroInfo(Loc); @@ -1389,13 +1472,13 @@ void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){ // Remember that we saw this macro last so that we add the tokens that // form its body to it. Macro = MI; - + if (NextIndex + 1 == Record.size() && PP->getPreprocessingRecord()) { // We have a macro definition. Load it now. PP->getPreprocessingRecord()->RegisterMacroDefinition(Macro, getMacroDefinition(Record[NextIndex])); } - + ++NumMacrosRead; break; } @@ -1407,7 +1490,7 @@ void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){ Token Tok; Tok.startToken(); - Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0])); + Tok.setLocation(ReadSourceLocation(F, Record[0])); Tok.setLength(Record[1]); if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2])) Tok.setIdentifierInfo(II); @@ -1416,92 +1499,242 @@ void ASTReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){ Macro->AddTokenToBody(Tok); break; } - - case PP_MACRO_INSTANTIATION: { - // If we already have a macro, that means that we've hit the end - // of the definition of the macro we were looking for. We're - // done. - if (Macro) - return; - - if (!PP->getPreprocessingRecord()) { - Error("missing preprocessing record in AST file"); - return; - } - - PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); - if (PPRec.getPreprocessedEntity(Record[0])) - return; - - MacroInstantiation *MI - = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]), - SourceRange( - SourceLocation::getFromRawEncoding(Record[1]), - SourceLocation::getFromRawEncoding(Record[2])), - getMacroDefinition(Record[4])); - PPRec.SetPreallocatedEntity(Record[0], MI); - return; - } + } + } + + return 0; +} - case PP_MACRO_DEFINITION: { - // If we already have a macro, that means that we've hit the end - // of the definition of the macro we were looking for. We're - // done. - if (Macro) - return; +PreprocessedEntity *ASTReader::LoadPreprocessedEntity(PerFileData &F) { + assert(PP && "Forgot to set Preprocessor ?"); + unsigned Code = F.PreprocessorDetailCursor.ReadCode(); + switch (Code) { + case llvm::bitc::END_BLOCK: + return 0; + + case llvm::bitc::ENTER_SUBBLOCK: + Error("unexpected subblock record in preprocessor detail block"); + return 0; - if (!PP->getPreprocessingRecord()) { - Error("missing preprocessing record in AST file"); - return; - } + case llvm::bitc::DEFINE_ABBREV: + Error("unexpected abbrevation record in preprocessor detail block"); + return 0; - PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); - if (PPRec.getPreprocessedEntity(Record[0])) - return; - - if (Record[1] >= MacroDefinitionsLoaded.size()) { - Error("out-of-bounds macro definition record"); - return; - } + default: + break; + } + if (!PP->getPreprocessingRecord()) { + Error("no preprocessing record"); + return 0; + } + + // Read the record. + PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); + const char *BlobStart = 0; + unsigned BlobLen = 0; + RecordData Record; + PreprocessorDetailRecordTypes RecType = + (PreprocessorDetailRecordTypes)F.PreprocessorDetailCursor.ReadRecord( + Code, Record, BlobStart, BlobLen); + switch (RecType) { + case PPD_MACRO_INSTANTIATION: { + if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) + return PE; + + MacroInstantiation *MI + = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]), + SourceRange(ReadSourceLocation(F, Record[1]), + ReadSourceLocation(F, Record[2])), + getMacroDefinition(Record[4])); + PPRec.SetPreallocatedEntity(Record[0], MI); + return MI; + } + + case PPD_MACRO_DEFINITION: { + if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) + return PE; + + if (Record[1] > MacroDefinitionsLoaded.size()) { + Error("out-of-bounds macro definition record"); + return 0; + } + + // Decode the identifier info and then check again; if the macro is + // still defined and associated with the identifier, + IdentifierInfo *II = DecodeIdentifierInfo(Record[4]); + if (!MacroDefinitionsLoaded[Record[1] - 1]) { MacroDefinition *MD - = new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]), - SourceLocation::getFromRawEncoding(Record[5]), - SourceRange( - SourceLocation::getFromRawEncoding(Record[2]), - SourceLocation::getFromRawEncoding(Record[3]))); + = new (PPRec) MacroDefinition(II, + ReadSourceLocation(F, Record[5]), + SourceRange( + ReadSourceLocation(F, Record[2]), + ReadSourceLocation(F, Record[3]))); + PPRec.SetPreallocatedEntity(Record[0], MD); - MacroDefinitionsLoaded[Record[1]] = MD; - return; + MacroDefinitionsLoaded[Record[1] - 1] = MD; + + if (DeserializationListener) + DeserializationListener->MacroDefinitionRead(Record[1], MD); } + + return MacroDefinitionsLoaded[Record[1] - 1]; + } + + case PPD_INCLUSION_DIRECTIVE: { + if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0])) + return PE; + + const char *FullFileNameStart = BlobStart + Record[3]; + const FileEntry *File + = PP->getFileManager().getFile(llvm::StringRef(FullFileNameStart, + BlobLen - Record[3])); + + // FIXME: Stable encoding + InclusionDirective::InclusionKind Kind + = static_cast<InclusionDirective::InclusionKind>(Record[5]); + InclusionDirective *ID + = new (PPRec) InclusionDirective(PPRec, Kind, + llvm::StringRef(BlobStart, Record[3]), + Record[4], + File, + SourceRange(ReadSourceLocation(F, Record[1]), + ReadSourceLocation(F, Record[2]))); + PPRec.SetPreallocatedEntity(Record[0], ID); + return ID; } } + + Error("invalid offset in preprocessor detail block"); + return 0; +} + +namespace { + /// \brief Trait class used to search the on-disk hash table containing all of + /// the header search information. + /// + /// The on-disk hash table contains a mapping from each header path to + /// information about that header (how many times it has been included, its + /// controlling macro, etc.). Note that we actually hash based on the + /// filename, and support "deep" comparisons of file names based on current + /// inode numbers, so that the search can cope with non-normalized path names + /// and symlinks. + class HeaderFileInfoTrait { + const char *SearchPath; + struct stat SearchPathStatBuf; + llvm::Optional<int> SearchPathStatResult; + + int StatSimpleCache(const char *Path, struct stat *StatBuf) { + if (Path == SearchPath) { + if (!SearchPathStatResult) + SearchPathStatResult = stat(Path, &SearchPathStatBuf); + + *StatBuf = SearchPathStatBuf; + return *SearchPathStatResult; + } + + return stat(Path, StatBuf); + } + + public: + typedef const char *external_key_type; + typedef const char *internal_key_type; + + typedef HeaderFileInfo data_type; + + HeaderFileInfoTrait(const char *SearchPath = 0) : SearchPath(SearchPath) { } + + static unsigned ComputeHash(const char *path) { + return llvm::HashString(llvm::sys::path::filename(path)); + } + + static internal_key_type GetInternalKey(const char *path) { return path; } + + bool EqualKey(internal_key_type a, internal_key_type b) { + if (strcmp(a, b) == 0) + return true; + + if (llvm::sys::path::filename(a) != llvm::sys::path::filename(b)) + return false; + + // The file names match, but the path names don't. stat() the files to + // see if they are the same. + struct stat StatBufA, StatBufB; + if (StatSimpleCache(a, &StatBufA) || StatSimpleCache(b, &StatBufB)) + return false; + + return StatBufA.st_ino == StatBufB.st_ino; + } + + static std::pair<unsigned, unsigned> + ReadKeyDataLength(const unsigned char*& d) { + unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d); + unsigned DataLen = (unsigned) *d++; + return std::make_pair(KeyLen + 1, DataLen); + } + + static internal_key_type ReadKey(const unsigned char *d, unsigned) { + return (const char *)d; + } + + static data_type ReadData(const internal_key_type, const unsigned char *d, + unsigned DataLen) { + const unsigned char *End = d + DataLen; + using namespace clang::io; + HeaderFileInfo HFI; + unsigned Flags = *d++; + HFI.isImport = (Flags >> 3) & 0x01; + HFI.DirInfo = (Flags >> 1) & 0x03; + HFI.Resolved = Flags & 0x01; + HFI.NumIncludes = ReadUnalignedLE16(d); + HFI.ControllingMacroID = ReadUnalignedLE32(d); + assert(End == d && "Wrong data length in HeaderFileInfo deserialization"); + (void)End; + + // This HeaderFileInfo was externally loaded. + HFI.External = true; + return HFI; + } + }; +} + +/// \brief The on-disk hash table used for the global method pool. +typedef OnDiskChainedHashTable<HeaderFileInfoTrait> + HeaderFileInfoLookupTable; + +void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F, + uint64_t Offset) { + // Note that this identifier has a macro definition. + II->setHasMacroDefinition(true); + + // Adjust the offset based on our position in the chain. + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (Chain[I] == &F) + break; + + Offset += Chain[I]->SizeInBits; + } + + UnreadMacroRecordOffsets[II] = Offset; } void ASTReader::ReadDefinedMacros() { for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - llvm::BitstreamCursor &MacroCursor = Chain[N - I - 1]->MacroCursor; + PerFileData &F = *Chain[N - I - 1]; + llvm::BitstreamCursor &MacroCursor = F.MacroCursor; // If there was no preprocessor block, skip this file. if (!MacroCursor.getBitStreamReader()) continue; llvm::BitstreamCursor Cursor = MacroCursor; - if (Cursor.EnterSubBlock(PREPROCESSOR_BLOCK_ID)) { - Error("malformed preprocessor block record in AST file"); - return; - } + Cursor.JumpToBit(F.MacroStartOffset); RecordData Record; while (true) { unsigned Code = Cursor.ReadCode(); - if (Code == llvm::bitc::END_BLOCK) { - if (Cursor.ReadBlockEnd()) { - Error("error at end of preprocessor block in AST file"); - return; - } + if (Code == llvm::bitc::END_BLOCK) break; - } if (Code == llvm::bitc::ENTER_SUBBLOCK) { // No known subblocks, always skip them. @@ -1534,35 +1767,64 @@ void ASTReader::ReadDefinedMacros() { case PP_TOKEN: // Ignore tokens. break; - - case PP_MACRO_INSTANTIATION: - case PP_MACRO_DEFINITION: - // Read the macro record. - ReadMacroRecord(Chain[N - I - 1]->Stream, Cursor.GetCurrentBitNo()); - break; } } } + + // Drain the unread macro-record offsets map. + while (!UnreadMacroRecordOffsets.empty()) + LoadMacroDefinition(UnreadMacroRecordOffsets.begin()); +} + +void ASTReader::LoadMacroDefinition( + llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos) { + assert(Pos != UnreadMacroRecordOffsets.end() && "Unknown macro definition"); + PerFileData *F = 0; + uint64_t Offset = Pos->second; + UnreadMacroRecordOffsets.erase(Pos); + + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (Offset < Chain[I]->SizeInBits) { + F = Chain[I]; + break; + } + + Offset -= Chain[I]->SizeInBits; + } + if (!F) { + Error("Malformed macro record offset"); + return; + } + + ReadMacroRecord(*F, Offset); } -MacroDefinition *ASTReader::getMacroDefinition(IdentID ID) { - if (ID == 0 || ID >= MacroDefinitionsLoaded.size()) +void ASTReader::LoadMacroDefinition(IdentifierInfo *II) { + llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos + = UnreadMacroRecordOffsets.find(II); + LoadMacroDefinition(Pos); +} + +MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) { + if (ID == 0 || ID > MacroDefinitionsLoaded.size()) return 0; - if (!MacroDefinitionsLoaded[ID]) { - unsigned Index = ID; + if (!MacroDefinitionsLoaded[ID - 1]) { + unsigned Index = ID - 1; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { PerFileData &F = *Chain[N - I - 1]; if (Index < F.LocalNumMacroDefinitions) { - ReadMacroRecord(F.Stream, F.MacroDefinitionOffsets[Index]); + SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor); + F.PreprocessorDetailCursor.JumpToBit(F.MacroDefinitionOffsets[Index]); + LoadPreprocessedEntity(F); break; } Index -= F.LocalNumMacroDefinitions; } - assert(MacroDefinitionsLoaded[ID] && "Broken chain"); + assert(MacroDefinitionsLoaded[ID - 1] && "Broken chain"); } - return MacroDefinitionsLoaded[ID]; + return MacroDefinitionsLoaded[ID - 1]; } /// \brief If we are loading a relocatable PCH file, and the filename is @@ -1573,7 +1835,7 @@ void ASTReader::MaybeAddSystemRootToFilename(std::string &Filename) { if (!RelocatablePCH) return; - if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute()) + if (Filename.empty() || llvm::sys::path::is_absolute(Filename)) return; if (isysroot == 0) { @@ -1628,17 +1890,38 @@ ASTReader::ReadASTBlock(PerFileData &F) { } break; + case DECL_UPDATES_BLOCK_ID: + if (Stream.SkipBlock()) { + Error("malformed block record in AST file"); + return Failure; + } + break; + case PREPROCESSOR_BLOCK_ID: F.MacroCursor = Stream; if (PP) PP->setExternalSource(this); - if (Stream.SkipBlock()) { + if (Stream.SkipBlock() || + ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) { Error("malformed block record in AST file"); return Failure; } + F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo(); break; + case PREPROCESSOR_DETAIL_BLOCK_ID: + F.PreprocessorDetailCursor = Stream; + if (Stream.SkipBlock() || + ReadBlockAbbrevs(F.PreprocessorDetailCursor, + PREPROCESSOR_DETAIL_BLOCK_ID)) { + Error("malformed preprocessor detail record in AST file"); + return Failure; + } + F.PreprocessorDetailStartOffset + = F.PreprocessorDetailCursor.GetCurrentBitNo(); + break; + case SOURCE_MANAGER_BLOCK_ID: switch (ReadSourceManagerBlock(F)) { case Success: @@ -1667,7 +1950,7 @@ ASTReader::ReadASTBlock(PerFileData &F) { const char *BlobStart = 0; unsigned BlobLen = 0; switch ((ASTRecordTypes)Stream.ReadRecord(Code, Record, - &BlobStart, &BlobLen)) { + &BlobStart, &BlobLen)) { default: // Default behavior: ignore. break; @@ -1698,8 +1981,8 @@ ASTReader::ReadASTBlock(PerFileData &F) { return IgnorePCH; } - // Load the chained file. - switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen))) { + // Load the chained file, which is always a PCH file. + switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen), PCH)) { case Failure: return Failure; // If we have to ignore the dependency, we'll have to ignore this too. case IgnorePCH: return IgnorePCH; @@ -1729,10 +2012,11 @@ ASTReader::ReadASTBlock(PerFileData &F) { case TU_UPDATE_LEXICAL: { DeclContextInfo Info = { /* No visible information */ 0, - reinterpret_cast<const DeclID *>(BlobStart), - BlobLen / sizeof(DeclID) + reinterpret_cast<const KindDeclIDPair *>(BlobStart), + BlobLen / sizeof(KindDeclIDPair) }; - DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info); + DeclContextOffsets[Context ? Context->getTranslationUnitDecl() : 0] + .push_back(Info); break; } @@ -1742,7 +2026,7 @@ ASTReader::ReadASTBlock(PerFileData &F) { (const unsigned char *)BlobStart + Record[1], (const unsigned char *)BlobStart, ASTDeclContextNameLookupTrait(*this)); - if (ID == 1) { // Is it the TU? + if (ID == 1 && Context) { // Is it the TU? DeclContextInfo Info = { Table, /* No lexical inforamtion */ 0, 0 }; @@ -1776,7 +2060,7 @@ ASTReader::ReadASTBlock(PerFileData &F) { = ASTIdentifierLookupTable::Create( (const unsigned char *)F.IdentifierTableData + Record[0], (const unsigned char *)F.IdentifierTableData, - ASTIdentifierLookupTrait(*this, F.Stream)); + ASTIdentifierLookupTrait(*this, F)); if (PP) PP->getIdentifierTable().setExternalIdentifierLookup(this); } @@ -1863,11 +2147,9 @@ ASTReader::ReadASTBlock(PerFileData &F) { TotalNumMethodPoolEntries += Record[1]; break; - case REFERENCED_SELECTOR_POOL: { - ReferencedSelectorsData.insert(ReferencedSelectorsData.end(), - Record.begin(), Record.end()); + case REFERENCED_SELECTOR_POOL: + F.ReferencedSelectorsData.swap(Record); break; - } case PP_COUNTER_VALUE: if (!Record.empty() && Listener) @@ -1877,28 +2159,26 @@ ASTReader::ReadASTBlock(PerFileData &F) { case SOURCE_LOCATION_OFFSETS: F.SLocOffsets = (const uint32_t *)BlobStart; F.LocalNumSLocEntries = Record[0]; - // We cannot delay this until the entire chain is loaded, because then - // source location preloads would also have to be delayed. - // FIXME: Is there a reason not to do that? - TotalNumSLocEntries += F.LocalNumSLocEntries; - SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]); + F.LocalSLocSize = Record[1]; break; case SOURCE_LOCATION_PRELOADS: - for (unsigned I = 0, N = Record.size(); I != N; ++I) { - ASTReadResult Result = ReadSLocEntryRecord(Record[I]); - if (Result != Success) - return Result; - } + if (PreloadSLocEntries.empty()) + PreloadSLocEntries.swap(Record); + else + PreloadSLocEntries.insert(PreloadSLocEntries.end(), + Record.begin(), Record.end()); break; case STAT_CACHE: { - ASTStatCache *MyStatCache = - new ASTStatCache((const unsigned char *)BlobStart + Record[0], - (const unsigned char *)BlobStart, - NumStatHits, NumStatMisses); - FileMgr.addStatCache(MyStatCache); - F.StatCache = MyStatCache; + if (!DisableStatCache) { + ASTStatCache *MyStatCache = + new ASTStatCache((const unsigned char *)BlobStart + Record[0], + (const unsigned char *)BlobStart, + NumStatHits, NumStatMisses); + FileMgr.addStatCache(MyStatCache); + F.StatCache = MyStatCache; + } break; } @@ -1926,12 +2206,7 @@ ASTReader::ReadASTBlock(PerFileData &F) { break; case PENDING_IMPLICIT_INSTANTIATIONS: - // Optimization for the first block. - if (PendingInstantiations.empty()) - PendingInstantiations.swap(Record); - else - PendingInstantiations.insert(PendingInstantiations.end(), - Record.begin(), Record.end()); + F.PendingInstantiations.swap(Record); break; case SEMA_DECL_REFS: @@ -1947,6 +2222,12 @@ ASTReader::ReadASTBlock(PerFileData &F) { MaybeAddSystemRootToFilename(OriginalFileName); break; + case ORIGINAL_PCH_DIR: + // The primary AST will be the last to get here, so it will be the one + // that's used. + OriginalDir.assign(BlobStart, BlobLen); + break; + case VERSION_CONTROL_BRANCH_REVISION: { const std::string &CurBranch = getClangFullRepositoryVersion(); llvm::StringRef ASTBranch(BlobStart, BlobLen); @@ -1963,6 +2244,17 @@ ASTReader::ReadASTBlock(PerFileData &F) { F.LocalNumMacroDefinitions = Record[1]; break; + case DECL_UPDATE_OFFSETS: { + if (Record.size() % 2 != 0) { + Error("invalid DECL_UPDATE_OFFSETS block in AST file"); + return Failure; + } + for (unsigned I = 0, N = Record.size(); I != N; I += 2) + DeclUpdateOffsets[static_cast<DeclID>(Record[I])] + .push_back(std::make_pair(&F, Record[I+1])); + break; + } + case DECL_REPLACEMENTS: { if (Record.size() % 2 != 0) { Error("invalid DECL_REPLACEMENTS block in AST file"); @@ -1973,13 +2265,57 @@ ASTReader::ReadASTBlock(PerFileData &F) { std::make_pair(&F, Record[I+1]); break; } - - case ADDITIONAL_TEMPLATE_SPECIALIZATIONS: { - AdditionalTemplateSpecializations &ATS = - AdditionalTemplateSpecializationsPending[Record[0]]; - ATS.insert(ATS.end(), Record.begin()+1, Record.end()); + + case CXX_BASE_SPECIFIER_OFFSETS: { + if (F.LocalNumCXXBaseSpecifiers != 0) { + Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file"); + return Failure; + } + + F.LocalNumCXXBaseSpecifiers = Record[0]; + F.CXXBaseSpecifiersOffsets = (const uint32_t *)BlobStart; break; } + + case DIAG_PRAGMA_MAPPINGS: + if (Record.size() % 2 != 0) { + Error("invalid DIAG_USER_MAPPINGS block in AST file"); + return Failure; + } + if (PragmaDiagMappings.empty()) + PragmaDiagMappings.swap(Record); + else + PragmaDiagMappings.insert(PragmaDiagMappings.end(), + Record.begin(), Record.end()); + break; + + case CUDA_SPECIAL_DECL_REFS: + // Later tables overwrite earlier ones. + CUDASpecialDeclRefs.swap(Record); + break; + + case HEADER_SEARCH_TABLE: + F.HeaderFileInfoTableData = BlobStart; + F.LocalNumHeaderFileInfos = Record[1]; + if (Record[0]) { + F.HeaderFileInfoTable + = HeaderFileInfoLookupTable::Create( + (const unsigned char *)F.HeaderFileInfoTableData + Record[0], + (const unsigned char *)F.HeaderFileInfoTableData); + if (PP) + PP->getHeaderSearchInfo().SetExternalSource(this); + } + break; + + case FP_PRAGMA_OPTIONS: + // Later tables overwrite earlier ones. + FPPragmaOptions.swap(Record); + break; + + case OPENCL_EXTENSIONS: + // Later tables overwrite earlier ones. + OpenCLExtensions.swap(Record); + break; } First = false; } @@ -1987,8 +2323,9 @@ ASTReader::ReadASTBlock(PerFileData &F) { return Failure; } -ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) { - switch(ReadASTCore(FileName)) { +ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, + ASTFileType Type) { + switch(ReadASTCore(FileName, Type)) { case Failure: return Failure; case IgnorePCH: return IgnorePCH; case Success: break; @@ -1996,11 +2333,13 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) { // Here comes stuff that we only do once the entire chain is loaded. - // Allocate space for loaded identifiers, decls and types. + // Allocate space for loaded slocentries, identifiers, decls and types. unsigned TotalNumIdentifiers = 0, TotalNumTypes = 0, TotalNumDecls = 0, TotalNumPreallocatedPreprocessingEntities = 0, TotalNumMacroDefs = 0, TotalNumSelectors = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + TotalNumSLocEntries += Chain[I]->LocalNumSLocEntries; + NextSLocOffset += Chain[I]->LocalSLocSize; TotalNumIdentifiers += Chain[I]->LocalNumIdentifiers; TotalNumTypes += Chain[I]->LocalNumTypes; TotalNumDecls += Chain[I]->LocalNumDecls; @@ -2009,6 +2348,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) { TotalNumMacroDefs += Chain[I]->LocalNumMacroDefinitions; TotalNumSelectors += Chain[I]->LocalNumSelectors; } + SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, NextSLocOffset); IdentifiersLoaded.resize(TotalNumIdentifiers); TypesLoaded.resize(TotalNumTypes); DeclsLoaded.resize(TotalNumDecls); @@ -2024,6 +2364,12 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) { } } SelectorsLoaded.resize(TotalNumSelectors); + // Preload SLocEntries. + for (unsigned I = 0, N = PreloadSLocEntries.size(); I != N; ++I) { + ASTReadResult Result = ReadSLocEntryRecord(PreloadSLocEntries[I]); + if (Result != Success) + return Result; + } // Check the predefines buffers. if (!DisableValidation && CheckPredefinesBuffers()) @@ -2058,7 +2404,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) { for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) { IdentifierInfo *II = Identifiers[I]; // Look in the on-disk hash tables for an entry for this identifier - ASTIdentifierLookupTrait Info(*this, Chain[J]->Stream, II); + ASTIdentifierLookupTrait Info(*this, *Chain[J], II); std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength()); ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info); if (Pos == IdTable->end()) @@ -2074,21 +2420,54 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName) { if (Context) InitializeContext(*Context); + if (DeserializationListener) + DeserializationListener->ReaderInitialized(this); + + // If this AST file is a precompiled preamble, then set the main file ID of + // the source manager to the file source file from which the preamble was + // built. This is the only valid way to use a precompiled preamble. + if (Type == Preamble) { + SourceLocation Loc + = SourceMgr.getLocation(FileMgr.getFile(getOriginalSourceFile()), 1, 1); + if (Loc.isValid()) { + std::pair<FileID, unsigned> Decomposed = SourceMgr.getDecomposedLoc(Loc); + SourceMgr.SetPreambleFileID(Decomposed.first); + } + } + return Success; } -ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName) { - Chain.push_back(new PerFileData()); +ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName, + ASTFileType Type) { + PerFileData *Prev = Chain.empty() ? 0 : Chain.back(); + Chain.push_back(new PerFileData(Type)); PerFileData &F = *Chain.back(); + if (Prev) + Prev->NextInSource = &F; + else + FirstInSource = &F; + F.Loaders.push_back(Prev); // Set the AST file name. F.FileName = FileName; + if (FileName != "-") { + CurrentDir = llvm::sys::path::parent_path(FileName); + if (CurrentDir.empty()) CurrentDir = "."; + } + // Open the AST file. // // FIXME: This shouldn't be here, we should just take a raw_ostream. std::string ErrStr; - F.Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr)); + llvm::error_code ec; + if (FileName == "-") { + ec = llvm::MemoryBuffer::getSTDIN(F.Buffer); + if (ec) + ErrStr = ec.message(); + } else + F.Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrStr)); if (!F.Buffer) { Error(ErrStr.c_str()); return IgnorePCH; @@ -2185,6 +2564,18 @@ void ASTReader::InitializeContext(ASTContext &Ctx) { PP->getIdentifierTable().setExternalIdentifierLookup(this); PP->getHeaderSearchInfo().SetExternalLookup(this); PP->setExternalSource(this); + PP->getHeaderSearchInfo().SetExternalSource(this); + + // If we have an update block for the TU waiting, we have to add it before + // deserializing the decl. + DeclContextOffsetsMap::iterator DCU = DeclContextOffsets.find(0); + if (DCU != DeclContextOffsets.end()) { + // Insertion could invalidate map, so grab vector. + DeclContextInfos T; + T.swap(DCU->second); + DeclContextOffsets.erase(DCU); + DeclContextOffsets[Ctx.getTranslationUnitDecl()].swap(T); + } // Load the translation unit declaration GetTranslationUnitDecl(); @@ -2273,17 +2664,27 @@ void ASTReader::InitializeContext(ASTContext &Ctx) { if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED]) Context->setInt128Installed(); + + ReadPragmaDiagnosticMappings(Context->getDiagnostics()); + + // If there were any CUDA special declarations, deserialize them. + if (!CUDASpecialDeclRefs.empty()) { + assert(CUDASpecialDeclRefs.size() == 1 && "More decl refs than expected!"); + Context->setcudaConfigureCallDecl( + cast<FunctionDecl>(GetDecl(CUDASpecialDeclRefs[0]))); + } } /// \brief Retrieve the name of the original source file name /// directly from the AST file, without actually loading the AST /// file. std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName, + FileManager &FileMgr, Diagnostic &Diags) { // Open the AST file. std::string ErrStr; llvm::OwningPtr<llvm::MemoryBuffer> Buffer; - Buffer.reset(llvm::MemoryBuffer::getFile(ASTFileName.c_str(), &ErrStr)); + Buffer.reset(FileMgr.getBufferForFile(ASTFileName, &ErrStr)); if (!Buffer) { Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr; return std::string(); @@ -2390,6 +2791,8 @@ bool ASTReader::ParseLanguageOptions( PARSE_LANGOPT(ObjC2); PARSE_LANGOPT(ObjCNonFragileABI); PARSE_LANGOPT(ObjCNonFragileABI2); + PARSE_LANGOPT(AppleKext); + PARSE_LANGOPT(ObjCDefaultSynthProperties); PARSE_LANGOPT(NoConstantCFStrings); PARSE_LANGOPT(PascalStrings); PARSE_LANGOPT(WritableStrings); @@ -2397,6 +2800,8 @@ bool ASTReader::ParseLanguageOptions( PARSE_LANGOPT(AltiVec); PARSE_LANGOPT(Exceptions); PARSE_LANGOPT(SjLjExceptions); + PARSE_LANGOPT(ObjCExceptions); + PARSE_LANGOPT(MSBitfields); PARSE_LANGOPT(NeXTRuntime); PARSE_LANGOPT(Freestanding); PARSE_LANGOPT(NoBuiltin); @@ -2417,13 +2822,16 @@ bool ASTReader::ParseLanguageOptions( PARSE_LANGOPT(AccessControl); PARSE_LANGOPT(CharIsSigned); PARSE_LANGOPT(ShortWChar); + PARSE_LANGOPT(ShortEnums); LangOpts.setGCMode((LangOptions::GCMode)Record[Idx++]); - LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]); + LangOpts.setVisibilityMode((Visibility)Record[Idx++]); LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode) Record[Idx++]); PARSE_LANGOPT(InstantiationDepth); PARSE_LANGOPT(OpenCL); + PARSE_LANGOPT(CUDA); PARSE_LANGOPT(CatchUndefined); + PARSE_LANGOPT(DefaultFPContract); // FIXME: Missing ElideConstructors?! #undef PARSE_LANGOPT @@ -2434,7 +2842,83 @@ bool ASTReader::ParseLanguageOptions( } void ASTReader::ReadPreprocessedEntities() { - ReadDefinedMacros(); + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + PerFileData &F = *Chain[I]; + if (!F.PreprocessorDetailCursor.getBitStreamReader()) + continue; + + SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor); + F.PreprocessorDetailCursor.JumpToBit(F.PreprocessorDetailStartOffset); + while (LoadPreprocessedEntity(F)) { } + } +} + +PreprocessedEntity *ASTReader::ReadPreprocessedEntityAtOffset(uint64_t Offset) { + PerFileData *F = 0; + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (Offset < Chain[I]->SizeInBits) { + F = Chain[I]; + break; + } + + Offset -= Chain[I]->SizeInBits; + } + + if (!F) { + Error("Malformed preprocessed entity offset"); + return 0; + } + + // Keep track of where we are in the stream, then jump back there + // after reading this entity. + SavedStreamPosition SavedPosition(F->PreprocessorDetailCursor); + F->PreprocessorDetailCursor.JumpToBit(Offset); + return LoadPreprocessedEntity(*F); +} + +HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { + HeaderFileInfoTrait Trait(FE->getName()); + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + PerFileData &F = *Chain[I]; + HeaderFileInfoLookupTable *Table + = static_cast<HeaderFileInfoLookupTable *>(F.HeaderFileInfoTable); + if (!Table) + continue; + + // Look in the on-disk hash table for an entry for this file name. + HeaderFileInfoLookupTable::iterator Pos = Table->find(FE->getName(), + &Trait); + if (Pos == Table->end()) + continue; + + HeaderFileInfo HFI = *Pos; + if (Listener) + Listener->ReadHeaderFileInfo(HFI, FE->getUID()); + + return HFI; + } + + return HeaderFileInfo(); +} + +void ASTReader::ReadPragmaDiagnosticMappings(Diagnostic &Diag) { + unsigned Idx = 0; + while (Idx < PragmaDiagMappings.size()) { + SourceLocation + Loc = SourceLocation::getFromRawEncoding(PragmaDiagMappings[Idx++]); + while (1) { + assert(Idx < PragmaDiagMappings.size() && + "Invalid data, didn't find '-1' marking end of diag/map pairs"); + if (Idx >= PragmaDiagMappings.size()) + break; // Something is messed up but at least avoid infinite loop in + // release build. + unsigned DiagID = PragmaDiagMappings[Idx++]; + if (DiagID == (unsigned)-1) + break; // no more diag/map pairs for this location. + diag::Mapping Map = (diag::Mapping)PragmaDiagMappings[Idx++]; + Diag.setDiagnosticMapping(DiagID, Map, Loc); + } + } } /// \brief Get the correct cursor and offset for loading a type. @@ -2447,7 +2931,7 @@ ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) { Index -= F->LocalNumTypes; } assert(F && F->LocalNumTypes > Index && "Broken chain"); - return RecordLocation(&F->DeclsCursor, F->TypeOffsets[Index]); + return RecordLocation(F, F->TypeOffsets[Index]); } /// \brief Read and return the type with the given index.. @@ -2458,7 +2942,7 @@ ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) { /// IDs. QualType ASTReader::ReadTypeRecord(unsigned Index) { RecordLocation Loc = TypeCursorForIndex(Index); - llvm::BitstreamCursor &DeclsCursor = *Loc.first; + llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor; // Keep track of where we are in the stream, then jump back there // after reading this type. @@ -2469,7 +2953,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { // Note that we are loading a type record. Deserializing AType(this); - DeclsCursor.JumpToBit(Loc.second); + DeclsCursor.JumpToBit(Loc.Offset); RecordData Record; unsigned Code = DeclsCursor.ReadCode(); switch ((TypeCode)DeclsCursor.ReadRecord(Code, Record)) { @@ -2535,6 +3019,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { } QualType PointeeType = GetType(Record[0]); QualType ClassType = GetType(Record[1]); + if (PointeeType.isNull() || ClassType.isNull()) + return QualType(); + return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr()); } @@ -2559,9 +3046,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { QualType ElementType = GetType(Record[0]); ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1]; unsigned IndexTypeQuals = Record[2]; - SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]); - SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]); - return Context->getVariableArrayType(ElementType, ReadExpr(DeclsCursor), + SourceLocation LBLoc = ReadSourceLocation(*Loc.F, Record[3]); + SourceLocation RBLoc = ReadSourceLocation(*Loc.F, Record[4]); + return Context->getVariableArrayType(ElementType, ReadExpr(*Loc.F), ASM, IndexTypeQuals, SourceRange(LBLoc, RBLoc)); } @@ -2574,9 +3061,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { QualType ElementType = GetType(Record[0]); unsigned NumElements = Record[1]; - unsigned AltiVecSpec = Record[2]; + unsigned VecKind = Record[2]; return Context->getVectorType(ElementType, NumElements, - (VectorType::AltiVecSpecific)AltiVecSpec); + (VectorType::VectorKind)VecKind); } case TYPE_EXT_VECTOR: { @@ -2602,28 +3089,30 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { case TYPE_FUNCTION_PROTO: { QualType ResultType = GetType(Record[0]); - bool NoReturn = Record[1]; - unsigned RegParm = Record[2]; - CallingConv CallConv = (CallingConv)Record[3]; + + FunctionProtoType::ExtProtoInfo EPI; + EPI.ExtInfo = FunctionType::ExtInfo(/*noreturn*/ Record[1], + /*regparm*/ Record[2], + static_cast<CallingConv>(Record[3])); + unsigned Idx = 4; unsigned NumParams = Record[Idx++]; llvm::SmallVector<QualType, 16> ParamTypes; for (unsigned I = 0; I != NumParams; ++I) ParamTypes.push_back(GetType(Record[Idx++])); - bool isVariadic = Record[Idx++]; - unsigned Quals = Record[Idx++]; - bool hasExceptionSpec = Record[Idx++]; - bool hasAnyExceptionSpec = Record[Idx++]; - unsigned NumExceptions = Record[Idx++]; + + EPI.Variadic = Record[Idx++]; + EPI.TypeQuals = Record[Idx++]; + EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]); + EPI.HasExceptionSpec = Record[Idx++]; + EPI.HasAnyExceptionSpec = Record[Idx++]; + EPI.NumExceptions = Record[Idx++]; llvm::SmallVector<QualType, 2> Exceptions; - for (unsigned I = 0; I != NumExceptions; ++I) + for (unsigned I = 0; I != EPI.NumExceptions; ++I) Exceptions.push_back(GetType(Record[Idx++])); + EPI.Exceptions = Exceptions.data(); return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams, - isVariadic, Quals, hasExceptionSpec, - hasAnyExceptionSpec, NumExceptions, - Exceptions.data(), - FunctionType::ExtInfo(NoReturn, RegParm, - CallConv)); + EPI); } case TYPE_UNRESOLVED_USING: @@ -2637,11 +3126,13 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { } TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0])); QualType Canonical = GetType(Record[1]); + if (!Canonical.isNull()) + Canonical = Context->getCanonicalType(Canonical); return Context->getTypedefType(Decl, Canonical); } case TYPE_TYPEOF_EXPR: - return Context->getTypeOfExprType(ReadExpr(DeclsCursor)); + return Context->getTypeOfExprType(ReadExpr(*Loc.F)); case TYPE_TYPEOF: { if (Record.size() != 1) { @@ -2653,7 +3144,10 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { } case TYPE_DECLTYPE: - return Context->getDecltypeType(ReadExpr(DeclsCursor)); + return Context->getDecltypeType(ReadExpr(*Loc.F)); + + case TYPE_AUTO: + return Context->getAutoType(GetType(Record[0])); case TYPE_RECORD: { if (Record.size() != 2) { @@ -2662,7 +3156,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { } bool IsDependent = Record[0]; QualType T = Context->getRecordType(cast<RecordDecl>(GetDecl(Record[1]))); - T->Dependent = IsDependent; + const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent); return T; } @@ -2673,10 +3167,44 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { } bool IsDependent = Record[0]; QualType T = Context->getEnumType(cast<EnumDecl>(GetDecl(Record[1]))); - T->Dependent = IsDependent; + const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent); return T; } + case TYPE_ATTRIBUTED: { + if (Record.size() != 3) { + Error("incorrect encoding of attributed type"); + return QualType(); + } + QualType modifiedType = GetType(Record[0]); + QualType equivalentType = GetType(Record[1]); + AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record[2]); + return Context->getAttributedType(kind, modifiedType, equivalentType); + } + + case TYPE_PAREN: { + if (Record.size() != 1) { + Error("incorrect encoding of paren type"); + return QualType(); + } + QualType InnerType = GetType(Record[0]); + return Context->getParenType(InnerType); + } + + case TYPE_PACK_EXPANSION: { + if (Record.size() != 2) { + Error("incorrect encoding of pack expansion type"); + return QualType(); + } + QualType Pattern = GetType(Record[0]); + if (Pattern.isNull()) + return QualType(); + llvm::Optional<unsigned> NumExpansions; + if (Record[1]) + NumExpansions = Record[1] - 1; + return Context->getPackExpansionType(Pattern, NumExpansions); + } + case TYPE_ELABORATED: { unsigned Idx = 0; ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++]; @@ -2698,7 +3226,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { llvm::SmallVector<ObjCProtocolDecl*, 4> Protos; for (unsigned I = 0; I != NumProtos; ++I) Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++]))); - return Context->getObjCObjectType(Base, Protos.data(), NumProtos); + return Context->getObjCObjectType(Base, Protos.data(), NumProtos); } case TYPE_OBJC_OBJECT_POINTER: { @@ -2716,6 +3244,15 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { Replacement); } + case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: { + unsigned Idx = 0; + QualType Parm = GetType(Record[Idx++]); + TemplateArgument ArgPack = ReadTemplateArgument(*Loc.F, Record, Idx); + return Context->getSubstTemplateTypeParmPackType( + cast<TemplateTypeParmType>(Parm), + ArgPack); + } + case TYPE_INJECTED_CLASS_NAME: { CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0])); QualType TST = GetType(Record[1]); // probably derivable @@ -2724,7 +3261,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { return QualType(new (*Context, TypeAlignment) InjectedClassNameType(D, TST), 0); } - + case TYPE_TEMPLATE_TYPE_PARM: { unsigned Idx = 0; unsigned Depth = Record[Idx++]; @@ -2733,16 +3270,18 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { IdentifierInfo *Name = GetIdentifierInfo(Record, Idx); return Context->getTemplateTypeParmType(Depth, Index, Pack, Name); } - + case TYPE_DEPENDENT_NAME: { unsigned Idx = 0; ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++]; NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx); const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx); QualType Canon = GetType(Record[Idx++]); + if (!Canon.isNull()) + Canon = Context->getCanonicalType(Canon); return Context->getDependentNameType(Keyword, NNS, Name, Canon); } - + case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: { unsigned Idx = 0; ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++]; @@ -2752,11 +3291,11 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { llvm::SmallVector<TemplateArgument, 8> Args; Args.reserve(NumArgs); while (NumArgs--) - Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx)); + Args.push_back(ReadTemplateArgument(*Loc.F, Record, Idx)); return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name, Args.size(), Args.data()); } - + case TYPE_DEPENDENT_SIZED_ARRAY: { unsigned Idx = 0; @@ -2767,8 +3306,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { unsigned IndexTypeQuals = Record[Idx++]; // DependentSizedArrayType - Expr *NumElts = ReadExpr(DeclsCursor); - SourceRange Brackets = ReadSourceRange(Record, Idx); + Expr *NumElts = ReadExpr(*Loc.F); + SourceRange Brackets = ReadSourceRange(*Loc.F, Record, Idx); return Context->getDependentSizedArrayType(ElementType, NumElts, ASM, IndexTypeQuals, Brackets); @@ -2777,9 +3316,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { case TYPE_TEMPLATE_SPECIALIZATION: { unsigned Idx = 0; bool IsDependent = Record[Idx++]; - TemplateName Name = ReadTemplateName(Record, Idx); + TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx); llvm::SmallVector<TemplateArgument, 8> Args; - ReadTemplateArgumentList(Args, DeclsCursor, Record, Idx); + ReadTemplateArgumentList(Args, *Loc.F, Record, Idx); QualType Canon = GetType(Record[Idx++]); QualType T; if (Canon.isNull()) @@ -2788,7 +3327,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { else T = Context->getTemplateSpecializationType(Name, Args.data(), Args.size(), Canon); - T->Dependent = IsDependent; + const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent); return T; } } @@ -2796,18 +3335,23 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { return QualType(); } -namespace { - -class TypeLocReader : public TypeLocVisitor<TypeLocReader> { +class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> { ASTReader &Reader; + ASTReader::PerFileData &F; llvm::BitstreamCursor &DeclsCursor; const ASTReader::RecordData &Record; unsigned &Idx; + SourceLocation ReadSourceLocation(const ASTReader::RecordData &R, + unsigned &I) { + return Reader.ReadSourceLocation(F, R, I); + } + public: - TypeLocReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor, + TypeLocReader(ASTReader &Reader, ASTReader::PerFileData &F, const ASTReader::RecordData &Record, unsigned &Idx) - : Reader(Reader), DeclsCursor(Cursor), Record(Record), Idx(Idx) { } + : Reader(Reader), F(F), DeclsCursor(F.DeclsCursor), Record(Record), Idx(Idx) + { } // We want compile-time assurance that we've enumerated all of // these, so unfortunately we have to declare them first, then @@ -2821,13 +3365,11 @@ public: void VisitArrayTypeLoc(ArrayTypeLoc); }; -} - void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { // nothing to do } void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { - TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setBuiltinLoc(ReadSourceLocation(Record, Idx)); if (TL.needsExtraLocalData()) { TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++])); TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++])); @@ -2836,28 +3378,28 @@ void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { } } void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) { - TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setStarLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { - TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setCaretLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { - TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setAmpLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { - TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setAmpAmpLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { - TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setStarLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) { - TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setLBracketLoc(ReadSourceLocation(Record, Idx)); + TL.setRBracketLoc(ReadSourceLocation(Record, Idx)); if (Record[Idx++]) - TL.setSizeExpr(Reader.ReadExpr(DeclsCursor)); + TL.setSizeExpr(Reader.ReadExpr(F)); else TL.setSizeExpr(0); } @@ -2876,17 +3418,18 @@ void TypeLocReader::VisitDependentSizedArrayTypeLoc( } void TypeLocReader::VisitDependentSizedExtVectorTypeLoc( DependentSizedExtVectorTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) { - TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setLParenLoc(ReadSourceLocation(Record, Idx)); + TL.setRParenLoc(ReadSourceLocation(Record, Idx)); + TL.setTrailingReturn(Record[Idx++]); for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) { TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++]))); } @@ -2898,87 +3441,119 @@ void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { VisitFunctionTypeLoc(TL); } void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { - TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setTypeofLoc(ReadSourceLocation(Record, Idx)); + TL.setLParenLoc(ReadSourceLocation(Record, Idx)); + TL.setRParenLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { - TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); + TL.setTypeofLoc(ReadSourceLocation(Record, Idx)); + TL.setLParenLoc(ReadSourceLocation(Record, Idx)); + TL.setRParenLoc(ReadSourceLocation(Record, Idx)); + TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx)); } void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); +} +void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) { + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); +} +void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) { + TL.setAttrNameLoc(ReadSourceLocation(Record, Idx)); + if (TL.hasAttrOperand()) { + SourceRange range; + range.setBegin(ReadSourceLocation(Record, Idx)); + range.setEnd(ReadSourceLocation(Record, Idx)); + TL.setAttrOperandParensRange(range); + } + if (TL.hasAttrExprOperand()) { + if (Record[Idx++]) + TL.setAttrExprOperand(Reader.ReadExpr(F)); + else + TL.setAttrExprOperand(0); + } else if (TL.hasAttrEnumOperand()) + TL.setAttrEnumOperandLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc( SubstTemplateTypeParmTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); +} +void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc( + SubstTemplateTypeParmPackTypeLoc TL) { + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TL) { - TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setTemplateNameLoc(ReadSourceLocation(Record, Idx)); + TL.setLAngleLoc(ReadSourceLocation(Record, Idx)); + TL.setRAngleLoc(ReadSourceLocation(Record, Idx)); for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) TL.setArgLocInfo(i, - Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(), - DeclsCursor, Record, Idx)); + Reader.GetTemplateArgumentLocInfo(F, + TL.getTypePtr()->getArg(i).getKind(), + Record, Idx)); +} +void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) { + TL.setLParenLoc(ReadSourceLocation(Record, Idx)); + TL.setRParenLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx)); + TL.setKeywordLoc(ReadSourceLocation(Record, Idx)); + TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx)); } void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { - TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx)); - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setKeywordLoc(ReadSourceLocation(Record, Idx)); + TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx)); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc TL) { - TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx)); - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setKeywordLoc(ReadSourceLocation(Record, Idx)); + TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx)); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); + TL.setLAngleLoc(ReadSourceLocation(Record, Idx)); + TL.setRAngleLoc(ReadSourceLocation(Record, Idx)); for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) TL.setArgLocInfo(I, - Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(), - DeclsCursor, Record, Idx)); + Reader.GetTemplateArgumentLocInfo(F, + TL.getTypePtr()->getArg(I).getKind(), + Record, Idx)); +} +void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { + TL.setEllipsisLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { TL.setHasBaseTypeAsWritten(Record[Idx++]); - TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setLAngleLoc(ReadSourceLocation(Record, Idx)); + TL.setRAngleLoc(ReadSourceLocation(Record, Idx)); for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) - TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { - TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setStarLoc(ReadSourceLocation(Record, Idx)); } -TypeSourceInfo *ASTReader::GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor, +TypeSourceInfo *ASTReader::GetTypeSourceInfo(PerFileData &F, const RecordData &Record, unsigned &Idx) { QualType InfoTy = GetType(Record[Idx++]); @@ -2986,7 +3561,7 @@ TypeSourceInfo *ASTReader::GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor, return 0; TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy); - TypeLocReader TLR(*this, DeclsCursor, Record, Idx); + TypeLocReader TLR(*this, F, Record, Idx); for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) TLR.Visit(TL); return TInfo; @@ -3043,6 +3618,9 @@ QualType ASTReader::GetType(TypeID ID) { assert(Index < TypesLoaded.size() && "Type index out-of-range"); if (TypesLoaded[Index].isNull()) { TypesLoaded[Index] = ReadTypeRecord(Index); + if (TypesLoaded[Index].isNull()) + return QualType(); + TypesLoaded[Index]->setFromAST(); TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID); if (DeserializationListener) @@ -3074,20 +3652,36 @@ TypeIdx ASTReader::GetTypeIdx(QualType T) const { return I->second; } +unsigned ASTReader::getTotalNumCXXBaseSpecifiers() const { + unsigned Result = 0; + for (unsigned I = 0, N = Chain.size(); I != N; ++I) + Result += Chain[I]->LocalNumCXXBaseSpecifiers; + + return Result; +} + TemplateArgumentLocInfo -ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, - llvm::BitstreamCursor &DeclsCursor, +ASTReader::GetTemplateArgumentLocInfo(PerFileData &F, + TemplateArgument::ArgKind Kind, const RecordData &Record, unsigned &Index) { switch (Kind) { case TemplateArgument::Expression: - return ReadExpr(DeclsCursor); + return ReadExpr(F); case TemplateArgument::Type: - return GetTypeSourceInfo(DeclsCursor, Record, Index); + return GetTypeSourceInfo(F, Record, Index); case TemplateArgument::Template: { - SourceRange QualifierRange = ReadSourceRange(Record, Index); - SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index); - return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc); + SourceRange QualifierRange = ReadSourceRange(F, Record, Index); + SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index); + return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc, + SourceLocation()); + } + case TemplateArgument::TemplateExpansion: { + SourceRange QualifierRange = ReadSourceRange(F, Record, Index); + SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index); + SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index); + return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc, + EllipsisLoc); } case TemplateArgument::Null: case TemplateArgument::Integral: @@ -3100,16 +3694,15 @@ ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, } TemplateArgumentLoc -ASTReader::ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor, +ASTReader::ReadTemplateArgumentLoc(PerFileData &F, const RecordData &Record, unsigned &Index) { - TemplateArgument Arg = ReadTemplateArgument(DeclsCursor, Record, Index); + TemplateArgument Arg = ReadTemplateArgument(F, Record, Index); if (Arg.getKind() == TemplateArgument::Expression) { if (Record[Index++]) // bool InfoHasSameExpr. return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr())); } - return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(), - DeclsCursor, + return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(F, Arg.getKind(), Record, Index)); } @@ -3117,6 +3710,63 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) { return GetDecl(ID); } +uint64_t +ASTReader::GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID) { + if (ID == 0) + return 0; + + --ID; + uint64_t Offset = 0; + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (ID < Chain[I]->LocalNumCXXBaseSpecifiers) + return Offset + Chain[I]->CXXBaseSpecifiersOffsets[ID]; + + ID -= Chain[I]->LocalNumCXXBaseSpecifiers; + Offset += Chain[I]->SizeInBits; + } + + assert(false && "CXXBaseSpecifiers not found"); + return 0; +} + +CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { + // Figure out which AST file contains this offset. + PerFileData *F = 0; + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (Offset < Chain[I]->SizeInBits) { + F = Chain[I]; + break; + } + + Offset -= Chain[I]->SizeInBits; + } + + if (!F) { + Error("Malformed AST file: C++ base specifiers at impossible offset"); + return 0; + } + + llvm::BitstreamCursor &Cursor = F->DeclsCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(Offset); + ReadingKindTracker ReadingKind(Read_Decl, *this); + RecordData Record; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.ReadRecord(Code, Record); + if (RecCode != DECL_CXX_BASE_SPECIFIERS) { + Error("Malformed AST file: missing C++ base specifiers"); + return 0; + } + + unsigned Idx = 0; + unsigned NumBases = Record[Idx++]; + void *Mem = Context->Allocate(sizeof(CXXBaseSpecifier) * NumBases); + CXXBaseSpecifier *Bases = new (Mem) CXXBaseSpecifier [NumBases]; + for (unsigned I = 0; I != NumBases; ++I) + Bases[I] = ReadCXXBaseSpecifier(*F, Record, Idx); + return Bases; +} + TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() { if (!DeclsLoaded[0]) { ReadDeclRecord(0, 1); @@ -3152,6 +3802,9 @@ Decl *ASTReader::GetDecl(DeclID ID) { /// source each time it is called, and is meant to be used via a /// LazyOffsetPtr (which is used by Decls for the body of functions, etc). Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) { + // Switch case IDs are per Decl. + ClearSwitchCaseIDs(); + // Offset here is a global offset across the entire chain. for (unsigned I = 0, N = Chain.size(); I != N; ++I) { PerFileData &F = *Chain[N - I - 1]; @@ -3159,7 +3812,7 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) { // Since we know that this statement is part of a decl, make sure to use // the decl cursor to read it. F.DeclsCursor.JumpToBit(Offset); - return ReadStmtFromStream(F.DeclsCursor); + return ReadStmtFromStream(F); } Offset -= F.SizeInBits; } @@ -3167,13 +3820,16 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) { } bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC, + bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl<Decl*> &Decls) { assert(DC->hasExternalLexicalStorage() && "DeclContext has no lexical decls in storage"); // There might be lexical decls in multiple parts of the chain, for the TU // at least. - DeclContextInfos &Infos = DeclContextOffsets[DC]; + // DeclContextOffsets might reallocate as we load additional decls below, + // so make a copy of the vector. + DeclContextInfos Infos = DeclContextOffsets[DC]; for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end(); I != E; ++I) { // IDs can be 0 if this context doesn't contain declarations. @@ -3181,10 +3837,15 @@ bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC, continue; // Load all of the declaration IDs - for (const DeclID *ID = I->LexicalDecls, - *IDE = ID + I->NumLexicalDecls; - ID != IDE; ++ID) - Decls.push_back(GetDecl(*ID)); + for (const KindDeclIDPair *ID = I->LexicalDecls, + *IDE = ID + I->NumLexicalDecls; ID != IDE; ++ID) { + if (isKindWeWant && !isKindWeWant((Decl::Kind)ID->first)) + continue; + + Decl *D = GetDecl(ID->second); + assert(D && "Null decl in lexical decls"); + Decls.push_back(D); + } } ++NumLexicalDeclContextsRead; @@ -3355,11 +4016,11 @@ void ASTReader::InitializeSema(Sema &S) { // Makes sure any declarations that were deserialized "too early" // still get added to the identifier's declaration chains. - if (SemaObj->TUScope) { - for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) { + for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) { + if (SemaObj->TUScope) SemaObj->TUScope->AddDecl(PreloadedDecls[I]); - SemaObj->IdResolver.AddDecl(PreloadedDecls[I]); - } + + SemaObj->IdResolver.AddDecl(PreloadedDecls[I]); } PreloadedDecls.clear(); @@ -3377,21 +4038,6 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->UnusedFileScopedDecls.push_back(D); } - // If there were any weak undeclared identifiers, deserialize them and add to - // Sema's list of weak undeclared identifiers. - if (!WeakUndeclaredIdentifiers.empty()) { - unsigned Idx = 0; - for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) { - IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx); - IdentifierInfo *AliasId=GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx); - SourceLocation Loc = ReadSourceLocation(WeakUndeclaredIdentifiers, Idx); - bool Used = WeakUndeclaredIdentifiers[Idx++]; - Sema::WeakInfo WI(AliasId, Loc); - WI.setUsed(Used); - SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI)); - } - } - // If there were any locally-scoped external declarations, // deserialize them and add them to Sema's table of locally-scoped // external declarations. @@ -3409,34 +4055,12 @@ void ASTReader::InitializeSema(Sema &S) { // FIXME: Do VTable uses and dynamic classes deserialize too much ? // Can we cut them down before writing them ? - // If there were any VTable uses, deserialize the information and add it - // to Sema's vector and map of VTable uses. - if (!VTableUses.empty()) { - unsigned Idx = 0; - for (unsigned I = 0, N = VTableUses[Idx++]; I != N; ++I) { - CXXRecordDecl *Class = cast<CXXRecordDecl>(GetDecl(VTableUses[Idx++])); - SourceLocation Loc = ReadSourceLocation(VTableUses, Idx); - bool DefinitionRequired = VTableUses[Idx++]; - SemaObj->VTableUses.push_back(std::make_pair(Class, Loc)); - SemaObj->VTablesUsed[Class] = DefinitionRequired; - } - } - // If there were any dynamic classes declarations, deserialize them // and add them to Sema's vector of such declarations. for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) SemaObj->DynamicClasses.push_back( cast<CXXRecordDecl>(GetDecl(DynamicClasses[I]))); - // If there were any pending implicit instantiations, deserialize them - // and add them to Sema's queue of such instantiations. - assert(PendingInstantiations.size() % 2 == 0 && "Expected pairs of entries"); - for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) { - ValueDecl *D=cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++])); - SourceLocation Loc = ReadSourceLocation(PendingInstantiations, Idx); - SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc)); - } - // Load the offsets of the declarations that Sema references. // They will be lazily deserialized when needed. if (!SemaDeclRefs.empty()) { @@ -3445,18 +4069,76 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->StdBadAlloc = SemaDeclRefs[1]; } - // If there are @selector references added them to its pool. This is for - // implementation of -Wselector. - if (!ReferencedSelectorsData.empty()) { - unsigned int DataSize = ReferencedSelectorsData.size()-1; - unsigned I = 0; - while (I < DataSize) { - Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]); - SourceLocation SelLoc = - SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]); - SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc)); + for (PerFileData *F = FirstInSource; F; F = F->NextInSource) { + + // If there are @selector references added them to its pool. This is for + // implementation of -Wselector. + if (!F->ReferencedSelectorsData.empty()) { + unsigned int DataSize = F->ReferencedSelectorsData.size()-1; + unsigned I = 0; + while (I < DataSize) { + Selector Sel = DecodeSelector(F->ReferencedSelectorsData[I++]); + SourceLocation SelLoc = ReadSourceLocation( + *F, F->ReferencedSelectorsData, I); + SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc)); + } + } + + // If there were any pending implicit instantiations, deserialize them + // and add them to Sema's queue of such instantiations. + assert(F->PendingInstantiations.size() % 2 == 0 && + "Expected pairs of entries"); + for (unsigned Idx = 0, N = F->PendingInstantiations.size(); Idx < N;) { + ValueDecl *D=cast<ValueDecl>(GetDecl(F->PendingInstantiations[Idx++])); + SourceLocation Loc = ReadSourceLocation(*F, F->PendingInstantiations,Idx); + SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc)); + } + } + + // The two special data sets below always come from the most recent PCH, + // which is at the front of the chain. + PerFileData &F = *Chain.front(); + + // If there were any weak undeclared identifiers, deserialize them and add to + // Sema's list of weak undeclared identifiers. + if (!WeakUndeclaredIdentifiers.empty()) { + unsigned Idx = 0; + for (unsigned I = 0, N = WeakUndeclaredIdentifiers[Idx++]; I != N; ++I) { + IdentifierInfo *WeakId = GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx); + IdentifierInfo *AliasId= GetIdentifierInfo(WeakUndeclaredIdentifiers,Idx); + SourceLocation Loc = ReadSourceLocation(F, WeakUndeclaredIdentifiers,Idx); + bool Used = WeakUndeclaredIdentifiers[Idx++]; + Sema::WeakInfo WI(AliasId, Loc); + WI.setUsed(Used); + SemaObj->WeakUndeclaredIdentifiers.insert(std::make_pair(WeakId, WI)); + } + } + + // If there were any VTable uses, deserialize the information and add it + // to Sema's vector and map of VTable uses. + if (!VTableUses.empty()) { + unsigned Idx = 0; + for (unsigned I = 0, N = VTableUses[Idx++]; I != N; ++I) { + CXXRecordDecl *Class = cast<CXXRecordDecl>(GetDecl(VTableUses[Idx++])); + SourceLocation Loc = ReadSourceLocation(F, VTableUses, Idx); + bool DefinitionRequired = VTableUses[Idx++]; + SemaObj->VTableUses.push_back(std::make_pair(Class, Loc)); + SemaObj->VTablesUsed[Class] = DefinitionRequired; } } + + if (!FPPragmaOptions.empty()) { + assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS"); + SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0]; + } + + if (!OpenCLExtensions.empty()) { + unsigned I = 0; +#define OPENCLEXT(nm) SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++]; +#include "clang/Basic/OpenCLExtensions.def" + + assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS"); + } } IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) { @@ -3480,6 +4162,64 @@ IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) { return 0; } +namespace clang { + /// \brief An identifier-lookup iterator that enumerates all of the + /// identifiers stored within a set of AST files. + class ASTIdentifierIterator : public IdentifierIterator { + /// \brief The AST reader whose identifiers are being enumerated. + const ASTReader &Reader; + + /// \brief The current index into the chain of AST files stored in + /// the AST reader. + unsigned Index; + + /// \brief The current position within the identifier lookup table + /// of the current AST file. + ASTIdentifierLookupTable::key_iterator Current; + + /// \brief The end position within the identifier lookup table of + /// the current AST file. + ASTIdentifierLookupTable::key_iterator End; + + public: + explicit ASTIdentifierIterator(const ASTReader &Reader); + + virtual llvm::StringRef Next(); + }; +} + +ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader) + : Reader(Reader), Index(Reader.Chain.size() - 1) { + ASTIdentifierLookupTable *IdTable + = (ASTIdentifierLookupTable *)Reader.Chain[Index]->IdentifierLookupTable; + Current = IdTable->key_begin(); + End = IdTable->key_end(); +} + +llvm::StringRef ASTIdentifierIterator::Next() { + while (Current == End) { + // If we have exhausted all of our AST files, we're done. + if (Index == 0) + return llvm::StringRef(); + + --Index; + ASTIdentifierLookupTable *IdTable + = (ASTIdentifierLookupTable *)Reader.Chain[Index]->IdentifierLookupTable; + Current = IdTable->key_begin(); + End = IdTable->key_end(); + } + + // We have any identifiers remaining in the current AST file; return + // the next one. + std::pair<const char*, unsigned> Key = *Current; + ++Current; + return llvm::StringRef(Key.first, Key.second); +} + +IdentifierIterator *ASTReader::getIdentifiers() const { + return new ASTIdentifierIterator(*this); +} + std::pair<ObjCMethodList, ObjCMethodList> ASTReader::ReadMethodPool(Selector Sel) { // Find this selector in a hash table. We want to find the most recent entry. @@ -3545,8 +4285,7 @@ ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II, PendingIdentifierInfos.push_back(PendingIdentifierInfo()); PendingIdentifierInfo &PII = PendingIdentifierInfos.back(); PII.II = II; - for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) - PII.DeclIDs.push_back(DeclIDs[I]); + PII.DeclIDs.append(DeclIDs.begin(), DeclIDs.end()); return; } @@ -3558,8 +4297,8 @@ ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II, // and add it to the declaration chain for this identifier, so // that (unqualified) name lookup will find it. SemaObj->TUScope->AddDecl(D); - SemaObj->IdResolver.AddDeclToIdentifierChain(II, D); } + SemaObj->IdResolver.AddDeclToIdentifierChain(II, D); } else { // Queue this declaration so that it will be added to the // translation unit scope and identifier's declaration chain @@ -3644,7 +4383,7 @@ Selector ASTReader::DecodeSelector(unsigned ID) { return SelectorsLoaded[ID - 1]; } -Selector ASTReader::GetExternalSelector(uint32_t ID) { +Selector ASTReader::GetExternalSelector(uint32_t ID) { return DecodeSelector(ID); } @@ -3693,9 +4432,65 @@ ASTReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) { return DeclarationName(); } +void ASTReader::ReadDeclarationNameLoc(PerFileData &F, + DeclarationNameLoc &DNLoc, + DeclarationName Name, + const RecordData &Record, unsigned &Idx) { + switch (Name.getNameKind()) { + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + DNLoc.NamedType.TInfo = GetTypeSourceInfo(F, Record, Idx); + break; + + case DeclarationName::CXXOperatorName: + DNLoc.CXXOperatorName.BeginOpNameLoc + = ReadSourceLocation(F, Record, Idx).getRawEncoding(); + DNLoc.CXXOperatorName.EndOpNameLoc + = ReadSourceLocation(F, Record, Idx).getRawEncoding(); + break; + + case DeclarationName::CXXLiteralOperatorName: + DNLoc.CXXLiteralOperatorName.OpNameLoc + = ReadSourceLocation(F, Record, Idx).getRawEncoding(); + break; + + case DeclarationName::Identifier: + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + case DeclarationName::CXXUsingDirective: + break; + } +} + +void ASTReader::ReadDeclarationNameInfo(PerFileData &F, + DeclarationNameInfo &NameInfo, + const RecordData &Record, unsigned &Idx) { + NameInfo.setName(ReadDeclarationName(Record, Idx)); + NameInfo.setLoc(ReadSourceLocation(F, Record, Idx)); + DeclarationNameLoc DNLoc; + ReadDeclarationNameLoc(F, DNLoc, NameInfo.getName(), Record, Idx); + NameInfo.setInfo(DNLoc); +} + +void ASTReader::ReadQualifierInfo(PerFileData &F, QualifierInfo &Info, + const RecordData &Record, unsigned &Idx) { + Info.NNS = ReadNestedNameSpecifier(Record, Idx); + Info.NNSRange = ReadSourceRange(F, Record, Idx); + unsigned NumTPLists = Record[Idx++]; + Info.NumTemplParamLists = NumTPLists; + if (NumTPLists) { + Info.TemplParamLists = new (*Context) TemplateParameterList*[NumTPLists]; + for (unsigned i=0; i != NumTPLists; ++i) + Info.TemplParamLists[i] = ReadTemplateParameterList(F, Record, Idx); + } +} + TemplateName -ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) { - TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++]; +ASTReader::ReadTemplateName(PerFileData &F, const RecordData &Record, + unsigned &Idx) { + TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++]; switch (Kind) { case TemplateName::Template: return TemplateName(cast_or_null<TemplateDecl>(GetDecl(Record[Idx++]))); @@ -3708,14 +4503,14 @@ ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) { return Context->getOverloadedTemplateName(Decls.begin(), Decls.end()); } - + case TemplateName::QualifiedTemplate: { NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx); bool hasTemplKeyword = Record[Idx++]; TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++])); return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template); } - + case TemplateName::DependentTemplate: { NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx); if (Record[Idx++]) // isIdentifier @@ -3724,16 +4519,30 @@ ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) { return Context->getDependentTemplateName(NNS, (OverloadedOperatorKind)Record[Idx++]); } + + case TemplateName::SubstTemplateTemplateParmPack: { + TemplateTemplateParmDecl *Param + = cast_or_null<TemplateTemplateParmDecl>(GetDecl(Record[Idx++])); + if (!Param) + return TemplateName(); + + TemplateArgument ArgPack = ReadTemplateArgument(F, Record, Idx); + if (ArgPack.getKind() != TemplateArgument::Pack) + return TemplateName(); + + return Context->getSubstTemplateTemplateParmPack(Param, ArgPack); + } } - + assert(0 && "Unhandled template name kind!"); return TemplateName(); } TemplateArgument -ASTReader::ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor, +ASTReader::ReadTemplateArgument(PerFileData &F, const RecordData &Record, unsigned &Idx) { - switch ((TemplateArgument::ArgKind)Record[Idx++]) { + TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++]; + switch (Kind) { case TemplateArgument::Null: return TemplateArgument(); case TemplateArgument::Type: @@ -3745,39 +4554,44 @@ ASTReader::ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor, QualType T = GetType(Record[Idx++]); return TemplateArgument(Value, T); } - case TemplateArgument::Template: - return TemplateArgument(ReadTemplateName(Record, Idx)); + case TemplateArgument::Template: + return TemplateArgument(ReadTemplateName(F, Record, Idx)); + case TemplateArgument::TemplateExpansion: { + TemplateName Name = ReadTemplateName(F, Record, Idx); + llvm::Optional<unsigned> NumTemplateExpansions; + if (unsigned NumExpansions = Record[Idx++]) + NumTemplateExpansions = NumExpansions - 1; + return TemplateArgument(Name, NumTemplateExpansions); + } case TemplateArgument::Expression: - return TemplateArgument(ReadExpr(DeclsCursor)); + return TemplateArgument(ReadExpr(F)); case TemplateArgument::Pack: { unsigned NumArgs = Record[Idx++]; - llvm::SmallVector<TemplateArgument, 8> Args; - Args.reserve(NumArgs); - while (NumArgs--) - Args.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx)); - TemplateArgument TemplArg; - TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true); - return TemplArg; + TemplateArgument *Args = new (*Context) TemplateArgument[NumArgs]; + for (unsigned I = 0; I != NumArgs; ++I) + Args[I] = ReadTemplateArgument(F, Record, Idx); + return TemplateArgument(Args, NumArgs); } } - + assert(0 && "Unhandled template argument kind!"); return TemplateArgument(); } TemplateParameterList * -ASTReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) { - SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx); - SourceLocation LAngleLoc = ReadSourceLocation(Record, Idx); - SourceLocation RAngleLoc = ReadSourceLocation(Record, Idx); +ASTReader::ReadTemplateParameterList(PerFileData &F, + const RecordData &Record, unsigned &Idx) { + SourceLocation TemplateLoc = ReadSourceLocation(F, Record, Idx); + SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Idx); + SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Idx); unsigned NumParams = Record[Idx++]; llvm::SmallVector<NamedDecl *, 16> Params; Params.reserve(NumParams); while (NumParams--) Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++]))); - - TemplateParameterList* TemplateParams = + + TemplateParameterList* TemplateParams = TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc, Params.data(), Params.size(), RAngleLoc); return TemplateParams; @@ -3786,12 +4600,12 @@ ASTReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) { void ASTReader:: ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs, - llvm::BitstreamCursor &DeclsCursor, - const RecordData &Record, unsigned &Idx) { + PerFileData &F, const RecordData &Record, + unsigned &Idx) { unsigned NumTemplateArgs = Record[Idx++]; TemplArgs.reserve(NumTemplateArgs); while (NumTemplateArgs--) - TemplArgs.push_back(ReadTemplateArgument(DeclsCursor, Record, Idx)); + TemplArgs.push_back(ReadTemplateArgument(F, Record, Idx)); } /// \brief Read a UnresolvedSet structure. @@ -3806,45 +4620,52 @@ void ASTReader::ReadUnresolvedSet(UnresolvedSetImpl &Set, } CXXBaseSpecifier -ASTReader::ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor, +ASTReader::ReadCXXBaseSpecifier(PerFileData &F, const RecordData &Record, unsigned &Idx) { bool isVirtual = static_cast<bool>(Record[Idx++]); bool isBaseOfClass = static_cast<bool>(Record[Idx++]); AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]); - TypeSourceInfo *TInfo = GetTypeSourceInfo(DeclsCursor, Record, Idx); - SourceRange Range = ReadSourceRange(Record, Idx); - return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, TInfo); + bool inheritConstructors = static_cast<bool>(Record[Idx++]); + TypeSourceInfo *TInfo = GetTypeSourceInfo(F, Record, Idx); + SourceRange Range = ReadSourceRange(F, Record, Idx); + SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Idx); + CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo, + EllipsisLoc); + Result.setInheritConstructors(inheritConstructors); + return Result; } -std::pair<CXXBaseOrMemberInitializer **, unsigned> -ASTReader::ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &Cursor, - const RecordData &Record, - unsigned &Idx) { - CXXBaseOrMemberInitializer **BaseOrMemberInitializers = 0; +std::pair<CXXCtorInitializer **, unsigned> +ASTReader::ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record, + unsigned &Idx) { + CXXCtorInitializer **CtorInitializers = 0; unsigned NumInitializers = Record[Idx++]; if (NumInitializers) { ASTContext &C = *getContext(); - BaseOrMemberInitializers - = new (C) CXXBaseOrMemberInitializer*[NumInitializers]; + CtorInitializers + = new (C) CXXCtorInitializer*[NumInitializers]; for (unsigned i=0; i != NumInitializers; ++i) { TypeSourceInfo *BaseClassInfo = 0; bool IsBaseVirtual = false; FieldDecl *Member = 0; - + IndirectFieldDecl *IndirectMember = 0; + bool IsBaseInitializer = Record[Idx++]; if (IsBaseInitializer) { - BaseClassInfo = GetTypeSourceInfo(Cursor, Record, Idx); + BaseClassInfo = GetTypeSourceInfo(F, Record, Idx); IsBaseVirtual = Record[Idx++]; } else { - Member = cast<FieldDecl>(GetDecl(Record[Idx++])); + bool IsIndirectMemberInitializer = Record[Idx++]; + if (IsIndirectMemberInitializer) + IndirectMember = cast<IndirectFieldDecl>(GetDecl(Record[Idx++])); + else + Member = cast<FieldDecl>(GetDecl(Record[Idx++])); } - SourceLocation MemberLoc = ReadSourceLocation(Record, Idx); - Expr *Init = ReadExpr(Cursor); - FieldDecl *AnonUnionMember - = cast_or_null<FieldDecl>(GetDecl(Record[Idx++])); - SourceLocation LParenLoc = ReadSourceLocation(Record, Idx); - SourceLocation RParenLoc = ReadSourceLocation(Record, Idx); + SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx); + Expr *Init = ReadExpr(F); + SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx); + SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx); bool IsWritten = Record[Idx++]; unsigned SourceOrderOrNumArrayIndices; llvm::SmallVector<VarDecl *, 8> Indices; @@ -3856,28 +4677,33 @@ ASTReader::ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &Cursor, for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i) Indices.push_back(cast<VarDecl>(GetDecl(Record[Idx++]))); } - - CXXBaseOrMemberInitializer *BOMInit; + + CXXCtorInitializer *BOMInit; if (IsBaseInitializer) { - BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo, - IsBaseVirtual, LParenLoc, - Init, RParenLoc); + BOMInit = new (C) CXXCtorInitializer(C, BaseClassInfo, IsBaseVirtual, + LParenLoc, Init, RParenLoc, + MemberOrEllipsisLoc); } else if (IsWritten) { - BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc, - LParenLoc, Init, RParenLoc); + if (Member) + BOMInit = new (C) CXXCtorInitializer(C, Member, MemberOrEllipsisLoc, + LParenLoc, Init, RParenLoc); + else + BOMInit = new (C) CXXCtorInitializer(C, IndirectMember, + MemberOrEllipsisLoc, LParenLoc, + Init, RParenLoc); } else { - BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc, - LParenLoc, Init, RParenLoc, - Indices.data(), - Indices.size()); + BOMInit = CXXCtorInitializer::Create(C, Member, MemberOrEllipsisLoc, + LParenLoc, Init, RParenLoc, + Indices.data(), Indices.size()); } - BOMInit->setAnonUnionMember(AnonUnionMember); - BaseOrMemberInitializers[i] = BOMInit; + if (IsWritten) + BOMInit->setSourceOrder(SourceOrderOrNumArrayIndices); + CtorInitializers[i] = BOMInit; } } - return std::make_pair(BaseOrMemberInitializers, NumInitializers); + return std::make_pair(CtorInitializers, NumInitializers); } NestedNameSpecifier * @@ -3902,7 +4728,10 @@ ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) { case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: { - Type *T = GetType(Record[Idx++]).getTypePtr(); + const Type *T = GetType(Record[Idx++]).getTypePtrOrNull(); + if (!T) + return 0; + bool Template = Record[Idx++]; NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T); break; @@ -3920,9 +4749,10 @@ ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) { } SourceRange -ASTReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) { - SourceLocation beg = SourceLocation::getFromRawEncoding(Record[Idx++]); - SourceLocation end = SourceLocation::getFromRawEncoding(Record[Idx++]); +ASTReader::ReadSourceRange(PerFileData &F, const RecordData &Record, + unsigned &Idx) { + SourceLocation beg = ReadSourceLocation(F, Record, Idx); + SourceLocation end = ReadSourceLocation(F, Record, Idx); return SourceRange(beg, end); } @@ -3965,7 +4795,7 @@ DiagnosticBuilder ASTReader::Diag(unsigned DiagID) { } DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) { - return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID); + return Diags.Report(Loc, DiagID); } /// \brief Retrieve the identifier table associated with the @@ -3988,70 +4818,8 @@ SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) { return SwitchCaseStmts[ID]; } -/// \brief Record that the given label statement has been -/// deserialized and has the given ID. -void ASTReader::RecordLabelStmt(LabelStmt *S, unsigned ID) { - assert(LabelStmts.find(ID) == LabelStmts.end() && - "Deserialized label twice"); - LabelStmts[ID] = S; - - // If we've already seen any goto statements that point to this - // label, resolve them now. - typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter; - std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID); - for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto) - Goto->second->setLabel(S); - UnresolvedGotoStmts.erase(Gotos.first, Gotos.second); - - // If we've already seen any address-label statements that point to - // this label, resolve them now. - typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter; - std::pair<AddrLabelIter, AddrLabelIter> AddrLabels - = UnresolvedAddrLabelExprs.equal_range(ID); - for (AddrLabelIter AddrLabel = AddrLabels.first; - AddrLabel != AddrLabels.second; ++AddrLabel) - AddrLabel->second->setLabel(S); - UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second); -} - -/// \brief Set the label of the given statement to the label -/// identified by ID. -/// -/// Depending on the order in which the label and other statements -/// referencing that label occur, this operation may complete -/// immediately (updating the statement) or it may queue the -/// statement to be back-patched later. -void ASTReader::SetLabelOf(GotoStmt *S, unsigned ID) { - std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID); - if (Label != LabelStmts.end()) { - // We've already seen this label, so set the label of the goto and - // we're done. - S->setLabel(Label->second); - } else { - // We haven't seen this label yet, so add this goto to the set of - // unresolved goto statements. - UnresolvedGotoStmts.insert(std::make_pair(ID, S)); - } -} - -/// \brief Set the label of the given expression to the label -/// identified by ID. -/// -/// Depending on the order in which the label and other statements -/// referencing that label occur, this operation may complete -/// immediately (updating the statement) or it may queue the -/// statement to be back-patched later. -void ASTReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) { - std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID); - if (Label != LabelStmts.end()) { - // We've already seen this label, so set the label of the - // label-address expression and we're done. - S->setLabel(Label->second); - } else { - // We haven't seen this label yet, so add this label-address - // expression to the set of unresolved label-address expressions. - UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S)); - } +void ASTReader::ClearSwitchCaseIDs() { + SwitchCaseStmts.clear(); } void ASTReader::FinishedDeserializing() { @@ -4066,43 +4834,57 @@ void ASTReader::FinishedDeserializing() { PendingIdentifierInfos.pop_front(); } + // Ready to load previous declarations of Decls that were delayed. + while (!PendingPreviousDecls.empty()) { + loadAndAttachPreviousDecl(PendingPreviousDecls.front().first, + PendingPreviousDecls.front().second); + PendingPreviousDecls.pop_front(); + } + // We are not in recursive loading, so it's safe to pass the "interesting" // decls to the consumer. if (Consumer) PassInterestingDeclsToConsumer(); + + assert(PendingForwardRefs.size() == 0 && + "Some forward refs did not get linked to the definition!"); } --NumCurrentElementsDeserializing; } ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context, - const char *isysroot, bool DisableValidation) + const char *isysroot, bool DisableValidation, + bool DisableStatCache) : Listener(new PCHValidator(PP, *this)), DeserializationListener(0), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context), Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation), - NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0), - TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0), - NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0), - NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0), - TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0), - TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0), - TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) { + DisableStatCache(DisableStatCache), NumStatHits(0), NumStatMisses(0), + NumSLocEntriesRead(0), TotalNumSLocEntries(0), NextSLocOffset(0), + NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), + TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0), + NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0), + NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0), + NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0), + NumCurrentElementsDeserializing(0) +{ RelocatablePCH = false; } ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr, Diagnostic &Diags, const char *isysroot, - bool DisableValidation) + bool DisableValidation, bool DisableStatCache) : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0), - isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0), - NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0), - NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), - TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0), - NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0), - NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0), - NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0), - NumCurrentElementsDeserializing(0) { + isysroot(isysroot), DisableValidation(DisableValidation), + DisableStatCache(DisableStatCache), NumStatHits(0), NumStatMisses(0), + NumSLocEntriesRead(0), TotalNumSLocEntries(0), + NextSLocOffset(0), NumStatementsRead(0), TotalNumStatements(0), + NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0), + NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0), + TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0), + TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0), + TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) { RelocatablePCH = false; } @@ -4131,17 +4913,23 @@ ASTReader::~ASTReader() { } } -ASTReader::PerFileData::PerFileData() - : StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0), - LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0), - IdentifierOffsets(0), IdentifierTableData(0), IdentifierLookupTable(0), - LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0), - NumPreallocatedPreprocessingEntities(0), SelectorLookupTable(0), - SelectorLookupTableData(0), SelectorOffsets(0), LocalNumSelectors(0) +ASTReader::PerFileData::PerFileData(ASTFileType Ty) + : Type(Ty), SizeInBits(0), LocalNumSLocEntries(0), SLocOffsets(0), LocalSLocSize(0), + LocalNumIdentifiers(0), IdentifierOffsets(0), IdentifierTableData(0), + IdentifierLookupTable(0), LocalNumMacroDefinitions(0), + MacroDefinitionOffsets(0), + LocalNumHeaderFileInfos(0), HeaderFileInfoTableData(0), + HeaderFileInfoTable(0), + LocalNumSelectors(0), SelectorOffsets(0), + SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0), + DeclOffsets(0), LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0), + LocalNumTypes(0), TypeOffsets(0), StatCache(0), + NumPreallocatedPreprocessingEntities(0), NextInSource(0) {} ASTReader::PerFileData::~PerFileData() { delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable); + delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable); delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable); } diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp index 7adbe12..dec15dd 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "ASTCommon.h" #include "clang/Serialization/ASTReader.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" @@ -30,26 +31,60 @@ using namespace clang::serialization; namespace clang { class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> { ASTReader &Reader; + ASTReader::PerFileData &F; llvm::BitstreamCursor &Cursor; const DeclID ThisDeclID; - const ASTReader::RecordData &Record; + typedef ASTReader::RecordData RecordData; + const RecordData &Record; unsigned &Idx; TypeID TypeIDForTypeDecl; uint64_t GetCurrentCursorOffset(); + SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) { + return Reader.ReadSourceLocation(F, R, I); + } + SourceRange ReadSourceRange(const RecordData &R, unsigned &I) { + return Reader.ReadSourceRange(F, R, I); + } + TypeSourceInfo *GetTypeSourceInfo(const RecordData &R, unsigned &I) { + return Reader.GetTypeSourceInfo(F, R, I); + } + void ReadQualifierInfo(QualifierInfo &Info, + const RecordData &R, unsigned &I) { + Reader.ReadQualifierInfo(F, Info, R, I); + } + void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name, + const RecordData &R, unsigned &I) { + Reader.ReadDeclarationNameLoc(F, DNLoc, Name, R, I); + } + void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo, + const RecordData &R, unsigned &I) { + Reader.ReadDeclarationNameInfo(F, NameInfo, R, I); + } + + void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data, + const RecordData &R, unsigned &I); + void InitializeCXXDefinitionData(CXXRecordDecl *D, + CXXRecordDecl *DefinitionDecl, + const RecordData &Record, unsigned &Idx); public: - ASTDeclReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor, - DeclID thisDeclID, const ASTReader::RecordData &Record, - unsigned &Idx) - : Reader(Reader), Cursor(Cursor), ThisDeclID(thisDeclID), Record(Record), - Idx(Idx), TypeIDForTypeDecl(0) { } + ASTDeclReader(ASTReader &Reader, ASTReader::PerFileData &F, + llvm::BitstreamCursor &Cursor, DeclID thisDeclID, + const RecordData &Record, unsigned &Idx) + : Reader(Reader), F(F), Cursor(Cursor), ThisDeclID(thisDeclID), + Record(Record), Idx(Idx), TypeIDForTypeDecl(0) { } + + static void attachPreviousDecl(Decl *D, Decl *previous); void Visit(Decl *D); + void UpdateDecl(Decl *D, const RecordData &Record); + void VisitDecl(Decl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *TU); void VisitNamedDecl(NamedDecl *ND); + void VisitLabelDecl(LabelDecl *LD); void VisitNamespaceDecl(NamespaceDecl *D); void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); @@ -75,6 +110,7 @@ namespace clang { void VisitCXXDestructorDecl(CXXDestructorDecl *D); void VisitCXXConversionDecl(CXXConversionDecl *D); void VisitFieldDecl(FieldDecl *FD); + void VisitIndirectFieldDecl(IndirectFieldDecl *FD); void VisitVarDecl(VarDecl *VD); void VisitImplicitParamDecl(ImplicitParamDecl *PD); void VisitParmVarDecl(ParmVarDecl *PD); @@ -134,7 +170,7 @@ void ASTDeclReader::Visit(Decl *D) { if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) { // if we have a fully initialized TypeDecl, we can safely read its type now. - TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr()); + TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull()); } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { // FunctionDecl's body was written last after all other Stmts/Exprs. if (Record[Idx++]) @@ -146,17 +182,17 @@ void ASTDeclReader::VisitDecl(Decl *D) { D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); D->setLexicalDeclContext( cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); - D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + D->setLocation(ReadSourceLocation(Record, Idx)); D->setInvalidDecl(Record[Idx++]); - if (Record[Idx++]) { + if (Record[Idx++]) { // hasAttrs AttrVec Attrs; - Reader.ReadAttributes(Cursor, Attrs); + Reader.ReadAttributes(F, Attrs, Record, Idx); D->setAttrs(Attrs); } D->setImplicit(Record[Idx++]); D->setUsed(Record[Idx++]); D->setAccess((AccessSpecifier)Record[Idx++]); - D->setPCHLevel(Record[Idx++] + 1); + D->setPCHLevel(Record[Idx++] + (F.Type <= ASTReader::PCH)); } void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) { @@ -178,29 +214,39 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) { VisitTypeDecl(TD); - TD->setTypeSourceInfo(Reader.GetTypeSourceInfo(Cursor, Record, Idx)); + TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); } void ASTDeclReader::VisitTagDecl(TagDecl *TD) { VisitTypeDecl(TD); - TD->IdentifierNamespace = Record[Idx++]; VisitRedeclarable(TD); + TD->IdentifierNamespace = Record[Idx++]; TD->setTagKind((TagDecl::TagKind)Record[Idx++]); TD->setDefinition(Record[Idx++]); TD->setEmbeddedInDeclarator(Record[Idx++]); - TD->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TD->setTagKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - // FIXME: maybe read optional qualifier and its range. - TD->setTypedefForAnonDecl( - cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++]))); + TD->setRBraceLoc(ReadSourceLocation(Record, Idx)); + TD->setTagKeywordLoc(ReadSourceLocation(Record, Idx)); + if (Record[Idx++]) { // hasExtInfo + TagDecl::ExtInfo *Info = new (*Reader.getContext()) TagDecl::ExtInfo(); + ReadQualifierInfo(*Info, Record, Idx); + TD->TypedefDeclOrQualifier = Info; + } else + TD->setTypedefForAnonDecl( + cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++]))); } void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { VisitTagDecl(ED); - ED->setIntegerType(Reader.GetType(Record[Idx++])); + if (TypeSourceInfo *TI = Reader.GetTypeSourceInfo(F, Record, Idx)) + ED->setIntegerTypeSourceInfo(TI); + else + ED->setIntegerType(Reader.GetType(Record[Idx++])); ED->setPromotionType(Reader.GetType(Record[Idx++])); ED->setNumPositiveBits(Record[Idx++]); ED->setNumNegativeBits(Record[Idx++]); + ED->IsScoped = Record[Idx++]; + ED->IsScopedUsingClassTag = Record[Idx++]; + ED->IsFixed = Record[Idx++]; ED->setInstantiationOfMemberEnum( cast_or_null<EnumDecl>(Reader.GetDecl(Record[Idx++]))); } @@ -220,22 +266,27 @@ void ASTDeclReader::VisitValueDecl(ValueDecl *VD) { void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) { VisitValueDecl(ECD); if (Record[Idx++]) - ECD->setInitExpr(Reader.ReadExpr(Cursor)); + ECD->setInitExpr(Reader.ReadExpr(F)); ECD->setInitVal(Reader.ReadAPSInt(Record, Idx)); } void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) { VisitValueDecl(DD); - TypeSourceInfo *TInfo = Reader.GetTypeSourceInfo(Cursor, Record, Idx); - if (TInfo) - DD->setTypeSourceInfo(TInfo); - // FIXME: read optional qualifier and its range. + if (Record[Idx++]) { // hasExtInfo + DeclaratorDecl::ExtInfo *Info + = new (*Reader.getContext()) DeclaratorDecl::ExtInfo(); + ReadQualifierInfo(*Info, Record, Idx); + Info->TInfo = GetTypeSourceInfo(Record, Idx); + DD->DeclInfo = Info; + } else + DD->DeclInfo = GetTypeSourceInfo(Record, Idx); } void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { VisitDeclaratorDecl(FD); - // FIXME: read DeclarationNameLoc. + VisitRedeclarable(FD); + ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName(), Record, Idx); FD->IdentifierNamespace = Record[Idx++]; switch ((FunctionDecl::TemplatedKind)Record[Idx++]) { default: assert(false && "Unhandled TemplatedKind!"); @@ -249,8 +300,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { case FunctionDecl::TK_MemberSpecialization: { FunctionDecl *InstFD = cast<FunctionDecl>(Reader.GetDecl(Record[Idx++])); TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; - SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); - FD->setInstantiationOfMemberFunction(InstFD, TSK); + SourceLocation POI = ReadSourceLocation(Record, Idx); + FD->setInstantiationOfMemberFunction(*Reader.getContext(), InstFD, TSK); FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI); break; } @@ -261,7 +312,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { // Template arguments. llvm::SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, Cursor, Record, Idx); + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); // Template args as written. llvm::SmallVector<TemplateArgumentLoc, 8> TemplArgLocs; @@ -271,20 +322,45 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { TemplArgLocs.reserve(NumTemplateArgLocs); for (unsigned i=0; i != NumTemplateArgLocs; ++i) TemplArgLocs.push_back( - Reader.ReadTemplateArgumentLoc(Cursor, Record, Idx)); + Reader.ReadTemplateArgumentLoc(F, Record, Idx)); - LAngleLoc = Reader.ReadSourceLocation(Record, Idx); - RAngleLoc = Reader.ReadSourceLocation(Record, Idx); + LAngleLoc = ReadSourceLocation(Record, Idx); + RAngleLoc = ReadSourceLocation(Record, Idx); } - SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); - - if (FD->isCanonicalDecl()) // if canonical add to template's set. - FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(), - TemplArgs.data(), TSK, - TemplArgLocs.size(), - TemplArgLocs.data(), - LAngleLoc, RAngleLoc, POI); + SourceLocation POI = ReadSourceLocation(Record, Idx); + + ASTContext &C = *Reader.getContext(); + TemplateArgumentList *TemplArgList + = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size()); + TemplateArgumentListInfo *TemplArgsInfo + = new (C) TemplateArgumentListInfo(LAngleLoc, RAngleLoc); + for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i) + TemplArgsInfo->addArgument(TemplArgLocs[i]); + FunctionTemplateSpecializationInfo *FTInfo + = FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK, + TemplArgList, + TemplArgsInfo, POI); + FD->TemplateOrSpecialization = FTInfo; + + if (FD->isCanonicalDecl()) { // if canonical add to template's set. + // The template that contains the specializations set. It's not safe to + // use getCanonicalDecl on Template since it may still be initializing. + FunctionTemplateDecl *CanonTemplate + = cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++])); + // Get the InsertPos by FindNodeOrInsertPos() instead of calling + // InsertNode(FTInfo) directly to avoid the getASTContext() call in + // FunctionTemplateSpecializationInfo's Profile(). + // We avoid getASTContext because a decl in the parent hierarchy may + // be initializing. + llvm::FoldingSetNodeID ID; + FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(), + TemplArgs.size(), C); + void *InsertPos = 0; + CanonTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); + assert(InsertPos && "Another specialization already inserted!"); + CanonTemplate->getSpecializations().InsertNode(FTInfo, InsertPos); + } break; } case FunctionDecl::TK_DependentFunctionTemplateSpecialization: { @@ -298,9 +374,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { TemplateArgumentListInfo TemplArgs; unsigned NumArgs = Record[Idx++]; while (NumArgs--) - TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(Cursor,Record, Idx)); - TemplArgs.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx)); - TemplArgs.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx)); + TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(F, Record, Idx)); + TemplArgs.setLAngleLoc(ReadSourceLocation(Record, Idx)); + TemplArgs.setRAngleLoc(ReadSourceLocation(Record, Idx)); FD->setDependentTemplateSpecialization(*Reader.getContext(), TemplDecls, TemplArgs); @@ -311,19 +387,18 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { // FunctionDecl's body is handled last at ASTDeclReader::Visit, // after everything else is read. - VisitRedeclarable(FD); - FD->setStorageClass((StorageClass)Record[Idx++]); - FD->setStorageClassAsWritten((StorageClass)Record[Idx++]); - FD->setInlineSpecified(Record[Idx++]); - FD->setVirtualAsWritten(Record[Idx++]); - FD->setPure(Record[Idx++]); - FD->setHasInheritedPrototype(Record[Idx++]); - FD->setHasWrittenPrototype(Record[Idx++]); - FD->setDeleted(Record[Idx++]); - FD->setTrivial(Record[Idx++]); - FD->setCopyAssignment(Record[Idx++]); - FD->setHasImplicitReturnZero(Record[Idx++]); - FD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); + FD->SClass = (StorageClass)Record[Idx++]; + FD->SClassAsWritten = (StorageClass)Record[Idx++]; + FD->IsInline = Record[Idx++]; + FD->IsInlineSpecified = Record[Idx++]; + FD->IsVirtualAsWritten = Record[Idx++]; + FD->IsPure = Record[Idx++]; + FD->HasInheritedPrototype = Record[Idx++]; + FD->HasWrittenPrototype = Record[Idx++]; + FD->IsDeleted = Record[Idx++]; + FD->IsTrivial = Record[Idx++]; + FD->HasImplicitReturnZero = Record[Idx++]; + FD->EndRangeLoc = ReadSourceLocation(Record, Idx); // Read in the parameters. unsigned NumParams = Record[Idx++]; @@ -331,7 +406,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { Params.reserve(NumParams); for (unsigned I = 0; I != NumParams; ++I) Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++]))); - FD->setParams(Params.data(), NumParams); + FD->setParams(*Reader.getContext(), Params.data(), NumParams); } void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { @@ -339,7 +414,7 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { if (Record[Idx++]) { // In practice, this won't be executed (since method definitions // don't occur in header files). - MD->setBody(Reader.ReadStmt(Cursor)); + MD->setBody(Reader.ReadStmt(F)); MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++]))); MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++]))); } @@ -351,8 +426,8 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]); MD->setNumSelectorArgs(unsigned(Record[Idx++])); MD->setResultType(Reader.GetType(Record[Idx++])); - MD->setResultTypeSourceInfo(Reader.GetTypeSourceInfo(Cursor, Record, Idx)); - MD->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + MD->setResultTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); + MD->setEndLoc(ReadSourceLocation(Record, Idx)); unsigned NumParams = Record[Idx++]; llvm::SmallVector<ParmVarDecl *, 16> Params; Params.reserve(NumParams); @@ -364,14 +439,14 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) { VisitNamedDecl(CD); - SourceLocation A = SourceLocation::getFromRawEncoding(Record[Idx++]); - SourceLocation B = SourceLocation::getFromRawEncoding(Record[Idx++]); + SourceLocation A = ReadSourceLocation(Record, Idx); + SourceLocation B = ReadSourceLocation(Record, Idx); CD->setAtEndRange(SourceRange(A, B)); } void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { VisitObjCContainerDecl(ID); - ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr()); + ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtrOrNull()); ID->setSuperClass(cast_or_null<ObjCInterfaceDecl> (Reader.GetDecl(Record[Idx++]))); @@ -384,7 +459,7 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { llvm::SmallVector<SourceLocation, 16> ProtoLocs; ProtoLocs.reserve(NumProtocols); for (unsigned I = 0; I != NumProtocols; ++I) - ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + ProtoLocs.push_back(ReadSourceLocation(Record, Idx)); ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(), *Reader.getContext()); @@ -409,9 +484,9 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { ID->setIvarList(0); ID->setForwardDecl(Record[Idx++]); ID->setImplicitInterfaceDecl(Record[Idx++]); - ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - ID->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); + ID->setClassLoc(ReadSourceLocation(Record, Idx)); + ID->setSuperClassLoc(ReadSourceLocation(Record, Idx)); + ID->setLocEnd(ReadSourceLocation(Record, Idx)); } void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) { @@ -426,7 +501,7 @@ void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) { void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { VisitObjCContainerDecl(PD); PD->setForwardDecl(Record[Idx++]); - PD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); + PD->setLocEnd(ReadSourceLocation(Record, Idx)); unsigned NumProtoRefs = Record[Idx++]; llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs; ProtoRefs.reserve(NumProtoRefs); @@ -435,7 +510,7 @@ void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { llvm::SmallVector<SourceLocation, 16> ProtoLocs; ProtoLocs.reserve(NumProtoRefs); for (unsigned I = 0; I != NumProtoRefs; ++I) - ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + ProtoLocs.push_back(ReadSourceLocation(Record, Idx)); PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), *Reader.getContext()); } @@ -454,7 +529,7 @@ void ASTDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) { llvm::SmallVector<SourceLocation, 16> SLocs; SLocs.reserve(NumClassRefs); for (unsigned I = 0; I != NumClassRefs; ++I) - SLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + SLocs.push_back(ReadSourceLocation(Record, Idx)); CD->setClassList(*Reader.getContext(), ClassRefs.data(), SLocs.data(), NumClassRefs); } @@ -469,7 +544,7 @@ void ASTDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) { llvm::SmallVector<SourceLocation, 16> ProtoLocs; ProtoLocs.reserve(NumProtoRefs); for (unsigned I = 0; I != NumProtoRefs; ++I) - ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + ProtoLocs.push_back(ReadSourceLocation(Record, Idx)); FPD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), *Reader.getContext()); } @@ -485,13 +560,13 @@ void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { llvm::SmallVector<SourceLocation, 16> ProtoLocs; ProtoLocs.reserve(NumProtoRefs); for (unsigned I = 0; I != NumProtoRefs; ++I) - ProtoLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++])); + ProtoLocs.push_back(ReadSourceLocation(Record, Idx)); CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), *Reader.getContext()); CD->setNextClassCategory(cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++]))); CD->setHasSynthBitfield(Record[Idx++]); - CD->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - CD->setCategoryNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + CD->setAtLoc(ReadSourceLocation(Record, Idx)); + CD->setCategoryNameLoc(ReadSourceLocation(Record, Idx)); } void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { @@ -501,8 +576,8 @@ void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { VisitNamedDecl(D); - D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - D->setType(Reader.GetTypeSourceInfo(Cursor, Record, Idx)); + D->setAtLoc(ReadSourceLocation(Record, Idx)); + D->setType(GetTypeSourceInfo(Record, Idx)); // FIXME: stable encoding D->setPropertyAttributes( (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]); @@ -537,27 +612,28 @@ void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { D->setSuperClass( cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]))); llvm::tie(D->IvarInitializers, D->NumIvarInitializers) - = Reader.ReadCXXBaseOrMemberInitializers(Cursor, Record, Idx); + = Reader.ReadCXXCtorInitializers(F, Record, Idx); D->setHasSynthBitfield(Record[Idx++]); } void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { VisitDecl(D); - D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + D->setAtLoc(ReadSourceLocation(Record, Idx)); D->setPropertyDecl( cast_or_null<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++]))); - D->setPropertyIvarDecl( - cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++]))); - D->setGetterCXXConstructor(Reader.ReadExpr(Cursor)); - D->setSetterCXXAssignment(Reader.ReadExpr(Cursor)); + D->PropertyIvarDecl = + cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])); + D->IvarLoc = ReadSourceLocation(Record, Idx); + D->setGetterCXXConstructor(Reader.ReadExpr(F)); + D->setSetterCXXAssignment(Reader.ReadExpr(F)); } void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) { VisitDeclaratorDecl(FD); FD->setMutable(Record[Idx++]); if (Record[Idx++]) - FD->setBitWidth(Reader.ReadExpr(Cursor)); + FD->setBitWidth(Reader.ReadExpr(F)); if (!FD->getDeclName()) { FieldDecl *Tmpl = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])); if (Tmpl) @@ -565,22 +641,33 @@ void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) { } } +void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { + VisitValueDecl(FD); + + FD->ChainingSize = Record[Idx++]; + assert(FD->ChainingSize >= 2 && "Anonymous chaining must be >= 2"); + FD->Chaining = new (*Reader.getContext())NamedDecl*[FD->ChainingSize]; + + for (unsigned I = 0; I != FD->ChainingSize; ++I) + FD->Chaining[I] = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); +} + void ASTDeclReader::VisitVarDecl(VarDecl *VD) { VisitDeclaratorDecl(VD); - VD->setStorageClass((StorageClass)Record[Idx++]); + VisitRedeclarable(VD); + VD->SClass = (StorageClass)Record[Idx++]; VD->setStorageClassAsWritten((StorageClass)Record[Idx++]); VD->setThreadSpecified(Record[Idx++]); VD->setCXXDirectInitializer(Record[Idx++]); VD->setExceptionVariable(Record[Idx++]); VD->setNRVOVariable(Record[Idx++]); - VisitRedeclarable(VD); if (Record[Idx++]) - VD->setInit(Reader.ReadExpr(Cursor)); + VD->setInit(Reader.ReadExpr(F)); if (Record[Idx++]) { // HasMemberSpecializationInfo. VarDecl *Tmpl = cast<VarDecl>(Reader.GetDecl(Record[Idx++])); TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; - SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); + SourceLocation POI = ReadSourceLocation(Record, Idx); Reader.getContext()->setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI); } } @@ -594,24 +681,40 @@ void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]); PD->setHasInheritedDefaultArg(Record[Idx++]); if (Record[Idx++]) // hasUninstantiatedDefaultArg. - PD->setUninstantiatedDefaultArg(Reader.ReadExpr(Cursor)); + PD->setUninstantiatedDefaultArg(Reader.ReadExpr(F)); } void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) { VisitDecl(AD); - AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr(Cursor))); + AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr(F))); } void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { VisitDecl(BD); - BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt(Cursor))); - BD->setSignatureAsWritten(Reader.GetTypeSourceInfo(Cursor, Record, Idx)); + BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt(F))); + BD->setSignatureAsWritten(GetTypeSourceInfo(Record, Idx)); unsigned NumParams = Record[Idx++]; llvm::SmallVector<ParmVarDecl *, 16> Params; Params.reserve(NumParams); for (unsigned I = 0; I != NumParams; ++I) Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++]))); BD->setParams(Params.data(), NumParams); + + bool capturesCXXThis = Record[Idx++]; + unsigned numCaptures = Record[Idx++]; + llvm::SmallVector<BlockDecl::Capture, 16> captures; + captures.reserve(numCaptures); + for (unsigned i = 0; i != numCaptures; ++i) { + VarDecl *decl = cast<VarDecl>(Reader.GetDecl(Record[Idx++])); + unsigned flags = Record[Idx++]; + bool byRef = (flags & 1); + bool nested = (flags & 2); + Expr *copyExpr = ((flags & 4) ? Reader.ReadExpr(F) : 0); + + captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr)); + } + BD->setCaptures(*Reader.getContext(), captures.begin(), + captures.end(), capturesCXXThis); } void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) { @@ -620,12 +723,17 @@ void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) { D->setHasBraces(Record[Idx++]); } +void ASTDeclReader::VisitLabelDecl(LabelDecl *D) { + VisitNamedDecl(D); +} + + void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { VisitNamedDecl(D); - D->setLBracLoc(Reader.ReadSourceLocation(Record, Idx)); - D->setRBracLoc(Reader.ReadSourceLocation(Record, Idx)); - D->setNextNamespace( - cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++]))); + D->IsInline = Record[Idx++]; + D->LBracLoc = ReadSourceLocation(Record, Idx); + D->RBracLoc = ReadSourceLocation(Record, Idx); + D->NextNamespace = Record[Idx++]; bool IsOriginal = Record[Idx++]; D->OrigOrAnonNamespace.setInt(IsOriginal); @@ -635,29 +743,20 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { VisitNamedDecl(D); - D->NamespaceLoc = Reader.ReadSourceLocation(Record, Idx); - D->setQualifierRange(Reader.ReadSourceRange(Record, Idx)); + D->NamespaceLoc = ReadSourceLocation(Record, Idx); + D->setQualifierRange(ReadSourceRange(Record, Idx)); D->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - D->IdentLoc = Reader.ReadSourceLocation(Record, Idx); + D->IdentLoc = ReadSourceLocation(Record, Idx); D->Namespace = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); } void ASTDeclReader::VisitUsingDecl(UsingDecl *D) { VisitNamedDecl(D); - D->setUsingLocation(Reader.ReadSourceLocation(Record, Idx)); - D->setNestedNameRange(Reader.ReadSourceRange(Record, Idx)); + D->setUsingLocation(ReadSourceLocation(Record, Idx)); + D->setNestedNameRange(ReadSourceRange(Record, Idx)); D->setTargetNestedNameDecl(Reader.ReadNestedNameSpecifier(Record, Idx)); - // FIXME: read the DNLoc component. - - // FIXME: It would probably be more efficient to read these into a vector - // and then re-cosntruct the shadow decl set over that vector since it - // would avoid existence checks. - unsigned NumShadows = Record[Idx++]; - for(unsigned I = 0; I != NumShadows; ++I) { - // Avoid invariant checking of UsingDecl::addShadowDecl, the decl may still - // be initializing. - D->Shadows.insert(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]))); - } + ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx); + D->FirstUsingShadow = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])); D->setTypeName(Record[Idx++]); NamedDecl *Pattern = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])); if (Pattern) @@ -667,7 +766,7 @@ void ASTDeclReader::VisitUsingDecl(UsingDecl *D) { void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { VisitNamedDecl(D); D->setTargetDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++]))); - D->setUsingDecl(cast<UsingDecl>(Reader.GetDecl(Record[Idx++]))); + D->UsingOrNextShadow = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])); UsingShadowDecl *Pattern = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])); if (Pattern) @@ -676,9 +775,9 @@ void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { VisitNamedDecl(D); - D->UsingLoc = Reader.ReadSourceLocation(Record, Idx); - D->NamespaceLoc = Reader.ReadSourceLocation(Record, Idx); - D->QualifierRange = Reader.ReadSourceRange(Record, Idx); + D->UsingLoc = ReadSourceLocation(Record, Idx); + D->NamespaceLoc = ReadSourceLocation(Record, Idx); + D->QualifierRange = ReadSourceRange(Record, Idx); D->Qualifier = Reader.ReadNestedNameSpecifier(Record, Idx); D->NominatedNamespace = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); D->CommonAncestor = cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])); @@ -686,88 +785,99 @@ void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { VisitValueDecl(D); - D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx)); - D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx)); + D->setTargetNestedNameRange(ReadSourceRange(Record, Idx)); + D->setUsingLoc(ReadSourceLocation(Record, Idx)); D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - // FIXME: read the DNLoc component. + ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx); } void ASTDeclReader::VisitUnresolvedUsingTypenameDecl( UnresolvedUsingTypenameDecl *D) { VisitTypeDecl(D); - D->TargetNestedNameRange = Reader.ReadSourceRange(Record, Idx); - D->UsingLocation = Reader.ReadSourceLocation(Record, Idx); - D->TypenameLocation = Reader.ReadSourceLocation(Record, Idx); + D->TargetNestedNameRange = ReadSourceRange(Record, Idx); + D->UsingLocation = ReadSourceLocation(Record, Idx); + D->TypenameLocation = ReadSourceLocation(Record, Idx); D->TargetNestedNameSpecifier = Reader.ReadNestedNameSpecifier(Record, Idx); } -void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { +void ASTDeclReader::ReadCXXDefinitionData( + struct CXXRecordDecl::DefinitionData &Data, + const RecordData &Record, unsigned &Idx) { + Data.UserDeclaredConstructor = Record[Idx++]; + Data.UserDeclaredCopyConstructor = Record[Idx++]; + Data.UserDeclaredCopyAssignment = Record[Idx++]; + Data.UserDeclaredDestructor = Record[Idx++]; + Data.Aggregate = Record[Idx++]; + Data.PlainOldData = Record[Idx++]; + Data.Empty = Record[Idx++]; + Data.Polymorphic = Record[Idx++]; + Data.Abstract = Record[Idx++]; + Data.HasTrivialConstructor = Record[Idx++]; + Data.HasTrivialCopyConstructor = Record[Idx++]; + Data.HasTrivialCopyAssignment = Record[Idx++]; + Data.HasTrivialDestructor = Record[Idx++]; + Data.ComputedVisibleConversions = Record[Idx++]; + Data.DeclaredDefaultConstructor = Record[Idx++]; + Data.DeclaredCopyConstructor = Record[Idx++]; + Data.DeclaredCopyAssignment = Record[Idx++]; + Data.DeclaredDestructor = Record[Idx++]; + + Data.NumBases = Record[Idx++]; + if (Data.NumBases) + Data.Bases = Reader.GetCXXBaseSpecifiersOffset(Record[Idx++]); + Data.NumVBases = Record[Idx++]; + if (Data.NumVBases) + Data.VBases = Reader.GetCXXBaseSpecifiersOffset(Record[Idx++]); + + Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx); + Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx); + assert(Data.Definition && "Data.Definition should be already set!"); + Data.FirstFriend + = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++])); +} + +void ASTDeclReader::InitializeCXXDefinitionData(CXXRecordDecl *D, + CXXRecordDecl *DefinitionDecl, + const RecordData &Record, + unsigned &Idx) { ASTContext &C = *Reader.getContext(); - // We need to allocate the DefinitionData struct ahead of VisitRecordDecl - // so that the other CXXRecordDecls can get a pointer even when the owner - // is still initializing. - bool OwnsDefinitionData = false; - enum DataOwnership { Data_NoDefData, Data_Owner, Data_NotOwner }; - switch ((DataOwnership)Record[Idx++]) { - default: - assert(0 && "Out of sync with ASTDeclWriter or messed up reading"); - case Data_NoDefData: - break; - case Data_Owner: - OwnsDefinitionData = true; + if (D == DefinitionDecl) { D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); - break; - case Data_NotOwner: - D->DefinitionData - = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))->DefinitionData; - break; + ReadCXXDefinitionData(*D->DefinitionData, Record, Idx); + // We read the definition info. Check if there are pending forward + // references that need to point to this DefinitionData pointer. + ASTReader::PendingForwardRefsMap::iterator + FindI = Reader.PendingForwardRefs.find(D); + if (FindI != Reader.PendingForwardRefs.end()) { + ASTReader::ForwardRefs &Refs = FindI->second; + for (ASTReader::ForwardRefs::iterator + I = Refs.begin(), E = Refs.end(); I != E; ++I) + (*I)->DefinitionData = D->DefinitionData; +#ifndef NDEBUG + // We later check whether PendingForwardRefs is empty to make sure all + // pending references were linked. + Reader.PendingForwardRefs.erase(D); +#endif + } + } else if (DefinitionDecl) { + if (DefinitionDecl->DefinitionData) { + D->DefinitionData = DefinitionDecl->DefinitionData; + } else { + // The definition is still initializing. + Reader.PendingForwardRefs[DefinitionDecl].push_back(D); + } } +} +void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { VisitRecordDecl(D); - if (OwnsDefinitionData) { - assert(D->DefinitionData); - struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; - - Data.UserDeclaredConstructor = Record[Idx++]; - Data.UserDeclaredCopyConstructor = Record[Idx++]; - Data.UserDeclaredCopyAssignment = Record[Idx++]; - Data.UserDeclaredDestructor = Record[Idx++]; - Data.Aggregate = Record[Idx++]; - Data.PlainOldData = Record[Idx++]; - Data.Empty = Record[Idx++]; - Data.Polymorphic = Record[Idx++]; - Data.Abstract = Record[Idx++]; - Data.HasTrivialConstructor = Record[Idx++]; - Data.HasTrivialCopyConstructor = Record[Idx++]; - Data.HasTrivialCopyAssignment = Record[Idx++]; - Data.HasTrivialDestructor = Record[Idx++]; - Data.ComputedVisibleConversions = Record[Idx++]; - Data.DeclaredDefaultConstructor = Record[Idx++]; - Data.DeclaredCopyConstructor = Record[Idx++]; - Data.DeclaredCopyAssignment = Record[Idx++]; - Data.DeclaredDestructor = Record[Idx++]; - - // setBases() is unsuitable since it may try to iterate the bases of an - // uninitialized base. - Data.NumBases = Record[Idx++]; - Data.Bases = new(C) CXXBaseSpecifier [Data.NumBases]; - for (unsigned i = 0; i != Data.NumBases; ++i) - Data.Bases[i] = Reader.ReadCXXBaseSpecifier(Cursor, Record, Idx); - - // FIXME: Make VBases lazily computed when needed to avoid storing them. - Data.NumVBases = Record[Idx++]; - Data.VBases = new(C) CXXBaseSpecifier [Data.NumVBases]; - for (unsigned i = 0; i != Data.NumVBases; ++i) - Data.VBases[i] = Reader.ReadCXXBaseSpecifier(Cursor, Record, Idx); - - Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx); - Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx); - assert(Data.Definition && "Data.Definition should be already set!"); - Data.FirstFriend - = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++])); - } + CXXRecordDecl *DefinitionDecl + = cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])); + InitializeCXXDefinitionData(D, DefinitionDecl, Record, Idx); + + ASTContext &C = *Reader.getContext(); enum CXXRecKind { CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization @@ -778,18 +888,28 @@ void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { case CXXRecNotTemplate: break; case CXXRecTemplate: - D->setDescribedClassTemplate( - cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]))); + D->TemplateOrInstantiation + = cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++])); break; case CXXRecMemberSpecialization: { CXXRecordDecl *RD = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])); TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; - SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); - D->setInstantiationOfMemberClass(RD, TSK); - D->getMemberSpecializationInfo()->setPointOfInstantiation(POI); + SourceLocation POI = ReadSourceLocation(Record, Idx); + MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK); + MSI->setPointOfInstantiation(POI); + D->TemplateOrInstantiation = MSI; break; } } + + // Load the key function to avoid deserializing every method so we can + // compute it. + if (D->IsDefinition) { + CXXMethodDecl *Key + = cast_or_null<CXXMethodDecl>(Reader.GetDecl(Record[Idx++])); + if (Key) + C.KeyFunctions[D] = Key; + } } void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { @@ -808,8 +928,8 @@ void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) { D->IsExplicitSpecified = Record[Idx++]; D->ImplicitlyDefined = Record[Idx++]; - llvm::tie(D->BaseOrMemberInitializers, D->NumBaseOrMemberInitializers) - = Reader.ReadCXXBaseOrMemberInitializers(Cursor, Record, Idx); + llvm::tie(D->CtorInitializers, D->NumCtorInitializers) + = Reader.ReadCXXCtorInitializers(F, Record, Idx); } void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) { @@ -826,17 +946,18 @@ void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) { void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) { VisitDecl(D); - D->setColonLoc(Reader.ReadSourceLocation(Record, Idx)); + D->setColonLoc(ReadSourceLocation(Record, Idx)); } void ASTDeclReader::VisitFriendDecl(FriendDecl *D) { VisitDecl(D); if (Record[Idx++]) - D->Friend = Reader.GetTypeSourceInfo(Cursor, Record, Idx); + D->Friend = GetTypeSourceInfo(Record, Idx); else D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); - D->NextFriend = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++])); - D->FriendLoc = Reader.ReadSourceLocation(Record, Idx); + D->NextFriend = Record[Idx++]; + D->UnsupportedFriend = (Record[Idx++] != 0); + D->FriendLoc = ReadSourceLocation(Record, Idx); } void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) { @@ -845,12 +966,12 @@ void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) { D->NumParams = NumParams; D->Params = new TemplateParameterList*[NumParams]; for (unsigned i = 0; i != NumParams; ++i) - D->Params[i] = Reader.ReadTemplateParameterList(Record, Idx); + D->Params[i] = Reader.ReadTemplateParameterList(F, Record, Idx); if (Record[Idx++]) // HasFriendDecl D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); else - D->Friend = Reader.GetTypeSourceInfo(Cursor, Record, Idx); - D->FriendLoc = Reader.ReadSourceLocation(Record, Idx); + D->Friend = GetTypeSourceInfo(Record, Idx); + D->FriendLoc = ReadSourceLocation(Record, Idx); } void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) { @@ -859,21 +980,32 @@ void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) { NamedDecl *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])); TemplateParameterList* TemplateParams - = Reader.ReadTemplateParameterList(Record, Idx); + = Reader.ReadTemplateParameterList(F, Record, Idx); D->init(TemplatedDecl, TemplateParams); } void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { - VisitTemplateDecl(D); - - D->IdentifierNamespace = Record[Idx++]; - RedeclarableTemplateDecl *PrevDecl = - cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++])); - assert((PrevDecl == 0 || PrevDecl->getKind() == D->getKind()) && - "PrevDecl kind mismatch"); - if (PrevDecl) - D->CommonOrPrev = PrevDecl; - if (PrevDecl == 0) { + // Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr() + // can be used while this is still initializing. + + assert(D->CommonOrPrev.isNull() && "getCommonPtr was called earlier on this"); + DeclID PreviousDeclID = Record[Idx++]; + DeclID FirstDeclID = PreviousDeclID ? Record[Idx++] : 0; + // We delay loading of the redeclaration chain to avoid deeply nested calls. + // We temporarily set the first (canonical) declaration as the previous one + // which is the one that matters and mark the real previous DeclID to be + // loaded & attached later on. + RedeclarableTemplateDecl *FirstDecl = + cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(FirstDeclID)); + assert((FirstDecl == 0 || FirstDecl->getKind() == D->getKind()) && + "FirstDecl kind mismatch"); + if (FirstDecl) { + D->CommonOrPrev = FirstDecl; + // Mark the real previous DeclID to be loaded & attached later on. + if (PreviousDeclID != FirstDeclID) + Reader.PendingPreviousDecls.push_back(std::make_pair(D, PreviousDeclID)); + } else { + D->CommonOrPrev = D->newCommon(*Reader.getContext()); if (RedeclarableTemplateDecl *RTD = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]))) { assert(RTD->getKind() == D->getKind() && @@ -897,9 +1029,9 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { Decl *NewLatest = Reader.GetDecl(I->second); assert((LatestDecl->getLocation().isInvalid() || NewLatest->getLocation().isInvalid() || - Reader.SourceMgr.isBeforeInTranslationUnit( - LatestDecl->getLocation(), - NewLatest->getLocation())) && + !Reader.SourceMgr.isBeforeInTranslationUnit( + NewLatest->getLocation(), + LatestDecl->getLocation())) && "The new latest is supposed to come after the previous latest"); LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest); } @@ -907,24 +1039,42 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch"); D->getCommonPtr()->Latest = LatestDecl; } + + VisitTemplateDecl(D); + D->IdentifierNamespace = Record[Idx++]; } void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); if (D->getPreviousDeclaration() == 0) { - // This ClassTemplateDecl owns a CommonPtr; read it. - - // FoldingSets are filled in VisitClassTemplateSpecializationDecl. - unsigned size = Record[Idx++]; - while (size--) - cast<ClassTemplateSpecializationDecl>(Reader.GetDecl(Record[Idx++])); - - size = Record[Idx++]; - while (size--) - cast<ClassTemplatePartialSpecializationDecl>( - Reader.GetDecl(Record[Idx++])); - + // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of + // the specializations. + llvm::SmallVector<serialization::DeclID, 2> SpecIDs; + SpecIDs.push_back(0); + + // Specializations. + unsigned Size = Record[Idx++]; + SpecIDs[0] += Size; + SpecIDs.append(Record.begin() + Idx, Record.begin() + Idx + Size); + Idx += Size; + + // Partial specializations. + Size = Record[Idx++]; + SpecIDs[0] += Size; + SpecIDs.append(Record.begin() + Idx, Record.begin() + Idx + Size); + Idx += Size; + + if (SpecIDs[0]) { + typedef serialization::DeclID DeclID; + + ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr(); + CommonPtr->LazySpecializations + = new (*Reader.getContext()) DeclID [SpecIDs.size()]; + memcpy(CommonPtr->LazySpecializations, SpecIDs.data(), + SpecIDs.size() * sizeof(DeclID)); + } + // InjectedClassNameType is computed. } } @@ -932,41 +1082,52 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { void ASTDeclReader::VisitClassTemplateSpecializationDecl( ClassTemplateSpecializationDecl *D) { VisitCXXRecordDecl(D); - + + ASTContext &C = *Reader.getContext(); if (Decl *InstD = Reader.GetDecl(Record[Idx++])) { if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) { - D->setInstantiationOf(CTD); + D->SpecializedTemplate = CTD; } else { llvm::SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, Cursor, Record, Idx); - D->setInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(InstD), - TemplArgs.data(), TemplArgs.size()); + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + TemplateArgumentList *ArgList + = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), + TemplArgs.size()); + ClassTemplateSpecializationDecl::SpecializedPartialSpecialization *PS + = new (C) ClassTemplateSpecializationDecl:: + SpecializedPartialSpecialization(); + PS->PartialSpecialization + = cast<ClassTemplatePartialSpecializationDecl>(InstD); + PS->TemplateArgs = ArgList; + D->SpecializedTemplate = PS; } } // Explicit info. - if (TypeSourceInfo *TyInfo = Reader.GetTypeSourceInfo(Cursor, Record, Idx)) { - D->setTypeAsWritten(TyInfo); - D->setExternLoc(Reader.ReadSourceLocation(Record, Idx)); - D->setTemplateKeywordLoc(Reader.ReadSourceLocation(Record, Idx)); + if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) { + ClassTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo + = new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo; + ExplicitInfo->TypeAsWritten = TyInfo; + ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx); + ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx); + D->ExplicitInfo = ExplicitInfo; } llvm::SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, Cursor, Record, Idx); - D->initTemplateArgs(TemplArgs.data(), TemplArgs.size()); - SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); - if (POI.isValid()) - D->setPointOfInstantiation(POI); - D->setSpecializationKind((TemplateSpecializationKind)Record[Idx++]); - + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), + TemplArgs.size()); + D->PointOfInstantiation = ReadSourceLocation(Record, Idx); + D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++]; + if (D->isCanonicalDecl()) { // It's kept in the folding set. ClassTemplateDecl *CanonPattern = cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++])); if (ClassTemplatePartialSpecializationDecl *Partial - = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { - CanonPattern->getPartialSpecializations().InsertNode(Partial); + = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { + CanonPattern->getCommonPtr()->PartialSpecializations.InsertNode(Partial); } else { - CanonPattern->getSpecializations().InsertNode(D); + CanonPattern->getCommonPtr()->Specializations.InsertNode(D); } } } @@ -975,23 +1136,25 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D) { VisitClassTemplateSpecializationDecl(D); - D->initTemplateParameters(Reader.ReadTemplateParameterList(Record, Idx)); - - TemplateArgumentListInfo ArgInfos; + ASTContext &C = *Reader.getContext(); + D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx); + unsigned NumArgs = Record[Idx++]; - while (NumArgs--) - ArgInfos.addArgument(Reader.ReadTemplateArgumentLoc(Cursor, Record, Idx)); - D->initTemplateArgsAsWritten(ArgInfos); - - D->setSequenceNumber(Record[Idx++]); + if (NumArgs) { + D->NumArgsAsWritten = NumArgs; + D->ArgsAsWritten = new (C) TemplateArgumentLoc[NumArgs]; + for (unsigned i=0; i != NumArgs; ++i) + D->ArgsAsWritten[i] = Reader.ReadTemplateArgumentLoc(F, Record, Idx); + } + + D->SequenceNumber = Record[Idx++]; // These are read/set from/to the first declaration. if (D->getPreviousDeclaration() == 0) { - D->setInstantiatedFromMember( + D->InstantiatedFromMember.setPointer( cast_or_null<ClassTemplatePartialSpecializationDecl>( Reader.GetDecl(Record[Idx++]))); - if (Record[Idx++]) - D->setMemberSpecialization(); + D->InstantiatedFromMember.setInt(Record[Idx++]); } } @@ -1003,7 +1166,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { // Read the function specialization declarations. // FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled - // through the specialized FunctionDecl's setFunctionTemplateSpecialization. + // when reading the specialized FunctionDecl. unsigned NumSpecs = Record[Idx++]; while (NumSpecs--) Reader.GetDecl(Record[Idx++]); @@ -1017,21 +1180,30 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setParameterPack(Record[Idx++]); bool Inherited = Record[Idx++]; - TypeSourceInfo *DefArg = Reader.GetTypeSourceInfo(Cursor, Record, Idx); + TypeSourceInfo *DefArg = GetTypeSourceInfo(Record, Idx); D->setDefaultArgument(DefArg, Inherited); } void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { - VisitVarDecl(D); + VisitDeclaratorDecl(D); // TemplateParmPosition. D->setDepth(Record[Idx++]); D->setPosition(Record[Idx++]); - // Rest of NonTypeTemplateParmDecl. - if (Record[Idx++]) { - Expr *DefArg = Reader.ReadExpr(Cursor); - bool Inherited = Record[Idx++]; - D->setDefaultArgument(DefArg, Inherited); - } + if (D->isExpandedParameterPack()) { + void **Data = reinterpret_cast<void **>(D + 1); + for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { + Data[2*I] = Reader.GetType(Record[Idx++]).getAsOpaquePtr(); + Data[2*I + 1] = GetTypeSourceInfo(Record, Idx); + } + } else { + // Rest of NonTypeTemplateParmDecl. + D->ParameterPack = Record[Idx++]; + if (Record[Idx++]) { + Expr *DefArg = Reader.ReadExpr(F); + bool Inherited = Record[Idx++]; + D->setDefaultArgument(DefArg, Inherited); + } + } } void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { @@ -1040,15 +1212,16 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { D->setDepth(Record[Idx++]); D->setPosition(Record[Idx++]); // Rest of TemplateTemplateParmDecl. - TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(Cursor, Record, Idx); + TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(F, Record, Idx); bool IsInherited = Record[Idx++]; D->setDefaultArgument(Arg, IsInherited); + D->ParameterPack = Record[Idx++]; } void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) { VisitDecl(D); - D->AssertExpr = Reader.ReadExpr(Cursor); - D->Message = cast<StringLiteral>(Reader.ReadExpr(Cursor)); + D->AssertExpr = Reader.ReadExpr(F); + D->Message = cast<StringLiteral>(Reader.ReadExpr(F)); } std::pair<uint64_t, uint64_t> @@ -1068,10 +1241,20 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { " reading"); case NoRedeclaration: break; - case PointsToPrevious: + case PointsToPrevious: { + DeclID PreviousDeclID = Record[Idx++]; + DeclID FirstDeclID = Record[Idx++]; + // We delay loading of the redeclaration chain to avoid deeply nested calls. + // We temporarily set the first (canonical) declaration as the previous one + // which is the one that matters and mark the real previous DeclID to be + // loaded & attached later on. D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink( - cast_or_null<T>(Reader.GetDecl(Record[Idx++]))); + cast_or_null<T>(Reader.GetDecl(FirstDeclID))); + if (PreviousDeclID != FirstDeclID) + Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D), + PreviousDeclID)); break; + } case PointsToLatest: D->RedeclLink = typename Redeclarable<T>::LatestDeclLink( cast_or_null<T>(Reader.GetDecl(Record[Idx++]))); @@ -1095,12 +1278,6 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { = Reader.FirstLatestDeclIDs.find(ThisDeclID); if (I != Reader.FirstLatestDeclIDs.end()) { Decl *NewLatest = Reader.GetDecl(I->second); - assert((D->getMostRecentDeclaration()->getLocation().isInvalid() || - NewLatest->getLocation().isInvalid() || - Reader.SourceMgr.isBeforeInTranslationUnit( - D->getMostRecentDeclaration()->getLocation(), - NewLatest->getLocation())) && - "The new latest is supposed to come after the previous latest"); D->RedeclLink = typename Redeclarable<T>::LatestDeclLink(cast_or_null<T>(NewLatest)); } @@ -1111,28 +1288,16 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { //===----------------------------------------------------------------------===// /// \brief Reads attributes from the current stream position. -void ASTReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor, - AttrVec &Attrs) { - unsigned Code = DeclsCursor.ReadCode(); - assert(Code == llvm::bitc::UNABBREV_RECORD && - "Expected unabbreviated record"); (void)Code; - - RecordData Record; - unsigned Idx = 0; - unsigned RecCode = DeclsCursor.ReadRecord(Code, Record); - assert(RecCode == DECL_ATTR && "Expected attribute record"); - (void)RecCode; - - while (Idx < Record.size()) { +void ASTReader::ReadAttributes(PerFileData &F, AttrVec &Attrs, + const RecordData &Record, unsigned &Idx) { + for (unsigned i = 0, e = Record[Idx++]; i != e; ++i) { Attr *New = 0; attr::Kind Kind = (attr::Kind)Record[Idx++]; - SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[Idx++]); - bool isInherited = Record[Idx++]; + SourceLocation Loc = ReadSourceLocation(F, Record, Idx); #include "clang/Serialization/AttrPCHRead.inc" assert(New && "Unable to decode attribute?"); - New->setInherited(isInherited); Attrs.push_back(New); } } @@ -1176,7 +1341,7 @@ ASTReader::DeclCursorForIndex(unsigned Index, DeclID ID) { // See if there's an override. DeclReplacementMap::iterator It = ReplacedDecls.find(ID); if (It != ReplacedDecls.end()) - return RecordLocation(&It->second.first->DeclsCursor, It->second.second); + return RecordLocation(It->second.first, It->second.second); PerFileData *F = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { @@ -1186,13 +1351,32 @@ ASTReader::DeclCursorForIndex(unsigned Index, DeclID ID) { Index -= F->LocalNumDecls; } assert(F && F->LocalNumDecls > Index && "Broken chain"); - return RecordLocation(&F->DeclsCursor, F->DeclOffsets[Index]); + return RecordLocation(F, F->DeclOffsets[Index]); +} + +void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) { + assert(D && previous); + if (TagDecl *TD = dyn_cast<TagDecl>(D)) { + TD->RedeclLink.setPointer(cast<TagDecl>(previous)); + } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + FD->RedeclLink.setPointer(cast<FunctionDecl>(previous)); + } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) { + VD->RedeclLink.setPointer(cast<VarDecl>(previous)); + } else { + RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D); + TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous); + } +} + +void ASTReader::loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID) { + Decl *previous = GetDecl(ID); + ASTDeclReader::attachPreviousDecl(D, previous); } /// \brief Read the declaration at the given offset from the AST file. Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { RecordLocation Loc = DeclCursorForIndex(Index, ID); - llvm::BitstreamCursor &DeclsCursor = *Loc.first; + llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor; // Keep track of where we are in the stream, then jump back there // after reading this declaration. SavedStreamPosition SavedPosition(DeclsCursor); @@ -1202,15 +1386,14 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { // Note that we are loading a declaration record. Deserializing ADecl(this); - DeclsCursor.JumpToBit(Loc.second); + DeclsCursor.JumpToBit(Loc.Offset); RecordData Record; unsigned Code = DeclsCursor.ReadCode(); unsigned Idx = 0; - ASTDeclReader Reader(*this, DeclsCursor, ID, Record, Idx); + ASTDeclReader Reader(*this, *Loc.F, DeclsCursor, ID, Record, Idx); Decl *D = 0; switch ((DeclCode)DeclsCursor.ReadRecord(Code, Record)) { - case DECL_ATTR: case DECL_CONTEXT_LEXICAL: case DECL_CONTEXT_VISIBLE: assert(false && "Record cannot be de-serialized with ReadDeclRecord"); @@ -1241,6 +1424,9 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { (LinkageSpecDecl::LanguageIDs)0, false); break; + case DECL_LABEL: + D = LabelDecl::Create(*Context, 0, SourceLocation(), 0); + break; case DECL_NAMESPACE: D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0); break; @@ -1289,8 +1475,7 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { D = CXXConversionDecl::Create(*Context, Decl::EmptyShell()); break; case DECL_ACCESS_SPEC: - D = AccessSpecDecl::Create(*Context, AS_none, 0, SourceLocation(), - SourceLocation()); + D = AccessSpecDecl::Create(*Context, Decl::EmptyShell()); break; case DECL_FRIEND: D = FriendDecl::Create(*Context, Decl::EmptyShell()); @@ -1318,10 +1503,16 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { break; case DECL_NON_TYPE_TEMPLATE_PARM: D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0, - QualType(),0); + QualType(), false, 0); + break; + case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: + D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0, 0, + 0, QualType(), 0, 0, Record[Idx++], + 0); break; case DECL_TEMPLATE_TEMPLATE_PARM: - D = TemplateTemplateParmDecl::Create(*Context, 0, SourceLocation(),0,0,0,0); + D = TemplateTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0, 0, + false, 0, 0); break; case DECL_STATIC_ASSERT: D = StaticAssertDecl::Create(*Context, 0, SourceLocation(), 0, 0); @@ -1371,12 +1562,17 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { case DECL_OBJC_PROPERTY_IMPL: D = ObjCPropertyImplDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 0, - ObjCPropertyImplDecl::Dynamic, 0); + ObjCPropertyImplDecl::Dynamic, 0, + SourceLocation()); break; case DECL_FIELD: D = FieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, 0, false); break; + case DECL_INDIRECTFIELD: + D = IndirectFieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), + 0, 0); + break; case DECL_VAR: D = VarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, SC_None, SC_None); @@ -1396,6 +1592,9 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { case DECL_BLOCK: D = BlockDecl::Create(*Context, 0, SourceLocation()); break; + case DECL_CXX_BASE_SPECIFIERS: + Error("attempt to read a C++ base-specifier record as a declaration"); + return 0; } assert(D && "Unknown declaration reading AST file"); @@ -1435,21 +1634,29 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { } } } + assert(Idx == Record.size()); - // If this is a template, read additional specializations that may be in a - // different part of the chain. - if (isa<RedeclarableTemplateDecl>(D)) { - AdditionalTemplateSpecializationsMap::iterator F = - AdditionalTemplateSpecializationsPending.find(ID); - if (F != AdditionalTemplateSpecializationsPending.end()) { - for (AdditionalTemplateSpecializations::iterator I = F->second.begin(), - E = F->second.end(); - I != E; ++I) - GetDecl(*I); - AdditionalTemplateSpecializationsPending.erase(F); + // The declaration may have been modified by files later in the chain. + // If this is the case, read the record containing the updates from each file + // and pass it to ASTDeclReader to make the modifications. + DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID); + if (UpdI != DeclUpdateOffsets.end()) { + FileOffsetsTy &UpdateOffsets = UpdI->second; + for (FileOffsetsTy::iterator + I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) { + PerFileData *F = I->first; + uint64_t Offset = I->second; + llvm::BitstreamCursor &Cursor = F->DeclsCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(Offset); + RecordData Record; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.ReadRecord(Code, Record); + (void)RecCode; + assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!"); + Reader.UpdateDecl(D, Record); } } - assert(Idx == Record.size()); // If we have deserialized a declaration that has a definition the // AST consumer might need to know about, queue it. @@ -1460,3 +1667,27 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { return D; } + +void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) { + unsigned Idx = 0; + while (Idx < Record.size()) { + switch ((DeclUpdateKind)Record[Idx++]) { + case UPD_CXX_SET_DEFINITIONDATA: { + CXXRecordDecl *RD = cast<CXXRecordDecl>(D); + CXXRecordDecl * + DefinitionDecl = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])); + assert(!RD->DefinitionData && "DefinitionData is already set!"); + InitializeCXXDefinitionData(RD, DefinitionDecl, Record, Idx); + break; + } + + case UPD_CXX_ADDED_IMPLICIT_MEMBER: + cast<CXXRecordDecl>(D)->addedMember(Reader.GetDecl(Record[Idx++])); + break; + + case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: + // It will be added to the template's specializations set when loaded. + Reader.GetDecl(Record[Idx++]); + } + } +} diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp index ee5d40a..4e91c98 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp @@ -14,6 +14,7 @@ #include "clang/Serialization/ASTReader.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/StmtVisitor.h" using namespace clang; using namespace clang::serialization; @@ -22,14 +23,36 @@ namespace clang { class ASTStmtReader : public StmtVisitor<ASTStmtReader> { ASTReader &Reader; + ASTReader::PerFileData &F; llvm::BitstreamCursor &DeclsCursor; const ASTReader::RecordData &Record; unsigned &Idx; + SourceLocation ReadSourceLocation(const ASTReader::RecordData &R, + unsigned &I) { + return Reader.ReadSourceLocation(F, R, I); + } + SourceRange ReadSourceRange(const ASTReader::RecordData &R, unsigned &I) { + return Reader.ReadSourceRange(F, R, I); + } + TypeSourceInfo *GetTypeSourceInfo(const ASTReader::RecordData &R, + unsigned &I) { + return Reader.GetTypeSourceInfo(F, R, I); + } + void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name, + const ASTReader::RecordData &R, unsigned &I) { + Reader.ReadDeclarationNameLoc(F, DNLoc, Name, R, I); + } + void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo, + const ASTReader::RecordData &R, unsigned &I) { + Reader.ReadDeclarationNameInfo(F, NameInfo, R, I); + } + public: - ASTStmtReader(ASTReader &Reader, llvm::BitstreamCursor &Cursor, + ASTStmtReader(ASTReader &Reader, ASTReader::PerFileData &F, + llvm::BitstreamCursor &Cursor, const ASTReader::RecordData &Record, unsigned &Idx) - : Reader(Reader), DeclsCursor(Cursor), Record(Record), Idx(Idx) { } + : Reader(Reader), F(F), DeclsCursor(Cursor), Record(Record), Idx(Idx) { } /// \brief The number of record fields required for the Stmt class /// itself. @@ -37,7 +60,7 @@ namespace clang { /// \brief The number of record fields required for the Expr class /// itself. - static const unsigned NumExprFields = NumStmtFields + 3; + static const unsigned NumExprFields = NumStmtFields + 6; /// \brief Read and initialize a ExplicitTemplateArgumentList structure. void ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList, @@ -82,6 +105,7 @@ namespace clang { void VisitBinaryOperator(BinaryOperator *E); void VisitCompoundAssignOperator(CompoundAssignOperator *E); void VisitConditionalOperator(ConditionalOperator *E); + void VisitBinaryConditionalOperator(BinaryConditionalOperator *E); void VisitImplicitCastExpr(ImplicitCastExpr *E); void VisitExplicitCastExpr(ExplicitCastExpr *E); void VisitCStyleCastExpr(CStyleCastExpr *E); @@ -93,7 +117,6 @@ namespace clang { void VisitVAArgExpr(VAArgExpr *E); void VisitAddrLabelExpr(AddrLabelExpr *E); void VisitStmtExpr(StmtExpr *E); - void VisitTypesCompatibleExpr(TypesCompatibleExpr *E); void VisitChooseExpr(ChooseExpr *E); void VisitGNUNullExpr(GNUNullExpr *E); void VisitShuffleVectorExpr(ShuffleVectorExpr *E); @@ -105,10 +128,7 @@ namespace clang { void VisitObjCProtocolExpr(ObjCProtocolExpr *E); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E); void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); - void VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E); void VisitObjCMessageExpr(ObjCMessageExpr *E); - void VisitObjCSuperExpr(ObjCSuperExpr *E); void VisitObjCIsaExpr(ObjCIsaExpr *E); void VisitObjCForCollectionStmt(ObjCForCollectionStmt *); @@ -134,6 +154,7 @@ namespace clang { void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); void VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E); void VisitCXXTypeidExpr(CXXTypeidExpr *E); + void VisitCXXUuidofExpr(CXXUuidofExpr *E); void VisitCXXThisExpr(CXXThisExpr *E); void VisitCXXThrowExpr(CXXThrowExpr *E); void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); @@ -144,7 +165,7 @@ namespace clang { void VisitCXXDeleteExpr(CXXDeleteExpr *E); void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); - void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E); + void VisitExprWithCleanups(ExprWithCleanups *E); void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); @@ -155,6 +176,16 @@ namespace clang { void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E); void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); + void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); + void VisitCXXNoexceptExpr(CXXNoexceptExpr *E); + void VisitPackExpansionExpr(PackExpansionExpr *E); + void VisitSizeOfPackExpr(SizeOfPackExpr *E); + void VisitSubstNonTypeTemplateParmPackExpr( + SubstNonTypeTemplateParmPackExpr *E); + void VisitOpaqueValueExpr(OpaqueValueExpr *E); + + // CUDA Expressions + void VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E); }; } @@ -162,11 +193,11 @@ void ASTStmtReader:: ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList, unsigned NumTemplateArgs) { TemplateArgumentListInfo ArgInfo; - ArgInfo.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx)); - ArgInfo.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx)); + ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx)); + ArgInfo.setRAngleLoc(ReadSourceLocation(Record, Idx)); for (unsigned i = 0; i != NumTemplateArgs; ++i) ArgInfo.addArgument( - Reader.ReadTemplateArgumentLoc(DeclsCursor, Record, Idx)); + Reader.ReadTemplateArgumentLoc(F, Record, Idx)); ArgList.initializeFrom(ArgInfo); } @@ -176,7 +207,8 @@ void ASTStmtReader::VisitStmt(Stmt *S) { void ASTStmtReader::VisitNullStmt(NullStmt *S) { VisitStmt(S); - S->setSemiLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setSemiLoc(ReadSourceLocation(Record, Idx)); + S->LeadingEmptyMacro = Record[Idx++]; } void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) { @@ -186,8 +218,8 @@ void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) { while (NumStmts--) Stmts.push_back(Reader.ReadSubStmt()); S->setStmts(*Reader.getContext(), Stmts.data(), Stmts.size()); - S->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setLBracLoc(ReadSourceLocation(Record, Idx)); + S->setRBracLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitSwitchCase(SwitchCase *S) { @@ -200,24 +232,25 @@ void ASTStmtReader::VisitCaseStmt(CaseStmt *S) { S->setLHS(Reader.ReadSubExpr()); S->setRHS(Reader.ReadSubExpr()); S->setSubStmt(Reader.ReadSubStmt()); - S->setCaseLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setEllipsisLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setCaseLoc(ReadSourceLocation(Record, Idx)); + S->setEllipsisLoc(ReadSourceLocation(Record, Idx)); + S->setColonLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) { VisitSwitchCase(S); S->setSubStmt(Reader.ReadSubStmt()); - S->setDefaultLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setDefaultLoc(ReadSourceLocation(Record, Idx)); + S->setColonLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitLabelStmt(LabelStmt *S) { VisitStmt(S); - S->setID(Reader.GetIdentifierInfo(Record, Idx)); + LabelDecl *LD = cast<LabelDecl>(Reader.GetDecl(Record[Idx++])); + LD->setStmt(S); + S->setDecl(LD); S->setSubStmt(Reader.ReadSubStmt()); - S->setIdentLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - Reader.RecordLabelStmt(S, Record[Idx++]); + S->setIdentLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitIfStmt(IfStmt *S) { @@ -227,8 +260,8 @@ void ASTStmtReader::VisitIfStmt(IfStmt *S) { S->setCond(Reader.ReadSubExpr()); S->setThen(Reader.ReadSubStmt()); S->setElse(Reader.ReadSubStmt()); - S->setIfLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setElseLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setIfLoc(ReadSourceLocation(Record, Idx)); + S->setElseLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) { @@ -237,7 +270,10 @@ void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) { cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]))); S->setCond(Reader.ReadSubExpr()); S->setBody(Reader.ReadSubStmt()); - S->setSwitchLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setSwitchLoc(ReadSourceLocation(Record, Idx)); + if (Record[Idx++]) + S->setAllEnumCasesCovered(); + SwitchCase *PrevSC = 0; for (unsigned N = Record.size(); Idx != N; ++Idx) { SwitchCase *SC = Reader.getSwitchCaseWithID(Record[Idx]); @@ -246,9 +282,6 @@ void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) { else S->setSwitchCaseList(SC); - // Retain this SwitchCase, since SwitchStmt::addSwitchCase() would - // normally retain it (but we aren't calling addSwitchCase). - SC->Retain(); PrevSC = SC; } } @@ -259,16 +292,16 @@ void ASTStmtReader::VisitWhileStmt(WhileStmt *S) { cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]))); S->setCond(Reader.ReadSubExpr()); S->setBody(Reader.ReadSubStmt()); - S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setWhileLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitDoStmt(DoStmt *S) { VisitStmt(S); S->setCond(Reader.ReadSubExpr()); S->setBody(Reader.ReadSubStmt()); - S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setDoLoc(ReadSourceLocation(Record, Idx)); + S->setWhileLoc(ReadSourceLocation(Record, Idx)); + S->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitForStmt(ForStmt *S) { @@ -279,46 +312,46 @@ void ASTStmtReader::VisitForStmt(ForStmt *S) { cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]))); S->setInc(Reader.ReadSubExpr()); S->setBody(Reader.ReadSubStmt()); - S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setForLoc(ReadSourceLocation(Record, Idx)); + S->setLParenLoc(ReadSourceLocation(Record, Idx)); + S->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitGotoStmt(GotoStmt *S) { VisitStmt(S); - Reader.SetLabelOf(S, Record[Idx++]); - S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setLabel(cast<LabelDecl>(Reader.GetDecl(Record[Idx++]))); + S->setGotoLoc(ReadSourceLocation(Record, Idx)); + S->setLabelLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) { VisitStmt(S); - S->setGotoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setGotoLoc(ReadSourceLocation(Record, Idx)); + S->setStarLoc(ReadSourceLocation(Record, Idx)); S->setTarget(Reader.ReadSubExpr()); } void ASTStmtReader::VisitContinueStmt(ContinueStmt *S) { VisitStmt(S); - S->setContinueLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setContinueLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitBreakStmt(BreakStmt *S) { VisitStmt(S); - S->setBreakLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setBreakLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitReturnStmt(ReturnStmt *S) { VisitStmt(S); S->setRetValue(Reader.ReadSubExpr()); - S->setReturnLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setReturnLoc(ReadSourceLocation(Record, Idx)); S->setNRVOCandidate(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]))); } void ASTStmtReader::VisitDeclStmt(DeclStmt *S) { VisitStmt(S); - S->setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setStartLoc(ReadSourceLocation(Record, Idx)); + S->setEndLoc(ReadSourceLocation(Record, Idx)); if (Idx + 1 == Record.size()) { // Single declaration @@ -339,8 +372,8 @@ void ASTStmtReader::VisitAsmStmt(AsmStmt *S) { unsigned NumOutputs = Record[Idx++]; unsigned NumInputs = Record[Idx++]; unsigned NumClobbers = Record[Idx++]; - S->setAsmLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setAsmLoc(ReadSourceLocation(Record, Idx)); + S->setRParenLoc(ReadSourceLocation(Record, Idx)); S->setVolatile(Record[Idx++]); S->setSimple(Record[Idx++]); S->setMSAsm(Record[Idx++]); @@ -373,12 +406,15 @@ void ASTStmtReader::VisitExpr(Expr *E) { E->setType(Reader.GetType(Record[Idx++])); E->setTypeDependent(Record[Idx++]); E->setValueDependent(Record[Idx++]); + E->ExprBits.ContainsUnexpandedParameterPack = Record[Idx++]; + E->setValueKind(static_cast<ExprValueKind>(Record[Idx++])); + E->setObjectKind(static_cast<ExprObjectKind>(Record[Idx++])); assert(Idx == NumExprFields && "Incorrect expression field count"); } void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) { VisitExpr(E); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]); } @@ -386,28 +422,31 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); bool HasQualifier = Record[Idx++]; - unsigned NumTemplateArgs = Record[Idx++]; + bool HasExplicitTemplateArgs = Record[Idx++]; E->DecoratedD.setInt((HasQualifier? DeclRefExpr::HasQualifierFlag : 0) | - (NumTemplateArgs ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0)); + (HasExplicitTemplateArgs + ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0)); if (HasQualifier) { E->getNameQualifier()->NNS = Reader.ReadNestedNameSpecifier(Record, Idx); - E->getNameQualifier()->Range = Reader.ReadSourceRange(Record, Idx); + E->getNameQualifier()->Range = ReadSourceRange(Record, Idx); } - if (NumTemplateArgs) + if (HasExplicitTemplateArgs) { + unsigned NumTemplateArgs = Record[Idx++]; ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), NumTemplateArgs); + } E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++]))); - // FIXME: read DeclarationNameLoc. - E->setLocation(Reader.ReadSourceLocation(Record, Idx)); + E->setLocation(ReadSourceLocation(Record, Idx)); + ReadDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record, Idx); } void ASTStmtReader::VisitIntegerLiteral(IntegerLiteral *E) { VisitExpr(E); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); E->setValue(*Reader.getContext(), Reader.ReadAPInt(Record, Idx)); } @@ -415,7 +454,7 @@ void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) { VisitExpr(E); E->setValue(*Reader.getContext(), Reader.ReadAPFloat(Record, Idx)); E->setExact(Record[Idx++]); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitImaginaryLiteral(ImaginaryLiteral *E) { @@ -438,20 +477,20 @@ void ASTStmtReader::VisitStringLiteral(StringLiteral *E) { // Read source locations for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I) - E->setStrTokenLoc(I, SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setStrTokenLoc(I, ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitCharacterLiteral(CharacterLiteral *E) { VisitExpr(E); E->setValue(Record[Idx++]); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); E->setWide(Record[Idx++]); } void ASTStmtReader::VisitParenExpr(ParenExpr *E) { VisitExpr(E); - E->setLParen(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParen(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLParen(ReadSourceLocation(Record, Idx)); + E->setRParen(ReadSourceLocation(Record, Idx)); E->setSubExpr(Reader.ReadSubExpr()); } @@ -462,15 +501,15 @@ void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) { for (unsigned i = 0; i != NumExprs; ++i) E->Exprs[i] = Reader.ReadSubStmt(); E->NumExprs = NumExprs; - E->LParenLoc = Reader.ReadSourceLocation(Record, Idx); - E->RParenLoc = Reader.ReadSourceLocation(Record, Idx); + E->LParenLoc = ReadSourceLocation(Record, Idx); + E->RParenLoc = ReadSourceLocation(Record, Idx); } void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) { VisitExpr(E); E->setSubExpr(Reader.ReadSubExpr()); E->setOpcode((UnaryOperator::Opcode)Record[Idx++]); - E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setOperatorLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) { @@ -480,13 +519,13 @@ void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) { ++Idx; assert(E->getNumExpressions() == Record[Idx]); ++Idx; - E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setTypeSourceInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); + E->setOperatorLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); + E->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) { Node::Kind Kind = static_cast<Node::Kind>(Record[Idx++]); - SourceLocation Start = SourceLocation::getFromRawEncoding(Record[Idx++]); - SourceLocation End = SourceLocation::getFromRawEncoding(Record[Idx++]); + SourceLocation Start = ReadSourceLocation(Record, Idx); + SourceLocation End = ReadSourceLocation(Record, Idx); switch (Kind) { case Node::Array: E->setComponent(I, Node(Start, Record[Idx++], End)); @@ -505,7 +544,7 @@ void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) { case Node::Base: { CXXBaseSpecifier *Base = new (*Reader.getContext()) CXXBaseSpecifier(); - *Base = Reader.ReadCXXBaseSpecifier(DeclsCursor, Record, Idx); + *Base = Reader.ReadCXXBaseSpecifier(F, Record, Idx); E->setComponent(I, Node(Base)); break; } @@ -523,23 +562,23 @@ void ASTStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { E->setArgument(Reader.ReadSubExpr()); ++Idx; } else { - E->setArgument(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); + E->setArgument(GetTypeSourceInfo(Record, Idx)); } - E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setOperatorLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { VisitExpr(E); E->setLHS(Reader.ReadSubExpr()); E->setRHS(Reader.ReadSubExpr()); - E->setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setRBracketLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); E->setNumArgs(*Reader.getContext(), Record[Idx++]); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); E->setCallee(Reader.ReadSubExpr()); for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) E->setArg(I, Reader.ReadSubExpr()); @@ -554,7 +593,7 @@ void ASTStmtReader::VisitMemberExpr(MemberExpr *E) { void ASTStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) { VisitExpr(E); E->setBase(Reader.ReadSubExpr()); - E->setIsaMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setIsaMemberLoc(ReadSourceLocation(Record, Idx)); E->setArrow(Record[Idx++]); } @@ -567,7 +606,7 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) { CastExpr::path_iterator BaseI = E->path_begin(); while (NumBaseSpecs--) { CXXBaseSpecifier *BaseSpec = new (*Reader.getContext()) CXXBaseSpecifier; - *BaseSpec = Reader.ReadCXXBaseSpecifier(DeclsCursor, Record, Idx); + *BaseSpec = Reader.ReadCXXBaseSpecifier(F, Record, Idx); *BaseI++ = BaseSpec; } } @@ -577,7 +616,7 @@ void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) { E->setLHS(Reader.ReadSubExpr()); E->setRHS(Reader.ReadSubExpr()); E->setOpcode((BinaryOperator::Opcode)Record[Idx++]); - E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setOperatorLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) { @@ -588,34 +627,46 @@ void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) { void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) { VisitExpr(E); - E->setCond(Reader.ReadSubExpr()); - E->setLHS(Reader.ReadSubExpr()); - E->setRHS(Reader.ReadSubExpr()); - E->setSAVE(Reader.ReadSubExpr()); - E->setQuestionLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->SubExprs[ConditionalOperator::COND] = Reader.ReadSubExpr(); + E->SubExprs[ConditionalOperator::LHS] = Reader.ReadSubExpr(); + E->SubExprs[ConditionalOperator::RHS] = Reader.ReadSubExpr(); + E->QuestionLoc = ReadSourceLocation(Record, Idx); + E->ColonLoc = ReadSourceLocation(Record, Idx); +} + +void +ASTStmtReader::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) { + VisitExpr(E); + E->OpaqueValue = cast<OpaqueValueExpr>(Reader.ReadSubExpr()); + E->SubExprs[BinaryConditionalOperator::COMMON] = Reader.ReadSubExpr(); + E->SubExprs[BinaryConditionalOperator::COND] = Reader.ReadSubExpr(); + E->SubExprs[BinaryConditionalOperator::LHS] = Reader.ReadSubExpr(); + E->SubExprs[BinaryConditionalOperator::RHS] = Reader.ReadSubExpr(); + E->QuestionLoc = ReadSourceLocation(Record, Idx); + E->ColonLoc = ReadSourceLocation(Record, Idx); + + E->getOpaqueValue()->setSourceExpr(E->getCommon()); } void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - E->setValueKind(static_cast<ExprValueKind>(Record[Idx++])); } void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { VisitCastExpr(E); - E->setTypeInfoAsWritten(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); + E->setTypeInfoAsWritten(GetTypeSourceInfo(Record, Idx)); } void ASTStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) { VisitExplicitCastExpr(E); - E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLParenLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { VisitExpr(E); - E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setTypeSourceInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); + E->setLParenLoc(ReadSourceLocation(Record, Idx)); + E->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); E->setInitializer(Reader.ReadSubExpr()); E->setFileScope(Record[Idx++]); } @@ -624,7 +675,7 @@ void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { VisitExpr(E); E->setBase(Reader.ReadSubExpr()); E->setAccessor(Reader.GetIdentifierInfo(Record, Idx)); - E->setAccessorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setAccessorLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitInitListExpr(InitListExpr *E) { @@ -634,8 +685,8 @@ void ASTStmtReader::VisitInitListExpr(InitListExpr *E) { for (unsigned I = 0; I != NumInits; ++I) E->updateInit(*Reader.getContext(), I, Reader.ReadSubExpr()); E->setSyntacticForm(cast_or_null<InitListExpr>(Reader.ReadSubStmt())); - E->setLBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLBraceLoc(ReadSourceLocation(Record, Idx)); + E->setRBraceLoc(ReadSourceLocation(Record, Idx)); E->setInitializedFieldInUnion( cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]))); E->sawArrayRangeDesignator(Record[Idx++]); @@ -649,7 +700,7 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) { assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs"); for (unsigned I = 0; I != NumSubExprs; ++I) E->setSubExpr(I, Reader.ReadSubExpr()); - E->setEqualOrColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setEqualOrColonLoc(ReadSourceLocation(Record, Idx)); E->setGNUSyntax(Record[Idx++]); llvm::SmallVector<Designator, 4> Designators; @@ -658,9 +709,9 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) { case DESIG_FIELD_DECL: { FieldDecl *Field = cast<FieldDecl>(Reader.GetDecl(Record[Idx++])); SourceLocation DotLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); SourceLocation FieldLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); Designators.push_back(Designator(Field->getIdentifier(), DotLoc, FieldLoc)); Designators.back().setField(Field); @@ -670,9 +721,9 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) { case DESIG_FIELD_NAME: { const IdentifierInfo *Name = Reader.GetIdentifierInfo(Record, Idx); SourceLocation DotLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); SourceLocation FieldLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); Designators.push_back(Designator(Name, DotLoc, FieldLoc)); break; } @@ -680,9 +731,9 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) { case DESIG_ARRAY: { unsigned Index = Record[Idx++]; SourceLocation LBracketLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); SourceLocation RBracketLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc)); break; } @@ -690,11 +741,11 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) { case DESIG_ARRAY_RANGE: { unsigned Index = Record[Idx++]; SourceLocation LBracketLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); SourceLocation EllipsisLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); SourceLocation RBracketLoc - = SourceLocation::getFromRawEncoding(Record[Idx++]); + = ReadSourceLocation(Record, Idx); Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc, RBracketLoc)); break; @@ -712,45 +763,37 @@ void ASTStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { void ASTStmtReader::VisitVAArgExpr(VAArgExpr *E) { VisitExpr(E); E->setSubExpr(Reader.ReadSubExpr()); - E->setWrittenTypeInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); - E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setWrittenTypeInfo(GetTypeSourceInfo(Record, Idx)); + E->setBuiltinLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) { VisitExpr(E); - E->setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - Reader.SetLabelOf(E, Record[Idx++]); + E->setAmpAmpLoc(ReadSourceLocation(Record, Idx)); + E->setLabelLoc(ReadSourceLocation(Record, Idx)); + E->setLabel(cast<LabelDecl>(Reader.GetDecl(Record[Idx++]))); } void ASTStmtReader::VisitStmtExpr(StmtExpr *E) { VisitExpr(E); - E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLParenLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); E->setSubStmt(cast_or_null<CompoundStmt>(Reader.ReadSubStmt())); } -void ASTStmtReader::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { - VisitExpr(E); - E->setArgTInfo1(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); - E->setArgTInfo2(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); - E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} - void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) { VisitExpr(E); E->setCond(Reader.ReadSubExpr()); E->setLHS(Reader.ReadSubExpr()); E->setRHS(Reader.ReadSubExpr()); - E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setBuiltinLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitGNUNullExpr(GNUNullExpr *E) { VisitExpr(E); - E->setTokenLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setTokenLocation(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { @@ -760,23 +803,21 @@ void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { while (NumExprs--) Exprs.push_back(Reader.ReadSubExpr()); E->setExprs(*Reader.getContext(), Exprs.data(), Exprs.size()); - E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setBuiltinLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitBlockExpr(BlockExpr *E) { VisitExpr(E); E->setBlockDecl(cast_or_null<BlockDecl>(Reader.GetDecl(Record[Idx++]))); - E->setHasBlockDeclRefExprs(Record[Idx++]); } void ASTStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { VisitExpr(E); - E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++]))); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setDecl(cast<VarDecl>(Reader.GetDecl(Record[Idx++]))); + E->setLocation(ReadSourceLocation(Record, Idx)); E->setByRef(Record[Idx++]); E->setConstQualAdded(Record[Idx++]); - E->setCopyConstructorExpr(Reader.ReadSubExpr()); } //===----------------------------------------------------------------------===// @@ -785,34 +826,34 @@ void ASTStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { void ASTStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) { VisitExpr(E); E->setString(cast<StringLiteral>(Reader.ReadSubStmt())); - E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setAtLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { VisitExpr(E); - E->setEncodedTypeSourceInfo(Reader.GetTypeSourceInfo(DeclsCursor,Record,Idx)); - E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setEncodedTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); + E->setAtLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) { VisitExpr(E); E->setSelector(Reader.GetSelector(Record, Idx)); - E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setAtLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) { VisitExpr(E); E->setProtocol(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++]))); - E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setAtLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { VisitExpr(E); E->setDecl(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++]))); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); E->setBase(Reader.ReadSubExpr()); E->setIsArrow(Record[Idx++]); E->setIsFreeIvar(Record[Idx++]); @@ -820,23 +861,31 @@ void ASTStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { VisitExpr(E); - E->setProperty(cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++]))); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setBase(Reader.ReadSubExpr()); -} - -void ASTStmtReader::VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E) { - VisitExpr(E); - E->setGetterMethod( - cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++]))); - E->setSetterMethod( - cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++]))); - E->setInterfaceDecl( - cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]))); - E->setBase(Reader.ReadSubExpr()); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + bool Implicit = Record[Idx++] != 0; + if (Implicit) { + ObjCMethodDecl *Getter = + cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])); + ObjCMethodDecl *Setter = + cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])); + E->setImplicitProperty(Getter, Setter); + } else { + E->setExplicitProperty( + cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++]))); + } + E->setLocation(ReadSourceLocation(Record, Idx)); + E->setReceiverLocation(ReadSourceLocation(Record, Idx)); + switch (Record[Idx++]) { + case 0: + E->setBase(Reader.ReadSubExpr()); + break; + case 1: + E->setSuperReceiver(Reader.GetType(Record[Idx++])); + break; + case 2: + E->setClassReceiver( + cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]))); + break; + } } void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { @@ -851,13 +900,13 @@ void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { break; case ObjCMessageExpr::Class: - E->setClassReceiver(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); + E->setClassReceiver(GetTypeSourceInfo(Record, Idx)); break; case ObjCMessageExpr::SuperClass: case ObjCMessageExpr::SuperInstance: { QualType T = Reader.GetType(Record[Idx++]); - SourceLocation SuperLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); + SourceLocation SuperLoc = ReadSourceLocation(Record, Idx); E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance); break; } @@ -870,39 +919,35 @@ void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) { else E->setSelector(Reader.GetSelector(Record, Idx)); - E->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->LBracLoc = ReadSourceLocation(Record, Idx); + E->RBracLoc = ReadSourceLocation(Record, Idx); + E->SelectorLoc = ReadSourceLocation(Record, Idx); for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) E->setArg(I, Reader.ReadSubExpr()); } -void ASTStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) { - VisitExpr(E); - E->setLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} - void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { VisitStmt(S); S->setElement(Reader.ReadSubStmt()); S->setCollection(Reader.ReadSubExpr()); S->setBody(Reader.ReadSubStmt()); - S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setForLoc(ReadSourceLocation(Record, Idx)); + S->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) { VisitStmt(S); S->setCatchBody(Reader.ReadSubStmt()); S->setCatchParamDecl(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]))); - S->setAtCatchLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setAtCatchLoc(ReadSourceLocation(Record, Idx)); + S->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { VisitStmt(S); S->setFinallyBody(Reader.ReadSubStmt()); - S->setAtFinallyLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setAtFinallyLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { @@ -916,20 +961,20 @@ void ASTStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { if (HasFinally) S->setFinallyStmt(Reader.ReadSubStmt()); - S->setAtTryLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setAtTryLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) { VisitStmt(S); S->setSynchExpr(Reader.ReadSubStmt()); S->setSynchBody(Reader.ReadSubStmt()); - S->setAtSynchronizedLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setAtSynchronizedLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) { VisitStmt(S); S->setThrowExpr(Reader.ReadSubStmt()); - S->setThrowLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + S->setThrowLoc(ReadSourceLocation(Record, Idx)); } //===----------------------------------------------------------------------===// @@ -938,7 +983,7 @@ void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) { void ASTStmtReader::VisitCXXCatchStmt(CXXCatchStmt *S) { VisitStmt(S); - S->CatchLoc = Reader.ReadSourceLocation(Record, Idx); + S->CatchLoc = ReadSourceLocation(Record, Idx); S->ExceptionDecl = cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])); S->HandlerBlock = Reader.ReadSubStmt(); } @@ -947,7 +992,7 @@ void ASTStmtReader::VisitCXXTryStmt(CXXTryStmt *S) { VisitStmt(S); assert(Record[Idx] == S->getNumHandlers() && "NumStmtFields is wrong ?"); ++Idx; - S->TryLoc = Reader.ReadSourceLocation(Record, Idx); + S->TryLoc = ReadSourceLocation(Record, Idx); S->getStmts()[0] = Reader.ReadSubStmt(); for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i) S->getStmts()[i + 1] = Reader.ReadSubStmt(); @@ -966,21 +1011,23 @@ void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) { for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) E->setArg(I, Reader.ReadSubExpr()); E->setConstructor(cast<CXXConstructorDecl>(Reader.GetDecl(Record[Idx++]))); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); E->setElidable(Record[Idx++]); E->setRequiresZeroInitialization(Record[Idx++]); E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]); + E->ParenRange = ReadSourceRange(Record, Idx); } void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { VisitCXXConstructExpr(E); - E->TyBeginLoc = Reader.ReadSourceLocation(Record, Idx); - E->RParenLoc = Reader.ReadSourceLocation(Record, Idx); + E->Type = GetTypeSourceInfo(Record, Idx); } void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { VisitExplicitCastExpr(E); - E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + SourceRange R = ReadSourceRange(Record, Idx); + E->Loc = R.getBegin(); + E->RParenLoc = R.getEnd(); } void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) { @@ -1001,43 +1048,55 @@ void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) { void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) { VisitExplicitCastExpr(E); - E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setTypeBeginLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { VisitExpr(E); E->setValue(Record[Idx++]); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) { VisitExpr(E); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) { VisitExpr(E); - E->setSourceRange(Reader.ReadSourceRange(Record, Idx)); + E->setSourceRange(ReadSourceRange(Record, Idx)); if (E->isTypeOperand()) { // typeid(int) E->setTypeOperandSourceInfo( - Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); + GetTypeSourceInfo(Record, Idx)); return; } // typeid(42+2) E->setExprOperand(Reader.ReadSubExpr()); } +void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) { + VisitExpr(E); + E->setSourceRange(ReadSourceRange(Record, Idx)); + if (E->isTypeOperand()) { // __uuidof(ComType) + E->setTypeOperandSourceInfo( + GetTypeSourceInfo(Record, Idx)); + return; + } + + // __uuidof(expr) + E->setExprOperand(Reader.ReadSubExpr()); +} void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) { VisitExpr(E); - E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLocation(ReadSourceLocation(Record, Idx)); E->setImplicit(Record[Idx++]); } void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) { VisitExpr(E); - E->setThrowLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setThrowLoc(ReadSourceLocation(Record, Idx)); E->setSubExpr(Reader.ReadSubExpr()); } @@ -1047,7 +1106,7 @@ void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { assert(Record[Idx] == E->Param.getInt() && "We messed up at creation ?"); ++Idx; // HasOtherExprStored and SubExpr was handled during creation. E->Param.setPointer(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++]))); - E->Loc = Reader.ReadSourceLocation(Record, Idx); + E->Loc = ReadSourceLocation(Record, Idx); } void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { @@ -1058,14 +1117,15 @@ void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { VisitExpr(E); - E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->TypeInfo = GetTypeSourceInfo(Record, Idx); + E->RParenLoc = ReadSourceLocation(Record, Idx); } void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) { VisitExpr(E); - E->setGlobalNew(Record[Idx++]); - E->setHasInitializer(Record[Idx++]); + E->GlobalNew = Record[Idx++]; + E->Initializer = Record[Idx++]; + E->UsualArrayDeleteWantsSize = Record[Idx++]; bool isArray = Record[Idx++]; unsigned NumPlacementArgs = Record[Idx++]; unsigned NumCtorArgs = Record[Idx++]; @@ -1074,13 +1134,16 @@ void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) { cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]))); E->setConstructor( cast_or_null<CXXConstructorDecl>(Reader.GetDecl(Record[Idx++]))); + E->AllocatedTypeInfo = GetTypeSourceInfo(Record, Idx); SourceRange TypeIdParens; - TypeIdParens.setBegin(SourceLocation::getFromRawEncoding(Record[Idx++])); - TypeIdParens.setEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); + TypeIdParens.setBegin(ReadSourceLocation(Record, Idx)); + TypeIdParens.setEnd(ReadSourceLocation(Record, Idx)); E->TypeIdParens = TypeIdParens; - E->setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - + E->StartLoc = ReadSourceLocation(Record, Idx); + E->EndLoc = ReadSourceLocation(Record, Idx); + E->ConstructorLParen = ReadSourceLocation(Record, Idx); + E->ConstructorRParen = ReadSourceLocation(Record, Idx); + E->AllocateArgsArray(*Reader.getContext(), isArray, NumPlacementArgs, NumCtorArgs); @@ -1092,12 +1155,13 @@ void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) { void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) { VisitExpr(E); - E->setGlobalDelete(Record[Idx++]); - E->setArrayForm(Record[Idx++]); - E->setOperatorDelete( - cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]))); - E->setArgument(Reader.ReadSubExpr()); - E->setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->GlobalDelete = Record[Idx++]; + E->ArrayForm = Record[Idx++]; + E->ArrayFormAsWritten = Record[Idx++]; + E->UsualArrayDeleteWantsSize = Record[Idx++]; + E->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])); + E->Argument = Reader.ReadSubExpr(); + E->Loc = ReadSourceLocation(Record, Idx); } void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { @@ -1105,21 +1169,21 @@ void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { E->setBase(Reader.ReadSubExpr()); E->setArrow(Record[Idx++]); - E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx)); + E->setOperatorLoc(ReadSourceLocation(Record, Idx)); E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - E->setQualifierRange(Reader.ReadSourceRange(Record, Idx)); - E->setScopeTypeInfo(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); - E->setColonColonLoc(Reader.ReadSourceLocation(Record, Idx)); - E->setTildeLoc(Reader.ReadSourceLocation(Record, Idx)); + E->setQualifierRange(ReadSourceRange(Record, Idx)); + E->setScopeTypeInfo(GetTypeSourceInfo(Record, Idx)); + E->setColonColonLoc(ReadSourceLocation(Record, Idx)); + E->setTildeLoc(ReadSourceLocation(Record, Idx)); IdentifierInfo *II = Reader.GetIdentifierInfo(Record, Idx); if (II) - E->setDestroyedType(II, Reader.ReadSourceLocation(Record, Idx)); + E->setDestroyedType(II, ReadSourceLocation(Record, Idx)); else - E->setDestroyedType(Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx)); + E->setDestroyedType(GetTypeSourceInfo(Record, Idx)); } -void ASTStmtReader::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { +void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) { VisitExpr(E); unsigned NumTemps = Record[Idx++]; if (NumTemps) { @@ -1134,41 +1198,31 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ VisitExpr(E); - unsigned NumTemplateArgs = Record[Idx++]; - assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() && - "Read wrong record during creation ?"); - if (E->hasExplicitTemplateArgs()) + if (Record[Idx++]) ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), - NumTemplateArgs); + Record[Idx++]); E->setBase(Reader.ReadSubExpr()); E->setBaseType(Reader.GetType(Record[Idx++])); E->setArrow(Record[Idx++]); - E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx)); + E->setOperatorLoc(ReadSourceLocation(Record, Idx)); E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - E->setQualifierRange(Reader.ReadSourceRange(Record, Idx)); + E->setQualifierRange(ReadSourceRange(Record, Idx)); E->setFirstQualifierFoundInScope( cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]))); - // FIXME: read whole DeclarationNameInfo. - E->setMember(Reader.ReadDeclarationName(Record, Idx)); - E->setMemberLoc(Reader.ReadSourceLocation(Record, Idx)); + ReadDeclarationNameInfo(E->MemberNameInfo, Record, Idx); } void ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { VisitExpr(E); - unsigned NumTemplateArgs = Record[Idx++]; - assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() && - "Read wrong record during creation ?"); - if (E->hasExplicitTemplateArgs()) - ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), - NumTemplateArgs); - - // FIXME: read whole DeclarationNameInfo. - E->setDeclName(Reader.ReadDeclarationName(Record, Idx)); - E->setLocation(Reader.ReadSourceLocation(Record, Idx)); - E->setQualifierRange(Reader.ReadSourceRange(Record, Idx)); + if (Record[Idx++]) + ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), + Record[Idx++]); + + ReadDeclarationNameInfo(E->NameInfo, Record, Idx); + E->setQualifierRange(ReadSourceRange(Record, Idx)); E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); } @@ -1179,21 +1233,18 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { ++Idx; // NumArgs; for (unsigned I = 0, N = E->arg_size(); I != N; ++I) E->setArg(I, Reader.ReadSubExpr()); - E->setTypeBeginLoc(Reader.ReadSourceLocation(Record, Idx)); - E->setTypeAsWritten(Reader.GetType(Record[Idx++])); - E->setLParenLoc(Reader.ReadSourceLocation(Record, Idx)); - E->setRParenLoc(Reader.ReadSourceLocation(Record, Idx)); + E->Type = GetTypeSourceInfo(Record, Idx); + E->setLParenLoc(ReadSourceLocation(Record, Idx)); + E->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - unsigned NumTemplateArgs = Record[Idx++]; - assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() && - "Read wrong record during creation ?"); - if (E->hasExplicitTemplateArgs()) + // Read the explicit template argument list, if available. + if (Record[Idx++]) ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), - NumTemplateArgs); + Record[Idx++]); unsigned NumDecls = Record[Idx++]; UnresolvedSet<8> Decls; @@ -1204,11 +1255,9 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { } E->initializeResults(*Reader.getContext(), Decls.begin(), Decls.end()); - // FIXME: read whole DeclarationNameInfo. - E->setName(Reader.ReadDeclarationName(Record, Idx)); + ReadDeclarationNameInfo(E->NameInfo, Record, Idx); E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - E->setQualifierRange(Reader.ReadSourceRange(Record, Idx)); - E->setNameLoc(Reader.ReadSourceLocation(Record, Idx)); + E->setQualifierRange(ReadSourceRange(Record, Idx)); } void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { @@ -1217,7 +1266,7 @@ void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { E->setHasUnresolvedUsing(Record[Idx++]); E->setBase(Reader.ReadSubExpr()); E->setBaseType(Reader.GetType(Record[Idx++])); - E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx)); + E->setOperatorLoc(ReadSourceLocation(Record, Idx)); } void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { @@ -1230,17 +1279,81 @@ void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { VisitExpr(E); E->UTT = (UnaryTypeTrait)Record[Idx++]; - SourceRange Range = Reader.ReadSourceRange(Record, Idx); + E->Value = (bool)Record[Idx++]; + SourceRange Range = ReadSourceRange(Record, Idx); E->Loc = Range.getBegin(); E->RParen = Range.getEnd(); - E->QueriedType = Reader.GetType(Record[Idx++]); + E->QueriedType = GetTypeSourceInfo(Record, Idx); +} + +void ASTStmtReader::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { + VisitExpr(E); + E->BTT = (BinaryTypeTrait)Record[Idx++]; + E->Value = (bool)Record[Idx++]; + SourceRange Range = ReadSourceRange(Record, Idx); + E->Loc = Range.getBegin(); + E->RParen = Range.getEnd(); + E->LhsType = GetTypeSourceInfo(Record, Idx); + E->RhsType = GetTypeSourceInfo(Record, Idx); +} + +void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { + VisitExpr(E); + E->Value = (bool)Record[Idx++]; + E->Range = ReadSourceRange(Record, Idx); + E->Operand = Reader.ReadSubExpr(); +} + +void ASTStmtReader::VisitPackExpansionExpr(PackExpansionExpr *E) { + VisitExpr(E); + E->EllipsisLoc = ReadSourceLocation(Record, Idx); + E->NumExpansions = Record[Idx++]; + E->Pattern = Reader.ReadSubExpr(); +} + +void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) { + VisitExpr(E); + E->OperatorLoc = ReadSourceLocation(Record, Idx); + E->PackLoc = ReadSourceLocation(Record, Idx); + E->RParenLoc = ReadSourceLocation(Record, Idx); + E->Length = Record[Idx++]; + E->Pack = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])); +} + +void ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr( + SubstNonTypeTemplateParmPackExpr *E) { + VisitExpr(E); + E->Param + = cast_or_null<NonTypeTemplateParmDecl>(Reader.GetDecl(Record[Idx++])); + TemplateArgument ArgPack = Reader.ReadTemplateArgument(F, Record, Idx); + if (ArgPack.getKind() != TemplateArgument::Pack) + return; + + E->Arguments = ArgPack.pack_begin(); + E->NumArguments = ArgPack.pack_size(); + E->NameLoc = ReadSourceLocation(Record, Idx); +} + +void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { + VisitExpr(E); + Idx++; // skip ID + E->Loc = ReadSourceLocation(Record, Idx); } -Stmt *ASTReader::ReadStmt(llvm::BitstreamCursor &Cursor) { +//===----------------------------------------------------------------------===// +// CUDA Expressions and Statements +//===----------------------------------------------------------------------===// + +void ASTStmtReader::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) { + VisitCallExpr(E); + E->setConfig(cast<CallExpr>(Reader.ReadSubExpr())); +} + +Stmt *ASTReader::ReadStmt(PerFileData &F) { switch (ReadingKind) { case Read_Decl: case Read_Type: - return ReadStmtFromStream(Cursor); + return ReadStmtFromStream(F); case Read_Stmt: return ReadSubStmt(); } @@ -1249,8 +1362,8 @@ Stmt *ASTReader::ReadStmt(llvm::BitstreamCursor &Cursor) { return 0; } -Expr *ASTReader::ReadExpr(llvm::BitstreamCursor &Cursor) { - return cast_or_null<Expr>(ReadStmt(Cursor)); +Expr *ASTReader::ReadExpr(PerFileData &F) { + return cast_or_null<Expr>(ReadStmt(F)); } Expr *ASTReader::ReadSubExpr() { @@ -1264,17 +1377,18 @@ Expr *ASTReader::ReadSubExpr() { // the stack, with expressions having operands removing those operands from the // stack. Evaluation terminates when we see a STMT_STOP record, and // the single remaining expression on the stack is our result. -Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { +Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { ReadingKindTracker ReadingKind(Read_Stmt, *this); - + llvm::BitstreamCursor &Cursor = F.DeclsCursor; + #ifndef NDEBUG unsigned PrevNumStmts = StmtStack.size(); #endif RecordData Record; unsigned Idx; - ASTStmtReader Reader(*this, Cursor, Record, Idx); + ASTStmtReader Reader(*this, F, Cursor, Record, Idx); Stmt::EmptyShell Empty; while (true) { @@ -1390,7 +1504,10 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { case EXPR_DECL_REF: S = DeclRefExpr::CreateEmpty(*Context, /*HasQualifier=*/Record[ASTStmtReader::NumExprFields], - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1]); + /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1], + /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1] + ? Record[ASTStmtReader::NumExprFields + 2] + : 0); break; case EXPR_INTEGER_LITERAL: @@ -1454,16 +1571,17 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { SourceRange QualifierRange; if (Record[Idx++]) { // HasQualifier. NNS = ReadNestedNameSpecifier(Record, Idx); - QualifierRange = ReadSourceRange(Record, Idx); + QualifierRange = ReadSourceRange(F, Record, Idx); } TemplateArgumentListInfo ArgInfo; - unsigned NumTemplateArgs = Record[Idx++]; - if (NumTemplateArgs) { - ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx)); - ArgInfo.setRAngleLoc(ReadSourceLocation(Record, Idx)); + bool HasExplicitTemplateArgs = Record[Idx++]; + if (HasExplicitTemplateArgs) { + unsigned NumTemplateArgs = Record[Idx++]; + ArgInfo.setLAngleLoc(ReadSourceLocation(F, Record, Idx)); + ArgInfo.setRAngleLoc(ReadSourceLocation(F, Record, Idx)); for (unsigned i = 0; i != NumTemplateArgs; ++i) - ArgInfo.addArgument(ReadTemplateArgumentLoc(Cursor, Record, Idx)); + ArgInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Idx)); } NamedDecl *FoundD = cast_or_null<NamedDecl>(GetDecl(Record[Idx++])); @@ -1471,16 +1589,19 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS); QualType T = GetType(Record[Idx++]); + ExprValueKind VK = static_cast<ExprValueKind>(Record[Idx++]); + ExprObjectKind OK = static_cast<ExprObjectKind>(Record[Idx++]); Expr *Base = ReadSubExpr(); ValueDecl *MemberD = cast<ValueDecl>(GetDecl(Record[Idx++])); - // FIXME: read DeclarationNameLoc. - SourceLocation MemberLoc = ReadSourceLocation(Record, Idx); + SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx); DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc); bool IsArrow = Record[Idx++]; S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange, MemberD, FoundDecl, MemberNameInfo, - NumTemplateArgs ? &ArgInfo : 0, T); + HasExplicitTemplateArgs ? &ArgInfo : 0, T, VK, OK); + ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc, + MemberD->getDeclName(), Record, Idx); break; } @@ -1496,6 +1617,10 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { S = new (Context) ConditionalOperator(Empty); break; + case EXPR_BINARY_CONDITIONAL_OPERATOR: + S = new (Context) BinaryConditionalOperator(Empty); + break; + case EXPR_IMPLICIT_CAST: S = ImplicitCastExpr::CreateEmpty(*Context, /*PathSize*/ Record[ASTStmtReader::NumExprFields]); @@ -1540,10 +1665,6 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { S = new (Context) StmtExpr(Empty); break; - case EXPR_TYPES_COMPATIBLE: - S = new (Context) TypesCompatibleExpr(Empty); - break; - case EXPR_CHOOSE: S = new (Context) ChooseExpr(Empty); break; @@ -1583,15 +1704,12 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { S = new (Context) ObjCPropertyRefExpr(Empty); break; case EXPR_OBJC_KVC_REF_EXPR: - S = new (Context) ObjCImplicitSetterGetterRefExpr(Empty); + llvm_unreachable("mismatching AST file"); break; case EXPR_OBJC_MESSAGE_EXPR: S = ObjCMessageExpr::CreateEmpty(*Context, Record[ASTStmtReader::NumExprFields]); break; - case EXPR_OBJC_SUPER_EXPR: - S = new (Context) ObjCSuperExpr(Empty); - break; case EXPR_OBJC_ISA: S = new (Context) ObjCIsaExpr(Empty); break; @@ -1678,6 +1796,12 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { case EXPR_CXX_TYPEID_TYPE: S = new (Context) CXXTypeidExpr(Empty, false); break; + case EXPR_CXX_UUIDOF_EXPR: + S = new (Context) CXXUuidofExpr(Empty, true); + break; + case EXPR_CXX_UUIDOF_TYPE: + S = new (Context) CXXUuidofExpr(Empty, false); + break; case EXPR_CXX_THIS: S = new (Context) CXXThisExpr(Empty); break; @@ -1710,18 +1834,24 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { S = new (Context) CXXPseudoDestructorExpr(Empty); break; - case EXPR_CXX_EXPR_WITH_TEMPORARIES: - S = new (Context) CXXExprWithTemporaries(Empty); + case EXPR_EXPR_WITH_CLEANUPS: + S = new (Context) ExprWithCleanups(Empty); break; case EXPR_CXX_DEPENDENT_SCOPE_MEMBER: S = CXXDependentScopeMemberExpr::CreateEmpty(*Context, - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]); + /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields], + /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] + ? Record[ASTStmtReader::NumExprFields + 1] + : 0); break; case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF: S = DependentScopeDeclRefExpr::CreateEmpty(*Context, - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]); + /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields], + /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] + ? Record[ASTStmtReader::NumExprFields + 1] + : 0); break; case EXPR_CXX_UNRESOLVED_CONSTRUCT: @@ -1731,17 +1861,62 @@ Stmt *ASTReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { case EXPR_CXX_UNRESOLVED_MEMBER: S = UnresolvedMemberExpr::CreateEmpty(*Context, - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]); + /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields], + /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] + ? Record[ASTStmtReader::NumExprFields + 1] + : 0); break; case EXPR_CXX_UNRESOLVED_LOOKUP: S = UnresolvedLookupExpr::CreateEmpty(*Context, - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]); + /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields], + /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] + ? Record[ASTStmtReader::NumExprFields + 1] + : 0); break; case EXPR_CXX_UNARY_TYPE_TRAIT: S = new (Context) UnaryTypeTraitExpr(Empty); break; + + case EXPR_BINARY_TYPE_TRAIT: + S = new (Context) BinaryTypeTraitExpr(Empty); + break; + + case EXPR_CXX_NOEXCEPT: + S = new (Context) CXXNoexceptExpr(Empty); + break; + + case EXPR_PACK_EXPANSION: + S = new (Context) PackExpansionExpr(Empty); + break; + + case EXPR_SIZEOF_PACK: + S = new (Context) SizeOfPackExpr(Empty); + break; + + case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK: + S = new (Context) SubstNonTypeTemplateParmPackExpr(Empty); + break; + + case EXPR_OPAQUE_VALUE: { + unsigned key = Record[ASTStmtReader::NumExprFields]; + OpaqueValueExpr *&expr = OpaqueValueExprs[key]; + + // If we already have an entry for this opaque value expression, + // don't bother reading it again. + if (expr) { + StmtStack.push_back(expr); + continue; + } + + S = expr = new (Context) OpaqueValueExpr(Empty); + break; + } + + case EXPR_CUDA_KERNEL_CALL: + S = new (Context) CUDAKernelCallExpr(*Context, Empty); + break; } // We hit a STMT_STOP, so we're done with this expression. diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp index 3b6b218..8fcb535 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Serialization/ASTWriter.h" +#include "clang/Serialization/ASTSerializationListener.h" #include "ASTCommon.h" #include "clang/Sema/Sema.h" #include "clang/Sema/IdentifierResolver.h" @@ -19,6 +20,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclContextInternals.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclFriend.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/Type.h" @@ -29,6 +31,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/OnDiskHashTable.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManagerInternals.h" @@ -38,9 +41,11 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/System/Path.h" +#include "llvm/Support/Path.h" #include <cstdio> +#include <string.h> using namespace clang; using namespace clang::serialization; @@ -60,13 +65,13 @@ const T *data(const std::vector<T, Allocator> &v) { namespace { class ASTTypeWriter { ASTWriter &Writer; - ASTWriter::RecordData &Record; + ASTWriter::RecordDataImpl &Record; public: /// \brief Type code that corresponds to the record generated. TypeCode Code; - ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordData &Record) + ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) : Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { } void VisitArrayType(const ArrayType *T); @@ -142,7 +147,7 @@ void ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) { void ASTTypeWriter::VisitVectorType(const VectorType *T) { Writer.AddTypeRef(T->getElementType(), Record); Record.push_back(T->getNumElements()); - Record.push_back(T->getAltiVecSpecific()); + Record.push_back(T->getVectorKind()); Code = TYPE_VECTOR; } @@ -172,6 +177,7 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { Writer.AddTypeRef(T->getArgType(I), Record); Record.push_back(T->isVariadic()); Record.push_back(T->getTypeQuals()); + Record.push_back(static_cast<unsigned>(T->getRefQualifier())); Record.push_back(T->hasExceptionSpec()); Record.push_back(T->hasAnyExceptionSpec()); Record.push_back(T->getNumExceptions()); @@ -207,6 +213,11 @@ void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) { Code = TYPE_DECLTYPE; } +void ASTTypeWriter::VisitAutoType(const AutoType *T) { + Writer.AddTypeRef(T->getDeducedType(), Record); + Code = TYPE_AUTO; +} + void ASTTypeWriter::VisitTagType(const TagType *T) { Record.push_back(T->isDependentType()); Writer.AddDeclRef(T->getDecl(), Record); @@ -224,6 +235,13 @@ void ASTTypeWriter::VisitEnumType(const EnumType *T) { Code = TYPE_ENUM; } +void ASTTypeWriter::VisitAttributedType(const AttributedType *T) { + Writer.AddTypeRef(T->getModifiedType(), Record); + Writer.AddTypeRef(T->getEquivalentType(), Record); + Record.push_back(T->getAttrKind()); + Code = TYPE_ATTRIBUTED; +} + void ASTTypeWriter::VisitSubstTemplateTypeParmType( const SubstTemplateTypeParmType *T) { @@ -233,6 +251,14 @@ ASTTypeWriter::VisitSubstTemplateTypeParmType( } void +ASTTypeWriter::VisitSubstTemplateTypeParmPackType( + const SubstTemplateTypeParmPackType *T) { + Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record); + Writer.AddTemplateArgument(T->getArgumentPack(), Record); + Code = TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK; +} + +void ASTTypeWriter::VisitTemplateSpecializationType( const TemplateSpecializationType *T) { Record.push_back(T->isDependentType()); @@ -295,6 +321,20 @@ ASTTypeWriter::VisitDependentTemplateSpecializationType( Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION; } +void ASTTypeWriter::VisitPackExpansionType(const PackExpansionType *T) { + Writer.AddTypeRef(T->getPattern(), Record); + if (llvm::Optional<unsigned> NumExpansions = T->getNumExpansions()) + Record.push_back(*NumExpansions + 1); + else + Record.push_back(0); + Code = TYPE_PACK_EXPANSION; +} + +void ASTTypeWriter::VisitParenType(const ParenType *T) { + Writer.AddTypeRef(T->getInnerType(), Record); + Code = TYPE_PAREN; +} + void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) { Record.push_back(T->getKeyword()); Writer.AddNestedNameSpecifier(T->getQualifier(), Record); @@ -332,10 +372,10 @@ namespace { class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { ASTWriter &Writer; - ASTWriter::RecordData &Record; + ASTWriter::RecordDataImpl &Record; public: - TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordData &Record) + TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) : Writer(Writer), Record(Record) { } #define ABSTRACT_TYPELOC(CLASS, PARENT) @@ -412,6 +452,7 @@ void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { Writer.AddSourceLocation(TL.getLParenLoc(), Record); Writer.AddSourceLocation(TL.getRParenLoc(), Record); + Record.push_back(TL.getTrailingReturn()); for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) Writer.AddDeclRef(TL.getArg(i), Record); } @@ -441,12 +482,30 @@ void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } +void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } +void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) { + Writer.AddSourceLocation(TL.getAttrNameLoc(), Record); + if (TL.hasAttrOperand()) { + SourceRange range = TL.getAttrOperandParensRange(); + Writer.AddSourceLocation(range.getBegin(), Record); + Writer.AddSourceLocation(range.getEnd(), Record); + } + if (TL.hasAttrExprOperand()) { + Expr *operand = TL.getAttrExprOperand(); + Record.push_back(operand ? 1 : 0); + if (operand) Writer.AddStmt(operand); + } else if (TL.hasAttrEnumOperand()) { + Writer.AddSourceLocation(TL.getAttrEnumOperandLoc(), Record); + } +} void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } @@ -454,6 +513,10 @@ void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc( SubstTemplateTypeParmTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } +void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc( + SubstTemplateTypeParmPackTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} void TypeLocWriter::VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TL) { Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record); @@ -463,6 +526,10 @@ void TypeLocWriter::VisitTemplateSpecializationTypeLoc( Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(), TL.getArgLoc(i).getLocInfo(), Record); } +void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) { + Writer.AddSourceLocation(TL.getLParenLoc(), Record); + Writer.AddSourceLocation(TL.getRParenLoc(), Record); +} void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { Writer.AddSourceLocation(TL.getKeywordLoc(), Record); Writer.AddSourceRange(TL.getQualifierRange(), Record); @@ -486,6 +553,9 @@ void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc( Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(), TL.getArgLoc(I).getLocInfo(), Record); } +void TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { + Writer.AddSourceLocation(TL.getEllipsisLoc(), Record); +} void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } @@ -506,7 +576,7 @@ void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { static void EmitBlockID(unsigned ID, const char *Name, llvm::BitstreamWriter &Stream, - ASTWriter::RecordData &Record) { + ASTWriter::RecordDataImpl &Record) { Record.clear(); Record.push_back(ID); Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record); @@ -521,7 +591,7 @@ static void EmitBlockID(unsigned ID, const char *Name, static void EmitRecordID(unsigned ID, const char *Name, llvm::BitstreamWriter &Stream, - ASTWriter::RecordData &Record) { + ASTWriter::RecordDataImpl &Record) { Record.clear(); Record.push_back(ID); while (*Name) @@ -530,7 +600,7 @@ static void EmitRecordID(unsigned ID, const char *Name, } static void AddStmtsExprs(llvm::BitstreamWriter &Stream, - ASTWriter::RecordData &Record) { + ASTWriter::RecordDataImpl &Record) { #define RECORD(X) EmitRecordID(X, #X, Stream, Record) RECORD(STMT_STOP); RECORD(STMT_NULL_PTR); @@ -577,7 +647,6 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_VA_ARG); RECORD(EXPR_ADDR_LABEL); RECORD(EXPR_STMT); - RECORD(EXPR_TYPES_COMPATIBLE); RECORD(EXPR_CHOOSE); RECORD(EXPR_GNU_NULL); RECORD(EXPR_SHUFFLE_VECTOR); @@ -591,7 +660,6 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_OBJC_PROPERTY_REF_EXPR); RECORD(EXPR_OBJC_KVC_REF_EXPR); RECORD(EXPR_OBJC_MESSAGE_EXPR); - RECORD(EXPR_OBJC_SUPER_EXPR); RECORD(STMT_OBJC_FOR_COLLECTION); RECORD(STMT_OBJC_CATCH); RECORD(STMT_OBJC_FINALLY); @@ -607,6 +675,32 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_CXX_FUNCTIONAL_CAST); RECORD(EXPR_CXX_BOOL_LITERAL); RECORD(EXPR_CXX_NULL_PTR_LITERAL); + RECORD(EXPR_CXX_TYPEID_EXPR); + RECORD(EXPR_CXX_TYPEID_TYPE); + RECORD(EXPR_CXX_UUIDOF_EXPR); + RECORD(EXPR_CXX_UUIDOF_TYPE); + RECORD(EXPR_CXX_THIS); + RECORD(EXPR_CXX_THROW); + RECORD(EXPR_CXX_DEFAULT_ARG); + RECORD(EXPR_CXX_BIND_TEMPORARY); + RECORD(EXPR_CXX_SCALAR_VALUE_INIT); + RECORD(EXPR_CXX_NEW); + RECORD(EXPR_CXX_DELETE); + RECORD(EXPR_CXX_PSEUDO_DESTRUCTOR); + RECORD(EXPR_EXPR_WITH_CLEANUPS); + RECORD(EXPR_CXX_DEPENDENT_SCOPE_MEMBER); + RECORD(EXPR_CXX_DEPENDENT_SCOPE_DECL_REF); + RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT); + RECORD(EXPR_CXX_UNRESOLVED_MEMBER); + RECORD(EXPR_CXX_UNRESOLVED_LOOKUP); + RECORD(EXPR_CXX_UNARY_TYPE_TRAIT); + RECORD(EXPR_CXX_NOEXCEPT); + RECORD(EXPR_OPAQUE_VALUE); + RECORD(EXPR_BINARY_TYPE_TRAIT); + RECORD(EXPR_PACK_EXPANSION); + RECORD(EXPR_SIZEOF_PACK); + RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK); + RECORD(EXPR_CUDA_KERNEL_CALL); #undef RECORD } @@ -643,6 +737,21 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(MACRO_DEFINITION_OFFSETS); RECORD(CHAINED_METADATA); RECORD(REFERENCED_SELECTOR_POOL); + RECORD(TU_UPDATE_LEXICAL); + RECORD(REDECLS_UPDATE_LATEST); + RECORD(SEMA_DECL_REFS); + RECORD(WEAK_UNDECLARED_IDENTIFIERS); + RECORD(PENDING_IMPLICIT_INSTANTIATIONS); + RECORD(DECL_REPLACEMENTS); + RECORD(UPDATE_VISIBLE); + RECORD(DECL_UPDATE_OFFSETS); + RECORD(DECL_UPDATES); + RECORD(CXX_BASE_SPECIFIER_OFFSETS); + RECORD(DIAG_PRAGMA_MAPPINGS); + RECORD(CUDA_SPECIAL_DECL_REFS); + RECORD(HEADER_SEARCH_TABLE); + RECORD(FP_PRAGMA_OPTIONS); + RECORD(OPENCL_EXTENSIONS); // SourceManager Block. BLOCK(SOURCE_MANAGER_BLOCK); @@ -657,8 +766,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(PP_MACRO_OBJECT_LIKE); RECORD(PP_MACRO_FUNCTION_LIKE); RECORD(PP_TOKEN); - RECORD(PP_MACRO_INSTANTIATION); - RECORD(PP_MACRO_DEFINITION); // Decls and Types block. BLOCK(DECLTYPES_BLOCK); @@ -684,7 +791,21 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(TYPE_OBJC_INTERFACE); RECORD(TYPE_OBJC_OBJECT); RECORD(TYPE_OBJC_OBJECT_POINTER); - RECORD(DECL_ATTR); + RECORD(TYPE_DECLTYPE); + RECORD(TYPE_ELABORATED); + RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM); + RECORD(TYPE_UNRESOLVED_USING); + RECORD(TYPE_INJECTED_CLASS_NAME); + RECORD(TYPE_OBJC_OBJECT); + RECORD(TYPE_TEMPLATE_TYPE_PARM); + RECORD(TYPE_TEMPLATE_SPECIALIZATION); + RECORD(TYPE_DEPENDENT_NAME); + RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION); + RECORD(TYPE_DEPENDENT_SIZED_ARRAY); + RECORD(TYPE_PAREN); + RECORD(TYPE_PACK_EXPANSION); + RECORD(TYPE_ATTRIBUTED); + RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK); RECORD(DECL_TRANSLATION_UNIT); RECORD(DECL_TYPEDEF); RECORD(DECL_ENUM); @@ -712,6 +833,39 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_BLOCK); RECORD(DECL_CONTEXT_LEXICAL); RECORD(DECL_CONTEXT_VISIBLE); + RECORD(DECL_NAMESPACE); + RECORD(DECL_NAMESPACE_ALIAS); + RECORD(DECL_USING); + RECORD(DECL_USING_SHADOW); + RECORD(DECL_USING_DIRECTIVE); + RECORD(DECL_UNRESOLVED_USING_VALUE); + RECORD(DECL_UNRESOLVED_USING_TYPENAME); + RECORD(DECL_LINKAGE_SPEC); + RECORD(DECL_CXX_RECORD); + RECORD(DECL_CXX_METHOD); + RECORD(DECL_CXX_CONSTRUCTOR); + RECORD(DECL_CXX_DESTRUCTOR); + RECORD(DECL_CXX_CONVERSION); + RECORD(DECL_ACCESS_SPEC); + RECORD(DECL_FRIEND); + RECORD(DECL_FRIEND_TEMPLATE); + RECORD(DECL_CLASS_TEMPLATE); + RECORD(DECL_CLASS_TEMPLATE_SPECIALIZATION); + RECORD(DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION); + RECORD(DECL_FUNCTION_TEMPLATE); + RECORD(DECL_TEMPLATE_TYPE_PARM); + RECORD(DECL_NON_TYPE_TEMPLATE_PARM); + RECORD(DECL_TEMPLATE_TEMPLATE_PARM); + RECORD(DECL_STATIC_ASSERT); + RECORD(DECL_CXX_BASE_SPECIFIERS); + RECORD(DECL_INDIRECTFIELD); + RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK); + + BLOCK(PREPROCESSOR_DETAIL_BLOCK); + RECORD(PPD_MACRO_INSTANTIATION); + RECORD(PPD_MACRO_DEFINITION); + RECORD(PPD_INCLUSION_DIRECTIVE); + // Statements and Exprs can occur in the Decls and Types block. AddStmtsExprs(Stream, Record); #undef RECORD @@ -756,7 +910,8 @@ adjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) { } /// \brief Write the AST metadata (e.g., i686-apple-darwin9). -void ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot) { +void ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot, + const std::string &OutputFile) { using namespace llvm; // Metadata @@ -792,9 +947,9 @@ void ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot) { FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev); - llvm::sys::Path MainFilePath(MainFile->getName()); + llvm::SmallString<128> MainFilePath(MainFile->getName()); - MainFilePath.makeAbsolute(); + llvm::sys::fs::make_absolute(MainFilePath); const char *MainFileNameStr = MainFilePath.c_str(); MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr, @@ -804,6 +959,23 @@ void ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot) { Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr); } + // Original PCH directory + if (!OutputFile.empty() && OutputFile != "-") { + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(ORIGINAL_PCH_DIR)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name + unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev); + + llvm::SmallString<128> OutputPath(OutputFile); + + llvm::sys::fs::make_absolute(OutputPath); + StringRef origDir = llvm::sys::path::parent_path(OutputPath); + + RecordData Record; + Record.push_back(ORIGINAL_PCH_DIR); + Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir); + } + // Repository branch/version information. BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev(); RepoAbbrev->Add(BitCodeAbbrevOp(VERSION_CONTROL_BRANCH_REVISION)); @@ -829,6 +1001,8 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants. Record.push_back(LangOpts.C99); // C99 Support Record.push_back(LangOpts.Microsoft); // Microsoft extensions. + // LangOpts.MSCVersion is ignored because all it does it set a macro, which is + // already saved elsewhere. Record.push_back(LangOpts.CPlusPlus); // C++ Support Record.push_back(LangOpts.CPlusPlus0x); // C++0x Support Record.push_back(LangOpts.CXXOperatorNames); // Treat C++ operator names as keywords. @@ -839,6 +1013,9 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { // modern abi enabled. Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced // modern abi enabled. + Record.push_back(LangOpts.AppleKext); // Apple's kernel extensions ABI + Record.push_back(LangOpts.ObjCDefaultSynthProperties); // Objective-C auto-synthesized + // properties enabled. Record.push_back(LangOpts.NoConstantCFStrings); // non cfstring generation enabled.. Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings @@ -847,7 +1024,9 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.AltiVec); Record.push_back(LangOpts.Exceptions); // Support exception handling. Record.push_back(LangOpts.SjLjExceptions); + Record.push_back(LangOpts.ObjCExceptions); + Record.push_back(LangOpts.MSBitfields); // MS-compatible structure layout Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime. Record.push_back(LangOpts.Freestanding); // Freestanding implementation Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin) @@ -879,12 +1058,17 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or // unsigned type Record.push_back(LangOpts.ShortWChar); // force wchar_t to be unsigned short + Record.push_back(LangOpts.ShortEnums); // Should the enum type be equivalent + // to the smallest integer type with + // enough room. Record.push_back(LangOpts.getGCMode()); Record.push_back(LangOpts.getVisibilityMode()); Record.push_back(LangOpts.getStackProtectorMode()); Record.push_back(LangOpts.InstantiationDepth); Record.push_back(LangOpts.OpenCL); + Record.push_back(LangOpts.CUDA); Record.push_back(LangOpts.CatchUndefined); + Record.push_back(LangOpts.DefaultFPContract); Record.push_back(LangOpts.ElideConstructors); Record.push_back(LangOpts.SpellChecking); Stream.EmitRecord(LANGUAGE_OPTIONS, Record); @@ -901,8 +1085,8 @@ public: typedef const char * key_type; typedef key_type key_type_ref; - typedef std::pair<int, struct stat> data_type; - typedef const data_type& data_type_ref; + typedef struct stat data_type; + typedef const data_type &data_type_ref; static unsigned ComputeHash(const char *path) { return llvm::HashString(path); @@ -913,9 +1097,7 @@ public: data_type_ref Data) { unsigned StrLen = strlen(path); clang::io::Emit16(Out, StrLen); - unsigned DataLen = 1; // result value - if (Data.first == 0) - DataLen += 4 + 4 + 2 + 8 + 8; + unsigned DataLen = 4 + 4 + 2 + 8 + 8; clang::io::Emit8(Out, DataLen); return std::make_pair(StrLen + 1, DataLen); } @@ -924,21 +1106,16 @@ public: Out.write(path, KeyLen); } - void EmitData(llvm::raw_ostream& Out, key_type_ref, + void EmitData(llvm::raw_ostream &Out, key_type_ref, data_type_ref Data, unsigned DataLen) { using namespace clang::io; uint64_t Start = Out.tell(); (void)Start; - // Result of stat() - Emit8(Out, Data.first? 1 : 0); - - if (Data.first == 0) { - Emit32(Out, (uint32_t) Data.second.st_ino); - Emit32(Out, (uint32_t) Data.second.st_dev); - Emit16(Out, (uint16_t) Data.second.st_mode); - Emit64(Out, (uint64_t) Data.second.st_mtime); - Emit64(Out, (uint64_t) Data.second.st_size); - } + Emit32(Out, (uint32_t) Data.st_ino); + Emit32(Out, (uint32_t) Data.st_dev); + Emit16(Out, (uint16_t) Data.st_mode); + Emit64(Out, (uint64_t) Data.st_mtime); + Emit64(Out, (uint64_t) Data.st_size); assert(Out.tell() - Start == DataLen && "Wrong data length"); } @@ -1002,11 +1179,6 @@ static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { // FileEntry fields. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time - // HeaderFileInfo fields. - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImport - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // DirInfo - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumIncludes - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // ControllingMacro Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name return Stream.EmitAbbrev(Abbrev); } @@ -1049,6 +1221,135 @@ static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) { return Stream.EmitAbbrev(Abbrev); } +namespace { + // Trait used for the on-disk hash table of header search information. + class HeaderFileInfoTrait { + ASTWriter &Writer; + HeaderSearch &HS; + + public: + HeaderFileInfoTrait(ASTWriter &Writer, HeaderSearch &HS) + : Writer(Writer), HS(HS) { } + + typedef const char *key_type; + typedef key_type key_type_ref; + + typedef HeaderFileInfo data_type; + typedef const data_type &data_type_ref; + + static unsigned ComputeHash(const char *path) { + // The hash is based only on the filename portion of the key, so that the + // reader can match based on filenames when symlinking or excess path + // elements ("foo/../", "../") change the form of the name. However, + // complete path is still the key. + return llvm::HashString(llvm::sys::path::filename(path)); + } + + std::pair<unsigned,unsigned> + EmitKeyDataLength(llvm::raw_ostream& Out, const char *path, + data_type_ref Data) { + unsigned StrLen = strlen(path); + clang::io::Emit16(Out, StrLen); + unsigned DataLen = 1 + 2 + 4; + clang::io::Emit8(Out, DataLen); + return std::make_pair(StrLen + 1, DataLen); + } + + void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) { + Out.write(path, KeyLen); + } + + void EmitData(llvm::raw_ostream &Out, key_type_ref, + data_type_ref Data, unsigned DataLen) { + using namespace clang::io; + uint64_t Start = Out.tell(); (void)Start; + + unsigned char Flags = (Data.isImport << 3) + | (Data.DirInfo << 1) + | Data.Resolved; + Emit8(Out, (uint8_t)Flags); + Emit16(Out, (uint16_t) Data.NumIncludes); + + if (!Data.ControllingMacro) + Emit32(Out, (uint32_t)Data.ControllingMacroID); + else + Emit32(Out, (uint32_t)Writer.getIdentifierRef(Data.ControllingMacro)); + assert(Out.tell() - Start == DataLen && "Wrong data length"); + } + }; +} // end anonymous namespace + +/// \brief Write the header search block for the list of files that +/// +/// \param HS The header search structure to save. +/// +/// \param Chain Whether we're creating a chained AST file. +void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, const char* isysroot) { + llvm::SmallVector<const FileEntry *, 16> FilesByUID; + HS.getFileMgr().GetUniqueIDMapping(FilesByUID); + + if (FilesByUID.size() > HS.header_file_size()) + FilesByUID.resize(HS.header_file_size()); + + HeaderFileInfoTrait GeneratorTrait(*this, HS); + OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator; + llvm::SmallVector<const char *, 4> SavedStrings; + unsigned NumHeaderSearchEntries = 0; + for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) { + const FileEntry *File = FilesByUID[UID]; + if (!File) + continue; + + const HeaderFileInfo &HFI = HS.header_file_begin()[UID]; + if (HFI.External && Chain) + continue; + + // Turn the file name into an absolute path, if it isn't already. + const char *Filename = File->getName(); + Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); + + // If we performed any translation on the file name at all, we need to + // save this string, since the generator will refer to it later. + if (Filename != File->getName()) { + Filename = strdup(Filename); + SavedStrings.push_back(Filename); + } + + Generator.insert(Filename, HFI, GeneratorTrait); + ++NumHeaderSearchEntries; + } + + // Create the on-disk hash table in a buffer. + llvm::SmallString<4096> TableData; + uint32_t BucketOffset; + { + llvm::raw_svector_ostream Out(TableData); + // Make sure that no bucket is at offset 0 + clang::io::Emit32(Out, 0); + BucketOffset = Generator.Emit(Out, GeneratorTrait); + } + + // Create a blob abbreviation + using namespace llvm; + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_TABLE)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + unsigned TableAbbrev = Stream.EmitAbbrev(Abbrev); + + // Write the stat cache + RecordData Record; + Record.push_back(HEADER_SEARCH_TABLE); + Record.push_back(BucketOffset); + Record.push_back(NumHeaderSearchEntries); + Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData.str()); + + // Free all of the strings we had to duplicate. + for (unsigned I = 0, N = SavedStrings.size(); I != N; ++I) + free((void*)SavedStrings[I]); +} + /// \brief Writes the block containing the serialized form of the /// source manager. /// @@ -1150,29 +1451,14 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.push_back(Content->Entry->getSize()); Record.push_back(Content->Entry->getModificationTime()); - // Emit header-search information associated with this file. - HeaderFileInfo HFI; - HeaderSearch &HS = PP.getHeaderSearchInfo(); - if (Content->Entry->getUID() < HS.header_file_size()) - HFI = HS.header_file_begin()[Content->Entry->getUID()]; - Record.push_back(HFI.isImport); - Record.push_back(HFI.DirInfo); - Record.push_back(HFI.NumIncludes); - AddIdentifierRef(HFI.ControllingMacro, Record); - // Turn the file name into an absolute path, if it isn't already. const char *Filename = Content->Entry->getName(); - llvm::sys::Path FilePath(Filename, strlen(Filename)); - FilePath.makeAbsolute(); + llvm::SmallString<128> FilePath(Filename); + llvm::sys::fs::make_absolute(FilePath); Filename = FilePath.c_str(); Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename); - - // FIXME: For now, preload all file source locations, so that - // we get the appropriate File entries in the reader. This is - // a temporary measure. - PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size()); } else { // The source location entry is a buffer. The blob associated // with this entry contains the contents of the buffer. @@ -1228,7 +1514,8 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.clear(); Record.push_back(SOURCE_LOCATION_OFFSETS); Record.push_back(SLocEntryOffsets.size()); - Record.push_back(SourceMgr.getNextOffset()); + unsigned BaseOffset = Chain ? Chain->getNextSLocOffset() : 0; + Record.push_back(SourceMgr.getNextOffset() - BaseOffset); Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, (const char *)data(SLocEntryOffsets), SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0])); @@ -1242,6 +1529,14 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Preprocessor Serialization //===----------------------------------------------------------------------===// +static int compareMacroDefinitions(const void *XPtr, const void *YPtr) { + const std::pair<const IdentifierInfo *, MacroInfo *> &X = + *(const std::pair<const IdentifierInfo *, MacroInfo *>*)XPtr; + const std::pair<const IdentifierInfo *, MacroInfo *> &Y = + *(const std::pair<const IdentifierInfo *, MacroInfo *>*)YPtr; + return X.first->getName().compare(Y.first->getName()); +} + /// \brief Writes the block containing the serialized form of the /// preprocessor. /// @@ -1256,30 +1551,63 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) { } // Enter the preprocessor block. - Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 2); + Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3); // If the AST file contains __DATE__ or __TIME__ emit a warning about this. // FIXME: use diagnostics subsystem for localization etc. if (PP.SawDateOrTime()) fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n"); + // Loop over all the macro definitions that are live at the end of the file, // emitting each to the PP section. PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); - for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); - I != E; ++I) { - // FIXME: This emits macros in hash table order, we should do it in a stable - // order so that output is reproducible. - MacroInfo *MI = I->second; + // Construct the list of macro definitions that need to be serialized. + llvm::SmallVector<std::pair<const IdentifierInfo *, MacroInfo *>, 2> + MacrosToEmit; + llvm::SmallPtrSet<const IdentifierInfo*, 4> MacroDefinitionsSeen; + for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0), + E = PP.macro_end(Chain == 0); + I != E; ++I) { + MacroDefinitionsSeen.insert(I->first); + MacrosToEmit.push_back(std::make_pair(I->first, I->second)); + } + + // Sort the set of macro definitions that need to be serialized by the + // name of the macro, to provide a stable ordering. + llvm::array_pod_sort(MacrosToEmit.begin(), MacrosToEmit.end(), + &compareMacroDefinitions); + + // Resolve any identifiers that defined macros at the time they were + // deserialized, adding them to the list of macros to emit (if appropriate). + for (unsigned I = 0, N = DeserializedMacroNames.size(); I != N; ++I) { + IdentifierInfo *Name + = const_cast<IdentifierInfo *>(DeserializedMacroNames[I]); + if (Name->hasMacroDefinition() && MacroDefinitionsSeen.insert(Name)) + MacrosToEmit.push_back(std::make_pair(Name, PP.getMacroInfo(Name))); + } + + for (unsigned I = 0, N = MacrosToEmit.size(); I != N; ++I) { + const IdentifierInfo *Name = MacrosToEmit[I].first; + MacroInfo *MI = MacrosToEmit[I].second; + if (!MI) + continue; + // Don't emit builtin macros like __LINE__ to the AST file unless they have // been redefined by the header (in which case they are not isBuiltinMacro). // Also skip macros from a AST file if we're chaining. - if (MI->isBuiltinMacro() || (Chain && MI->isFromAST())) + + // FIXME: There is a (probably minor) optimization we could do here, if + // the macro comes from the original PCH but the identifier comes from a + // chained PCH, by storing the offset into the original PCH rather than + // writing the macro definition a second time. + if (MI->isBuiltinMacro() || + (Chain && Name->isFromAST() && MI->isFromAST())) continue; - AddIdentifierRef(I->first, Record); - MacroOffsets[I->first] = Stream.GetCurrentBitNo(); + AddIdentifierRef(Name, Record); + MacroOffsets[Name] = Stream.GetCurrentBitNo(); Record.push_back(MI->getDefinitionLoc().getRawEncoding()); Record.push_back(MI->isUsed()); @@ -1296,12 +1624,12 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) { I != E; ++I) AddIdentifierRef(*I, Record); } - + // If we have a detailed preprocessing record, record the macro definition // ID that corresponds to this macro. if (PPRec) Record.push_back(getMacroDefinitionID(PPRec->findMacroDefinition(MI))); - + Stream.EmitRecord(Code, Record); Record.clear(); @@ -1318,7 +1646,6 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) { // FIXME: When reading literal tokens, reconstruct the literal pointer if // it is needed. AddIdentifierRef(Tok.getIdentifierInfo(), Record); - // FIXME: Should translate token kind to a stable encoding. Record.push_back(Tok.getKind()); // FIXME: Should translate token flags to a stable encoding. @@ -1329,49 +1656,111 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) { } ++NumMacros; } + Stream.ExitBlock(); + + if (PPRec) + WritePreprocessorDetail(*PPRec); +} + +void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { + if (PPRec.begin(Chain) == PPRec.end(Chain)) + return; + // Enter the preprocessor block. + Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3); + // If the preprocessor has a preprocessing record, emit it. unsigned NumPreprocessingRecords = 0; - if (PPRec) { - for (PreprocessingRecord::iterator E = PPRec->begin(), EEnd = PPRec->end(); - E != EEnd; ++E) { - Record.clear(); + using namespace llvm; + + // Set up the abbreviation for + unsigned InclusionAbbrev = 0; + { + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // start location + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // end location + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + InclusionAbbrev = Stream.EmitAbbrev(Abbrev); + } + + unsigned IndexBase = Chain ? PPRec.getNumPreallocatedEntities() : 0; + RecordData Record; + for (PreprocessingRecord::iterator E = PPRec.begin(Chain), + EEnd = PPRec.end(Chain); + E != EEnd; ++E) { + Record.clear(); + + if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { + // Record this macro definition's location. + MacroID ID = getMacroDefinitionID(MD); - if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { - Record.push_back(NumPreprocessingRecords++); - AddSourceLocation(MI->getSourceRange().getBegin(), Record); - AddSourceLocation(MI->getSourceRange().getEnd(), Record); - AddIdentifierRef(MI->getName(), Record); - Record.push_back(getMacroDefinitionID(MI->getDefinition())); - Stream.EmitRecord(PP_MACRO_INSTANTIATION, Record); + // Don't write the macro definition if it is from another AST file. + if (ID < FirstMacroID) continue; - } - if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { - // Record this macro definition's location. - IdentID ID = getMacroDefinitionID(MD); - if (ID != MacroDefinitionOffsets.size()) { - if (ID > MacroDefinitionOffsets.size()) - MacroDefinitionOffsets.resize(ID + 1); - - MacroDefinitionOffsets[ID] = Stream.GetCurrentBitNo(); - } else - MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); + // Notify the serialization listener that we're serializing this entity. + if (SerializationListener) + SerializationListener->SerializedPreprocessedEntity(*E, + Stream.GetCurrentBitNo()); + + unsigned Position = ID - FirstMacroID; + if (Position != MacroDefinitionOffsets.size()) { + if (Position > MacroDefinitionOffsets.size()) + MacroDefinitionOffsets.resize(Position + 1); - Record.push_back(NumPreprocessingRecords++); - Record.push_back(ID); - AddSourceLocation(MD->getSourceRange().getBegin(), Record); - AddSourceLocation(MD->getSourceRange().getEnd(), Record); - AddIdentifierRef(MD->getName(), Record); - AddSourceLocation(MD->getLocation(), Record); - Stream.EmitRecord(PP_MACRO_DEFINITION, Record); - continue; - } + MacroDefinitionOffsets[Position] = Stream.GetCurrentBitNo(); + } else + MacroDefinitionOffsets.push_back(Stream.GetCurrentBitNo()); + + Record.push_back(IndexBase + NumPreprocessingRecords++); + Record.push_back(ID); + AddSourceLocation(MD->getSourceRange().getBegin(), Record); + AddSourceLocation(MD->getSourceRange().getEnd(), Record); + AddIdentifierRef(MD->getName(), Record); + AddSourceLocation(MD->getLocation(), Record); + Stream.EmitRecord(PPD_MACRO_DEFINITION, Record); + continue; + } + + // Notify the serialization listener that we're serializing this entity. + if (SerializationListener) + SerializationListener->SerializedPreprocessedEntity(*E, + Stream.GetCurrentBitNo()); + + if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { + Record.push_back(IndexBase + NumPreprocessingRecords++); + AddSourceLocation(MI->getSourceRange().getBegin(), Record); + AddSourceLocation(MI->getSourceRange().getEnd(), Record); + AddIdentifierRef(MI->getName(), Record); + Record.push_back(getMacroDefinitionID(MI->getDefinition())); + Stream.EmitRecord(PPD_MACRO_INSTANTIATION, Record); + continue; } + + if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) { + Record.push_back(PPD_INCLUSION_DIRECTIVE); + Record.push_back(IndexBase + NumPreprocessingRecords++); + AddSourceLocation(ID->getSourceRange().getBegin(), Record); + AddSourceLocation(ID->getSourceRange().getEnd(), Record); + Record.push_back(ID->getFileName().size()); + Record.push_back(ID->wasInQuotes()); + Record.push_back(static_cast<unsigned>(ID->getKind())); + llvm::SmallString<64> Buffer; + Buffer += ID->getFileName(); + Buffer += ID->getFile()->getName(); + Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer); + continue; + } + + llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter"); } - Stream.ExitBlock(); - + // Write the offsets table for the preprocessing record. if (NumPreprocessingRecords > 0) { // Write the offsets table for identifier IDs. @@ -1382,7 +1771,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macro defs Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); unsigned MacroDefOffsetAbbrev = Stream.EmitAbbrev(Abbrev); - + Record.clear(); Record.push_back(MACRO_DEFINITION_OFFSETS); Record.push_back(NumPreprocessingRecords); @@ -1393,6 +1782,32 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) { } } +void ASTWriter::WritePragmaDiagnosticMappings(const Diagnostic &Diag) { + RecordData Record; + for (Diagnostic::DiagStatePointsTy::const_iterator + I = Diag.DiagStatePoints.begin(), E = Diag.DiagStatePoints.end(); + I != E; ++I) { + const Diagnostic::DiagStatePoint &point = *I; + if (point.Loc.isInvalid()) + continue; + + Record.push_back(point.Loc.getRawEncoding()); + for (Diagnostic::DiagState::iterator + I = point.State->begin(), E = point.State->end(); I != E; ++I) { + unsigned diag = I->first, map = I->second; + if (map & 0x10) { // mapping from a diagnostic pragma. + Record.push_back(diag); + Record.push_back(map & 0x7); + } + } + Record.push_back(-1); // mark the end of the diag/map pairs for this + // location. + } + + if (!Record.empty()) + Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record); +} + //===----------------------------------------------------------------------===// // Type Serialization //===----------------------------------------------------------------------===// @@ -1403,6 +1818,8 @@ void ASTWriter::WriteType(QualType T) { if (Idx.getIndex() == 0) // we haven't seen this type before. Idx = TypeIdx(NextTypeID++); + assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST"); + // Record the offset for this type. unsigned Index = Idx.getIndex() - FirstTypeID; if (TypeOffsets.size() == Index) @@ -1457,14 +1874,15 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, uint64_t Offset = Stream.GetCurrentBitNo(); RecordData Record; Record.push_back(DECL_CONTEXT_LEXICAL); - llvm::SmallVector<DeclID, 64> Decls; + llvm::SmallVector<KindDeclIDPair, 64> Decls; for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); D != DEnd; ++D) - Decls.push_back(GetDeclRef(*D)); + Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D))); ++NumLexicalDeclContexts; Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, - reinterpret_cast<char*>(Decls.data()), Decls.size() * sizeof(DeclID)); + reinterpret_cast<char*>(Decls.data()), + Decls.size() * sizeof(KindDeclIDPair)); return Offset; } @@ -1674,7 +2092,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { // Create a blob abbreviation for the selector table offsets. Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev); @@ -2088,13 +2506,6 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, /// DeclContext in a dependent AST file. As such, they only exist for the TU /// (in C++) and for namespaces. void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { - assert((DC->isTranslationUnit() || DC->isNamespace()) && - "Only TU and namespaces should have visible decl updates."); - - // Make the context build its lookup table, but don't make it load external - // decls. - DC->lookup(DeclarationName()); - StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); if (!Map || Map->empty()) return; @@ -2130,19 +2541,23 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str()); } -/// \brief Write ADDITIONAL_TEMPLATE_SPECIALIZATIONS blocks for all templates -/// that have new specializations in the current AST file. -void ASTWriter::WriteAdditionalTemplateSpecializations() { +/// \brief Write an FP_PRAGMA_OPTIONS block for the given FPOptions. +void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) { RecordData Record; - for (AdditionalTemplateSpecializationsMap::iterator - I = AdditionalTemplateSpecializations.begin(), - E = AdditionalTemplateSpecializations.end(); - I != E; ++I) { - Record.clear(); - Record.push_back(I->first); - Record.insert(Record.end(), I->second.begin(), I->second.end()); - Stream.EmitRecord(ADDITIONAL_TEMPLATE_SPECIALIZATIONS, Record); - } + Record.push_back(Opts.fp_contract); + Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record); +} + +/// \brief Write an OPENCL_EXTENSIONS block for the given OpenCLOptions. +void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) { + if (!SemaRef.Context.getLangOptions().OpenCL) + return; + + const OpenCLOptions &Opts = SemaRef.getOpenCLOptions(); + RecordData Record; +#define OPENCLEXT(nm) Record.push_back(Opts.nm); +#include "clang/Basic/OpenCLExtensions.def" + Stream.EmitRecord(OPENCL_EXTENSIONS, Record); } //===----------------------------------------------------------------------===// @@ -2150,22 +2565,19 @@ void ASTWriter::WriteAdditionalTemplateSpecializations() { //===----------------------------------------------------------------------===// /// \brief Write a record containing the given attributes. -void ASTWriter::WriteAttributeRecord(const AttrVec &Attrs) { - RecordData Record; +void ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) { + Record.push_back(Attrs.size()); for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){ const Attr * A = *i; Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs AddSourceLocation(A->getLocation(), Record); - Record.push_back(A->isInherited()); #include "clang/Serialization/AttrPCHWrite.inc" } - - Stream.EmitRecord(DECL_ATTR, Record); } -void ASTWriter::AddString(llvm::StringRef Str, RecordData &Record) { +void ASTWriter::AddString(llvm::StringRef Str, RecordDataImpl &Record) { Record.push_back(Str.size()); Record.insert(Record.end(), Str.begin(), Str.end()); } @@ -2193,15 +2605,20 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { } ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) - : Stream(Stream), Chain(0), FirstDeclID(1), NextDeclID(FirstDeclID), + : Stream(Stream), Chain(0), SerializationListener(0), + FirstDeclID(1), NextDeclID(FirstDeclID), FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1), - NextSelectorID(FirstSelectorID), CollectedStmts(&StmtsToEmit), + NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID), + CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), - NumVisibleDeclContexts(0) { + NumVisibleDeclContexts(0), FirstCXXBaseSpecifiersID(1), + NextCXXBaseSpecifiersID(1) +{ } void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, + const std::string &OutputFile, const char *isysroot) { // Emit the file header. Stream.Emit((unsigned)'C', 8); @@ -2214,11 +2631,12 @@ void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (Chain) WriteASTChain(SemaRef, StatCalls, isysroot); else - WriteASTCore(SemaRef, StatCalls, isysroot); + WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile); } void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, - const char *isysroot) { + const char *isysroot, + const std::string &OutputFile) { using namespace llvm; ASTContext &Context = SemaRef.Context; @@ -2318,10 +2736,15 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs); } + RecordData CUDASpecialDeclRefs; + if (Context.getcudaConfigureCallDecl()) { + AddDeclRef(Context.getcudaConfigureCallDecl(), CUDASpecialDeclRefs); + } + // Write the remaining AST contents. RecordData Record; Stream.EnterSubblock(AST_BLOCK_ID, 5); - WriteMetadata(Context, isysroot); + WriteMetadata(Context, isysroot, OutputFile); WriteLanguageOptions(Context.getLangOptions()); if (StatCalls && !isysroot) WriteStatCache(*StatCalls); @@ -2363,12 +2786,36 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, Stream.ExitBlock(); WritePreprocessor(PP); + WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot); WriteSelectors(SemaRef); WriteReferencedSelectorsPool(SemaRef); WriteIdentifierTable(PP); + WriteFPPragmaOptions(SemaRef.getFPOptions()); + WriteOpenCLExtensions(SemaRef); WriteTypeDeclOffsets(); + WritePragmaDiagnosticMappings(Context.getDiagnostics()); + // Write the C++ base-specifier set offsets. + if (!CXXBaseSpecifiersOffsets.empty()) { + // Create a blob abbreviation for the C++ base specifiers offsets. + using namespace llvm; + + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(CXX_BASE_SPECIFIER_OFFSETS)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); + + // Write the selector offsets table. + Record.clear(); + Record.push_back(CXX_BASE_SPECIFIER_OFFSETS); + Record.push_back(CXXBaseSpecifiersOffsets.size()); + Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record, + (const char *)CXXBaseSpecifiersOffsets.data(), + CXXBaseSpecifiersOffsets.size() * sizeof(uint32_t)); + } + // Write the record containing external, unnamed definitions. if (!ExternalDefinitions.empty()) Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions); @@ -2411,6 +2858,10 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (!SemaDeclRefs.empty()) Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); + // Write the record containing CUDA-specific declaration references. + if (!CUDASpecialDeclRefs.empty()) + Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs); + // Some simple statistics Record.clear(); Record.push_back(NumStatements); @@ -2425,21 +2876,12 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, const char *isysroot) { using namespace llvm; - FirstDeclID += Chain->getTotalNumDecls(); - FirstTypeID += Chain->getTotalNumTypes(); - FirstIdentID += Chain->getTotalNumIdentifiers(); - FirstSelectorID += Chain->getTotalNumSelectors(); - NextDeclID = FirstDeclID; - NextTypeID = FirstTypeID; - NextIdentID = FirstIdentID; - NextSelectorID = FirstSelectorID; - ASTContext &Context = SemaRef.Context; Preprocessor &PP = SemaRef.PP; RecordData Record; Stream.EnterSubblock(AST_BLOCK_ID, 5); - WriteMetadata(Context, isysroot); + WriteMetadata(Context, isysroot, ""); if (StatCalls && !isysroot) WriteStatCache(*StatCalls); // FIXME: Source manager block should only write new stuff, which could be @@ -2451,12 +2893,12 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, // We don't start with the translation unit, but with its decls that // don't come from the chained PCH. const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); - llvm::SmallVector<DeclID, 64> NewGlobalDecls; + llvm::SmallVector<KindDeclIDPair, 64> NewGlobalDecls; for (DeclContext::decl_iterator I = TU->noload_decls_begin(), E = TU->noload_decls_end(); I != E; ++I) { if ((*I)->getPCHLevel() == 0) - NewGlobalDecls.push_back(GetDeclRef(*I)); + NewGlobalDecls.push_back(std::make_pair((*I)->getKind(), GetDeclRef(*I))); else if ((*I)->isChangedSinceDeserialization()) (void)GetDeclRef(*I); // Make sure it's written, but don't record it. } @@ -2469,17 +2911,15 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, Record.push_back(TU_UPDATE_LEXICAL); Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, reinterpret_cast<const char*>(NewGlobalDecls.data()), - NewGlobalDecls.size() * sizeof(DeclID)); - // And in C++, a visible updates block for the TU. - if (Context.getLangOptions().CPlusPlus) { - Abv = new llvm::BitCodeAbbrev(); - Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); - UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); - WriteDeclContextVisibleUpdate(TU); - } + NewGlobalDecls.size() * sizeof(KindDeclIDPair)); + // And a visible updates block for the DeclContexts. + Abv = new llvm::BitCodeAbbrev(); + Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); + UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); + WriteDeclContextVisibleUpdate(TU); // Build a record containing all of the new tentative definitions in this // file, in TentativeDefinitions order. @@ -2574,6 +3014,9 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, Stream.EnterSubblock(DECLTYPES_BLOCK_ID, 3); WriteDeclsBlockAbbrevs(); + for (DeclsToRewriteTy::iterator + I = DeclsToRewrite.begin(), E = DeclsToRewrite.end(); I != E; ++I) + DeclTypesToEmit.push(const_cast<Decl*>(*I)); while (!DeclTypesToEmit.empty()) { DeclOrType DOT = DeclTypesToEmit.front(); DeclTypesToEmit.pop(); @@ -2588,7 +3031,13 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, WriteSelectors(SemaRef); WriteReferencedSelectorsPool(SemaRef); WriteIdentifierTable(PP); + WriteFPPragmaOptions(SemaRef.getFPOptions()); + WriteOpenCLExtensions(SemaRef); + WriteTypeDeclOffsets(); + // FIXME: For chained PCH only write the new mappings (we currently + // write all of them again). + WritePragmaDiagnosticMappings(Context.getDiagnostics()); /// Build a record containing first declarations from a chained PCH and the /// most recent declarations in this AST that they point to. @@ -2645,28 +3094,50 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (!SemaDeclRefs.empty()) Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); - // Write the updates to C++ namespaces. - for (llvm::SmallPtrSet<const NamespaceDecl *, 16>::iterator - I = UpdatedNamespaces.begin(), - E = UpdatedNamespaces.end(); + // Write the updates to DeclContexts. + for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator + I = UpdatedDeclContexts.begin(), + E = UpdatedDeclContexts.end(); I != E; ++I) WriteDeclContextVisibleUpdate(*I); - // Write the updates to C++ template specialization lists. - if (!AdditionalTemplateSpecializations.empty()) - WriteAdditionalTemplateSpecializations(); + WriteDeclUpdatesBlocks(); Record.clear(); Record.push_back(NumStatements); Record.push_back(NumMacros); Record.push_back(NumLexicalDeclContexts); Record.push_back(NumVisibleDeclContexts); - WriteDeclUpdateBlock(); + WriteDeclReplacementsBlock(); Stream.EmitRecord(STATISTICS, Record); Stream.ExitBlock(); } -void ASTWriter::WriteDeclUpdateBlock() { +void ASTWriter::WriteDeclUpdatesBlocks() { + if (DeclUpdates.empty()) + return; + + RecordData OffsetsRecord; + Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, 3); + for (DeclUpdateMap::iterator + I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) { + const Decl *D = I->first; + UpdateRecord &URec = I->second; + + if (DeclsToRewrite.count(D)) + continue; // The decl will be written completely,no need to store updates. + + uint64_t Offset = Stream.GetCurrentBitNo(); + Stream.EmitRecord(DECL_UPDATES, URec); + + OffsetsRecord.push_back(GetDeclRef(D)); + OffsetsRecord.push_back(Offset); + } + Stream.ExitBlock(); + Stream.EmitRecord(DECL_UPDATE_OFFSETS, OffsetsRecord); +} + +void ASTWriter::WriteDeclReplacementsBlock() { if (ReplacedDecls.empty()) return; @@ -2679,33 +3150,31 @@ void ASTWriter::WriteDeclUpdateBlock() { Stream.EmitRecord(DECL_REPLACEMENTS, Record); } -void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) { +void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) { Record.push_back(Loc.getRawEncoding()); } -void ASTWriter::AddSourceRange(SourceRange Range, RecordData &Record) { +void ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) { AddSourceLocation(Range.getBegin(), Record); AddSourceLocation(Range.getEnd(), Record); } -void ASTWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) { +void ASTWriter::AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record) { Record.push_back(Value.getBitWidth()); - unsigned N = Value.getNumWords(); - const uint64_t* Words = Value.getRawData(); - for (unsigned I = 0; I != N; ++I) - Record.push_back(Words[I]); + const uint64_t *Words = Value.getRawData(); + Record.append(Words, Words + Value.getNumWords()); } -void ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) { +void ASTWriter::AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record) { Record.push_back(Value.isUnsigned()); AddAPInt(Value, Record); } -void ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordData &Record) { +void ASTWriter::AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record) { AddAPInt(Value.bitcastToAPInt(), Record); } -void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) { +void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) { Record.push_back(getIdentifierRef(II)); } @@ -2719,17 +3188,17 @@ IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) { return ID; } -IdentID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) { +MacroID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) { if (MD == 0) return 0; - - IdentID &ID = MacroDefinitions[MD]; + + MacroID &ID = MacroDefinitions[MD]; if (ID == 0) - ID = MacroDefinitions.size(); + ID = NextMacroID++; return ID; } -void ASTWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) { +void ASTWriter::AddSelectorRef(const Selector SelRef, RecordDataImpl &Record) { Record.push_back(getSelectorRef(SelRef)); } @@ -2750,13 +3219,23 @@ SelectorID ASTWriter::getSelectorRef(Selector Sel) { return SID; } -void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record) { +void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record) { AddDeclRef(Temp->getDestructor(), Record); } +void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, + CXXBaseSpecifier const *BasesEnd, + RecordDataImpl &Record) { + assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded"); + CXXBaseSpecifiersToWrite.push_back( + QueuedCXXBaseSpecifiers(NextCXXBaseSpecifiersID, + Bases, BasesEnd)); + Record.push_back(NextCXXBaseSpecifiersID++); +} + void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, const TemplateArgumentLocInfo &Arg, - RecordData &Record) { + RecordDataImpl &Record) { switch (Kind) { case TemplateArgument::Expression: AddStmt(Arg.getAsExpr()); @@ -2768,6 +3247,11 @@ void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, AddSourceRange(Arg.getTemplateQualifierRange(), Record); AddSourceLocation(Arg.getTemplateNameLoc(), Record); break; + case TemplateArgument::TemplateExpansion: + AddSourceRange(Arg.getTemplateQualifierRange(), Record); + AddSourceLocation(Arg.getTemplateNameLoc(), Record); + AddSourceLocation(Arg.getTemplateEllipsisLoc(), Record); + break; case TemplateArgument::Null: case TemplateArgument::Integral: case TemplateArgument::Declaration: @@ -2777,7 +3261,7 @@ void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, } void ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, - RecordData &Record) { + RecordDataImpl &Record) { AddTemplateArgument(Arg.getArgument(), Record); if (Arg.getArgument().getKind() == TemplateArgument::Expression) { @@ -2791,7 +3275,7 @@ void ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, Record); } -void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record) { +void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record) { if (TInfo == 0) { AddTypeRef(QualType(), Record); return; @@ -2803,7 +3287,7 @@ void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record) { TLW.Visit(TL); } -void ASTWriter::AddTypeRef(QualType T, RecordData &Record) { +void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) { Record.push_back(GetOrCreateTypeID(T)); } @@ -2842,7 +3326,7 @@ TypeIdx ASTWriter::getTypeIdx(QualType T) const { return I->second; } -void ASTWriter::AddDeclRef(const Decl *D, RecordData &Record) { +void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { Record.push_back(GetDeclRef(D)); } @@ -2850,7 +3334,7 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) { if (D == 0) { return 0; } - + assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer"); DeclID &ID = DeclIDs[D]; if (ID == 0) { // We haven't seen this declaration before. Give it a new ID and @@ -2876,7 +3360,7 @@ DeclID ASTWriter::getDeclID(const Decl *D) { return DeclIDs[D]; } -void ASTWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) { +void ASTWriter::AddDeclarationName(DeclarationName Name, RecordDataImpl &Record) { // FIXME: Emit a stable enum for NameKind. 0 = Identifier etc. Record.push_back(Name.getNameKind()); switch (Name.getNameKind()) { @@ -2910,8 +3394,57 @@ void ASTWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) { } } +void ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, + DeclarationName Name, RecordDataImpl &Record) { + switch (Name.getNameKind()) { + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + AddTypeSourceInfo(DNLoc.NamedType.TInfo, Record); + break; + + case DeclarationName::CXXOperatorName: + AddSourceLocation( + SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.BeginOpNameLoc), + Record); + AddSourceLocation( + SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.EndOpNameLoc), + Record); + break; + + case DeclarationName::CXXLiteralOperatorName: + AddSourceLocation( + SourceLocation::getFromRawEncoding(DNLoc.CXXLiteralOperatorName.OpNameLoc), + Record); + break; + + case DeclarationName::Identifier: + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + case DeclarationName::CXXUsingDirective: + break; + } +} + +void ASTWriter::AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo, + RecordDataImpl &Record) { + AddDeclarationName(NameInfo.getName(), Record); + AddSourceLocation(NameInfo.getLoc(), Record); + AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName(), Record); +} + +void ASTWriter::AddQualifierInfo(const QualifierInfo &Info, + RecordDataImpl &Record) { + AddNestedNameSpecifier(Info.NNS, Record); + AddSourceRange(Info.NNSRange, Record); + Record.push_back(Info.NumTemplParamLists); + for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i) + AddTemplateParameterList(Info.TemplParamLists[i], Record); +} + void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, - RecordData &Record) { + RecordDataImpl &Record) { // Nested name specifiers usually aren't too long. I think that 8 would // typically accomodate the vast majority. llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames; @@ -2949,8 +3482,8 @@ void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, } } -void ASTWriter::AddTemplateName(TemplateName Name, RecordData &Record) { - TemplateName::NameKind Kind = Name.getKind(); +void ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) { + TemplateName::NameKind Kind = Name.getKind(); Record.push_back(Kind); switch (Kind) { case TemplateName::Template: @@ -2965,7 +3498,7 @@ void ASTWriter::AddTemplateName(TemplateName Name, RecordData &Record) { AddDeclRef(*I, Record); break; } - + case TemplateName::QualifiedTemplate: { QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName(); AddNestedNameSpecifier(QualT->getQualifier(), Record); @@ -2973,7 +3506,7 @@ void ASTWriter::AddTemplateName(TemplateName Name, RecordData &Record) { AddDeclRef(QualT->getTemplateDecl(), Record); break; } - + case TemplateName::DependentTemplate: { DependentTemplateName *DepT = Name.getAsDependentTemplateName(); AddNestedNameSpecifier(DepT->getQualifier(), Record); @@ -2984,11 +3517,19 @@ void ASTWriter::AddTemplateName(TemplateName Name, RecordData &Record) { Record.push_back(DepT->getOperator()); break; } + + case TemplateName::SubstTemplateTemplateParmPack: { + SubstTemplateTemplateParmPackStorage *SubstPack + = Name.getAsSubstTemplateTemplateParmPack(); + AddDeclRef(SubstPack->getParameterPack(), Record); + AddTemplateArgument(SubstPack->getArgumentPack(), Record); + break; + } } } -void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, - RecordData &Record) { +void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, + RecordDataImpl &Record) { Record.push_back(Arg.getKind()); switch (Arg.getKind()) { case TemplateArgument::Null: @@ -3004,7 +3545,14 @@ void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, AddTypeRef(Arg.getIntegralType(), Record); break; case TemplateArgument::Template: - AddTemplateName(Arg.getAsTemplate(), Record); + AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record); + break; + case TemplateArgument::TemplateExpansion: + AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record); + if (llvm::Optional<unsigned> NumExpansions = Arg.getNumTemplateExpansions()) + Record.push_back(*NumExpansions + 1); + else + Record.push_back(0); break; case TemplateArgument::Expression: AddStmt(Arg.getAsExpr()); @@ -3020,7 +3568,7 @@ void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, void ASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams, - RecordData &Record) { + RecordDataImpl &Record) { assert(TemplateParams && "No TemplateParams!"); AddSourceLocation(TemplateParams->getTemplateLoc(), Record); AddSourceLocation(TemplateParams->getLAngleLoc(), Record); @@ -3035,16 +3583,16 @@ ASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams, /// \brief Emit a template argument list. void ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, - RecordData &Record) { + RecordDataImpl &Record) { assert(TemplateArgs && "No TemplateArgs!"); - Record.push_back(TemplateArgs->flat_size()); - for (int i=0, e = TemplateArgs->flat_size(); i != e; ++i) + Record.push_back(TemplateArgs->size()); + for (int i=0, e = TemplateArgs->size(); i != e; ++i) AddTemplateArgument(TemplateArgs->get(i), Record); } void -ASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record) { +ASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordDataImpl &Record) { Record.push_back(Set.size()); for (UnresolvedSetImpl::const_iterator I = Set.begin(), E = Set.end(); I != E; ++I) { @@ -3054,31 +3602,69 @@ ASTWriter::AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record) { } void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, - RecordData &Record) { + RecordDataImpl &Record) { Record.push_back(Base.isVirtual()); Record.push_back(Base.isBaseOfClass()); Record.push_back(Base.getAccessSpecifierAsWritten()); + Record.push_back(Base.getInheritConstructors()); AddTypeSourceInfo(Base.getTypeSourceInfo(), Record); AddSourceRange(Base.getSourceRange(), Record); + AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc() + : SourceLocation(), + Record); +} + +void ASTWriter::FlushCXXBaseSpecifiers() { + RecordData Record; + for (unsigned I = 0, N = CXXBaseSpecifiersToWrite.size(); I != N; ++I) { + Record.clear(); + + // Record the offset of this base-specifier set. + unsigned Index = CXXBaseSpecifiersToWrite[I].ID - FirstCXXBaseSpecifiersID; + if (Index == CXXBaseSpecifiersOffsets.size()) + CXXBaseSpecifiersOffsets.push_back(Stream.GetCurrentBitNo()); + else { + if (Index > CXXBaseSpecifiersOffsets.size()) + CXXBaseSpecifiersOffsets.resize(Index + 1); + CXXBaseSpecifiersOffsets[Index] = Stream.GetCurrentBitNo(); + } + + const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases, + *BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd; + Record.push_back(BEnd - B); + for (; B != BEnd; ++B) + AddCXXBaseSpecifier(*B, Record); + Stream.EmitRecord(serialization::DECL_CXX_BASE_SPECIFIERS, Record); + + // Flush any expressions that were written as part of the base specifiers. + FlushStmts(); + } + + CXXBaseSpecifiersToWrite.clear(); } -void ASTWriter::AddCXXBaseOrMemberInitializers( - const CXXBaseOrMemberInitializer * const *BaseOrMembers, - unsigned NumBaseOrMembers, RecordData &Record) { - Record.push_back(NumBaseOrMembers); - for (unsigned i=0; i != NumBaseOrMembers; ++i) { - const CXXBaseOrMemberInitializer *Init = BaseOrMembers[i]; +void ASTWriter::AddCXXCtorInitializers( + const CXXCtorInitializer * const *CtorInitializers, + unsigned NumCtorInitializers, + RecordDataImpl &Record) { + Record.push_back(NumCtorInitializers); + for (unsigned i=0; i != NumCtorInitializers; ++i) { + const CXXCtorInitializer *Init = CtorInitializers[i]; Record.push_back(Init->isBaseInitializer()); if (Init->isBaseInitializer()) { AddTypeSourceInfo(Init->getBaseClassInfo(), Record); Record.push_back(Init->isBaseVirtual()); } else { - AddDeclRef(Init->getMember(), Record); + Record.push_back(Init->isIndirectMemberInitializer()); + if (Init->isIndirectMemberInitializer()) + AddDeclRef(Init->getIndirectMember(), Record); + else + AddDeclRef(Init->getMember(), Record); } + AddSourceLocation(Init->getMemberLocation(), Record); AddStmt(Init->getInit()); - AddDeclRef(Init->getAnonUnionMember(), Record); AddSourceLocation(Init->getLParenLoc(), Record); AddSourceLocation(Init->getRParenLoc(), Record); Record.push_back(Init->isWritten()); @@ -3092,22 +3678,86 @@ void ASTWriter::AddCXXBaseOrMemberInitializers( } } -void ASTWriter::SetReader(ASTReader *Reader) { +void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) { + assert(D->DefinitionData); + struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; + Record.push_back(Data.UserDeclaredConstructor); + Record.push_back(Data.UserDeclaredCopyConstructor); + Record.push_back(Data.UserDeclaredCopyAssignment); + Record.push_back(Data.UserDeclaredDestructor); + Record.push_back(Data.Aggregate); + Record.push_back(Data.PlainOldData); + Record.push_back(Data.Empty); + Record.push_back(Data.Polymorphic); + Record.push_back(Data.Abstract); + Record.push_back(Data.HasTrivialConstructor); + Record.push_back(Data.HasTrivialCopyConstructor); + Record.push_back(Data.HasTrivialCopyAssignment); + Record.push_back(Data.HasTrivialDestructor); + Record.push_back(Data.ComputedVisibleConversions); + Record.push_back(Data.DeclaredDefaultConstructor); + Record.push_back(Data.DeclaredCopyConstructor); + Record.push_back(Data.DeclaredCopyAssignment); + Record.push_back(Data.DeclaredDestructor); + + Record.push_back(Data.NumBases); + if (Data.NumBases > 0) + AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases, + Record); + + // FIXME: Make VBases lazily computed when needed to avoid storing them. + Record.push_back(Data.NumVBases); + if (Data.NumVBases > 0) + AddCXXBaseSpecifiersRef(Data.getVBases(), Data.getVBases() + Data.NumVBases, + Record); + + AddUnresolvedSet(Data.Conversions, Record); + AddUnresolvedSet(Data.VisibleConversions, Record); + // Data.Definition is the owning decl, no need to write it. + AddDeclRef(Data.FirstFriend, Record); +} + +void ASTWriter::ReaderInitialized(ASTReader *Reader) { assert(Reader && "Cannot remove chain"); + assert(!Chain && "Cannot replace chain"); assert(FirstDeclID == NextDeclID && FirstTypeID == NextTypeID && FirstIdentID == NextIdentID && FirstSelectorID == NextSelectorID && + FirstMacroID == NextMacroID && + FirstCXXBaseSpecifiersID == NextCXXBaseSpecifiersID && "Setting chain after writing has started."); Chain = Reader; + + FirstDeclID += Chain->getTotalNumDecls(); + FirstTypeID += Chain->getTotalNumTypes(); + FirstIdentID += Chain->getTotalNumIdentifiers(); + FirstSelectorID += Chain->getTotalNumSelectors(); + FirstMacroID += Chain->getTotalNumMacroDefinitions(); + FirstCXXBaseSpecifiersID += Chain->getTotalNumCXXBaseSpecifiers(); + NextDeclID = FirstDeclID; + NextTypeID = FirstTypeID; + NextIdentID = FirstIdentID; + NextSelectorID = FirstSelectorID; + NextMacroID = FirstMacroID; + NextCXXBaseSpecifiersID = FirstCXXBaseSpecifiersID; } void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) { IdentifierIDs[II] = ID; + if (II->hasMacroDefinition()) + DeserializedMacroNames.push_back(II); } void ASTWriter::TypeRead(TypeIdx Idx, QualType T) { - TypeIdxs[T] = Idx; + // Always take the highest-numbered type index. This copes with an interesting + // case for chained AST writing where we schedule writing the type and then, + // later, deserialize the type from another AST. In this case, we want to + // keep the higher-numbered entry so that we can properly write it out to + // the AST file. + TypeIdx &StoredIdx = TypeIdxs[T]; + if (Idx.getIndex() >= StoredIdx.getIndex()) + StoredIdx = Idx; } void ASTWriter::DeclRead(DeclID ID, const Decl *D) { @@ -3117,3 +3767,75 @@ void ASTWriter::DeclRead(DeclID ID, const Decl *D) { void ASTWriter::SelectorRead(SelectorID ID, Selector S) { SelectorIDs[S] = ID; } + +void ASTWriter::MacroDefinitionRead(serialization::MacroID ID, + MacroDefinition *MD) { + MacroDefinitions[MD] = ID; +} + +void ASTWriter::CompletedTagDefinition(const TagDecl *D) { + assert(D->isDefinition()); + if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { + // We are interested when a PCH decl is modified. + if (RD->getPCHLevel() > 0) { + // A forward reference was mutated into a definition. Rewrite it. + // FIXME: This happens during template instantiation, should we + // have created a new definition decl instead ? + RewriteDecl(RD); + } + + for (CXXRecordDecl::redecl_iterator + I = RD->redecls_begin(), E = RD->redecls_end(); I != E; ++I) { + CXXRecordDecl *Redecl = cast<CXXRecordDecl>(*I); + if (Redecl == RD) + continue; + + // We are interested when a PCH decl is modified. + if (Redecl->getPCHLevel() > 0) { + UpdateRecord &Record = DeclUpdates[Redecl]; + Record.push_back(UPD_CXX_SET_DEFINITIONDATA); + assert(Redecl->DefinitionData); + assert(Redecl->DefinitionData->Definition == D); + AddDeclRef(D, Record); // the DefinitionDecl + } + } + } +} +void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) { + // TU and namespaces are handled elsewhere. + if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC)) + return; + + if (!(D->getPCHLevel() == 0 && cast<Decl>(DC)->getPCHLevel() > 0)) + return; // Not a source decl added to a DeclContext from PCH. + + AddUpdatedDeclContext(DC); +} + +void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { + assert(D->isImplicit()); + if (!(D->getPCHLevel() == 0 && RD->getPCHLevel() > 0)) + return; // Not a source member added to a class from PCH. + if (!isa<CXXMethodDecl>(D)) + return; // We are interested in lazily declared implicit methods. + + // A decl coming from PCH was modified. + assert(RD->isDefinition()); + UpdateRecord &Record = DeclUpdates[RD]; + Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER); + AddDeclRef(D, Record); +} + +void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, + const ClassTemplateSpecializationDecl *D) { + // The specializations set is kept in the canonical template. + TD = TD->getCanonicalDecl(); + if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0)) + return; // Not a source specialization added to a template from PCH. + + UpdateRecord &Record = DeclUpdates[TD]; + Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); + AddDeclRef(D, Record); +} + +ASTSerializationListener::~ASTSerializationListener() { } diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp index ce39a10..ce07e138 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp @@ -16,6 +16,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/DeclContextInternals.h" #include "llvm/ADT/Twine.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Support/ErrorHandling.h" @@ -30,22 +31,23 @@ namespace clang { ASTWriter &Writer; ASTContext &Context; - ASTWriter::RecordData &Record; + typedef ASTWriter::RecordData RecordData; + RecordData &Record; public: serialization::DeclCode Code; unsigned AbbrevToUse; - ASTDeclWriter(ASTWriter &Writer, ASTContext &Context, - ASTWriter::RecordData &Record) + ASTDeclWriter(ASTWriter &Writer, ASTContext &Context, RecordData &Record) : Writer(Writer), Context(Context), Record(Record) { } - + void Visit(Decl *D); void VisitDecl(Decl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *D); void VisitNamedDecl(NamedDecl *D); + void VisitLabelDecl(LabelDecl *LD); void VisitNamespaceDecl(NamespaceDecl *D); void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); @@ -71,6 +73,7 @@ namespace clang { void VisitCXXDestructorDecl(CXXDestructorDecl *D); void VisitCXXConversionDecl(CXXConversionDecl *D); void VisitFieldDecl(FieldDecl *D); + void VisitIndirectFieldDecl(IndirectFieldDecl *D); void VisitVarDecl(VarDecl *D); void VisitImplicitParamDecl(ImplicitParamDecl *D); void VisitParmVarDecl(ParmVarDecl *D); @@ -133,6 +136,8 @@ void ASTDeclWriter::VisitDecl(Decl *D) { Writer.AddSourceLocation(D->getLocation(), Record); Record.push_back(D->isInvalidDecl()); Record.push_back(D->hasAttrs()); + if (D->hasAttrs()) + Writer.WriteAttributes(D->getAttrs(), Record); Record.push_back(D->isImplicit()); Record.push_back(D->isUsed(false)); Record.push_back(D->getAccess()); @@ -163,23 +168,31 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { void ASTDeclWriter::VisitTagDecl(TagDecl *D) { VisitTypeDecl(D); - Record.push_back(D->getIdentifierNamespace()); VisitRedeclarable(D); + Record.push_back(D->getIdentifierNamespace()); Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding Record.push_back(D->isDefinition()); Record.push_back(D->isEmbeddedInDeclarator()); Writer.AddSourceLocation(D->getRBraceLoc(), Record); Writer.AddSourceLocation(D->getTagKeywordLoc(), Record); - // FIXME: maybe write optional qualifier and its range. - Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record); + Record.push_back(D->hasExtInfo()); + if (D->hasExtInfo()) + Writer.AddQualifierInfo(*D->getExtInfo(), Record); + else + Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record); } void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { VisitTagDecl(D); - Writer.AddTypeRef(D->getIntegerType(), Record); + Writer.AddTypeSourceInfo(D->getIntegerTypeSourceInfo(), Record); + if (!D->getIntegerTypeSourceInfo()) + Writer.AddTypeRef(D->getIntegerType(), Record); Writer.AddTypeRef(D->getPromotionType(), Record); Record.push_back(D->getNumPositiveBits()); Record.push_back(D->getNumNegativeBits()); + Record.push_back(D->isScoped()); + Record.push_back(D->isScopedUsingClassTag()); + Record.push_back(D->isFixed()); Writer.AddDeclRef(D->getInstantiatedFromMemberEnum(), Record); Code = serialization::DECL_ENUM; } @@ -208,14 +221,17 @@ void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) { void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) { VisitValueDecl(D); + Record.push_back(D->hasExtInfo()); + if (D->hasExtInfo()) + Writer.AddQualifierInfo(*D->getExtInfo(), Record); Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record); - // FIXME: write optional qualifier and its range. } void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { VisitDeclaratorDecl(D); - // FIXME: write DeclarationNameLoc. + VisitRedeclarable(D); + Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record); Record.push_back(D->getIdentifierNamespace()); Record.push_back(D->getTemplatedKind()); switch (D->getTemplatedKind()) { @@ -236,8 +252,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { case FunctionDecl::TK_FunctionTemplateSpecialization: { FunctionTemplateSpecializationInfo * FTSInfo = D->getTemplateSpecializationInfo(); - // We want it canonical to guarantee that it has a Common*. - Writer.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl(), Record); + Writer.AddDeclRef(FTSInfo->getTemplate(), Record); Record.push_back(FTSInfo->getTemplateSpecializationKind()); // Template arguments. @@ -257,6 +272,12 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { } Writer.AddSourceLocation(FTSInfo->getPointOfInstantiation(), Record); + + if (D->isCanonicalDecl()) { + // Write the template that contains the specializations set. We will + // add a FunctionTemplateSpecializationInfo to it when reading. + Writer.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl(), Record); + } break; } case FunctionDecl::TK_DependentFunctionTemplateSpecialization: { @@ -281,9 +302,9 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { // FunctionDecl's body is handled last at ASTWriterDecl::Visit, // after everything else is written. - VisitRedeclarable(D); Record.push_back(D->getStorageClass()); // FIXME: stable encoding Record.push_back(D->getStorageClassAsWritten()); + Record.push_back(D->IsInline); Record.push_back(D->isInlineSpecified()); Record.push_back(D->isVirtualAsWritten()); Record.push_back(D->isPure()); @@ -291,7 +312,6 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Record.push_back(D->hasWrittenPrototype()); Record.push_back(D->isDeleted()); Record.push_back(D->isTrivial()); - Record.push_back(D->isCopyAssignment()); Record.push_back(D->hasImplicitReturnZero()); Writer.AddSourceLocation(D->getLocEnd(), Record); @@ -484,8 +504,8 @@ void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { VisitObjCImplDecl(D); Writer.AddDeclRef(D->getSuperClass(), Record); - Writer.AddCXXBaseOrMemberInitializers(D->IvarInitializers, - D->NumIvarInitializers, Record); + Writer.AddCXXCtorInitializers(D->IvarInitializers, D->NumIvarInitializers, + Record); Record.push_back(D->hasSynthBitfield()); Code = serialization::DECL_OBJC_IMPLEMENTATION; } @@ -495,6 +515,7 @@ void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { Writer.AddSourceLocation(D->getLocStart(), Record); Writer.AddDeclRef(D->getPropertyDecl(), Record); Writer.AddDeclRef(D->getPropertyIvarDecl(), Record); + Writer.AddSourceLocation(D->getPropertyIvarDeclLoc(), Record); Writer.AddStmt(D->getGetterCXXConstructor()); Writer.AddStmt(D->getSetterCXXAssignment()); Code = serialization::DECL_OBJC_PROPERTY_IMPL; @@ -511,15 +532,26 @@ void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) { Code = serialization::DECL_FIELD; } +void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { + VisitValueDecl(D); + Record.push_back(D->getChainingSize()); + + for (IndirectFieldDecl::chain_iterator + P = D->chain_begin(), + PEnd = D->chain_end(); P != PEnd; ++P) + Writer.AddDeclRef(*P, Record); + Code = serialization::DECL_INDIRECTFIELD; +} + void ASTDeclWriter::VisitVarDecl(VarDecl *D) { VisitDeclaratorDecl(D); + VisitRedeclarable(D); Record.push_back(D->getStorageClass()); // FIXME: stable encoding Record.push_back(D->getStorageClassAsWritten()); Record.push_back(D->isThreadSpecified()); Record.push_back(D->hasCXXDirectInitializer()); Record.push_back(D->isExceptionVariable()); Record.push_back(D->isNRVOVariable()); - VisitRedeclarable(D); Record.push_back(D->getInit() ? 1 : 0); if (D->getInit()) Writer.AddStmt(D->getInit()); @@ -592,6 +624,22 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) { for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end(); P != PEnd; ++P) Writer.AddDeclRef(*P, Record); + Record.push_back(D->capturesCXXThis()); + Record.push_back(D->getNumCaptures()); + for (BlockDecl::capture_iterator + i = D->capture_begin(), e = D->capture_end(); i != e; ++i) { + const BlockDecl::Capture &capture = *i; + Writer.AddDeclRef(capture.getVariable(), Record); + + unsigned flags = 0; + if (capture.isByRef()) flags |= 1; + if (capture.isNested()) flags |= 2; + if (capture.hasCopyExpr()) flags |= 4; + Record.push_back(flags); + + if (capture.hasCopyExpr()) Writer.AddStmt(capture.getCopyExpr()); + } + Code = serialization::DECL_BLOCK; } @@ -604,8 +652,15 @@ void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { Code = serialization::DECL_LINKAGE_SPEC; } +void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) { + VisitNamedDecl(D); + Code = serialization::DECL_LABEL; +} + + void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { VisitNamedDecl(D); + Record.push_back(D->isInline()); Writer.AddSourceLocation(D->getLBracLoc(), Record); Writer.AddSourceLocation(D->getRBracLoc(), Record); Writer.AddDeclRef(D->getNextNamespace(), Record); @@ -620,7 +675,22 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { if (Writer.hasChain() && !D->isOriginalNamespace() && D->getOriginalNamespace()->getPCHLevel() > 0) { - Writer.AddUpdatedNamespace(D->getOriginalNamespace()); + NamespaceDecl *NS = D->getOriginalNamespace(); + Writer.AddUpdatedDeclContext(NS); + + // Make sure all visible decls are written. They will be recorded later. + NS->lookup(DeclarationName()); + StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(NS->getLookupPtr()); + if (Map) { + for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); + D != DEnd; ++D) { + DeclContext::lookup_result Result = D->second.getLookupResult(); + while (Result.first != Result.second) { + Writer.GetDeclRef(*Result.first); + ++Result.first; + } + } + } } } @@ -639,10 +709,8 @@ void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) { Writer.AddSourceRange(D->getNestedNameRange(), Record); Writer.AddSourceLocation(D->getUsingLocation(), Record); Writer.AddNestedNameSpecifier(D->getTargetNestedNameDecl(), Record); - Record.push_back(D->getNumShadowDecls()); - for (UsingDecl::shadow_iterator P = D->shadow_begin(), - PEnd = D->shadow_end(); P != PEnd; ++P) - Writer.AddDeclRef(*P, Record); + Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record); + Writer.AddDeclRef(D->FirstUsingShadow, Record); Record.push_back(D->isTypeName()); Writer.AddDeclRef(Context.getInstantiatedFromUsingDecl(D), Record); Code = serialization::DECL_USING; @@ -651,7 +719,7 @@ void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) { void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) { VisitNamedDecl(D); Writer.AddDeclRef(D->getTargetDecl(), Record); - Writer.AddDeclRef(D->getUsingDecl(), Record); + Writer.AddDeclRef(D->UsingOrNextShadow, Record); Writer.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D), Record); Code = serialization::DECL_USING_SHADOW; } @@ -672,6 +740,7 @@ void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { Writer.AddSourceRange(D->getTargetNestedNameRange(), Record); Writer.AddSourceLocation(D->getUsingLoc(), Record); Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record); + Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record); Code = serialization::DECL_UNRESOLVED_USING_VALUE; } @@ -686,64 +755,14 @@ void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl( } void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) { - // See comments at ASTDeclReader::VisitCXXRecordDecl about why this happens - // before VisitRecordDecl. - enum { Data_NoDefData, Data_Owner, Data_NotOwner }; - bool OwnsDefinitionData = false; - if (D->DefinitionData) { - assert(D->DefinitionData->Definition && - "DefinitionData don't point to a definition decl!"); - OwnsDefinitionData = D->DefinitionData->Definition == D; - if (OwnsDefinitionData) { - Record.push_back(Data_Owner); - } else { - Record.push_back(Data_NotOwner); - Writer.AddDeclRef(D->DefinitionData->Definition, Record); - } - } else - Record.push_back(Data_NoDefData); - VisitRecordDecl(D); - if (OwnsDefinitionData) { - assert(D->DefinitionData); - struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; - - Record.push_back(Data.UserDeclaredConstructor); - Record.push_back(Data.UserDeclaredCopyConstructor); - Record.push_back(Data.UserDeclaredCopyAssignment); - Record.push_back(Data.UserDeclaredDestructor); - Record.push_back(Data.Aggregate); - Record.push_back(Data.PlainOldData); - Record.push_back(Data.Empty); - Record.push_back(Data.Polymorphic); - Record.push_back(Data.Abstract); - Record.push_back(Data.HasTrivialConstructor); - Record.push_back(Data.HasTrivialCopyConstructor); - Record.push_back(Data.HasTrivialCopyAssignment); - Record.push_back(Data.HasTrivialDestructor); - Record.push_back(Data.ComputedVisibleConversions); - Record.push_back(Data.DeclaredDefaultConstructor); - Record.push_back(Data.DeclaredCopyConstructor); - Record.push_back(Data.DeclaredCopyAssignment); - Record.push_back(Data.DeclaredDestructor); - - Record.push_back(D->getNumBases()); - for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), - E = D->bases_end(); I != E; ++I) - Writer.AddCXXBaseSpecifier(*I, Record); - - // FIXME: Make VBases lazily computed when needed to avoid storing them. - Record.push_back(D->getNumVBases()); - for (CXXRecordDecl::base_class_iterator I = D->vbases_begin(), - E = D->vbases_end(); I != E; ++I) - Writer.AddCXXBaseSpecifier(*I, Record); - - Writer.AddUnresolvedSet(Data.Conversions, Record); - Writer.AddUnresolvedSet(Data.VisibleConversions, Record); - // Data.Definition is written at the top. - Writer.AddDeclRef(Data.FirstFriend, Record); - } + CXXRecordDecl *DefinitionDecl = 0; + if (D->DefinitionData) + DefinitionDecl = D->DefinitionData->Definition; + Writer.AddDeclRef(DefinitionDecl, Record); + if (D == DefinitionDecl) + Writer.AddCXXDefinitionData(D, Record); enum { CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization @@ -761,6 +780,11 @@ void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) { Record.push_back(CXXRecNotTemplate); } + // Store the key function to avoid deserializing every method so we can + // compute it. + if (D->IsDefinition) + Writer.AddDeclRef(Context.getKeyFunction(D), Record); + Code = serialization::DECL_CXX_RECORD; } @@ -779,8 +803,8 @@ void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { Record.push_back(D->IsExplicitSpecified); Record.push_back(D->ImplicitlyDefined); - Writer.AddCXXBaseOrMemberInitializers(D->BaseOrMemberInitializers, - D->NumBaseOrMemberInitializers, Record); + Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers, + Record); Code = serialization::DECL_CXX_CONSTRUCTOR; } @@ -813,7 +837,8 @@ void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) { Writer.AddTypeSourceInfo(D->Friend.get<TypeSourceInfo*>(), Record); else Writer.AddDeclRef(D->Friend.get<NamedDecl*>(), Record); - Writer.AddDeclRef(D->NextFriend, Record); + Writer.AddDeclRef(D->getNextFriend(), Record); + Record.push_back(D->UnsupportedFriend); Writer.AddSourceLocation(D->FriendLoc, Record); Code = serialization::DECL_FRIEND; } @@ -840,10 +865,13 @@ void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) { } void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { - VisitTemplateDecl(D); + // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that + // getCommonPtr() can be used while this is still initializing. - Record.push_back(D->getIdentifierNamespace()); Writer.AddDeclRef(D->getPreviousDeclaration(), Record); + if (D->getPreviousDeclaration()) + Writer.AddDeclRef(D->getFirstDeclaration(), Record); + if (D->getPreviousDeclaration() == 0) { // This TemplateDecl owns the CommonPtr; write it. assert(D->isCanonicalDecl()); @@ -866,6 +894,9 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { Writer.FirstLatestDecls[First] = D; } } + + VisitTemplateDecl(D); + Record.push_back(D->getIdentifierNamespace()); } void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { @@ -911,10 +942,6 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl( InstFromD = cast<ClassTemplatePartialSpecializationDecl>(InstFromD)-> getSpecializedTemplate(); } - // Is this a specialization of an already-serialized template? - if (InstFromD->getCanonicalDecl()->getPCHLevel() != 0) - Writer.AddAdditionalTemplateSpecialization(Writer.getDeclID(InstFromD), - Writer.getDeclID(D)); // Explicit info. Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record); @@ -987,17 +1014,33 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { } void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { - VisitVarDecl(D); + // For an expanded parameter pack, record the number of expansion types here + // so that it's easier for + if (D->isExpandedParameterPack()) + Record.push_back(D->getNumExpansionTypes()); + + VisitDeclaratorDecl(D); // TemplateParmPosition. Record.push_back(D->getDepth()); Record.push_back(D->getPosition()); - // Rest of NonTypeTemplateParmDecl. - Record.push_back(D->getDefaultArgument() != 0); - if (D->getDefaultArgument()) { - Writer.AddStmt(D->getDefaultArgument()); - Record.push_back(D->defaultArgumentWasInherited()); + + if (D->isExpandedParameterPack()) { + for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { + Writer.AddTypeRef(D->getExpansionType(I), Record); + Writer.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I), Record); + } + + Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK; + } else { + // Rest of NonTypeTemplateParmDecl. + Record.push_back(D->isParameterPack()); + Record.push_back(D->getDefaultArgument() != 0); + if (D->getDefaultArgument()) { + Writer.AddStmt(D->getDefaultArgument()); + Record.push_back(D->defaultArgumentWasInherited()); + } + Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM; } - Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM; } void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { @@ -1008,6 +1051,7 @@ void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { // Rest of TemplateTemplateParmDecl. Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record); Record.push_back(D->defaultArgumentWasInherited()); + Record.push_back(D->isParameterPack()); Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM; } @@ -1041,9 +1085,14 @@ void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) { if (D->RedeclLink.getNext() == D) { Record.push_back(NoRedeclaration); } else { - Record.push_back(D->RedeclLink.NextIsPrevious() ? PointsToPrevious - : PointsToLatest); - Writer.AddDeclRef(D->RedeclLink.getPointer(), Record); + if (D->RedeclLink.NextIsPrevious()) { + Record.push_back(PointsToPrevious); + Writer.AddDeclRef(D->getPreviousDeclaration(), Record); + Writer.AddDeclRef(D->getFirstDeclaration(), Record); + } else { + Record.push_back(PointsToLatest); + Writer.AddDeclRef(D->RedeclLink.getPointer(), Record); + } } T *First = D->getFirstDeclaration(); @@ -1086,15 +1135,16 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { // ValueDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DeclaratorDecl + Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo Abv->Add(BitCodeAbbrevOp(serialization::PREDEF_TYPE_NULL_ID)); // InfoType // VarDecl + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration Abv->Add(BitCodeAbbrevOp(0)); // StorageClass Abv->Add(BitCodeAbbrevOp(0)); // StorageClassAsWritten Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer Abv->Add(BitCodeAbbrevOp(0)); // isExceptionVariable Abv->Add(BitCodeAbbrevOp(0)); // isNRVOVariable - Abv->Add(BitCodeAbbrevOp(0)); // PrevDecl Abv->Add(BitCodeAbbrevOp(0)); // HasInit Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo // ParmVarDecl @@ -1137,6 +1187,9 @@ static bool isRequiredDecl(const Decl *D, ASTContext &Context) { } void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { + // Switch case IDs are per Decl. + ClearSwitchCaseIDs(); + RecordData Record; ASTDeclWriter W(*this, Context, Record); @@ -1186,13 +1239,12 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { D->getDeclKindName() + "'"); Stream.EmitRecord(W.Code, Record, W.AbbrevToUse); - // If the declaration had any attributes, write them now. - if (D->hasAttrs()) - WriteAttributeRecord(D->getAttrs()); - // Flush any expressions that were written as part of this declaration. FlushStmts(); - + + // Flush C++ base specifiers, if there are any. + FlushCXXBaseSpecifiers(); + // Note "external" declarations so that we can add them to a record in the // AST file later. // diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp index 7f2da6c..8a5ffe9 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp @@ -14,6 +14,7 @@ #include "clang/Serialization/ASTWriter.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/StmtVisitor.h" #include "llvm/Bitcode/BitstreamWriter.h" using namespace clang; @@ -75,6 +76,7 @@ namespace clang { void VisitBinaryOperator(BinaryOperator *E); void VisitCompoundAssignOperator(CompoundAssignOperator *E); void VisitConditionalOperator(ConditionalOperator *E); + void VisitBinaryConditionalOperator(BinaryConditionalOperator *E); void VisitImplicitCastExpr(ImplicitCastExpr *E); void VisitExplicitCastExpr(ExplicitCastExpr *E); void VisitCStyleCastExpr(CStyleCastExpr *E); @@ -86,7 +88,6 @@ namespace clang { void VisitVAArgExpr(VAArgExpr *E); void VisitAddrLabelExpr(AddrLabelExpr *E); void VisitStmtExpr(StmtExpr *E); - void VisitTypesCompatibleExpr(TypesCompatibleExpr *E); void VisitChooseExpr(ChooseExpr *E); void VisitGNUNullExpr(GNUNullExpr *E); void VisitShuffleVectorExpr(ShuffleVectorExpr *E); @@ -100,10 +101,7 @@ namespace clang { void VisitObjCProtocolExpr(ObjCProtocolExpr *E); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E); void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E); - void VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E); void VisitObjCMessageExpr(ObjCMessageExpr *E); - void VisitObjCSuperExpr(ObjCSuperExpr *E); void VisitObjCIsaExpr(ObjCIsaExpr *E); // Objective-C Statements @@ -131,6 +129,7 @@ namespace clang { void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); void VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E); void VisitCXXTypeidExpr(CXXTypeidExpr *E); + void VisitCXXUuidofExpr(CXXUuidofExpr *E); void VisitCXXThisExpr(CXXThisExpr *E); void VisitCXXThrowExpr(CXXThrowExpr *E); void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); @@ -141,7 +140,7 @@ namespace clang { void VisitCXXDeleteExpr(CXXDeleteExpr *E); void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); - void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E); + void VisitExprWithCleanups(ExprWithCleanups *E); void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); @@ -151,6 +150,16 @@ namespace clang { void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E); void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); + void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); + void VisitCXXNoexceptExpr(CXXNoexceptExpr *E); + void VisitPackExpansionExpr(PackExpansionExpr *E); + void VisitSizeOfPackExpr(SizeOfPackExpr *E); + void VisitSubstNonTypeTemplateParmPackExpr( + SubstNonTypeTemplateParmPackExpr *E); + void VisitOpaqueValueExpr(OpaqueValueExpr *E); + + // CUDA Expressions + void VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E); }; } @@ -168,6 +177,7 @@ void ASTStmtWriter::VisitStmt(Stmt *S) { void ASTStmtWriter::VisitNullStmt(NullStmt *S) { VisitStmt(S); Writer.AddSourceLocation(S->getSemiLoc(), Record); + Record.push_back(S->LeadingEmptyMacro); Code = serialization::STMT_NULL; } @@ -208,10 +218,9 @@ void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) { void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) { VisitStmt(S); - Writer.AddIdentifierRef(S->getID(), Record); + Writer.AddDeclRef(S->getDecl(), Record); Writer.AddStmt(S->getSubStmt()); Writer.AddSourceLocation(S->getIdentLoc(), Record); - Record.push_back(Writer.GetLabelID(S)); Code = serialization::STMT_LABEL; } @@ -232,6 +241,7 @@ void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) { Writer.AddStmt(S->getCond()); Writer.AddStmt(S->getBody()); Writer.AddSourceLocation(S->getSwitchLoc(), Record); + Record.push_back(S->isAllEnumCasesCovered()); for (SwitchCase *SC = S->getSwitchCaseList(); SC; SC = SC->getNextSwitchCase()) Record.push_back(Writer.RecordSwitchCaseID(SC)); @@ -272,7 +282,7 @@ void ASTStmtWriter::VisitForStmt(ForStmt *S) { void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) { VisitStmt(S); - Record.push_back(Writer.GetLabelID(S->getLabel())); + Writer.AddDeclRef(S->getLabel(), Record); Writer.AddSourceLocation(S->getGotoLoc(), Record); Writer.AddSourceLocation(S->getLabelLoc(), Record); Code = serialization::STMT_GOTO; @@ -354,6 +364,9 @@ void ASTStmtWriter::VisitExpr(Expr *E) { Writer.AddTypeRef(E->getType(), Record); Record.push_back(E->isTypeDependent()); Record.push_back(E->isValueDependent()); + Record.push_back(E->containsUnexpandedParameterPack()); + Record.push_back(E->getValueKind()); + Record.push_back(E->getObjectKind()); } void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) { @@ -367,22 +380,22 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); Record.push_back(E->hasQualifier()); - unsigned NumTemplateArgs = E->getNumTemplateArgs(); - assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() && - "Template args list with no args ?"); - Record.push_back(NumTemplateArgs); + Record.push_back(E->hasExplicitTemplateArgs()); if (E->hasQualifier()) { Writer.AddNestedNameSpecifier(E->getQualifier(), Record); Writer.AddSourceRange(E->getQualifierRange(), Record); } - if (NumTemplateArgs) + if (E->hasExplicitTemplateArgs()) { + unsigned NumTemplateArgs = E->getNumTemplateArgs(); + Record.push_back(NumTemplateArgs); AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs()); + } Writer.AddDeclRef(E->getDecl(), Record); - // FIXME: write DeclarationNameLoc. Writer.AddSourceLocation(E->getLocation(), Record); + Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record); Code = serialization::EXPR_DECL_REF; } @@ -533,11 +546,10 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { Writer.AddSourceRange(E->getQualifierRange(), Record); } - unsigned NumTemplateArgs = E->getNumTemplateArgs(); - assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() && - "Template args list with no args ?"); - Record.push_back(NumTemplateArgs); - if (NumTemplateArgs) { + Record.push_back(E->hasExplicitTemplateArgs()); + if (E->hasExplicitTemplateArgs()) { + unsigned NumTemplateArgs = E->getNumTemplateArgs(); + Record.push_back(NumTemplateArgs); Writer.AddSourceLocation(E->getLAngleLoc(), Record); Writer.AddSourceLocation(E->getRAngleLoc(), Record); for (unsigned i=0; i != NumTemplateArgs; ++i) @@ -549,11 +561,14 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { Record.push_back(FoundDecl.getAccess()); Writer.AddTypeRef(E->getType(), Record); + Record.push_back(E->getValueKind()); + Record.push_back(E->getObjectKind()); Writer.AddStmt(E->getBase()); Writer.AddDeclRef(E->getMemberDecl(), Record); - // FIXME: write DeclarationNameLoc. Writer.AddSourceLocation(E->getMemberLoc(), Record); Record.push_back(E->isArrow()); + Writer.AddDeclarationNameLoc(E->MemberDNLoc, + E->getMemberDecl()->getDeclName(), Record); Code = serialization::EXPR_MEMBER; } @@ -597,15 +612,26 @@ void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) { Writer.AddStmt(E->getCond()); Writer.AddStmt(E->getLHS()); Writer.AddStmt(E->getRHS()); - Writer.AddStmt(E->getSAVE()); Writer.AddSourceLocation(E->getQuestionLoc(), Record); Writer.AddSourceLocation(E->getColonLoc(), Record); Code = serialization::EXPR_CONDITIONAL_OPERATOR; } +void +ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) { + VisitExpr(E); + Writer.AddStmt(E->getOpaqueValue()); + Writer.AddStmt(E->getCommon()); + Writer.AddStmt(E->getCond()); + Writer.AddStmt(E->getTrueExpr()); + Writer.AddStmt(E->getFalseExpr()); + Writer.AddSourceLocation(E->getQuestionLoc(), Record); + Writer.AddSourceLocation(E->getColonLoc(), Record); + Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR; +} + void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - Record.push_back(E->getValueKind()); Code = serialization::EXPR_IMPLICIT_CAST; } @@ -706,7 +732,7 @@ void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) { VisitExpr(E); Writer.AddSourceLocation(E->getAmpAmpLoc(), Record); Writer.AddSourceLocation(E->getLabelLoc(), Record); - Record.push_back(Writer.GetLabelID(E->getLabel())); + Writer.AddDeclRef(E->getLabel(), Record); Code = serialization::EXPR_ADDR_LABEL; } @@ -718,15 +744,6 @@ void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) { Code = serialization::EXPR_STMT; } -void ASTStmtWriter::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { - VisitExpr(E); - Writer.AddTypeSourceInfo(E->getArgTInfo1(), Record); - Writer.AddTypeSourceInfo(E->getArgTInfo2(), Record); - Writer.AddSourceLocation(E->getBuiltinLoc(), Record); - Writer.AddSourceLocation(E->getRParenLoc(), Record); - Code = serialization::EXPR_TYPES_COMPATIBLE; -} - void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) { VisitExpr(E); Writer.AddStmt(E->getCond()); @@ -756,7 +773,6 @@ void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) { VisitExpr(E); Writer.AddDeclRef(E->getBlockDecl(), Record); - Record.push_back(E->hasBlockDeclRefExprs()); Code = serialization::EXPR_BLOCK; } @@ -766,7 +782,6 @@ void ASTStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { Writer.AddSourceLocation(E->getLocation(), Record); Record.push_back(E->isByRef()); Record.push_back(E->isConstQualAdded()); - Writer.AddStmt(E->getCopyConstructorExpr()); Code = serialization::EXPR_BLOCK_DECL_REF; } @@ -817,26 +832,29 @@ void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { VisitExpr(E); - Writer.AddDeclRef(E->getProperty(), Record); + Record.push_back(E->isImplicitProperty()); + if (E->isImplicitProperty()) { + Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record); + Writer.AddDeclRef(E->getImplicitPropertySetter(), Record); + } else { + Writer.AddDeclRef(E->getExplicitProperty(), Record); + } Writer.AddSourceLocation(E->getLocation(), Record); - Writer.AddStmt(E->getBase()); + Writer.AddSourceLocation(E->getReceiverLocation(), Record); + if (E->isObjectReceiver()) { + Record.push_back(0); + Writer.AddStmt(E->getBase()); + } else if (E->isSuperReceiver()) { + Record.push_back(1); + Writer.AddTypeRef(E->getSuperReceiverType(), Record); + } else { + Record.push_back(2); + Writer.AddDeclRef(E->getClassReceiver(), Record); + } + Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR; } -void ASTStmtWriter::VisitObjCImplicitSetterGetterRefExpr( - ObjCImplicitSetterGetterRefExpr *E) { - VisitExpr(E); - Writer.AddDeclRef(E->getGetterMethod(), Record); - Writer.AddDeclRef(E->getSetterMethod(), Record); - - // NOTE: InterfaceDecl and Base are mutually exclusive. - Writer.AddDeclRef(E->getInterfaceDecl(), Record); - Writer.AddStmt(E->getBase()); - Writer.AddSourceLocation(E->getLocation(), Record); - Writer.AddSourceLocation(E->getClassLoc(), Record); - Code = serialization::EXPR_OBJC_KVC_REF_EXPR; -} - void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) { VisitExpr(E); Record.push_back(E->getNumArgs()); @@ -867,6 +885,7 @@ void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) { Writer.AddSourceLocation(E->getLeftLoc(), Record); Writer.AddSourceLocation(E->getRightLoc(), Record); + Writer.AddSourceLocation(E->getSelectorLoc(), Record); for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end(); Arg != ArgEnd; ++Arg) @@ -874,12 +893,6 @@ void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) { Code = serialization::EXPR_OBJC_MESSAGE_EXPR; } -void ASTStmtWriter::VisitObjCSuperExpr(ObjCSuperExpr *E) { - VisitExpr(E); - Writer.AddSourceLocation(E->getLoc(), Record); - Code = serialization::EXPR_OBJC_SUPER_EXPR; -} - void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { VisitStmt(S); Writer.AddStmt(S->getElement()); @@ -972,19 +985,20 @@ void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) { Record.push_back(E->isElidable()); Record.push_back(E->requiresZeroInitialization()); Record.push_back(E->getConstructionKind()); // FIXME: stable encoding + Writer.AddSourceRange(E->getParenRange(), Record); Code = serialization::EXPR_CXX_CONSTRUCT; } void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { VisitCXXConstructExpr(E); - Writer.AddSourceLocation(E->getTypeBeginLoc(), Record); - Writer.AddSourceLocation(E->getRParenLoc(), Record); + Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record); Code = serialization::EXPR_CXX_TEMPORARY_OBJECT; } void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { VisitExplicitCastExpr(E); - Writer.AddSourceLocation(E->getOperatorLoc(), Record); + Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()), + Record); } void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) { @@ -1039,6 +1053,18 @@ void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) { } } +void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) { + VisitExpr(E); + Writer.AddSourceRange(E->getSourceRange(), Record); + if (E->isTypeOperand()) { + Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record); + Code = serialization::EXPR_CXX_UUIDOF_TYPE; + } else { + Writer.AddStmt(E->getExprOperand()); + Code = serialization::EXPR_CXX_UUIDOF_EXPR; + } +} + void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) { VisitExpr(E); Writer.AddSourceLocation(E->getLocation(), Record); @@ -1076,7 +1102,7 @@ void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { VisitExpr(E); - Writer.AddSourceLocation(E->getTypeBeginLoc(), Record); + Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record); Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT; } @@ -1085,15 +1111,19 @@ void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) { VisitExpr(E); Record.push_back(E->isGlobalNew()); Record.push_back(E->hasInitializer()); + Record.push_back(E->doesUsualArrayDeleteWantSize()); Record.push_back(E->isArray()); Record.push_back(E->getNumPlacementArgs()); Record.push_back(E->getNumConstructorArgs()); Writer.AddDeclRef(E->getOperatorNew(), Record); Writer.AddDeclRef(E->getOperatorDelete(), Record); Writer.AddDeclRef(E->getConstructor(), Record); + Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record); Writer.AddSourceRange(E->getTypeIdParens(), Record); Writer.AddSourceLocation(E->getStartLoc(), Record); Writer.AddSourceLocation(E->getEndLoc(), Record); + Writer.AddSourceLocation(E->getConstructorLParen(), Record); + Writer.AddSourceLocation(E->getConstructorRParen(), Record); for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end(); I != e; ++I) Writer.AddStmt(*I); @@ -1105,6 +1135,8 @@ void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { VisitExpr(E); Record.push_back(E->isGlobalDelete()); Record.push_back(E->isArrayForm()); + Record.push_back(E->isArrayFormAsWritten()); + Record.push_back(E->doesUsualArrayDeleteWantSize()); Writer.AddDeclRef(E->getOperatorDelete(), Record); Writer.AddStmt(E->getArgument()); Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record); @@ -1134,30 +1166,28 @@ void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR; } -void ASTStmtWriter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { +void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) { VisitExpr(E); Record.push_back(E->getNumTemporaries()); for (unsigned i = 0, e = E->getNumTemporaries(); i != e; ++i) Writer.AddCXXTemporary(E->getTemporary(i), Record); Writer.AddStmt(E->getSubExpr()); - Code = serialization::EXPR_CXX_EXPR_WITH_TEMPORARIES; + Code = serialization::EXPR_EXPR_WITH_CLEANUPS; } void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ VisitExpr(E); - // Don't emit anything here, NumTemplateArgs must be emitted first. + // Don't emit anything here, hasExplicitTemplateArgs() must be + // emitted first. + Record.push_back(E->hasExplicitTemplateArgs()); if (E->hasExplicitTemplateArgs()) { const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs(); - assert(Args.NumTemplateArgs && - "Num of template args was zero! AST reading will mess up!"); Record.push_back(Args.NumTemplateArgs); AddExplicitTemplateArgumentList(Args); - } else { - Record.push_back(0); } if (!E->isImplicitAccess()) @@ -1170,9 +1200,7 @@ ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ Writer.AddNestedNameSpecifier(E->getQualifier(), Record); Writer.AddSourceRange(E->getQualifierRange(), Record); Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record); - // FIXME: write whole DeclarationNameInfo. - Writer.AddDeclarationName(E->getMember(), Record); - Writer.AddSourceLocation(E->getMemberLoc(), Record); + Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record); Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER; } @@ -1180,21 +1208,16 @@ void ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { VisitExpr(E); - // Don't emit anything here, NumTemplateArgs must be emitted first. - + // Don't emit anything here, hasExplicitTemplateArgs() must be + // emitted first. + Record.push_back(E->hasExplicitTemplateArgs()); if (E->hasExplicitTemplateArgs()) { const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs(); - assert(Args.NumTemplateArgs && - "Num of template args was zero! AST reading will mess up!"); Record.push_back(Args.NumTemplateArgs); AddExplicitTemplateArgumentList(Args); - } else { - Record.push_back(0); } - // FIXME: write whole DeclarationNameInfo. - Writer.AddDeclarationName(E->getDeclName(), Record); - Writer.AddSourceLocation(E->getLocation(), Record); + Writer.AddDeclarationNameInfo(E->NameInfo, Record); Writer.AddSourceRange(E->getQualifierRange(), Record); Writer.AddNestedNameSpecifier(E->getQualifier(), Record); Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF; @@ -1207,8 +1230,7 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { for (CXXUnresolvedConstructExpr::arg_iterator ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI) Writer.AddStmt(*ArgI); - Writer.AddSourceLocation(E->getTypeBeginLoc(), Record); - Writer.AddTypeRef(E->getTypeAsWritten(), Record); + Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record); Writer.AddSourceLocation(E->getLParenLoc(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record); Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT; @@ -1217,16 +1239,12 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - // Don't emit anything here, NumTemplateArgs must be emitted first. - + // Don't emit anything here, hasExplicitTemplateArgs() must be emitted first. + Record.push_back(E->hasExplicitTemplateArgs()); if (E->hasExplicitTemplateArgs()) { const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs(); - assert(Args.NumTemplateArgs && - "Num of template args was zero! AST reading will mess up!"); Record.push_back(Args.NumTemplateArgs); AddExplicitTemplateArgumentList(Args); - } else { - Record.push_back(0); } Record.push_back(E->getNumDecls()); @@ -1236,11 +1254,9 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { Record.push_back(OvI.getAccess()); } - // FIXME: write whole DeclarationNameInfo. - Writer.AddDeclarationName(E->getName(), Record); + Writer.AddDeclarationNameInfo(E->NameInfo, Record); Writer.AddNestedNameSpecifier(E->getQualifier(), Record); Writer.AddSourceRange(E->getQualifierRange(), Record); - Writer.AddSourceLocation(E->getNameLoc(), Record); } void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { @@ -1264,11 +1280,74 @@ void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { void ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { VisitExpr(E); Record.push_back(E->getTrait()); + Record.push_back(E->getValue()); Writer.AddSourceRange(E->getSourceRange(), Record); - Writer.AddTypeRef(E->getQueriedType(), Record); + Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record); Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT; } +void ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { + VisitExpr(E); + Record.push_back(E->getTrait()); + Record.push_back(E->getValue()); + Writer.AddSourceRange(E->getSourceRange(), Record); + Writer.AddTypeSourceInfo(E->getLhsTypeSourceInfo(), Record); + Writer.AddTypeSourceInfo(E->getRhsTypeSourceInfo(), Record); + Code = serialization::EXPR_BINARY_TYPE_TRAIT; +} + +void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { + VisitExpr(E); + Record.push_back(E->getValue()); + Writer.AddSourceRange(E->getSourceRange(), Record); + Writer.AddStmt(E->getOperand()); + Code = serialization::EXPR_CXX_NOEXCEPT; +} + +void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) { + VisitExpr(E); + Writer.AddSourceLocation(E->getEllipsisLoc(), Record); + Record.push_back(E->NumExpansions); + Writer.AddStmt(E->getPattern()); + Code = serialization::EXPR_PACK_EXPANSION; +} + +void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { + VisitExpr(E); + Writer.AddSourceLocation(E->OperatorLoc, Record); + Writer.AddSourceLocation(E->PackLoc, Record); + Writer.AddSourceLocation(E->RParenLoc, Record); + Record.push_back(E->Length); + Writer.AddDeclRef(E->Pack, Record); + Code = serialization::EXPR_SIZEOF_PACK; +} + +void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr( + SubstNonTypeTemplateParmPackExpr *E) { + VisitExpr(E); + Writer.AddDeclRef(E->Param, Record); + Writer.AddTemplateArgument(E->getArgumentPack(), Record); + Writer.AddSourceLocation(E->NameLoc, Record); + Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK; +} + +void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { + VisitExpr(E); + Record.push_back(Writer.getOpaqueValueID(E)); + Writer.AddSourceLocation(E->getLocation(), Record); + Code = serialization::EXPR_OPAQUE_VALUE; +} + +//===----------------------------------------------------------------------===// +// CUDA Expressions and Statements. +//===----------------------------------------------------------------------===// + +void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) { + VisitCallExpr(E); + Writer.AddStmt(E->getConfig()); + Code = serialization::EXPR_CUDA_KERNEL_CALL; +} + //===----------------------------------------------------------------------===// // ASTWriter Implementation //===----------------------------------------------------------------------===// @@ -1287,16 +1366,14 @@ unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) { return SwitchCaseIDs[S]; } -/// \brief Retrieve the ID for the given label statement, which may -/// or may not have been emitted yet. -unsigned ASTWriter::GetLabelID(LabelStmt *S) { - std::map<LabelStmt *, unsigned>::iterator Pos = LabelIDs.find(S); - if (Pos != LabelIDs.end()) - return Pos->second; +void ASTWriter::ClearSwitchCaseIDs() { + SwitchCaseIDs.clear(); +} - unsigned NextID = LabelIDs.size(); - LabelIDs[S] = NextID; - return NextID; +unsigned ASTWriter::getOpaqueValueID(OpaqueValueExpr *e) { + unsigned &entry = OpaqueValues[e]; + if (!entry) entry = OpaqueValues.size(); + return entry; } /// \brief Write the given substatement or subexpression to the diff --git a/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp b/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp index 5329b6c..b8833ce 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp @@ -19,6 +19,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/Lex/Preprocessor.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemStatCache.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Support/raw_ostream.h" #include <string> @@ -26,15 +27,15 @@ using namespace clang; PCHGenerator::PCHGenerator(const Preprocessor &PP, + const std::string &OutputFile, bool Chaining, const char *isysroot, llvm::raw_ostream *OS) - : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0), - StatCalls(0), Stream(Buffer), Writer(Stream) { - + : PP(PP), OutputFile(OutputFile), isysroot(isysroot), Out(OS), SemaPtr(0), + StatCalls(0), Stream(Buffer), Writer(Stream), Chaining(Chaining) { // Install a stat() listener to keep track of all of the stat() // calls. - StatCalls = new MemorizeStatCalls; + StatCalls = new MemorizeStatCalls(); // If we have a chain, we want new stat calls only, so install the memorizer // *after* the already installed ASTReader's stat cache. PP.getFileManager().addStatCache(StatCalls, @@ -45,9 +46,12 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { if (PP.getDiagnostics().hasErrorOccurred()) return; + // Set up the serialization listener. + Writer.SetSerializationListener(GetASTSerializationListener()); + // Emit the PCH file assert(SemaPtr && "No Sema?"); - Writer.WriteAST(*SemaPtr, StatCalls, isysroot); + Writer.WriteAST(*SemaPtr, StatCalls, OutputFile, isysroot); // Write the generated bitstream to "Out". Out->write((char *)&Buffer.front(), Buffer.size()); @@ -59,6 +63,16 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { Buffer.clear(); } +ASTMutationListener *PCHGenerator::GetASTMutationListener() { + if (Chaining) + return &Writer; + return 0; +} + +ASTSerializationListener *PCHGenerator::GetASTSerializationListener() { + return 0; +} + ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() { return &Writer; } |