diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp | 151 |
1 files changed, 125 insertions, 26 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp index fd0c171..3adbc57 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp +++ b/contrib/llvm/tools/clang/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 @@ -4221,7 +4259,6 @@ void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) { TL.setLocalRangeBegin(ReadSourceLocation(Record, Idx)); TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx)); - TL.setTrailingReturn(Record[Idx++]); for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) { TL.setArg(i, ReadDeclAs<ParmVarDecl>(Record, Idx)); } @@ -4427,6 +4464,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 +4667,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 +4884,6 @@ namespace { class DeclContextNameLookupVisitor { ASTReader &Reader; llvm::SmallVectorImpl<const DeclContext *> &Contexts; - const DeclContext *DC; DeclarationName Name; SmallVectorImpl<NamedDecl *> &Decls; @@ -4941,7 +4985,6 @@ namespace { class DeclContextAllNamesVisitor { ASTReader &Reader; llvm::SmallVectorImpl<const DeclContext *> &Contexts; - const DeclContext *DC; llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > &Decls; public: @@ -5025,6 +5068,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 +5931,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 +6271,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 +6451,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), |