summaryrefslogtreecommitdiffstats
path: root/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r--lib/Serialization/ASTReader.cpp150
1 files changed, 125 insertions, 25 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index fd0c171..beef338 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -90,6 +90,12 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
#define BENIGN_LANGOPT(Name, Bits, Default, Description)
#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
#include "clang/Basic/LangOptions.def"
+
+ if (PPLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) {
+ Reader.Diag(diag::err_pch_langopt_value_mismatch)
+ << "target Objective-C runtime";
+ return true;
+ }
return false;
}
@@ -829,7 +835,7 @@ bool ASTReader::ParseLineTable(ModuleFile &F,
Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
FileKind, IncludeOffset));
}
- LineTable.AddEntry(FID, Entries);
+ LineTable.AddEntry(FileID::get(FID), Entries);
}
return false;
@@ -1121,8 +1127,9 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(int ID) {
// This is the module's main file.
IncludeLoc = getImportLocation(F);
}
- FileID FID = SourceMgr.createFileID(File, IncludeLoc,
- (SrcMgr::CharacteristicKind)Record[2],
+ SrcMgr::CharacteristicKind
+ FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
+ FileID FID = SourceMgr.createFileID(File, IncludeLoc, FileCharacter,
ID, BaseOffset + Record[0]);
SrcMgr::FileInfo &FileInfo =
const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile());
@@ -1139,7 +1146,8 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(int ID) {
}
const SrcMgr::ContentCache *ContentCache
- = SourceMgr.getOrCreateContentCache(File);
+ = SourceMgr.getOrCreateContentCache(File,
+ /*isSystemFile=*/FileCharacter != SrcMgr::C_User);
if (OverriddenBuffer && !ContentCache->BufferOverridden &&
ContentCache->ContentsEntry == ContentCache->OrigEntry) {
unsigned Code = SLocEntryCursor.ReadCode();
@@ -1737,6 +1745,17 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
}
break;
+ case COMMENTS_BLOCK_ID: {
+ llvm::BitstreamCursor C = Stream;
+ if (Stream.SkipBlock() ||
+ ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {
+ Error("malformed comments block in AST file");
+ return Failure;
+ }
+ CommentsCursors.push_back(std::make_pair(C, &F));
+ break;
+ }
+
default:
if (!Stream.SkipBlock())
break;
@@ -2473,6 +2492,26 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries(ModuleFile &M) {
Error("source location entry is incorrect");
return Failure;
}
+
+ off_t StoredSize = (off_t)Record[4];
+ time_t StoredTime = (time_t)Record[5];
+
+ // Check if there was a request to override the contents of the file
+ // that was part of the precompiled header. Overridding such a file
+ // can lead to problems when lexing using the source locations from the
+ // PCH.
+ SourceManager &SM = getSourceManager();
+ if (SM.isFileOverridden(File)) {
+ Error(diag::err_fe_pch_file_overridden, Filename);
+ // After emitting the diagnostic, recover by disabling the override so
+ // that the original file will be used.
+ SM.disableFileContentsOverride(File);
+ // The FileEntry is a virtual file entry with the size of the contents
+ // that would override the original contents. Set it to the original's
+ // size/time.
+ FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),
+ StoredSize, StoredTime);
+ }
// The stat info from the FileEntry came from the cached stat
// info of the PCH, so we cannot trust it.
@@ -2482,12 +2521,12 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries(ModuleFile &M) {
StatBuf.st_mtime = File->getModificationTime();
}
- if (((off_t)Record[4] != StatBuf.st_size
+ if ((StoredSize != 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
+ || StoredTime != StatBuf.st_mtime
#endif
)) {
Error(diag::err_fe_pch_file_modified, Filename);
@@ -2831,11 +2870,6 @@ void ASTReader::InitializeContext() {
// Load the special types.
if (SpecialTypes.size() >= NumSpecialTypeIDs) {
- if (Context.getBuiltinVaListType().isNull()) {
- Context.setBuiltinVaListType(
- GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST]));
- }
-
if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {
if (!Context.CFConstantStringTypeDecl)
Context.setCFConstantStringType(GetType(String));
@@ -2975,7 +3009,7 @@ std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
OwningPtr<llvm::MemoryBuffer> Buffer;
Buffer.reset(FileMgr.getBufferForFile(ASTFileName, &ErrStr));
if (!Buffer) {
- Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
+ Diags.Report(diag::err_fe_unable_to_read_pch_file) << ASTFileName << ErrStr;
return std::string();
}
@@ -3297,8 +3331,7 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) {
/// them to the AST listener if one is set.
///
/// \returns true if the listener deems the file unacceptable, false otherwise.
-bool ASTReader::ParseLanguageOptions(
- const SmallVectorImpl<uint64_t> &Record) {
+bool ASTReader::ParseLanguageOptions(const RecordData &Record) {
if (Listener) {
LangOptions LangOpts;
unsigned Idx = 0;
@@ -3307,6 +3340,10 @@ bool ASTReader::ParseLanguageOptions(
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++]));
#include "clang/Basic/LangOptions.def"
+
+ ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++];
+ VersionTuple runtimeVersion = ReadVersionTuple(Record, Idx);
+ LangOpts.ObjCRuntime = ObjCRuntime(runtimeKind, runtimeVersion);
unsigned Length = Record[Idx++];
LangOpts.CurrentModule.assign(Record.begin() + Idx,
@@ -3869,6 +3906,8 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
} else if (EST == EST_Uninstantiated) {
EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
EPI.ExceptionSpecTemplate = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
+ } else if (EST == EST_Unevaluated) {
+ EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
}
return Context.getFunctionType(ResultType, ParamTypes.data(), NumParams,
EPI);
@@ -4124,7 +4163,6 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
ASTReader &Reader;
ModuleFile &F;
- llvm::BitstreamCursor &DeclsCursor;
const ASTReader::RecordData &Record;
unsigned &Idx;
@@ -4141,7 +4179,7 @@ class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
public:
TypeLocReader(ASTReader &Reader, ModuleFile &F,
const ASTReader::RecordData &Record, unsigned &Idx)
- : Reader(Reader), F(F), DeclsCursor(F.DeclsCursor), Record(Record), Idx(Idx)
+ : Reader(Reader), F(F), Record(Record), Idx(Idx)
{ }
// We want compile-time assurance that we've enumerated all of
@@ -4427,6 +4465,9 @@ QualType ASTReader::GetType(TypeID ID) {
T = Context.ARCUnbridgedCastTy;
break;
+ case PREDEF_TYPE_VA_LIST_TAG:
+ T = Context.getVaListTagType();
+ break;
}
assert(!T.isNull() && "Unknown predefined type");
@@ -4627,13 +4668,18 @@ Decl *ASTReader::GetDecl(DeclID ID) {
case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
return Context.getObjCInstanceTypeDecl();
+
+ case PREDEF_DECL_BUILTIN_VA_LIST_ID:
+ return Context.getBuiltinVaListDecl();
}
}
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
if (Index >= DeclsLoaded.size()) {
+ assert(0 && "declaration ID out-of-range for AST file");
Error("declaration ID out-of-range for AST file");
+ return 0;
}
if (!DeclsLoaded[Index]) {
@@ -4839,7 +4885,6 @@ namespace {
class DeclContextNameLookupVisitor {
ASTReader &Reader;
llvm::SmallVectorImpl<const DeclContext *> &Contexts;
- const DeclContext *DC;
DeclarationName Name;
SmallVectorImpl<NamedDecl *> &Decls;
@@ -4941,7 +4986,6 @@ namespace {
class DeclContextAllNamesVisitor {
ASTReader &Reader;
llvm::SmallVectorImpl<const DeclContext *> &Contexts;
- const DeclContext *DC;
llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > &Decls;
public:
@@ -5025,6 +5069,7 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
I = Decls.begin(), E = Decls.end(); I != E; ++I) {
SetExternalVisibleDeclsForName(DC, I->first, I->second);
}
+ const_cast<DeclContext *>(DC)->setHasExternalVisibleStorage(false);
}
/// \brief Under non-PCH compilation the consumer receives the objc methods
@@ -5887,7 +5932,7 @@ ASTReader::ReadTemplateArgument(ModuleFile &F,
case TemplateArgument::Integral: {
llvm::APSInt Value = ReadAPSInt(Record, Idx);
QualType T = readType(F, Record, Idx);
- return TemplateArgument(Value, T);
+ return TemplateArgument(Context, Value, T);
}
case TemplateArgument::Template:
return TemplateArgument(ReadTemplateName(F, Record, Idx));
@@ -6227,18 +6272,72 @@ IdentifierTable &ASTReader::getIdentifierTable() {
/// \brief Record that the given ID maps to the given switch-case
/// statement.
void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
- assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
- SwitchCaseStmts[ID] = SC;
+ assert((*CurrSwitchCaseStmts)[ID] == 0 &&
+ "Already have a SwitchCase with this ID");
+ (*CurrSwitchCaseStmts)[ID] = SC;
}
/// \brief Retrieve the switch-case statement with the given ID.
SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
- assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
- return SwitchCaseStmts[ID];
+ assert((*CurrSwitchCaseStmts)[ID] != 0 && "No SwitchCase with this ID");
+ return (*CurrSwitchCaseStmts)[ID];
}
void ASTReader::ClearSwitchCaseIDs() {
- SwitchCaseStmts.clear();
+ CurrSwitchCaseStmts->clear();
+}
+
+void ASTReader::ReadComments() {
+ std::vector<RawComment *> Comments;
+ for (SmallVectorImpl<std::pair<llvm::BitstreamCursor,
+ serialization::ModuleFile *> >::iterator
+ I = CommentsCursors.begin(),
+ E = CommentsCursors.end();
+ I != E; ++I) {
+ llvm::BitstreamCursor &Cursor = I->first;
+ serialization::ModuleFile &F = *I->second;
+ SavedStreamPosition SavedPosition(Cursor);
+
+ RecordData Record;
+ while (true) {
+ unsigned Code = Cursor.ReadCode();
+ if (Code == llvm::bitc::END_BLOCK)
+ break;
+
+ if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+ // No known subblocks, always skip them.
+ Cursor.ReadSubBlockID();
+ if (Cursor.SkipBlock()) {
+ Error("malformed block record in AST file");
+ return;
+ }
+ continue;
+ }
+
+ if (Code == llvm::bitc::DEFINE_ABBREV) {
+ Cursor.ReadAbbrevRecord();
+ continue;
+ }
+
+ // Read a record.
+ Record.clear();
+ switch ((CommentRecordTypes) Cursor.ReadRecord(Code, Record)) {
+ case COMMENTS_RAW_COMMENT: {
+ unsigned Idx = 0;
+ SourceRange SR = ReadSourceRange(F, Record, Idx);
+ RawComment::CommentKind Kind =
+ (RawComment::CommentKind) Record[Idx++];
+ bool IsTrailingComment = Record[Idx++];
+ bool IsAlmostTrailingComment = Record[Idx++];
+ Comments.push_back(new (Context) RawComment(SR, Kind,
+ IsTrailingComment,
+ IsAlmostTrailingComment));
+ break;
+ }
+ }
+ }
+ }
+ Context.Comments.addCommentsToFront(Comments);
}
void ASTReader::finishPendingActions() {
@@ -6353,7 +6452,8 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
DisableValidation(DisableValidation),
DisableStatCache(DisableStatCache),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
- CurrentGeneration(0), NumStatHits(0), NumStatMisses(0),
+ CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts),
+ NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), TotalNumSLocEntries(0),
NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
OpenPOWER on IntegriCloud