summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization')
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp10
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h8
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp1848
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp849
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp727
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp1154
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp260
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp277
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp24
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;
}
OpenPOWER on IntegriCloud