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.cpp1
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h8
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp4300
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp798
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h243
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp352
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp1259
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp121
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp50
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ChainedIncludesSource.cpp52
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp34
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/Module.cpp109
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp253
13 files changed, 4293 insertions, 3287 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp
index 782e5c6..445e750 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp
@@ -43,6 +43,7 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
case BuiltinType::Long: ID = PREDEF_TYPE_LONG_ID; break;
case BuiltinType::LongLong: ID = PREDEF_TYPE_LONGLONG_ID; break;
case BuiltinType::Int128: ID = PREDEF_TYPE_INT128_ID; break;
+ case BuiltinType::Half: ID = PREDEF_TYPE_HALF_ID; break;
case BuiltinType::Float: ID = PREDEF_TYPE_FLOAT_ID; break;
case BuiltinType::Double: ID = PREDEF_TYPE_DOUBLE_ID; break;
case BuiltinType::LongDouble: ID = PREDEF_TYPE_LONGDOUBLE_ID; break;
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h
index 838df13..367f57f 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_SERIALIZATION_LIB_AST_COMMON_H
#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/AST/ASTContext.h"
namespace clang {
@@ -31,7 +32,7 @@ enum DeclUpdateKind {
TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
template <typename IdxForTypeTy>
-TypeID MakeTypeID(QualType T, IdxForTypeTy IdxForType) {
+TypeID MakeTypeID(ASTContext &Context, QualType T, IdxForTypeTy IdxForType) {
if (T.isNull())
return PREDEF_TYPE_NULL_ID;
@@ -46,6 +47,11 @@ TypeID MakeTypeID(QualType T, IdxForTypeTy IdxForType) {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
return TypeIdxFromBuiltin(BT).asTypeID(FastQuals);
+ if (T == Context.AutoDeductTy)
+ return TypeIdx(PREDEF_TYPE_AUTO_DEDUCT).asTypeID(FastQuals);
+ if (T == Context.AutoRRefDeductTy)
+ return TypeIdx(PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals);
+
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 a4ed5f4..fe1cc30 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp
@@ -13,7 +13,9 @@
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTDeserializationListener.h"
+#include "clang/Serialization/ModuleManager.h"
#include "ASTCommon.h"
+#include "ASTReaderInternals.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
#include "clang/Sema/Sema.h"
@@ -52,6 +54,7 @@
using namespace clang;
using namespace clang::serialization;
+using namespace clang::serialization::reader;
//===----------------------------------------------------------------------===//
// PCH validator implementation
@@ -62,103 +65,36 @@ ASTReaderListener::~ASTReaderListener() {}
bool
PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
const LangOptions &PPLangOpts = PP.getLangOptions();
-#define PARSE_LANGOPT_BENIGN(Option)
-#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
- if (PPLangOpts.Option != LangOpts.Option) { \
- Reader.Diag(DiagID) << LangOpts.Option << PPLangOpts.Option; \
- return true; \
- }
-
- PARSE_LANGOPT_BENIGN(Trigraphs);
- PARSE_LANGOPT_BENIGN(BCPLComment);
- PARSE_LANGOPT_BENIGN(DollarIdents);
- PARSE_LANGOPT_BENIGN(AsmPreprocessor);
- PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
- PARSE_LANGOPT_IMPORTANT(GNUKeywords, diag::warn_pch_gnu_keywords);
- PARSE_LANGOPT_BENIGN(ImplicitInt);
- PARSE_LANGOPT_BENIGN(Digraphs);
- PARSE_LANGOPT_BENIGN(HexFloats);
- PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
- PARSE_LANGOPT_IMPORTANT(C1X, diag::warn_pch_c1x);
- 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);
- PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
- 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(AppleKext, diag::warn_pch_apple_kext);
- PARSE_LANGOPT_IMPORTANT(ObjCDefaultSynthProperties,
- diag::warn_pch_objc_auto_properties);
- PARSE_LANGOPT_BENIGN(ObjCInferRelatedResultType)
- PARSE_LANGOPT_IMPORTANT(NoConstantCFStrings,
- diag::warn_pch_no_constant_cfstrings);
- PARSE_LANGOPT_BENIGN(PascalStrings);
- PARSE_LANGOPT_BENIGN(WritableStrings);
- PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
- diag::warn_pch_lax_vector_conversions);
- PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
- PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
- PARSE_LANGOPT_IMPORTANT(ObjCExceptions, diag::warn_pch_objc_exceptions);
- PARSE_LANGOPT_IMPORTANT(CXXExceptions, diag::warn_pch_cxx_exceptions);
- PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_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);
- PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
- diag::warn_pch_thread_safe_statics);
- PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
- PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
- PARSE_LANGOPT_BENIGN(EmitAllDecls);
- PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
- PARSE_LANGOPT_BENIGN(getSignedOverflowBehavior());
- PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
- diag::warn_pch_heinous_extensions);
- // FIXME: Most of the options below are benign if the macro wasn't
- // used. Unfortunately, this means that a PCH compiled without
- // optimization can't be used with optimization turned on, even
- // though the only thing that changes is whether __OPTIMIZE__ was
- // defined... but if __OPTIMIZE__ never showed up in the header, it
- // doesn't matter. We could consider making this some special kind
- // of check.
- PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
- PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
- PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
- PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
- PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
- PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
- PARSE_LANGOPT_IMPORTANT(Deprecated, diag::warn_pch_deprecated);
- 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();
- return true;
+
+#define LANGOPT(Name, Bits, Default, Description) \
+ if (PPLangOpts.Name != LangOpts.Name) { \
+ Reader.Diag(diag::err_pch_langopt_mismatch) \
+ << Description << LangOpts.Name << PPLangOpts.Name; \
+ return true; \
+ }
+
+#define VALUE_LANGOPT(Name, Bits, Default, Description) \
+ if (PPLangOpts.Name != LangOpts.Name) { \
+ Reader.Diag(diag::err_pch_langopt_value_mismatch) \
+ << Description; \
+ return true; \
+}
+
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+ if (PPLangOpts.get##Name() != LangOpts.get##Name()) { \
+ Reader.Diag(diag::err_pch_langopt_value_mismatch) \
+ << Description; \
+ return true; \
}
- PARSE_LANGOPT_BENIGN(getVisibilityMode());
- PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
- 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_BENIGN(DefaultFPContract);
- PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
- PARSE_LANGOPT_BENIGN(SpellChecking);
- PARSE_LANGOPT_IMPORTANT(ObjCAutoRefCount, diag::warn_pch_auto_ref_count);
- PARSE_LANGOPT_BENIGN(ObjCInferRelatedReturnType);
-#undef PARSE_LANGOPT_IMPORTANT
-#undef PARSE_LANGOPT_BENIGN
+#define BENIGN_LANGOPT(Name, Bits, Default, Description)
+#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
+#include "clang/Basic/LangOptions.def"
+
return false;
}
-bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
+bool PCHValidator::ReadTargetTriple(StringRef Triple) {
if (Triple == PP.getTargetInfo().getTriple().str())
return false;
@@ -169,14 +105,14 @@ bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
namespace {
struct EmptyStringRef {
- bool operator ()(llvm::StringRef r) const { return r.empty(); }
+ bool operator ()(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,
+static bool EqualConcatenations(SmallVector<StringRef, 2> L,
PCHPredefinesBlocks R) {
// First, sum up the lengths.
unsigned LL = 0, RL = 0;
@@ -196,7 +132,7 @@ static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L,
R.erase(std::remove_if(R.begin(), R.end(), EmptyBlock()), R.end());
// Do it the hard way. At this point, both vectors must be non-empty.
- llvm::StringRef LR = L[0], RR = R[0].Data;
+ StringRef LR = L[0], RR = R[0].Data;
unsigned LI = 0, RI = 0, LN = L.size(), RN = R.size();
(void) RN;
for (;;) {
@@ -236,12 +172,12 @@ static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L,
}
}
-static std::pair<FileID, llvm::StringRef::size_type>
-FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) {
- std::pair<FileID, llvm::StringRef::size_type> Res;
+static std::pair<FileID, StringRef::size_type>
+FindMacro(const PCHPredefinesBlocks &Buffers, StringRef MacroDef) {
+ std::pair<FileID, StringRef::size_type> Res;
for (unsigned I = 0, N = Buffers.size(); I != N; ++I) {
Res.second = Buffers[I].Data.find(MacroDef);
- if (Res.second != llvm::StringRef::npos) {
+ if (Res.second != StringRef::npos) {
Res.first = Buffers[I].BufferID;
break;
}
@@ -250,7 +186,7 @@ FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) {
}
bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
- llvm::StringRef OriginalFileName,
+ StringRef OriginalFileName,
std::string &SuggestedPredefines,
FileManager &FileMgr) {
// We are in the context of an implicit include, so the predefines buffer will
@@ -261,9 +197,9 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
PCHInclude += "#include \"";
PCHInclude += NormalizeDashIncludePath(OriginalFileName, FileMgr);
PCHInclude += "\"\n";
- std::pair<llvm::StringRef,llvm::StringRef> Split =
- llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
- llvm::StringRef Left = Split.first, Right = Split.second;
+ std::pair<StringRef,StringRef> Split =
+ StringRef(PP.getPredefines()).split(PCHInclude.str());
+ StringRef Left = Split.first, Right = Split.second;
if (Left == PP.getPredefines()) {
Error("Missing PCH include entry!");
return true;
@@ -271,7 +207,7 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
// If the concatenation of all the PCH buffers is equal to the adjusted
// command line, we're done.
- llvm::SmallVector<llvm::StringRef, 2> CommandLine;
+ SmallVector<StringRef, 2> CommandLine;
CommandLine.push_back(Left);
CommandLine.push_back(Right);
if (EqualConcatenations(CommandLine, Buffers))
@@ -281,18 +217,18 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
// The predefines buffers are different. Determine what the differences are,
// and whether they require us to reject the PCH file.
- llvm::SmallVector<llvm::StringRef, 8> PCHLines;
+ SmallVector<StringRef, 8> PCHLines;
for (unsigned I = 0, N = Buffers.size(); I != N; ++I)
Buffers[I].Data.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
- llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
+ SmallVector<StringRef, 8> CmdLineLines;
Left.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;
+ SmallVector<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 ")) {
@@ -325,7 +261,7 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
// Determine which predefines that were used to build the PCH file are missing
// from the command line.
- std::vector<llvm::StringRef> MissingPredefines;
+ std::vector<StringRef> MissingPredefines;
std::set_difference(PCHLines.begin(), PCHLines.end(),
CmdLineLines.begin(), CmdLineLines.end(),
std::back_inserter(MissingPredefines));
@@ -333,7 +269,7 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
bool MissingDefines = false;
bool ConflictingDefines = false;
for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
- llvm::StringRef Missing = MissingPredefines[I];
+ 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.
@@ -351,13 +287,13 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
= Missing.find_first_of("( \n\r", StartOfMacroName);
assert(EndOfMacroName != std::string::npos &&
"Couldn't find the end of the macro name");
- llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
+ StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
// Determine whether this macro was given a different definition on the
// command line.
std::string MacroDefStart = "#define " + MacroName.str();
std::string::size_type MacroDefLen = MacroDefStart.size();
- llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
+ SmallVector<StringRef, 8>::iterator ConflictPos
= std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
MacroDefStart);
for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
@@ -382,12 +318,12 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
<< MacroName;
// Show the definition of this macro within the PCH file.
- std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
+ std::pair<FileID, StringRef::size_type> MacroLoc =
FindMacro(Buffers, Missing);
- assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
+ assert(MacroLoc.second!=StringRef::npos && "Unable to find macro!");
SourceLocation PCHMissingLoc =
SourceMgr.getLocForStartOfFile(MacroLoc.first)
- .getFileLocWithOffset(MacroLoc.second);
+ .getLocWithOffset(MacroLoc.second);
Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
ConflictingDefines = true;
@@ -405,12 +341,12 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
}
// Show the definition of this macro within the PCH file.
- std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
+ std::pair<FileID, StringRef::size_type> MacroLoc =
FindMacro(Buffers, Missing);
- assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
+ assert(MacroLoc.second!=StringRef::npos && "Unable to find macro!");
SourceLocation PCHMissingLoc =
SourceMgr.getLocForStartOfFile(MacroLoc.first)
- .getFileLocWithOffset(MacroLoc.second);
+ .getLocWithOffset(MacroLoc.second);
Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
}
@@ -421,12 +357,12 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
// parameters that were not present when building the PCH
// file. Extra #defines are okay, so long as the identifiers being
// defined were not used within the precompiled header.
- std::vector<llvm::StringRef> ExtraPredefines;
+ std::vector<StringRef> ExtraPredefines;
std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
PCHLines.begin(), PCHLines.end(),
std::back_inserter(ExtraPredefines));
for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
- llvm::StringRef &Extra = ExtraPredefines[I];
+ StringRef &Extra = ExtraPredefines[I];
if (!Extra.startswith("#define ")) {
Reader.Diag(diag::warn_pch_compiler_options_mismatch);
return true;
@@ -439,7 +375,7 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
= Extra.find_first_of("( \n\r", StartOfMacroName);
assert(EndOfMacroName != std::string::npos &&
"Couldn't find the end of the macro name");
- llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
+ StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
// Check whether this name was used somewhere in the PCH file. If
// so, defining it as a macro could change behavior, so we reject
@@ -479,440 +415,321 @@ ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
}
-namespace {
-class ASTSelectorLookupTrait {
- ASTReader &Reader;
-public:
- struct data_type {
- SelectorID ID;
- ObjCMethodList Instance, Factory;
- };
+unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
+ return serialization::ComputeHash(Sel);
+}
- typedef Selector external_key_type;
- typedef external_key_type internal_key_type;
- explicit ASTSelectorLookupTrait(ASTReader &Reader) : Reader(Reader) { }
+std::pair<unsigned, unsigned>
+ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
+ using namespace clang::io;
+ unsigned KeyLen = ReadUnalignedLE16(d);
+ unsigned DataLen = ReadUnalignedLE16(d);
+ return std::make_pair(KeyLen, DataLen);
+}
- static bool EqualKey(const internal_key_type& a,
- const internal_key_type& b) {
- return a == b;
- }
+ASTSelectorLookupTrait::internal_key_type
+ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
+ using namespace clang::io;
+ SelectorTable &SelTable = Reader.getContext().Selectors;
+ unsigned N = ReadUnalignedLE16(d);
+ IdentifierInfo *FirstII
+ = Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+ if (N == 0)
+ return SelTable.getNullarySelector(FirstII);
+ else if (N == 1)
+ return SelTable.getUnarySelector(FirstII);
- static unsigned ComputeHash(Selector Sel) {
- return serialization::ComputeHash(Sel);
- }
+ SmallVector<IdentifierInfo *, 16> Args;
+ Args.push_back(FirstII);
+ for (unsigned I = 1; I != N; ++I)
+ Args.push_back(Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)));
- // This hopefully will just get inlined and removed by the optimizer.
- static const internal_key_type&
- GetInternalKey(const external_key_type& x) { return x; }
+ return SelTable.getSelector(N, Args.data());
+}
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- using namespace clang::io;
- unsigned KeyLen = ReadUnalignedLE16(d);
- unsigned DataLen = ReadUnalignedLE16(d);
- return std::make_pair(KeyLen, DataLen);
- }
+ASTSelectorLookupTrait::data_type
+ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,
+ unsigned DataLen) {
+ using namespace clang::io;
- internal_key_type ReadKey(const unsigned char* d, unsigned) {
- using namespace clang::io;
- SelectorTable &SelTable = Reader.getContext()->Selectors;
- unsigned N = ReadUnalignedLE16(d);
- IdentifierInfo *FirstII
- = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
- if (N == 0)
- return SelTable.getNullarySelector(FirstII);
- else if (N == 1)
- return SelTable.getUnarySelector(FirstII);
+ data_type Result;
- llvm::SmallVector<IdentifierInfo *, 16> Args;
- Args.push_back(FirstII);
- for (unsigned I = 1; I != N; ++I)
- Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
+ Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d));
+ unsigned NumInstanceMethods = ReadUnalignedLE16(d);
+ unsigned NumFactoryMethods = ReadUnalignedLE16(d);
- return SelTable.getSelector(N, Args.data());
+ // Load instance methods
+ for (unsigned I = 0; I != NumInstanceMethods; ++I) {
+ if (ObjCMethodDecl *Method
+ = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
+ Result.Instance.push_back(Method);
}
- data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
- using namespace clang::io;
-
- data_type Result;
-
- Result.ID = ReadUnalignedLE32(d);
- unsigned NumInstanceMethods = ReadUnalignedLE16(d);
- unsigned NumFactoryMethods = ReadUnalignedLE16(d);
-
- // Load instance methods
- ObjCMethodList *Prev = 0;
- for (unsigned I = 0; I != NumInstanceMethods; ++I) {
- ObjCMethodDecl *Method
- = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
- if (!Result.Instance.Method) {
- // This is the first method, which is the easy case.
- Result.Instance.Method = Method;
- Prev = &Result.Instance;
- continue;
- }
-
- ObjCMethodList *Mem =
- Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
- Prev->Next = new (Mem) ObjCMethodList(Method, 0);
- Prev = Prev->Next;
- }
-
- // Load factory methods
- Prev = 0;
- for (unsigned I = 0; I != NumFactoryMethods; ++I) {
- ObjCMethodDecl *Method
- = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
- if (!Result.Factory.Method) {
- // This is the first method, which is the easy case.
- Result.Factory.Method = Method;
- Prev = &Result.Factory;
- continue;
- }
-
- ObjCMethodList *Mem =
- Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
- Prev->Next = new (Mem) ObjCMethodList(Method, 0);
- Prev = Prev->Next;
- }
-
- return Result;
+ // Load factory methods
+ for (unsigned I = 0; I != NumFactoryMethods; ++I) {
+ if (ObjCMethodDecl *Method
+ = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
+ Result.Factory.push_back(Method);
}
-};
-
-} // end anonymous namespace
-
-/// \brief The on-disk hash table used for the global method pool.
-typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
- ASTSelectorLookupTable;
-
-namespace clang {
-class ASTIdentifierLookupTrait {
- ASTReader &Reader;
- 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
- // identifier that was constructed before the AST file was read.
- IdentifierInfo *KnownII;
-
-public:
- typedef IdentifierInfo * data_type;
-
- typedef const std::pair<const char*, unsigned> external_key_type;
-
- typedef external_key_type internal_key_type;
- ASTIdentifierLookupTrait(ASTReader &Reader, ASTReader::PerFileData &F,
- IdentifierInfo *II = 0)
- : Reader(Reader), F(F), KnownII(II) { }
+ return Result;
+}
- static bool EqualKey(const internal_key_type& a,
- const internal_key_type& b) {
- return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
- : false;
- }
+unsigned ASTIdentifierLookupTrait::ComputeHash(const internal_key_type& a) {
+ return llvm::HashString(StringRef(a.first, a.second));
+}
- static unsigned ComputeHash(const internal_key_type& a) {
- return llvm::HashString(llvm::StringRef(a.first, a.second));
- }
+std::pair<unsigned, unsigned>
+ASTIdentifierLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
+ using namespace clang::io;
+ unsigned DataLen = ReadUnalignedLE16(d);
+ unsigned KeyLen = ReadUnalignedLE16(d);
+ return std::make_pair(KeyLen, DataLen);
+}
- // This hopefully will just get inlined and removed by the optimizer.
- static const internal_key_type&
- GetInternalKey(const external_key_type& x) { return x; }
+std::pair<const char*, unsigned>
+ASTIdentifierLookupTrait::ReadKey(const unsigned char* d, unsigned n) {
+ assert(n >= 2 && d[n-1] == '\0');
+ return std::make_pair((const char*) d, n-1);
+}
- // This hopefully will just get inlined and removed by the optimizer.
- static const external_key_type&
- GetExternalKey(const internal_key_type& x) { return x; }
+IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
+ const unsigned char* d,
+ unsigned DataLen) {
+ using namespace clang::io;
+ unsigned RawID = ReadUnalignedLE32(d);
+ bool IsInteresting = RawID & 0x01;
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- using namespace clang::io;
- unsigned DataLen = ReadUnalignedLE16(d);
- unsigned KeyLen = ReadUnalignedLE16(d);
- return std::make_pair(KeyLen, DataLen);
- }
+ // Wipe out the "is interesting" bit.
+ RawID = RawID >> 1;
- static std::pair<const char*, unsigned>
- ReadKey(const unsigned char* d, unsigned n) {
- assert(n >= 2 && d[n-1] == '\0');
- return std::make_pair((const char*) d, n-1);
- }
-
- IdentifierInfo *ReadData(const internal_key_type& k,
- const unsigned char* d,
- unsigned DataLen) {
- using namespace clang::io;
- IdentID ID = ReadUnalignedLE32(d);
- bool IsInteresting = ID & 0x01;
-
- // Wipe out the "is interesting" bit.
- ID = ID >> 1;
-
- if (!IsInteresting) {
- // For uninteresting identifiers, just build the IdentifierInfo
- // and associate it with the persistent ID.
- IdentifierInfo *II = KnownII;
- if (!II)
- II = &Reader.getIdentifierTable().getOwn(llvm::StringRef(k.first,
- k.second));
- Reader.SetIdentifierInfo(ID, II);
- II->setIsFromAST();
- return II;
- }
-
- unsigned Bits = ReadUnalignedLE16(d);
- bool CPlusPlusOperatorKeyword = Bits & 0x01;
- Bits >>= 1;
- bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
- Bits >>= 1;
- bool Poisoned = Bits & 0x01;
- Bits >>= 1;
- bool ExtensionToken = Bits & 0x01;
- Bits >>= 1;
- bool hasMacroDefinition = Bits & 0x01;
- Bits >>= 1;
- unsigned ObjCOrBuiltinID = Bits & 0x3FF;
- Bits >>= 10;
-
- assert(Bits == 0 && "Extra bits in the identifier?");
- DataLen -= 6;
-
- // Build the IdentifierInfo itself and link the identifier ID with
- // the new IdentifierInfo.
+ IdentID ID = Reader.getGlobalIdentifierID(F, RawID);
+ if (!IsInteresting) {
+ // For uninteresting identifiers, just build the IdentifierInfo
+ // and associate it with the persistent ID.
IdentifierInfo *II = KnownII;
if (!II)
- II = &Reader.getIdentifierTable().getOwn(llvm::StringRef(k.first,
- k.second));
+ II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
Reader.SetIdentifierInfo(ID, II);
-
- // Set or check the various bits in the IdentifierInfo structure.
- // Token IDs are read-only.
- if (HasRevertedTokenIDToIdentifier)
- II->RevertTokenIDToIdentifier();
- II->setObjCOrBuiltinID(ObjCOrBuiltinID);
- assert(II->isExtensionToken() == ExtensionToken &&
- "Incorrect extension token flag");
- (void)ExtensionToken;
- II->setIsPoisoned(Poisoned);
- assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
- "Incorrect C++ operator keyword flag");
- (void)CPlusPlusOperatorKeyword;
-
- // If this identifier is a macro, deserialize the macro
- // definition.
- if (hasMacroDefinition) {
- uint32_t Offset = ReadUnalignedLE32(d);
- Reader.SetIdentifierIsMacro(II, F, Offset);
- DataLen -= 4;
- }
-
- // Read all of the declarations visible at global scope with this
- // name.
- if (Reader.getContext() == 0) return II;
- if (DataLen > 0) {
- llvm::SmallVector<uint32_t, 4> DeclIDs;
- for (; DataLen > 0; DataLen -= 4)
- DeclIDs.push_back(ReadUnalignedLE32(d));
- Reader.SetGloballyVisibleDecls(II, DeclIDs);
- }
-
II->setIsFromAST();
return II;
}
-};
-
-} // end anonymous namespace
-
-/// \brief The on-disk hash table used to contain information about
-/// all of the identifiers in the program.
-typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
- ASTIdentifierLookupTable;
-
-namespace {
-class ASTDeclContextNameLookupTrait {
- ASTReader &Reader;
-
-public:
- /// \brief Pair of begin/end iterators for DeclIDs.
- typedef std::pair<DeclID *, DeclID *> data_type;
-
- /// \brief Special internal key for declaration names.
- /// The hash table creates keys for comparison; we do not create
- /// a DeclarationName for the internal key to avoid deserializing types.
- struct DeclNameKey {
- DeclarationName::NameKind Kind;
- uint64_t Data;
- DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
- };
-
- typedef DeclarationName external_key_type;
- typedef DeclNameKey internal_key_type;
-
- explicit ASTDeclContextNameLookupTrait(ASTReader &Reader) : Reader(Reader) { }
-
- static bool EqualKey(const internal_key_type& a,
- const internal_key_type& b) {
- return a.Kind == b.Kind && a.Data == b.Data;
- }
-
- unsigned ComputeHash(const DeclNameKey &Key) const {
- llvm::FoldingSetNodeID ID;
- ID.AddInteger(Key.Kind);
- switch (Key.Kind) {
- case DeclarationName::Identifier:
- case DeclarationName::CXXLiteralOperatorName:
- ID.AddString(((IdentifierInfo*)Key.Data)->getName());
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- ID.AddInteger((TypeID)Key.Data);
- break;
- case DeclarationName::CXXOperatorName:
- ID.AddInteger((OverloadedOperatorKind)Key.Data);
- break;
- case DeclarationName::CXXUsingDirective:
- break;
- }
-
- return ID.ComputeHash();
+ unsigned Bits = ReadUnalignedLE16(d);
+ bool CPlusPlusOperatorKeyword = Bits & 0x01;
+ Bits >>= 1;
+ bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
+ Bits >>= 1;
+ bool Poisoned = Bits & 0x01;
+ Bits >>= 1;
+ bool ExtensionToken = Bits & 0x01;
+ Bits >>= 1;
+ bool hasMacroDefinition = Bits & 0x01;
+ Bits >>= 1;
+ unsigned ObjCOrBuiltinID = Bits & 0x3FF;
+ Bits >>= 10;
+
+ assert(Bits == 0 && "Extra bits in the identifier?");
+ DataLen -= 6;
+
+ // Build the IdentifierInfo itself and link the identifier ID with
+ // the new IdentifierInfo.
+ IdentifierInfo *II = KnownII;
+ if (!II)
+ II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second));
+ Reader.SetIdentifierInfo(ID, II);
+
+ // Set or check the various bits in the IdentifierInfo structure.
+ // Token IDs are read-only.
+ if (HasRevertedTokenIDToIdentifier)
+ II->RevertTokenIDToIdentifier();
+ II->setObjCOrBuiltinID(ObjCOrBuiltinID);
+ assert(II->isExtensionToken() == ExtensionToken &&
+ "Incorrect extension token flag");
+ (void)ExtensionToken;
+ if (Poisoned)
+ II->setIsPoisoned(true);
+ assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
+ "Incorrect C++ operator keyword flag");
+ (void)CPlusPlusOperatorKeyword;
+
+ // If this identifier is a macro, deserialize the macro
+ // definition.
+ if (hasMacroDefinition) {
+ // FIXME: Check for conflicts?
+ uint32_t Offset = ReadUnalignedLE32(d);
+ Reader.SetIdentifierIsMacro(II, F, Offset);
+ DataLen -= 4;
+ }
+
+ // Read all of the declarations visible at global scope with this
+ // name.
+ if (DataLen > 0) {
+ SmallVector<uint32_t, 4> DeclIDs;
+ for (; DataLen > 0; DataLen -= 4)
+ DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d)));
+ Reader.SetGloballyVisibleDecls(II, DeclIDs);
+ }
+
+ II->setIsFromAST();
+ return II;
+}
+
+unsigned
+ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) const {
+ llvm::FoldingSetNodeID ID;
+ ID.AddInteger(Key.Kind);
+
+ switch (Key.Kind) {
+ case DeclarationName::Identifier:
+ case DeclarationName::CXXLiteralOperatorName:
+ ID.AddString(((IdentifierInfo*)Key.Data)->getName());
+ break;
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
+ break;
+ case DeclarationName::CXXOperatorName:
+ ID.AddInteger((OverloadedOperatorKind)Key.Data);
+ break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ case DeclarationName::CXXUsingDirective:
+ break;
}
- internal_key_type GetInternalKey(const external_key_type& Name) const {
- DeclNameKey Key;
- Key.Kind = Name.getNameKind();
- switch (Name.getNameKind()) {
- case DeclarationName::Identifier:
- Key.Data = (uint64_t)Name.getAsIdentifierInfo();
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- Key.Data = Reader.GetTypeID(Name.getCXXNameType());
- break;
- case DeclarationName::CXXOperatorName:
- Key.Data = Name.getCXXOverloadedOperator();
- break;
- case DeclarationName::CXXLiteralOperatorName:
- Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
- break;
- case DeclarationName::CXXUsingDirective:
- break;
- }
+ return ID.ComputeHash();
+}
- return Key;
+ASTDeclContextNameLookupTrait::internal_key_type
+ASTDeclContextNameLookupTrait::GetInternalKey(
+ const external_key_type& Name) const {
+ DeclNameKey Key;
+ Key.Kind = Name.getNameKind();
+ switch (Name.getNameKind()) {
+ case DeclarationName::Identifier:
+ Key.Data = (uint64_t)Name.getAsIdentifierInfo();
+ break;
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
+ break;
+ case DeclarationName::CXXOperatorName:
+ Key.Data = Name.getCXXOverloadedOperator();
+ break;
+ case DeclarationName::CXXLiteralOperatorName:
+ Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
+ break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ case DeclarationName::CXXUsingDirective:
+ Key.Data = 0;
+ break;
}
- external_key_type GetExternalKey(const internal_key_type& Key) const {
- ASTContext *Context = Reader.getContext();
- switch (Key.Kind) {
- case DeclarationName::Identifier:
- return DeclarationName((IdentifierInfo*)Key.Data);
-
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- return DeclarationName(Selector(Key.Data));
+ return Key;
+}
- case DeclarationName::CXXConstructorName:
- return Context->DeclarationNames.getCXXConstructorName(
- Context->getCanonicalType(Reader.GetType(Key.Data)));
+ASTDeclContextNameLookupTrait::external_key_type
+ASTDeclContextNameLookupTrait::GetExternalKey(
+ const internal_key_type& Key) const {
+ ASTContext &Context = Reader.getContext();
+ switch (Key.Kind) {
+ case DeclarationName::Identifier:
+ return DeclarationName((IdentifierInfo*)Key.Data);
- case DeclarationName::CXXDestructorName:
- return Context->DeclarationNames.getCXXDestructorName(
- Context->getCanonicalType(Reader.GetType(Key.Data)));
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ return DeclarationName(Selector(Key.Data));
- case DeclarationName::CXXConversionFunctionName:
- return Context->DeclarationNames.getCXXConversionFunctionName(
- Context->getCanonicalType(Reader.GetType(Key.Data)));
+ case DeclarationName::CXXConstructorName:
+ return Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(Reader.getLocalType(F, Key.Data)));
- case DeclarationName::CXXOperatorName:
- return Context->DeclarationNames.getCXXOperatorName(
- (OverloadedOperatorKind)Key.Data);
+ case DeclarationName::CXXDestructorName:
+ return Context.DeclarationNames.getCXXDestructorName(
+ Context.getCanonicalType(Reader.getLocalType(F, Key.Data)));
- case DeclarationName::CXXLiteralOperatorName:
- return Context->DeclarationNames.getCXXLiteralOperatorName(
- (IdentifierInfo*)Key.Data);
+ case DeclarationName::CXXConversionFunctionName:
+ return Context.DeclarationNames.getCXXConversionFunctionName(
+ Context.getCanonicalType(Reader.getLocalType(F, Key.Data)));
- case DeclarationName::CXXUsingDirective:
- return DeclarationName::getUsingDirectiveName();
- }
+ case DeclarationName::CXXOperatorName:
+ return Context.DeclarationNames.getCXXOperatorName(
+ (OverloadedOperatorKind)Key.Data);
- llvm_unreachable("Invalid Name Kind ?");
- }
+ case DeclarationName::CXXLiteralOperatorName:
+ return Context.DeclarationNames.getCXXLiteralOperatorName(
+ (IdentifierInfo*)Key.Data);
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- using namespace clang::io;
- unsigned KeyLen = ReadUnalignedLE16(d);
- unsigned DataLen = ReadUnalignedLE16(d);
- return std::make_pair(KeyLen, DataLen);
+ case DeclarationName::CXXUsingDirective:
+ return DeclarationName::getUsingDirectiveName();
}
- internal_key_type ReadKey(const unsigned char* d, unsigned) {
- using namespace clang::io;
+ llvm_unreachable("Invalid Name Kind ?");
+}
- DeclNameKey Key;
- Key.Kind = (DeclarationName::NameKind)*d++;
- switch (Key.Kind) {
- case DeclarationName::Identifier:
- Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- Key.Data =
- (uint64_t)Reader.DecodeSelector(ReadUnalignedLE32(d)).getAsOpaquePtr();
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- Key.Data = ReadUnalignedLE32(d); // TypeID
- break;
- case DeclarationName::CXXOperatorName:
- Key.Data = *d++; // OverloadedOperatorKind
- break;
- case DeclarationName::CXXLiteralOperatorName:
- Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
- break;
- case DeclarationName::CXXUsingDirective:
- break;
- }
+std::pair<unsigned, unsigned>
+ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
+ using namespace clang::io;
+ unsigned KeyLen = ReadUnalignedLE16(d);
+ unsigned DataLen = ReadUnalignedLE16(d);
+ return std::make_pair(KeyLen, DataLen);
+}
- return Key;
- }
+ASTDeclContextNameLookupTrait::internal_key_type
+ASTDeclContextNameLookupTrait::ReadKey(const unsigned char* d, unsigned) {
+ using namespace clang::io;
- data_type ReadData(internal_key_type, const unsigned char* d,
- unsigned DataLen) {
- using namespace clang::io;
- unsigned NumDecls = ReadUnalignedLE16(d);
- DeclID *Start = (DeclID *)d;
- return std::make_pair(Start, Start + NumDecls);
+ DeclNameKey Key;
+ Key.Kind = (DeclarationName::NameKind)*d++;
+ switch (Key.Kind) {
+ case DeclarationName::Identifier:
+ Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+ break;
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ Key.Data =
+ (uint64_t)Reader.getLocalSelector(F, ReadUnalignedLE32(d))
+ .getAsOpaquePtr();
+ break;
+ case DeclarationName::CXXOperatorName:
+ Key.Data = *d++; // OverloadedOperatorKind
+ break;
+ case DeclarationName::CXXLiteralOperatorName:
+ Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+ break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ case DeclarationName::CXXUsingDirective:
+ Key.Data = 0;
+ break;
}
-};
-} // end anonymous namespace
+ return Key;
+}
-/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
-typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
- ASTDeclContextNameLookupTable;
+ASTDeclContextNameLookupTrait::data_type
+ASTDeclContextNameLookupTrait::ReadData(internal_key_type,
+ const unsigned char* d,
+ unsigned DataLen) {
+ using namespace clang::io;
+ unsigned NumDecls = ReadUnalignedLE16(d);
+ DeclID *Start = (DeclID *)d;
+ return std::make_pair(Start, Start + NumDecls);
+}
-bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
+bool ASTReader::ReadDeclContextStorage(Module &M,
+ llvm::BitstreamCursor &Cursor,
const std::pair<uint64_t, uint64_t> &Offsets,
DeclContextInfo &Info) {
SavedStreamPosition SavedPosition(Cursor);
@@ -932,9 +749,6 @@ bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair*>(Blob);
Info.NumLexicalDecls = BlobLen / sizeof(KindDeclIDPair);
- } else {
- Info.LexicalDecls = 0;
- Info.NumLexicalDecls = 0;
}
// Now the lookup table.
@@ -954,20 +768,18 @@ bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
= ASTDeclContextNameLookupTable::Create(
(const unsigned char *)Blob + Record[0],
(const unsigned char *)Blob,
- ASTDeclContextNameLookupTrait(*this));
- } else {
- Info.NameLookupTableData = 0;
+ ASTDeclContextNameLookupTrait(*this, M));
}
return false;
}
-void ASTReader::Error(llvm::StringRef Msg) {
+void ASTReader::Error(StringRef Msg) {
Error(diag::err_fe_pch_malformed, Msg);
}
void ASTReader::Error(unsigned DiagID,
- llvm::StringRef Arg1, llvm::StringRef Arg2) {
+ StringRef Arg1, StringRef Arg2) {
if (Diags.isDiagnosticInFlight())
Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2);
else
@@ -990,8 +802,8 @@ bool ASTReader::CheckPredefinesBuffers() {
/// \brief Read the line table in the source manager block.
/// \returns true if there was an error.
-bool ASTReader::ParseLineTable(PerFileData &F,
- llvm::SmallVectorImpl<uint64_t> &Record) {
+bool ASTReader::ParseLineTable(Module &F,
+ SmallVectorImpl<uint64_t> &Record) {
unsigned Idx = 0;
LineTableInfo &LineTable = SourceMgr.getLineTable();
@@ -1010,6 +822,9 @@ bool ASTReader::ParseLineTable(PerFileData &F,
std::vector<LineEntry> Entries;
while (Idx < Record.size()) {
int FID = Record[Idx++];
+ assert(FID >= 0 && "Serialized line entries for non-local file.");
+ // Remap FileID from 1-based old view.
+ FID += F.SLocEntryBaseID - 1;
// Extract the line entries
unsigned NumEntries = Record[Idx++];
@@ -1131,7 +946,7 @@ public:
/// \brief Read a source manager block
-ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) {
+ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(Module &F) {
using namespace SrcMgr;
llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
@@ -1188,11 +1003,6 @@ ASTReader::ASTReadResult ASTReader::ReadSourceManagerBlock(PerFileData &F) {
default: // Default behavior: ignore.
break;
- case SM_LINE_TABLE:
- if (ParseLineTable(F, Record))
- return Failure;
- break;
-
case SM_SLOC_FILE_ENTRY:
case SM_SLOC_BUFFER_ENTRY:
case SM_SLOC_EXPANSION_ENTRY:
@@ -1235,38 +1045,20 @@ resolveFileRelativeToOriginalDir(const std::string &Filename,
return currPCHPath.str();
}
-/// \brief Get a cursor that's correctly positioned for reading the source
-/// location entry with the given ID.
-ASTReader::PerFileData *ASTReader::SLocCursorForID(unsigned ID) {
- assert(ID != 0 && ID <= TotalNumSLocEntries &&
- "SLocCursorForID should only be called for real IDs.");
-
- ID -= 1;
- PerFileData *F = 0;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- F = Chain[N - I - 1];
- if (ID < F->LocalNumSLocEntries)
- break;
- ID -= F->LocalNumSLocEntries;
- }
- assert(F && F->LocalNumSLocEntries > ID && "Chain corrupted");
-
- F->SLocEntryCursor.JumpToBit(F->SLocOffsets[ID]);
- return F;
-}
-
/// \brief Read in the source location entry with the given ID.
-ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
+ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(int ID) {
if (ID == 0)
return Success;
- if (ID > TotalNumSLocEntries) {
+ if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {
Error("source location entry ID out-of-range for AST file");
return Failure;
}
- PerFileData *F = SLocCursorForID(ID);
+ Module *F = GlobalSLocEntryMap.find(-ID)->second;
+ F->SLocEntryCursor.JumpToBit(F->SLocEntryOffsets[ID - F->SLocEntryBaseID]);
llvm::BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;
+ unsigned BaseOffset = F->SLocEntryBaseOffset;
++NumSLocEntriesRead;
unsigned Code = SLocEntryCursor.ReadCode();
@@ -1326,12 +1118,19 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
return Failure;
}
- FileID FID = SourceMgr.createFileID(File, ReadSourceLocation(*F, Record[1]),
+ SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
+ if (IncludeLoc.isInvalid() && F->Kind != MK_MainFile) {
+ // This is the module's main file.
+ IncludeLoc = getImportLocation(F);
+ }
+ FileID FID = SourceMgr.createFileID(File, IncludeLoc,
(SrcMgr::CharacteristicKind)Record[2],
- ID, Record[0]);
+ ID, BaseOffset + Record[0]);
+ SrcMgr::FileInfo &FileInfo =
+ const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile());
+ FileInfo.NumCreatedFIDs = Record[6];
if (Record[3])
- const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
- .setHasLineDirectives();
+ FileInfo.setHasLineDirectives();
break;
}
@@ -1350,14 +1149,15 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
}
llvm::MemoryBuffer *Buffer
- = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(BlobStart, BlobLen - 1),
+ = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1),
Name);
- FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
+ FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID,
+ BaseOffset + Offset);
if (strcmp(Name, "<built-in>") == 0) {
PCHPredefinesBlock Block = {
BufferID,
- llvm::StringRef(BlobStart, BlobLen - 1)
+ StringRef(BlobStart, BlobLen - 1)
};
PCHPredefinesBuffers.push_back(Block);
}
@@ -1367,12 +1167,12 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
case SM_SLOC_EXPANSION_ENTRY: {
SourceLocation SpellingLoc = ReadSourceLocation(*F, Record[1]);
- SourceMgr.createInstantiationLoc(SpellingLoc,
+ SourceMgr.createExpansionLoc(SpellingLoc,
ReadSourceLocation(*F, Record[2]),
ReadSourceLocation(*F, Record[3]),
Record[4],
ID,
- Record[0]);
+ BaseOffset + Record[0]);
break;
}
}
@@ -1380,6 +1180,25 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) {
return Success;
}
+/// \brief Find the location where the module F is imported.
+SourceLocation ASTReader::getImportLocation(Module *F) {
+ if (F->ImportLoc.isValid())
+ return F->ImportLoc;
+
+ // Otherwise we have a PCH. It's considered to be "imported" at the first
+ // location of its includer.
+ if (F->ImportedBy.empty() || !F->ImportedBy[0]) {
+ // Main file is the importer. We assume that it is the first entry in the
+ // entry table. We can't ask the manager, because at the time of PCH loading
+ // the main file entry doesn't exist yet.
+ // The very first entry is the invalid instantiation loc, which takes up
+ // offsets 0 and 1.
+ return SourceLocation::getFromRawEncoding(2U);
+ }
+ //return F->Loaders[0]->FirstLoc;
+ return F->ImportedBy[0]->FirstLoc;
+}
+
/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
/// specified cursor. Read the abbreviations that are at the top of the block
/// and then leave the cursor pointing into the block.
@@ -1403,8 +1222,7 @@ bool ASTReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
}
}
-PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset) {
- assert(PP && "Forgot to set Preprocessor ?");
+void ASTReader::ReadMacroRecord(Module &F, uint64_t Offset) {
llvm::BitstreamCursor &Stream = F.MacroCursor;
// Keep track of where we are in the stream, then jump back there
@@ -1413,21 +1231,21 @@ PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset)
Stream.JumpToBit(Offset);
RecordData Record;
- llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
+ SmallVector<IdentifierInfo*, 16> MacroArgs;
MacroInfo *Macro = 0;
while (true) {
unsigned Code = Stream.ReadCode();
switch (Code) {
case llvm::bitc::END_BLOCK:
- return 0;
+ return;
case llvm::bitc::ENTER_SUBBLOCK:
// No known subblocks, always skip them.
Stream.ReadSubBlockID();
if (Stream.SkipBlock()) {
Error("malformed block record in AST file");
- return 0;
+ return;
}
continue;
@@ -1451,50 +1269,55 @@ PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset)
// of the definition of the macro we were looking for. We're
// done.
if (Macro)
- return 0;
+ return;
- IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
+ IdentifierInfo *II = getLocalIdentifier(F, Record[0]);
if (II == 0) {
Error("macro must have a name in AST file");
- return 0;
+ return;
}
SourceLocation Loc = ReadSourceLocation(F, Record[1]);
bool isUsed = Record[2];
- MacroInfo *MI = PP->AllocateMacroInfo(Loc);
+ MacroInfo *MI = PP.AllocateMacroInfo(Loc);
MI->setIsUsed(isUsed);
MI->setIsFromAST();
unsigned NextIndex = 3;
+ MI->setExportLocation(ReadSourceLocation(F, Record, NextIndex));
+
if (RecType == PP_MACRO_FUNCTION_LIKE) {
// Decode function-like macro info.
- bool isC99VarArgs = Record[3];
- bool isGNUVarArgs = Record[4];
+ bool isC99VarArgs = Record[NextIndex++];
+ bool isGNUVarArgs = Record[NextIndex++];
MacroArgs.clear();
- unsigned NumArgs = Record[5];
- NextIndex = 6 + NumArgs;
+ unsigned NumArgs = Record[NextIndex++];
for (unsigned i = 0; i != NumArgs; ++i)
- MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
+ MacroArgs.push_back(getLocalIdentifier(F, Record[NextIndex++]));
// Install function-like macro info.
MI->setIsFunctionLike();
if (isC99VarArgs) MI->setIsC99Varargs();
if (isGNUVarArgs) MI->setIsGNUVarargs();
MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
- PP->getPreprocessorAllocator());
+ PP.getPreprocessorAllocator());
}
// Finally, install the macro.
- PP->setMacroInfo(II, MI);
+ PP.setMacroInfo(II, MI);
// 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]));
+ if (NextIndex + 1 == Record.size() && PP.getPreprocessingRecord() &&
+ Record[NextIndex]) {
+ // We have a macro definition. Register the association
+ PreprocessedEntityID
+ GlobalID = getGlobalPreprocessedEntityID(F, Record[NextIndex]);
+ PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
+ PPRec.RegisterMacroDefinition(Macro,
+ PPRec.getPPEntityID(GlobalID-1, /*isLoaded=*/true));
}
++NumMacrosRead;
@@ -1510,7 +1333,7 @@ PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset)
Tok.startToken();
Tok.setLocation(ReadSourceLocation(F, Record[0]));
Tok.setLength(Record[1]);
- if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
+ if (IdentifierInfo *II = getLocalIdentifier(F, Record[2]))
Tok.setIdentifierInfo(II);
Tok.setKind((tok::TokenKind)Record[3]);
Tok.setFlag((Token::TokenFlags)Record[4]);
@@ -1520,234 +1343,98 @@ PreprocessedEntity *ASTReader::ReadMacroRecord(PerFileData &F, uint64_t Offset)
}
}
- return 0;
+ 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;
-
- case llvm::bitc::DEFINE_ABBREV:
- Error("unexpected abbrevation record in preprocessor detail block");
- return 0;
-
- 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_EXPANSION: {
- if (PreprocessedEntity *PE = PPRec.getPreprocessedEntity(Record[0]))
- return PE;
-
- MacroExpansion *ME =
- new (PPRec) MacroExpansion(DecodeIdentifierInfo(Record[3]),
- SourceRange(ReadSourceLocation(F, Record[1]),
- ReadSourceLocation(F, Record[2])),
- getMacroDefinition(Record[4]));
- PPRec.SetPreallocatedEntity(Record[0], ME);
- return ME;
- }
-
- 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(II,
- ReadSourceLocation(F, Record[5]),
- SourceRange(
- ReadSourceLocation(F, Record[2]),
- ReadSourceLocation(F, Record[3])));
-
- PPRec.SetPreallocatedEntity(Record[0], MD);
- 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;
- }
- }
+PreprocessedEntityID
+ASTReader::getGlobalPreprocessedEntityID(Module &M, unsigned LocalID) const {
+ ContinuousRangeMap<uint32_t, int, 2>::const_iterator
+ I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS);
+ assert(I != M.PreprocessedEntityRemap.end()
+ && "Invalid index into preprocessed entity index remap");
- Error("invalid offset in preprocessor detail block");
- return 0;
+ return LocalID + I->second;
}
-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));
- }
+unsigned HeaderFileInfoTrait::ComputeHash(const char *path) {
+ return llvm::HashString(llvm::sys::path::filename(path));
+}
- static internal_key_type GetInternalKey(const char *path) { return path; }
+HeaderFileInfoTrait::internal_key_type
+HeaderFileInfoTrait::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);
- }
+bool HeaderFileInfoTrait::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 internal_key_type ReadKey(const unsigned char *d, unsigned) {
- return (const char *)d;
- }
+std::pair<unsigned, unsigned>
+HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
+ unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
+ unsigned DataLen = (unsigned) *d++;
+ return std::make_pair(KeyLen + 1, DataLen);
+}
- static data_type ReadData(const internal_key_type, const unsigned char *d,
+HeaderFileInfoTrait::data_type
+HeaderFileInfoTrait::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 >> 4) & 0x01;
- HFI.isPragmaOnce = (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;
- }
- };
+ const unsigned char *End = d + DataLen;
+ using namespace clang::io;
+ HeaderFileInfo HFI;
+ unsigned Flags = *d++;
+ HFI.isImport = (Flags >> 5) & 0x01;
+ HFI.isPragmaOnce = (Flags >> 4) & 0x01;
+ HFI.DirInfo = (Flags >> 2) & 0x03;
+ HFI.Resolved = (Flags >> 1) & 0x01;
+ HFI.IndexHeaderMapHeader = Flags & 0x01;
+ HFI.NumIncludes = ReadUnalignedLE16(d);
+ HFI.ControllingMacroID = Reader.getGlobalDeclID(M, ReadUnalignedLE32(d));
+ if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) {
+ // The framework offset is 1 greater than the actual offset,
+ // since 0 is used as an indicator for "no framework name".
+ StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
+ HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
+ }
+
+ 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) {
+void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, Module &F,
+ uint64_t LocalOffset) {
// 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;
+ // Adjust the offset to a global offset.
+ UnreadMacroRecordOffsets[II] = F.GlobalBitOffset + LocalOffset;
}
void ASTReader::ReadDefinedMacros() {
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- PerFileData &F = *Chain[N - I - 1];
- llvm::BitstreamCursor &MacroCursor = F.MacroCursor;
+ for (ModuleReverseIterator I = ModuleMgr.rbegin(),
+ E = ModuleMgr.rend(); I != E; ++I) {
+ llvm::BitstreamCursor &MacroCursor = (*I)->MacroCursor;
// If there was no preprocessor block, skip this file.
if (!MacroCursor.getBitStreamReader())
continue;
llvm::BitstreamCursor Cursor = MacroCursor;
- Cursor.JumpToBit(F.MacroStartOffset);
+ Cursor.JumpToBit((*I)->MacroStartOffset);
RecordData Record;
while (true) {
@@ -1780,7 +1467,7 @@ void ASTReader::ReadDefinedMacros() {
case PP_MACRO_OBJECT_LIKE:
case PP_MACRO_FUNCTION_LIKE:
- DecodeIdentifierInfo(Record[0]);
+ getLocalIdentifier(**I, Record[0]);
break;
case PP_TOKEN:
@@ -1798,24 +1485,11 @@ void ASTReader::ReadDefinedMacros() {
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);
+ RecordLocation Loc = getLocalBitOffset(Offset);
+ ReadMacroRecord(*Loc.F, Loc.Offset);
}
void ASTReader::LoadMacroDefinition(IdentifierInfo *II) {
@@ -1824,29 +1498,7 @@ void ASTReader::LoadMacroDefinition(IdentifierInfo *II) {
LoadMacroDefinition(Pos);
}
-MacroDefinition *ASTReader::getMacroDefinition(MacroID ID) {
- if (ID == 0 || ID > MacroDefinitionsLoaded.size())
- return 0;
-
- 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) {
- SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor);
- F.PreprocessorDetailCursor.JumpToBit(F.MacroDefinitionOffsets[Index]);
- LoadPreprocessedEntity(F);
- break;
- }
- Index -= F.LocalNumMacroDefinitions;
- }
- assert(MacroDefinitionsLoaded[ID - 1] && "Broken chain");
- }
-
- return MacroDefinitionsLoaded[ID - 1];
-}
-
-const FileEntry *ASTReader::getFileEntry(llvm::StringRef filenameStrRef) {
+const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) {
std::string Filename = filenameStrRef;
MaybeAddSystemRootToFilename(Filename);
const FileEntry *File = FileMgr.getFile(Filename);
@@ -1873,21 +1525,21 @@ void ASTReader::MaybeAddSystemRootToFilename(std::string &Filename) {
if (Filename.empty() || llvm::sys::path::is_absolute(Filename))
return;
- if (isysroot == 0) {
+ if (isysroot.empty()) {
// If no system root was given, default to '/'
Filename.insert(Filename.begin(), '/');
return;
}
- unsigned Length = strlen(isysroot);
+ unsigned Length = isysroot.size();
if (isysroot[Length - 1] != '/')
Filename.insert(Filename.begin(), '/');
- Filename.insert(Filename.begin(), isysroot, isysroot + Length);
+ Filename.insert(Filename.begin(), isysroot.begin(), isysroot.end());
}
ASTReader::ASTReadResult
-ASTReader::ReadASTBlock(PerFileData &F) {
+ASTReader::ReadASTBlock(Module &F) {
llvm::BitstreamCursor &Stream = F.Stream;
if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
@@ -1897,7 +1549,6 @@ ASTReader::ReadASTBlock(PerFileData &F) {
// Read all of the records and blocks for the ASt file.
RecordData Record;
- bool First = true;
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
if (Code == llvm::bitc::END_BLOCK) {
@@ -1934,8 +1585,8 @@ ASTReader::ReadASTBlock(PerFileData &F) {
case PREPROCESSOR_BLOCK_ID:
F.MacroCursor = Stream;
- if (PP)
- PP->setExternalSource(this);
+ if (!PP.getExternalSource())
+ PP.setExternalSource(this);
if (Stream.SkipBlock() ||
ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
@@ -1955,6 +1606,11 @@ ASTReader::ReadASTBlock(PerFileData &F) {
}
F.PreprocessorDetailStartOffset
= F.PreprocessorDetailCursor.GetCurrentBitNo();
+
+ if (!PP.getPreprocessingRecord())
+ PP.createPreprocessingRecord(true);
+ if (!PP.getPreprocessingRecord()->getExternalSource())
+ PP.getPreprocessingRecord()->SetExternalSource(*this);
break;
case SOURCE_MANAGER_BLOCK_ID:
@@ -1971,7 +1627,6 @@ ASTReader::ReadASTBlock(PerFileData &F) {
}
break;
}
- First = false;
continue;
}
@@ -2005,79 +1660,108 @@ ASTReader::ReadASTBlock(PerFileData &F) {
break;
}
- case CHAINED_METADATA: {
- if (!First) {
- Error("CHAINED_METADATA is not first record in block");
- return Failure;
- }
- if (Record[0] != VERSION_MAJOR && !DisableValidation) {
- Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
- : diag::warn_pch_version_too_new);
- return IgnorePCH;
- }
-
- // 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;
- case Success: break;
+ case IMPORTS: {
+ // Load each of the imported PCH files.
+ unsigned Idx = 0, N = Record.size();
+ while (Idx < N) {
+ // Read information about the AST file.
+ ModuleKind ImportedKind = (ModuleKind)Record[Idx++];
+ unsigned Length = Record[Idx++];
+ llvm::SmallString<128> ImportedFile(Record.begin() + Idx,
+ Record.begin() + Idx + Length);
+ Idx += Length;
+
+ // Load the AST file.
+ switch(ReadASTCore(ImportedFile, ImportedKind, &F)) {
+ case Failure: return Failure;
+ // If we have to ignore the dependency, we'll have to ignore this too.
+ case IgnorePCH: return IgnorePCH;
+ case Success: break;
+ }
}
break;
}
- case TYPE_OFFSET:
+ case TYPE_OFFSET: {
if (F.LocalNumTypes != 0) {
Error("duplicate TYPE_OFFSET record in AST file");
return Failure;
}
F.TypeOffsets = (const uint32_t *)BlobStart;
F.LocalNumTypes = Record[0];
+ unsigned LocalBaseTypeIndex = Record[1];
+ F.BaseTypeIndex = getTotalNumTypes();
+
+ if (F.LocalNumTypes > 0) {
+ // Introduce the global -> local mapping for types within this module.
+ GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F));
+
+ // Introduce the local -> global mapping for types within this module.
+ F.TypeRemap.insert(std::make_pair(LocalBaseTypeIndex,
+ F.BaseTypeIndex - LocalBaseTypeIndex));
+
+ TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes);
+ }
break;
-
- case DECL_OFFSET:
+ }
+
+ case DECL_OFFSET: {
if (F.LocalNumDecls != 0) {
Error("duplicate DECL_OFFSET record in AST file");
return Failure;
}
F.DeclOffsets = (const uint32_t *)BlobStart;
F.LocalNumDecls = Record[0];
+ unsigned LocalBaseDeclID = Record[1];
+ F.BaseDeclID = getTotalNumDecls();
+
+ if (F.LocalNumDecls > 0) {
+ // Introduce the global -> local mapping for declarations within this
+ // module.
+ GlobalDeclMap.insert(
+ std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F));
+
+ // Introduce the local -> global mapping for declarations within this
+ // module.
+ F.DeclRemap.insert(std::make_pair(LocalBaseDeclID,
+ F.BaseDeclID - LocalBaseDeclID));
+
+ DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls);
+ }
break;
-
+ }
+
case TU_UPDATE_LEXICAL: {
- DeclContextInfo Info = {
- /* No visible information */ 0,
- reinterpret_cast<const KindDeclIDPair *>(BlobStart),
- BlobLen / sizeof(KindDeclIDPair)
- };
- DeclContextOffsets[Context ? Context->getTranslationUnitDecl() : 0]
- .push_back(Info);
+ DeclContext *TU = Context.getTranslationUnitDecl();
+ DeclContextInfo &Info = F.DeclContextInfos[TU];
+ Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair *>(BlobStart);
+ Info.NumLexicalDecls
+ = static_cast<unsigned int>(BlobLen / sizeof(KindDeclIDPair));
+ TU->setHasExternalLexicalStorage(true);
break;
}
case UPDATE_VISIBLE: {
- serialization::DeclID ID = Record[0];
+ unsigned Idx = 0;
+ serialization::DeclID ID = ReadDeclID(F, Record, Idx);
void *Table = ASTDeclContextNameLookupTable::Create(
- (const unsigned char *)BlobStart + Record[1],
+ (const unsigned char *)BlobStart + Record[Idx++],
(const unsigned char *)BlobStart,
- ASTDeclContextNameLookupTrait(*this));
- if (ID == 1 && Context) { // Is it the TU?
- DeclContextInfo Info = {
- Table, /* No lexical inforamtion */ 0, 0
- };
- DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
+ ASTDeclContextNameLookupTrait(*this, F));
+ if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID) { // Is it the TU?
+ DeclContext *TU = Context.getTranslationUnitDecl();
+ F.DeclContextInfos[TU].NameLookupTableData = Table;
+ TU->setHasExternalVisibleStorage(true);
} else
- PendingVisibleUpdates[ID].push_back(Table);
+ PendingVisibleUpdates[ID].push_back(std::make_pair(Table, &F));
break;
}
case REDECLS_UPDATE_LATEST: {
assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs");
- for (unsigned i = 0, e = Record.size(); i < e; i += 2) {
- DeclID First = Record[i], Latest = Record[i+1];
- assert((FirstLatestDeclIDs.find(First) == FirstLatestDeclIDs.end() ||
- Latest > FirstLatestDeclIDs[First]) &&
- "The new latest is supposed to come after the previous latest");
+ for (unsigned i = 0, e = Record.size(); i < e; /* in loop */) {
+ DeclID First = ReadDeclID(F, Record, i);
+ DeclID Latest = ReadDeclID(F, Record, i);
FirstLatestDeclIDs[First] = Latest;
}
break;
@@ -2096,35 +1780,47 @@ ASTReader::ReadASTBlock(PerFileData &F) {
(const unsigned char *)F.IdentifierTableData + Record[0],
(const unsigned char *)F.IdentifierTableData,
ASTIdentifierLookupTrait(*this, F));
- if (PP)
- PP->getIdentifierTable().setExternalIdentifierLookup(this);
+
+ PP.getIdentifierTable().setExternalIdentifierLookup(this);
}
break;
- case IDENTIFIER_OFFSET:
+ case IDENTIFIER_OFFSET: {
if (F.LocalNumIdentifiers != 0) {
Error("duplicate IDENTIFIER_OFFSET record in AST file");
return Failure;
}
F.IdentifierOffsets = (const uint32_t *)BlobStart;
F.LocalNumIdentifiers = Record[0];
+ unsigned LocalBaseIdentifierID = Record[1];
+ F.BaseIdentifierID = getTotalNumIdentifiers();
+
+ if (F.LocalNumIdentifiers > 0) {
+ // Introduce the global -> local mapping for identifiers within this
+ // module.
+ GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1,
+ &F));
+
+ // Introduce the local -> global mapping for identifiers within this
+ // module.
+ F.IdentifierRemap.insert(
+ std::make_pair(LocalBaseIdentifierID,
+ F.BaseIdentifierID - LocalBaseIdentifierID));
+
+ IdentifiersLoaded.resize(IdentifiersLoaded.size()
+ + F.LocalNumIdentifiers);
+ }
break;
-
+ }
+
case EXTERNAL_DEFINITIONS:
- // Optimization for the first block.
- if (ExternalDefinitions.empty())
- ExternalDefinitions.swap(Record);
- else
- ExternalDefinitions.insert(ExternalDefinitions.end(),
- Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ ExternalDefinitions.push_back(getGlobalDeclID(F, Record[I]));
break;
case SPECIAL_TYPES:
- // Optimization for the first block
- if (SpecialTypes.empty())
- SpecialTypes.swap(Record);
- else
- SpecialTypes.insert(SpecialTypes.end(), Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ SpecialTypes.push_back(getGlobalTypeID(F, Record[I]));
break;
case STATISTICS:
@@ -2135,42 +1831,63 @@ ASTReader::ReadASTBlock(PerFileData &F) {
break;
case UNUSED_FILESCOPED_DECLS:
- // Optimization for the first block.
- if (UnusedFileScopedDecls.empty())
- UnusedFileScopedDecls.swap(Record);
- else
- UnusedFileScopedDecls.insert(UnusedFileScopedDecls.end(),
- Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I]));
break;
case DELEGATING_CTORS:
- // Optimization for the first block.
- if (DelegatingCtorDecls.empty())
- DelegatingCtorDecls.swap(Record);
- else
- DelegatingCtorDecls.insert(DelegatingCtorDecls.end(),
- Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I]));
break;
case WEAK_UNDECLARED_IDENTIFIERS:
- // Later blocks overwrite earlier ones.
- WeakUndeclaredIdentifiers.swap(Record);
+ if (Record.size() % 4 != 0) {
+ Error("invalid weak identifiers record");
+ return Failure;
+ }
+
+ // FIXME: Ignore weak undeclared identifiers from non-original PCH
+ // files. This isn't the way to do it :)
+ WeakUndeclaredIdentifiers.clear();
+
+ // Translate the weak, undeclared identifiers into global IDs.
+ for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) {
+ WeakUndeclaredIdentifiers.push_back(
+ getGlobalIdentifierID(F, Record[I++]));
+ WeakUndeclaredIdentifiers.push_back(
+ getGlobalIdentifierID(F, Record[I++]));
+ WeakUndeclaredIdentifiers.push_back(
+ ReadSourceLocation(F, Record, I).getRawEncoding());
+ WeakUndeclaredIdentifiers.push_back(Record[I++]);
+ }
break;
case LOCALLY_SCOPED_EXTERNAL_DECLS:
- // Optimization for the first block.
- if (LocallyScopedExternalDecls.empty())
- LocallyScopedExternalDecls.swap(Record);
- else
- LocallyScopedExternalDecls.insert(LocallyScopedExternalDecls.end(),
- Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ LocallyScopedExternalDecls.push_back(getGlobalDeclID(F, Record[I]));
break;
- case SELECTOR_OFFSETS:
+ case SELECTOR_OFFSETS: {
F.SelectorOffsets = (const uint32_t *)BlobStart;
F.LocalNumSelectors = Record[0];
- break;
+ unsigned LocalBaseSelectorID = Record[1];
+ F.BaseSelectorID = getTotalNumSelectors();
+
+ if (F.LocalNumSelectors > 0) {
+ // Introduce the global -> local mapping for selectors within this
+ // module.
+ GlobalSelectorMap.insert(std::make_pair(getTotalNumSelectors()+1, &F));
+
+ // Introduce the local -> global mapping for selectors within this
+ // module.
+ F.SelectorRemap.insert(std::make_pair(LocalBaseSelectorID,
+ F.BaseSelectorID - LocalBaseSelectorID));
+ SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors);
+ }
+ break;
+ }
+
case METHOD_POOL:
F.SelectorLookupTableData = (const unsigned char *)BlobStart;
if (Record[0])
@@ -2178,12 +1895,19 @@ ASTReader::ReadASTBlock(PerFileData &F) {
= ASTSelectorLookupTable::Create(
F.SelectorLookupTableData + Record[0],
F.SelectorLookupTableData,
- ASTSelectorLookupTrait(*this));
+ ASTSelectorLookupTrait(*this, F));
TotalNumMethodPoolEntries += Record[1];
break;
case REFERENCED_SELECTOR_POOL:
- F.ReferencedSelectorsData.swap(Record);
+ if (!Record.empty()) {
+ for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) {
+ ReferencedSelectorsData.push_back(getGlobalSelectorID(F,
+ Record[Idx++]));
+ ReferencedSelectorsData.push_back(ReadSourceLocation(F, Record, Idx).
+ getRawEncoding());
+ }
+ }
break;
case PP_COUNTER_VALUE:
@@ -2191,10 +1915,94 @@ ASTReader::ReadASTBlock(PerFileData &F) {
Listener->ReadCounter(Record[0]);
break;
- case SOURCE_LOCATION_OFFSETS:
- F.SLocOffsets = (const uint32_t *)BlobStart;
+ case SOURCE_LOCATION_OFFSETS: {
+ F.SLocEntryOffsets = (const uint32_t *)BlobStart;
F.LocalNumSLocEntries = Record[0];
- F.LocalSLocSize = Record[1];
+ unsigned SLocSpaceSize = Record[1];
+ llvm::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
+ SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,
+ SLocSpaceSize);
+ // Make our entry in the range map. BaseID is negative and growing, so
+ // we invert it. Because we invert it, though, we need the other end of
+ // the range.
+ unsigned RangeStart =
+ unsigned(-F.SLocEntryBaseID) - F.LocalNumSLocEntries + 1;
+ GlobalSLocEntryMap.insert(std::make_pair(RangeStart, &F));
+ F.FirstLoc = SourceLocation::getFromRawEncoding(F.SLocEntryBaseOffset);
+
+ // SLocEntryBaseOffset is lower than MaxLoadedOffset and decreasing.
+ assert((F.SLocEntryBaseOffset & (1U << 31U)) == 0);
+ GlobalSLocOffsetMap.insert(
+ std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset
+ - SLocSpaceSize,&F));
+
+ // Initialize the remapping table.
+ // Invalid stays invalid.
+ F.SLocRemap.insert(std::make_pair(0U, 0));
+ // This module. Base was 2 when being compiled.
+ F.SLocRemap.insert(std::make_pair(2U,
+ static_cast<int>(F.SLocEntryBaseOffset - 2)));
+
+ TotalNumSLocEntries += F.LocalNumSLocEntries;
+ break;
+ }
+
+ case MODULE_OFFSET_MAP: {
+ // Additional remapping information.
+ const unsigned char *Data = (const unsigned char*)BlobStart;
+ const unsigned char *DataEnd = Data + BlobLen;
+
+ // Continuous range maps we may be updating in our module.
+ ContinuousRangeMap<uint32_t, int, 2>::Builder SLocRemap(F.SLocRemap);
+ ContinuousRangeMap<uint32_t, int, 2>::Builder
+ IdentifierRemap(F.IdentifierRemap);
+ ContinuousRangeMap<uint32_t, int, 2>::Builder
+ PreprocessedEntityRemap(F.PreprocessedEntityRemap);
+ ContinuousRangeMap<uint32_t, int, 2>::Builder
+ SelectorRemap(F.SelectorRemap);
+ ContinuousRangeMap<uint32_t, int, 2>::Builder DeclRemap(F.DeclRemap);
+ ContinuousRangeMap<uint32_t, int, 2>::Builder TypeRemap(F.TypeRemap);
+
+ while(Data < DataEnd) {
+ uint16_t Len = io::ReadUnalignedLE16(Data);
+ StringRef Name = StringRef((const char*)Data, Len);
+ Data += Len;
+ Module *OM = ModuleMgr.lookup(Name);
+ if (!OM) {
+ Error("SourceLocation remap refers to unknown module");
+ return Failure;
+ }
+
+ uint32_t SLocOffset = io::ReadUnalignedLE32(Data);
+ uint32_t IdentifierIDOffset = io::ReadUnalignedLE32(Data);
+ uint32_t PreprocessedEntityIDOffset = io::ReadUnalignedLE32(Data);
+ uint32_t SelectorIDOffset = io::ReadUnalignedLE32(Data);
+ uint32_t DeclIDOffset = io::ReadUnalignedLE32(Data);
+ uint32_t TypeIndexOffset = io::ReadUnalignedLE32(Data);
+
+ // Source location offset is mapped to OM->SLocEntryBaseOffset.
+ SLocRemap.insert(std::make_pair(SLocOffset,
+ static_cast<int>(OM->SLocEntryBaseOffset - SLocOffset)));
+ IdentifierRemap.insert(
+ std::make_pair(IdentifierIDOffset,
+ OM->BaseIdentifierID - IdentifierIDOffset));
+ PreprocessedEntityRemap.insert(
+ std::make_pair(PreprocessedEntityIDOffset,
+ OM->BasePreprocessedEntityID - PreprocessedEntityIDOffset));
+ SelectorRemap.insert(std::make_pair(SelectorIDOffset,
+ OM->BaseSelectorID - SelectorIDOffset));
+ DeclRemap.insert(std::make_pair(DeclIDOffset,
+ OM->BaseDeclID - DeclIDOffset));
+
+ TypeRemap.insert(std::make_pair(TypeIndexOffset,
+ OM->BaseTypeIndex - TypeIndexOffset));
+ }
+ break;
+ }
+
+ case SOURCE_MANAGER_LINE_TABLE:
+ if (ParseLineTable(F, Record))
+ return Failure;
break;
case FILE_SOURCE_LOCATION_OFFSETS:
@@ -2202,13 +2010,17 @@ ASTReader::ReadASTBlock(PerFileData &F) {
F.LocalNumSLocFileEntries = Record[0];
break;
- case SOURCE_LOCATION_PRELOADS:
- if (PreloadSLocEntries.empty())
- PreloadSLocEntries.swap(Record);
- else
- PreloadSLocEntries.insert(PreloadSLocEntries.end(),
- Record.begin(), Record.end());
+ case SOURCE_LOCATION_PRELOADS: {
+ // Need to transform from the local view (1-based IDs) to the global view,
+ // which is based off F.SLocEntryBaseID.
+ if (!F.PreloadSLocEntries.empty()) {
+ Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");
+ return Failure;
+ }
+
+ F.PreloadSLocEntries.swap(Record);
break;
+ }
case STAT_CACHE: {
if (!DisableStatCache) {
@@ -2223,35 +2035,56 @@ ASTReader::ReadASTBlock(PerFileData &F) {
}
case EXT_VECTOR_DECLS:
- // Optimization for the first block.
- if (ExtVectorDecls.empty())
- ExtVectorDecls.swap(Record);
- else
- ExtVectorDecls.insert(ExtVectorDecls.end(),
- Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I]));
break;
case VTABLE_USES:
+ if (Record.size() % 3 != 0) {
+ Error("Invalid VTABLE_USES record");
+ return Failure;
+ }
+
// Later tables overwrite earlier ones.
- VTableUses.swap(Record);
+ // FIXME: Modules will have some trouble with this. This is clearly not
+ // the right way to do this.
+ VTableUses.clear();
+
+ for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) {
+ VTableUses.push_back(getGlobalDeclID(F, Record[Idx++]));
+ VTableUses.push_back(
+ ReadSourceLocation(F, Record, Idx).getRawEncoding());
+ VTableUses.push_back(Record[Idx++]);
+ }
break;
case DYNAMIC_CLASSES:
- // Optimization for the first block.
- if (DynamicClasses.empty())
- DynamicClasses.swap(Record);
- else
- DynamicClasses.insert(DynamicClasses.end(),
- Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ DynamicClasses.push_back(getGlobalDeclID(F, Record[I]));
break;
case PENDING_IMPLICIT_INSTANTIATIONS:
- F.PendingInstantiations.swap(Record);
+ if (PendingInstantiations.size() % 2 != 0) {
+ Error("Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
+ return Failure;
+ }
+
+ // Later lists of pending instantiations overwrite earlier ones.
+ // FIXME: This is most certainly wrong for modules.
+ PendingInstantiations.clear();
+ for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
+ PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++]));
+ PendingInstantiations.push_back(
+ ReadSourceLocation(F, Record, I).getRawEncoding());
+ }
break;
case SEMA_DECL_REFS:
// Later tables overwrite earlier ones.
- SemaDeclRefs.swap(Record);
+ // FIXME: Modules will have some trouble with this.
+ SemaDeclRefs.clear();
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
break;
case ORIGINAL_FILE_NAME:
@@ -2274,28 +2107,54 @@ ASTReader::ReadASTBlock(PerFileData &F) {
case VERSION_CONTROL_BRANCH_REVISION: {
const std::string &CurBranch = getClangFullRepositoryVersion();
- llvm::StringRef ASTBranch(BlobStart, BlobLen);
- if (llvm::StringRef(CurBranch) != ASTBranch && !DisableValidation) {
+ StringRef ASTBranch(BlobStart, BlobLen);
+ if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {
Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
return IgnorePCH;
}
break;
}
- case MACRO_DEFINITION_OFFSETS:
- F.MacroDefinitionOffsets = (const uint32_t *)BlobStart;
- F.NumPreallocatedPreprocessingEntities = Record[0];
- F.LocalNumMacroDefinitions = Record[1];
- break;
+ case PPD_ENTITIES_OFFSETS: {
+ F.PreprocessedEntityOffsets = (const PPEntityOffset *)BlobStart;
+ assert(BlobLen % sizeof(PPEntityOffset) == 0);
+ F.NumPreprocessedEntities = BlobLen / sizeof(PPEntityOffset);
+
+ unsigned LocalBasePreprocessedEntityID = Record[0];
+
+ unsigned StartingID;
+ if (!PP.getPreprocessingRecord())
+ PP.createPreprocessingRecord(true);
+ if (!PP.getPreprocessingRecord()->getExternalSource())
+ PP.getPreprocessingRecord()->SetExternalSource(*this);
+ StartingID
+ = PP.getPreprocessingRecord()
+ ->allocateLoadedEntities(F.NumPreprocessedEntities);
+ F.BasePreprocessedEntityID = StartingID;
+
+ if (F.NumPreprocessedEntities > 0) {
+ // Introduce the global -> local mapping for preprocessed entities in
+ // this module.
+ GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F));
+
+ // Introduce the local -> global mapping for preprocessed entities in
+ // this module.
+ F.PreprocessedEntityRemap.insert(
+ std::make_pair(LocalBasePreprocessedEntityID,
+ F.BasePreprocessedEntityID - LocalBasePreprocessedEntityID));
+ }
+ 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]));
+ DeclUpdateOffsets[getGlobalDeclID(F, Record[I])]
+ .push_back(std::make_pair(&F, Record[I+1]));
break;
}
@@ -2305,8 +2164,22 @@ ASTReader::ReadASTBlock(PerFileData &F) {
return Failure;
}
for (unsigned I = 0, N = Record.size(); I != N; I += 2)
- ReplacedDecls[static_cast<DeclID>(Record[I])] =
- std::make_pair(&F, Record[I+1]);
+ ReplacedDecls[getGlobalDeclID(F, Record[I])]
+ = std::make_pair(&F, Record[I+1]);
+ break;
+ }
+
+ case OBJC_CHAINED_CATEGORIES: {
+ if (Record.size() % 3 != 0) {
+ Error("invalid OBJC_CHAINED_CATEGORIES block in AST file");
+ return Failure;
+ }
+ for (unsigned I = 0, N = Record.size(); I != N; I += 3) {
+ serialization::GlobalDeclID GlobID = getGlobalDeclID(F, Record[I]);
+ F.ChainedObjCCategories[GlobID] = std::make_pair(Record[I+1],
+ Record[I+2]);
+ ObjCChainedCategoriesInterfaces.insert(GlobID);
+ }
break;
}
@@ -2318,6 +2191,7 @@ ASTReader::ReadASTBlock(PerFileData &F) {
F.LocalNumCXXBaseSpecifiers = Record[0];
F.CXXBaseSpecifiersOffsets = (const uint32_t *)BlobStart;
+ NumCXXBaseSpecifiersLoaded += F.LocalNumCXXBaseSpecifiers;
break;
}
@@ -2326,31 +2200,42 @@ ASTReader::ReadASTBlock(PerFileData &F) {
Error("invalid DIAG_USER_MAPPINGS block in AST file");
return Failure;
}
- if (PragmaDiagMappings.empty())
- PragmaDiagMappings.swap(Record);
+
+ if (F.PragmaDiagMappings.empty())
+ F.PragmaDiagMappings.swap(Record);
else
- PragmaDiagMappings.insert(PragmaDiagMappings.end(),
- Record.begin(), Record.end());
+ F.PragmaDiagMappings.insert(F.PragmaDiagMappings.end(),
+ Record.begin(), Record.end());
break;
case CUDA_SPECIAL_DECL_REFS:
// Later tables overwrite earlier ones.
- CUDASpecialDeclRefs.swap(Record);
+ // FIXME: Modules will have trouble with this.
+ CUDASpecialDeclRefs.clear();
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
break;
- case HEADER_SEARCH_TABLE:
+ case HEADER_SEARCH_TABLE: {
F.HeaderFileInfoTableData = BlobStart;
F.LocalNumHeaderFileInfos = Record[1];
+ F.HeaderFileFrameworkStrings = BlobStart + Record[2];
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);
+ (const unsigned char *)F.HeaderFileInfoTableData,
+ HeaderFileInfoTrait(*this, F,
+ &PP.getHeaderSearchInfo(),
+ BlobStart + Record[2]));
+
+ PP.getHeaderSearchInfo().SetExternalSource(this);
+ if (!PP.getHeaderSearchInfo().getExternalLookup())
+ PP.getHeaderSearchInfo().SetExternalLookup(this);
}
break;
-
+ }
+
case FP_PRAGMA_OPTIONS:
// Later tables overwrite earlier ones.
FPPragmaOptions.swap(Record);
@@ -2362,272 +2247,222 @@ ASTReader::ReadASTBlock(PerFileData &F) {
break;
case TENTATIVE_DEFINITIONS:
- // Optimization for the first block.
- if (TentativeDefinitions.empty())
- TentativeDefinitions.swap(Record);
- else
- TentativeDefinitions.insert(TentativeDefinitions.end(),
- Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I]));
break;
case KNOWN_NAMESPACES:
- // Optimization for the first block.
- if (KnownNamespaces.empty())
- KnownNamespaces.swap(Record);
- else
- KnownNamespaces.insert(KnownNamespaces.end(),
- Record.begin(), Record.end());
+ for (unsigned I = 0, N = Record.size(); I != N; ++I)
+ KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));
break;
}
- First = false;
}
Error("premature end of bitstream in AST file");
return Failure;
}
-ASTReader::ASTReadResult ASTReader::validateFileEntries() {
- for (unsigned CI = 0, CN = Chain.size(); CI != CN; ++CI) {
- PerFileData *F = Chain[CI];
- llvm::BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;
+ASTReader::ASTReadResult ASTReader::validateFileEntries(Module &M) {
+ llvm::BitstreamCursor &SLocEntryCursor = M.SLocEntryCursor;
- for (unsigned i = 0, e = F->LocalNumSLocFileEntries; i != e; ++i) {
- SLocEntryCursor.JumpToBit(F->SLocFileOffsets[i]);
- unsigned Code = SLocEntryCursor.ReadCode();
- if (Code == llvm::bitc::END_BLOCK ||
- Code == llvm::bitc::ENTER_SUBBLOCK ||
- Code == llvm::bitc::DEFINE_ABBREV) {
- Error("incorrectly-formatted source location entry in AST file");
- return Failure;
+ for (unsigned i = 0, e = M.LocalNumSLocFileEntries; i != e; ++i) {
+ SLocEntryCursor.JumpToBit(M.SLocFileOffsets[i]);
+ unsigned Code = SLocEntryCursor.ReadCode();
+ if (Code == llvm::bitc::END_BLOCK ||
+ Code == llvm::bitc::ENTER_SUBBLOCK ||
+ Code == llvm::bitc::DEFINE_ABBREV) {
+ Error("incorrectly-formatted source location entry in AST file");
+ return Failure;
+ }
+
+ RecordData Record;
+ const char *BlobStart;
+ unsigned BlobLen;
+ switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
+ default:
+ Error("incorrectly-formatted source location entry in AST file");
+ return Failure;
+
+ case SM_SLOC_FILE_ENTRY: {
+ StringRef Filename(BlobStart, BlobLen);
+ const FileEntry *File = getFileEntry(Filename);
+
+ if (File == 0) {
+ std::string ErrorStr = "could not find file '";
+ ErrorStr += Filename;
+ ErrorStr += "' referenced by AST file";
+ Error(ErrorStr.c_str());
+ return IgnorePCH;
}
-
- RecordData Record;
- const char *BlobStart;
- unsigned BlobLen;
- switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
- default:
- Error("incorrectly-formatted source location entry in AST file");
+
+ if (Record.size() < 6) {
+ Error("source location entry is incorrect");
return Failure;
-
- case SM_SLOC_FILE_ENTRY: {
- llvm::StringRef Filename(BlobStart, BlobLen);
- const FileEntry *File = getFileEntry(Filename);
-
- if (File == 0) {
- std::string ErrorStr = "could not find file '";
- ErrorStr += Filename;
- ErrorStr += "' referenced by AST file";
- Error(ErrorStr.c_str());
- return IgnorePCH;
- }
-
- if (Record.size() < 6) {
- Error("source location entry is incorrect");
- return Failure;
- }
+ }
- // The stat info from the FileEntry came from the cached stat
- // info of the PCH, so we cannot trust it.
- struct stat StatBuf;
- if (::stat(File->getName(), &StatBuf) != 0) {
- StatBuf.st_size = File->getSize();
- StatBuf.st_mtime = File->getModificationTime();
- }
+ // The stat info from the FileEntry came from the cached stat
+ // info of the PCH, so we cannot trust it.
+ struct stat StatBuf;
+ if (::stat(File->getName(), &StatBuf) != 0) {
+ StatBuf.st_size = File->getSize();
+ StatBuf.st_mtime = File->getModificationTime();
+ }
- if (((off_t)Record[4] != StatBuf.st_size
+ if (((off_t)Record[4] != StatBuf.st_size
#if !defined(LLVM_ON_WIN32)
- // In our regression testing, the Windows file system seems to
- // have inconsistent modification times that sometimes
- // erroneously trigger this error-handling path.
- || (time_t)Record[5] != StatBuf.st_mtime
+ // In our regression testing, the Windows file system seems to
+ // have inconsistent modification times that sometimes
+ // erroneously trigger this error-handling path.
+ || (time_t)Record[5] != StatBuf.st_mtime
#endif
- )) {
- Error(diag::err_fe_pch_file_modified, Filename);
- return IgnorePCH;
- }
-
- break;
- }
+ )) {
+ Error(diag::err_fe_pch_file_modified, Filename);
+ return IgnorePCH;
}
+
+ break;
+ }
}
}
return Success;
}
+namespace {
+ /// \brief Visitor class used to look up identifirs in an AST file.
+ class IdentifierLookupVisitor {
+ StringRef Name;
+ IdentifierInfo *Found;
+ public:
+ explicit IdentifierLookupVisitor(StringRef Name) : Name(Name), Found() { }
+
+ static bool visit(Module &M, void *UserData) {
+ IdentifierLookupVisitor *This
+ = static_cast<IdentifierLookupVisitor *>(UserData);
+
+ ASTIdentifierLookupTable *IdTable
+ = (ASTIdentifierLookupTable *)M.IdentifierLookupTable;
+ if (!IdTable)
+ return false;
+
+ std::pair<const char*, unsigned> Key(This->Name.begin(),
+ This->Name.size());
+ ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key);
+ if (Pos == IdTable->end())
+ return false;
+
+ // Dereferencing the iterator has the effect of building the
+ // IdentifierInfo node and populating it with the various
+ // declarations it needs.
+ This->Found = *Pos;
+ return true;
+ }
+
+ // \brief Retrieve the identifier info found within the module
+ // files.
+ IdentifierInfo *getIdentifierInfo() const { return Found; }
+ };
+}
+
+
ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
- ASTFileType Type) {
- switch(ReadASTCore(FileName, Type)) {
+ ModuleKind Type) {
+ switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0)) {
case Failure: return Failure;
case IgnorePCH: return IgnorePCH;
case Success: break;
}
// Here comes stuff that we only do once the entire chain is loaded.
-
- if (!DisableValidation) {
- switch(validateFileEntries()) {
- case Failure: return Failure;
- case IgnorePCH: return IgnorePCH;
- case Success: break;
- }
- }
-
- // 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;
- TotalNumPreallocatedPreprocessingEntities +=
- Chain[I]->NumPreallocatedPreprocessingEntities;
- TotalNumMacroDefs += Chain[I]->LocalNumMacroDefinitions;
- TotalNumSelectors += Chain[I]->LocalNumSelectors;
- }
- SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, NextSLocOffset);
- IdentifiersLoaded.resize(TotalNumIdentifiers);
- TypesLoaded.resize(TotalNumTypes);
- DeclsLoaded.resize(TotalNumDecls);
- MacroDefinitionsLoaded.resize(TotalNumMacroDefs);
- if (PP) {
- if (TotalNumIdentifiers > 0)
- PP->getHeaderSearchInfo().SetExternalLookup(this);
- if (TotalNumPreallocatedPreprocessingEntities > 0) {
- if (!PP->getPreprocessingRecord())
- PP->createPreprocessingRecord(true);
- PP->getPreprocessingRecord()->SetExternalSource(*this,
- TotalNumPreallocatedPreprocessingEntities);
- }
- }
- 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())
+ if (!DisableValidation && Type != MK_Module && Type != MK_Preamble &&
+ // FIXME: CheckPredefinesBuffers also sets the SuggestedPredefines;
+ // if DisableValidation is true, defines that were set on command-line
+ // but not in the PCH file will not be added to SuggestedPredefines.
+ CheckPredefinesBuffers())
return IgnorePCH;
- if (PP) {
- // Initialization of keywords and pragmas occurs before the
- // AST file is read, so there may be some identifiers that were
- // loaded into the IdentifierTable before we intercepted the
- // creation of identifiers. Iterate through the list of known
- // identifiers and determine whether we have to establish
- // preprocessor definitions or top-level identifier declaration
- // chains for those identifiers.
- //
- // We copy the IdentifierInfo pointers to a small vector first,
- // since de-serializing declarations or macro definitions can add
- // new entries into the identifier table, invalidating the
- // iterators.
- llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
- for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
- IdEnd = PP->getIdentifierTable().end();
- Id != IdEnd; ++Id)
- Identifiers.push_back(Id->second);
- // We need to search the tables in all files.
- for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
- ASTIdentifierLookupTable *IdTable
- = (ASTIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
- // Not all AST files necessarily have identifier tables, only the useful
- // ones.
- if (!IdTable)
- continue;
- 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], II);
- std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
- ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
- if (Pos == IdTable->end())
- continue;
-
- // Dereferencing the iterator has the effect of populating the
- // IdentifierInfo node with the various declarations it needs.
- (void)*Pos;
- }
- }
+ // Initialization of keywords and pragmas occurs before the
+ // AST file is read, so there may be some identifiers that were
+ // loaded into the IdentifierTable before we intercepted the
+ // creation of identifiers. Iterate through the list of known
+ // identifiers and determine whether we have to establish
+ // preprocessor definitions or top-level identifier declaration
+ // chains for those identifiers.
+ //
+ // We copy the IdentifierInfo pointers to a small vector first,
+ // since de-serializing declarations or macro definitions can add
+ // new entries into the identifier table, invalidating the
+ // iterators.
+ //
+ // FIXME: We need a lazier way to load this information, e.g., by marking
+ // the identifier data as 'dirty', so that it will be looked up in the
+ // AST file(s) if it is uttered in the source. This could save us some
+ // module load time.
+ SmallVector<IdentifierInfo *, 128> Identifiers;
+ for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),
+ IdEnd = PP.getIdentifierTable().end();
+ Id != IdEnd; ++Id)
+ Identifiers.push_back(Id->second);
+
+ for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
+ IdentifierLookupVisitor Visitor(Identifiers[I]->getName());
+ ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
}
- if (Context)
- InitializeContext(*Context);
+ InitializeContext();
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) {
- if (OriginalFileID.isInvalid()) {
- SourceLocation Loc
- = SourceMgr.getLocation(FileMgr.getFile(getOriginalSourceFile()), 1, 1);
- if (Loc.isValid())
- OriginalFileID = SourceMgr.getDecomposedLoc(Loc).first;
+ // If this AST file is a precompiled preamble, then set the preamble file ID
+ // of the source manager to the file source file from which the preamble was
+ // built.
+ if (Type == MK_Preamble) {
+ if (!OriginalFileID.isInvalid()) {
+ OriginalFileID = FileID::get(ModuleMgr.getPrimaryModule().SLocEntryBaseID
+ + OriginalFileID.getOpaqueValue() - 1);
+ SourceMgr.setPreambleFileID(OriginalFileID);
}
-
- if (!OriginalFileID.isInvalid())
- SourceMgr.SetPreambleFileID(OriginalFileID);
}
return Success;
}
-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);
+ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName,
+ ModuleKind Type,
+ Module *ImportedBy) {
+ Module *M;
+ bool NewModule;
+ std::string ErrorStr;
+ llvm::tie(M, NewModule) = ModuleMgr.addModule(FileName, Type, ImportedBy,
+ ErrorStr);
+
+ if (!M) {
+ // We couldn't load the module.
+ std::string Msg = "Unable to load module \"" + FileName.str() + "\": "
+ + ErrorStr;
+ Error(Msg);
+ return Failure;
+ }
- // Set the AST file name.
- F.FileName = FileName;
+ if (!NewModule) {
+ // We've already loaded this module.
+ return Success;
+ }
+ // FIXME: This seems rather a hack. Should CurrentDir be part of the
+ // module?
if (FileName != "-") {
CurrentDir = llvm::sys::path::parent_path(FileName);
if (CurrentDir.empty()) CurrentDir = ".";
}
- if (!ASTBuffers.empty()) {
- F.Buffer.reset(ASTBuffers.back());
- ASTBuffers.pop_back();
- assert(F.Buffer && "Passed null buffer");
- } else {
- // Open the AST file.
- //
- // FIXME: This shouldn't be here, we should just take a raw_ostream.
- std::string 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;
- }
- }
-
- // Initialize the stream
- F.StreamFile.init((const unsigned char *)F.Buffer->getBufferStart(),
- (const unsigned char *)F.Buffer->getBufferEnd());
+ Module &F = *M;
llvm::BitstreamCursor &Stream = F.Stream;
Stream.init(F.StreamFile);
F.SizeInBits = F.Buffer->getBufferSize() * 8;
-
+
// Sniff for the signature.
if (Stream.Read(8) != 'C' ||
Stream.Read(8) != 'P' ||
@@ -2668,9 +2503,8 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName,
// AST block, skipping subblocks, to see if there are other
// AST blocks elsewhere.
- // Clear out any preallocated source location entries, so that
- // the source manager does not try to resolve them later.
- SourceMgr.ClearPreallocatedSLocEntries();
+ // FIXME: We can't clear loaded slocentries anymore.
+ //SourceMgr.ClearPreallocatedSLocEntries();
// Remove the stat cache.
if (F.StatCache)
@@ -2687,143 +2521,152 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName,
break;
}
}
+
+ // Once read, set the Module bit base offset and update the size in
+ // bits of all files we've seen.
+ F.GlobalBitOffset = TotalModulesSizeInBits;
+ TotalModulesSizeInBits += F.SizeInBits;
+ GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));
- return Success;
-}
+ // Make sure that the files this module was built against are still available.
+ if (!DisableValidation) {
+ switch(validateFileEntries(*M)) {
+ case Failure: return Failure;
+ case IgnorePCH: return IgnorePCH;
+ case Success: break;
+ }
+ }
+
+ // Preload SLocEntries.
+ for (unsigned I = 0, N = M->PreloadSLocEntries.size(); I != N; ++I) {
+ int Index = int(M->PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID;
+ // Load it through the SourceManager and don't call ReadSLocEntryRecord()
+ // directly because the entry may have already been loaded in which case
+ // calling ReadSLocEntryRecord() directly would trigger an assertion in
+ // SourceManager.
+ SourceMgr.getLoadedSLocEntryByID(Index);
+ }
-void ASTReader::setPreprocessor(Preprocessor &pp) {
- PP = &pp;
- unsigned TotalNum = 0;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I)
- TotalNum += Chain[I]->NumPreallocatedPreprocessingEntities;
- if (TotalNum) {
- if (!PP->getPreprocessingRecord())
- PP->createPreprocessingRecord(true);
- PP->getPreprocessingRecord()->SetExternalSource(*this, TotalNum);
- }
+ return Success;
}
-void ASTReader::InitializeContext(ASTContext &Ctx) {
- Context = &Ctx;
- assert(Context && "Passed null context!");
+void ASTReader::InitializeContext() {
+ // If there's a listener, notify them that we "read" the translation unit.
+ if (DeserializationListener)
+ DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID,
+ Context.getTranslationUnitDecl());
- assert(PP && "Forgot to set Preprocessor ?");
- PP->getIdentifierTable().setExternalIdentifierLookup(this);
- PP->getHeaderSearchInfo().SetExternalLookup(this);
- PP->setExternalSource(this);
- PP->getHeaderSearchInfo().SetExternalSource(this);
+ // Make sure we load the declaration update records for the translation unit,
+ // if there are any.
+ loadDeclUpdateRecords(PREDEF_DECL_TRANSLATION_UNIT_ID,
+ Context.getTranslationUnitDecl());
+
+ // FIXME: Find a better way to deal with collisions between these
+ // built-in types. Right now, we just ignore the problem.
- // 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();
-
// Load the special types.
- Context->setBuiltinVaListType(
- GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
- if (unsigned Id = SpecialTypes[SPECIAL_TYPE_OBJC_ID])
- Context->setObjCIdType(GetType(Id));
- if (unsigned Sel = SpecialTypes[SPECIAL_TYPE_OBJC_SELECTOR])
- Context->setObjCSelType(GetType(Sel));
- if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL])
- Context->setObjCProtoType(GetType(Proto));
- if (unsigned Class = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS])
- Context->setObjCClassType(GetType(Class));
-
- if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING])
- Context->setCFConstantStringType(GetType(String));
- if (unsigned FastEnum
- = SpecialTypes[SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
- Context->setObjCFastEnumerationStateType(GetType(FastEnum));
- if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
- QualType FileType = GetType(File);
- if (FileType.isNull()) {
- Error("FILE type is NULL");
- return;
+ if (SpecialTypes.size() > NumSpecialTypeIDs) {
+ if (Context.getBuiltinVaListType().isNull()) {
+ Context.setBuiltinVaListType(
+ GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
}
- if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
- Context->setFILEDecl(Typedef->getDecl());
- else {
- const TagType *Tag = FileType->getAs<TagType>();
- if (!Tag) {
- Error("Invalid FILE type in AST file");
+
+ if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL]) {
+ if (Context.ObjCProtoType.isNull())
+ Context.ObjCProtoType = GetType(Proto);
+ }
+
+ if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {
+ if (!Context.CFConstantStringTypeDecl)
+ Context.setCFConstantStringType(GetType(String));
+ }
+
+ if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
+ QualType FileType = GetType(File);
+ if (FileType.isNull()) {
+ Error("FILE type is NULL");
return;
}
- Context->setFILEDecl(Tag->getDecl());
+
+ if (!Context.FILEDecl) {
+ if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
+ Context.setFILEDecl(Typedef->getDecl());
+ else {
+ const TagType *Tag = FileType->getAs<TagType>();
+ if (!Tag) {
+ Error("Invalid FILE type in AST file");
+ return;
+ }
+ Context.setFILEDecl(Tag->getDecl());
+ }
+ }
}
- }
- if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) {
- QualType Jmp_bufType = GetType(Jmp_buf);
- if (Jmp_bufType.isNull()) {
- Error("jmp_bug type is NULL");
- return;
+
+ if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) {
+ QualType Jmp_bufType = GetType(Jmp_buf);
+ if (Jmp_bufType.isNull()) {
+ Error("jmp_buf type is NULL");
+ return;
+ }
+
+ if (!Context.jmp_bufDecl) {
+ if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
+ Context.setjmp_bufDecl(Typedef->getDecl());
+ else {
+ const TagType *Tag = Jmp_bufType->getAs<TagType>();
+ if (!Tag) {
+ Error("Invalid jmp_buf type in AST file");
+ return;
+ }
+ Context.setjmp_bufDecl(Tag->getDecl());
+ }
+ }
}
- if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
- Context->setjmp_bufDecl(Typedef->getDecl());
- else {
- const TagType *Tag = Jmp_bufType->getAs<TagType>();
- if (!Tag) {
- Error("Invalid jmp_buf type in AST file");
+
+ if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) {
+ QualType Sigjmp_bufType = GetType(Sigjmp_buf);
+ if (Sigjmp_bufType.isNull()) {
+ Error("sigjmp_buf type is NULL");
return;
}
- Context->setjmp_bufDecl(Tag->getDecl());
+
+ if (!Context.sigjmp_bufDecl) {
+ if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
+ Context.setsigjmp_bufDecl(Typedef->getDecl());
+ else {
+ const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
+ assert(Tag && "Invalid sigjmp_buf type in AST file");
+ Context.setsigjmp_bufDecl(Tag->getDecl());
+ }
+ }
}
- }
- if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) {
- QualType Sigjmp_bufType = GetType(Sigjmp_buf);
- if (Sigjmp_bufType.isNull()) {
- Error("sigjmp_buf type is NULL");
- return;
+
+ if (unsigned ObjCIdRedef
+ = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) {
+ if (Context.ObjCIdRedefinitionType.isNull())
+ Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef);
}
- if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
- Context->setsigjmp_bufDecl(Typedef->getDecl());
- else {
- const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
- assert(Tag && "Invalid sigjmp_buf type in AST file");
- Context->setsigjmp_bufDecl(Tag->getDecl());
+
+ if (unsigned ObjCClassRedef
+ = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) {
+ if (Context.ObjCClassRedefinitionType.isNull())
+ Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef);
+ }
+
+ if (unsigned ObjCSelRedef
+ = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) {
+ if (Context.ObjCSelRedefinitionType.isNull())
+ Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef);
}
}
- if (unsigned ObjCIdRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION])
- Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
- if (unsigned ObjCClassRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
- Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
- if (unsigned String = SpecialTypes[SPECIAL_TYPE_BLOCK_DESCRIPTOR])
- Context->setBlockDescriptorType(GetType(String));
- if (unsigned String
- = SpecialTypes[SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
- Context->setBlockDescriptorExtendedType(GetType(String));
- if (unsigned ObjCSelRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
- Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
- if (unsigned String = SpecialTypes[SPECIAL_TYPE_NS_CONSTANT_STRING])
- Context->setNSConstantStringType(GetType(String));
-
- if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED])
- Context->setInt128Installed();
-
- if (unsigned AutoDeduct = SpecialTypes[SPECIAL_TYPE_AUTO_DEDUCT])
- Context->AutoDeductTy = GetType(AutoDeduct);
- if (unsigned AutoRRefDeduct = SpecialTypes[SPECIAL_TYPE_AUTO_RREF_DEDUCT])
- Context->AutoRRefDeductTy = GetType(AutoRRefDeduct);
-
- ReadPragmaDiagnosticMappings(Context->getDiagnostics());
+
+ 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(
+ Context.setcudaConfigureCallDecl(
cast<FunctionDecl>(GetDecl(CUDASpecialDeclRefs[0])));
}
}
@@ -2833,7 +2676,7 @@ void ASTReader::InitializeContext(ASTContext &Ctx) {
/// file.
std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
FileManager &FileMgr,
- Diagnostic &Diags) {
+ DiagnosticsEngine &Diags) {
// Open the AST file.
std::string ErrStr;
llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
@@ -2917,181 +2760,349 @@ std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
///
/// \returns true if the listener deems the file unacceptable, false otherwise.
bool ASTReader::ParseLanguageOptions(
- const llvm::SmallVectorImpl<uint64_t> &Record) {
+ const SmallVectorImpl<uint64_t> &Record) {
if (Listener) {
LangOptions LangOpts;
-
- #define PARSE_LANGOPT(Option) \
- LangOpts.Option = Record[Idx]; \
- ++Idx
-
unsigned Idx = 0;
- PARSE_LANGOPT(Trigraphs);
- PARSE_LANGOPT(BCPLComment);
- PARSE_LANGOPT(DollarIdents);
- PARSE_LANGOPT(AsmPreprocessor);
- PARSE_LANGOPT(GNUMode);
- PARSE_LANGOPT(GNUKeywords);
- PARSE_LANGOPT(ImplicitInt);
- PARSE_LANGOPT(Digraphs);
- PARSE_LANGOPT(HexFloats);
- PARSE_LANGOPT(C99);
- PARSE_LANGOPT(C1X);
- PARSE_LANGOPT(Microsoft);
- PARSE_LANGOPT(CPlusPlus);
- PARSE_LANGOPT(CPlusPlus0x);
- PARSE_LANGOPT(CXXOperatorNames);
- PARSE_LANGOPT(ObjC1);
- PARSE_LANGOPT(ObjC2);
- PARSE_LANGOPT(ObjCNonFragileABI);
- PARSE_LANGOPT(ObjCNonFragileABI2);
- PARSE_LANGOPT(AppleKext);
- PARSE_LANGOPT(ObjCDefaultSynthProperties);
- PARSE_LANGOPT(ObjCInferRelatedResultType);
- PARSE_LANGOPT(NoConstantCFStrings);
- PARSE_LANGOPT(PascalStrings);
- PARSE_LANGOPT(WritableStrings);
- PARSE_LANGOPT(LaxVectorConversions);
- PARSE_LANGOPT(AltiVec);
- PARSE_LANGOPT(Exceptions);
- PARSE_LANGOPT(ObjCExceptions);
- PARSE_LANGOPT(CXXExceptions);
- PARSE_LANGOPT(SjLjExceptions);
- PARSE_LANGOPT(MSBitfields);
- PARSE_LANGOPT(NeXTRuntime);
- PARSE_LANGOPT(Freestanding);
- PARSE_LANGOPT(NoBuiltin);
- PARSE_LANGOPT(ThreadsafeStatics);
- PARSE_LANGOPT(POSIXThreads);
- PARSE_LANGOPT(Blocks);
- PARSE_LANGOPT(EmitAllDecls);
- PARSE_LANGOPT(MathErrno);
- LangOpts.setSignedOverflowBehavior((LangOptions::SignedOverflowBehaviorTy)
- Record[Idx++]);
- PARSE_LANGOPT(HeinousExtensions);
- PARSE_LANGOPT(Optimize);
- PARSE_LANGOPT(OptimizeSize);
- PARSE_LANGOPT(Static);
- PARSE_LANGOPT(PICLevel);
- PARSE_LANGOPT(GNUInline);
- PARSE_LANGOPT(NoInline);
- PARSE_LANGOPT(Deprecated);
- PARSE_LANGOPT(AccessControl);
- PARSE_LANGOPT(CharIsSigned);
- PARSE_LANGOPT(ShortWChar);
- PARSE_LANGOPT(ShortEnums);
- LangOpts.setGCMode((LangOptions::GCMode)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);
- PARSE_LANGOPT(ElideConstructors);
- PARSE_LANGOPT(SpellChecking);
- PARSE_LANGOPT(MRTD);
- PARSE_LANGOPT(ObjCAutoRefCount);
- #undef PARSE_LANGOPT
-
+#define LANGOPT(Name, Bits, Default, Description) \
+ LangOpts.Name = Record[Idx++];
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+ LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++]));
+#include "clang/Basic/LangOptions.def"
+
return Listener->ReadLanguageOptions(LangOpts);
}
return false;
}
-void ASTReader::ReadPreprocessedEntities() {
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- PerFileData &F = *Chain[I];
- if (!F.PreprocessorDetailCursor.getBitStreamReader())
- continue;
+PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
+ PreprocessedEntityID PPID = Index+1;
+ GlobalPreprocessedEntityMapType::iterator
+ I = GlobalPreprocessedEntityMap.find(Index);
+ assert(I != GlobalPreprocessedEntityMap.end() &&
+ "Corrupted global preprocessed entity map");
+ Module &M = *I->second;
+ unsigned LocalIndex = Index - M.BasePreprocessedEntityID;
+ const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
- SavedStreamPosition SavedPosition(F.PreprocessorDetailCursor);
- F.PreprocessorDetailCursor.JumpToBit(F.PreprocessorDetailStartOffset);
- while (LoadPreprocessedEntity(F)) { }
+ SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);
+ M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset);
+
+ unsigned Code = M.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;
+
+ case llvm::bitc::DEFINE_ABBREV:
+ Error("unexpected abbrevation record in preprocessor detail block");
+ return 0;
+
+ default:
+ break;
}
-}
-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;
+ if (!PP.getPreprocessingRecord()) {
+ Error("no preprocessing record");
+ return 0;
+ }
+
+ // Read the record.
+ SourceRange Range(ReadSourceLocation(M, PPOffs.Begin),
+ ReadSourceLocation(M, PPOffs.End));
+ PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
+ const char *BlobStart = 0;
+ unsigned BlobLen = 0;
+ RecordData Record;
+ PreprocessorDetailRecordTypes RecType =
+ (PreprocessorDetailRecordTypes)M.PreprocessorDetailCursor.ReadRecord(
+ Code, Record, BlobStart, BlobLen);
+ switch (RecType) {
+ case PPD_MACRO_EXPANSION: {
+ bool isBuiltin = Record[0];
+ IdentifierInfo *Name = 0;
+ MacroDefinition *Def = 0;
+ if (isBuiltin)
+ Name = getLocalIdentifier(M, Record[1]);
+ else {
+ PreprocessedEntityID
+ GlobalID = getGlobalPreprocessedEntityID(M, Record[1]);
+ Def =cast<MacroDefinition>(PPRec.getLoadedPreprocessedEntity(GlobalID-1));
}
+
+ MacroExpansion *ME;
+ if (isBuiltin)
+ ME = new (PPRec) MacroExpansion(Name, Range);
+ else
+ ME = new (PPRec) MacroExpansion(Def, Range);
+
+ return ME;
+ }
+
+ case PPD_MACRO_DEFINITION: {
+ // Decode the identifier info and then check again; if the macro is
+ // still defined and associated with the identifier,
+ IdentifierInfo *II = getLocalIdentifier(M, Record[0]);
+ MacroDefinition *MD
+ = new (PPRec) MacroDefinition(II, Range);
+
+ if (DeserializationListener)
+ DeserializationListener->MacroDefinitionRead(PPID, MD);
+
+ return MD;
+ }
+
+ case PPD_INCLUSION_DIRECTIVE: {
+ const char *FullFileNameStart = BlobStart + Record[0];
+ const FileEntry *File
+ = PP.getFileManager().getFile(StringRef(FullFileNameStart,
+ BlobLen - Record[0]));
- Offset -= Chain[I]->SizeInBits;
+ // FIXME: Stable encoding
+ InclusionDirective::InclusionKind Kind
+ = static_cast<InclusionDirective::InclusionKind>(Record[2]);
+ InclusionDirective *ID
+ = new (PPRec) InclusionDirective(PPRec, Kind,
+ StringRef(BlobStart, Record[0]),
+ Record[1],
+ File,
+ Range);
+ return ID;
+ }
}
- if (!F) {
- Error("Malformed preprocessed entity offset");
- return 0;
+ Error("invalid offset in preprocessor detail block");
+ return 0;
+}
+
+/// \brief \arg SLocMapI points at a chunk of a module that contains no
+/// preprocessed entities or the entities it contains are not the ones we are
+/// looking for. Find the next module that contains entities and return the ID
+/// of the first entry.
+PreprocessedEntityID ASTReader::findNextPreprocessedEntity(
+ GlobalSLocOffsetMapType::const_iterator SLocMapI) const {
+ ++SLocMapI;
+ for (GlobalSLocOffsetMapType::const_iterator
+ EndI = GlobalSLocOffsetMap.end(); SLocMapI != EndI; ++SLocMapI) {
+ Module &M = *SLocMapI->second;
+ if (M.NumPreprocessedEntities)
+ return getGlobalPreprocessedEntityID(M, M.BasePreprocessedEntityID);
}
- // 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);
+ return getTotalNumPreprocessedEntities();
}
-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;
+namespace {
+
+template <unsigned PPEntityOffset::*PPLoc>
+struct PPEntityComp {
+ const ASTReader &Reader;
+ Module &M;
+
+ PPEntityComp(const ASTReader &Reader, Module &M) : Reader(Reader), M(M) { }
+
+ bool operator()(const PPEntityOffset &L, const PPEntityOffset &R) const {
+ SourceLocation LHS = getLoc(L);
+ SourceLocation RHS = getLoc(R);
+ return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
+ }
+
+ bool operator()(const PPEntityOffset &L, SourceLocation RHS) const {
+ SourceLocation LHS = getLoc(L);
+ return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
+ }
+
+ bool operator()(SourceLocation LHS, const PPEntityOffset &R) const {
+ SourceLocation RHS = getLoc(R);
+ return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
+ }
+
+ SourceLocation getLoc(const PPEntityOffset &PPE) const {
+ return Reader.ReadSourceLocation(M, PPE.*PPLoc);
+ }
+};
+
+}
+
+/// \brief Returns the first preprocessed entity ID that ends after \arg BLoc.
+PreprocessedEntityID
+ASTReader::findBeginPreprocessedEntity(SourceLocation BLoc) const {
+ if (SourceMgr.isLocalSourceLocation(BLoc))
+ return getTotalNumPreprocessedEntities();
+
+ GlobalSLocOffsetMapType::const_iterator
+ SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
+ BLoc.getOffset());
+ assert(SLocMapI != GlobalSLocOffsetMap.end() &&
+ "Corrupted global sloc offset map");
+
+ if (SLocMapI->second->NumPreprocessedEntities == 0)
+ return findNextPreprocessedEntity(SLocMapI);
+
+ Module &M = *SLocMapI->second;
+ typedef const PPEntityOffset *pp_iterator;
+ pp_iterator pp_begin = M.PreprocessedEntityOffsets;
+ pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
+
+ size_t Count = M.NumPreprocessedEntities;
+ size_t Half;
+ pp_iterator First = pp_begin;
+ pp_iterator PPI;
+
+ // Do a binary search manually instead of using std::lower_bound because
+ // The end locations of entities may be unordered (when a macro expansion
+ // is inside another macro argument), but for this case it is not important
+ // whether we get the first macro expansion or its containing macro.
+ while (Count > 0) {
+ Half = Count/2;
+ PPI = First;
+ std::advance(PPI, Half);
+ if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
+ BLoc)){
+ First = PPI;
+ ++First;
+ Count = Count - Half - 1;
+ } else
+ Count = Half;
+ }
+
+ if (PPI == pp_end)
+ return findNextPreprocessedEntity(SLocMapI);
+
+ return getGlobalPreprocessedEntityID(M,
+ M.BasePreprocessedEntityID + (PPI - pp_begin));
+}
+
+/// \brief Returns the first preprocessed entity ID that begins after \arg ELoc.
+PreprocessedEntityID
+ASTReader::findEndPreprocessedEntity(SourceLocation ELoc) const {
+ if (SourceMgr.isLocalSourceLocation(ELoc))
+ return getTotalNumPreprocessedEntities();
+
+ GlobalSLocOffsetMapType::const_iterator
+ SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
+ ELoc.getOffset());
+ assert(SLocMapI != GlobalSLocOffsetMap.end() &&
+ "Corrupted global sloc offset map");
+
+ if (SLocMapI->second->NumPreprocessedEntities == 0)
+ return findNextPreprocessedEntity(SLocMapI);
+
+ Module &M = *SLocMapI->second;
+ typedef const PPEntityOffset *pp_iterator;
+ pp_iterator pp_begin = M.PreprocessedEntityOffsets;
+ pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
+ pp_iterator PPI =
+ std::upper_bound(pp_begin, pp_end, ELoc,
+ PPEntityComp<&PPEntityOffset::Begin>(*this, M));
+
+ if (PPI == pp_end)
+ return findNextPreprocessedEntity(SLocMapI);
+
+ return getGlobalPreprocessedEntityID(M,
+ M.BasePreprocessedEntityID + (PPI - pp_begin));
+}
+
+/// \brief Returns a pair of [Begin, End) indices of preallocated
+/// preprocessed entities that \arg Range encompasses.
+std::pair<unsigned, unsigned>
+ ASTReader::findPreprocessedEntitiesInRange(SourceRange Range) {
+ if (Range.isInvalid())
+ return std::make_pair(0,0);
+ assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
+
+ PreprocessedEntityID BeginID = findBeginPreprocessedEntity(Range.getBegin());
+ PreprocessedEntityID EndID = findEndPreprocessedEntity(Range.getEnd());
+ return std::make_pair(BeginID, EndID);
+}
+
+namespace {
+ /// \brief Visitor used to search for information about a header file.
+ class HeaderFileInfoVisitor {
+ ASTReader &Reader;
+ const FileEntry *FE;
- // 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;
+ llvm::Optional<HeaderFileInfo> HFI;
+
+ public:
+ HeaderFileInfoVisitor(ASTReader &Reader, const FileEntry *FE)
+ : Reader(Reader), FE(FE) { }
+
+ static bool visit(Module &M, void *UserData) {
+ HeaderFileInfoVisitor *This
+ = static_cast<HeaderFileInfoVisitor *>(UserData);
+
+ HeaderFileInfoTrait Trait(This->Reader, M,
+ &This->Reader.getPreprocessor().getHeaderSearchInfo(),
+ M.HeaderFileFrameworkStrings,
+ This->FE->getName());
+
+ HeaderFileInfoLookupTable *Table
+ = static_cast<HeaderFileInfoLookupTable *>(M.HeaderFileInfoTable);
+ if (!Table)
+ return false;
- HeaderFileInfo HFI = *Pos;
- if (Listener)
- Listener->ReadHeaderFileInfo(HFI, FE->getUID());
+ // Look in the on-disk hash table for an entry for this file name.
+ HeaderFileInfoLookupTable::iterator Pos = Table->find(This->FE->getName(),
+ &Trait);
+ if (Pos == Table->end())
+ return false;
+
+ This->HFI = *Pos;
+ return true;
+ }
+
+ llvm::Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }
+ };
+}
- return HFI;
+HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) {
+ HeaderFileInfoVisitor Visitor(*this, FE);
+ ModuleMgr.visit(&HeaderFileInfoVisitor::visit, &Visitor);
+ if (llvm::Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo()) {
+ 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);
+void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
+ for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
+ Module &F = *(*I);
+ unsigned Idx = 0;
+ while (Idx < F.PragmaDiagMappings.size()) {
+ SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
+ while (1) {
+ assert(Idx < F.PragmaDiagMappings.size() &&
+ "Invalid data, didn't find '-1' marking end of diag/map pairs");
+ if (Idx >= F.PragmaDiagMappings.size()) {
+ break; // Something is messed up but at least avoid infinite loop in
+ // release build.
+ }
+ unsigned DiagID = F.PragmaDiagMappings[Idx++];
+ if (DiagID == (unsigned)-1) {
+ break; // no more diag/map pairs for this location.
+ }
+ diag::Mapping Map = (diag::Mapping)F.PragmaDiagMappings[Idx++];
+ // The user bit gets set by WritePragmaDiagnosticMappings.
+ Diag.setDiagnosticMapping(DiagID, Map, Loc);
+ }
}
}
}
/// \brief Get the correct cursor and offset for loading a type.
ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
- PerFileData *F = 0;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- F = Chain[N - I - 1];
- if (Index < F->LocalNumTypes)
- break;
- Index -= F->LocalNumTypes;
- }
- assert(F && F->LocalNumTypes > Index && "Broken chain");
- return RecordLocation(F, F->TypeOffsets[Index]);
+ GlobalTypeMapType::iterator I = GlobalTypeMap.find(Index);
+ assert(I != GlobalTypeMap.end() && "Corrupted global type map");
+ Module *M = I->second;
+ return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex]);
}
/// \brief Read and return the type with the given index..
@@ -3100,7 +3111,7 @@ ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
/// routine actually reads the record corresponding to the type at the given
/// location. It is a helper routine for GetType, which deals with reading type
/// IDs.
-QualType ASTReader::ReadTypeRecord(unsigned Index) {
+QualType ASTReader::readTypeRecord(unsigned Index) {
RecordLocation Loc = TypeCursorForIndex(Index);
llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
@@ -3113,6 +3124,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
// Note that we are loading a type record.
Deserializing AType(this);
+ unsigned Idx = 0;
DeclsCursor.JumpToBit(Loc.Offset);
RecordData Record;
unsigned Code = DeclsCursor.ReadCode();
@@ -3122,9 +3134,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("Incorrect encoding of extended qualifier type");
return QualType();
}
- QualType Base = GetType(Record[0]);
- Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
- return Context->getQualifiedType(Base, Quals);
+ QualType Base = readType(*Loc.F, Record, Idx);
+ Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[Idx++]);
+ return Context.getQualifiedType(Base, Quals);
}
case TYPE_COMPLEX: {
@@ -3132,8 +3144,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("Incorrect encoding of complex type");
return QualType();
}
- QualType ElemType = GetType(Record[0]);
- return Context->getComplexType(ElemType);
+ QualType ElemType = readType(*Loc.F, Record, Idx);
+ return Context.getComplexType(ElemType);
}
case TYPE_POINTER: {
@@ -3141,8 +3153,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("Incorrect encoding of pointer type");
return QualType();
}
- QualType PointeeType = GetType(Record[0]);
- return Context->getPointerType(PointeeType);
+ QualType PointeeType = readType(*Loc.F, Record, Idx);
+ return Context.getPointerType(PointeeType);
}
case TYPE_BLOCK_POINTER: {
@@ -3150,8 +3162,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("Incorrect encoding of block pointer type");
return QualType();
}
- QualType PointeeType = GetType(Record[0]);
- return Context->getBlockPointerType(PointeeType);
+ QualType PointeeType = readType(*Loc.F, Record, Idx);
+ return Context.getBlockPointerType(PointeeType);
}
case TYPE_LVALUE_REFERENCE: {
@@ -3159,8 +3171,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("Incorrect encoding of lvalue reference type");
return QualType();
}
- QualType PointeeType = GetType(Record[0]);
- return Context->getLValueReferenceType(PointeeType, Record[1]);
+ QualType PointeeType = readType(*Loc.F, Record, Idx);
+ return Context.getLValueReferenceType(PointeeType, Record[1]);
}
case TYPE_RVALUE_REFERENCE: {
@@ -3168,8 +3180,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("Incorrect encoding of rvalue reference type");
return QualType();
}
- QualType PointeeType = GetType(Record[0]);
- return Context->getRValueReferenceType(PointeeType);
+ QualType PointeeType = readType(*Loc.F, Record, Idx);
+ return Context.getRValueReferenceType(PointeeType);
}
case TYPE_MEMBER_POINTER: {
@@ -3177,38 +3189,38 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("Incorrect encoding of member pointer type");
return QualType();
}
- QualType PointeeType = GetType(Record[0]);
- QualType ClassType = GetType(Record[1]);
+ QualType PointeeType = readType(*Loc.F, Record, Idx);
+ QualType ClassType = readType(*Loc.F, Record, Idx);
if (PointeeType.isNull() || ClassType.isNull())
return QualType();
- return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
+ return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());
}
case TYPE_CONSTANT_ARRAY: {
- QualType ElementType = GetType(Record[0]);
+ QualType ElementType = readType(*Loc.F, Record, Idx);
ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
unsigned IndexTypeQuals = Record[2];
unsigned Idx = 3;
llvm::APInt Size = ReadAPInt(Record, Idx);
- return Context->getConstantArrayType(ElementType, Size,
+ return Context.getConstantArrayType(ElementType, Size,
ASM, IndexTypeQuals);
}
case TYPE_INCOMPLETE_ARRAY: {
- QualType ElementType = GetType(Record[0]);
+ QualType ElementType = readType(*Loc.F, Record, Idx);
ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
unsigned IndexTypeQuals = Record[2];
- return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
+ return Context.getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
}
case TYPE_VARIABLE_ARRAY: {
- QualType ElementType = GetType(Record[0]);
+ QualType ElementType = readType(*Loc.F, Record, Idx);
ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
unsigned IndexTypeQuals = Record[2];
SourceLocation LBLoc = ReadSourceLocation(*Loc.F, Record[3]);
SourceLocation RBLoc = ReadSourceLocation(*Loc.F, Record[4]);
- return Context->getVariableArrayType(ElementType, ReadExpr(*Loc.F),
+ return Context.getVariableArrayType(ElementType, ReadExpr(*Loc.F),
ASM, IndexTypeQuals,
SourceRange(LBLoc, RBLoc));
}
@@ -3219,10 +3231,10 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
return QualType();
}
- QualType ElementType = GetType(Record[0]);
+ QualType ElementType = readType(*Loc.F, Record, Idx);
unsigned NumElements = Record[1];
unsigned VecKind = Record[2];
- return Context->getVectorType(ElementType, NumElements,
+ return Context.getVectorType(ElementType, NumElements,
(VectorType::VectorKind)VecKind);
}
@@ -3232,9 +3244,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
return QualType();
}
- QualType ElementType = GetType(Record[0]);
+ QualType ElementType = readType(*Loc.F, Record, Idx);
unsigned NumElements = Record[1];
- return Context->getExtVectorType(ElementType, NumElements);
+ return Context.getExtVectorType(ElementType, NumElements);
}
case TYPE_FUNCTION_NO_PROTO: {
@@ -3242,14 +3254,14 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("incorrect encoding of no-proto function type");
return QualType();
}
- QualType ResultType = GetType(Record[0]);
+ QualType ResultType = readType(*Loc.F, Record, Idx);
FunctionType::ExtInfo Info(Record[1], Record[2], Record[3],
(CallingConv)Record[4], Record[5]);
- return Context->getFunctionNoProtoType(ResultType, Info);
+ return Context.getFunctionNoProtoType(ResultType, Info);
}
case TYPE_FUNCTION_PROTO: {
- QualType ResultType = GetType(Record[0]);
+ QualType ResultType = readType(*Loc.F, Record, Idx);
FunctionProtoType::ExtProtoInfo EPI;
EPI.ExtInfo = FunctionType::ExtInfo(/*noreturn*/ Record[1],
@@ -3260,9 +3272,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
unsigned Idx = 6;
unsigned NumParams = Record[Idx++];
- llvm::SmallVector<QualType, 16> ParamTypes;
+ SmallVector<QualType, 16> ParamTypes;
for (unsigned I = 0; I != NumParams; ++I)
- ParamTypes.push_back(GetType(Record[Idx++]));
+ ParamTypes.push_back(readType(*Loc.F, Record, Idx));
EPI.Variadic = Record[Idx++];
EPI.TypeQuals = Record[Idx++];
@@ -3272,65 +3284,70 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
EPI.ExceptionSpecType = EST;
if (EST == EST_Dynamic) {
EPI.NumExceptions = Record[Idx++];
- llvm::SmallVector<QualType, 2> Exceptions;
+ SmallVector<QualType, 2> Exceptions;
for (unsigned I = 0; I != EPI.NumExceptions; ++I)
- Exceptions.push_back(GetType(Record[Idx++]));
+ Exceptions.push_back(readType(*Loc.F, Record, Idx));
EPI.Exceptions = Exceptions.data();
} else if (EST == EST_ComputedNoexcept) {
EPI.NoexceptExpr = ReadExpr(*Loc.F);
}
- return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
+ return Context.getFunctionType(ResultType, ParamTypes.data(), NumParams,
EPI);
}
- case TYPE_UNRESOLVED_USING:
- return Context->getTypeDeclType(
- cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
-
+ case TYPE_UNRESOLVED_USING: {
+ unsigned Idx = 0;
+ return Context.getTypeDeclType(
+ ReadDeclAs<UnresolvedUsingTypenameDecl>(*Loc.F, Record, Idx));
+ }
+
case TYPE_TYPEDEF: {
if (Record.size() != 2) {
Error("incorrect encoding of typedef type");
return QualType();
}
- TypedefNameDecl *Decl = cast<TypedefNameDecl>(GetDecl(Record[0]));
- QualType Canonical = GetType(Record[1]);
+ unsigned Idx = 0;
+ TypedefNameDecl *Decl = ReadDeclAs<TypedefNameDecl>(*Loc.F, Record, Idx);
+ QualType Canonical = readType(*Loc.F, Record, Idx);
if (!Canonical.isNull())
- Canonical = Context->getCanonicalType(Canonical);
- return Context->getTypedefType(Decl, Canonical);
+ Canonical = Context.getCanonicalType(Canonical);
+ return Context.getTypedefType(Decl, Canonical);
}
case TYPE_TYPEOF_EXPR:
- return Context->getTypeOfExprType(ReadExpr(*Loc.F));
+ return Context.getTypeOfExprType(ReadExpr(*Loc.F));
case TYPE_TYPEOF: {
if (Record.size() != 1) {
Error("incorrect encoding of typeof(type) in AST file");
return QualType();
}
- QualType UnderlyingType = GetType(Record[0]);
- return Context->getTypeOfType(UnderlyingType);
+ QualType UnderlyingType = readType(*Loc.F, Record, Idx);
+ return Context.getTypeOfType(UnderlyingType);
}
case TYPE_DECLTYPE:
- return Context->getDecltypeType(ReadExpr(*Loc.F));
+ return Context.getDecltypeType(ReadExpr(*Loc.F));
case TYPE_UNARY_TRANSFORM: {
- QualType BaseType = GetType(Record[0]);
- QualType UnderlyingType = GetType(Record[1]);
+ QualType BaseType = readType(*Loc.F, Record, Idx);
+ QualType UnderlyingType = readType(*Loc.F, Record, Idx);
UnaryTransformType::UTTKind UKind = (UnaryTransformType::UTTKind)Record[2];
- return Context->getUnaryTransformType(BaseType, UnderlyingType, UKind);
+ return Context.getUnaryTransformType(BaseType, UnderlyingType, UKind);
}
case TYPE_AUTO:
- return Context->getAutoType(GetType(Record[0]));
+ return Context.getAutoType(readType(*Loc.F, Record, Idx));
case TYPE_RECORD: {
if (Record.size() != 2) {
Error("incorrect encoding of record type");
return QualType();
}
- bool IsDependent = Record[0];
- QualType T = Context->getRecordType(cast<RecordDecl>(GetDecl(Record[1])));
+ unsigned Idx = 0;
+ bool IsDependent = Record[Idx++];
+ QualType T
+ = Context.getRecordType(ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx));
const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
return T;
}
@@ -3340,8 +3357,10 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("incorrect encoding of enum type");
return QualType();
}
- bool IsDependent = Record[0];
- QualType T = Context->getEnumType(cast<EnumDecl>(GetDecl(Record[1])));
+ unsigned Idx = 0;
+ bool IsDependent = Record[Idx++];
+ QualType T
+ = Context.getEnumType(ReadDeclAs<EnumDecl>(*Loc.F, Record, Idx));
const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
return T;
}
@@ -3351,10 +3370,10 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("incorrect encoding of attributed type");
return QualType();
}
- QualType modifiedType = GetType(Record[0]);
- QualType equivalentType = GetType(Record[1]);
+ QualType modifiedType = readType(*Loc.F, Record, Idx);
+ QualType equivalentType = readType(*Loc.F, Record, Idx);
AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record[2]);
- return Context->getAttributedType(kind, modifiedType, equivalentType);
+ return Context.getAttributedType(kind, modifiedType, equivalentType);
}
case TYPE_PAREN: {
@@ -3362,8 +3381,8 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("incorrect encoding of paren type");
return QualType();
}
- QualType InnerType = GetType(Record[0]);
- return Context->getParenType(InnerType);
+ QualType InnerType = readType(*Loc.F, Record, Idx);
+ return Context.getParenType(InnerType);
}
case TYPE_PACK_EXPANSION: {
@@ -3371,70 +3390,71 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Error("incorrect encoding of pack expansion type");
return QualType();
}
- QualType Pattern = GetType(Record[0]);
+ QualType Pattern = readType(*Loc.F, Record, Idx);
if (Pattern.isNull())
return QualType();
llvm::Optional<unsigned> NumExpansions;
if (Record[1])
NumExpansions = Record[1] - 1;
- return Context->getPackExpansionType(Pattern, NumExpansions);
+ return Context.getPackExpansionType(Pattern, NumExpansions);
}
case TYPE_ELABORATED: {
unsigned Idx = 0;
ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
- QualType NamedType = GetType(Record[Idx++]);
- return Context->getElaboratedType(Keyword, NNS, NamedType);
+ NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
+ QualType NamedType = readType(*Loc.F, Record, Idx);
+ return Context.getElaboratedType(Keyword, NNS, NamedType);
}
case TYPE_OBJC_INTERFACE: {
unsigned Idx = 0;
- ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
- return Context->getObjCInterfaceType(ItfD);
+ ObjCInterfaceDecl *ItfD
+ = ReadDeclAs<ObjCInterfaceDecl>(*Loc.F, Record, Idx);
+ return Context.getObjCInterfaceType(ItfD);
}
case TYPE_OBJC_OBJECT: {
unsigned Idx = 0;
- QualType Base = GetType(Record[Idx++]);
+ QualType Base = readType(*Loc.F, Record, Idx);
unsigned NumProtos = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
+ 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);
+ Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
+ return Context.getObjCObjectType(Base, Protos.data(), NumProtos);
}
case TYPE_OBJC_OBJECT_POINTER: {
unsigned Idx = 0;
- QualType Pointee = GetType(Record[Idx++]);
- return Context->getObjCObjectPointerType(Pointee);
+ QualType Pointee = readType(*Loc.F, Record, Idx);
+ return Context.getObjCObjectPointerType(Pointee);
}
case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
unsigned Idx = 0;
- QualType Parm = GetType(Record[Idx++]);
- QualType Replacement = GetType(Record[Idx++]);
+ QualType Parm = readType(*Loc.F, Record, Idx);
+ QualType Replacement = readType(*Loc.F, Record, Idx);
return
- Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
+ Context.getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
Replacement);
}
case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {
unsigned Idx = 0;
- QualType Parm = GetType(Record[Idx++]);
+ QualType Parm = readType(*Loc.F, Record, Idx);
TemplateArgument ArgPack = ReadTemplateArgument(*Loc.F, Record, Idx);
- return Context->getSubstTemplateTypeParmPackType(
+ 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
+ CXXRecordDecl *D = ReadDeclAs<CXXRecordDecl>(*Loc.F, Record, Idx);
+ QualType TST = readType(*Loc.F, Record, Idx); // probably derivable
// FIXME: ASTContext::getInjectedClassNameType is not currently suitable
// for AST reading, too much interdependencies.
return
- QualType(new (*Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
+ QualType(new (Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
}
case TYPE_TEMPLATE_TYPE_PARM: {
@@ -3442,33 +3462,33 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
unsigned Depth = Record[Idx++];
unsigned Index = Record[Idx++];
bool Pack = Record[Idx++];
- TemplateTypeParmDecl *D =
- cast_or_null<TemplateTypeParmDecl>(GetDecl(Record[Idx++]));
- return Context->getTemplateTypeParmType(Depth, Index, Pack, D);
+ TemplateTypeParmDecl *D
+ = ReadDeclAs<TemplateTypeParmDecl>(*Loc.F, Record, Idx);
+ return Context.getTemplateTypeParmType(Depth, Index, Pack, D);
}
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++]);
+ NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
+ const IdentifierInfo *Name = this->GetIdentifierInfo(*Loc.F, Record, Idx);
+ QualType Canon = readType(*Loc.F, Record, Idx);
if (!Canon.isNull())
- Canon = Context->getCanonicalType(Canon);
- return Context->getDependentNameType(Keyword, NNS, Name, Canon);
+ Canon = Context.getCanonicalType(Canon);
+ return Context.getDependentNameType(Keyword, NNS, Name, Canon);
}
case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
unsigned Idx = 0;
ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
- const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
+ NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
+ const IdentifierInfo *Name = this->GetIdentifierInfo(*Loc.F, Record, Idx);
unsigned NumArgs = Record[Idx++];
- llvm::SmallVector<TemplateArgument, 8> Args;
+ SmallVector<TemplateArgument, 8> Args;
Args.reserve(NumArgs);
while (NumArgs--)
Args.push_back(ReadTemplateArgument(*Loc.F, Record, Idx));
- return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name,
+ return Context.getDependentTemplateSpecializationType(Keyword, NNS, Name,
Args.size(), Args.data());
}
@@ -3476,7 +3496,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
unsigned Idx = 0;
// ArrayType
- QualType ElementType = GetType(Record[Idx++]);
+ QualType ElementType = readType(*Loc.F, Record, Idx);
ArrayType::ArraySizeModifier ASM
= (ArrayType::ArraySizeModifier)Record[Idx++];
unsigned IndexTypeQuals = Record[Idx++];
@@ -3485,7 +3505,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
Expr *NumElts = ReadExpr(*Loc.F);
SourceRange Brackets = ReadSourceRange(*Loc.F, Record, Idx);
- return Context->getDependentSizedArrayType(ElementType, NumElts, ASM,
+ return Context.getDependentSizedArrayType(ElementType, NumElts, ASM,
IndexTypeQuals, Brackets);
}
@@ -3493,19 +3513,28 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
unsigned Idx = 0;
bool IsDependent = Record[Idx++];
TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx);
- llvm::SmallVector<TemplateArgument, 8> Args;
+ SmallVector<TemplateArgument, 8> Args;
ReadTemplateArgumentList(Args, *Loc.F, Record, Idx);
- QualType Underlying = GetType(Record[Idx++]);
+ QualType Underlying = readType(*Loc.F, Record, Idx);
QualType T;
if (Underlying.isNull())
- T = Context->getCanonicalTemplateSpecializationType(Name, Args.data(),
+ T = Context.getCanonicalTemplateSpecializationType(Name, Args.data(),
Args.size());
else
- T = Context->getTemplateSpecializationType(Name, Args.data(),
+ T = Context.getTemplateSpecializationType(Name, Args.data(),
Args.size(), Underlying);
const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
return T;
}
+
+ case TYPE_ATOMIC: {
+ if (Record.size() != 1) {
+ Error("Incorrect encoding of atomic type");
+ return QualType();
+ }
+ QualType ValueType = readType(*Loc.F, Record, Idx);
+ return Context.getAtomicType(ValueType);
+ }
}
// Suppress a GCC warning
return QualType();
@@ -3513,7 +3542,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
ASTReader &Reader;
- ASTReader::PerFileData &F;
+ Module &F;
llvm::BitstreamCursor &DeclsCursor;
const ASTReader::RecordData &Record;
unsigned &Idx;
@@ -3523,8 +3552,13 @@ class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
return Reader.ReadSourceLocation(F, R, I);
}
+ template<typename T>
+ T *ReadDeclAs(const ASTReader::RecordData &Record, unsigned &Idx) {
+ return Reader.ReadDeclAs<T>(F, Record, Idx);
+ }
+
public:
- TypeLocReader(ASTReader &Reader, ASTReader::PerFileData &F,
+ TypeLocReader(ASTReader &Reader, Module &F,
const ASTReader::RecordData &Record, unsigned &Idx)
: Reader(Reader), F(F), DeclsCursor(F.DeclsCursor), Record(Record), Idx(Idx)
{ }
@@ -3608,7 +3642,7 @@ void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
TL.setLocalRangeEnd(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++])));
+ TL.setArg(i, ReadDeclAs<ParmVarDecl>(Record, Idx));
}
}
void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
@@ -3735,15 +3769,20 @@ void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
TL.setStarLoc(ReadSourceLocation(Record, Idx));
}
+void TypeLocReader::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
+ TL.setKWLoc(ReadSourceLocation(Record, Idx));
+ TL.setLParenLoc(ReadSourceLocation(Record, Idx));
+ TL.setRParenLoc(ReadSourceLocation(Record, Idx));
+}
-TypeSourceInfo *ASTReader::GetTypeSourceInfo(PerFileData &F,
+TypeSourceInfo *ASTReader::GetTypeSourceInfo(Module &F,
const RecordData &Record,
unsigned &Idx) {
- QualType InfoTy = GetType(Record[Idx++]);
+ QualType InfoTy = readType(F, Record, Idx);
if (InfoTy.isNull())
return 0;
- TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
+ TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy);
TypeLocReader TLR(*this, F, Record, Idx);
for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
TLR.Visit(TL);
@@ -3758,41 +3797,47 @@ QualType ASTReader::GetType(TypeID ID) {
QualType T;
switch ((PredefinedTypeIDs)Index) {
case PREDEF_TYPE_NULL_ID: return QualType();
- case PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
- case PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
+ case PREDEF_TYPE_VOID_ID: T = Context.VoidTy; break;
+ case PREDEF_TYPE_BOOL_ID: T = Context.BoolTy; break;
case PREDEF_TYPE_CHAR_U_ID:
case PREDEF_TYPE_CHAR_S_ID:
// FIXME: Check that the signedness of CharTy is correct!
- T = Context->CharTy;
+ T = Context.CharTy;
break;
- case PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
- case PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
- case PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
- case PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
- case PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
- case PREDEF_TYPE_UINT128_ID: T = Context->UnsignedInt128Ty; break;
- case PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
- case PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
- case PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
- case PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
- case PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
- case PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
- case PREDEF_TYPE_INT128_ID: T = Context->Int128Ty; break;
- case PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
- case PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
- case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
- case PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
- case PREDEF_TYPE_BOUND_MEMBER: T = Context->BoundMemberTy; break;
- case PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
- case PREDEF_TYPE_UNKNOWN_ANY: T = Context->UnknownAnyTy; break;
- case PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
- case PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
- case PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
- case PREDEF_TYPE_OBJC_ID: T = Context->ObjCBuiltinIdTy; break;
- case PREDEF_TYPE_OBJC_CLASS: T = Context->ObjCBuiltinClassTy; break;
- case PREDEF_TYPE_OBJC_SEL: T = Context->ObjCBuiltinSelTy; break;
+ case PREDEF_TYPE_UCHAR_ID: T = Context.UnsignedCharTy; break;
+ case PREDEF_TYPE_USHORT_ID: T = Context.UnsignedShortTy; break;
+ case PREDEF_TYPE_UINT_ID: T = Context.UnsignedIntTy; break;
+ case PREDEF_TYPE_ULONG_ID: T = Context.UnsignedLongTy; break;
+ case PREDEF_TYPE_ULONGLONG_ID: T = Context.UnsignedLongLongTy; break;
+ case PREDEF_TYPE_UINT128_ID: T = Context.UnsignedInt128Ty; break;
+ case PREDEF_TYPE_SCHAR_ID: T = Context.SignedCharTy; break;
+ case PREDEF_TYPE_WCHAR_ID: T = Context.WCharTy; break;
+ case PREDEF_TYPE_SHORT_ID: T = Context.ShortTy; break;
+ case PREDEF_TYPE_INT_ID: T = Context.IntTy; break;
+ case PREDEF_TYPE_LONG_ID: T = Context.LongTy; break;
+ case PREDEF_TYPE_LONGLONG_ID: T = Context.LongLongTy; break;
+ case PREDEF_TYPE_INT128_ID: T = Context.Int128Ty; break;
+ case PREDEF_TYPE_HALF_ID: T = Context.HalfTy; break;
+ case PREDEF_TYPE_FLOAT_ID: T = Context.FloatTy; break;
+ case PREDEF_TYPE_DOUBLE_ID: T = Context.DoubleTy; break;
+ case PREDEF_TYPE_LONGDOUBLE_ID: T = Context.LongDoubleTy; break;
+ case PREDEF_TYPE_OVERLOAD_ID: T = Context.OverloadTy; break;
+ case PREDEF_TYPE_BOUND_MEMBER: T = Context.BoundMemberTy; break;
+ case PREDEF_TYPE_DEPENDENT_ID: T = Context.DependentTy; break;
+ case PREDEF_TYPE_UNKNOWN_ANY: T = Context.UnknownAnyTy; break;
+ case PREDEF_TYPE_NULLPTR_ID: T = Context.NullPtrTy; break;
+ case PREDEF_TYPE_CHAR16_ID: T = Context.Char16Ty; break;
+ case PREDEF_TYPE_CHAR32_ID: T = Context.Char32Ty; break;
+ case PREDEF_TYPE_OBJC_ID: T = Context.ObjCBuiltinIdTy; break;
+ case PREDEF_TYPE_OBJC_CLASS: T = Context.ObjCBuiltinClassTy; break;
+ case PREDEF_TYPE_OBJC_SEL: T = Context.ObjCBuiltinSelTy; break;
+ case PREDEF_TYPE_AUTO_DEDUCT: T = Context.getAutoDeductType(); break;
+
+ case PREDEF_TYPE_AUTO_RREF_DEDUCT:
+ T = Context.getAutoRRefDeductType();
+ break;
}
assert(!T.isNull() && "Unknown predefined type");
@@ -3802,12 +3847,11 @@ QualType ASTReader::GetType(TypeID ID) {
Index -= NUM_PREDEF_TYPE_IDS;
assert(Index < TypesLoaded.size() && "Type index out-of-range");
if (TypesLoaded[Index].isNull()) {
- TypesLoaded[Index] = ReadTypeRecord(Index);
+ TypesLoaded[Index] = readTypeRecord(Index);
if (TypesLoaded[Index].isNull())
return QualType();
TypesLoaded[Index]->setFromAST();
- TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
if (DeserializationListener)
DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
TypesLoaded[Index]);
@@ -3816,37 +3860,28 @@ QualType ASTReader::GetType(TypeID ID) {
return TypesLoaded[Index].withFastQualifiers(FastQuals);
}
-TypeID ASTReader::GetTypeID(QualType T) const {
- return MakeTypeID(T,
- std::bind1st(std::mem_fun(&ASTReader::GetTypeIdx), this));
+QualType ASTReader::getLocalType(Module &F, unsigned LocalID) {
+ return GetType(getGlobalTypeID(F, LocalID));
}
-TypeIdx ASTReader::GetTypeIdx(QualType T) const {
- if (T.isNull())
- return TypeIdx();
- assert(!T.getLocalFastQualifiers());
-
- TypeIdxMap::const_iterator I = TypeIdxs.find(T);
- // GetTypeIdx is mostly used for computing the hash of DeclarationNames and
- // comparing keys of ASTDeclContextNameLookupTable.
- // If the type didn't come from the AST file use a specially marked index
- // so that any hash/key comparison fail since no such index is stored
- // in a AST file.
- if (I == TypeIdxs.end())
- return TypeIdx(-1);
- return I->second;
-}
+serialization::TypeID
+ASTReader::getGlobalTypeID(Module &F, unsigned LocalID) const {
+ unsigned FastQuals = LocalID & Qualifiers::FastMask;
+ unsigned LocalIndex = LocalID >> Qualifiers::FastWidth;
+
+ if (LocalIndex < NUM_PREDEF_TYPE_IDS)
+ return LocalID;
-unsigned ASTReader::getTotalNumCXXBaseSpecifiers() const {
- unsigned Result = 0;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I)
- Result += Chain[I]->LocalNumCXXBaseSpecifiers;
+ ContinuousRangeMap<uint32_t, int, 2>::iterator I
+ = F.TypeRemap.find(LocalIndex - NUM_PREDEF_TYPE_IDS);
+ assert(I != F.TypeRemap.end() && "Invalid index into type index remap");
- return Result;
+ unsigned GlobalIndex = LocalIndex + I->second;
+ return (GlobalIndex << Qualifiers::FastWidth) | FastQuals;
}
TemplateArgumentLocInfo
-ASTReader::GetTemplateArgumentLocInfo(PerFileData &F,
+ASTReader::GetTemplateArgumentLocInfo(Module &F,
TemplateArgument::ArgKind Kind,
const RecordData &Record,
unsigned &Index) {
@@ -3881,7 +3916,7 @@ ASTReader::GetTemplateArgumentLocInfo(PerFileData &F,
}
TemplateArgumentLoc
-ASTReader::ReadTemplateArgumentLoc(PerFileData &F,
+ASTReader::ReadTemplateArgumentLoc(Module &F,
const RecordData &Record, unsigned &Index) {
TemplateArgument Arg = ReadTemplateArgument(F, Record, Index);
@@ -3897,47 +3932,20 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) {
return GetDecl(ID);
}
-uint64_t
-ASTReader::GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID) {
- if (ID == 0)
+uint64_t ASTReader::readCXXBaseSpecifiers(Module &M, const RecordData &Record,
+ unsigned &Idx){
+ if (Idx >= Record.size())
return 0;
- --ID;
- uint64_t Offset = 0;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- PerFileData &F = *Chain[N - I - 1];
-
- if (ID < F.LocalNumCXXBaseSpecifiers)
- return Offset + F.CXXBaseSpecifiersOffsets[ID];
-
- ID -= F.LocalNumCXXBaseSpecifiers;
- Offset += F.SizeInBits;
- }
-
- assert(false && "CXXBaseSpecifiers not found");
- return 0;
+ unsigned LocalID = Record[Idx++];
+ return getGlobalBitOffset(M, M.CXXBaseSpecifiersOffsets[LocalID - 1]);
}
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[N - I - 1]->SizeInBits) {
- F = Chain[N - I - 1];
- break;
- }
-
- Offset -= Chain[N - I - 1]->SizeInBits;
- }
-
- if (!F) {
- Error("Malformed AST file: C++ base specifiers at impossible offset");
- return 0;
- }
-
- llvm::BitstreamCursor &Cursor = F->DeclsCursor;
+ RecordLocation Loc = getLocalBitOffset(Offset);
+ llvm::BitstreamCursor &Cursor = Loc.F->DeclsCursor;
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Offset);
+ Cursor.JumpToBit(Loc.Offset);
ReadingKindTracker ReadingKind(Read_Decl, *this);
RecordData Record;
unsigned Code = Cursor.ReadCode();
@@ -3949,35 +3957,72 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
unsigned Idx = 0;
unsigned NumBases = Record[Idx++];
- void *Mem = Context->Allocate(sizeof(CXXBaseSpecifier) * NumBases);
+ 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);
+ Bases[I] = ReadCXXBaseSpecifier(*Loc.F, Record, Idx);
return Bases;
}
-TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
- if (!DeclsLoaded[0]) {
- ReadDeclRecord(0, 1);
- if (DeserializationListener)
- DeserializationListener->DeclRead(1, DeclsLoaded[0]);
- }
+serialization::DeclID
+ASTReader::getGlobalDeclID(Module &F, unsigned LocalID) const {
+ if (LocalID < NUM_PREDEF_DECL_IDS)
+ return LocalID;
+
+ ContinuousRangeMap<uint32_t, int, 2>::iterator I
+ = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS);
+ assert(I != F.DeclRemap.end() && "Invalid index into decl index remap");
+
+ return LocalID + I->second;
+}
- return cast<TranslationUnitDecl>(DeclsLoaded[0]);
+bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID,
+ Module &M) const {
+ GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(ID);
+ assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
+ return &M == I->second;
}
Decl *ASTReader::GetDecl(DeclID ID) {
- if (ID == 0)
+ if (ID < NUM_PREDEF_DECL_IDS) {
+ switch ((PredefinedDeclIDs)ID) {
+ case PREDEF_DECL_NULL_ID:
+ return 0;
+
+ case PREDEF_DECL_TRANSLATION_UNIT_ID:
+ return Context.getTranslationUnitDecl();
+
+ case PREDEF_DECL_OBJC_ID_ID:
+ return Context.getObjCIdDecl();
+
+ case PREDEF_DECL_OBJC_SEL_ID:
+ return Context.getObjCSelDecl();
+
+ case PREDEF_DECL_OBJC_CLASS_ID:
+ return Context.getObjCClassDecl();
+
+ case PREDEF_DECL_INT_128_ID:
+ return Context.getInt128Decl();
+
+ case PREDEF_DECL_UNSIGNED_INT_128_ID:
+ return Context.getUInt128Decl();
+
+ case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
+ return Context.getObjCInstanceTypeDecl();
+ }
+
return 0;
+ }
+
+ unsigned Index = ID - NUM_PREDEF_DECL_IDS;
- if (ID > DeclsLoaded.size()) {
+ if (Index > DeclsLoaded.size()) {
Error("declaration ID out-of-range for AST file");
return 0;
}
-
- unsigned Index = ID - 1;
- if (!DeclsLoaded[Index]) {
- ReadDeclRecord(Index, ID);
+
+if (!DeclsLoaded[Index]) {
+ ReadDeclRecord(ID);
if (DeserializationListener)
DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
}
@@ -3985,6 +4030,17 @@ Decl *ASTReader::GetDecl(DeclID ID) {
return DeclsLoaded[Index];
}
+serialization::DeclID ASTReader::ReadDeclID(Module &F,
+ const RecordData &Record,
+ unsigned &Idx) {
+ if (Idx >= Record.size()) {
+ Error("Corrupted AST file");
+ return 0;
+ }
+
+ return getGlobalDeclID(F, Record[Idx++]);
+}
+
/// \brief Resolve the offset of a statement into a statement.
///
/// This operation will read a new statement from the external
@@ -3995,49 +4051,137 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
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];
- if (Offset < F.SizeInBits) {
- // 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);
- }
- Offset -= F.SizeInBits;
- }
- llvm_unreachable("Broken chain");
+ RecordLocation Loc = getLocalBitOffset(Offset);
+ Loc.F->DeclsCursor.JumpToBit(Loc.Offset);
+ return ReadStmtFromStream(*Loc.F);
}
-ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
- bool (*isKindWeWant)(Decl::Kind),
- llvm::SmallVectorImpl<Decl*> &Decls) {
- // There might be lexical decls in multiple parts of the chain, for the TU
- // at least.
- // 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.
- if (!I->LexicalDecls)
- continue;
+namespace {
+ class FindExternalLexicalDeclsVisitor {
+ ASTReader &Reader;
+ const DeclContext *DC;
+ bool (*isKindWeWant)(Decl::Kind);
+
+ SmallVectorImpl<Decl*> &Decls;
+ bool PredefsVisited[NUM_PREDEF_DECL_IDS];
- // Load all of the declaration IDs
- for (const KindDeclIDPair *ID = I->LexicalDecls,
- *IDE = ID + I->NumLexicalDecls; ID != IDE; ++ID) {
- if (isKindWeWant && !isKindWeWant((Decl::Kind)ID->first))
- continue;
+ public:
+ FindExternalLexicalDeclsVisitor(ASTReader &Reader, const DeclContext *DC,
+ bool (*isKindWeWant)(Decl::Kind),
+ SmallVectorImpl<Decl*> &Decls)
+ : Reader(Reader), DC(DC), isKindWeWant(isKindWeWant), Decls(Decls)
+ {
+ for (unsigned I = 0; I != NUM_PREDEF_DECL_IDS; ++I)
+ PredefsVisited[I] = false;
+ }
- Decl *D = GetDecl(ID->second);
- assert(D && "Null decl in lexical decls");
- Decls.push_back(D);
+ static bool visit(Module &M, bool Preorder, void *UserData) {
+ if (Preorder)
+ return false;
+
+ FindExternalLexicalDeclsVisitor *This
+ = static_cast<FindExternalLexicalDeclsVisitor *>(UserData);
+
+ Module::DeclContextInfosMap::iterator Info
+ = M.DeclContextInfos.find(This->DC);
+ if (Info == M.DeclContextInfos.end() || !Info->second.LexicalDecls)
+ return false;
+
+ // Load all of the declaration IDs
+ for (const KindDeclIDPair *ID = Info->second.LexicalDecls,
+ *IDE = ID + Info->second.NumLexicalDecls;
+ ID != IDE; ++ID) {
+ if (This->isKindWeWant && !This->isKindWeWant((Decl::Kind)ID->first))
+ continue;
+
+ // Don't add predefined declarations to the lexical context more
+ // than once.
+ if (ID->second < NUM_PREDEF_DECL_IDS) {
+ if (This->PredefsVisited[ID->second])
+ continue;
+
+ This->PredefsVisited[ID->second] = true;
+ }
+
+ if (Decl *D = This->Reader.GetLocalDecl(M, ID->second)) {
+ if (!This->DC->isDeclInLexicalTraversal(D))
+ This->Decls.push_back(D);
+ }
+ }
+
+ return false;
}
- }
+ };
+}
+ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
+ bool (*isKindWeWant)(Decl::Kind),
+ SmallVectorImpl<Decl*> &Decls) {
+ // There might be lexical decls in multiple modules, for the TU at
+ // least. Walk all of the modules in the order they were loaded.
+ FindExternalLexicalDeclsVisitor Visitor(*this, DC, isKindWeWant, Decls);
+ ModuleMgr.visitDepthFirst(&FindExternalLexicalDeclsVisitor::visit, &Visitor);
++NumLexicalDeclContextsRead;
return ELR_Success;
}
+namespace {
+ /// \brief Module visitor used to perform name lookup into a
+ /// declaration context.
+ class DeclContextNameLookupVisitor {
+ ASTReader &Reader;
+ const DeclContext *DC;
+ DeclarationName Name;
+ SmallVectorImpl<NamedDecl *> &Decls;
+
+ public:
+ DeclContextNameLookupVisitor(ASTReader &Reader,
+ const DeclContext *DC, DeclarationName Name,
+ SmallVectorImpl<NamedDecl *> &Decls)
+ : Reader(Reader), DC(DC), Name(Name), Decls(Decls) { }
+
+ static bool visit(Module &M, void *UserData) {
+ DeclContextNameLookupVisitor *This
+ = static_cast<DeclContextNameLookupVisitor *>(UserData);
+
+ // Check whether we have any visible declaration information for
+ // this context in this module.
+ Module::DeclContextInfosMap::iterator Info
+ = M.DeclContextInfos.find(This->DC);
+ if (Info == M.DeclContextInfos.end() || !Info->second.NameLookupTableData)
+ return false;
+
+ // Look for this name within this module.
+ ASTDeclContextNameLookupTable *LookupTable =
+ (ASTDeclContextNameLookupTable*)Info->second.NameLookupTableData;
+ ASTDeclContextNameLookupTable::iterator Pos
+ = LookupTable->find(This->Name);
+ if (Pos == LookupTable->end())
+ return false;
+
+ bool FoundAnything = false;
+ ASTDeclContextNameLookupTrait::data_type Data = *Pos;
+ for (; Data.first != Data.second; ++Data.first) {
+ NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M, *Data.first);
+ if (!ND)
+ continue;
+
+ if (ND->getDeclName() != This->Name) {
+ assert(!This->Name.getCXXNameType().isNull() &&
+ "Name mismatch without a type");
+ continue;
+ }
+
+ // Record this declaration.
+ FoundAnything = true;
+ This->Decls.push_back(ND);
+ }
+
+ return FoundAnything;
+ }
+ };
+}
+
DeclContext::lookup_result
ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
@@ -4047,69 +4191,39 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
DeclContext::lookup_iterator(0));
- llvm::SmallVector<NamedDecl *, 64> Decls;
- // There might be visible decls in multiple parts of the chain, for the TU
- // and namespaces. For any given name, the last available results replace
- // all earlier ones. For this reason, we walk in reverse.
- DeclContextInfos &Infos = DeclContextOffsets[DC];
- for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
- I != E; ++I) {
- if (!I->NameLookupTableData)
- continue;
-
- ASTDeclContextNameLookupTable *LookupTable =
- (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
- ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
- if (Pos == LookupTable->end())
- continue;
-
- ASTDeclContextNameLookupTrait::data_type Data = *Pos;
- for (; Data.first != Data.second; ++Data.first)
- Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
- break;
- }
-
+ SmallVector<NamedDecl *, 64> Decls;
+ DeclContextNameLookupVisitor Visitor(*this, DC, Name, Decls);
+ ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor);
++NumVisibleDeclContextsRead;
-
SetExternalVisibleDeclsForName(DC, Name, Decls);
return const_cast<DeclContext*>(DC)->lookup(Name);
}
-void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
- assert(DC->hasExternalVisibleStorage() &&
- "DeclContext has no visible decls in storage");
+/// \brief Under non-PCH compilation the consumer receives the objc methods
+/// before receiving the implementation, and codegen depends on this.
+/// We simulate this by deserializing and passing to consumer the methods of the
+/// implementation before passing the deserialized implementation decl.
+static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD,
+ ASTConsumer *Consumer) {
+ assert(ImplD && Consumer);
- llvm::SmallVector<NamedDecl *, 64> Decls;
- // There might be visible decls in multiple parts of the chain, for the TU
- // and namespaces.
- DeclContextInfos &Infos = DeclContextOffsets[DC];
- for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
- I != E; ++I) {
- if (!I->NameLookupTableData)
- continue;
+ for (ObjCImplDecl::method_iterator
+ I = ImplD->meth_begin(), E = ImplD->meth_end(); I != E; ++I)
+ Consumer->HandleInterestingDecl(DeclGroupRef(*I));
- ASTDeclContextNameLookupTable *LookupTable =
- (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
- for (ASTDeclContextNameLookupTable::item_iterator
- ItemI = LookupTable->item_begin(),
- ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) {
- ASTDeclContextNameLookupTable::item_iterator::value_type Val
- = *ItemI;
- ASTDeclContextNameLookupTrait::data_type Data = Val.second;
- Decls.clear();
- for (; Data.first != Data.second; ++Data.first)
- Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
- MaterializeVisibleDeclsForName(DC, Val.first, Decls);
- }
- }
+ Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));
}
void ASTReader::PassInterestingDeclsToConsumer() {
assert(Consumer);
while (!InterestingDecls.empty()) {
- DeclGroupRef DG(InterestingDecls.front());
+ Decl *D = InterestingDecls.front();
InterestingDecls.pop_front();
- Consumer->HandleInterestingDecl(DG);
+
+ if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+ PassObjCImplDeclToConsumer(ImplD, Consumer);
+ else
+ Consumer->HandleInterestingDecl(DeclGroupRef(D));
}
}
@@ -4124,6 +4238,7 @@ void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
// passing to the consumer.
GetDecl(ExternalDefinitions[I]);
}
+ ExternalDefinitions.clear();
PassInterestingDeclsToConsumer();
}
@@ -4148,7 +4263,7 @@ void ASTReader::PrintStats() {
std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
- if (TotalNumSLocEntries)
+ if (unsigned TotalNumSLocEntries = getTotalNumSLocs())
std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
NumSLocEntriesRead, TotalNumSLocEntries,
((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
@@ -4194,13 +4309,51 @@ void ASTReader::PrintStats() {
std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
}
std::fprintf(stderr, "\n");
+ dump();
+ std::fprintf(stderr, "\n");
+}
+
+template<typename Key, typename Module, unsigned InitialCapacity>
+static void
+dumpModuleIDMap(StringRef Name,
+ const ContinuousRangeMap<Key, Module *,
+ InitialCapacity> &Map) {
+ if (Map.begin() == Map.end())
+ return;
+
+ typedef ContinuousRangeMap<Key, Module *, InitialCapacity> MapType;
+ llvm::errs() << Name << ":\n";
+ for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
+ I != IEnd; ++I) {
+ llvm::errs() << " " << I->first << " -> " << I->second->FileName
+ << "\n";
+ }
+}
+
+void ASTReader::dump() {
+ llvm::errs() << "*** PCH/Module Remappings:\n";
+ dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap);
+ dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap);
+ dumpModuleIDMap("Global type map", GlobalTypeMap);
+ dumpModuleIDMap("Global declaration map", GlobalDeclMap);
+ dumpModuleIDMap("Global identifier map", GlobalIdentifierMap);
+ dumpModuleIDMap("Global selector map", GlobalSelectorMap);
+ dumpModuleIDMap("Global preprocessed entity map",
+ GlobalPreprocessedEntityMap);
+
+ llvm::errs() << "\n*** PCH/Modules Loaded:";
+ for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(),
+ MEnd = ModuleMgr.end();
+ M != MEnd; ++M)
+ (*M)->dump();
}
/// Return the amount of memory used by memory buffers, breaking down
/// by heap-backed versus mmap'ed memory.
void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
- for (unsigned i = 0, e = Chain.size(); i != e; ++i)
- if (llvm::MemoryBuffer *buf = Chain[i]->Buffer.get()) {
+ for (ModuleConstIterator I = ModuleMgr.begin(),
+ E = ModuleMgr.end(); I != E; ++I) {
+ if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) {
size_t bytes = buf->getBufferSize();
switch (buf->getBufferKind()) {
case llvm::MemoryBuffer::MemoryBuffer_Malloc:
@@ -4211,6 +4364,7 @@ void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
break;
}
}
+ }
}
void ASTReader::InitializeSema(Sema &S) {
@@ -4227,114 +4381,14 @@ void ASTReader::InitializeSema(Sema &S) {
}
PreloadedDecls.clear();
- // If there were any tentative definitions, deserialize them and add
- // them to Sema's list of tentative definitions.
- for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
- VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
- SemaObj->TentativeDefinitions.push_back(Var);
- }
-
- // If there were any unused file scoped decls, deserialize them and add to
- // Sema's list of unused file scoped decls.
- for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
- DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
- SemaObj->UnusedFileScopedDecls.push_back(D);
- }
-
- // If there were any delegating constructors, add them to Sema's list
- for (unsigned I = 0, N = DelegatingCtorDecls.size(); I != N; ++I) {
- CXXConstructorDecl *D
- = cast<CXXConstructorDecl>(GetDecl(DelegatingCtorDecls[I]));
- SemaObj->DelegatingCtorDecls.push_back(D);
- }
-
- // If there were any locally-scoped external declarations,
- // deserialize them and add them to Sema's table of locally-scoped
- // external declarations.
- for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
- NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
- SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
- }
-
- // If there were any ext_vector type declarations, deserialize them
- // and add them to Sema's vector of such declarations.
- for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
- SemaObj->ExtVectorDecls.push_back(
- cast<TypedefNameDecl>(GetDecl(ExtVectorDecls[I])));
-
- // FIXME: Do VTable uses and dynamic classes deserialize too much ?
- // Can we cut them down before writing them ?
-
- // 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])));
-
// Load the offsets of the declarations that Sema references.
// They will be lazily deserialized when needed.
if (!SemaDeclRefs.empty()) {
assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
- SemaObj->StdNamespace = SemaDeclRefs[0];
- SemaObj->StdBadAlloc = SemaDeclRefs[1];
- }
-
- 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));
- }
- }
- }
-
- // The 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 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));
- }
-
- // 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 (!SemaObj->StdNamespace)
+ SemaObj->StdNamespace = SemaDeclRefs[0];
+ if (!SemaObj->StdBadAlloc)
+ SemaObj->StdBadAlloc = SemaDeclRefs[1];
}
if (!FPPragmaOptions.empty()) {
@@ -4352,24 +4406,9 @@ void ASTReader::InitializeSema(Sema &S) {
}
IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
- // Try to find this name within our on-disk hash tables. We start with the
- // most recent one, since that one contains the most up-to-date info.
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- ASTIdentifierLookupTable *IdTable
- = (ASTIdentifierLookupTable *)Chain[I]->IdentifierLookupTable;
- if (!IdTable)
- continue;
- std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
- ASTIdentifierLookupTable::iterator Pos = IdTable->find(Key);
- if (Pos == IdTable->end())
- continue;
-
- // Dereferencing the iterator has the effect of building the
- // IdentifierInfo node and populating it with the various
- // declarations it needs.
- return *Pos;
- }
- return 0;
+ IdentifierLookupVisitor Visitor(StringRef(NameStart, NameEnd - NameStart));
+ ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
+ return Visitor.getIdentifierInfo();
}
namespace clang {
@@ -4394,27 +4433,28 @@ namespace clang {
public:
explicit ASTIdentifierIterator(const ASTReader &Reader);
- virtual llvm::StringRef Next();
+ virtual StringRef Next();
};
}
ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader)
- : Reader(Reader), Index(Reader.Chain.size() - 1) {
+ : Reader(Reader), Index(Reader.ModuleMgr.size() - 1) {
ASTIdentifierLookupTable *IdTable
- = (ASTIdentifierLookupTable *)Reader.Chain[Index]->IdentifierLookupTable;
+ = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].IdentifierLookupTable;
Current = IdTable->key_begin();
End = IdTable->key_end();
}
-llvm::StringRef ASTIdentifierIterator::Next() {
+StringRef ASTIdentifierIterator::Next() {
while (Current == End) {
// If we have exhausted all of our AST files, we're done.
if (Index == 0)
- return llvm::StringRef();
+ return StringRef();
--Index;
ASTIdentifierLookupTable *IdTable
- = (ASTIdentifierLookupTable *)Reader.Chain[Index]->IdentifierLookupTable;
+ = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].
+ IdentifierLookupTable;
Current = IdTable->key_begin();
End = IdTable->key_end();
}
@@ -4423,43 +4463,103 @@ llvm::StringRef ASTIdentifierIterator::Next() {
// the next one.
std::pair<const char*, unsigned> Key = *Current;
++Current;
- return llvm::StringRef(Key.first, Key.second);
+ return 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.
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- PerFileData &F = *Chain[I];
- if (!F.SelectorLookupTable)
- continue;
-
- ASTSelectorLookupTable *PoolTable
- = (ASTSelectorLookupTable*)F.SelectorLookupTable;
- ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
- if (Pos != PoolTable->end()) {
- ++NumSelectorsRead;
+namespace clang { namespace serialization {
+ class ReadMethodPoolVisitor {
+ ASTReader &Reader;
+ Selector Sel;
+ llvm::SmallVector<ObjCMethodDecl *, 4> InstanceMethods;
+ llvm::SmallVector<ObjCMethodDecl *, 4> FactoryMethods;
+
+ /// \brief Build an ObjCMethodList from a vector of Objective-C method
+ /// declarations.
+ ObjCMethodList
+ buildObjCMethodList(const SmallVectorImpl<ObjCMethodDecl *> &Vec) const
+ {
+ ObjCMethodList List;
+ ObjCMethodList *Prev = 0;
+ for (unsigned I = 0, N = Vec.size(); I != N; ++I) {
+ if (!List.Method) {
+ // This is the first method, which is the easy case.
+ List.Method = Vec[I];
+ Prev = &List;
+ continue;
+ }
+
+ ObjCMethodList *Mem =
+ Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
+ Prev->Next = new (Mem) ObjCMethodList(Vec[I], 0);
+ Prev = Prev->Next;
+ }
+
+ return List;
+ }
+
+ public:
+ ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel)
+ : Reader(Reader), Sel(Sel) { }
+
+ static bool visit(Module &M, void *UserData) {
+ ReadMethodPoolVisitor *This
+ = static_cast<ReadMethodPoolVisitor *>(UserData);
+
+ if (!M.SelectorLookupTable)
+ return false;
+
+ ASTSelectorLookupTable *PoolTable
+ = (ASTSelectorLookupTable*)M.SelectorLookupTable;
+ ASTSelectorLookupTable::iterator Pos = PoolTable->find(This->Sel);
+ if (Pos == PoolTable->end())
+ return false;
+
+ ++This->Reader.NumSelectorsRead;
// FIXME: Not quite happy with the statistics here. We probably should
// disable this tracking when called via LoadSelector.
// Also, should entries without methods count as misses?
- ++NumMethodPoolEntriesRead;
+ ++This->Reader.NumMethodPoolEntriesRead;
ASTSelectorLookupTrait::data_type Data = *Pos;
- if (DeserializationListener)
- DeserializationListener->SelectorRead(Data.ID, Sel);
- return std::make_pair(Data.Instance, Data.Factory);
+ if (This->Reader.DeserializationListener)
+ This->Reader.DeserializationListener->SelectorRead(Data.ID,
+ This->Sel);
+
+ This->InstanceMethods.append(Data.Instance.begin(), Data.Instance.end());
+ This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());
+ return true;
+ }
+
+ /// \brief Retrieve the instance methods found by this visitor.
+ ObjCMethodList getInstanceMethods() const {
+ return buildObjCMethodList(InstanceMethods);
}
- }
- ++NumMethodPoolMisses;
- return std::pair<ObjCMethodList, ObjCMethodList>();
+ /// \brief Retrieve the instance methods found by this visitor.
+ ObjCMethodList getFactoryMethods() const {
+ return buildObjCMethodList(FactoryMethods);
+ }
+ };
+} } // end namespace clang::serialization
+
+std::pair<ObjCMethodList, ObjCMethodList>
+ASTReader::ReadMethodPool(Selector Sel) {
+ ReadMethodPoolVisitor Visitor(*this, Sel);
+ ModuleMgr.visit(&ReadMethodPoolVisitor::visit, &Visitor);
+ std::pair<ObjCMethodList, ObjCMethodList> Result;
+ Result.first = Visitor.getInstanceMethods();
+ Result.second = Visitor.getFactoryMethods();
+
+ if (!Result.first.Method && !Result.second.Method)
+ ++NumMethodPoolMisses;
+ return Result;
}
void ASTReader::ReadKnownNamespaces(
- llvm::SmallVectorImpl<NamespaceDecl *> &Namespaces) {
+ SmallVectorImpl<NamespaceDecl *> &Namespaces) {
Namespaces.clear();
for (unsigned I = 0, N = KnownNamespaces.size(); I != N; ++I) {
@@ -4469,12 +4569,136 @@ void ASTReader::ReadKnownNamespaces(
}
}
+void ASTReader::ReadTentativeDefinitions(
+ SmallVectorImpl<VarDecl *> &TentativeDefs) {
+ for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
+ VarDecl *Var = dyn_cast_or_null<VarDecl>(GetDecl(TentativeDefinitions[I]));
+ if (Var)
+ TentativeDefs.push_back(Var);
+ }
+ TentativeDefinitions.clear();
+}
+
+void ASTReader::ReadUnusedFileScopedDecls(
+ SmallVectorImpl<const DeclaratorDecl *> &Decls) {
+ for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
+ DeclaratorDecl *D
+ = dyn_cast_or_null<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
+ if (D)
+ Decls.push_back(D);
+ }
+ UnusedFileScopedDecls.clear();
+}
+
+void ASTReader::ReadDelegatingConstructors(
+ SmallVectorImpl<CXXConstructorDecl *> &Decls) {
+ for (unsigned I = 0, N = DelegatingCtorDecls.size(); I != N; ++I) {
+ CXXConstructorDecl *D
+ = dyn_cast_or_null<CXXConstructorDecl>(GetDecl(DelegatingCtorDecls[I]));
+ if (D)
+ Decls.push_back(D);
+ }
+ DelegatingCtorDecls.clear();
+}
+
+void ASTReader::ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {
+ for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I) {
+ TypedefNameDecl *D
+ = dyn_cast_or_null<TypedefNameDecl>(GetDecl(ExtVectorDecls[I]));
+ if (D)
+ Decls.push_back(D);
+ }
+ ExtVectorDecls.clear();
+}
+
+void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {
+ for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) {
+ CXXRecordDecl *D
+ = dyn_cast_or_null<CXXRecordDecl>(GetDecl(DynamicClasses[I]));
+ if (D)
+ Decls.push_back(D);
+ }
+ DynamicClasses.clear();
+}
+
+void
+ASTReader::ReadLocallyScopedExternalDecls(SmallVectorImpl<NamedDecl *> &Decls) {
+ for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
+ NamedDecl *D
+ = dyn_cast_or_null<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
+ if (D)
+ Decls.push_back(D);
+ }
+ LocallyScopedExternalDecls.clear();
+}
+
+void ASTReader::ReadReferencedSelectors(
+ SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
+ if (ReferencedSelectorsData.empty())
+ return;
+
+ // If there are @selector references added them to its pool. This is for
+ // implementation of -Wselector.
+ unsigned int DataSize = ReferencedSelectorsData.size()-1;
+ unsigned I = 0;
+ while (I < DataSize) {
+ Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
+ SourceLocation SelLoc
+ = SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
+ Sels.push_back(std::make_pair(Sel, SelLoc));
+ }
+ ReferencedSelectorsData.clear();
+}
+
+void ASTReader::ReadWeakUndeclaredIdentifiers(
+ SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WeakIDs) {
+ if (WeakUndeclaredIdentifiers.empty())
+ return;
+
+ for (unsigned I = 0, N = WeakUndeclaredIdentifiers.size(); I < N; /*none*/) {
+ IdentifierInfo *WeakId
+ = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
+ IdentifierInfo *AliasId
+ = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
+ SourceLocation Loc
+ = SourceLocation::getFromRawEncoding(WeakUndeclaredIdentifiers[I++]);
+ bool Used = WeakUndeclaredIdentifiers[I++];
+ WeakInfo WI(AliasId, Loc);
+ WI.setUsed(Used);
+ WeakIDs.push_back(std::make_pair(WeakId, WI));
+ }
+ WeakUndeclaredIdentifiers.clear();
+}
+
+void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {
+ for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) {
+ ExternalVTableUse VT;
+ VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
+ VT.Location = SourceLocation::getFromRawEncoding(VTableUses[Idx++]);
+ VT.DefinitionRequired = VTableUses[Idx++];
+ VTables.push_back(VT);
+ }
+
+ VTableUses.clear();
+}
+
+void ASTReader::ReadPendingInstantiations(
+ SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending) {
+ for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {
+ ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
+ SourceLocation Loc
+ = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
+ Pending.push_back(std::make_pair(D, Loc));
+ }
+ PendingInstantiations.clear();
+}
+
void ASTReader::LoadSelector(Selector Sel) {
// It would be complicated to avoid reading the methods anyway. So don't.
ReadMethodPool(Sel);
}
-void ASTReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
+void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) {
assert(ID && "Non-zero identifier ID required");
assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
IdentifiersLoaded[ID - 1] = II;
@@ -4500,7 +4724,7 @@ void ASTReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
/// will not be placed onto the pending queue.
void
ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
- const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
+ const SmallVectorImpl<uint32_t> &DeclIDs,
bool Nonrecursive) {
if (NumCurrentElementsDeserializing && !Nonrecursive) {
PendingIdentifierInfos.push_back(PendingIdentifierInfo());
@@ -4529,7 +4753,7 @@ ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
}
}
-IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
+IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {
if (ID == 0)
return 0;
@@ -4538,21 +4762,13 @@ IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
return 0;
}
- assert(PP && "Forgot to set Preprocessor ?");
ID -= 1;
if (!IdentifiersLoaded[ID]) {
- unsigned Index = ID;
- const char *Str = 0;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- PerFileData *F = Chain[N - I - 1];
- if (Index < F->LocalNumIdentifiers) {
- uint32_t Offset = F->IdentifierOffsets[Index];
- Str = F->IdentifierTableData + Offset;
- break;
- }
- Index -= F->LocalNumIdentifiers;
- }
- assert(Str && "Broken Chain");
+ GlobalIdentifierMapType::iterator I = GlobalIdentifierMap.find(ID + 1);
+ assert(I != GlobalIdentifierMap.end() && "Corrupted global identifier map");
+ Module *M = I->second;
+ unsigned Index = ID - M->BaseIdentifierID;
+ const char *Str = M->IdentifierTableData + M->IdentifierOffsets[Index];
// All of the strings in the AST file are preceded by a 16-bit length.
// Extract that 16-bit length to avoid having to execute strlen().
@@ -4563,7 +4779,7 @@ IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
unsigned StrLen = (((unsigned) StrLenPtr[0])
| (((unsigned) StrLenPtr[1]) << 8)) - 1;
IdentifiersLoaded[ID]
- = &PP->getIdentifierTable().get(llvm::StringRef(Str, StrLen));
+ = &PP.getIdentifierTable().get(StringRef(Str, StrLen));
if (DeserializationListener)
DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
}
@@ -4571,11 +4787,31 @@ IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) {
return IdentifiersLoaded[ID];
}
-bool ASTReader::ReadSLocEntry(unsigned ID) {
+IdentifierInfo *ASTReader::getLocalIdentifier(Module &M, unsigned LocalID) {
+ return DecodeIdentifierInfo(getGlobalIdentifierID(M, LocalID));
+}
+
+IdentifierID ASTReader::getGlobalIdentifierID(Module &M, unsigned LocalID) {
+ if (LocalID < NUM_PREDEF_IDENT_IDS)
+ return LocalID;
+
+ ContinuousRangeMap<uint32_t, int, 2>::iterator I
+ = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS);
+ assert(I != M.IdentifierRemap.end()
+ && "Invalid index into identifier index remap");
+
+ return LocalID + I->second;
+}
+
+bool ASTReader::ReadSLocEntry(int ID) {
return ReadSLocEntryRecord(ID) != Success;
}
-Selector ASTReader::DecodeSelector(unsigned ID) {
+Selector ASTReader::getLocalSelector(Module &M, unsigned LocalID) {
+ return DecodeSelector(getGlobalSelectorID(M, LocalID));
+}
+
+Selector ASTReader::DecodeSelector(serialization::SelectorID ID) {
if (ID == 0)
return Selector();
@@ -4586,25 +4822,21 @@ Selector ASTReader::DecodeSelector(unsigned ID) {
if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
// Load this selector from the selector table.
- unsigned Idx = ID - 1;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- PerFileData &F = *Chain[N - I - 1];
- if (Idx < F.LocalNumSelectors) {
- ASTSelectorLookupTrait Trait(*this);
- SelectorsLoaded[ID - 1] =
- Trait.ReadKey(F.SelectorLookupTableData + F.SelectorOffsets[Idx], 0);
- if (DeserializationListener)
- DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
- break;
- }
- Idx -= F.LocalNumSelectors;
- }
+ GlobalSelectorMapType::iterator I = GlobalSelectorMap.find(ID);
+ assert(I != GlobalSelectorMap.end() && "Corrupted global selector map");
+ Module &M = *I->second;
+ ASTSelectorLookupTrait Trait(*this, M);
+ unsigned Idx = ID - M.BaseSelectorID - NUM_PREDEF_SELECTOR_IDS;
+ SelectorsLoaded[ID - 1] =
+ Trait.ReadKey(M.SelectorLookupTableData + M.SelectorOffsets[Idx], 0);
+ if (DeserializationListener)
+ DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
}
return SelectorsLoaded[ID - 1];
}
-Selector ASTReader::GetExternalSelector(uint32_t ID) {
+Selector ASTReader::GetExternalSelector(serialization::SelectorID ID) {
return DecodeSelector(ID);
}
@@ -4613,37 +4845,51 @@ uint32_t ASTReader::GetNumExternalSelectors() {
return getTotalNumSelectors() + 1;
}
+serialization::SelectorID
+ASTReader::getGlobalSelectorID(Module &M, unsigned LocalID) const {
+ if (LocalID < NUM_PREDEF_SELECTOR_IDS)
+ return LocalID;
+
+ ContinuousRangeMap<uint32_t, int, 2>::iterator I
+ = M.SelectorRemap.find(LocalID - NUM_PREDEF_SELECTOR_IDS);
+ assert(I != M.SelectorRemap.end()
+ && "Invalid index into identifier index remap");
+
+ return LocalID + I->second;
+}
+
DeclarationName
-ASTReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
+ASTReader::ReadDeclarationName(Module &F,
+ const RecordData &Record, unsigned &Idx) {
DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
switch (Kind) {
case DeclarationName::Identifier:
- return DeclarationName(GetIdentifierInfo(Record, Idx));
+ return DeclarationName(GetIdentifierInfo(F, Record, Idx));
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
- return DeclarationName(GetSelector(Record, Idx));
+ return DeclarationName(ReadSelector(F, Record, Idx));
case DeclarationName::CXXConstructorName:
- return Context->DeclarationNames.getCXXConstructorName(
- Context->getCanonicalType(GetType(Record[Idx++])));
+ return Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(readType(F, Record, Idx)));
case DeclarationName::CXXDestructorName:
- return Context->DeclarationNames.getCXXDestructorName(
- Context->getCanonicalType(GetType(Record[Idx++])));
+ return Context.DeclarationNames.getCXXDestructorName(
+ Context.getCanonicalType(readType(F, Record, Idx)));
case DeclarationName::CXXConversionFunctionName:
- return Context->DeclarationNames.getCXXConversionFunctionName(
- Context->getCanonicalType(GetType(Record[Idx++])));
+ return Context.DeclarationNames.getCXXConversionFunctionName(
+ Context.getCanonicalType(readType(F, Record, Idx)));
case DeclarationName::CXXOperatorName:
- return Context->DeclarationNames.getCXXOperatorName(
+ return Context.DeclarationNames.getCXXOperatorName(
(OverloadedOperatorKind)Record[Idx++]);
case DeclarationName::CXXLiteralOperatorName:
- return Context->DeclarationNames.getCXXLiteralOperatorName(
- GetIdentifierInfo(Record, Idx));
+ return Context.DeclarationNames.getCXXLiteralOperatorName(
+ GetIdentifierInfo(F, Record, Idx));
case DeclarationName::CXXUsingDirective:
return DeclarationName::getUsingDirectiveName();
@@ -4653,7 +4899,7 @@ ASTReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
return DeclarationName();
}
-void ASTReader::ReadDeclarationNameLoc(PerFileData &F,
+void ASTReader::ReadDeclarationNameLoc(Module &F,
DeclarationNameLoc &DNLoc,
DeclarationName Name,
const RecordData &Record, unsigned &Idx) {
@@ -4685,72 +4931,73 @@ void ASTReader::ReadDeclarationNameLoc(PerFileData &F,
}
}
-void ASTReader::ReadDeclarationNameInfo(PerFileData &F,
+void ASTReader::ReadDeclarationNameInfo(Module &F,
DeclarationNameInfo &NameInfo,
const RecordData &Record, unsigned &Idx) {
- NameInfo.setName(ReadDeclarationName(Record, Idx));
+ NameInfo.setName(ReadDeclarationName(F, 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,
+void ASTReader::ReadQualifierInfo(Module &F, QualifierInfo &Info,
const RecordData &Record, unsigned &Idx) {
Info.QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);
unsigned NumTPLists = Record[Idx++];
Info.NumTemplParamLists = NumTPLists;
if (NumTPLists) {
- Info.TemplParamLists = new (*Context) TemplateParameterList*[NumTPLists];
+ Info.TemplParamLists = new (Context) TemplateParameterList*[NumTPLists];
for (unsigned i=0; i != NumTPLists; ++i)
Info.TemplParamLists[i] = ReadTemplateParameterList(F, Record, Idx);
}
}
TemplateName
-ASTReader::ReadTemplateName(PerFileData &F, const RecordData &Record,
+ASTReader::ReadTemplateName(Module &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++])));
+ return TemplateName(ReadDeclAs<TemplateDecl>(F, Record, Idx));
case TemplateName::OverloadedTemplate: {
unsigned size = Record[Idx++];
UnresolvedSet<8> Decls;
while (size--)
- Decls.addDecl(cast<NamedDecl>(GetDecl(Record[Idx++])));
+ Decls.addDecl(ReadDeclAs<NamedDecl>(F, Record, Idx));
- return Context->getOverloadedTemplateName(Decls.begin(), Decls.end());
+ return Context.getOverloadedTemplateName(Decls.begin(), Decls.end());
}
case TemplateName::QualifiedTemplate: {
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+ NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
bool hasTemplKeyword = Record[Idx++];
- TemplateDecl *Template = cast<TemplateDecl>(GetDecl(Record[Idx++]));
- return Context->getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
+ TemplateDecl *Template = ReadDeclAs<TemplateDecl>(F, Record, Idx);
+ return Context.getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
}
case TemplateName::DependentTemplate: {
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
+ NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
if (Record[Idx++]) // isIdentifier
- return Context->getDependentTemplateName(NNS,
- GetIdentifierInfo(Record, Idx));
- return Context->getDependentTemplateName(NNS,
+ return Context.getDependentTemplateName(NNS,
+ GetIdentifierInfo(F, Record,
+ Idx));
+ return Context.getDependentTemplateName(NNS,
(OverloadedOperatorKind)Record[Idx++]);
}
case TemplateName::SubstTemplateTemplateParm: {
TemplateTemplateParmDecl *param
- = cast_or_null<TemplateTemplateParmDecl>(GetDecl(Record[Idx++]));
+ = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
if (!param) return TemplateName();
TemplateName replacement = ReadTemplateName(F, Record, Idx);
- return Context->getSubstTemplateTemplateParm(param, replacement);
+ return Context.getSubstTemplateTemplateParm(param, replacement);
}
case TemplateName::SubstTemplateTemplateParmPack: {
TemplateTemplateParmDecl *Param
- = cast_or_null<TemplateTemplateParmDecl>(GetDecl(Record[Idx++]));
+ = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
if (!Param)
return TemplateName();
@@ -4758,28 +5005,27 @@ ASTReader::ReadTemplateName(PerFileData &F, const RecordData &Record,
if (ArgPack.getKind() != TemplateArgument::Pack)
return TemplateName();
- return Context->getSubstTemplateTemplateParmPack(Param, ArgPack);
+ return Context.getSubstTemplateTemplateParmPack(Param, ArgPack);
}
}
- assert(0 && "Unhandled template name kind!");
- return TemplateName();
+ llvm_unreachable("Unhandled template name kind!");
}
TemplateArgument
-ASTReader::ReadTemplateArgument(PerFileData &F,
+ASTReader::ReadTemplateArgument(Module &F,
const RecordData &Record, unsigned &Idx) {
TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++];
switch (Kind) {
case TemplateArgument::Null:
return TemplateArgument();
case TemplateArgument::Type:
- return TemplateArgument(GetType(Record[Idx++]));
+ return TemplateArgument(readType(F, Record, Idx));
case TemplateArgument::Declaration:
- return TemplateArgument(GetDecl(Record[Idx++]));
+ return TemplateArgument(ReadDecl(F, Record, Idx));
case TemplateArgument::Integral: {
llvm::APSInt Value = ReadAPSInt(Record, Idx);
- QualType T = GetType(Record[Idx++]);
+ QualType T = readType(F, Record, Idx);
return TemplateArgument(Value, T);
}
case TemplateArgument::Template:
@@ -4795,40 +5041,39 @@ ASTReader::ReadTemplateArgument(PerFileData &F,
return TemplateArgument(ReadExpr(F));
case TemplateArgument::Pack: {
unsigned NumArgs = Record[Idx++];
- TemplateArgument *Args = new (*Context) TemplateArgument[NumArgs];
+ 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();
+ llvm_unreachable("Unhandled template argument kind!");
}
TemplateParameterList *
-ASTReader::ReadTemplateParameterList(PerFileData &F,
+ASTReader::ReadTemplateParameterList(Module &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;
+ SmallVector<NamedDecl *, 16> Params;
Params.reserve(NumParams);
while (NumParams--)
- Params.push_back(cast<NamedDecl>(GetDecl(Record[Idx++])));
+ Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx));
TemplateParameterList* TemplateParams =
- TemplateParameterList::Create(*Context, TemplateLoc, LAngleLoc,
+ TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,
Params.data(), Params.size(), RAngleLoc);
return TemplateParams;
}
void
ASTReader::
-ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
- PerFileData &F, const RecordData &Record,
+ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs,
+ Module &F, const RecordData &Record,
unsigned &Idx) {
unsigned NumTemplateArgs = Record[Idx++];
TemplArgs.reserve(NumTemplateArgs);
@@ -4837,18 +5082,18 @@ ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
}
/// \brief Read a UnresolvedSet structure.
-void ASTReader::ReadUnresolvedSet(UnresolvedSetImpl &Set,
+void ASTReader::ReadUnresolvedSet(Module &F, UnresolvedSetImpl &Set,
const RecordData &Record, unsigned &Idx) {
unsigned NumDecls = Record[Idx++];
while (NumDecls--) {
- NamedDecl *D = cast<NamedDecl>(GetDecl(Record[Idx++]));
+ NamedDecl *D = ReadDeclAs<NamedDecl>(F, Record, Idx);
AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
Set.addDecl(D, AS);
}
}
CXXBaseSpecifier
-ASTReader::ReadCXXBaseSpecifier(PerFileData &F,
+ASTReader::ReadCXXBaseSpecifier(Module &F,
const RecordData &Record, unsigned &Idx) {
bool isVirtual = static_cast<bool>(Record[Idx++]);
bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
@@ -4864,15 +5109,13 @@ ASTReader::ReadCXXBaseSpecifier(PerFileData &F,
}
std::pair<CXXCtorInitializer **, unsigned>
-ASTReader::ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record,
+ASTReader::ReadCXXCtorInitializers(Module &F, const RecordData &Record,
unsigned &Idx) {
CXXCtorInitializer **CtorInitializers = 0;
unsigned NumInitializers = Record[Idx++];
if (NumInitializers) {
- ASTContext &C = *getContext();
-
CtorInitializers
- = new (C) CXXCtorInitializer*[NumInitializers];
+ = new (Context) CXXCtorInitializer*[NumInitializers];
for (unsigned i=0; i != NumInitializers; ++i) {
TypeSourceInfo *BaseClassInfo = 0;
bool IsBaseVirtual = false;
@@ -4888,15 +5131,15 @@ ASTReader::ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record,
break;
case CTOR_INITIALIZER_DELEGATING:
- Target = cast<CXXConstructorDecl>(GetDecl(Record[Idx++]));
+ Target = ReadDeclAs<CXXConstructorDecl>(F, Record, Idx);
break;
case CTOR_INITIALIZER_MEMBER:
- Member = cast<FieldDecl>(GetDecl(Record[Idx++]));
+ Member = ReadDeclAs<FieldDecl>(F, Record, Idx);
break;
case CTOR_INITIALIZER_INDIRECT_MEMBER:
- IndirectMember = cast<IndirectFieldDecl>(GetDecl(Record[Idx++]));
+ IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx);
break;
}
@@ -4906,34 +5149,34 @@ ASTReader::ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record,
SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx);
bool IsWritten = Record[Idx++];
unsigned SourceOrderOrNumArrayIndices;
- llvm::SmallVector<VarDecl *, 8> Indices;
+ SmallVector<VarDecl *, 8> Indices;
if (IsWritten) {
SourceOrderOrNumArrayIndices = Record[Idx++];
} else {
SourceOrderOrNumArrayIndices = Record[Idx++];
Indices.reserve(SourceOrderOrNumArrayIndices);
for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i)
- Indices.push_back(cast<VarDecl>(GetDecl(Record[Idx++])));
+ Indices.push_back(ReadDeclAs<VarDecl>(F, Record, Idx));
}
CXXCtorInitializer *BOMInit;
if (Type == CTOR_INITIALIZER_BASE) {
- BOMInit = new (C) CXXCtorInitializer(C, BaseClassInfo, IsBaseVirtual,
+ BOMInit = new (Context) CXXCtorInitializer(Context, BaseClassInfo, IsBaseVirtual,
LParenLoc, Init, RParenLoc,
MemberOrEllipsisLoc);
} else if (Type == CTOR_INITIALIZER_DELEGATING) {
- BOMInit = new (C) CXXCtorInitializer(C, MemberOrEllipsisLoc, LParenLoc,
+ BOMInit = new (Context) CXXCtorInitializer(Context, MemberOrEllipsisLoc, LParenLoc,
Target, Init, RParenLoc);
} else if (IsWritten) {
if (Member)
- BOMInit = new (C) CXXCtorInitializer(C, Member, MemberOrEllipsisLoc,
+ BOMInit = new (Context) CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc,
LParenLoc, Init, RParenLoc);
else
- BOMInit = new (C) CXXCtorInitializer(C, IndirectMember,
+ BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember,
MemberOrEllipsisLoc, LParenLoc,
Init, RParenLoc);
} else {
- BOMInit = CXXCtorInitializer::Create(C, Member, MemberOrEllipsisLoc,
+ BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc,
LParenLoc, Init, RParenLoc,
Indices.data(), Indices.size());
}
@@ -4948,7 +5191,8 @@ ASTReader::ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record,
}
NestedNameSpecifier *
-ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
+ASTReader::ReadNestedNameSpecifier(Module &F,
+ const RecordData &Record, unsigned &Idx) {
unsigned N = Record[Idx++];
NestedNameSpecifier *NNS = 0, *Prev = 0;
for (unsigned I = 0; I != N; ++I) {
@@ -4956,37 +5200,36 @@ ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
= (NestedNameSpecifier::SpecifierKind)Record[Idx++];
switch (Kind) {
case NestedNameSpecifier::Identifier: {
- IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
- NNS = NestedNameSpecifier::Create(*Context, Prev, II);
+ IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);
+ NNS = NestedNameSpecifier::Create(Context, Prev, II);
break;
}
case NestedNameSpecifier::Namespace: {
- NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
- NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
+ NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);
+ NNS = NestedNameSpecifier::Create(Context, Prev, NS);
break;
}
case NestedNameSpecifier::NamespaceAlias: {
- NamespaceAliasDecl *Alias
- = cast<NamespaceAliasDecl>(GetDecl(Record[Idx++]));
- NNS = NestedNameSpecifier::Create(*Context, Prev, Alias);
+ NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);
+ NNS = NestedNameSpecifier::Create(Context, Prev, Alias);
break;
}
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
- const Type *T = GetType(Record[Idx++]).getTypePtrOrNull();
+ const Type *T = readType(F, Record, Idx).getTypePtrOrNull();
if (!T)
return 0;
bool Template = Record[Idx++];
- NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
+ NNS = NestedNameSpecifier::Create(Context, Prev, Template, T);
break;
}
case NestedNameSpecifier::Global: {
- NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
+ NNS = NestedNameSpecifier::GlobalSpecifier(Context);
// No associated value, and there can't be a prefix.
break;
}
@@ -4997,7 +5240,7 @@ ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
}
NestedNameSpecifierLoc
-ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record,
+ASTReader::ReadNestedNameSpecifierLoc(Module &F, const RecordData &Record,
unsigned &Idx) {
unsigned N = Record[Idx++];
NestedNameSpecifierLocBuilder Builder;
@@ -5006,24 +5249,23 @@ ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record,
= (NestedNameSpecifier::SpecifierKind)Record[Idx++];
switch (Kind) {
case NestedNameSpecifier::Identifier: {
- IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
+ IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);
SourceRange Range = ReadSourceRange(F, Record, Idx);
- Builder.Extend(*Context, II, Range.getBegin(), Range.getEnd());
+ Builder.Extend(Context, II, Range.getBegin(), Range.getEnd());
break;
}
case NestedNameSpecifier::Namespace: {
- NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
+ NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);
SourceRange Range = ReadSourceRange(F, Record, Idx);
- Builder.Extend(*Context, NS, Range.getBegin(), Range.getEnd());
+ Builder.Extend(Context, NS, Range.getBegin(), Range.getEnd());
break;
}
case NestedNameSpecifier::NamespaceAlias: {
- NamespaceAliasDecl *Alias
- = cast<NamespaceAliasDecl>(GetDecl(Record[Idx++]));
+ NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);
SourceRange Range = ReadSourceRange(F, Record, Idx);
- Builder.Extend(*Context, Alias, Range.getBegin(), Range.getEnd());
+ Builder.Extend(Context, Alias, Range.getBegin(), Range.getEnd());
break;
}
@@ -5036,7 +5278,7 @@ ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record,
SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
// FIXME: 'template' keyword location not saved anywhere, so we fake it.
- Builder.Extend(*Context,
+ Builder.Extend(Context,
Template? T->getTypeLoc().getBeginLoc() : SourceLocation(),
T->getTypeLoc(), ColonColonLoc);
break;
@@ -5044,17 +5286,17 @@ ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record,
case NestedNameSpecifier::Global: {
SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
- Builder.MakeGlobal(*Context, ColonColonLoc);
+ Builder.MakeGlobal(Context, ColonColonLoc);
break;
}
}
}
- return Builder.getWithLocInContext(*Context);
+ return Builder.getWithLocInContext(Context);
}
SourceRange
-ASTReader::ReadSourceRange(PerFileData &F, const RecordData &Record,
+ASTReader::ReadSourceRange(Module &F, const RecordData &Record,
unsigned &Idx) {
SourceLocation beg = ReadSourceLocation(F, Record, Idx);
SourceLocation end = ReadSourceLocation(F, Record, Idx);
@@ -5101,10 +5343,11 @@ VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record,
return VersionTuple(Major, Minor - 1, Subminor - 1);
}
-CXXTemporary *ASTReader::ReadCXXTemporary(const RecordData &Record,
+CXXTemporary *ASTReader::ReadCXXTemporary(Module &F,
+ const RecordData &Record,
unsigned &Idx) {
- CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++]));
- return CXXTemporary::Create(*Context, Decl);
+ CXXDestructorDecl *Decl = ReadDeclAs<CXXDestructorDecl>(F, Record, Idx);
+ return CXXTemporary::Create(Context, Decl);
}
DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
@@ -5118,8 +5361,7 @@ DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
/// \brief Retrieve the identifier table associated with the
/// preprocessor.
IdentifierTable &ASTReader::getIdentifierTable() {
- assert(PP && "Forgot to set Preprocessor ?");
- return PP->getIdentifierTable();
+ return PP.getIdentifierTable();
}
/// \brief Record that the given ID maps to the given switch-case
@@ -5169,56 +5411,29 @@ void ASTReader::FinishedDeserializing() {
--NumCurrentElementsDeserializing;
}
-ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
- const char *isysroot, bool DisableValidation,
+ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
+ StringRef 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),
+ Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context),
+ Consumer(0), ModuleMgr(FileMgr.getFileSystemOptions()),
+ RelocatablePCH(false), isysroot(isysroot),
+ DisableValidation(DisableValidation),
DisableStatCache(DisableStatCache), NumStatHits(0), NumStatMisses(0),
- NumSLocEntriesRead(0), TotalNumSLocEntries(0), NextSLocOffset(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)
+ NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
+ TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),
+ NumCXXBaseSpecifiersLoaded(0)
{
- RelocatablePCH = false;
-}
-
-ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
- Diagnostic &Diags, const char *isysroot,
- bool DisableValidation, bool DisableStatCache)
- : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
- Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(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;
+ SourceMgr.setExternalSLocEntrySource(this);
}
ASTReader::~ASTReader() {
- for (unsigned i = 0, e = Chain.size(); i != e; ++i)
- delete Chain[e - i - 1];
- // Delete all visible decl lookup tables
- for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
- E = DeclContextOffsets.end();
- I != E; ++I) {
- for (DeclContextInfos::iterator J = I->second.begin(), F = I->second.end();
- J != F; ++J) {
- if (J->NameLookupTableData)
- delete static_cast<ASTDeclContextNameLookupTable*>(
- J->NameLookupTableData);
- }
- }
for (DeclContextVisibleUpdatesPending::iterator
I = PendingVisibleUpdates.begin(),
E = PendingVisibleUpdates.end();
@@ -5226,27 +5441,6 @@ ASTReader::~ASTReader() {
for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
F = I->second.end();
J != F; ++J)
- delete static_cast<ASTDeclContextNameLookupTable*>(*J);
- }
-}
-
-ASTReader::PerFileData::PerFileData(ASTFileType Ty)
- : Type(Ty), SizeInBits(0), LocalNumSLocEntries(0), SLocOffsets(0),
- SLocFileOffsets(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);
+ delete static_cast<ASTDeclContextNameLookupTable*>(J->first);
+ }
}
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp
index 24ab544..6cc3f0a 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -14,6 +14,7 @@
#include "ASTCommon.h"
#include "clang/Serialization/ASTReader.h"
+#include "clang/Sema/SemaDiagnostic.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclVisitor.h"
@@ -31,7 +32,7 @@ using namespace clang::serialization;
namespace clang {
class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {
ASTReader &Reader;
- ASTReader::PerFileData &F;
+ Module &F;
llvm::BitstreamCursor &Cursor;
const DeclID ThisDeclID;
typedef ASTReader::RecordData RecordData;
@@ -43,23 +44,42 @@ namespace clang {
DeclID LexicalDeclContextIDForTemplateParmDecl;
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);
}
+
+ serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
+ return Reader.ReadDeclID(F, R, I);
+ }
+
+ Decl *ReadDecl(const RecordData &R, unsigned &I) {
+ return Reader.ReadDecl(F, R, I);
+ }
+
+ template<typename T>
+ T *ReadDeclAs(const RecordData &R, unsigned &I) {
+ return Reader.ReadDeclAs<T>(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);
@@ -72,7 +92,7 @@ namespace clang {
CXXRecordDecl *DefinitionDecl,
const RecordData &Record, unsigned &Idx);
public:
- ASTDeclReader(ASTReader &Reader, ASTReader::PerFileData &F,
+ ASTDeclReader(ASTReader &Reader, Module &F,
llvm::BitstreamCursor &Cursor, DeclID thisDeclID,
const RecordData &Record, unsigned &Idx)
: Reader(Reader), F(F), Cursor(Cursor), ThisDeclID(thisDeclID),
@@ -82,9 +102,14 @@ namespace clang {
void Visit(Decl *D);
- void UpdateDecl(Decl *D, ASTReader::PerFileData &Module,
+ void UpdateDecl(Decl *D, Module &Module,
const RecordData &Record);
+ static void setNextObjCCategory(ObjCCategoryDecl *Cat,
+ ObjCCategoryDecl *Next) {
+ Cat->NextClassCategory = Next;
+ }
+
void VisitDecl(Decl *D);
void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
void VisitNamedDecl(NamedDecl *ND);
@@ -104,6 +129,8 @@ namespace clang {
ClassTemplateSpecializationDecl *D);
void VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D);
+ void VisitClassScopeFunctionSpecializationDecl(
+ ClassScopeFunctionSpecializationDecl *D);
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
void VisitValueDecl(ValueDecl *VD);
void VisitEnumConstantDecl(EnumConstantDecl *ECD);
@@ -159,16 +186,7 @@ namespace clang {
}
uint64_t ASTDeclReader::GetCurrentCursorOffset() {
- uint64_t Off = 0;
- for (unsigned I = 0, N = Reader.Chain.size(); I != N; ++I) {
- ASTReader::PerFileData &F = *Reader.Chain[N - I - 1];
- if (&Cursor == &F.DeclsCursor) {
- Off += F.DeclsCursor.GetCurrentBitNo();
- break;
- }
- Off += F.SizeInBits;
- }
- return Off;
+ return F.DeclsCursor.GetCurrentBitNo() + F.GlobalBitOffset;
}
void ASTDeclReader::Visit(Decl *D) {
@@ -211,13 +229,12 @@ void ASTDeclReader::VisitDecl(Decl *D) {
// parameter immediately, because the template parameter might be
// used in the formulation of its DeclContext. Use the translation
// unit DeclContext as a placeholder.
- DeclContextIDForTemplateParmDecl = Record[Idx++];
- LexicalDeclContextIDForTemplateParmDecl = Record[Idx++];
- D->setDeclContext(Reader.getContext()->getTranslationUnitDecl());
+ DeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ LexicalDeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
+ D->setDeclContext(Reader.getContext().getTranslationUnitDecl());
} else {
- D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
- D->setLexicalDeclContext(
- cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
+ D->setDeclContext(ReadDeclAs<DeclContext>(Record, Idx));
+ D->setLexicalDeclContext(ReadDeclAs<DeclContext>(Record, Idx));
}
D->setLocation(ReadSourceLocation(Record, Idx));
D->setInvalidDecl(Record[Idx++]);
@@ -230,25 +247,24 @@ void ASTDeclReader::VisitDecl(Decl *D) {
D->setUsed(Record[Idx++]);
D->setReferenced(Record[Idx++]);
D->setAccess((AccessSpecifier)Record[Idx++]);
- D->setPCHLevel(Record[Idx++] + (F.Type <= ASTReader::PCH));
+ D->FromASTFile = true;
+ D->ModulePrivate = Record[Idx++];
}
void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
- VisitDecl(TU);
- TU->setAnonymousNamespace(
- cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+ llvm_unreachable("Translation units are not serialized");
}
void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {
VisitDecl(ND);
- ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
+ ND->setDeclName(Reader.ReadDeclarationName(F, Record, Idx));
}
void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
VisitNamedDecl(TD);
TD->setLocStart(ReadSourceLocation(Record, Idx));
// Delay type reading until after we have fully initialized the decl.
- TypeIDForTypeDecl = Record[Idx++];
+ TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
}
void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
@@ -266,16 +282,16 @@ void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
VisitRedeclarable(TD);
TD->IdentifierNamespace = Record[Idx++];
TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
- TD->setDefinition(Record[Idx++]);
+ TD->setCompleteDefinition(Record[Idx++]);
TD->setEmbeddedInDeclarator(Record[Idx++]);
+ TD->setFreeStanding(Record[Idx++]);
TD->setRBraceLoc(ReadSourceLocation(Record, Idx));
if (Record[Idx++]) { // hasExtInfo
- TagDecl::ExtInfo *Info = new (*Reader.getContext()) TagDecl::ExtInfo();
+ TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo();
ReadQualifierInfo(*Info, Record, Idx);
TD->TypedefNameDeclOrQualifier = Info;
} else
- TD->setTypedefNameForAnonDecl(
- cast_or_null<TypedefNameDecl>(Reader.GetDecl(Record[Idx++])));
+ TD->setTypedefNameForAnonDecl(ReadDeclAs<TypedefNameDecl>(Record, Idx));
}
void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
@@ -283,15 +299,14 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
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->setIntegerType(Reader.readType(F, Record, Idx));
+ ED->setPromotionType(Reader.readType(F, 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++])));
+ ED->setInstantiationOfMemberEnum(ReadDeclAs<EnumDecl>(Record, Idx));
}
void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
@@ -303,7 +318,7 @@ void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {
VisitNamedDecl(VD);
- VD->setType(Reader.GetType(Record[Idx++]));
+ VD->setType(Reader.readType(F, Record, Idx));
}
void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
@@ -318,7 +333,7 @@ void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
DD->setInnerLocStart(ReadSourceLocation(Record, Idx));
if (Record[Idx++]) { // hasExtInfo
DeclaratorDecl::ExtInfo *Info
- = new (*Reader.getContext()) DeclaratorDecl::ExtInfo();
+ = new (Reader.getContext()) DeclaratorDecl::ExtInfo();
ReadQualifierInfo(*Info, Record, Idx);
DD->DeclInfo = Info;
}
@@ -331,35 +346,35 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName(), Record, Idx);
FD->IdentifierNamespace = Record[Idx++];
switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
- default: assert(false && "Unhandled TemplatedKind!");
- break;
+ default: llvm_unreachable("Unhandled TemplatedKind!");
case FunctionDecl::TK_NonTemplate:
break;
case FunctionDecl::TK_FunctionTemplate:
- FD->setDescribedFunctionTemplate(
- cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++])));
+ FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>(Record,
+ Idx));
break;
case FunctionDecl::TK_MemberSpecialization: {
- FunctionDecl *InstFD = cast<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
+ FunctionDecl *InstFD = ReadDeclAs<FunctionDecl>(Record, Idx);
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
SourceLocation POI = ReadSourceLocation(Record, Idx);
- FD->setInstantiationOfMemberFunction(*Reader.getContext(), InstFD, TSK);
+ FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
break;
}
case FunctionDecl::TK_FunctionTemplateSpecialization: {
- FunctionTemplateDecl *Template
- = cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ FunctionTemplateDecl *Template = ReadDeclAs<FunctionTemplateDecl>(Record,
+ Idx);
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
// Template arguments.
- llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+ SmallVector<TemplateArgument, 8> TemplArgs;
Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
// Template args as written.
- llvm::SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
+ SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
SourceLocation LAngleLoc, RAngleLoc;
- if (Record[Idx++]) { // TemplateArgumentsAsWritten != 0
+ bool HasTemplateArgumentsAsWritten = Record[Idx++];
+ if (HasTemplateArgumentsAsWritten) {
unsigned NumTemplateArgLocs = Record[Idx++];
TemplArgLocs.reserve(NumTemplateArgLocs);
for (unsigned i=0; i != NumTemplateArgLocs; ++i)
@@ -372,24 +387,24 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
SourceLocation POI = ReadSourceLocation(Record, Idx);
- ASTContext &C = *Reader.getContext();
+ ASTContext &C = Reader.getContext();
TemplateArgumentList *TemplArgList
= TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size());
- TemplateArgumentListInfo *TemplArgsInfo
- = new (C) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
+ TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i)
- TemplArgsInfo->addArgument(TemplArgLocs[i]);
+ TemplArgsInfo.addArgument(TemplArgLocs[i]);
FunctionTemplateSpecializationInfo *FTInfo
= FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK,
TemplArgList,
- TemplArgsInfo, POI);
+ HasTemplateArgumentsAsWritten ? &TemplArgsInfo : 0,
+ 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++]));
+ = ReadDeclAs<FunctionTemplateDecl>(Record, Idx);
// Get the InsertPos by FindNodeOrInsertPos() instead of calling
// InsertNode(FTInfo) directly to avoid the getASTContext() call in
// FunctionTemplateSpecializationInfo's Profile().
@@ -410,7 +425,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
UnresolvedSet<8> TemplDecls;
unsigned NumTemplates = Record[Idx++];
while (NumTemplates--)
- TemplDecls.addDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+ TemplDecls.addDecl(ReadDeclAs<NamedDecl>(Record, Idx));
// Templates args.
TemplateArgumentListInfo TemplArgs;
@@ -420,7 +435,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
TemplArgs.setLAngleLoc(ReadSourceLocation(Record, Idx));
TemplArgs.setRAngleLoc(ReadSourceLocation(Record, Idx));
- FD->setDependentTemplateSpecialization(*Reader.getContext(),
+ FD->setDependentTemplateSpecialization(Reader.getContext(),
TemplDecls, TemplArgs);
break;
}
@@ -442,15 +457,16 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->IsDefaulted = Record[Idx++];
FD->IsExplicitlyDefaulted = Record[Idx++];
FD->HasImplicitReturnZero = Record[Idx++];
+ FD->IsConstexpr = Record[Idx++];
FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
// Read in the parameters.
unsigned NumParams = Record[Idx++];
- llvm::SmallVector<ParmVarDecl *, 16> Params;
+ SmallVector<ParmVarDecl *, 16> Params;
Params.reserve(NumParams);
for (unsigned I = 0; I != NumParams; ++I)
- Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- FD->setParams(*Reader.getContext(), Params.data(), NumParams);
+ Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
+ FD->setParams(Reader.getContext(), Params);
}
void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
@@ -459,77 +475,87 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
// In practice, this won't be executed (since method definitions
// don't occur in header files).
MD->setBody(Reader.ReadStmt(F));
- MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
- MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
+ MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
+ MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
}
MD->setInstanceMethod(Record[Idx++]);
MD->setVariadic(Record[Idx++]);
MD->setSynthesized(Record[Idx++]);
MD->setDefined(Record[Idx++]);
+
+ MD->IsRedeclaration = Record[Idx++];
+ MD->HasRedeclaration = Record[Idx++];
+ if (MD->HasRedeclaration)
+ Reader.getContext().setObjCMethodRedeclaration(MD,
+ ReadDeclAs<ObjCMethodDecl>(Record, Idx));
+
MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
MD->SetRelatedResultType(Record[Idx++]);
- MD->setNumSelectorArgs(unsigned(Record[Idx++]));
- MD->setResultType(Reader.GetType(Record[Idx++]));
+ MD->setResultType(Reader.readType(F, Record, Idx));
MD->setResultTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
MD->setEndLoc(ReadSourceLocation(Record, Idx));
unsigned NumParams = Record[Idx++];
- llvm::SmallVector<ParmVarDecl *, 16> Params;
+ SmallVector<ParmVarDecl *, 16> Params;
Params.reserve(NumParams);
for (unsigned I = 0; I != NumParams; ++I)
- Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- MD->setMethodParams(*Reader.getContext(), Params.data(), NumParams,
- NumParams);
+ Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
+
+ MD->SelLocsKind = Record[Idx++];
+ unsigned NumStoredSelLocs = Record[Idx++];
+ SmallVector<SourceLocation, 16> SelLocs;
+ SelLocs.reserve(NumStoredSelLocs);
+ for (unsigned i = 0; i != NumStoredSelLocs; ++i)
+ SelLocs.push_back(ReadSourceLocation(Record, Idx));
+
+ MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs);
}
void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
VisitNamedDecl(CD);
- SourceLocation A = ReadSourceLocation(Record, Idx);
- SourceLocation B = ReadSourceLocation(Record, Idx);
- CD->setAtEndRange(SourceRange(A, B));
+ CD->setAtStartLoc(ReadSourceLocation(Record, Idx));
+ CD->setAtEndRange(ReadSourceRange(Record, Idx));
}
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
VisitObjCContainerDecl(ID);
- ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtrOrNull());
- ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
- (Reader.GetDecl(Record[Idx++])));
+ ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
+ ID->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
// Read the directly referenced protocols and their SourceLocations.
unsigned NumProtocols = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl *, 16> Protocols;
+ SmallVector<ObjCProtocolDecl *, 16> Protocols;
Protocols.reserve(NumProtocols);
for (unsigned I = 0; I != NumProtocols; ++I)
- Protocols.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+ Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+ SmallVector<SourceLocation, 16> ProtoLocs;
ProtoLocs.reserve(NumProtocols);
for (unsigned I = 0; I != NumProtocols; ++I)
ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(),
- *Reader.getContext());
+ Reader.getContext());
// Read the transitive closure of protocols referenced by this class.
NumProtocols = Record[Idx++];
Protocols.clear();
Protocols.reserve(NumProtocols);
for (unsigned I = 0; I != NumProtocols; ++I)
- Protocols.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+ Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
ID->AllReferencedProtocols.set(Protocols.data(), NumProtocols,
- *Reader.getContext());
+ Reader.getContext());
// Read the ivars.
unsigned NumIvars = Record[Idx++];
- llvm::SmallVector<ObjCIvarDecl *, 16> IVars;
+ SmallVector<ObjCIvarDecl *, 16> IVars;
IVars.reserve(NumIvars);
for (unsigned I = 0; I != NumIvars; ++I)
- IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
- ID->setCategoryList(
- cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+ IVars.push_back(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
+ ID->setCategoryList(ReadDeclAs<ObjCCategoryDecl>(Record, Idx));
+
// We will rebuild this list lazily.
ID->setIvarList(0);
ID->setForwardDecl(Record[Idx++]);
ID->setImplicitInterfaceDecl(Record[Idx++]);
- ID->setClassLoc(ReadSourceLocation(Record, Idx));
ID->setSuperClassLoc(ReadSourceLocation(Record, Idx));
ID->setLocEnd(ReadSourceLocation(Record, Idx));
}
@@ -548,16 +574,16 @@ void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
PD->setForwardDecl(Record[Idx++]);
PD->setLocEnd(ReadSourceLocation(Record, Idx));
unsigned NumProtoRefs = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+ SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
ProtoRefs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+ ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+ SmallVector<SourceLocation, 16> ProtoLocs;
ProtoLocs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
- *Reader.getContext());
+ Reader.getContext());
}
void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
@@ -566,57 +592,48 @@ void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
void ASTDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) {
VisitDecl(CD);
- unsigned NumClassRefs = Record[Idx++];
- llvm::SmallVector<ObjCInterfaceDecl *, 16> ClassRefs;
- ClassRefs.reserve(NumClassRefs);
- for (unsigned I = 0; I != NumClassRefs; ++I)
- ClassRefs.push_back(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
- llvm::SmallVector<SourceLocation, 16> SLocs;
- SLocs.reserve(NumClassRefs);
- for (unsigned I = 0; I != NumClassRefs; ++I)
- SLocs.push_back(ReadSourceLocation(Record, Idx));
- CD->setClassList(*Reader.getContext(), ClassRefs.data(), SLocs.data(),
- NumClassRefs);
+ ObjCInterfaceDecl *ClassRef = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
+ SourceLocation SLoc = ReadSourceLocation(Record, Idx);
+ CD->setClass(Reader.getContext(), ClassRef, SLoc);
}
void ASTDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) {
VisitDecl(FPD);
unsigned NumProtoRefs = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+ SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
ProtoRefs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+ ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+ SmallVector<SourceLocation, 16> ProtoLocs;
ProtoLocs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
FPD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
- *Reader.getContext());
+ Reader.getContext());
}
void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
VisitObjCContainerDecl(CD);
- CD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
unsigned NumProtoRefs = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+ SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
ProtoRefs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+ ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+ SmallVector<SourceLocation, 16> ProtoLocs;
ProtoLocs.reserve(NumProtoRefs);
for (unsigned I = 0; I != NumProtoRefs; ++I)
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++])));
+ Reader.getContext());
+ CD->NextClassCategory = ReadDeclAs<ObjCCategoryDecl>(Record, Idx);
CD->setHasSynthBitfield(Record[Idx++]);
- CD->setAtLoc(ReadSourceLocation(Record, Idx));
CD->setCategoryNameLoc(ReadSourceLocation(Record, Idx));
}
void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
VisitNamedDecl(CAD);
- CAD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
}
void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
@@ -631,31 +648,26 @@ void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// FIXME: stable encoding
D->setPropertyImplementation(
(ObjCPropertyDecl::PropertyControl)Record[Idx++]);
- D->setGetterName(Reader.ReadDeclarationName(Record, Idx).getObjCSelector());
- D->setSetterName(Reader.ReadDeclarationName(Record, Idx).getObjCSelector());
- D->setGetterMethodDecl(
- cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
- D->setSetterMethodDecl(
- cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
- D->setPropertyIvarDecl(
- cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setGetterName(Reader.ReadDeclarationName(F,Record, Idx).getObjCSelector());
+ D->setSetterName(Reader.ReadDeclarationName(F,Record, Idx).getObjCSelector());
+ D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
+ D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
+ D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
}
void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
VisitObjCContainerDecl(D);
- D->setClassInterface(
- cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
}
void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
VisitObjCImplDecl(D);
- D->setIdentifier(Reader.GetIdentifierInfo(Record, Idx));
+ D->setIdentifier(Reader.GetIdentifierInfo(F, Record, Idx));
}
void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
VisitObjCImplDecl(D);
- D->setSuperClass(
- cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
llvm::tie(D->IvarInitializers, D->NumIvarInitializers)
= Reader.ReadCXXCtorInitializers(F, Record, Idx);
D->setHasSynthBitfield(Record[Idx++]);
@@ -665,10 +677,8 @@ void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
VisitDecl(D);
D->setAtLoc(ReadSourceLocation(Record, Idx));
- D->setPropertyDecl(
- cast_or_null<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
- D->PropertyIvarDecl =
- cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++]));
+ D->setPropertyDecl(ReadDeclAs<ObjCPropertyDecl>(Record, Idx));
+ D->PropertyIvarDecl = ReadDeclAs<ObjCIvarDecl>(Record, Idx);
D->IvarLoc = ReadSourceLocation(Record, Idx);
D->setGetterCXXConstructor(Reader.ReadExpr(F));
D->setSetterCXXAssignment(Reader.ReadExpr(F));
@@ -683,9 +693,8 @@ void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
else if (BitWidthOrInitializer == 2)
FD->setInClassInitializer(Reader.ReadExpr(F));
if (!FD->getDeclName()) {
- FieldDecl *Tmpl = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]));
- if (Tmpl)
- Reader.getContext()->setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
+ if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>(Record, Idx))
+ Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
}
}
@@ -694,10 +703,10 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
FD->ChainingSize = Record[Idx++];
assert(FD->ChainingSize >= 2 && "Anonymous chaining must be >= 2");
- FD->Chaining = new (*Reader.getContext())NamedDecl*[FD->ChainingSize];
+ 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++]));
+ FD->Chaining[I] = ReadDeclAs<NamedDecl>(Record, Idx);
}
void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
@@ -715,10 +724,10 @@ void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
VD->setInit(Reader.ReadExpr(F));
if (Record[Idx++]) { // HasMemberSpecializationInfo.
- VarDecl *Tmpl = cast<VarDecl>(Reader.GetDecl(Record[Idx++]));
+ VarDecl *Tmpl = ReadDeclAs<VarDecl>(Record, Idx);
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
SourceLocation POI = ReadSourceLocation(Record, Idx);
- Reader.getContext()->setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
+ Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
}
}
@@ -756,18 +765,18 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt(F)));
BD->setSignatureAsWritten(GetTypeSourceInfo(Record, Idx));
unsigned NumParams = Record[Idx++];
- llvm::SmallVector<ParmVarDecl *, 16> Params;
+ 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);
+ Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
+ BD->setParams(Params);
bool capturesCXXThis = Record[Idx++];
unsigned numCaptures = Record[Idx++];
- llvm::SmallVector<BlockDecl::Capture, 16> captures;
+ SmallVector<BlockDecl::Capture, 16> captures;
captures.reserve(numCaptures);
for (unsigned i = 0; i != numCaptures; ++i) {
- VarDecl *decl = cast<VarDecl>(Reader.GetDecl(Record[Idx++]));
+ VarDecl *decl = ReadDeclAs<VarDecl>(Record, Idx);
unsigned flags = Record[Idx++];
bool byRef = (flags & 1);
bool nested = (flags & 2);
@@ -775,7 +784,7 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr));
}
- BD->setCaptures(*Reader.getContext(), captures.begin(),
+ BD->setCaptures(Reader.getContext(), captures.begin(),
captures.end(), capturesCXXThis);
}
@@ -800,9 +809,10 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
D->NextNamespace = Record[Idx++];
bool IsOriginal = Record[Idx++];
+ // FIXME: Modules will likely have trouble with pointing directly at
+ // the original namespace.
D->OrigOrAnonNamespace.setInt(IsOriginal);
- D->OrigOrAnonNamespace.setPointer(
- cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+ D->OrigOrAnonNamespace.setPointer(ReadDeclAs<NamespaceDecl>(Record, Idx));
}
void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
@@ -810,7 +820,7 @@ void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
D->NamespaceLoc = ReadSourceLocation(Record, Idx);
D->IdentLoc = ReadSourceLocation(Record, Idx);
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
- D->Namespace = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ D->Namespace = ReadDeclAs<NamedDecl>(Record, Idx);
}
void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
@@ -818,21 +828,19 @@ void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
D->setUsingLocation(ReadSourceLocation(Record, Idx));
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
- D->FirstUsingShadow = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
+ D->FirstUsingShadow = ReadDeclAs<UsingShadowDecl>(Record, Idx);
D->setTypeName(Record[Idx++]);
- NamedDecl *Pattern = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
- if (Pattern)
- Reader.getContext()->setInstantiatedFromUsingDecl(D, Pattern);
+ if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>(Record, Idx))
+ Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern);
}
void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
VisitNamedDecl(D);
- D->setTargetDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
- D->UsingOrNextShadow = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
- UsingShadowDecl *Pattern
- = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
+ D->setTargetDecl(ReadDeclAs<NamedDecl>(Record, Idx));
+ D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(Record, Idx);
+ UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>(Record, Idx);
if (Pattern)
- Reader.getContext()->setInstantiatedFromUsingShadowDecl(D, Pattern);
+ Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern);
}
void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
@@ -840,8 +848,8 @@ void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
D->UsingLoc = ReadSourceLocation(Record, Idx);
D->NamespaceLoc = ReadSourceLocation(Record, Idx);
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
- D->NominatedNamespace = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
- D->CommonAncestor = cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]));
+ D->NominatedNamespace = ReadDeclAs<NamedDecl>(Record, Idx);
+ D->CommonAncestor = ReadDeclAs<DeclContext>(Record, Idx);
}
void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
@@ -863,7 +871,9 @@ void ASTDeclReader::ReadCXXDefinitionData(
const RecordData &Record, unsigned &Idx) {
Data.UserDeclaredConstructor = Record[Idx++];
Data.UserDeclaredCopyConstructor = Record[Idx++];
+ Data.UserDeclaredMoveConstructor = Record[Idx++];
Data.UserDeclaredCopyAssignment = Record[Idx++];
+ Data.UserDeclaredMoveAssignment = Record[Idx++];
Data.UserDeclaredDestructor = Record[Idx++];
Data.Aggregate = Record[Idx++];
Data.PlainOldData = Record[Idx++];
@@ -877,7 +887,7 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.HasPublicFields = Record[Idx++];
Data.HasMutableFields = Record[Idx++];
Data.HasTrivialDefaultConstructor = Record[Idx++];
- Data.HasConstExprNonCopyMoveConstructor = Record[Idx++];
+ Data.HasConstexprNonCopyMoveConstructor = Record[Idx++];
Data.HasTrivialCopyConstructor = Record[Idx++];
Data.HasTrivialMoveConstructor = Record[Idx++];
Data.HasTrivialCopyAssignment = Record[Idx++];
@@ -888,28 +898,31 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.UserProvidedDefaultConstructor = Record[Idx++];
Data.DeclaredDefaultConstructor = Record[Idx++];
Data.DeclaredCopyConstructor = Record[Idx++];
+ Data.DeclaredMoveConstructor = Record[Idx++];
Data.DeclaredCopyAssignment = Record[Idx++];
+ Data.DeclaredMoveAssignment = Record[Idx++];
Data.DeclaredDestructor = Record[Idx++];
+ Data.FailedImplicitMoveConstructor = Record[Idx++];
+ Data.FailedImplicitMoveAssignment = Record[Idx++];
Data.NumBases = Record[Idx++];
if (Data.NumBases)
- Data.Bases = Reader.GetCXXBaseSpecifiersOffset(Record[Idx++]);
+ Data.Bases = Reader.readCXXBaseSpecifiers(F, Record, Idx);
Data.NumVBases = Record[Idx++];
if (Data.NumVBases)
- Data.VBases = Reader.GetCXXBaseSpecifiersOffset(Record[Idx++]);
+ Data.VBases = Reader.readCXXBaseSpecifiers(F, Record, Idx);
- Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx);
- Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx);
+ Reader.ReadUnresolvedSet(F, Data.Conversions, Record, Idx);
+ Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx);
assert(Data.Definition && "Data.Definition should be already set!");
- Data.FirstFriend
- = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++]));
+ Data.FirstFriend = ReadDeclAs<FriendDecl>(Record, Idx);
}
void ASTDeclReader::InitializeCXXDefinitionData(CXXRecordDecl *D,
CXXRecordDecl *DefinitionDecl,
const RecordData &Record,
unsigned &Idx) {
- ASTContext &C = *Reader.getContext();
+ ASTContext &C = Reader.getContext();
if (D == DefinitionDecl) {
D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
@@ -942,26 +955,24 @@ void ASTDeclReader::InitializeCXXDefinitionData(CXXRecordDecl *D,
void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
VisitRecordDecl(D);
- CXXRecordDecl *DefinitionDecl
- = cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
+ CXXRecordDecl *DefinitionDecl = ReadDeclAs<CXXRecordDecl>(Record, Idx);
InitializeCXXDefinitionData(D, DefinitionDecl, Record, Idx);
- ASTContext &C = *Reader.getContext();
+ ASTContext &C = Reader.getContext();
enum CXXRecKind {
CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
};
switch ((CXXRecKind)Record[Idx++]) {
default:
- assert(false && "Out of sync with ASTDeclWriter::VisitCXXRecordDecl?");
+ llvm_unreachable("Out of sync with ASTDeclWriter::VisitCXXRecordDecl?");
case CXXRecNotTemplate:
break;
case CXXRecTemplate:
- D->TemplateOrInstantiation
- = cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ D->TemplateOrInstantiation = ReadDeclAs<ClassTemplateDecl>(Record, Idx);
break;
case CXXRecMemberSpecialization: {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
+ CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(Record, Idx);
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
SourceLocation POI = ReadSourceLocation(Record, Idx);
MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK);
@@ -973,10 +984,8 @@ void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
// 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)
+ if (D->IsCompleteDefinition) {
+ if (CXXMethodDecl *Key = ReadDeclAs<CXXMethodDecl>(Record, Idx))
C.KeyFunctions[D] = Key;
}
}
@@ -985,10 +994,10 @@ void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
VisitFunctionDecl(D);
unsigned NumOverridenMethods = Record[Idx++];
while (NumOverridenMethods--) {
- CXXMethodDecl *MD = cast<CXXMethodDecl>(Reader.GetDecl(Record[Idx++]));
// Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
// MD may be initializing.
- Reader.getContext()->addOverriddenMethod(D, MD);
+ if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx))
+ Reader.getContext().addOverriddenMethod(D, MD);
}
}
@@ -1005,7 +1014,7 @@ void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
VisitCXXMethodDecl(D);
D->ImplicitlyDefined = Record[Idx++];
- D->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
+ D->OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx);
}
void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
@@ -1023,7 +1032,7 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
if (Record[Idx++])
D->Friend = GetTypeSourceInfo(Record, Idx);
else
- D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
D->NextFriend = Record[Idx++];
D->UnsupportedFriend = (Record[Idx++] != 0);
D->FriendLoc = ReadSourceLocation(Record, Idx);
@@ -1037,7 +1046,7 @@ void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
for (unsigned i = 0; i != NumParams; ++i)
D->Params[i] = Reader.ReadTemplateParameterList(F, Record, Idx);
if (Record[Idx++]) // HasFriendDecl
- D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
else
D->Friend = GetTypeSourceInfo(Record, Idx);
D->FriendLoc = ReadSourceLocation(Record, Idx);
@@ -1046,8 +1055,7 @@ void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
VisitNamedDecl(D);
- NamedDecl *TemplatedDecl
- = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ NamedDecl *TemplatedDecl = ReadDeclAs<NamedDecl>(Record, Idx);
TemplateParameterList* TemplateParams
= Reader.ReadTemplateParameterList(F, Record, Idx);
D->init(TemplatedDecl, TemplateParams);
@@ -1058,8 +1066,8 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
// 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;
+ DeclID PreviousDeclID = ReadDeclID(Record, Idx);
+ DeclID FirstDeclID = PreviousDeclID ? ReadDeclID(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
@@ -1074,9 +1082,9 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
if (PreviousDeclID != FirstDeclID)
Reader.PendingPreviousDecls.push_back(std::make_pair(D, PreviousDeclID));
} else {
- D->CommonOrPrev = D->newCommon(*Reader.getContext());
+ D->CommonOrPrev = D->newCommon(Reader.getContext());
if (RedeclarableTemplateDecl *RTD
- = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
+ = ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx)) {
assert(RTD->getKind() == D->getKind() &&
"InstantiatedFromMemberTemplate kind mismatch");
D->setInstantiatedFromMemberTemplateImpl(RTD);
@@ -1084,8 +1092,8 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
D->setMemberSpecialization();
}
- RedeclarableTemplateDecl *LatestDecl =
- cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ RedeclarableTemplateDecl *LatestDecl
+ = ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx);
// This decl is a first one and the latest declaration that it points to is
// in the same AST file. However, if this actually needs to point to a
@@ -1095,14 +1103,8 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
ASTReader::FirstLatestDeclIDMap::iterator I
= Reader.FirstLatestDeclIDs.find(ThisDeclID);
if (I != Reader.FirstLatestDeclIDs.end()) {
- Decl *NewLatest = Reader.GetDecl(I->second);
- assert((LatestDecl->getLocation().isInvalid() ||
- NewLatest->getLocation().isInvalid() ||
- !Reader.SourceMgr.isBeforeInTranslationUnit(
- NewLatest->getLocation(),
- LatestDecl->getLocation())) &&
- "The new latest is supposed to come after the previous latest");
- LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest);
+ if (Decl *NewLatest = Reader.GetDecl(I->second))
+ LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest);
}
assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch");
@@ -1119,27 +1121,27 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (D->getPreviousDeclaration() == 0) {
// This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
// the specializations.
- llvm::SmallVector<serialization::DeclID, 2> SpecIDs;
+ 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;
+ for (unsigned I = 0; I != Size; ++I)
+ SpecIDs.push_back(ReadDeclID(Record, Idx));
// Partial specializations.
Size = Record[Idx++];
SpecIDs[0] += Size;
- SpecIDs.append(Record.begin() + Idx, Record.begin() + Idx + Size);
- Idx += Size;
+ for (unsigned I = 0; I != Size; ++I)
+ SpecIDs.push_back(ReadDeclID(Record, Idx));
if (SpecIDs[0]) {
typedef serialization::DeclID DeclID;
ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr();
CommonPtr->LazySpecializations
- = new (*Reader.getContext()) DeclID [SpecIDs.size()];
+ = new (Reader.getContext()) DeclID [SpecIDs.size()];
memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
SpecIDs.size() * sizeof(DeclID));
}
@@ -1152,12 +1154,12 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
VisitCXXRecordDecl(D);
- ASTContext &C = *Reader.getContext();
- if (Decl *InstD = Reader.GetDecl(Record[Idx++])) {
+ ASTContext &C = Reader.getContext();
+ if (Decl *InstD = ReadDecl(Record, Idx)) {
if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
D->SpecializedTemplate = CTD;
} else {
- llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+ SmallVector<TemplateArgument, 8> TemplArgs;
Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
TemplateArgumentList *ArgList
= TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
@@ -1182,7 +1184,7 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl(
D->ExplicitInfo = ExplicitInfo;
}
- llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+ SmallVector<TemplateArgument, 8> TemplArgs;
Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
TemplArgs.size());
@@ -1190,8 +1192,7 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl(
D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++];
if (D->isCanonicalDecl()) { // It's kept in the folding set.
- ClassTemplateDecl *CanonPattern
- = cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>(Record,Idx);
if (ClassTemplatePartialSpecializationDecl *Partial
= dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
CanonPattern->getCommonPtr()->PartialSpecializations.InsertNode(Partial);
@@ -1205,7 +1206,7 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
VisitClassTemplateSpecializationDecl(D);
- ASTContext &C = *Reader.getContext();
+ ASTContext &C = Reader.getContext();
D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx);
unsigned NumArgs = Record[Idx++];
@@ -1221,12 +1222,17 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
// These are read/set from/to the first declaration.
if (D->getPreviousDeclaration() == 0) {
D->InstantiatedFromMember.setPointer(
- cast_or_null<ClassTemplatePartialSpecializationDecl>(
- Reader.GetDecl(Record[Idx++])));
+ ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx));
D->InstantiatedFromMember.setInt(Record[Idx++]);
}
}
+void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
+ ClassScopeFunctionSpecializationDecl *D) {
+ VisitDecl(D);
+ D->Specialization = ReadDeclAs<CXXMethodDecl>(Record, Idx);
+}
+
void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
VisitRedeclarableTemplateDecl(D);
@@ -1238,7 +1244,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
// when reading the specialized FunctionDecl.
unsigned NumSpecs = Record[Idx++];
while (NumSpecs--)
- Reader.GetDecl(Record[Idx++]);
+ (void)ReadDecl(Record, Idx);
}
}
@@ -1260,7 +1266,7 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
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] = Reader.readType(F, Record, Idx).getAsOpaquePtr();
Data[2*I + 1] = GetTypeSourceInfo(Record, Idx);
}
} else {
@@ -1310,13 +1316,13 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
RedeclKind Kind = (RedeclKind)Record[Idx++];
switch (Kind) {
default:
- assert(0 && "Out of sync with ASTDeclWriter::VisitRedeclarable or messed up"
- " reading");
+ llvm_unreachable("Out of sync with ASTDeclWriter::VisitRedeclarable or"
+ " messed up reading");
case NoRedeclaration:
break;
case PointsToPrevious: {
- DeclID PreviousDeclID = Record[Idx++];
- DeclID FirstDeclID = Record[Idx++];
+ DeclID PreviousDeclID = ReadDeclID(Record, Idx);
+ DeclID FirstDeclID = ReadDeclID(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
@@ -1330,7 +1336,7 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
}
case PointsToLatest:
D->RedeclLink = typename Redeclarable<T>::LatestDeclLink(
- cast_or_null<T>(Reader.GetDecl(Record[Idx++])));
+ ReadDeclAs<T>(Record, Idx));
break;
}
@@ -1361,12 +1367,12 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
//===----------------------------------------------------------------------===//
/// \brief Reads attributes from the current stream position.
-void ASTReader::ReadAttributes(PerFileData &F, AttrVec &Attrs,
+void ASTReader::ReadAttributes(Module &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 = ReadSourceLocation(F, Record, Idx);
+ SourceRange Range = ReadSourceRange(F, Record, Idx);
#include "clang/Serialization/AttrPCHRead.inc"
@@ -1398,33 +1404,47 @@ inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) {
/// code generation, e.g., inline function definitions, Objective-C
/// declarations with metadata, etc.
static bool isConsumerInterestedIn(Decl *D) {
- if (isa<FileScopeAsmDecl>(D))
+ // An ObjCMethodDecl is never considered as "interesting" because its
+ // implementation container always is.
+
+ if (isa<FileScopeAsmDecl>(D) ||
+ isa<ObjCProtocolDecl>(D) ||
+ isa<ObjCImplDecl>(D))
return true;
if (VarDecl *Var = dyn_cast<VarDecl>(D))
return Var->isFileVarDecl() &&
Var->isThisDeclarationADefinition() == VarDecl::Definition;
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
return Func->doesThisDeclarationHaveABody();
- return isa<ObjCProtocolDecl>(D) || isa<ObjCImplementationDecl>(D);
+
+ return false;
}
-/// \brief Get the correct cursor and offset for loading a type.
+/// \brief Get the correct cursor and offset for loading a declaration.
ASTReader::RecordLocation
-ASTReader::DeclCursorForIndex(unsigned Index, DeclID ID) {
+ASTReader::DeclCursorForID(DeclID ID) {
// See if there's an override.
DeclReplacementMap::iterator It = ReplacedDecls.find(ID);
if (It != ReplacedDecls.end())
return RecordLocation(It->second.first, It->second.second);
- PerFileData *F = 0;
- for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
- F = Chain[N - I - 1];
- if (Index < F->LocalNumDecls)
- break;
- Index -= F->LocalNumDecls;
- }
- assert(F && F->LocalNumDecls > Index && "Broken chain");
- return RecordLocation(F, F->DeclOffsets[Index]);
+ GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID);
+ assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
+ Module *M = I->second;
+ return RecordLocation(M,
+ M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS]);
+}
+
+ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) {
+ ContinuousRangeMap<uint64_t, Module*, 4>::iterator I
+ = GlobalBitOffsetsMap.find(GlobalOffset);
+
+ assert(I != GlobalBitOffsetsMap.end() && "Corrupted global bit offsets map");
+ return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset);
+}
+
+uint64_t ASTReader::getGlobalBitOffset(Module &M, uint32_t LocalOffset) {
+ return LocalOffset + M.GlobalBitOffset;
}
void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
@@ -1447,8 +1467,9 @@ void ASTReader::loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID) {
}
/// \brief Read the declaration at the given offset from the AST file.
-Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
- RecordLocation Loc = DeclCursorForIndex(Index, ID);
+Decl *ASTReader::ReadDeclRecord(DeclID ID) {
+ unsigned Index = ID - NUM_PREDEF_DECL_IDS;
+ RecordLocation Loc = DeclCursorForID(ID);
llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
// Keep track of where we are in the stream, then jump back there
// after reading this declaration.
@@ -1469,215 +1490,216 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
switch ((DeclCode)DeclsCursor.ReadRecord(Code, Record)) {
case DECL_CONTEXT_LEXICAL:
case DECL_CONTEXT_VISIBLE:
- assert(false && "Record cannot be de-serialized with ReadDeclRecord");
- break;
- case DECL_TRANSLATION_UNIT:
- assert(Index == 0 && "Translation unit must be at index 0");
- D = Context->getTranslationUnitDecl();
- break;
+ llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord");
case DECL_TYPEDEF:
- D = TypedefDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
+ D = TypedefDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
0, 0);
break;
case DECL_TYPEALIAS:
- D = TypeAliasDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
+ D = TypeAliasDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
0, 0);
break;
case DECL_ENUM:
- D = EnumDecl::Create(*Context, Decl::EmptyShell());
+ D = EnumDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_RECORD:
- D = RecordDecl::Create(*Context, Decl::EmptyShell());
+ D = RecordDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_ENUM_CONSTANT:
- D = EnumConstantDecl::Create(*Context, 0, SourceLocation(), 0, QualType(),
+ D = EnumConstantDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
0, llvm::APSInt());
break;
case DECL_FUNCTION:
- D = FunctionDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
+ D = FunctionDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
DeclarationName(), QualType(), 0);
break;
case DECL_LINKAGE_SPEC:
- D = LinkageSpecDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
+ D = LinkageSpecDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
(LinkageSpecDecl::LanguageIDs)0,
SourceLocation());
break;
case DECL_LABEL:
- D = LabelDecl::Create(*Context, 0, SourceLocation(), 0);
+ D = LabelDecl::Create(Context, 0, SourceLocation(), 0);
break;
case DECL_NAMESPACE:
- D = NamespaceDecl::Create(*Context, 0, SourceLocation(),
+ D = NamespaceDecl::Create(Context, 0, SourceLocation(),
SourceLocation(), 0);
break;
case DECL_NAMESPACE_ALIAS:
- D = NamespaceAliasDecl::Create(*Context, 0, SourceLocation(),
+ D = NamespaceAliasDecl::Create(Context, 0, SourceLocation(),
SourceLocation(), 0,
NestedNameSpecifierLoc(),
SourceLocation(), 0);
break;
case DECL_USING:
- D = UsingDecl::Create(*Context, 0, SourceLocation(),
+ D = UsingDecl::Create(Context, 0, SourceLocation(),
NestedNameSpecifierLoc(), DeclarationNameInfo(),
false);
break;
case DECL_USING_SHADOW:
- D = UsingShadowDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+ D = UsingShadowDecl::Create(Context, 0, SourceLocation(), 0, 0);
break;
case DECL_USING_DIRECTIVE:
- D = UsingDirectiveDecl::Create(*Context, 0, SourceLocation(),
+ D = UsingDirectiveDecl::Create(Context, 0, SourceLocation(),
SourceLocation(), NestedNameSpecifierLoc(),
SourceLocation(), 0, 0);
break;
case DECL_UNRESOLVED_USING_VALUE:
- D = UnresolvedUsingValueDecl::Create(*Context, 0, SourceLocation(),
+ D = UnresolvedUsingValueDecl::Create(Context, 0, SourceLocation(),
NestedNameSpecifierLoc(),
DeclarationNameInfo());
break;
case DECL_UNRESOLVED_USING_TYPENAME:
- D = UnresolvedUsingTypenameDecl::Create(*Context, 0, SourceLocation(),
+ D = UnresolvedUsingTypenameDecl::Create(Context, 0, SourceLocation(),
SourceLocation(),
NestedNameSpecifierLoc(),
SourceLocation(),
DeclarationName());
break;
case DECL_CXX_RECORD:
- D = CXXRecordDecl::Create(*Context, Decl::EmptyShell());
+ D = CXXRecordDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_CXX_METHOD:
- D = CXXMethodDecl::Create(*Context, 0, SourceLocation(),
+ D = CXXMethodDecl::Create(Context, 0, SourceLocation(),
DeclarationNameInfo(), QualType(), 0,
- false, SC_None, false, SourceLocation());
+ false, SC_None, false, false, SourceLocation());
break;
case DECL_CXX_CONSTRUCTOR:
- D = CXXConstructorDecl::Create(*Context, Decl::EmptyShell());
+ D = CXXConstructorDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_CXX_DESTRUCTOR:
- D = CXXDestructorDecl::Create(*Context, Decl::EmptyShell());
+ D = CXXDestructorDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_CXX_CONVERSION:
- D = CXXConversionDecl::Create(*Context, Decl::EmptyShell());
+ D = CXXConversionDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_ACCESS_SPEC:
- D = AccessSpecDecl::Create(*Context, Decl::EmptyShell());
+ D = AccessSpecDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_FRIEND:
- D = FriendDecl::Create(*Context, Decl::EmptyShell());
+ D = FriendDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_FRIEND_TEMPLATE:
- D = FriendTemplateDecl::Create(*Context, Decl::EmptyShell());
+ D = FriendTemplateDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_CLASS_TEMPLATE:
- D = ClassTemplateDecl::Create(*Context, Decl::EmptyShell());
+ D = ClassTemplateDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_CLASS_TEMPLATE_SPECIALIZATION:
- D = ClassTemplateSpecializationDecl::Create(*Context, Decl::EmptyShell());
+ D = ClassTemplateSpecializationDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
- D = ClassTemplatePartialSpecializationDecl::Create(*Context,
+ D = ClassTemplatePartialSpecializationDecl::Create(Context,
Decl::EmptyShell());
break;
+ case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION:
+ D = ClassScopeFunctionSpecializationDecl::Create(Context,
+ Decl::EmptyShell());
+ break;
case DECL_FUNCTION_TEMPLATE:
- D = FunctionTemplateDecl::Create(*Context, Decl::EmptyShell());
+ D = FunctionTemplateDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_TEMPLATE_TYPE_PARM:
- D = TemplateTypeParmDecl::Create(*Context, Decl::EmptyShell());
+ D = TemplateTypeParmDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_NON_TYPE_TEMPLATE_PARM:
- D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(),
+ D = NonTypeTemplateParmDecl::Create(Context, 0, SourceLocation(),
SourceLocation(), 0, 0, 0, QualType(),
false, 0);
break;
case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK:
- D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(),
+ D = NonTypeTemplateParmDecl::Create(Context, 0, SourceLocation(),
SourceLocation(), 0, 0, 0, QualType(),
0, 0, Record[Idx++], 0);
break;
case DECL_TEMPLATE_TEMPLATE_PARM:
- D = TemplateTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0, 0,
+ D = TemplateTemplateParmDecl::Create(Context, 0, SourceLocation(), 0, 0,
false, 0, 0);
break;
case DECL_TYPE_ALIAS_TEMPLATE:
- D = TypeAliasTemplateDecl::Create(*Context, Decl::EmptyShell());
+ D = TypeAliasTemplateDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_STATIC_ASSERT:
- D = StaticAssertDecl::Create(*Context, 0, SourceLocation(), 0, 0,
+ D = StaticAssertDecl::Create(Context, 0, SourceLocation(), 0, 0,
SourceLocation());
break;
case DECL_OBJC_METHOD:
- D = ObjCMethodDecl::Create(*Context, SourceLocation(), SourceLocation(),
+ D = ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(),
Selector(), QualType(), 0, 0);
break;
case DECL_OBJC_INTERFACE:
- D = ObjCInterfaceDecl::Create(*Context, 0, SourceLocation(), 0);
+ D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
break;
case DECL_OBJC_IVAR:
- D = ObjCIvarDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
+ D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
0, QualType(), 0, ObjCIvarDecl::None);
break;
case DECL_OBJC_PROTOCOL:
- D = ObjCProtocolDecl::Create(*Context, 0, SourceLocation(), 0);
+ D = ObjCProtocolDecl::Create(Context, 0, 0, SourceLocation(),
+ SourceLocation());
break;
case DECL_OBJC_AT_DEFS_FIELD:
- D = ObjCAtDefsFieldDecl::Create(*Context, 0, SourceLocation(),
+ D = ObjCAtDefsFieldDecl::Create(Context, 0, SourceLocation(),
SourceLocation(), 0, QualType(), 0);
break;
case DECL_OBJC_CLASS:
- D = ObjCClassDecl::Create(*Context, 0, SourceLocation());
+ D = ObjCClassDecl::Create(Context, 0, SourceLocation());
break;
case DECL_OBJC_FORWARD_PROTOCOL:
- D = ObjCForwardProtocolDecl::Create(*Context, 0, SourceLocation());
+ D = ObjCForwardProtocolDecl::Create(Context, 0, SourceLocation());
break;
case DECL_OBJC_CATEGORY:
- D = ObjCCategoryDecl::Create(*Context, 0, SourceLocation(),
- SourceLocation(), SourceLocation(), 0);
+ D = ObjCCategoryDecl::Create(Context, Decl::EmptyShell());
break;
case DECL_OBJC_CATEGORY_IMPL:
- D = ObjCCategoryImplDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+ D = ObjCCategoryImplDecl::Create(Context, 0, 0, 0, SourceLocation(),
+ SourceLocation());
break;
case DECL_OBJC_IMPLEMENTATION:
- D = ObjCImplementationDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+ D = ObjCImplementationDecl::Create(Context, 0, 0, 0, SourceLocation(),
+ SourceLocation());
break;
case DECL_OBJC_COMPATIBLE_ALIAS:
- D = ObjCCompatibleAliasDecl::Create(*Context, 0, SourceLocation(), 0, 0);
+ D = ObjCCompatibleAliasDecl::Create(Context, 0, SourceLocation(), 0, 0);
break;
case DECL_OBJC_PROPERTY:
- D = ObjCPropertyDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(),
+ D = ObjCPropertyDecl::Create(Context, 0, SourceLocation(), 0, SourceLocation(),
0);
break;
case DECL_OBJC_PROPERTY_IMPL:
- D = ObjCPropertyImplDecl::Create(*Context, 0, SourceLocation(),
+ D = ObjCPropertyImplDecl::Create(Context, 0, SourceLocation(),
SourceLocation(), 0,
ObjCPropertyImplDecl::Dynamic, 0,
SourceLocation());
break;
case DECL_FIELD:
- D = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 0,
+ D = FieldDecl::Create(Context, 0, SourceLocation(), SourceLocation(), 0,
QualType(), 0, 0, false, false);
break;
case DECL_INDIRECTFIELD:
- D = IndirectFieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(),
+ D = IndirectFieldDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
0, 0);
break;
case DECL_VAR:
- D = VarDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 0,
+ D = VarDecl::Create(Context, 0, SourceLocation(), SourceLocation(), 0,
QualType(), 0, SC_None, SC_None);
break;
case DECL_IMPLICIT_PARAM:
- D = ImplicitParamDecl::Create(*Context, 0, SourceLocation(), 0, QualType());
+ D = ImplicitParamDecl::Create(Context, 0, SourceLocation(), 0, QualType());
break;
case DECL_PARM_VAR:
- D = ParmVarDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 0,
+ D = ParmVarDecl::Create(Context, 0, SourceLocation(), SourceLocation(), 0,
QualType(), 0, SC_None, SC_None, 0);
break;
case DECL_FILE_SCOPE_ASM:
- D = FileScopeAsmDecl::Create(*Context, 0, 0, SourceLocation(),
+ D = FileScopeAsmDecl::Create(Context, 0, 0, SourceLocation(),
SourceLocation());
break;
case DECL_BLOCK:
- D = BlockDecl::Create(*Context, 0, SourceLocation());
+ D = BlockDecl::Create(Context, 0, SourceLocation());
break;
case DECL_CXX_BASE_SPECIFIERS:
Error("attempt to read a C++ base-specifier record as a declaration");
@@ -1693,16 +1715,13 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
if (Offsets.first || Offsets.second) {
- DC->setHasExternalLexicalStorage(Offsets.first != 0);
- DC->setHasExternalVisibleStorage(Offsets.second != 0);
- DeclContextInfo Info;
- if (ReadDeclContextStorage(DeclsCursor, Offsets, Info))
+ if (Offsets.first != 0)
+ DC->setHasExternalLexicalStorage(true);
+ if (Offsets.second != 0)
+ DC->setHasExternalVisibleStorage(true);
+ if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets,
+ Loc.F->DeclContextInfos[DC]))
return 0;
- DeclContextInfos &Infos = DeclContextOffsets[DC];
- // Reading the TU will happen after reading its lexical update blocks,
- // so we need to make sure we insert in front. For all other contexts,
- // the vector is empty here anyway, so there's no loss in efficiency.
- Infos.insert(Infos.begin(), Info);
}
// Now add the pending visible updates for this decl context, if it has any.
@@ -1713,20 +1732,32 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
// storage, even if the original stored version didn't.
DC->setHasExternalVisibleStorage(true);
DeclContextVisibleUpdates &U = I->second;
- DeclContextInfos &Infos = DeclContextOffsets[DC];
- DeclContextInfo Info;
- Info.LexicalDecls = 0;
- Info.NumLexicalDecls = 0;
for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end();
UI != UE; ++UI) {
- Info.NameLookupTableData = *UI;
- Infos.push_back(Info);
+ UI->second->DeclContextInfos[DC].NameLookupTableData = UI->first;
}
PendingVisibleUpdates.erase(I);
}
}
assert(Idx == Record.size());
+ // Load any relevant update records.
+ loadDeclUpdateRecords(ID, D);
+
+ if (ObjCChainedCategoriesInterfaces.count(ID))
+ loadObjCChainedCategories(ID, cast<ObjCInterfaceDecl>(D));
+
+ // If we have deserialized a declaration that has a definition the
+ // AST consumer might need to know about, queue it.
+ // We don't pass it to the consumer immediately because we may be in recursive
+ // loading, and some declarations may still be initializing.
+ if (isConsumerInterestedIn(D))
+ InterestingDecls.push_back(D);
+
+ return D;
+}
+
+void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
// 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.
@@ -1734,8 +1765,8 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID 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;
+ I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) {
+ Module *F = I->first;
uint64_t Offset = I->second;
llvm::BitstreamCursor &Cursor = F->DeclsCursor;
SavedStreamPosition SavedPosition(Cursor);
@@ -1745,45 +1776,166 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
unsigned RecCode = Cursor.ReadRecord(Code, Record);
(void)RecCode;
assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
+
+ unsigned Idx = 0;
+ ASTDeclReader Reader(*this, *F, Cursor, ID, Record, Idx);
Reader.UpdateDecl(D, *F, Record);
}
}
+}
- // If we have deserialized a declaration that has a definition the
- // AST consumer might need to know about, queue it.
- // We don't pass it to the consumer immediately because we may be in recursive
- // loading, and some declarations may still be initializing.
- if (isConsumerInterestedIn(D))
- InterestingDecls.push_back(D);
+namespace {
+ /// \brief Given an ObjC interface, goes through the modules and links to the
+ /// interface all the categories for it.
+ class ObjCChainedCategoriesVisitor {
+ ASTReader &Reader;
+ serialization::GlobalDeclID InterfaceID;
+ ObjCInterfaceDecl *Interface;
+ ObjCCategoryDecl *GlobHeadCat, *GlobTailCat;
+ llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap;
- return D;
+ public:
+ ObjCChainedCategoriesVisitor(ASTReader &Reader,
+ serialization::GlobalDeclID InterfaceID,
+ ObjCInterfaceDecl *Interface)
+ : Reader(Reader), InterfaceID(InterfaceID), Interface(Interface),
+ GlobHeadCat(0), GlobTailCat(0) { }
+
+ static bool visit(Module &M, void *UserData) {
+ return static_cast<ObjCChainedCategoriesVisitor *>(UserData)->visit(M);
+ }
+
+ bool visit(Module &M) {
+ if (Reader.isDeclIDFromModule(InterfaceID, M))
+ return true; // We reached the module where the interface originated
+ // from. Stop traversing the imported modules.
+
+ Module::ChainedObjCCategoriesMap::iterator
+ I = M.ChainedObjCCategories.find(InterfaceID);
+ if (I == M.ChainedObjCCategories.end())
+ return false;
+
+ ObjCCategoryDecl *
+ HeadCat = Reader.GetLocalDeclAs<ObjCCategoryDecl>(M, I->second.first);
+ ObjCCategoryDecl *
+ TailCat = Reader.GetLocalDeclAs<ObjCCategoryDecl>(M, I->second.second);
+
+ addCategories(HeadCat, TailCat);
+ return false;
+ }
+
+ void addCategories(ObjCCategoryDecl *HeadCat,
+ ObjCCategoryDecl *TailCat = 0) {
+ if (!HeadCat) {
+ assert(!TailCat);
+ return;
+ }
+
+ if (!TailCat) {
+ TailCat = HeadCat;
+ while (TailCat->getNextClassCategory())
+ TailCat = TailCat->getNextClassCategory();
+ }
+
+ if (!GlobHeadCat) {
+ GlobHeadCat = HeadCat;
+ GlobTailCat = TailCat;
+ } else {
+ ASTDeclReader::setNextObjCCategory(GlobTailCat, HeadCat);
+ GlobTailCat = TailCat;
+ }
+
+ llvm::DenseSet<DeclarationName> Checked;
+ for (ObjCCategoryDecl *Cat = HeadCat,
+ *CatEnd = TailCat->getNextClassCategory();
+ Cat != CatEnd; Cat = Cat->getNextClassCategory()) {
+ if (Checked.count(Cat->getDeclName()))
+ continue;
+ Checked.insert(Cat->getDeclName());
+ checkForDuplicate(Cat);
+ }
+ }
+
+ /// \brief Warns for duplicate categories that come from different modules.
+ void checkForDuplicate(ObjCCategoryDecl *Cat) {
+ DeclarationName Name = Cat->getDeclName();
+ // Find the top category with the same name. We do not want to warn for
+ // duplicates along the established chain because there were already
+ // warnings for them when the module was created. We only want to warn for
+ // duplicates between non-dependent modules:
+ //
+ // MT //
+ // / \ //
+ // ML MR //
+ //
+ // We want to warn for duplicates between ML and MR,not between ML and MT.
+ //
+ // FIXME: We should not warn for duplicates in diamond:
+ //
+ // MT //
+ // / \ //
+ // ML MR //
+ // \ / //
+ // MB //
+ //
+ // If there are duplicates in ML/MR, there will be warning when creating
+ // MB *and* when importing MB. We should not warn when importing.
+ for (ObjCCategoryDecl *Next = Cat->getNextClassCategory(); Next;
+ Next = Next->getNextClassCategory()) {
+ if (Next->getDeclName() == Name)
+ Cat = Next;
+ }
+
+ ObjCCategoryDecl *&PrevCat = NameCategoryMap[Name];
+ if (!PrevCat)
+ PrevCat = Cat;
+
+ if (PrevCat != Cat) {
+ Reader.Diag(Cat->getLocation(), diag::warn_dup_category_def)
+ << Interface->getDeclName() << Name;
+ Reader.Diag(PrevCat->getLocation(), diag::note_previous_definition);
+ }
+ }
+
+ ObjCCategoryDecl *getHeadCategory() const { return GlobHeadCat; }
+ };
+}
+
+void ASTReader::loadObjCChainedCategories(serialization::GlobalDeclID ID,
+ ObjCInterfaceDecl *D) {
+ ObjCChainedCategoriesVisitor Visitor(*this, ID, D);
+ ModuleMgr.visit(ObjCChainedCategoriesVisitor::visit, &Visitor);
+ // Also add the categories that the interface already links to.
+ Visitor.addCategories(D->getCategoryList());
+ D->setCategoryList(Visitor.getHeadCategory());
}
-void ASTDeclReader::UpdateDecl(Decl *D, ASTReader::PerFileData &Module,
+void ASTDeclReader::UpdateDecl(Decl *D, Module &Module,
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++]));
+ CXXRecordDecl *DefinitionDecl
+ = Reader.ReadDeclAs<CXXRecordDecl>(Module, 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++]));
+ cast<CXXRecordDecl>(D)->addedMember(Reader.ReadDecl(Module, 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++]);
+ (void)Reader.ReadDecl(Module, Record, Idx);
break;
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
- NamespaceDecl *Anon = cast<NamespaceDecl>(Reader.GetDecl(Record[Idx++]));
+ NamespaceDecl *Anon
+ = Reader.ReadDeclAs<NamespaceDecl>(Module, Record, Idx);
// Guard against these being loaded out of original order. Don't use
// getNextNamespace(), since it tries to access the context and can't in
// the middle of deserialization.
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h
new file mode 100644
index 0000000..99e8be5
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h
@@ -0,0 +1,243 @@
+//===--- ASTReaderInternals.h - AST Reader Internals ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides internal definitions used in the AST reader.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H
+#define LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H
+
+#include "clang/Basic/OnDiskHashTable.h"
+#include "clang/AST/DeclarationName.h"
+#include <utility>
+#include <sys/stat.h>
+
+namespace clang {
+
+class ASTReader;
+class HeaderSearch;
+struct HeaderFileInfo;
+
+namespace serialization {
+
+class Module;
+
+namespace reader {
+
+/// \brief Class that performs name lookup into a DeclContext stored
+/// in an AST file.
+class ASTDeclContextNameLookupTrait {
+ ASTReader &Reader;
+ Module &F;
+
+public:
+ /// \brief Pair of begin/end iterators for DeclIDs.
+ ///
+ /// Note that these declaration IDs are local to the module that contains this
+ /// particular lookup t
+ typedef std::pair<DeclID *, DeclID *> data_type;
+
+ /// \brief Special internal key for declaration names.
+ /// The hash table creates keys for comparison; we do not create
+ /// a DeclarationName for the internal key to avoid deserializing types.
+ struct DeclNameKey {
+ DeclarationName::NameKind Kind;
+ uint64_t Data;
+ DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
+ };
+
+ typedef DeclarationName external_key_type;
+ typedef DeclNameKey internal_key_type;
+
+ explicit ASTDeclContextNameLookupTrait(ASTReader &Reader,
+ Module &F)
+ : Reader(Reader), F(F) { }
+
+ static bool EqualKey(const internal_key_type& a,
+ const internal_key_type& b) {
+ return a.Kind == b.Kind && a.Data == b.Data;
+ }
+
+ unsigned ComputeHash(const DeclNameKey &Key) const;
+ internal_key_type GetInternalKey(const external_key_type& Name) const;
+ external_key_type GetExternalKey(const internal_key_type& Key) const;
+
+ static std::pair<unsigned, unsigned>
+ ReadKeyDataLength(const unsigned char*& d);
+
+ internal_key_type ReadKey(const unsigned char* d, unsigned);
+
+ data_type ReadData(internal_key_type, const unsigned char* d,
+ unsigned DataLen);
+};
+
+/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
+typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
+ ASTDeclContextNameLookupTable;
+
+/// \brief Class that performs lookup for an identifier stored in an AST file.
+class ASTIdentifierLookupTrait {
+ ASTReader &Reader;
+ Module &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
+ // identifier that was constructed before the AST file was read.
+ IdentifierInfo *KnownII;
+
+public:
+ typedef IdentifierInfo * data_type;
+
+ typedef const std::pair<const char*, unsigned> external_key_type;
+
+ typedef external_key_type internal_key_type;
+
+ ASTIdentifierLookupTrait(ASTReader &Reader, Module &F,
+ IdentifierInfo *II = 0)
+ : Reader(Reader), F(F), KnownII(II) { }
+
+ static bool EqualKey(const internal_key_type& a,
+ const internal_key_type& b) {
+ return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
+ : false;
+ }
+
+ static unsigned ComputeHash(const internal_key_type& a);
+
+ // This hopefully will just get inlined and removed by the optimizer.
+ 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);
+
+ static std::pair<const char*, unsigned>
+ ReadKey(const unsigned char* d, unsigned n);
+
+ IdentifierInfo *ReadData(const internal_key_type& k,
+ const unsigned char* d,
+ unsigned DataLen);
+};
+
+/// \brief The on-disk hash table used to contain information about
+/// all of the identifiers in the program.
+typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
+ ASTIdentifierLookupTable;
+
+/// \brief Class that performs lookup for a selector's entries in the global
+/// method pool stored in an AST file.
+class ASTSelectorLookupTrait {
+ ASTReader &Reader;
+ Module &F;
+
+public:
+ struct data_type {
+ SelectorID ID;
+ llvm::SmallVector<ObjCMethodDecl *, 2> Instance;
+ llvm::SmallVector<ObjCMethodDecl *, 2> Factory;
+ };
+
+ typedef Selector external_key_type;
+ typedef external_key_type internal_key_type;
+
+ ASTSelectorLookupTrait(ASTReader &Reader, Module &F)
+ : Reader(Reader), F(F) { }
+
+ static bool EqualKey(const internal_key_type& a,
+ const internal_key_type& b) {
+ return a == b;
+ }
+
+ static unsigned ComputeHash(Selector Sel);
+
+ static const internal_key_type&
+ GetInternalKey(const external_key_type& x) { return x; }
+
+ static std::pair<unsigned, unsigned>
+ ReadKeyDataLength(const unsigned char*& d);
+
+ internal_key_type ReadKey(const unsigned char* d, unsigned);
+ data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
+};
+
+/// \brief The on-disk hash table used for the global method pool.
+typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
+ ASTSelectorLookupTable;
+
+/// \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 {
+ ASTReader &Reader;
+ Module &M;
+ HeaderSearch *HS;
+ const char *FrameworkStrings;
+ 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(ASTReader &Reader, Module &M, HeaderSearch *HS,
+ const char *FrameworkStrings,
+ const char *SearchPath = 0)
+ : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings),
+ SearchPath(SearchPath) { }
+
+ static unsigned ComputeHash(const char *path);
+ static internal_key_type GetInternalKey(const char *path);
+ bool EqualKey(internal_key_type a, internal_key_type b);
+
+ static std::pair<unsigned, unsigned>
+ ReadKeyDataLength(const unsigned char*& d);
+
+ static internal_key_type ReadKey(const unsigned char *d, unsigned) {
+ return (const char *)d;
+ }
+
+ data_type ReadData(const internal_key_type, const unsigned char *d,
+ unsigned DataLen);
+};
+
+/// \brief The on-disk hash table used for known header files.
+typedef OnDiskChainedHashTable<HeaderFileInfoTrait>
+ HeaderFileInfoLookupTable;
+
+} // end namespace clang::serialization::reader
+} // end namespace clang::serialization
+} // end namespace clang
+
+
+#endif
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp
index 14927b9..ab07b85 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -22,34 +22,51 @@ using namespace clang::serialization;
namespace clang {
class ASTStmtReader : public StmtVisitor<ASTStmtReader> {
+ typedef ASTReader::RecordData RecordData;
+
ASTReader &Reader;
- ASTReader::PerFileData &F;
+ Module &F;
llvm::BitstreamCursor &DeclsCursor;
const ASTReader::RecordData &Record;
unsigned &Idx;
- SourceLocation ReadSourceLocation(const ASTReader::RecordData &R,
- unsigned &I) {
+ SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) {
return Reader.ReadSourceLocation(F, R, I);
}
- SourceRange ReadSourceRange(const ASTReader::RecordData &R, unsigned &I) {
+
+ SourceRange ReadSourceRange(const RecordData &R, unsigned &I) {
return Reader.ReadSourceRange(F, R, I);
}
- TypeSourceInfo *GetTypeSourceInfo(const ASTReader::RecordData &R,
- unsigned &I) {
+
+ TypeSourceInfo *GetTypeSourceInfo(const RecordData &R, unsigned &I) {
return Reader.GetTypeSourceInfo(F, R, I);
}
+
+ serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
+ return Reader.ReadDeclID(F, R, I);
+ }
+
+ Decl *ReadDecl(const RecordData &R, unsigned &I) {
+ return Reader.ReadDecl(F, R, I);
+ }
+
+ template<typename T>
+ T *ReadDeclAs(const RecordData &R, unsigned &I) {
+ return Reader.ReadDeclAs<T>(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, ASTReader::PerFileData &F,
+ ASTStmtReader(ASTReader &Reader, Module &F,
llvm::BitstreamCursor &Cursor,
const ASTReader::RecordData &Record, unsigned &Idx)
: Reader(Reader), F(F), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
@@ -63,7 +80,7 @@ namespace clang {
static const unsigned NumExprFields = NumStmtFields + 7;
/// \brief Read and initialize a ExplicitTemplateArgumentList structure.
- void ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList,
+ void ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList,
unsigned NumTemplateArgs);
void VisitStmt(Stmt *S);
@@ -74,7 +91,7 @@ namespace clang {
}
void ASTStmtReader::
-ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList,
+ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList,
unsigned NumTemplateArgs) {
TemplateArgumentListInfo ArgInfo;
ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx));
@@ -92,16 +109,16 @@ void ASTStmtReader::VisitStmt(Stmt *S) {
void ASTStmtReader::VisitNullStmt(NullStmt *S) {
VisitStmt(S);
S->setSemiLoc(ReadSourceLocation(Record, Idx));
- S->LeadingEmptyMacro = ReadSourceLocation(Record, Idx);
+ S->HasLeadingEmptyMacro = Record[Idx++];
}
void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
VisitStmt(S);
- llvm::SmallVector<Stmt *, 16> Stmts;
+ SmallVector<Stmt *, 16> Stmts;
unsigned NumStmts = Record[Idx++];
while (NumStmts--)
Stmts.push_back(Reader.ReadSubStmt());
- S->setStmts(*Reader.getContext(), Stmts.data(), Stmts.size());
+ S->setStmts(Reader.getContext(), Stmts.data(), Stmts.size());
S->setLBracLoc(ReadSourceLocation(Record, Idx));
S->setRBracLoc(ReadSourceLocation(Record, Idx));
}
@@ -130,7 +147,7 @@ void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) {
void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
VisitStmt(S);
- LabelDecl *LD = cast<LabelDecl>(Reader.GetDecl(Record[Idx++]));
+ LabelDecl *LD = ReadDeclAs<LabelDecl>(Record, Idx);
LD->setStmt(S);
S->setDecl(LD);
S->setSubStmt(Reader.ReadSubStmt());
@@ -139,8 +156,8 @@ void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
void ASTStmtReader::VisitIfStmt(IfStmt *S) {
VisitStmt(S);
- S->setConditionVariable(*Reader.getContext(),
- cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ S->setConditionVariable(Reader.getContext(),
+ ReadDeclAs<VarDecl>(Record, Idx));
S->setCond(Reader.ReadSubExpr());
S->setThen(Reader.ReadSubStmt());
S->setElse(Reader.ReadSubStmt());
@@ -150,8 +167,8 @@ void ASTStmtReader::VisitIfStmt(IfStmt *S) {
void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
VisitStmt(S);
- S->setConditionVariable(*Reader.getContext(),
- cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ S->setConditionVariable(Reader.getContext(),
+ ReadDeclAs<VarDecl>(Record, Idx));
S->setCond(Reader.ReadSubExpr());
S->setBody(Reader.ReadSubStmt());
S->setSwitchLoc(ReadSourceLocation(Record, Idx));
@@ -172,8 +189,9 @@ void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
void ASTStmtReader::VisitWhileStmt(WhileStmt *S) {
VisitStmt(S);
- S->setConditionVariable(*Reader.getContext(),
- cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ S->setConditionVariable(Reader.getContext(),
+ ReadDeclAs<VarDecl>(Record, Idx));
+
S->setCond(Reader.ReadSubExpr());
S->setBody(Reader.ReadSubStmt());
S->setWhileLoc(ReadSourceLocation(Record, Idx));
@@ -192,8 +210,8 @@ void ASTStmtReader::VisitForStmt(ForStmt *S) {
VisitStmt(S);
S->setInit(Reader.ReadSubStmt());
S->setCond(Reader.ReadSubExpr());
- S->setConditionVariable(*Reader.getContext(),
- cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ S->setConditionVariable(Reader.getContext(),
+ ReadDeclAs<VarDecl>(Record, Idx));
S->setInc(Reader.ReadSubExpr());
S->setBody(Reader.ReadSubStmt());
S->setForLoc(ReadSourceLocation(Record, Idx));
@@ -203,7 +221,7 @@ void ASTStmtReader::VisitForStmt(ForStmt *S) {
void ASTStmtReader::VisitGotoStmt(GotoStmt *S) {
VisitStmt(S);
- S->setLabel(cast<LabelDecl>(Reader.GetDecl(Record[Idx++])));
+ S->setLabel(ReadDeclAs<LabelDecl>(Record, Idx));
S->setGotoLoc(ReadSourceLocation(Record, Idx));
S->setLabelLoc(ReadSourceLocation(Record, Idx));
}
@@ -229,7 +247,7 @@ void ASTStmtReader::VisitReturnStmt(ReturnStmt *S) {
VisitStmt(S);
S->setRetValue(Reader.ReadSubExpr());
S->setReturnLoc(ReadSourceLocation(Record, Idx));
- S->setNRVOCandidate(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ S->setNRVOCandidate(ReadDeclAs<VarDecl>(Record, Idx));
}
void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
@@ -239,13 +257,13 @@ void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
if (Idx + 1 == Record.size()) {
// Single declaration
- S->setDeclGroup(DeclGroupRef(Reader.GetDecl(Record[Idx++])));
+ S->setDeclGroup(DeclGroupRef(ReadDecl(Record, Idx)));
} else {
- llvm::SmallVector<Decl *, 16> Decls;
- Decls.reserve(Record.size() - Idx);
- for (unsigned N = Record.size(); Idx != N; ++Idx)
- Decls.push_back(Reader.GetDecl(Record[Idx]));
- S->setDeclGroup(DeclGroupRef(DeclGroup::Create(*Reader.getContext(),
+ SmallVector<Decl *, 16> Decls;
+ Decls.reserve(Record.size() - Idx);
+ for (unsigned N = Record.size(); Idx != N; )
+ Decls.push_back(ReadDecl(Record, Idx));
+ S->setDeclGroup(DeclGroupRef(DeclGroup::Create(Reader.getContext(),
Decls.data(),
Decls.size())));
}
@@ -265,21 +283,21 @@ void ASTStmtReader::VisitAsmStmt(AsmStmt *S) {
S->setAsmString(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
// Outputs and inputs
- llvm::SmallVector<IdentifierInfo *, 16> Names;
- llvm::SmallVector<StringLiteral*, 16> Constraints;
- llvm::SmallVector<Stmt*, 16> Exprs;
+ SmallVector<IdentifierInfo *, 16> Names;
+ SmallVector<StringLiteral*, 16> Constraints;
+ SmallVector<Stmt*, 16> Exprs;
for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
- Names.push_back(Reader.GetIdentifierInfo(Record, Idx));
+ Names.push_back(Reader.GetIdentifierInfo(F, Record, Idx));
Constraints.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
Exprs.push_back(Reader.ReadSubStmt());
}
// Constraints
- llvm::SmallVector<StringLiteral*, 16> Clobbers;
+ SmallVector<StringLiteral*, 16> Clobbers;
for (unsigned I = 0; I != NumClobbers; ++I)
Clobbers.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
- S->setOutputsAndInputsAndClobbers(*Reader.getContext(),
+ S->setOutputsAndInputsAndClobbers(Reader.getContext(),
Names.data(), Constraints.data(),
Exprs.data(), NumOutputs, NumInputs,
Clobbers.data(), NumClobbers);
@@ -287,7 +305,7 @@ void ASTStmtReader::VisitAsmStmt(AsmStmt *S) {
void ASTStmtReader::VisitExpr(Expr *E) {
VisitStmt(E);
- E->setType(Reader.GetType(Record[Idx++]));
+ E->setType(Reader.readType(F, Record, Idx));
E->setTypeDependent(Record[Idx++]);
E->setValueDependent(Record[Idx++]);
E->setInstantiationDependent(Record[Idx++]);
@@ -309,6 +327,7 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
E->DeclRefExprBits.HasQualifier = Record[Idx++];
E->DeclRefExprBits.HasFoundDecl = Record[Idx++];
E->DeclRefExprBits.HasExplicitTemplateArgs = Record[Idx++];
+ E->DeclRefExprBits.HadMultipleCandidates = Record[Idx++];
unsigned NumTemplateArgs = 0;
if (E->hasExplicitTemplateArgs())
NumTemplateArgs = Record[Idx++];
@@ -318,13 +337,13 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
= Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
if (E->hasFoundDecl())
- E->getInternalFoundDecl() = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ E->getInternalFoundDecl() = ReadDeclAs<NamedDecl>(Record, Idx);
if (E->hasExplicitTemplateArgs())
ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
NumTemplateArgs);
- E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
+ E->setDecl(ReadDeclAs<ValueDecl>(Record, Idx));
E->setLocation(ReadSourceLocation(Record, Idx));
ReadDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record, Idx);
}
@@ -332,12 +351,12 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
void ASTStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
VisitExpr(E);
E->setLocation(ReadSourceLocation(Record, Idx));
- E->setValue(*Reader.getContext(), Reader.ReadAPInt(Record, Idx));
+ E->setValue(Reader.getContext(), Reader.ReadAPInt(Record, Idx));
}
void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
VisitExpr(E);
- E->setValue(*Reader.getContext(), Reader.ReadAPFloat(Record, Idx));
+ E->setValue(Reader.getContext(), Reader.ReadAPFloat(Record, Idx));
E->setExact(Record[Idx++]);
E->setLocation(ReadSourceLocation(Record, Idx));
}
@@ -353,12 +372,12 @@ void ASTStmtReader::VisitStringLiteral(StringLiteral *E) {
assert(Record[Idx] == E->getNumConcatenated() &&
"Wrong number of concatenated tokens!");
++Idx;
- E->IsWide = Record[Idx++];
+ E->Kind = static_cast<StringLiteral::StringKind>(Record[Idx++]);
E->IsPascal = Record[Idx++];
// Read string data
llvm::SmallString<16> Str(&Record[Idx], &Record[Idx] + Len);
- E->setString(*Reader.getContext(), Str.str());
+ E->setString(Reader.getContext(), Str.str());
Idx += Len;
// Read source locations
@@ -370,7 +389,7 @@ void ASTStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
VisitExpr(E);
E->setValue(Record[Idx++]);
E->setLocation(ReadSourceLocation(Record, Idx));
- E->setWide(Record[Idx++]);
+ E->setKind(static_cast<CharacterLiteral::CharacterKind>(Record[Idx++]));
}
void ASTStmtReader::VisitParenExpr(ParenExpr *E) {
@@ -383,7 +402,7 @@ void ASTStmtReader::VisitParenExpr(ParenExpr *E) {
void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) {
VisitExpr(E);
unsigned NumExprs = Record[Idx++];
- E->Exprs = new (*Reader.getContext()) Stmt*[NumExprs];
+ E->Exprs = new (Reader.getContext()) Stmt*[NumExprs];
for (unsigned i = 0; i != NumExprs; ++i)
E->Exprs[i] = Reader.ReadSubStmt();
E->NumExprs = NumExprs;
@@ -418,18 +437,18 @@ void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
break;
case Node::Field:
- E->setComponent(I,
- Node(Start,
- dyn_cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])),
- End));
+ E->setComponent(I, Node(Start, ReadDeclAs<FieldDecl>(Record, Idx), End));
break;
case Node::Identifier:
- E->setComponent(I, Node(Start, Reader.GetIdentifier(Record[Idx++]), End));
+ E->setComponent(I,
+ Node(Start,
+ Reader.GetIdentifierInfo(F, Record, Idx),
+ End));
break;
case Node::Base: {
- CXXBaseSpecifier *Base = new (*Reader.getContext()) CXXBaseSpecifier();
+ CXXBaseSpecifier *Base = new (Reader.getContext()) CXXBaseSpecifier();
*Base = Reader.ReadCXXBaseSpecifier(F, Record, Idx);
E->setComponent(I, Node(Base));
break;
@@ -463,7 +482,7 @@ void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
void ASTStmtReader::VisitCallExpr(CallExpr *E) {
VisitExpr(E);
- E->setNumArgs(*Reader.getContext(), Record[Idx++]);
+ E->setNumArgs(Reader.getContext(), Record[Idx++]);
E->setRParenLoc(ReadSourceLocation(Record, Idx));
E->setCallee(Reader.ReadSubExpr());
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
@@ -509,7 +528,7 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {
E->setCastKind((CastExpr::CastKind)Record[Idx++]);
CastExpr::path_iterator BaseI = E->path_begin();
while (NumBaseSpecs--) {
- CXXBaseSpecifier *BaseSpec = new (*Reader.getContext()) CXXBaseSpecifier;
+ CXXBaseSpecifier *BaseSpec = new (Reader.getContext()) CXXBaseSpecifier;
*BaseSpec = Reader.ReadCXXBaseSpecifier(F, Record, Idx);
*BaseI++ = BaseSpec;
}
@@ -525,8 +544,8 @@ void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
VisitBinaryOperator(E);
- E->setComputationLHSType(Reader.GetType(Record[Idx++]));
- E->setComputationResultType(Reader.GetType(Record[Idx++]));
+ E->setComputationLHSType(Reader.readType(F, Record, Idx));
+ E->setComputationResultType(Reader.readType(F, Record, Idx));
}
void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
@@ -578,7 +597,7 @@ void ASTStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
VisitExpr(E);
E->setBase(Reader.ReadSubExpr());
- E->setAccessor(Reader.GetIdentifierInfo(Record, Idx));
+ E->setAccessor(Reader.GetIdentifierInfo(F, Record, Idx));
E->setAccessorLoc(ReadSourceLocation(Record, Idx));
}
@@ -593,19 +612,18 @@ void ASTStmtReader::VisitInitListExpr(InitListExpr *E) {
filler = Reader.ReadSubExpr();
E->ArrayFillerOrUnionFieldInit = filler;
} else
- E->ArrayFillerOrUnionFieldInit
- = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+ E->ArrayFillerOrUnionFieldInit = ReadDeclAs<FieldDecl>(Record, Idx);
E->sawArrayRangeDesignator(Record[Idx++]);
unsigned NumInits = Record[Idx++];
- E->reserveInits(*Reader.getContext(), NumInits);
+ E->reserveInits(Reader.getContext(), NumInits);
if (isArrayFiller) {
for (unsigned I = 0; I != NumInits; ++I) {
Expr *init = Reader.ReadSubExpr();
- E->updateInit(*Reader.getContext(), I, init ? init : filler);
+ E->updateInit(Reader.getContext(), I, init ? init : filler);
}
} else {
for (unsigned I = 0; I != NumInits; ++I)
- E->updateInit(*Reader.getContext(), I, Reader.ReadSubExpr());
+ E->updateInit(Reader.getContext(), I, Reader.ReadSubExpr());
}
}
@@ -620,11 +638,11 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
E->setEqualOrColonLoc(ReadSourceLocation(Record, Idx));
E->setGNUSyntax(Record[Idx++]);
- llvm::SmallVector<Designator, 4> Designators;
+ SmallVector<Designator, 4> Designators;
while (Idx < Record.size()) {
switch ((DesignatorTypes)Record[Idx++]) {
case DESIG_FIELD_DECL: {
- FieldDecl *Field = cast<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+ FieldDecl *Field = ReadDeclAs<FieldDecl>(Record, Idx);
SourceLocation DotLoc
= ReadSourceLocation(Record, Idx);
SourceLocation FieldLoc
@@ -636,7 +654,7 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
}
case DESIG_FIELD_NAME: {
- const IdentifierInfo *Name = Reader.GetIdentifierInfo(Record, Idx);
+ const IdentifierInfo *Name = Reader.GetIdentifierInfo(F, Record, Idx);
SourceLocation DotLoc
= ReadSourceLocation(Record, Idx);
SourceLocation FieldLoc
@@ -669,7 +687,7 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
}
}
}
- E->setDesignators(*Reader.getContext(),
+ E->setDesignators(Reader.getContext(),
Designators.data(), Designators.size());
}
@@ -689,7 +707,7 @@ void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
VisitExpr(E);
E->setAmpAmpLoc(ReadSourceLocation(Record, Idx));
E->setLabelLoc(ReadSourceLocation(Record, Idx));
- E->setLabel(cast<LabelDecl>(Reader.GetDecl(Record[Idx++])));
+ E->setLabel(ReadDeclAs<LabelDecl>(Record, Idx));
}
void ASTStmtReader::VisitStmtExpr(StmtExpr *E) {
@@ -715,23 +733,23 @@ void ASTStmtReader::VisitGNUNullExpr(GNUNullExpr *E) {
void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
VisitExpr(E);
- llvm::SmallVector<Expr *, 16> Exprs;
+ SmallVector<Expr *, 16> Exprs;
unsigned NumExprs = Record[Idx++];
while (NumExprs--)
Exprs.push_back(Reader.ReadSubExpr());
- E->setExprs(*Reader.getContext(), Exprs.data(), Exprs.size());
+ E->setExprs(Reader.getContext(), Exprs.data(), Exprs.size());
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->setBlockDecl(ReadDeclAs<BlockDecl>(Record, Idx));
}
void ASTStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
VisitExpr(E);
- E->setDecl(cast<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ E->setDecl(ReadDeclAs<VarDecl>(Record, Idx));
E->setLocation(ReadSourceLocation(Record, Idx));
E->setByRef(Record[Idx++]);
E->setConstQualAdded(Record[Idx++]);
@@ -740,9 +758,9 @@ void ASTStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
VisitExpr(E);
E->NumAssocs = Record[Idx++];
- E->AssocTypes = new (*Reader.getContext()) TypeSourceInfo*[E->NumAssocs];
+ E->AssocTypes = new (Reader.getContext()) TypeSourceInfo*[E->NumAssocs];
E->SubExprs =
- new(*Reader.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
+ new(Reader.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
E->SubExprs[GenericSelectionExpr::CONTROLLING] = Reader.ReadSubExpr();
for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
@@ -756,6 +774,25 @@ void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
E->RParenLoc = ReadSourceLocation(Record, Idx);
}
+void ASTStmtReader::VisitAtomicExpr(AtomicExpr *E) {
+ VisitExpr(E);
+ E->setOp(AtomicExpr::AtomicOp(Record[Idx++]));
+ E->setPtr(Reader.ReadSubExpr());
+ E->setOrder(Reader.ReadSubExpr());
+ E->setNumSubExprs(2);
+ if (E->getOp() != AtomicExpr::Load) {
+ E->setVal1(Reader.ReadSubExpr());
+ E->setNumSubExprs(3);
+ }
+ if (E->isCmpXChg()) {
+ E->setOrderFail(Reader.ReadSubExpr());
+ E->setVal2(Reader.ReadSubExpr());
+ E->setNumSubExprs(5);
+ }
+ E->setBuiltinLoc(ReadSourceLocation(Record, Idx));
+ E->setRParenLoc(ReadSourceLocation(Record, Idx));
+}
+
//===----------------------------------------------------------------------===//
// Objective-C Expressions and Statements
@@ -774,21 +811,21 @@ void ASTStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
void ASTStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
VisitExpr(E);
- E->setSelector(Reader.GetSelector(Record, Idx));
+ E->setSelector(Reader.ReadSelector(F, 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->setProtocol(ReadDeclAs<ObjCProtocolDecl>(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->setDecl(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
E->setLocation(ReadSourceLocation(Record, Idx));
E->setBase(Reader.ReadSubExpr());
E->setIsArrow(Record[Idx++]);
@@ -799,14 +836,11 @@ void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
VisitExpr(E);
bool Implicit = Record[Idx++] != 0;
if (Implicit) {
- ObjCMethodDecl *Getter =
- cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++]));
- ObjCMethodDecl *Setter =
- cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++]));
+ ObjCMethodDecl *Getter = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
+ ObjCMethodDecl *Setter = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
E->setImplicitProperty(Getter, Setter);
} else {
- E->setExplicitProperty(
- cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
+ E->setExplicitProperty(ReadDeclAs<ObjCPropertyDecl>(Record, Idx));
}
E->setLocation(ReadSourceLocation(Record, Idx));
E->setReceiverLocation(ReadSourceLocation(Record, Idx));
@@ -815,11 +849,10 @@ void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
E->setBase(Reader.ReadSubExpr());
break;
case 1:
- E->setSuperReceiver(Reader.GetType(Record[Idx++]));
+ E->setSuperReceiver(Reader.readType(F, Record, Idx));
break;
case 2:
- E->setClassReceiver(
- cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ E->setClassReceiver(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
break;
}
}
@@ -828,6 +861,8 @@ void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
VisitExpr(E);
assert(Record[Idx] == E->getNumArgs());
++Idx;
+ unsigned NumStoredSelLocs = Record[Idx++];
+ E->SelLocsKind = Record[Idx++];
E->setDelegateInitCall(Record[Idx++]);
ObjCMessageExpr::ReceiverKind Kind
= static_cast<ObjCMessageExpr::ReceiverKind>(Record[Idx++]);
@@ -842,7 +877,7 @@ void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
case ObjCMessageExpr::SuperClass:
case ObjCMessageExpr::SuperInstance: {
- QualType T = Reader.GetType(Record[Idx++]);
+ QualType T = Reader.readType(F, Record, Idx);
SourceLocation SuperLoc = ReadSourceLocation(Record, Idx);
E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance);
break;
@@ -852,16 +887,19 @@ void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
assert(Kind == E->getReceiverKind());
if (Record[Idx++])
- E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+ E->setMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
else
- E->setSelector(Reader.GetSelector(Record, Idx));
+ E->setSelector(Reader.ReadSelector(F, 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());
+
+ SourceLocation *Locs = E->getStoredSelLocs();
+ for (unsigned I = 0; I != NumStoredSelLocs; ++I)
+ Locs[I] = ReadSourceLocation(Record, Idx);
}
void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
@@ -876,7 +914,7 @@ void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
void ASTStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
VisitStmt(S);
S->setCatchBody(Reader.ReadSubStmt());
- S->setCatchParamDecl(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ S->setCatchParamDecl(ReadDeclAs<VarDecl>(Record, Idx));
S->setAtCatchLoc(ReadSourceLocation(Record, Idx));
S->setRParenLoc(ReadSourceLocation(Record, Idx));
}
@@ -927,7 +965,7 @@ void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
void ASTStmtReader::VisitCXXCatchStmt(CXXCatchStmt *S) {
VisitStmt(S);
S->CatchLoc = ReadSourceLocation(Record, Idx);
- S->ExceptionDecl = cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]));
+ S->ExceptionDecl = ReadDeclAs<VarDecl>(Record, Idx);
S->HandlerBlock = Reader.ReadSubStmt();
}
@@ -963,12 +1001,13 @@ void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
VisitExpr(E);
E->NumArgs = Record[Idx++];
if (E->NumArgs)
- E->Args = new (*Reader.getContext()) Stmt*[E->NumArgs];
+ E->Args = new (Reader.getContext()) Stmt*[E->NumArgs];
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
E->setArg(I, Reader.ReadSubExpr());
- E->setConstructor(cast<CXXConstructorDecl>(Reader.GetDecl(Record[Idx++])));
+ E->setConstructor(ReadDeclAs<CXXConstructorDecl>(Record, Idx));
E->setLocation(ReadSourceLocation(Record, Idx));
- E->setElidable(Record[Idx++]);
+ E->setElidable(Record[Idx++]);
+ E->setHadMultipleCandidates(Record[Idx++]);
E->setRequiresZeroInitialization(Record[Idx++]);
E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]);
E->ParenRange = ReadSourceRange(Record, Idx);
@@ -1048,15 +1087,15 @@ void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
VisitExpr(E);
- assert(Record[Idx] == E->Param.getInt() && "We messed up at creation ?");
+ assert((bool)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->Param.setPointer(ReadDeclAs<ParmVarDecl>(Record, Idx));
E->Loc = ReadSourceLocation(Record, Idx);
}
void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
VisitExpr(E);
- E->setTemporary(Reader.ReadCXXTemporary(Record, Idx));
+ E->setTemporary(Reader.ReadCXXTemporary(F, Record, Idx));
E->setSubExpr(Reader.ReadSubExpr());
}
@@ -1072,13 +1111,12 @@ void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
E->Initializer = Record[Idx++];
E->UsualArrayDeleteWantsSize = Record[Idx++];
bool isArray = Record[Idx++];
+ E->setHadMultipleCandidates(Record[Idx++]);
unsigned NumPlacementArgs = Record[Idx++];
unsigned NumCtorArgs = Record[Idx++];
- E->setOperatorNew(cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
- E->setOperatorDelete(
- cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
- E->setConstructor(
- cast_or_null<CXXConstructorDecl>(Reader.GetDecl(Record[Idx++])));
+ E->setOperatorNew(ReadDeclAs<FunctionDecl>(Record, Idx));
+ E->setOperatorDelete(ReadDeclAs<FunctionDecl>(Record, Idx));
+ E->setConstructor(ReadDeclAs<CXXConstructorDecl>(Record, Idx));
E->AllocatedTypeInfo = GetTypeSourceInfo(Record, Idx);
SourceRange TypeIdParens;
TypeIdParens.setBegin(ReadSourceLocation(Record, Idx));
@@ -1089,7 +1127,7 @@ void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
E->ConstructorLParen = ReadSourceLocation(Record, Idx);
E->ConstructorRParen = ReadSourceLocation(Record, Idx);
- E->AllocateArgsArray(*Reader.getContext(), isArray, NumPlacementArgs,
+ E->AllocateArgsArray(Reader.getContext(), isArray, NumPlacementArgs,
NumCtorArgs);
// Install all the subexpressions.
@@ -1104,7 +1142,7 @@ void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
E->ArrayForm = Record[Idx++];
E->ArrayFormAsWritten = Record[Idx++];
E->UsualArrayDeleteWantsSize = Record[Idx++];
- E->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
+ E->OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx);
E->Argument = Reader.ReadSubExpr();
E->Loc = ReadSourceLocation(Record, Idx);
}
@@ -1120,7 +1158,7 @@ void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
E->ColonColonLoc = ReadSourceLocation(Record, Idx);
E->TildeLoc = ReadSourceLocation(Record, Idx);
- IdentifierInfo *II = Reader.GetIdentifierInfo(Record, Idx);
+ IdentifierInfo *II = Reader.GetIdentifierInfo(F, Record, Idx);
if (II)
E->setDestroyedType(II, ReadSourceLocation(Record, Idx));
else
@@ -1131,9 +1169,9 @@ void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) {
VisitExpr(E);
unsigned NumTemps = Record[Idx++];
if (NumTemps) {
- E->setNumTemporaries(*Reader.getContext(), NumTemps);
+ E->setNumTemporaries(Reader.getContext(), NumTemps);
for (unsigned i = 0; i != NumTemps; ++i)
- E->setTemporary(i, Reader.ReadCXXTemporary(Record, Idx));
+ E->setTemporary(i, Reader.ReadCXXTemporary(F, Record, Idx));
}
E->setSubExpr(Reader.ReadSubExpr());
}
@@ -1147,12 +1185,11 @@ ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
Record[Idx++]);
E->Base = Reader.ReadSubExpr();
- E->BaseType = Reader.GetType(Record[Idx++]);
+ E->BaseType = Reader.readType(F, Record, Idx);
E->IsArrow = Record[Idx++];
E->OperatorLoc = ReadSourceLocation(Record, Idx);
E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
- E->FirstQualifierFoundInScope
- = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ E->FirstQualifierFoundInScope = ReadDeclAs<NamedDecl>(Record, Idx);
ReadDeclarationNameInfo(E->MemberNameInfo, Record, Idx);
}
@@ -1191,11 +1228,11 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
unsigned NumDecls = Record[Idx++];
UnresolvedSet<8> Decls;
for (unsigned i = 0; i != NumDecls; ++i) {
- NamedDecl *D = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ NamedDecl *D = ReadDeclAs<NamedDecl>(Record, Idx);
AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
Decls.addDecl(D, AS);
}
- E->initializeResults(*Reader.getContext(), Decls.begin(), Decls.end());
+ E->initializeResults(Reader.getContext(), Decls.begin(), Decls.end());
ReadDeclarationNameInfo(E->NameInfo, Record, Idx);
E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
@@ -1206,7 +1243,7 @@ void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
E->IsArrow = Record[Idx++];
E->HasUnresolvedUsing = Record[Idx++];
E->Base = Reader.ReadSubExpr();
- E->BaseType = Reader.GetType(Record[Idx++]);
+ E->BaseType = Reader.readType(F, Record, Idx);
E->OperatorLoc = ReadSourceLocation(Record, Idx);
}
@@ -1216,7 +1253,7 @@ void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
if (E->RequiresADL)
E->StdIsAssociatedNamespace = Record[Idx++];
E->Overloaded = Record[Idx++];
- E->NamingClass = cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
+ E->NamingClass = ReadDeclAs<CXXRecordDecl>(Record, Idx);
}
void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
@@ -1280,14 +1317,13 @@ void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
E->PackLoc = ReadSourceLocation(Record, Idx);
E->RParenLoc = ReadSourceLocation(Record, Idx);
E->Length = Record[Idx++];
- E->Pack = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
+ E->Pack = ReadDeclAs<NamedDecl>(Record, Idx);
}
void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
- E->Param
- = cast_or_null<NonTypeTemplateParmDecl>(Reader.GetDecl(Record[Idx++]));
+ E->Param = ReadDeclAs<NonTypeTemplateParmDecl>(Record, Idx);
E->NameLoc = ReadSourceLocation(Record, Idx);
E->Replacement = Reader.ReadSubExpr();
}
@@ -1295,8 +1331,7 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
void ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr(
SubstNonTypeTemplateParmPackExpr *E) {
VisitExpr(E);
- E->Param
- = cast_or_null<NonTypeTemplateParmDecl>(Reader.GetDecl(Record[Idx++]));
+ E->Param = ReadDeclAs<NonTypeTemplateParmDecl>(Record, Idx);
TemplateArgument ArgPack = Reader.ReadTemplateArgument(F, Record, Idx);
if (ArgPack.getKind() != TemplateArgument::Pack)
return;
@@ -1377,7 +1412,7 @@ void ASTStmtReader::VisitAsTypeExpr(AsTypeExpr *E) {
// ASTReader Implementation
//===----------------------------------------------------------------------===//
-Stmt *ASTReader::ReadStmt(PerFileData &F) {
+Stmt *ASTReader::ReadStmt(Module &F) {
switch (ReadingKind) {
case Read_Decl:
case Read_Type:
@@ -1390,7 +1425,7 @@ Stmt *ASTReader::ReadStmt(PerFileData &F) {
return 0;
}
-Expr *ASTReader::ReadExpr(PerFileData &F) {
+Expr *ASTReader::ReadExpr(Module &F) {
return cast_or_null<Expr>(ReadStmt(F));
}
@@ -1405,7 +1440,7 @@ 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(PerFileData &F) {
+Stmt *ASTReader::ReadStmtFromStream(Module &F) {
ReadingKindTracker ReadingKind(Read_Stmt, *this);
llvm::BitstreamCursor &Cursor = F.DeclsCursor;
@@ -1531,20 +1566,20 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
case EXPR_DECL_REF:
S = DeclRefExpr::CreateEmpty(
- *Context,
+ Context,
/*HasQualifier=*/Record[ASTStmtReader::NumExprFields],
/*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1],
/*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2],
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2] ?
- Record[ASTStmtReader::NumExprFields + 3] : 0);
+ Record[ASTStmtReader::NumExprFields + 4] : 0);
break;
case EXPR_INTEGER_LITERAL:
- S = IntegerLiteral::Create(*Context, Empty);
+ S = IntegerLiteral::Create(Context, Empty);
break;
case EXPR_FLOATING_LITERAL:
- S = FloatingLiteral::Create(*Context, Empty);
+ S = FloatingLiteral::Create(Context, Empty);
break;
case EXPR_IMAGINARY_LITERAL:
@@ -1552,7 +1587,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_STRING_LITERAL:
- S = StringLiteral::CreateEmpty(*Context,
+ S = StringLiteral::CreateEmpty(Context,
Record[ASTStmtReader::NumExprFields + 1]);
break;
@@ -1573,7 +1608,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_OFFSETOF:
- S = OffsetOfExpr::CreateEmpty(*Context,
+ S = OffsetOfExpr::CreateEmpty(Context,
Record[ASTStmtReader::NumExprFields],
Record[ASTStmtReader::NumExprFields + 1]);
break;
@@ -1587,7 +1622,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_CALL:
- S = new (Context) CallExpr(*Context, Stmt::CallExprClass, Empty);
+ S = new (Context) CallExpr(Context, Stmt::CallExprClass, Empty);
break;
case EXPR_MEMBER: {
@@ -1610,25 +1645,29 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
for (unsigned i = 0; i != NumTemplateArgs; ++i)
ArgInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Idx));
}
-
- NamedDecl *FoundD = cast_or_null<NamedDecl>(GetDecl(Record[Idx++]));
+
+ bool HadMultipleCandidates = Record[Idx++];
+
+ NamedDecl *FoundD = ReadDeclAs<NamedDecl>(F, Record, Idx);
AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS);
- QualType T = GetType(Record[Idx++]);
+ QualType T = readType(F, 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++]));
+ ValueDecl *MemberD = ReadDeclAs<ValueDecl>(F, Record, Idx);
SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx);
DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc);
bool IsArrow = Record[Idx++];
- S = MemberExpr::Create(*Context, Base, IsArrow, QualifierLoc,
+ S = MemberExpr::Create(Context, Base, IsArrow, QualifierLoc,
MemberD, FoundDecl, MemberNameInfo,
HasExplicitTemplateArgs ? &ArgInfo : 0, T, VK, OK);
ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc,
MemberD->getDeclName(), Record, Idx);
+ if (HadMultipleCandidates)
+ cast<MemberExpr>(S)->setHadMultipleCandidates(true);
break;
}
@@ -1649,12 +1688,12 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_IMPLICIT_CAST:
- S = ImplicitCastExpr::CreateEmpty(*Context,
+ S = ImplicitCastExpr::CreateEmpty(Context,
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
break;
case EXPR_CSTYLE_CAST:
- S = CStyleCastExpr::CreateEmpty(*Context,
+ S = CStyleCastExpr::CreateEmpty(Context,
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
break;
@@ -1667,11 +1706,11 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_INIT_LIST:
- S = new (Context) InitListExpr(*getContext(), Empty);
+ S = new (Context) InitListExpr(getContext(), Empty);
break;
case EXPR_DESIGNATED_INIT:
- S = DesignatedInitExpr::CreateEmpty(*Context,
+ S = DesignatedInitExpr::CreateEmpty(Context,
Record[ASTStmtReader::NumExprFields] - 1);
break;
@@ -1738,8 +1777,9 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
llvm_unreachable("mismatching AST file");
break;
case EXPR_OBJC_MESSAGE_EXPR:
- S = ObjCMessageExpr::CreateEmpty(*Context,
- Record[ASTStmtReader::NumExprFields]);
+ S = ObjCMessageExpr::CreateEmpty(Context,
+ Record[ASTStmtReader::NumExprFields],
+ Record[ASTStmtReader::NumExprFields + 1]);
break;
case EXPR_OBJC_ISA:
S = new (Context) ObjCIsaExpr(Empty);
@@ -1760,7 +1800,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
S = new (Context) ObjCAtFinallyStmt(Empty);
break;
case STMT_OBJC_AT_TRY:
- S = ObjCAtTryStmt::CreateEmpty(*Context,
+ S = ObjCAtTryStmt::CreateEmpty(Context,
Record[ASTStmtReader::NumStmtFields],
Record[ASTStmtReader::NumStmtFields + 1]);
break;
@@ -1787,7 +1827,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case STMT_CXX_TRY:
- S = CXXTryStmt::Create(*Context, Empty,
+ S = CXXTryStmt::Create(Context, Empty,
/*NumHandlers=*/Record[ASTStmtReader::NumStmtFields]);
break;
@@ -1796,11 +1836,11 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_CXX_OPERATOR_CALL:
- S = new (Context) CXXOperatorCallExpr(*Context, Empty);
+ S = new (Context) CXXOperatorCallExpr(Context, Empty);
break;
case EXPR_CXX_MEMBER_CALL:
- S = new (Context) CXXMemberCallExpr(*Context, Empty);
+ S = new (Context) CXXMemberCallExpr(Context, Empty);
break;
case EXPR_CXX_CONSTRUCT:
@@ -1812,26 +1852,26 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_CXX_STATIC_CAST:
- S = CXXStaticCastExpr::CreateEmpty(*Context,
+ S = CXXStaticCastExpr::CreateEmpty(Context,
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
break;
case EXPR_CXX_DYNAMIC_CAST:
- S = CXXDynamicCastExpr::CreateEmpty(*Context,
+ S = CXXDynamicCastExpr::CreateEmpty(Context,
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
break;
case EXPR_CXX_REINTERPRET_CAST:
- S = CXXReinterpretCastExpr::CreateEmpty(*Context,
+ S = CXXReinterpretCastExpr::CreateEmpty(Context,
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
break;
case EXPR_CXX_CONST_CAST:
- S = CXXConstCastExpr::CreateEmpty(*Context);
+ S = CXXConstCastExpr::CreateEmpty(Context);
break;
case EXPR_CXX_FUNCTIONAL_CAST:
- S = CXXFunctionalCastExpr::CreateEmpty(*Context,
+ S = CXXFunctionalCastExpr::CreateEmpty(Context,
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
break;
@@ -1864,7 +1904,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
bool HasOtherExprStored = Record[ASTStmtReader::NumExprFields];
if (HasOtherExprStored) {
Expr *SubExpr = ReadSubExpr();
- S = CXXDefaultArgExpr::Create(*Context, SourceLocation(), 0, SubExpr);
+ S = CXXDefaultArgExpr::Create(Context, SourceLocation(), 0, SubExpr);
} else
S = new (Context) CXXDefaultArgExpr(Empty);
break;
@@ -1891,7 +1931,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
- S = CXXDependentScopeMemberExpr::CreateEmpty(*Context,
+ S = CXXDependentScopeMemberExpr::CreateEmpty(Context,
/*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields],
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
? Record[ASTStmtReader::NumExprFields + 1]
@@ -1899,7 +1939,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
- S = DependentScopeDeclRefExpr::CreateEmpty(*Context,
+ S = DependentScopeDeclRefExpr::CreateEmpty(Context,
/*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields],
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
? Record[ASTStmtReader::NumExprFields + 1]
@@ -1907,12 +1947,12 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_CXX_UNRESOLVED_CONSTRUCT:
- S = CXXUnresolvedConstructExpr::CreateEmpty(*Context,
+ S = CXXUnresolvedConstructExpr::CreateEmpty(Context,
/*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
break;
case EXPR_CXX_UNRESOLVED_MEMBER:
- S = UnresolvedMemberExpr::CreateEmpty(*Context,
+ S = UnresolvedMemberExpr::CreateEmpty(Context,
/*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields],
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
? Record[ASTStmtReader::NumExprFields + 1]
@@ -1920,7 +1960,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
break;
case EXPR_CXX_UNRESOLVED_LOOKUP:
- S = UnresolvedLookupExpr::CreateEmpty(*Context,
+ S = UnresolvedLookupExpr::CreateEmpty(Context,
/*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields],
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
? Record[ASTStmtReader::NumExprFields + 1]
@@ -1983,12 +2023,16 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
}
case EXPR_CUDA_KERNEL_CALL:
- S = new (Context) CUDAKernelCallExpr(*Context, Empty);
+ S = new (Context) CUDAKernelCallExpr(Context, Empty);
break;
case EXPR_ASTYPE:
S = new (Context) AsTypeExpr(Empty);
break;
+
+ case EXPR_ATOMIC:
+ S = new (Context) AtomicExpr(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 39f2fbd..b31262d 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Serialization/ASTWriter.h"
-#include "clang/Serialization/ASTSerializationListener.h"
#include "ASTCommon.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/IdentifierResolver.h"
@@ -45,21 +44,23 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
+#include <algorithm>
#include <cstdio>
#include <string.h>
+#include <utility>
using namespace clang;
using namespace clang::serialization;
template <typename T, typename Allocator>
-static llvm::StringRef data(const std::vector<T, Allocator> &v) {
- if (v.empty()) return llvm::StringRef();
- return llvm::StringRef(reinterpret_cast<const char*>(&v[0]),
+static StringRef data(const std::vector<T, Allocator> &v) {
+ if (v.empty()) return StringRef();
+ return StringRef(reinterpret_cast<const char*>(&v[0]),
sizeof(T) * v.size());
}
template <typename T>
-static llvm::StringRef data(const llvm::SmallVectorImpl<T> &v) {
- return llvm::StringRef(reinterpret_cast<const char*>(v.data()),
+static StringRef data(const SmallVectorImpl<T> &v) {
+ return StringRef(reinterpret_cast<const char*>(v.data()),
sizeof(T) * v.size());
}
@@ -90,7 +91,7 @@ namespace {
}
void ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) {
- assert(false && "Built-in types are never serialized");
+ llvm_unreachable("Built-in types are never serialized");
}
void ASTTypeWriter::VisitComplexType(const ComplexType *T) {
@@ -304,7 +305,7 @@ void
ASTTypeWriter::VisitDependentSizedExtVectorType(
const DependentSizedExtVectorType *T) {
// FIXME: Serialize this type (C++ only)
- assert(false && "Cannot serialize dependent sized extended vector types");
+ llvm_unreachable("Cannot serialize dependent sized extended vector types");
}
void
@@ -387,6 +388,12 @@ ASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
Code = TYPE_OBJC_OBJECT_POINTER;
}
+void
+ASTTypeWriter::VisitAtomicType(const AtomicType *T) {
+ Writer.AddTypeRef(T->getValueType(), Record);
+ Code = TYPE_ATOMIC;
+}
+
namespace {
class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
@@ -595,6 +602,11 @@ void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
Writer.AddSourceLocation(TL.getStarLoc(), Record);
}
+void TypeLocWriter::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
+ Writer.AddSourceLocation(TL.getKWLoc(), Record);
+ Writer.AddSourceLocation(TL.getLParenLoc(), Record);
+ Writer.AddSourceLocation(TL.getRParenLoc(), Record);
+}
//===----------------------------------------------------------------------===//
// ASTWriter Implementation
@@ -762,8 +774,8 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(STAT_CACHE);
RECORD(EXT_VECTOR_DECLS);
RECORD(VERSION_CONTROL_BRANCH_REVISION);
- RECORD(MACRO_DEFINITION_OFFSETS);
- RECORD(CHAINED_METADATA);
+ RECORD(PPD_ENTITIES_OFFSETS);
+ RECORD(IMPORTS);
RECORD(REFERENCED_SELECTOR_POOL);
RECORD(TU_UPDATE_LEXICAL);
RECORD(REDECLS_UPDATE_LATEST);
@@ -778,11 +790,14 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(DIAG_PRAGMA_MAPPINGS);
RECORD(CUDA_SPECIAL_DECL_REFS);
RECORD(HEADER_SEARCH_TABLE);
+ RECORD(ORIGINAL_PCH_DIR);
RECORD(FP_PRAGMA_OPTIONS);
RECORD(OPENCL_EXTENSIONS);
RECORD(DELEGATING_CTORS);
RECORD(FILE_SOURCE_LOCATION_OFFSETS);
RECORD(KNOWN_NAMESPACES);
+ RECORD(MODULE_OFFSET_MAP);
+ RECORD(SOURCE_MANAGER_LINE_TABLE);
// SourceManager Block.
BLOCK(SOURCE_MANAGER_BLOCK);
@@ -790,7 +805,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(SM_SLOC_BUFFER_ENTRY);
RECORD(SM_SLOC_BUFFER_BLOB);
RECORD(SM_SLOC_EXPANSION_ENTRY);
- RECORD(SM_LINE_TABLE);
// Preprocessor Block.
BLOCK(PREPROCESSOR_BLOCK);
@@ -837,7 +851,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(TYPE_PACK_EXPANSION);
RECORD(TYPE_ATTRIBUTED);
RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
- RECORD(DECL_TRANSLATION_UNIT);
+ RECORD(TYPE_ATOMIC);
RECORD(DECL_TYPEDEF);
RECORD(DECL_ENUM);
RECORD(DECL_RECORD);
@@ -916,15 +930,15 @@ void ASTWriter::WriteBlockInfoBlock() {
/// \returns either the original filename (if it needs no adjustment) or the
/// adjusted filename (which points into the @p Filename parameter).
static const char *
-adjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) {
+adjustFilenameForRelocatablePCH(const char *Filename, StringRef isysroot) {
assert(Filename && "No file name to adjust?");
- if (!isysroot)
+ if (isysroot.empty())
return Filename;
// Verify that the filename and the system root have the same prefix.
unsigned Pos = 0;
- for (; Filename[Pos] && isysroot[Pos]; ++Pos)
+ for (; Filename[Pos] && Pos < isysroot.size(); ++Pos)
if (Filename[Pos] != isysroot[Pos])
return Filename; // Prefixes don't match.
@@ -942,34 +956,52 @@ 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, StringRef isysroot,
const std::string &OutputFile) {
using namespace llvm;
// Metadata
- const TargetInfo &Target = Context.Target;
+ const TargetInfo &Target = Context.getTargetInfo();
BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev();
- MetaAbbrev->Add(BitCodeAbbrevOp(
- Chain ? CHAINED_METADATA : METADATA));
+ MetaAbbrev->Add(BitCodeAbbrevOp(METADATA));
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
- // Target triple or chained PCH name
- MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
RecordData Record;
- Record.push_back(Chain ? CHAINED_METADATA : METADATA);
+ Record.push_back(METADATA);
Record.push_back(VERSION_MAJOR);
Record.push_back(VERSION_MINOR);
Record.push_back(CLANG_VERSION_MAJOR);
Record.push_back(CLANG_VERSION_MINOR);
- Record.push_back(isysroot != 0);
- // FIXME: This writes the absolute path for chained headers.
- const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple();
- Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr);
+ Record.push_back(!isysroot.empty());
+ const std::string &Triple = Target.getTriple().getTriple();
+ Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, Triple);
+
+ if (Chain) {
+ serialization::ModuleManager &Mgr = Chain->getModuleManager();
+ llvm::SmallVector<char, 128> ModulePaths;
+ Record.clear();
+
+ for (ModuleManager::ModuleIterator M = Mgr.begin(), MEnd = Mgr.end();
+ M != MEnd; ++M) {
+ // Skip modules that weren't directly imported.
+ if (!(*M)->isDirectlyImported())
+ continue;
+
+ Record.push_back((unsigned)(*M)->Kind); // FIXME: Stable encoding
+ // FIXME: Write import location, once it matters.
+ // FIXME: This writes the absolute path for AST files we depend on.
+ const std::string &FileName = (*M)->FileName;
+ Record.push_back(FileName.size());
+ Record.append(FileName.begin(), FileName.end());
+ }
+ Stream.EmitRecord(IMPORTS, Record);
+ }
// Original file name and file ID
SourceManager &SM = Context.getSourceManager();
@@ -1026,94 +1058,11 @@ void ASTWriter::WriteMetadata(ASTContext &Context, const char *isysroot,
/// \brief Write the LangOptions structure.
void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
RecordData Record;
- Record.push_back(LangOpts.Trigraphs);
- Record.push_back(LangOpts.BCPLComment); // BCPL-style '//' comments.
- Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers.
- Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode.
- Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc)
- Record.push_back(LangOpts.GNUKeywords); // Allow GNU-extension keywords
- Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'.
- Record.push_back(LangOpts.Digraphs); // C94, C99 and C++
- Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants.
- Record.push_back(LangOpts.C99); // C99 Support
- Record.push_back(LangOpts.C1X); // C1X 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.
-
- Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled.
- Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled.
- Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C
- // 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.ObjCInferRelatedResultType);
- Record.push_back(LangOpts.NoConstantCFStrings); // non cfstring generation enabled..
-
- Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings
- Record.push_back(LangOpts.WritableStrings); // Allow writable strings
- Record.push_back(LangOpts.LaxVectorConversions);
- Record.push_back(LangOpts.AltiVec);
- Record.push_back(LangOpts.Exceptions); // Support exception handling.
- Record.push_back(LangOpts.ObjCExceptions);
- Record.push_back(LangOpts.CXXExceptions);
- Record.push_back(LangOpts.SjLjExceptions);
-
- 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)
-
- // Whether static initializers are protected by locks.
- Record.push_back(LangOpts.ThreadsafeStatics);
- Record.push_back(LangOpts.POSIXThreads);
- Record.push_back(LangOpts.Blocks); // block extension to C
- Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if
- // they are unused.
- Record.push_back(LangOpts.MathErrno); // Math functions must respect errno
- // (modulo the platform support).
-
- Record.push_back(LangOpts.getSignedOverflowBehavior());
- Record.push_back(LangOpts.HeinousExtensions);
-
- Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined.
- Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be
- // defined.
- Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as
- // opposed to __DYNAMIC__).
- Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero.
-
- Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be
- // used (instead of C99 semantics).
- Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined.
- Record.push_back(LangOpts.Deprecated); // Should __DEPRECATED be defined.
- Record.push_back(LangOpts.AccessControl); // Whether C++ access control should
- // be enabled.
- 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);
- Record.push_back(LangOpts.MRTD);
- Record.push_back(LangOpts.ObjCAutoRefCount);
- Record.push_back(LangOpts.ObjCInferRelatedReturnType);
+#define LANGOPT(Name, Bits, Default, Description) \
+ Record.push_back(LangOpts.Name);
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+ Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
+#include "clang/Basic/LangOptions.def"
Stream.EmitRecord(LANGUAGE_OPTIONS, Record);
}
@@ -1136,7 +1085,7 @@ public:
}
std::pair<unsigned,unsigned>
- EmitKeyDataLength(llvm::raw_ostream& Out, const char *path,
+ EmitKeyDataLength(raw_ostream& Out, const char *path,
data_type_ref Data) {
unsigned StrLen = strlen(path);
clang::io::Emit16(Out, StrLen);
@@ -1145,11 +1094,11 @@ public:
return std::make_pair(StrLen + 1, DataLen);
}
- void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) {
+ void EmitKey(raw_ostream& Out, const char *path, unsigned KeyLen) {
Out.write(path, KeyLen);
}
- void EmitData(llvm::raw_ostream &Out, key_type_ref,
+ void EmitData(raw_ostream &Out, key_type_ref,
data_type_ref Data, unsigned DataLen) {
using namespace clang::io;
uint64_t Start = Out.tell(); (void)Start;
@@ -1174,7 +1123,7 @@ void ASTWriter::WriteStatCache(MemorizeStatCalls &StatCalls) {
for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
StatEnd = StatCalls.end();
Stat != StatEnd; ++Stat, ++NumStatEntries) {
- llvm::StringRef Filename = Stat->first();
+ StringRef Filename = Stat->first();
Generator.insert(Filename.data(), Stat->second);
}
@@ -1222,6 +1171,7 @@ static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
// FileEntry fields.
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumCreatedFIDs
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
return Stream.EmitAbbrev(Abbrev);
}
@@ -1270,6 +1220,10 @@ namespace {
ASTWriter &Writer;
HeaderSearch &HS;
+ // Keep track of the framework names we've used during serialization.
+ SmallVector<char, 128> FrameworkStringData;
+ llvm::StringMap<unsigned> FrameworkNameOffset;
+
public:
HeaderFileInfoTrait(ASTWriter &Writer, HeaderSearch &HS)
: Writer(Writer), HS(HS) { }
@@ -1289,28 +1243,29 @@ namespace {
}
std::pair<unsigned,unsigned>
- EmitKeyDataLength(llvm::raw_ostream& Out, const char *path,
+ EmitKeyDataLength(raw_ostream& Out, const char *path,
data_type_ref Data) {
unsigned StrLen = strlen(path);
clang::io::Emit16(Out, StrLen);
- unsigned DataLen = 1 + 2 + 4;
+ unsigned DataLen = 1 + 2 + 4 + 4;
clang::io::Emit8(Out, DataLen);
return std::make_pair(StrLen + 1, DataLen);
}
- void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) {
+ void EmitKey(raw_ostream& Out, const char *path, unsigned KeyLen) {
Out.write(path, KeyLen);
}
- void EmitData(llvm::raw_ostream &Out, key_type_ref,
+ void EmitData(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 << 4)
- | (Data.isPragmaOnce << 3)
- | (Data.DirInfo << 1)
- | Data.Resolved;
+ unsigned char Flags = (Data.isImport << 5)
+ | (Data.isPragmaOnce << 4)
+ | (Data.DirInfo << 2)
+ | (Data.Resolved << 1)
+ | Data.IndexHeaderMapHeader;
Emit8(Out, (uint8_t)Flags);
Emit16(Out, (uint16_t) Data.NumIncludes);
@@ -1318,8 +1273,29 @@ namespace {
Emit32(Out, (uint32_t)Data.ControllingMacroID);
else
Emit32(Out, (uint32_t)Writer.getIdentifierRef(Data.ControllingMacro));
+
+ unsigned Offset = 0;
+ if (!Data.Framework.empty()) {
+ // If this header refers into a framework, save the framework name.
+ llvm::StringMap<unsigned>::iterator Pos
+ = FrameworkNameOffset.find(Data.Framework);
+ if (Pos == FrameworkNameOffset.end()) {
+ Offset = FrameworkStringData.size() + 1;
+ FrameworkStringData.append(Data.Framework.begin(),
+ Data.Framework.end());
+ FrameworkStringData.push_back(0);
+
+ FrameworkNameOffset[Data.Framework] = Offset;
+ } else
+ Offset = Pos->second;
+ }
+ Emit32(Out, Offset);
+
assert(Out.tell() - Start == DataLen && "Wrong data length");
}
+
+ const char *strings_begin() const { return FrameworkStringData.begin(); }
+ const char *strings_end() const { return FrameworkStringData.end(); }
};
} // end anonymous namespace
@@ -1328,8 +1304,8 @@ namespace {
/// \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;
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, StringRef isysroot) {
+ SmallVector<const FileEntry *, 16> FilesByUID;
HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
if (FilesByUID.size() > HS.header_file_size())
@@ -1337,7 +1313,7 @@ void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, const char* isysroot) {
HeaderFileInfoTrait GeneratorTrait(*this, HS);
OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;
- llvm::SmallVector<const char *, 4> SavedStrings;
+ SmallVector<const char *, 4> SavedStrings;
unsigned NumHeaderSearchEntries = 0;
for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
const FileEntry *File = FilesByUID[UID];
@@ -1379,14 +1355,17 @@ void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, const char* isysroot) {
Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_TABLE));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
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
+ // Write the header search table
RecordData Record;
Record.push_back(HEADER_SEARCH_TABLE);
Record.push_back(BucketOffset);
Record.push_back(NumHeaderSearchEntries);
+ Record.push_back(TableData.size());
+ TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end());
Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData.str());
// Free all of the strings we had to duplicate.
@@ -1404,7 +1383,7 @@ void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, const char* isysroot) {
/// the files in the AST.
void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP,
- const char *isysroot) {
+ StringRef isysroot) {
RecordData Record;
// Enter the source manager block.
@@ -1416,43 +1395,6 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream);
unsigned SLocExpansionAbbrv = CreateSLocExpansionAbbrev(Stream);
- // Write the line table.
- if (SourceMgr.hasLineTable()) {
- LineTableInfo &LineTable = SourceMgr.getLineTable();
-
- // Emit the file names
- Record.push_back(LineTable.getNumFilenames());
- for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
- // Emit the file name
- const char *Filename = LineTable.getFilename(I);
- Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
- unsigned FilenameLen = Filename? strlen(Filename) : 0;
- Record.push_back(FilenameLen);
- if (FilenameLen)
- Record.insert(Record.end(), Filename, Filename + FilenameLen);
- }
-
- // Emit the line entries
- for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
- L != LEnd; ++L) {
- // Emit the file ID
- Record.push_back(L->first);
-
- // Emit the line entries
- Record.push_back(L->second.size());
- for (std::vector<LineEntry>::iterator LE = L->second.begin(),
- LEEnd = L->second.end();
- LE != LEEnd; ++LE) {
- Record.push_back(LE->FileOffset);
- Record.push_back(LE->LineNo);
- Record.push_back(LE->FilenameID);
- Record.push_back((unsigned)LE->FileKind);
- Record.push_back(LE->IncludeOffset);
- }
- }
- Stream.EmitRecord(SM_LINE_TABLE, Record);
- }
-
// Write out the source location entry table. We skip the first
// entry, which is always the same dummy entry.
std::vector<uint32_t> SLocEntryOffsets;
@@ -1460,12 +1402,11 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// We will go through them in ASTReader::validateFileEntries().
std::vector<uint32_t> SLocFileEntryOffsets;
RecordData PreloadSLocs;
- unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0;
- SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID);
- for (unsigned I = BaseSLocID + 1, N = SourceMgr.sloc_entry_size();
+ SLocEntryOffsets.reserve(SourceMgr.local_sloc_entry_size() - 1);
+ for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size();
I != N; ++I) {
// Get this source location entry.
- const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I);
+ const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I);
// Record the offset of this source-location entry.
SLocEntryOffsets.push_back(Stream.GetCurrentBitNo());
@@ -1483,7 +1424,8 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
Record.clear();
Record.push_back(Code);
- Record.push_back(SLoc->getOffset());
+ // Starting offset of this entry within this module, so skip the dummy.
+ Record.push_back(SLoc->getOffset() - 2);
if (SLoc->isFile()) {
const SrcMgr::FileInfo &File = SLoc->getFile();
Record.push_back(File.getIncludeLoc().getRawEncoding());
@@ -1502,6 +1444,8 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
Record.push_back(Content->OrigEntry->getSize());
Record.push_back(Content->OrigEntry->getModificationTime());
+ Record.push_back(File.NumCreatedFIDs);
+
// Turn the file name into an absolute path, if it isn't already.
const char *Filename = Content->OrigEntry->getName();
llvm::SmallString<128> FilePath(Filename);
@@ -1528,27 +1472,29 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
= Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
const char *Name = Buffer->getBufferIdentifier();
Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
- llvm::StringRef(Name, strlen(Name) + 1));
+ StringRef(Name, strlen(Name) + 1));
Record.clear();
Record.push_back(SM_SLOC_BUFFER_BLOB);
Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
- llvm::StringRef(Buffer->getBufferStart(),
+ StringRef(Buffer->getBufferStart(),
Buffer->getBufferSize() + 1));
- if (strcmp(Name, "<built-in>") == 0)
- PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size());
+ if (strcmp(Name, "<built-in>") == 0) {
+ PreloadSLocs.push_back(SLocEntryOffsets.size());
+ }
}
} else {
// The source location entry is a macro expansion.
- const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation();
- Record.push_back(Inst.getSpellingLoc().getRawEncoding());
- Record.push_back(Inst.getInstantiationLocStart().getRawEncoding());
- Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding());
+ const SrcMgr::ExpansionInfo &Expansion = SLoc->getExpansion();
+ Record.push_back(Expansion.getSpellingLoc().getRawEncoding());
+ Record.push_back(Expansion.getExpansionLocStart().getRawEncoding());
+ Record.push_back(Expansion.isMacroArgExpansion() ? 0
+ : Expansion.getExpansionLocEnd().getRawEncoding());
// Compute the token length for this macro expansion.
- unsigned NextOffset = SourceMgr.getNextOffset();
+ unsigned NextOffset = SourceMgr.getNextLocalOffset();
if (I + 1 != N)
- NextOffset = SourceMgr.getSLocEntry(I + 1).getOffset();
+ NextOffset = SourceMgr.getLocalSLocEntry(I + 1).getOffset();
Record.push_back(NextOffset - SLoc->getOffset() - 1);
Stream.EmitRecordWithAbbrev(SLocExpansionAbbrv, Record);
}
@@ -1565,15 +1511,14 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // next offset
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // total size
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev);
Record.clear();
Record.push_back(SOURCE_LOCATION_OFFSETS);
Record.push_back(SLocEntryOffsets.size());
- unsigned BaseOffset = Chain ? Chain->getNextSLocOffset() : 0;
- Record.push_back(SourceMgr.getNextOffset() - BaseOffset);
+ Record.push_back(SourceMgr.getNextLocalOffset() - 1); // skip dummy
Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, data(SLocEntryOffsets));
Abbrev = new BitCodeAbbrev();
@@ -1591,6 +1536,49 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// Write the source location entry preloads array, telling the AST
// reader which source locations entries it should load eagerly.
Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs);
+
+ // Write the line table. It depends on remapping working, so it must come
+ // after the source location offsets.
+ if (SourceMgr.hasLineTable()) {
+ LineTableInfo &LineTable = SourceMgr.getLineTable();
+
+ Record.clear();
+ // Emit the file names
+ Record.push_back(LineTable.getNumFilenames());
+ for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
+ // Emit the file name
+ const char *Filename = LineTable.getFilename(I);
+ Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
+ unsigned FilenameLen = Filename? strlen(Filename) : 0;
+ Record.push_back(FilenameLen);
+ if (FilenameLen)
+ Record.insert(Record.end(), Filename, Filename + FilenameLen);
+ }
+
+ // Emit the line entries
+ for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
+ L != LEnd; ++L) {
+ // Only emit entries for local files.
+ if (L->first < 0)
+ continue;
+
+ // Emit the file ID
+ Record.push_back(L->first);
+
+ // Emit the line entries
+ Record.push_back(L->second.size());
+ for (std::vector<LineEntry>::iterator LE = L->second.begin(),
+ LEEnd = L->second.end();
+ LE != LEEnd; ++LE) {
+ Record.push_back(LE->FileOffset);
+ Record.push_back(LE->LineNo);
+ Record.push_back(LE->FilenameID);
+ Record.push_back((unsigned)LE->FileKind);
+ Record.push_back(LE->IncludeOffset);
+ }
+ }
+ Stream.EmitRecord(SOURCE_MANAGER_LINE_TABLE, Record);
+ }
}
//===----------------------------------------------------------------------===//
@@ -1608,7 +1596,11 @@ static int compareMacroDefinitions(const void *XPtr, const void *YPtr) {
/// \brief Writes the block containing the serialized form of the
/// preprocessor.
///
-void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
+void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
+ PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
+ if (PPRec)
+ WritePreprocessorDetail(*PPRec);
+
RecordData Record;
// If the preprocessor __COUNTER__ value has been bumped, remember it.
@@ -1629,17 +1621,18 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
// 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();
// Construct the list of macro definitions that need to be serialized.
- llvm::SmallVector<std::pair<const IdentifierInfo *, MacroInfo *>, 2>
+ 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));
+ if (!IsModule || I->second->isExported()) {
+ 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
@@ -1671,14 +1664,15 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
// 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()))
+ (Chain && Name->isFromAST() && MI->isFromAST() &&
+ !MI->hasChangedAfterLoad()))
continue;
AddIdentifierRef(Name, Record);
MacroOffsets[Name] = Stream.GetCurrentBitNo();
Record.push_back(MI->getDefinitionLoc().getRawEncoding());
Record.push_back(MI->isUsed());
-
+ AddSourceLocation(MI->getExportLocation(), Record);
unsigned Code;
if (MI->isObjectLike()) {
Code = PP_MACRO_OBJECT_LIKE;
@@ -1696,7 +1690,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
// 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)));
+ Record.push_back(MacroDefinitions[PPRec->findMacroDefinition(MI)]);
Stream.EmitRecord(Code, Record);
Record.clear();
@@ -1725,15 +1719,14 @@ 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))
+ if (PPRec.local_begin() == PPRec.local_end())
return;
-
+
+ SmallVector<PPEntityOffset, 64> PreprocessedEntityOffsets;
+
// Enter the preprocessor block.
Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3);
@@ -1746,9 +1739,6 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
{
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
@@ -1756,65 +1746,41 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
InclusionAbbrev = Stream.EmitAbbrev(Abbrev);
}
- unsigned IndexBase = Chain ? PPRec.getNumPreallocatedEntities() : 0;
+ unsigned FirstPreprocessorEntityID
+ = (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0)
+ + NUM_PREDEF_PP_ENTITY_IDS;
+ unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID;
RecordData Record;
- for (PreprocessingRecord::iterator E = PPRec.begin(Chain),
- EEnd = PPRec.end(Chain);
- E != EEnd; ++E) {
+ for (PreprocessingRecord::iterator E = PPRec.local_begin(),
+ EEnd = PPRec.local_end();
+ E != EEnd;
+ (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) {
Record.clear();
+ PreprocessedEntityOffsets.push_back(PPEntityOffset((*E)->getSourceRange(),
+ Stream.GetCurrentBitNo()));
+
if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
- // Record this macro definition's location.
- MacroID ID = getMacroDefinitionID(MD);
-
- // Don't write the macro definition if it is from another AST file.
- if (ID < FirstMacroID)
- continue;
+ // Record this macro definition's ID.
+ MacroDefinitions[MD] = NextPreprocessorEntityID;
- // 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);
-
- 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 (MacroExpansion *ME = dyn_cast<MacroExpansion>(*E)) {
- Record.push_back(IndexBase + NumPreprocessingRecords++);
- AddSourceLocation(ME->getSourceRange().getBegin(), Record);
- AddSourceLocation(ME->getSourceRange().getEnd(), Record);
- AddIdentifierRef(ME->getName(), Record);
- Record.push_back(getMacroDefinitionID(ME->getDefinition()));
+ Record.push_back(ME->isBuiltinMacro());
+ if (ME->isBuiltinMacro())
+ AddIdentifierRef(ME->getName(), Record);
+ else
+ Record.push_back(MacroDefinitions[ME->getDefinition()]);
Stream.EmitRecord(PPD_MACRO_EXPANSION, 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()));
@@ -1831,40 +1797,39 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
// Write the offsets table for the preprocessing record.
if (NumPreprocessingRecords > 0) {
+ assert(PreprocessedEntityOffsets.size() == NumPreprocessingRecords);
+
// Write the offsets table for identifier IDs.
using namespace llvm;
BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
- Abbrev->Add(BitCodeAbbrevOp(MACRO_DEFINITION_OFFSETS));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of records
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macro defs
+ Abbrev->Add(BitCodeAbbrevOp(PPD_ENTITIES_OFFSETS));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first pp entity
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned MacroDefOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
+ unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
Record.clear();
- Record.push_back(MACRO_DEFINITION_OFFSETS);
- Record.push_back(NumPreprocessingRecords);
- Record.push_back(MacroDefinitionOffsets.size());
- Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record,
- data(MacroDefinitionOffsets));
+ Record.push_back(PPD_ENTITIES_OFFSETS);
+ Record.push_back(FirstPreprocessorEntityID - NUM_PREDEF_PP_ENTITY_IDS);
+ Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record,
+ data(PreprocessedEntityOffsets));
}
}
-void ASTWriter::WritePragmaDiagnosticMappings(const Diagnostic &Diag) {
+void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag) {
RecordData Record;
- for (Diagnostic::DiagStatePointsTy::const_iterator
+ for (DiagnosticsEngine::DiagStatePointsTy::const_iterator
I = Diag.DiagStatePoints.begin(), E = Diag.DiagStatePoints.end();
I != E; ++I) {
- const Diagnostic::DiagStatePoint &point = *I;
+ const DiagnosticsEngine::DiagStatePoint &point = *I;
if (point.Loc.isInvalid())
continue;
Record.push_back(point.Loc.getRawEncoding());
- for (Diagnostic::DiagState::iterator
+ for (DiagnosticsEngine::DiagState::const_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);
+ if (I->second.isPragma()) {
+ Record.push_back(I->first);
+ Record.push_back(I->second.getMapping());
}
}
Record.push_back(-1); // mark the end of the diag/map pairs for this
@@ -1890,7 +1855,7 @@ void ASTWriter::WriteCXXBaseSpecifiersOffsets() {
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
- // Write the selector offsets table.
+ // Write the base specifier offsets table.
Record.clear();
Record.push_back(CXX_BASE_SPECIFIER_OFFSETS);
Record.push_back(CXXBaseSpecifiersOffsets.size());
@@ -1964,7 +1929,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
uint64_t Offset = Stream.GetCurrentBitNo();
RecordData Record;
Record.push_back(DECL_CONTEXT_LEXICAL);
- llvm::SmallVector<KindDeclIDPair, 64> Decls;
+ SmallVector<KindDeclIDPair, 64> Decls;
for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
D != DEnd; ++D)
Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D)));
@@ -1982,22 +1947,26 @@ void ASTWriter::WriteTypeDeclOffsets() {
BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base type index
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
Record.clear();
Record.push_back(TYPE_OFFSET);
Record.push_back(TypeOffsets.size());
+ Record.push_back(FirstTypeID - NUM_PREDEF_TYPE_IDS);
Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, data(TypeOffsets));
// Write the declaration offsets array
Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
Record.clear();
Record.push_back(DECL_OFFSET);
Record.push_back(DeclOffsets.size());
+ Record.push_back(FirstDeclID - NUM_PREDEF_DECL_IDS);
Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets));
}
@@ -2027,7 +1996,7 @@ public:
}
std::pair<unsigned,unsigned>
- EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel,
+ EmitKeyDataLength(raw_ostream& Out, Selector Sel,
data_type_ref Methods) {
unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
clang::io::Emit16(Out, KeyLen);
@@ -2044,7 +2013,7 @@ public:
return std::make_pair(KeyLen, DataLen);
}
- void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) {
+ void EmitKey(raw_ostream& Out, Selector Sel, unsigned) {
uint64_t Start = Out.tell();
assert((Start >> 32) == 0 && "Selector key offset too large");
Writer.SetSelectorOffset(Sel, Start);
@@ -2057,7 +2026,7 @@ public:
Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
}
- void EmitData(llvm::raw_ostream& Out, key_type_ref,
+ void EmitData(raw_ostream& Out, key_type_ref,
data_type_ref Methods, unsigned DataLen) {
uint64_t Start = Out.tell(); (void)Start;
clang::io::Emit32(Out, Methods.ID);
@@ -2130,12 +2099,12 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
bool changed = false;
for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method;
M = M->Next) {
- if (M->Method->getPCHLevel() == 0)
+ if (!M->Method->isFromASTFile())
changed = true;
}
for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method;
M = M->Next) {
- if (M->Method->getPCHLevel() == 0)
+ if (!M->Method->isFromASTFile())
changed = true;
}
if (!changed)
@@ -2177,6 +2146,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
@@ -2184,6 +2154,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
Record.clear();
Record.push_back(SELECTOR_OFFSETS);
Record.push_back(SelectorOffsets.size());
+ Record.push_back(FirstSelectorID - NUM_PREDEF_SELECTOR_IDS);
Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record,
data(SelectorOffsets));
}
@@ -2219,41 +2190,53 @@ namespace {
class ASTIdentifierTableTrait {
ASTWriter &Writer;
Preprocessor &PP;
-
+ bool IsModule;
+
/// \brief Determines whether this is an "interesting" identifier
/// that needs a full IdentifierInfo structure written into the hash
/// table.
- static bool isInterestingIdentifier(const IdentifierInfo *II) {
- return II->isPoisoned() ||
- II->isExtensionToken() ||
- II->hasMacroDefinition() ||
- II->getObjCOrBuiltinID() ||
- II->getFETokenInfo<void>();
+ bool isInterestingIdentifier(IdentifierInfo *II, MacroInfo *&Macro) {
+ if (II->isPoisoned() ||
+ II->isExtensionToken() ||
+ II->getObjCOrBuiltinID() ||
+ II->getFETokenInfo<void>())
+ return true;
+
+ return hasMacroDefinition(II, Macro);
+ }
+
+ bool hasMacroDefinition(IdentifierInfo *II, MacroInfo *&Macro) {
+ if (!II->hasMacroDefinition())
+ return false;
+
+ if (Macro || (Macro = PP.getMacroInfo(II)))
+ return !Macro->isBuiltinMacro() && (!IsModule || Macro->isExported());
+
+ return false;
}
public:
- typedef const IdentifierInfo* key_type;
+ typedef IdentifierInfo* key_type;
typedef key_type key_type_ref;
typedef IdentID data_type;
typedef data_type data_type_ref;
- ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP)
- : Writer(Writer), PP(PP) { }
+ ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP, bool IsModule)
+ : Writer(Writer), PP(PP), IsModule(IsModule) { }
static unsigned ComputeHash(const IdentifierInfo* II) {
return llvm::HashString(II->getName());
}
std::pair<unsigned,unsigned>
- EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II,
- IdentID ID) {
+ EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
unsigned KeyLen = II->getLength() + 1;
unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
- if (isInterestingIdentifier(II)) {
+ MacroInfo *Macro = 0;
+ if (isInterestingIdentifier(II, Macro)) {
DataLen += 2; // 2 bytes for builtin ID, flags
- if (II->hasMacroDefinition() &&
- !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro())
+ if (hasMacroDefinition(II, Macro))
DataLen += 4;
for (IdentifierResolver::iterator D = IdentifierResolver::begin(II),
DEnd = IdentifierResolver::end();
@@ -2268,7 +2251,7 @@ public:
return std::make_pair(KeyLen, DataLen);
}
- void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II,
+ void EmitKey(raw_ostream& Out, const IdentifierInfo* II,
unsigned KeyLen) {
// Record the location of the key data. This is used when generating
// the mapping from persistent IDs to strings.
@@ -2276,27 +2259,26 @@ public:
Out.write(II->getNameStart(), KeyLen);
}
- void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II,
+ void EmitData(raw_ostream& Out, IdentifierInfo* II,
IdentID ID, unsigned) {
- if (!isInterestingIdentifier(II)) {
+ MacroInfo *Macro = 0;
+ if (!isInterestingIdentifier(II, Macro)) {
clang::io::Emit32(Out, ID << 1);
return;
}
clang::io::Emit32(Out, (ID << 1) | 0x01);
uint32_t Bits = 0;
- bool hasMacroDefinition =
- II->hasMacroDefinition() &&
- !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro();
+ bool HasMacroDefinition = hasMacroDefinition(II, Macro);
Bits = (uint32_t)II->getObjCOrBuiltinID();
- Bits = (Bits << 1) | unsigned(hasMacroDefinition);
+ Bits = (Bits << 1) | unsigned(HasMacroDefinition);
Bits = (Bits << 1) | unsigned(II->isExtensionToken());
Bits = (Bits << 1) | unsigned(II->isPoisoned());
Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());
Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
clang::io::Emit16(Out, Bits);
- if (hasMacroDefinition)
+ if (HasMacroDefinition)
clang::io::Emit32(Out, Writer.getMacroOffset(II));
// Emit the declaration IDs in reverse order, because the
@@ -2306,9 +2288,9 @@ public:
// adds declarations to the end of the list (so we need to see the
// struct "status" before the function "status").
// Only emit declarations that aren't from a chained PCH, though.
- llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II),
+ SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II),
IdentifierResolver::end());
- for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
+ for (SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
DEnd = Decls.rend();
D != DEnd; ++D)
clang::io::Emit32(Out, Writer.getDeclID(*D));
@@ -2321,14 +2303,14 @@ public:
/// The identifier table consists of a blob containing string data
/// (the actual identifiers themselves) and a separate "offsets" index
/// that maps identifier IDs to locations within the blob.
-void ASTWriter::WriteIdentifierTable(Preprocessor &PP) {
+void ASTWriter::WriteIdentifierTable(Preprocessor &PP, bool IsModule) {
using namespace llvm;
// Create and write out the blob that contains the identifier
// strings.
{
OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;
- ASTIdentifierTableTrait Trait(*this, PP);
+ ASTIdentifierTableTrait Trait(*this, PP, IsModule);
// Look for any identifiers that were named while processing the
// headers, but are otherwise not needed. We add these to the hash
@@ -2348,14 +2330,15 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP) {
ID != IDEnd; ++ID) {
assert(ID->first && "NULL identifier in identifier table");
if (!Chain || !ID->first->isFromAST())
- Generator.insert(ID->first, ID->second, Trait);
+ Generator.insert(const_cast<IdentifierInfo *>(ID->first), ID->second,
+ Trait);
}
// Create the on-disk hash table in a buffer.
llvm::SmallString<4096> IdentifierTable;
uint32_t BucketOffset;
{
- ASTIdentifierTableTrait Trait(*this, PP);
+ ASTIdentifierTableTrait Trait(*this, PP, IsModule);
llvm::raw_svector_ostream Out(IdentifierTable);
// Make sure that no bucket is at offset 0
clang::io::Emit32(Out, 0);
@@ -2380,12 +2363,14 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP) {
BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
RecordData Record;
Record.push_back(IDENTIFIER_OFFSET);
Record.push_back(IdentifierOffsets.size());
+ Record.push_back(FirstIdentID - NUM_PREDEF_IDENT_IDS);
Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
data(IdentifierOffsets));
}
@@ -2424,7 +2409,6 @@ public:
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName:
- ID.AddInteger(Writer.GetOrCreateTypeID(Name.getCXXNameType()));
break;
case DeclarationName::CXXOperatorName:
ID.AddInteger(Name.getCXXOverloadedOperator());
@@ -2439,7 +2423,7 @@ public:
}
std::pair<unsigned,unsigned>
- EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name,
+ EmitKeyDataLength(raw_ostream& Out, DeclarationName Name,
data_type_ref Lookup) {
unsigned KeyLen = 1;
switch (Name.getNameKind()) {
@@ -2447,15 +2431,15 @@ public:
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
case DeclarationName::CXXLiteralOperatorName:
KeyLen += 4;
break;
case DeclarationName::CXXOperatorName:
KeyLen += 1;
break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
case DeclarationName::CXXUsingDirective:
break;
}
@@ -2468,7 +2452,7 @@ public:
return std::make_pair(KeyLen, DataLen);
}
- void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) {
+ void EmitKey(raw_ostream& Out, DeclarationName Name, unsigned) {
using namespace clang::io;
assert(Name.getNameKind() < 0x100 && "Invalid name kind ?");
@@ -2482,11 +2466,6 @@ public:
case DeclarationName::ObjCMultiArgSelector:
Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector()));
break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- Emit32(Out, Writer.getTypeID(Name.getCXXNameType()));
- break;
case DeclarationName::CXXOperatorName:
assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?");
Emit8(Out, Name.getCXXOverloadedOperator());
@@ -2494,12 +2473,15 @@ public:
case DeclarationName::CXXLiteralOperatorName:
Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier()));
break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
case DeclarationName::CXXUsingDirective:
break;
}
}
- void EmitData(llvm::raw_ostream& Out, key_type_ref,
+ void EmitData(raw_ostream& Out, key_type_ref,
data_type Lookup, unsigned DataLen) {
uint64_t Start = Out.tell(); (void)Start;
clang::io::Emit16(Out, Lookup.second - Lookup.first);
@@ -2534,9 +2516,7 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
return 0;
// Force the DeclContext to build a its name-lookup table.
- if (DC->hasExternalVisibleStorage())
- DC->MaterializeVisibleDeclsFromExternalStorage();
- else
+ if (!DC->hasExternalVisibleStorage())
DC->lookup(DeclarationName());
// Serialize the contents of the mapping used for lookup. Note that,
@@ -2553,13 +2533,37 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
ASTDeclContextNameLookupTrait Trait(*this);
// Create the on-disk hash table representation.
+ DeclarationName ConversionName;
+ llvm::SmallVector<NamedDecl *, 4> ConversionDecls;
for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
D != DEnd; ++D) {
DeclarationName Name = D->first;
DeclContext::lookup_result Result = D->second.getLookupResult();
- Generator.insert(Name, Result, Trait);
+ if (Result.first != Result.second) {
+ if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
+ // Hash all conversion function names to the same name. The actual
+ // type information in conversion function name is not used in the
+ // key (since such type information is not stable across different
+ // modules), so the intended effect is to coalesce all of the conversion
+ // functions under a single key.
+ if (!ConversionName)
+ ConversionName = Name;
+ ConversionDecls.append(Result.first, Result.second);
+ continue;
+ }
+
+ Generator.insert(Name, Result, Trait);
+ }
}
+ // Add the conversion functions
+ if (!ConversionDecls.empty()) {
+ Generator.insert(ConversionName,
+ DeclContext::lookup_result(ConversionDecls.begin(),
+ ConversionDecls.end()),
+ Trait);
+ }
+
// Create the on-disk hash table in a buffer.
llvm::SmallString<4096> LookupTable;
uint32_t BucketOffset;
@@ -2602,7 +2606,8 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
DeclContext::lookup_result Result = D->second.getLookupResult();
// For any name that appears in this table, the results are complete, i.e.
// they overwrite results from previous PCHs. Merging is always a mess.
- Generator.insert(Name, Result, Trait);
+ if (Result.first != Result.second)
+ Generator.insert(Name, Result, Trait);
}
// Create the on-disk hash table in a buffer.
@@ -2652,14 +2657,14 @@ void ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) {
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);
+ AddSourceRange(A->getRange(), Record);
#include "clang/Serialization/AttrPCHWrite.inc"
}
}
-void ASTWriter::AddString(llvm::StringRef Str, RecordDataImpl &Record) {
+void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) {
Record.push_back(Str.size());
Record.insert(Record.end(), Str.begin(), Str.end());
}
@@ -2700,15 +2705,15 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
}
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
- : Stream(Stream), Chain(0), SerializationListener(0),
- FirstDeclID(1), NextDeclID(FirstDeclID),
+ : Stream(Stream), Context(0), Chain(0), WritingAST(false),
+ FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
- FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1),
- NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID),
+ FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
+ FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
CollectedStmts(&StmtsToEmit),
NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
NumVisibleDeclContexts(0),
- FirstCXXBaseSpecifiersID(1), NextCXXBaseSpecifiersID(1),
+ NextCXXBaseSpecifiersID(1),
DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0),
DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0),
DeclRefExprAbbrev(0), CharacterLiteralAbbrev(0),
@@ -2721,7 +2726,9 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
const std::string &OutputFile,
- const char *isysroot) {
+ bool IsModule, StringRef isysroot) {
+ WritingAST = true;
+
// Emit the file header.
Stream.Emit((unsigned)'C', 8);
Stream.Emit((unsigned)'P', 8);
@@ -2730,30 +2737,53 @@ void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
WriteBlockInfoBlock();
- if (Chain)
- WriteASTChain(SemaRef, StatCalls, isysroot);
- else
- WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile);
+ Context = &SemaRef.Context;
+ WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile, IsModule);
+ Context = 0;
+
+ WritingAST = false;
+}
+
+template<typename Vector>
+static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
+ ASTWriter::RecordData &Record) {
+ for (typename Vector::iterator I = Vec.begin(0, true), E = Vec.end();
+ I != E; ++I) {
+ Writer.AddDeclRef(*I, Record);
+ }
}
void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
- const char *isysroot,
- const std::string &OutputFile) {
+ StringRef isysroot,
+ const std::string &OutputFile, bool IsModule) {
using namespace llvm;
ASTContext &Context = SemaRef.Context;
Preprocessor &PP = SemaRef.PP;
- // The translation unit is the first declaration we'll emit.
- DeclIDs[Context.getTranslationUnitDecl()] = 1;
- ++NextDeclID;
- DeclTypesToEmit.push(Context.getTranslationUnitDecl());
-
- // Make sure that we emit IdentifierInfos (and any attached
- // declarations) for builtins.
- {
+ // Set up predefined declaration IDs.
+ DeclIDs[Context.getTranslationUnitDecl()] = PREDEF_DECL_TRANSLATION_UNIT_ID;
+ if (Context.ObjCIdDecl)
+ DeclIDs[Context.ObjCIdDecl] = PREDEF_DECL_OBJC_ID_ID;
+ if (Context.ObjCSelDecl)
+ DeclIDs[Context.ObjCSelDecl] = PREDEF_DECL_OBJC_SEL_ID;
+ if (Context.ObjCClassDecl)
+ DeclIDs[Context.ObjCClassDecl] = PREDEF_DECL_OBJC_CLASS_ID;
+ if (Context.Int128Decl)
+ DeclIDs[Context.Int128Decl] = PREDEF_DECL_INT_128_ID;
+ if (Context.UInt128Decl)
+ DeclIDs[Context.UInt128Decl] = PREDEF_DECL_UNSIGNED_INT_128_ID;
+ if (Context.ObjCInstanceTypeDecl)
+ DeclIDs[Context.ObjCInstanceTypeDecl] = PREDEF_DECL_OBJC_INSTANCETYPE_ID;
+
+ if (!Chain) {
+ // Make sure that we emit IdentifierInfos (and any attached
+ // declarations) for builtins. We don't need to do this when we're
+ // emitting chained PCH files, because all of the builtins will be
+ // in the original PCH file.
+ // FIXME: Modules won't like this at all.
IdentifierTable &Table = PP.getIdentifierTable();
- llvm::SmallVector<const char *, 32> BuiltinNames;
+ SmallVector<const char *, 32> BuiltinNames;
Context.BuiltinInfo.GetBuiltinNames(BuiltinNames,
Context.getLangOptions().NoBuiltin);
for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I)
@@ -2764,24 +2794,24 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// TentativeDefinitions order. Generally, this record will be empty for
// headers.
RecordData TentativeDefinitions;
- for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) {
- AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions);
- }
-
+ AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions, TentativeDefinitions);
+
// Build a record containing all of the file scoped decls in this file.
RecordData UnusedFileScopedDecls;
- for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i)
- AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls);
+ AddLazyVectorDecls(*this, SemaRef.UnusedFileScopedDecls,
+ UnusedFileScopedDecls);
+ // Build a record containing all of the delegating constructors we still need
+ // to resolve.
RecordData DelegatingCtorDecls;
- for (unsigned i=0, e = SemaRef.DelegatingCtorDecls.size(); i != e; ++i)
- AddDeclRef(SemaRef.DelegatingCtorDecls[i], DelegatingCtorDecls);
+ AddLazyVectorDecls(*this, SemaRef.DelegatingCtorDecls, DelegatingCtorDecls);
+ // Write the set of weak, undeclared identifiers. We always write the
+ // entire table, since later PCH files in a PCH chain are only interested in
+ // the results at the end of the chain.
RecordData WeakUndeclaredIdentifiers;
if (!SemaRef.WeakUndeclaredIdentifiers.empty()) {
- WeakUndeclaredIdentifiers.push_back(
- SemaRef.WeakUndeclaredIdentifiers.size());
- for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator
+ for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator
I = SemaRef.WeakUndeclaredIdentifiers.begin(),
E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) {
AddIdentifierRef(I->first, WeakUndeclaredIdentifiers);
@@ -2800,18 +2830,18 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
TD = SemaRef.LocallyScopedExternalDecls.begin(),
TDEnd = SemaRef.LocallyScopedExternalDecls.end();
- TD != TDEnd; ++TD)
- AddDeclRef(TD->second, LocallyScopedExternalDecls);
-
+ TD != TDEnd; ++TD) {
+ if (!TD->second->isFromASTFile())
+ AddDeclRef(TD->second, LocallyScopedExternalDecls);
+ }
+
// Build a record containing all of the ext_vector declarations.
RecordData ExtVectorDecls;
- for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I)
- AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls);
+ AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls);
// Build a record containing all of the VTable uses information.
RecordData VTableUses;
if (!SemaRef.VTableUses.empty()) {
- VTableUses.push_back(SemaRef.VTableUses.size());
for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
AddDeclRef(SemaRef.VTableUses[I].first, VTableUses);
AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
@@ -2821,8 +2851,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// Build a record containing all of dynamic classes declarations.
RecordData DynamicClasses;
- for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I)
- AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses);
+ AddLazyVectorDecls(*this, SemaRef.DynamicClasses, DynamicClasses);
// Build a record containing all of pending implicit instantiations.
RecordData PendingInstantiations;
@@ -2862,155 +2891,65 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
Stream.EnterSubblock(AST_BLOCK_ID, 5);
WriteMetadata(Context, isysroot, OutputFile);
WriteLanguageOptions(Context.getLangOptions());
- if (StatCalls && !isysroot)
+ if (StatCalls && isysroot.empty())
WriteStatCache(*StatCalls);
WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
- // Write the record of special types.
- Record.clear();
-
- AddTypeRef(Context.getBuiltinVaListType(), Record);
- AddTypeRef(Context.getObjCIdType(), Record);
- AddTypeRef(Context.getObjCSelType(), Record);
- AddTypeRef(Context.getObjCProtoType(), Record);
- AddTypeRef(Context.getObjCClassType(), Record);
- AddTypeRef(Context.getRawCFConstantStringType(), Record);
- AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record);
- AddTypeRef(Context.getFILEType(), Record);
- AddTypeRef(Context.getjmp_bufType(), Record);
- AddTypeRef(Context.getsigjmp_bufType(), Record);
- AddTypeRef(Context.ObjCIdRedefinitionType, Record);
- AddTypeRef(Context.ObjCClassRedefinitionType, Record);
- AddTypeRef(Context.getRawBlockdescriptorType(), Record);
- AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record);
- AddTypeRef(Context.ObjCSelRedefinitionType, Record);
- AddTypeRef(Context.getRawNSConstantStringType(), Record);
- Record.push_back(Context.isInt128Installed());
- AddTypeRef(Context.AutoDeductTy, Record);
- AddTypeRef(Context.AutoRRefDeductTy, Record);
- Stream.EmitRecord(SPECIAL_TYPES, Record);
-
- // Keep writing types and declarations until all types and
- // declarations have been written.
- Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
- WriteDeclsBlockAbbrevs();
- while (!DeclTypesToEmit.empty()) {
- DeclOrType DOT = DeclTypesToEmit.front();
- DeclTypesToEmit.pop();
- if (DOT.isType())
- WriteType(DOT.getType());
- else
- WriteDecl(Context, DOT.getDecl());
- }
- Stream.ExitBlock();
-
- WritePreprocessor(PP);
- WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot);
- WriteSelectors(SemaRef);
- WriteReferencedSelectorsPool(SemaRef);
- WriteIdentifierTable(PP);
- WriteFPPragmaOptions(SemaRef.getFPOptions());
- WriteOpenCLExtensions(SemaRef);
-
- WriteTypeDeclOffsets();
- WritePragmaDiagnosticMappings(Context.getDiagnostics());
-
- WriteCXXBaseSpecifiersOffsets();
-
- // Write the record containing external, unnamed definitions.
- if (!ExternalDefinitions.empty())
- Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions);
-
- // Write the record containing tentative definitions.
- if (!TentativeDefinitions.empty())
- Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
-
- // Write the record containing unused file scoped decls.
- if (!UnusedFileScopedDecls.empty())
- Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
-
- // Write the record containing weak undeclared identifiers.
- if (!WeakUndeclaredIdentifiers.empty())
- Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,
- WeakUndeclaredIdentifiers);
-
- // Write the record containing locally-scoped external definitions.
- if (!LocallyScopedExternalDecls.empty())
- Stream.EmitRecord(LOCALLY_SCOPED_EXTERNAL_DECLS,
- LocallyScopedExternalDecls);
-
- // Write the record containing ext_vector type names.
- if (!ExtVectorDecls.empty())
- Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
-
- // Write the record containing VTable uses information.
- if (!VTableUses.empty())
- Stream.EmitRecord(VTABLE_USES, VTableUses);
-
- // Write the record containing dynamic classes declarations.
- if (!DynamicClasses.empty())
- Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses);
-
- // Write the record containing pending implicit instantiations.
- if (!PendingInstantiations.empty())
- Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
-
- // Write the record containing declaration references of Sema.
- 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);
- // Write the delegating constructors.
- if (!DelegatingCtorDecls.empty())
- Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls);
-
- // Write the known namespaces.
- if (!KnownNamespaces.empty())
- Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
-
- // Some simple statistics
- Record.clear();
- Record.push_back(NumStatements);
- Record.push_back(NumMacros);
- Record.push_back(NumLexicalDeclContexts);
- Record.push_back(NumVisibleDeclContexts);
- Stream.EmitRecord(STATISTICS, Record);
- Stream.ExitBlock();
-}
-
-void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
- const char *isysroot) {
- using namespace llvm;
-
- ASTContext &Context = SemaRef.Context;
- Preprocessor &PP = SemaRef.PP;
-
- RecordData Record;
- Stream.EnterSubblock(AST_BLOCK_ID, 5);
- WriteMetadata(Context, isysroot, "");
- if (StatCalls && !isysroot)
- WriteStatCache(*StatCalls);
- // FIXME: Source manager block should only write new stuff, which could be
- // done by tracking the largest ID in the chain
- WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
-
- // The special types are in the chained PCH.
+ if (Chain) {
+ // Write the mapping information describing our module dependencies and how
+ // each of those modules were mapped into our own offset/ID space, so that
+ // the reader can build the appropriate mapping to its own offset/ID space.
+ // The map consists solely of a blob with the following format:
+ // *(module-name-len:i16 module-name:len*i8
+ // source-location-offset:i32
+ // identifier-id:i32
+ // preprocessed-entity-id:i32
+ // macro-definition-id:i32
+ // selector-id:i32
+ // declaration-id:i32
+ // c++-base-specifiers-id:i32
+ // type-id:i32)
+ //
+ llvm::BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(Abbrev);
+ llvm::SmallString<2048> Buffer;
+ {
+ llvm::raw_svector_ostream Out(Buffer);
+ for (ModuleManager::ModuleConstIterator M = Chain->ModuleMgr.begin(),
+ MEnd = Chain->ModuleMgr.end();
+ M != MEnd; ++M) {
+ StringRef FileName = (*M)->FileName;
+ io::Emit16(Out, FileName.size());
+ Out.write(FileName.data(), FileName.size());
+ io::Emit32(Out, (*M)->SLocEntryBaseOffset);
+ io::Emit32(Out, (*M)->BaseIdentifierID);
+ io::Emit32(Out, (*M)->BasePreprocessedEntityID);
+ io::Emit32(Out, (*M)->BaseSelectorID);
+ io::Emit32(Out, (*M)->BaseDeclID);
+ io::Emit32(Out, (*M)->BaseTypeIndex);
+ }
+ }
+ Record.clear();
+ Record.push_back(MODULE_OFFSET_MAP);
+ Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
+ Buffer.data(), Buffer.size());
+ }
- // We don't start with the translation unit, but with its decls that
- // don't come from the chained PCH.
+ // Create a lexical update block containing all of the declarations in the
+ // translation unit that do not come from other AST files.
const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
- llvm::SmallVector<KindDeclIDPair, 64> NewGlobalDecls;
+ 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)
+ if (!(*I)->isFromASTFile())
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.
}
- // We also need to write a lexical updates block for the TU.
+
llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
@@ -3019,7 +2958,8 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
Record.push_back(TU_UPDATE_LEXICAL);
Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
data(NewGlobalDecls));
- // And a visible updates block for the DeclContexts.
+
+ // And a visible updates block for the translation unit.
Abv = new llvm::BitCodeAbbrev();
Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
@@ -3027,108 +2967,41 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
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.
- RecordData TentativeDefinitions;
- for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) {
- if (SemaRef.TentativeDefinitions[i]->getPCHLevel() == 0)
- AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions);
- }
-
- // Build a record containing all of the file scoped decls in this file.
- RecordData UnusedFileScopedDecls;
- for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) {
- if (SemaRef.UnusedFileScopedDecls[i]->getPCHLevel() == 0)
- AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls);
- }
-
- // Build a record containing all of the delegating constructor decls in this
- // file.
- RecordData DelegatingCtorDecls;
- for (unsigned i=0, e = SemaRef.DelegatingCtorDecls.size(); i != e; ++i) {
- if (SemaRef.DelegatingCtorDecls[i]->getPCHLevel() == 0)
- AddDeclRef(SemaRef.DelegatingCtorDecls[i], DelegatingCtorDecls);
- }
-
- // We write the entire table, overwriting the tables from the chain.
- RecordData WeakUndeclaredIdentifiers;
- if (!SemaRef.WeakUndeclaredIdentifiers.empty()) {
- WeakUndeclaredIdentifiers.push_back(
- SemaRef.WeakUndeclaredIdentifiers.size());
- for (llvm::DenseMap<IdentifierInfo*,Sema::WeakInfo>::iterator
- I = SemaRef.WeakUndeclaredIdentifiers.begin(),
- E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) {
- AddIdentifierRef(I->first, WeakUndeclaredIdentifiers);
- AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers);
- AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers);
- WeakUndeclaredIdentifiers.push_back(I->second.getUsed());
- }
- }
-
- // Build a record containing all of the locally-scoped external
- // declarations in this header file. Generally, this record will be
- // empty.
- RecordData LocallyScopedExternalDecls;
- // FIXME: This is filling in the AST file in densemap order which is
- // nondeterminstic!
- for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
- TD = SemaRef.LocallyScopedExternalDecls.begin(),
- TDEnd = SemaRef.LocallyScopedExternalDecls.end();
- TD != TDEnd; ++TD) {
- if (TD->second->getPCHLevel() == 0)
- AddDeclRef(TD->second, LocallyScopedExternalDecls);
- }
-
- // Build a record containing all of the ext_vector declarations.
- RecordData ExtVectorDecls;
- for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I) {
- if (SemaRef.ExtVectorDecls[I]->getPCHLevel() == 0)
- AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls);
- }
-
- // Build a record containing all of the VTable uses information.
- // We write everything here, because it's too hard to determine whether
- // a use is new to this part.
- RecordData VTableUses;
- if (!SemaRef.VTableUses.empty()) {
- VTableUses.push_back(SemaRef.VTableUses.size());
- for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
- AddDeclRef(SemaRef.VTableUses[I].first, VTableUses);
- AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
- VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]);
+
+ // If the translation unit has an anonymous namespace, and we don't already
+ // have an update block for it, write it as an update block.
+ if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
+ ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
+ if (Record.empty()) {
+ Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE);
+ Record.push_back(reinterpret_cast<uint64_t>(NS));
}
}
-
- // Build a record containing all of dynamic classes declarations.
- RecordData DynamicClasses;
- for (unsigned I = 0, N = SemaRef.DynamicClasses.size(); I != N; ++I)
- if (SemaRef.DynamicClasses[I]->getPCHLevel() == 0)
- AddDeclRef(SemaRef.DynamicClasses[I], DynamicClasses);
-
- // Build a record containing all of pending implicit instantiations.
- RecordData PendingInstantiations;
- for (std::deque<Sema::PendingImplicitInstantiation>::iterator
- I = SemaRef.PendingInstantiations.begin(),
- N = SemaRef.PendingInstantiations.end(); I != N; ++I) {
- AddDeclRef(I->first, PendingInstantiations);
- AddSourceLocation(I->second, PendingInstantiations);
- }
- assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
- "There are local ones at end of translation unit!");
-
- // Build a record containing some declaration references.
- // It's not worth the effort to avoid duplication here.
- RecordData SemaDeclRefs;
- if (SemaRef.StdNamespace || SemaRef.StdBadAlloc) {
- AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs);
- AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs);
- }
-
+
+ // Resolve any declaration pointers within the declaration updates block and
+ // chained Objective-C categories block to declaration IDs.
+ ResolveDeclUpdatesBlocks();
+ ResolveChainedObjCCategories();
+
+ // Form the record of special types.
+ RecordData SpecialTypes;
+ AddTypeRef(Context.getBuiltinVaListType(), SpecialTypes);
+ AddTypeRef(Context.ObjCProtoType, SpecialTypes);
+ AddTypeRef(Context.getRawCFConstantStringType(), SpecialTypes);
+ AddTypeRef(Context.getFILEType(), SpecialTypes);
+ AddTypeRef(Context.getjmp_bufType(), SpecialTypes);
+ AddTypeRef(Context.getsigjmp_bufType(), SpecialTypes);
+ AddTypeRef(Context.ObjCIdRedefinitionType, SpecialTypes);
+ AddTypeRef(Context.ObjCClassRedefinitionType, SpecialTypes);
+ AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes);
+
+ // Keep writing types and declarations until all types and
+ // declarations have been written.
Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
WriteDeclsBlockAbbrevs();
- for (DeclsToRewriteTy::iterator
- I = DeclsToRewrite.begin(), E = DeclsToRewrite.end(); I != E; ++I)
+ 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();
@@ -3140,30 +3013,31 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
}
Stream.ExitBlock();
- WritePreprocessor(PP);
+ WritePreprocessor(PP, IsModule);
+ WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot);
WriteSelectors(SemaRef);
WriteReferencedSelectorsPool(SemaRef);
- WriteIdentifierTable(PP);
+ WriteIdentifierTable(PP, IsModule);
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());
WriteCXXBaseSpecifiersOffsets();
+
+ Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
/// Build a record containing first declarations from a chained PCH and the
/// most recent declarations in this AST that they point to.
RecordData FirstLatestDeclIDs;
- for (FirstLatestDeclMap::iterator
- I = FirstLatestDecls.begin(), E = FirstLatestDecls.end(); I != E; ++I) {
- assert(I->first->getPCHLevel() > I->second->getPCHLevel() &&
- "Expected first & second to be in different PCHs");
+ for (FirstLatestDeclMap::iterator I = FirstLatestDecls.begin(),
+ E = FirstLatestDecls.end();
+ I != E; ++I) {
AddDeclRef(I->first, FirstLatestDeclIDs);
AddDeclRef(I->second, FirstLatestDeclIDs);
}
+
if (!FirstLatestDeclIDs.empty())
Stream.EmitRecord(REDECLS_UPDATE_LATEST, FirstLatestDeclIDs);
@@ -3208,30 +3082,70 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
// Write the record containing declaration references of Sema.
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);
// Write the delegating constructors.
if (!DelegatingCtorDecls.empty())
Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls);
- // Write the updates to DeclContexts.
+ // Write the known namespaces.
+ if (!KnownNamespaces.empty())
+ Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
+
+ // Write the visible updates to DeclContexts.
for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator
- I = UpdatedDeclContexts.begin(),
- E = UpdatedDeclContexts.end();
- I != E; ++I)
+ I = UpdatedDeclContexts.begin(),
+ E = UpdatedDeclContexts.end();
+ I != E; ++I)
WriteDeclContextVisibleUpdate(*I);
WriteDeclUpdatesBlocks();
+ WriteDeclReplacementsBlock();
+ WriteChainedObjCCategories();
+ // Some simple statistics
Record.clear();
Record.push_back(NumStatements);
Record.push_back(NumMacros);
Record.push_back(NumLexicalDeclContexts);
Record.push_back(NumVisibleDeclContexts);
- WriteDeclReplacementsBlock();
Stream.EmitRecord(STATISTICS, Record);
Stream.ExitBlock();
}
+/// \brief Go through the declaration update blocks and resolve declaration
+/// pointers into declaration IDs.
+void ASTWriter::ResolveDeclUpdatesBlocks() {
+ 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
+
+ unsigned Idx = 0, N = URec.size();
+ while (Idx < N) {
+ switch ((DeclUpdateKind)URec[Idx++]) {
+ case UPD_CXX_SET_DEFINITIONDATA:
+ case UPD_CXX_ADDED_IMPLICIT_MEMBER:
+ case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
+ case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
+ URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx]));
+ ++Idx;
+ break;
+
+ case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
+ ++Idx;
+ break;
+ }
+ }
+ }
+}
+
void ASTWriter::WriteDeclUpdatesBlocks() {
if (DeclUpdates.empty())
return;
@@ -3261,7 +3175,7 @@ void ASTWriter::WriteDeclReplacementsBlock() {
return;
RecordData Record;
- for (llvm::SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator
+ for (SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator
I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) {
Record.push_back(I->first);
Record.push_back(I->second);
@@ -3269,6 +3183,37 @@ void ASTWriter::WriteDeclReplacementsBlock() {
Stream.EmitRecord(DECL_REPLACEMENTS, Record);
}
+void ASTWriter::ResolveChainedObjCCategories() {
+ for (SmallVector<ChainedObjCCategoriesData, 16>::iterator
+ I = LocalChainedObjCCategories.begin(),
+ E = LocalChainedObjCCategories.end(); I != E; ++I) {
+ ChainedObjCCategoriesData &Data = *I;
+ Data.InterfaceID = GetDeclRef(Data.Interface);
+ Data.TailCategoryID = GetDeclRef(Data.TailCategory);
+ }
+
+}
+
+void ASTWriter::WriteChainedObjCCategories() {
+ if (LocalChainedObjCCategories.empty())
+ return;
+
+ RecordData Record;
+ for (SmallVector<ChainedObjCCategoriesData, 16>::iterator
+ I = LocalChainedObjCCategories.begin(),
+ E = LocalChainedObjCCategories.end(); I != E; ++I) {
+ ChainedObjCCategoriesData &Data = *I;
+ serialization::DeclID
+ HeadCatID = getDeclID(Data.Interface->getCategoryList());
+ assert(HeadCatID != 0 && "Category not written ?");
+
+ Record.push_back(Data.InterfaceID);
+ Record.push_back(HeadCatID);
+ Record.push_back(Data.TailCategoryID);
+ }
+ Stream.EmitRecord(OBJC_CHAINED_CATEGORIES, Record);
+}
+
void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) {
Record.push_back(Loc.getRawEncoding());
}
@@ -3307,16 +3252,6 @@ IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
return ID;
}
-MacroID ASTWriter::getMacroDefinitionID(MacroDefinition *MD) {
- if (MD == 0)
- return 0;
-
- MacroID &ID = MacroDefinitions[MD];
- if (ID == 0)
- ID = NextMacroID++;
- return ID;
-}
-
void ASTWriter::AddSelectorRef(const Selector SelRef, RecordDataImpl &Record) {
Record.push_back(getSelectorRef(SelRef));
}
@@ -3416,13 +3351,13 @@ void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) {
Record.push_back(GetOrCreateTypeID(T));
}
-TypeID ASTWriter::GetOrCreateTypeID(QualType T) {
- return MakeTypeID(T,
+TypeID ASTWriter::GetOrCreateTypeID( QualType T) {
+ return MakeTypeID(*Context, T,
std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this));
}
TypeID ASTWriter::getTypeID(QualType T) const {
- return MakeTypeID(T,
+ return MakeTypeID(*Context, T,
std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this));
}
@@ -3456,6 +3391,8 @@ void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
}
DeclID ASTWriter::GetDeclRef(const Decl *D) {
+ assert(WritingAST && "Cannot request a declaration ID before AST writing");
+
if (D == 0) {
return 0;
}
@@ -3571,7 +3508,7 @@ void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
RecordDataImpl &Record) {
// Nested name specifiers usually aren't too long. I think that 8 would
// typically accommodate the vast majority.
- llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames;
+ SmallVector<NestedNameSpecifier *, 8> NestedNames;
// Push each of the NNS's onto a stack for serialization in reverse order.
while (NNS) {
@@ -3614,7 +3551,7 @@ void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
RecordDataImpl &Record) {
// Nested name specifiers usually aren't too long. I think that 8 would
// typically accommodate the vast majority.
- llvm::SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
+ SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
// Push each of the nested-name-specifiers's onto a stack for
// serialization in reverse order.
@@ -3805,7 +3742,7 @@ void ASTWriter::FlushCXXBaseSpecifiers() {
Record.clear();
// Record the offset of this base-specifier set.
- unsigned Index = CXXBaseSpecifiersToWrite[I].ID - FirstCXXBaseSpecifiersID;
+ unsigned Index = CXXBaseSpecifiersToWrite[I].ID - 1;
if (Index == CXXBaseSpecifiersOffsets.size())
CXXBaseSpecifiersOffsets.push_back(Stream.GetCurrentBitNo());
else {
@@ -3871,7 +3808,9 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
Record.push_back(Data.UserDeclaredConstructor);
Record.push_back(Data.UserDeclaredCopyConstructor);
+ Record.push_back(Data.UserDeclaredMoveConstructor);
Record.push_back(Data.UserDeclaredCopyAssignment);
+ Record.push_back(Data.UserDeclaredMoveAssignment);
Record.push_back(Data.UserDeclaredDestructor);
Record.push_back(Data.Aggregate);
Record.push_back(Data.PlainOldData);
@@ -3885,7 +3824,7 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
Record.push_back(Data.HasPublicFields);
Record.push_back(Data.HasMutableFields);
Record.push_back(Data.HasTrivialDefaultConstructor);
- Record.push_back(Data.HasConstExprNonCopyMoveConstructor);
+ Record.push_back(Data.HasConstexprNonCopyMoveConstructor);
Record.push_back(Data.HasTrivialCopyConstructor);
Record.push_back(Data.HasTrivialMoveConstructor);
Record.push_back(Data.HasTrivialCopyAssignment);
@@ -3896,8 +3835,12 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
Record.push_back(Data.UserProvidedDefaultConstructor);
Record.push_back(Data.DeclaredDefaultConstructor);
Record.push_back(Data.DeclaredCopyConstructor);
+ Record.push_back(Data.DeclaredMoveConstructor);
Record.push_back(Data.DeclaredCopyAssignment);
+ Record.push_back(Data.DeclaredMoveAssignment);
Record.push_back(Data.DeclaredDestructor);
+ Record.push_back(Data.FailedImplicitMoveConstructor);
+ Record.push_back(Data.FailedImplicitMoveAssignment);
Record.push_back(Data.NumBases);
if (Data.NumBases > 0)
@@ -3918,28 +3861,23 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
void ASTWriter::ReaderInitialized(ASTReader *Reader) {
assert(Reader && "Cannot remove chain");
- assert(!Chain && "Cannot replace chain");
+ assert((!Chain || Chain == Reader) && "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();
+ FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls();
+ FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes();
+ FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers();
+ FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
NextDeclID = FirstDeclID;
NextTypeID = FirstTypeID;
NextIdentID = FirstIdentID;
NextSelectorID = FirstSelectorID;
- NextMacroID = FirstMacroID;
- NextCXXBaseSpecifiersID = FirstCXXBaseSpecifiersID;
}
void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {
@@ -3967,16 +3905,18 @@ void ASTWriter::SelectorRead(SelectorID ID, Selector S) {
SelectorIDs[S] = ID;
}
-void ASTWriter::MacroDefinitionRead(serialization::MacroID ID,
+void ASTWriter::MacroDefinitionRead(serialization::PreprocessedEntityID ID,
MacroDefinition *MD) {
+ assert(MacroDefinitions.find(MD) == MacroDefinitions.end());
MacroDefinitions[MD] = ID;
}
void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
- assert(D->isDefinition());
+ assert(D->isCompleteDefinition());
+ assert(!WritingAST && "Already writing the AST!");
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
// We are interested when a PCH decl is modified.
- if (RD->getPCHLevel() > 0) {
+ if (RD->isFromASTFile()) {
// 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 ?
@@ -3990,67 +3930,73 @@ void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
continue;
// We are interested when a PCH decl is modified.
- if (Redecl->getPCHLevel() > 0) {
+ if (Redecl->isFromASTFile()) {
UpdateRecord &Record = DeclUpdates[Redecl];
Record.push_back(UPD_CXX_SET_DEFINITIONDATA);
assert(Redecl->DefinitionData);
assert(Redecl->DefinitionData->Definition == D);
- AddDeclRef(D, Record); // the DefinitionDecl
+ Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
}
}
}
}
void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
+ assert(!WritingAST && "Already writing the AST!");
+
// TU and namespaces are handled elsewhere.
if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC))
return;
- if (!(D->getPCHLevel() == 0 && cast<Decl>(DC)->getPCHLevel() > 0))
+ if (!(!D->isFromASTFile() && cast<Decl>(DC)->isFromASTFile()))
return; // Not a source decl added to a DeclContext from PCH.
AddUpdatedDeclContext(DC);
}
void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
+ assert(!WritingAST && "Already writing the AST!");
assert(D->isImplicit());
- if (!(D->getPCHLevel() == 0 && RD->getPCHLevel() > 0))
+ if (!(!D->isFromASTFile() && RD->isFromASTFile()))
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());
+ assert(RD->isCompleteDefinition());
UpdateRecord &Record = DeclUpdates[RD];
Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER);
- AddDeclRef(D, Record);
+ Record.push_back(reinterpret_cast<uint64_t>(D));
}
void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
const ClassTemplateSpecializationDecl *D) {
// The specializations set is kept in the canonical template.
+ assert(!WritingAST && "Already writing the AST!");
TD = TD->getCanonicalDecl();
- if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0))
+ if (!(!D->isFromASTFile() && TD->isFromASTFile()))
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);
+ Record.push_back(reinterpret_cast<uint64_t>(D));
}
void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {
// The specializations set is kept in the canonical template.
+ assert(!WritingAST && "Already writing the AST!");
TD = TD->getCanonicalDecl();
- if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0))
+ if (!(!D->isFromASTFile() && TD->isFromASTFile()))
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);
+ Record.push_back(reinterpret_cast<uint64_t>(D));
}
void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
- if (D->getPCHLevel() == 0)
+ assert(!WritingAST && "Already writing the AST!");
+ if (!D->isFromASTFile())
return; // Declaration not imported from PCH.
// Implicit decl from a PCH was defined.
@@ -4059,7 +4005,8 @@ void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
}
void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
- if (D->getPCHLevel() == 0)
+ assert(!WritingAST && "Already writing the AST!");
+ if (!D->isFromASTFile())
return;
// Since the actual instantiation is delayed, this really means that we need
@@ -4070,4 +4017,16 @@ void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
D->getMemberSpecializationInfo()->getPointOfInstantiation(), Record);
}
-ASTSerializationListener::~ASTSerializationListener() { }
+void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
+ const ObjCInterfaceDecl *IFD) {
+ assert(!WritingAST && "Already writing the AST!");
+ if (!IFD->isFromASTFile())
+ return; // Declaration not imported from PCH.
+ if (CatD->getNextClassCategory() &&
+ !CatD->getNextClassCategory()->isFromASTFile())
+ return; // We already recorded that the tail of a category chain should be
+ // attached to an interface.
+
+ ChainedObjCCategoriesData Data = { IFD, CatD, 0, 0 };
+ LocalChainedObjCCategories.push_back(Data);
+}
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
index 2b83494..a8243e5 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -65,6 +65,8 @@ namespace clang {
ClassTemplateSpecializationDecl *D);
void VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D);
+ void VisitClassScopeFunctionSpecializationDecl(
+ ClassScopeFunctionSpecializationDecl *D);
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
void VisitValueDecl(ValueDecl *D);
void VisitEnumConstantDecl(EnumConstantDecl *D);
@@ -153,13 +155,11 @@ void ASTDeclWriter::VisitDecl(Decl *D) {
Record.push_back(D->isUsed(false));
Record.push_back(D->isReferenced());
Record.push_back(D->getAccess());
- Record.push_back(D->getPCHLevel());
+ Record.push_back(D->ModulePrivate);
}
void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
- VisitDecl(D);
- Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
- Code = serialization::DECL_TRANSLATION_UNIT;
+ llvm_unreachable("Translation units aren't directly serialized");
}
void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
@@ -180,11 +180,11 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
if (!D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
- D->getPCHLevel() == 0 &&
D->RedeclLink.getNext() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
D->getAccess() == AS_none &&
+ !D->isModulePrivate() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier)
AbbrevToUse = Writer.getDeclTypedefAbbrev();
@@ -202,8 +202,9 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
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->isCompleteDefinition());
Record.push_back(D->isEmbeddedInDeclarator());
+ Record.push_back(D->isFreeStanding());
Writer.AddSourceLocation(D->getRBraceLoc(), Record);
Record.push_back(D->hasExtInfo());
if (D->hasExtInfo())
@@ -228,12 +229,12 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
if (!D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
- D->getPCHLevel() == 0 &&
!D->hasExtInfo() &&
D->RedeclLink.getNext() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
D->getAccess() == AS_none &&
+ !D->isModulePrivate() &&
!CXXRecordDecl::classofKind(D->getKind()) &&
!D->getIntegerTypeSourceInfo() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier)
@@ -251,12 +252,12 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
if (!D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
- D->getPCHLevel() == 0 &&
!D->hasExtInfo() &&
D->RedeclLink.getNext() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
D->getAccess() == AS_none &&
+ !D->isModulePrivate() &&
!CXXRecordDecl::classofKind(D->getKind()) &&
D->getDeclName().getNameKind() == DeclarationName::Identifier)
AbbrevToUse = Writer.getDeclRecordAbbrev();
@@ -295,8 +296,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->getIdentifierNamespace());
Record.push_back(D->getTemplatedKind());
switch (D->getTemplatedKind()) {
- default: assert(false && "Unhandled TemplatedKind!");
- break;
+ default: llvm_unreachable("Unhandled TemplatedKind!");
case FunctionDecl::TK_NonTemplate:
break;
case FunctionDecl::TK_FunctionTemplate:
@@ -321,13 +321,14 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
// Template args as written.
Record.push_back(FTSInfo->TemplateArgumentsAsWritten != 0);
if (FTSInfo->TemplateArgumentsAsWritten) {
- Record.push_back(FTSInfo->TemplateArgumentsAsWritten->size());
- for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->size(); i!=e; ++i)
+ Record.push_back(FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs);
+ for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs;
+ i!=e; ++i)
Writer.AddTemplateArgumentLoc((*FTSInfo->TemplateArgumentsAsWritten)[i],
Record);
- Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->getLAngleLoc(),
+ Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->LAngleLoc,
Record);
- Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->getRAngleLoc(),
+ Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->RAngleLoc,
Record);
}
@@ -375,6 +376,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->isDefaulted());
Record.push_back(D->isExplicitlyDefaulted());
Record.push_back(D->hasImplicitReturnZero());
+ Record.push_back(D->isConstexpr());
Writer.AddSourceLocation(D->getLocEnd(), Record);
Record.push_back(D->param_size());
@@ -400,12 +402,19 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Record.push_back(D->isVariadic());
Record.push_back(D->isSynthesized());
Record.push_back(D->isDefined());
+
+ Record.push_back(D->IsRedeclaration);
+ Record.push_back(D->HasRedeclaration);
+ if (D->HasRedeclaration) {
+ assert(Context.getObjCMethodRedeclaration(D));
+ Writer.AddDeclRef(Context.getObjCMethodRedeclaration(D), Record);
+ }
+
// FIXME: stable encoding for @required/@optional
Record.push_back(D->getImplementationControl());
// FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
Record.push_back(D->getObjCDeclQualifier());
Record.push_back(D->hasRelatedResultType());
- Record.push_back(D->getNumSelectorArgs());
Writer.AddTypeRef(D->getResultType(), Record);
Writer.AddTypeSourceInfo(D->getResultTypeSourceInfo(), Record);
Writer.AddSourceLocation(D->getLocEnd(), Record);
@@ -413,11 +422,20 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
for (ObjCMethodDecl::param_iterator P = D->param_begin(),
PEnd = D->param_end(); P != PEnd; ++P)
Writer.AddDeclRef(*P, Record);
+
+ Record.push_back(D->SelLocsKind);
+ unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
+ SourceLocation *SelLocs = D->getStoredSelLocs();
+ Record.push_back(NumStoredSelLocs);
+ for (unsigned i = 0; i != NumStoredSelLocs; ++i)
+ Writer.AddSourceLocation(SelLocs[i], Record);
+
Code = serialization::DECL_OBJC_METHOD;
}
void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
VisitNamedDecl(D);
+ Writer.AddSourceLocation(D->getAtStartLoc(), Record);
Writer.AddSourceRange(D->getAtEndRange(), Record);
// Abstract class (no need to define a stable serialization::DECL code).
}
@@ -454,7 +472,6 @@ void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Writer.AddDeclRef(D->getCategoryList(), Record);
Record.push_back(D->isForwardDecl());
Record.push_back(D->isImplicitInterfaceDecl());
- Writer.AddSourceLocation(D->getClassLoc(), Record);
Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
Writer.AddSourceLocation(D->getLocEnd(), Record);
Code = serialization::DECL_OBJC_INTERFACE;
@@ -471,7 +488,7 @@ void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
!D->isUsed(false) &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
- D->getPCHLevel() == 0 &&
+ !D->isModulePrivate() &&
!D->getBitWidth() &&
!D->hasExtInfo() &&
D->getDeclName())
@@ -502,11 +519,8 @@ void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
void ASTDeclWriter::VisitObjCClassDecl(ObjCClassDecl *D) {
VisitDecl(D);
- Record.push_back(D->size());
- for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
- Writer.AddDeclRef(I->getInterface(), Record);
- for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
- Writer.AddSourceLocation(I->getLocation(), Record);
+ Writer.AddDeclRef(D->getForwardInterfaceDecl(), Record);
+ Writer.AddSourceLocation(D->getForwardDecl()->getLocation(), Record);
Code = serialization::DECL_OBJC_CLASS;
}
@@ -536,7 +550,6 @@ void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
Writer.AddSourceLocation(*PL, Record);
Writer.AddDeclRef(D->getNextClassCategory(), Record);
Record.push_back(D->hasSynthBitfield());
- Writer.AddSourceLocation(D->getAtLoc(), Record);
Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
Code = serialization::DECL_OBJC_CATEGORY;
}
@@ -612,7 +625,7 @@ void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
!D->isUsed(false) &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
- D->getPCHLevel() == 0 &&
+ !D->isModulePrivate() &&
!D->getBitWidth() &&
!D->hasInClassInitializer() &&
!D->hasExtInfo() &&
@@ -665,7 +678,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
!D->isInvalidDecl() &&
!D->isReferenced() &&
D->getAccess() == AS_none &&
- D->getPCHLevel() == 0 &&
+ !D->isModulePrivate() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
!D->hasExtInfo() &&
D->RedeclLink.getNext() == D &&
@@ -706,7 +719,7 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
!D->isImplicit() &&
!D->isUsed(false) &&
D->getAccess() == AS_none &&
- D->getPCHLevel() == 0 &&
+ !D->isModulePrivate() &&
D->getStorageClass() == 0 &&
!D->hasCXXDirectInitializer() && // Can params have this ever?
D->getFunctionScopeDepth() == 0 &&
@@ -793,7 +806,7 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
Code = serialization::DECL_NAMESPACE;
if (Writer.hasChain() && !D->isOriginalNamespace() &&
- D->getOriginalNamespace()->getPCHLevel() > 0) {
+ D->getOriginalNamespace()->isFromASTFile()) {
NamespaceDecl *NS = D->getOriginalNamespace();
Writer.AddUpdatedDeclContext(NS);
@@ -819,7 +832,7 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
// anonymous namespace.
Decl *Parent = cast<Decl>(
D->getParent()->getRedeclContext()->getPrimaryContext());
- if (Parent->getPCHLevel() > 0) {
+ if (Parent->isFromASTFile() || isa<TranslationUnitDecl>(Parent)) {
ASTWriter::UpdateRecord &Record = Writer.DeclUpdates[Parent];
Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE);
Writer.AddDeclRef(D, Record);
@@ -909,7 +922,7 @@ void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
// Store the key function to avoid deserializing every method so we can
// compute it.
- if (D->IsDefinition)
+ if (D->IsCompleteDefinition)
Writer.AddDeclRef(Context.getKeyFunction(D), Record);
Code = serialization::DECL_CXX_RECORD;
@@ -1015,7 +1028,7 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
// in a chained PCH, keep track of the association with the map so we can
// update the first decl during AST reading.
if (First->getMostRecentDeclaration() == D &&
- First->getPCHLevel() > D->getPCHLevel()) {
+ First->isFromASTFile() && !D->isFromASTFile()) {
assert(Writer.FirstLatestDecls.find(First)==Writer.FirstLatestDecls.end()
&& "The latest is already set");
Writer.FirstLatestDecls[First] = D;
@@ -1058,16 +1071,12 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *> InstFrom
= D->getSpecializedTemplateOrPartial();
- Decl *InstFromD;
- if (InstFrom.is<ClassTemplateDecl *>()) {
- InstFromD = InstFrom.get<ClassTemplateDecl *>();
+ if (Decl *InstFromD = InstFrom.dyn_cast<ClassTemplateDecl *>()) {
Writer.AddDeclRef(InstFromD, Record);
} else {
- InstFromD = InstFrom.get<ClassTemplatePartialSpecializationDecl *>();
- Writer.AddDeclRef(InstFromD, Record);
+ Writer.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>(),
+ Record);
Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record);
- InstFromD = cast<ClassTemplatePartialSpecializationDecl>(InstFromD)->
- getSpecializedTemplate();
}
// Explicit info.
@@ -1110,6 +1119,14 @@ void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
}
+void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
+ ClassScopeFunctionSpecializationDecl *D) {
+ VisitDecl(D);
+ Writer.AddDeclRef(D->getSpecialization(), Record);
+ Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION;
+}
+
+
void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
VisitRedeclarableTemplateDecl(D);
@@ -1233,7 +1250,7 @@ void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
// in a chained PCH, keep track of the association with the map so we can
// update the first decl during AST reading.
if (ThisDecl != First && First->getMostRecentDeclaration() == ThisDecl &&
- First->getPCHLevel() > ThisDecl->getPCHLevel()) {
+ First->isFromASTFile() && !ThisDecl->isFromASTFile()) {
assert(Writer.FirstLatestDecls.find(First) == Writer.FirstLatestDecls.end()
&& "The latest is already set");
Writer.FirstLatestDecls[First] = ThisDecl;
@@ -1262,7 +1279,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // PCH level
+ Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
@@ -1293,7 +1310,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // PCH level
+ Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
@@ -1327,7 +1344,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // PCH level
+ Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
@@ -1339,8 +1356,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
// TagDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isDefinition
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypedefNameAnonDecl
@@ -1372,7 +1390,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // PCH level
+ Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
@@ -1384,8 +1402,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
// TagDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isDefinition
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypedefNameAnonDecl
@@ -1411,7 +1430,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // PCH level
+ Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
@@ -1459,7 +1478,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // PCH level
+ Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
@@ -1484,7 +1503,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // PCH level
+ Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
@@ -1527,6 +1546,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
DeclRefExprAbbrev = Stream.EmitAbbrev(Abv);
@@ -1592,8 +1612,11 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
/// relatively painless since they would presumably only do it for top-level
/// decls.
static bool isRequiredDecl(const Decl *D, ASTContext &Context) {
+ // An ObjCMethodDecl is never considered as "required" because its
+ // implementation container always is.
+
// File scoped assembly or obj-c implementation must be seen.
- if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplementationDecl>(D))
+ if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D))
return true;
return Context.DeclMustBeEmitted(D);
@@ -1648,7 +1671,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
if (!W.Code)
- llvm::report_fatal_error(llvm::StringRef("unexpected declaration kind '") +
+ llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
D->getDeclKindName() + "'");
Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp
index 1d73ed4..7e2d45c 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -36,7 +36,7 @@ namespace clang {
: Writer(Writer), Record(Record) { }
void
- AddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args);
+ AddExplicitTemplateArgumentList(const ASTTemplateArgumentListInfo &Args);
void VisitStmt(Stmt *S);
#define STMT(Type, Base) \
@@ -46,7 +46,7 @@ namespace clang {
}
void ASTStmtWriter::
-AddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args) {
+AddExplicitTemplateArgumentList(const ASTTemplateArgumentListInfo &Args) {
Writer.AddSourceLocation(Args.LAngleLoc, Record);
Writer.AddSourceLocation(Args.RAngleLoc, Record);
for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
@@ -59,7 +59,7 @@ void ASTStmtWriter::VisitStmt(Stmt *S) {
void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
VisitStmt(S);
Writer.AddSourceLocation(S->getSemiLoc(), Record);
- Writer.AddSourceLocation(S->LeadingEmptyMacro, Record);
+ Record.push_back(S->HasLeadingEmptyMacro);
Code = serialization::STMT_NULL;
}
@@ -265,6 +265,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
Record.push_back(E->hasQualifier());
Record.push_back(E->getDecl() != E->getFoundDecl());
Record.push_back(E->hasExplicitTemplateArgs());
+ Record.push_back(E->hadMultipleCandidates());
if (E->hasExplicitTemplateArgs()) {
unsigned NumTemplateArgs = E->getNumTemplateArgs();
@@ -324,7 +325,7 @@ void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
VisitExpr(E);
Record.push_back(E->getByteLength());
Record.push_back(E->getNumConcatenated());
- Record.push_back(E->isWide());
+ Record.push_back(E->getKind());
Record.push_back(E->isPascal());
// FIXME: String data should be stored as a blob at the end of the
// StringLiteral. However, we can't do so now because we have no
@@ -340,7 +341,7 @@ void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
VisitExpr(E);
Record.push_back(E->getValue());
Writer.AddSourceLocation(E->getLocation(), Record);
- Record.push_back(E->isWide());
+ Record.push_back(E->getKind());
AbbrevToUse = Writer.getCharacterLiteralAbbrev();
@@ -457,7 +458,9 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
for (unsigned i=0; i != NumTemplateArgs; ++i)
Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
}
-
+
+ Record.push_back(E->hadMultipleCandidates());
+
DeclAccessPair FoundDecl = E->getFoundDecl();
Writer.AddDeclRef(FoundDecl.getDecl(), Record);
Record.push_back(FoundDecl.getAccess());
@@ -733,6 +736,21 @@ void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
Code = serialization::EXPR_GENERIC_SELECTION;
}
+void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
+ VisitExpr(E);
+ Record.push_back(E->getOp());
+ Writer.AddStmt(E->getPtr());
+ Writer.AddStmt(E->getOrder());
+ if (E->getOp() != AtomicExpr::Load)
+ Writer.AddStmt(E->getVal1());
+ if (E->isCmpXChg()) {
+ Writer.AddStmt(E->getOrderFail());
+ Writer.AddStmt(E->getVal2());
+ }
+ Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
+ Writer.AddSourceLocation(E->getRParenLoc(), Record);
+}
+
//===----------------------------------------------------------------------===//
// Objective-C Expressions and Statements.
//===----------------------------------------------------------------------===//
@@ -806,6 +824,8 @@ void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
VisitExpr(E);
Record.push_back(E->getNumArgs());
+ Record.push_back(E->getNumStoredSelLocs());
+ Record.push_back(E->SelLocsKind);
Record.push_back(E->isDelegateInitCall());
Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
switch (E->getReceiverKind()) {
@@ -834,11 +854,15 @@ 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)
Writer.AddStmt(*Arg);
+
+ SourceLocation *Locs = E->getStoredSelLocs();
+ for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
+ Writer.AddSourceLocation(Locs[i], Record);
+
Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
}
@@ -952,6 +976,7 @@ void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
Writer.AddDeclRef(E->getConstructor(), Record);
Writer.AddSourceLocation(E->getLocation(), Record);
Record.push_back(E->isElidable());
+ Record.push_back(E->hadMultipleCandidates());
Record.push_back(E->requiresZeroInitialization());
Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
Writer.AddSourceRange(E->getParenRange(), Record);
@@ -1071,6 +1096,7 @@ void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
Record.push_back(E->hasInitializer());
Record.push_back(E->doesUsualArrayDeleteWantSize());
Record.push_back(E->isArray());
+ Record.push_back(E->hadMultipleCandidates());
Record.push_back(E->getNumPlacementArgs());
Record.push_back(E->getNumConstructorArgs());
Writer.AddDeclRef(E->getOperatorNew(), Record);
@@ -1142,7 +1168,7 @@ ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
Record.push_back(E->hasExplicitTemplateArgs());
if (E->hasExplicitTemplateArgs()) {
- const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
+ const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs();
Record.push_back(Args.NumTemplateArgs);
AddExplicitTemplateArgumentList(Args);
}
@@ -1168,7 +1194,7 @@ ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
// emitted first.
Record.push_back(E->hasExplicitTemplateArgs());
if (E->hasExplicitTemplateArgs()) {
- const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
+ const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs();
Record.push_back(Args.NumTemplateArgs);
AddExplicitTemplateArgumentList(Args);
}
@@ -1197,7 +1223,7 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
// Don't emit anything here, hasExplicitTemplateArgs() must be emitted first.
Record.push_back(E->hasExplicitTemplateArgs());
if (E->hasExplicitTemplateArgs()) {
- const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
+ const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs();
Record.push_back(Args.NumTemplateArgs);
AddExplicitTemplateArgumentList(Args);
}
@@ -1428,7 +1454,7 @@ void ASTWriter::WriteSubStmt(Stmt *S) {
}
// Redirect ASTWriter::AddStmt to collect sub stmts.
- llvm::SmallVector<Stmt *, 16> SubStmts;
+ SmallVector<Stmt *, 16> SubStmts;
CollectedStmts = &SubStmts;
Writer.Code = serialization::STMT_NULL_PTR;
@@ -1440,7 +1466,7 @@ void ASTWriter::WriteSubStmt(Stmt *S) {
SourceManager &SrcMgr
= DeclIDs.begin()->first->getASTContext().getSourceManager();
S->dump(SrcMgr);
- assert(0 && "Unhandled sub statement writing AST file");
+ llvm_unreachable("Unhandled sub statement writing AST file");
}
#endif
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ChainedIncludesSource.cpp b/contrib/llvm/tools/clang/lib/Serialization/ChainedIncludesSource.cpp
index 3b7cd23..5fcf11a 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ChainedIncludesSource.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ChainedIncludesSource.cpp
@@ -26,17 +26,20 @@
using namespace clang;
static ASTReader *createASTReader(CompilerInstance &CI,
- llvm::StringRef pchFile,
- llvm::MemoryBuffer **memBufs,
- unsigned numBufs,
+ StringRef pchFile,
+ SmallVector<llvm::MemoryBuffer *, 4> &memBufs,
+ SmallVector<std::string, 4> &bufNames,
ASTDeserializationListener *deserialListener = 0) {
Preprocessor &PP = CI.getPreprocessor();
llvm::OwningPtr<ASTReader> Reader;
- Reader.reset(new ASTReader(PP, &CI.getASTContext(), /*isysroot=*/0,
+ Reader.reset(new ASTReader(PP, CI.getASTContext(), /*isysroot=*/"",
/*DisableValidation=*/true));
- Reader->setASTMemoryBuffers(memBufs, numBufs);
+ for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
+ StringRef sr(bufNames[ti]);
+ Reader->addInMemoryBuffer(sr, memBufs[ti]);
+ }
Reader->setDeserializationListener(deserialListener);
- switch (Reader->ReadAST(pchFile, ASTReader::PCH)) {
+ switch (Reader->ReadAST(pchFile, serialization::MK_PCH)) {
case ASTReader::Success:
// Set the predefines buffer as suggested by the PCH reader.
PP.setPredefines(Reader->getSuggestedPredefines());
@@ -62,7 +65,8 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) {
llvm::OwningPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
InputKind IK = CI.getFrontendOpts().Inputs[0].first;
- llvm::SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
+ SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
+ SmallVector<std::string, 4> serialBufNames;
for (unsigned i = 0, e = includes.size(); i != e; ++i) {
bool firstInclude = (i == 0);
@@ -83,8 +87,8 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) {
TextDiagnosticPrinter *DiagClient =
new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic(DiagID,
- DiagClient));
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, DiagClient));
llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance());
Clang->setInvocation(CInvok.take());
@@ -98,16 +102,15 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) {
&Clang->getPreprocessor());
Clang->createASTContext();
- llvm::SmallVector<char, 256> serialAST;
+ SmallVector<char, 256> serialAST;
llvm::raw_svector_ostream OS(serialAST);
llvm::OwningPtr<ASTConsumer> consumer;
consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-",
- /*Chaining=*/!firstInclude,
- /*isysroot=*/0, &OS));
+ /*IsModule=*/false, /*isysroot=*/"", &OS));
Clang->getASTContext().setASTMutationListener(
consumer->GetASTMutationListener());
Clang->setASTConsumer(consumer.take());
- Clang->createSema(/*CompleteTranslationUnit=*/false, 0);
+ Clang->createSema(TU_Prefix, 0);
if (firstInclude) {
Preprocessor &PP = Clang->getPreprocessor();
@@ -115,19 +118,23 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) {
PP.getLangOptions());
} else {
assert(!serialBufs.empty());
- llvm::SmallVector<llvm::MemoryBuffer *, 4> bufs;
+ SmallVector<llvm::MemoryBuffer *, 4> bufs;
for (unsigned si = 0, se = serialBufs.size(); si != se; ++si) {
bufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
- llvm::StringRef(serialBufs[si]->getBufferStart(),
+ StringRef(serialBufs[si]->getBufferStart(),
serialBufs[si]->getBufferSize())));
}
std::string pchName = includes[i-1];
llvm::raw_string_ostream os(pchName);
os << ".pch" << i-1;
os.flush();
+
+ serialBufNames.push_back(pchName);
+
llvm::OwningPtr<ExternalASTSource> Reader;
- Reader.reset(createASTReader(*Clang, pchName, bufs.data(), bufs.size(),
- Clang->getASTConsumer().GetASTDeserializationListener()));
+
+ Reader.reset(createASTReader(*Clang, pchName, bufs, serialBufNames,
+ Clang->getASTConsumer().GetASTDeserializationListener()));
if (!Reader)
return 0;
Clang->getASTContext().setExternalSource(Reader);
@@ -140,16 +147,16 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) {
OS.flush();
Clang->getDiagnosticClient().EndSourceFile();
serialBufs.push_back(
- llvm::MemoryBuffer::getMemBufferCopy(llvm::StringRef(serialAST.data(),
+ llvm::MemoryBuffer::getMemBufferCopy(StringRef(serialAST.data(),
serialAST.size())));
source->CIs.push_back(Clang.take());
}
assert(!serialBufs.empty());
std::string pchName = includes.back() + ".pch-final";
+ serialBufNames.push_back(pchName);
llvm::OwningPtr<ASTReader> Reader;
- Reader.reset(createASTReader(CI, pchName,
- serialBufs.data(), serialBufs.size()));
+ Reader.reset(createASTReader(CI, pchName, serialBufs, serialBufNames));
if (!Reader)
return 0;
@@ -182,13 +189,10 @@ ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
return getFinalReader().FindExternalVisibleDeclsByName(DC, Name);
}
-void ChainedIncludesSource::MaterializeVisibleDecls(const DeclContext *DC) {
- return getFinalReader().MaterializeVisibleDecls(DC);
-}
ExternalLoadResult
ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC,
bool (*isKindWeWant)(Decl::Kind),
- llvm::SmallVectorImpl<Decl*> &Result) {
+ SmallVectorImpl<Decl*> &Result) {
return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result);
}
void ChainedIncludesSource::CompleteType(TagDecl *Tag) {
diff --git a/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp b/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp
index b8833ce..a2534db 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp
@@ -27,31 +27,29 @@
using namespace clang;
PCHGenerator::PCHGenerator(const Preprocessor &PP,
- const std::string &OutputFile,
- bool Chaining,
- const char *isysroot,
- llvm::raw_ostream *OS)
- : PP(PP), OutputFile(OutputFile), isysroot(isysroot), Out(OS), SemaPtr(0),
- StatCalls(0), Stream(Buffer), Writer(Stream), Chaining(Chaining) {
+ StringRef OutputFile,
+ bool IsModule,
+ StringRef isysroot,
+ raw_ostream *OS)
+ : PP(PP), OutputFile(OutputFile), IsModule(IsModule),
+ isysroot(isysroot.str()), Out(OS),
+ SemaPtr(0), StatCalls(0), Stream(Buffer), Writer(Stream) {
// Install a stat() listener to keep track of all of the stat()
// calls.
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,
- /*AtBeginning=*/!Chaining);
+ PP.getFileManager().addStatCache(StatCalls, /*AtBeginning=*/false);
+}
+
+PCHGenerator::~PCHGenerator() {
}
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, OutputFile, isysroot);
+ Writer.WriteAST(*SemaPtr, StatCalls, OutputFile, IsModule, isysroot);
// Write the generated bitstream to "Out".
Out->write((char *)&Buffer.front(), Buffer.size());
@@ -64,13 +62,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
}
ASTMutationListener *PCHGenerator::GetASTMutationListener() {
- if (Chaining)
- return &Writer;
- return 0;
-}
-
-ASTSerializationListener *PCHGenerator::GetASTSerializationListener() {
- return 0;
+ return &Writer;
}
ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
diff --git a/contrib/llvm/tools/clang/lib/Serialization/Module.cpp b/contrib/llvm/tools/clang/lib/Serialization/Module.cpp
new file mode 100644
index 0000000..0a721c4
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/Serialization/Module.cpp
@@ -0,0 +1,109 @@
+//===--- Module.cpp - Module description ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Module class, which describes a module that has
+// been loaded from an AST file.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Serialization/Module.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "ASTReaderInternals.h"
+
+using namespace clang;
+using namespace serialization;
+using namespace reader;
+
+Module::Module(ModuleKind Kind)
+ : Kind(Kind), DirectlyImported(false), SizeInBits(0),
+ LocalNumSLocEntries(0), SLocEntryBaseID(0),
+ SLocEntryBaseOffset(0), SLocEntryOffsets(0),
+ SLocFileOffsets(0), LocalNumIdentifiers(0),
+ IdentifierOffsets(0), BaseIdentifierID(0), IdentifierTableData(0),
+ IdentifierLookupTable(0), BasePreprocessedEntityID(0),
+ PreprocessedEntityOffsets(0), NumPreprocessedEntities(0),
+ LocalNumHeaderFileInfos(0),
+ HeaderFileInfoTableData(0), HeaderFileInfoTable(0),
+ HeaderFileFrameworkStrings(0),
+ LocalNumSelectors(0), SelectorOffsets(0), BaseSelectorID(0),
+ SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0),
+ DeclOffsets(0), BaseDeclID(0),
+ LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0),
+ LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0), StatCache(0)
+{}
+
+Module::~Module() {
+ for (DeclContextInfosMap::iterator I = DeclContextInfos.begin(),
+ E = DeclContextInfos.end();
+ I != E; ++I) {
+ if (I->second.NameLookupTableData)
+ delete static_cast<ASTDeclContextNameLookupTable*>(
+ I->second.NameLookupTableData);
+ }
+
+ delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
+ delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
+ delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
+}
+
+template<typename Key, typename Offset, unsigned InitialCapacity>
+static void
+dumpLocalRemap(StringRef Name,
+ const ContinuousRangeMap<Key, Offset, InitialCapacity> &Map) {
+ if (Map.begin() == Map.end())
+ return;
+
+ typedef ContinuousRangeMap<Key, Offset, InitialCapacity> MapType;
+ llvm::errs() << " " << Name << ":\n";
+ for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
+ I != IEnd; ++I) {
+ llvm::errs() << " " << I->first << " -> " << I->second << "\n";
+ }
+}
+
+void Module::dump() {
+ llvm::errs() << "\nModule: " << FileName << "\n";
+ if (!Imports.empty()) {
+ llvm::errs() << " Imports: ";
+ for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
+ if (I)
+ llvm::errs() << ", ";
+ llvm::errs() << Imports[I]->FileName;
+ }
+ llvm::errs() << "\n";
+ }
+
+ // Remapping tables.
+ llvm::errs() << " Base source location offset: " << SLocEntryBaseOffset
+ << '\n';
+ dumpLocalRemap("Source location offset local -> global map", SLocRemap);
+
+ llvm::errs() << " Base identifier ID: " << BaseIdentifierID << '\n'
+ << " Number of identifiers: " << LocalNumIdentifiers << '\n';
+ dumpLocalRemap("Identifier ID local -> global map", IdentifierRemap);
+
+ llvm::errs() << " Base selector ID: " << BaseSelectorID << '\n'
+ << " Number of selectors: " << LocalNumSelectors << '\n';
+ dumpLocalRemap("Selector ID local -> global map", SelectorRemap);
+
+ llvm::errs() << " Base preprocessed entity ID: " << BasePreprocessedEntityID
+ << '\n'
+ << " Number of preprocessed entities: "
+ << NumPreprocessedEntities << '\n';
+ dumpLocalRemap("Preprocessed entity ID local -> global map",
+ PreprocessedEntityRemap);
+
+ llvm::errs() << " Base type index: " << BaseTypeIndex << '\n'
+ << " Number of types: " << LocalNumTypes << '\n';
+ dumpLocalRemap("Type index local -> global map", TypeRemap);
+
+ llvm::errs() << " Base decl ID: " << BaseDeclID << '\n'
+ << " Number of decls: " << LocalNumDecls << '\n';
+ dumpLocalRemap("Decl ID local -> global map", DeclRemap);
+}
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp b/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp
new file mode 100644
index 0000000..c4b1f71
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp
@@ -0,0 +1,253 @@
+//===--- ModuleManager.cpp - Module Manager ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ModuleManager class, which manages a set of loaded
+// modules for the ASTReader.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Serialization/ModuleManager.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+
+#ifndef NDEBUG
+#include "llvm/Support/GraphWriter.h"
+#endif
+
+using namespace clang;
+using namespace serialization;
+
+Module *ModuleManager::lookup(StringRef Name) {
+ const FileEntry *Entry = FileMgr.getFile(Name);
+ return Modules[Entry];
+}
+
+llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) {
+ const FileEntry *Entry = FileMgr.getFile(Name);
+ return InMemoryBuffers[Entry];
+}
+
+std::pair<Module *, bool>
+ModuleManager::addModule(StringRef FileName, ModuleKind Type,
+ Module *ImportedBy, std::string &ErrorStr) {
+ const FileEntry *Entry = FileMgr.getFile(FileName);
+ if (!Entry && FileName != "-") {
+ ErrorStr = "file not found";
+ return std::make_pair(static_cast<Module*>(0), false);
+ }
+
+ // Check whether we already loaded this module, before
+ Module *&ModuleEntry = Modules[Entry];
+ bool NewModule = false;
+ if (!ModuleEntry) {
+ // Allocate a new module.
+ Module *New = new Module(Type);
+ New->FileName = FileName.str();
+ Chain.push_back(New);
+ NewModule = true;
+ ModuleEntry = New;
+
+ // Load the contents of the module
+ if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) {
+ // The buffer was already provided for us.
+ assert(Buffer && "Passed null buffer");
+ New->Buffer.reset(Buffer);
+ } else {
+ // Open the AST file.
+ llvm::error_code ec;
+ if (FileName == "-") {
+ ec = llvm::MemoryBuffer::getSTDIN(New->Buffer);
+ if (ec)
+ ErrorStr = ec.message();
+ } else
+ New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr));
+
+ if (!New->Buffer)
+ return std::make_pair(static_cast<Module*>(0), false);
+ }
+
+ // Initialize the stream
+ New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),
+ (const unsigned char *)New->Buffer->getBufferEnd()); }
+
+ if (ImportedBy) {
+ ModuleEntry->ImportedBy.insert(ImportedBy);
+ ImportedBy->Imports.insert(ModuleEntry);
+ } else {
+ ModuleEntry->DirectlyImported = true;
+ }
+
+ return std::make_pair(ModuleEntry, NewModule);
+}
+
+void ModuleManager::addInMemoryBuffer(StringRef FileName,
+ llvm::MemoryBuffer *Buffer) {
+
+ const FileEntry *Entry = FileMgr.getVirtualFile(FileName,
+ Buffer->getBufferSize(), 0);
+ InMemoryBuffers[Entry] = Buffer;
+}
+
+ModuleManager::ModuleManager(const FileSystemOptions &FSO) : FileMgr(FSO) { }
+
+ModuleManager::~ModuleManager() {
+ for (unsigned i = 0, e = Chain.size(); i != e; ++i)
+ delete Chain[e - i - 1];
+}
+
+void ModuleManager::visit(bool (*Visitor)(Module &M, void *UserData),
+ void *UserData) {
+ unsigned N = size();
+
+ // Record the number of incoming edges for each module. When we
+ // encounter a module with no incoming edges, push it into the queue
+ // to seed the queue.
+ SmallVector<Module *, 4> Queue;
+ Queue.reserve(N);
+ llvm::DenseMap<Module *, unsigned> UnusedIncomingEdges;
+ for (ModuleIterator M = begin(), MEnd = end(); M != MEnd; ++M) {
+ if (unsigned Size = (*M)->ImportedBy.size())
+ UnusedIncomingEdges[*M] = Size;
+ else
+ Queue.push_back(*M);
+ }
+
+ llvm::SmallPtrSet<Module *, 4> Skipped;
+ unsigned QueueStart = 0;
+ while (QueueStart < Queue.size()) {
+ Module *CurrentModule = Queue[QueueStart++];
+
+ // Check whether this module should be skipped.
+ if (Skipped.count(CurrentModule))
+ continue;
+
+ if (Visitor(*CurrentModule, UserData)) {
+ // The visitor has requested that cut off visitation of any
+ // module that the current module depends on. To indicate this
+ // behavior, we mark all of the reachable modules as having N
+ // incoming edges (which is impossible otherwise).
+ SmallVector<Module *, 4> Stack;
+ Stack.push_back(CurrentModule);
+ Skipped.insert(CurrentModule);
+ while (!Stack.empty()) {
+ Module *NextModule = Stack.back();
+ Stack.pop_back();
+
+ // For any module that this module depends on, push it on the
+ // stack (if it hasn't already been marked as visited).
+ for (llvm::SetVector<Module *>::iterator
+ M = NextModule->Imports.begin(),
+ MEnd = NextModule->Imports.end();
+ M != MEnd; ++M) {
+ if (Skipped.insert(*M))
+ Stack.push_back(*M);
+ }
+ }
+ continue;
+ }
+
+ // For any module that this module depends on, push it on the
+ // stack (if it hasn't already been marked as visited).
+ for (llvm::SetVector<Module *>::iterator M = CurrentModule->Imports.begin(),
+ MEnd = CurrentModule->Imports.end();
+ M != MEnd; ++M) {
+
+ // Remove our current module as an impediment to visiting the
+ // module we depend on. If we were the last unvisited module
+ // that depends on this particular module, push it into the
+ // queue to be visited.
+ unsigned &NumUnusedEdges = UnusedIncomingEdges[*M];
+ if (NumUnusedEdges && (--NumUnusedEdges == 0))
+ Queue.push_back(*M);
+ }
+ }
+}
+
+/// \brief Perform a depth-first visit of the current module.
+static bool visitDepthFirst(Module &M,
+ bool (*Visitor)(Module &M, bool Preorder,
+ void *UserData),
+ void *UserData,
+ llvm::SmallPtrSet<Module *, 4> &Visited) {
+ // Preorder visitation
+ if (Visitor(M, /*Preorder=*/true, UserData))
+ return true;
+
+ // Visit children
+ for (llvm::SetVector<Module *>::iterator IM = M.Imports.begin(),
+ IMEnd = M.Imports.end();
+ IM != IMEnd; ++IM) {
+ if (!Visited.insert(*IM))
+ continue;
+
+ if (visitDepthFirst(**IM, Visitor, UserData, Visited))
+ return true;
+ }
+
+ // Postorder visitation
+ return Visitor(M, /*Preorder=*/false, UserData);
+}
+
+void ModuleManager::visitDepthFirst(bool (*Visitor)(Module &M, bool Preorder,
+ void *UserData),
+ void *UserData) {
+ llvm::SmallPtrSet<Module *, 4> Visited;
+ for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+ if (!Visited.insert(Chain[I]))
+ continue;
+
+ if (::visitDepthFirst(*Chain[I], Visitor, UserData, Visited))
+ return;
+ }
+}
+
+#ifndef NDEBUG
+namespace llvm {
+ template<>
+ struct GraphTraits<ModuleManager> {
+ typedef Module NodeType;
+ typedef llvm::SetVector<Module *>::const_iterator ChildIteratorType;
+ typedef ModuleManager::ModuleConstIterator nodes_iterator;
+
+ static ChildIteratorType child_begin(NodeType *Node) {
+ return Node->Imports.begin();
+ }
+
+ static ChildIteratorType child_end(NodeType *Node) {
+ return Node->Imports.end();
+ }
+
+ static nodes_iterator nodes_begin(const ModuleManager &Manager) {
+ return Manager.begin();
+ }
+
+ static nodes_iterator nodes_end(const ModuleManager &Manager) {
+ return Manager.end();
+ }
+ };
+
+ template<>
+ struct DOTGraphTraits<ModuleManager> : public DefaultDOTGraphTraits {
+ explicit DOTGraphTraits(bool IsSimple = false)
+ : DefaultDOTGraphTraits(IsSimple) { }
+
+ static bool renderGraphFromBottomUp() {
+ return true;
+ }
+
+ std::string getNodeLabel(Module *M, const ModuleManager&) {
+ return llvm::sys::path::stem(M->FileName);
+ }
+ };
+}
+
+void ModuleManager::viewGraph() {
+ llvm::ViewGraph(*this, "Modules");
+}
+#endif
OpenPOWER on IntegriCloud