diff options
Diffstat (limited to 'lib/Serialization')
-rw-r--r-- | lib/Serialization/ASTCommon.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTCommon.h | 4 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 273 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 219 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 195 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 215 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 57 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 119 | ||||
-rw-r--r-- | lib/Serialization/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/Serialization/ChainedIncludesSource.cpp | 235 |
10 files changed, 970 insertions, 352 deletions
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index 5e94f59..782e5c6 100644 --- a/lib/Serialization/ASTCommon.cpp +++ b/lib/Serialization/ASTCommon.cpp @@ -50,7 +50,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::Char16: ID = PREDEF_TYPE_CHAR16_ID; break; case BuiltinType::Char32: ID = PREDEF_TYPE_CHAR32_ID; break; case BuiltinType::Overload: ID = PREDEF_TYPE_OVERLOAD_ID; break; + case BuiltinType::BoundMember:ID = PREDEF_TYPE_BOUND_MEMBER; break; case BuiltinType::Dependent: ID = PREDEF_TYPE_DEPENDENT_ID; break; + case BuiltinType::UnknownAny: ID = PREDEF_TYPE_UNKNOWN_ANY; break; case BuiltinType::ObjCId: ID = PREDEF_TYPE_OBJC_ID; break; case BuiltinType::ObjCClass: ID = PREDEF_TYPE_OBJC_CLASS; break; case BuiltinType::ObjCSel: ID = PREDEF_TYPE_OBJC_SEL; break; diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h index d416699..838df13 100644 --- a/lib/Serialization/ASTCommon.h +++ b/lib/Serialization/ASTCommon.h @@ -23,7 +23,9 @@ namespace serialization { enum DeclUpdateKind { UPD_CXX_SET_DEFINITIONDATA, UPD_CXX_ADDED_IMPLICIT_MEMBER, - UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION + UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, + UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, + UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER }; TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index c3953ba..d2e41a9 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -23,6 +23,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLocVisitor.h" #include "clang/Lex/MacroInfo.h" @@ -36,6 +37,7 @@ #include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" +#include "clang/Basic/VersionTuple.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/MemoryBuffer.h" @@ -77,6 +79,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { 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); @@ -126,6 +129,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { 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); @@ -953,8 +957,16 @@ bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, return false; } -void ASTReader::Error(const char *Msg) { - Diag(diag::err_fe_pch_malformed) << Msg; +void ASTReader::Error(llvm::StringRef Msg) { + Error(diag::err_fe_pch_malformed, Msg); +} + +void ASTReader::Error(unsigned DiagID, + llvm::StringRef Arg1, llvm::StringRef Arg2) { + if (Diags.isDiagnosticInFlight()) + Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2); + else + Diag(DiagID) << Arg1 << Arg2; } /// \brief Tell the AST listener about the predefines buffers in the chain. @@ -1306,8 +1318,7 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(unsigned ID) { || (time_t)Record[5] != File->getModificationTime() #endif )) { - Diag(diag::err_fe_pch_file_modified) - << Filename; + Error(diag::err_fe_pch_file_modified, Filename); return Failure; } @@ -2460,20 +2471,26 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName, if (CurrentDir.empty()) CurrentDir = "."; } - // Open the AST file. - // - // FIXME: This shouldn't be here, we should just take a raw_ostream. - std::string ErrStr; - 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; + 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 @@ -2668,6 +2685,11 @@ void ASTReader::InitializeContext(ASTContext &Ctx) { 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()); // If there were any CUDA special declarations, deserialize them. @@ -2786,6 +2808,7 @@ bool ASTReader::ParseLanguageOptions( PARSE_LANGOPT(Digraphs); PARSE_LANGOPT(HexFloats); PARSE_LANGOPT(C99); + PARSE_LANGOPT(C1X); PARSE_LANGOPT(Microsoft); PARSE_LANGOPT(CPlusPlus); PARSE_LANGOPT(CPlusPlus0x); @@ -2823,6 +2846,7 @@ bool ASTReader::ParseLanguageOptions( PARSE_LANGOPT(PICLevel); PARSE_LANGOPT(GNUInline); PARSE_LANGOPT(NoInline); + PARSE_LANGOPT(Deprecated); PARSE_LANGOPT(AccessControl); PARSE_LANGOPT(CharIsSigned); PARSE_LANGOPT(ShortWChar); @@ -2836,7 +2860,9 @@ bool ASTReader::ParseLanguageOptions( PARSE_LANGOPT(CUDA); PARSE_LANGOPT(CatchUndefined); PARSE_LANGOPT(DefaultFPContract); - // FIXME: Missing ElideConstructors?! + PARSE_LANGOPT(ElideConstructors); + PARSE_LANGOPT(SpellChecking); + PARSE_LANGOPT(MRTD); #undef PARSE_LANGOPT return Listener->ReadLanguageOptions(LangOpts); @@ -2999,12 +3025,12 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { } case TYPE_LVALUE_REFERENCE: { - if (Record.size() != 1) { + if (Record.size() != 2) { Error("Incorrect encoding of lvalue reference type"); return QualType(); } QualType PointeeType = GetType(Record[0]); - return Context->getLValueReferenceType(PointeeType); + return Context->getLValueReferenceType(PointeeType, Record[1]); } case TYPE_RVALUE_REFERENCE: { @@ -3082,12 +3108,12 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { } case TYPE_FUNCTION_NO_PROTO: { - if (Record.size() != 4) { + if (Record.size() != 5) { Error("incorrect encoding of no-proto function type"); return QualType(); } QualType ResultType = GetType(Record[0]); - FunctionType::ExtInfo Info(Record[1], Record[2], (CallingConv)Record[3]); + FunctionType::ExtInfo Info(Record[1], Record[2], Record[3], (CallingConv)Record[4]); return Context->getFunctionNoProtoType(ResultType, Info); } @@ -3096,10 +3122,11 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { FunctionProtoType::ExtProtoInfo EPI; EPI.ExtInfo = FunctionType::ExtInfo(/*noreturn*/ Record[1], - /*regparm*/ Record[2], - static_cast<CallingConv>(Record[3])); + /*hasregparm*/ Record[2], + /*regparm*/ Record[3], + static_cast<CallingConv>(Record[4])); - unsigned Idx = 4; + unsigned Idx = 5; unsigned NumParams = Record[Idx++]; llvm::SmallVector<QualType, 16> ParamTypes; for (unsigned I = 0; I != NumParams; ++I) @@ -3108,13 +3135,18 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { EPI.Variadic = Record[Idx++]; EPI.TypeQuals = Record[Idx++]; EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]); - EPI.HasExceptionSpec = Record[Idx++]; - EPI.HasAnyExceptionSpec = Record[Idx++]; - EPI.NumExceptions = Record[Idx++]; - llvm::SmallVector<QualType, 2> Exceptions; - for (unsigned I = 0; I != EPI.NumExceptions; ++I) - Exceptions.push_back(GetType(Record[Idx++])); - EPI.Exceptions = Exceptions.data(); + ExceptionSpecificationType EST = + static_cast<ExceptionSpecificationType>(Record[Idx++]); + EPI.ExceptionSpecType = EST; + if (EST == EST_Dynamic) { + EPI.NumExceptions = Record[Idx++]; + llvm::SmallVector<QualType, 2> Exceptions; + for (unsigned I = 0; I != EPI.NumExceptions; ++I) + Exceptions.push_back(GetType(Record[Idx++])); + EPI.Exceptions = Exceptions.data(); + } else if (EST == EST_ComputedNoexcept) { + EPI.NoexceptExpr = ReadExpr(*Loc.F); + } return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams, EPI); } @@ -3128,7 +3160,7 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { Error("incorrect encoding of typedef type"); return QualType(); } - TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0])); + TypedefNameDecl *Decl = cast<TypedefNameDecl>(GetDecl(Record[0])); QualType Canonical = GetType(Record[1]); if (!Canonical.isNull()) Canonical = Context->getCanonicalType(Canonical); @@ -3271,8 +3303,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { unsigned Depth = Record[Idx++]; unsigned Index = Record[Idx++]; bool Pack = Record[Idx++]; - IdentifierInfo *Name = GetIdentifierInfo(Record, Idx); - return Context->getTemplateTypeParmType(Depth, Index, Pack, Name); + TemplateTypeParmDecl *D = + cast_or_null<TemplateTypeParmDecl>(GetDecl(Record[Idx++])); + return Context->getTemplateTypeParmType(Depth, Index, Pack, D); } case TYPE_DEPENDENT_NAME: { @@ -3398,6 +3431,7 @@ void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { } void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { TL.setStarLoc(ReadSourceLocation(Record, Idx)); + TL.setClassTInfo(Reader.GetTypeSourceInfo(F, Record, Idx)); } void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) { TL.setLBracketLoc(ReadSourceLocation(Record, Idx)); @@ -3431,8 +3465,8 @@ void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) { - TL.setLParenLoc(ReadSourceLocation(Record, Idx)); - TL.setRParenLoc(ReadSourceLocation(Record, Idx)); + 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, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++]))); @@ -3517,20 +3551,20 @@ void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) { } void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { TL.setKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx)); + TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx)); } void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { TL.setKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx)); + TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx)); TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc TL) { TL.setKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx)); + TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx)); TL.setNameLoc(ReadSourceLocation(Record, Idx)); TL.setLAngleLoc(ReadSourceLocation(Record, Idx)); TL.setRAngleLoc(ReadSourceLocation(Record, Idx)); @@ -3605,7 +3639,9 @@ QualType ASTReader::GetType(TypeID ID) { 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; @@ -3675,16 +3711,18 @@ ASTReader::GetTemplateArgumentLocInfo(PerFileData &F, case TemplateArgument::Type: return GetTypeSourceInfo(F, Record, Index); case TemplateArgument::Template: { - SourceRange QualifierRange = ReadSourceRange(F, Record, Index); + NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, + Index); SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index); - return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc, + return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, SourceLocation()); } case TemplateArgument::TemplateExpansion: { - SourceRange QualifierRange = ReadSourceRange(F, Record, Index); + NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, + Index); SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index); SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index); - return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc, + return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc); } case TemplateArgument::Null: @@ -3722,11 +3760,13 @@ ASTReader::GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID) { --ID; uint64_t Offset = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (ID < Chain[I]->LocalNumCXXBaseSpecifiers) - return Offset + Chain[I]->CXXBaseSpecifiersOffsets[ID]; + PerFileData &F = *Chain[N - I - 1]; + + if (ID < F.LocalNumCXXBaseSpecifiers) + return Offset + F.CXXBaseSpecifiersOffsets[ID]; - ID -= Chain[I]->LocalNumCXXBaseSpecifiers; - Offset += Chain[I]->SizeInBits; + ID -= F.LocalNumCXXBaseSpecifiers; + Offset += F.SizeInBits; } assert(false && "CXXBaseSpecifiers not found"); @@ -3737,14 +3777,14 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { // Figure out which AST file contains this offset. PerFileData *F = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (Offset < Chain[I]->SizeInBits) { - F = Chain[I]; + if (Offset < Chain[N - I - 1]->SizeInBits) { + F = Chain[N - I - 1]; break; } - Offset -= Chain[I]->SizeInBits; + Offset -= Chain[N - I - 1]->SizeInBits; } - + if (!F) { Error("Malformed AST file: C++ base specifiers at impossible offset"); return 0; @@ -4014,6 +4054,23 @@ void ASTReader::PrintStats() { std::fprintf(stderr, "\n"); } +/// 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()) { + size_t bytes = buf->getBufferSize(); + switch (buf->getBufferKind()) { + case llvm::MemoryBuffer::MemoryBuffer_Malloc: + sizes.malloc_bytes += bytes; + break; + case llvm::MemoryBuffer::MemoryBuffer_MMap: + sizes.mmap_bytes += bytes; + break; + } + } +} + void ASTReader::InitializeSema(Sema &S) { SemaObj = &S; S.ExternalSource = this; @@ -4054,7 +4111,7 @@ void ASTReader::InitializeSema(Sema &S) { // 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<TypedefDecl>(GetDecl(ExtVectorDecls[I]))); + cast<TypedefNameDecl>(GetDecl(ExtVectorDecls[I]))); // FIXME: Do VTable uses and dynamic classes deserialize too much ? // Can we cut them down before writing them ? @@ -4087,22 +4144,22 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc)); } } - - // If there were any pending implicit instantiations, deserialize them - // and add them to Sema's queue of such instantiations. - assert(F->PendingInstantiations.size() % 2 == 0 && - "Expected pairs of entries"); - for (unsigned Idx = 0, N = F->PendingInstantiations.size(); Idx < N;) { - ValueDecl *D=cast<ValueDecl>(GetDecl(F->PendingInstantiations[Idx++])); - SourceLocation Loc = ReadSourceLocation(*F, F->PendingInstantiations,Idx); - SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc)); - } } - // The two special data sets below always come from the most recent PCH, + // 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()) { @@ -4354,8 +4411,8 @@ IdentifierInfo *ASTReader::DecodeIdentifierInfo(unsigned ID) { return IdentifiersLoaded[ID]; } -void ASTReader::ReadSLocEntry(unsigned ID) { - ReadSLocEntryRecord(ID); +bool ASTReader::ReadSLocEntry(unsigned ID) { + return ReadSLocEntryRecord(ID) != Success; } Selector ASTReader::DecodeSelector(unsigned ID) { @@ -4762,103 +4819,57 @@ NestedNameSpecifierLoc ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record, unsigned &Idx) { unsigned N = Record[Idx++]; - NestedNameSpecifier *NNS = 0, *Prev = 0; - llvm::SmallVector<char, 32> LocationData; + NestedNameSpecifierLocBuilder Builder; for (unsigned I = 0; I != N; ++I) { NestedNameSpecifier::SpecifierKind Kind = (NestedNameSpecifier::SpecifierKind)Record[Idx++]; switch (Kind) { case NestedNameSpecifier::Identifier: { - // Nested-name-specifier - IdentifierInfo *II = GetIdentifierInfo(Record, Idx); - NNS = NestedNameSpecifier::Create(*Context, Prev, II); - - // Location information + IdentifierInfo *II = GetIdentifierInfo(Record, Idx); SourceRange Range = ReadSourceRange(F, Record, Idx); - unsigned RawStart = Range.getBegin().getRawEncoding(); - unsigned RawEnd = Range.getEnd().getRawEncoding(); - LocationData.append(reinterpret_cast<char*>(&RawStart), - reinterpret_cast<char*>(&RawStart) +sizeof(unsigned)); - LocationData.append(reinterpret_cast<char*>(&RawEnd), - reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned)); + Builder.Extend(*Context, II, Range.getBegin(), Range.getEnd()); break; } case NestedNameSpecifier::Namespace: { - // Nested-name-specifier NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++])); - NNS = NestedNameSpecifier::Create(*Context, Prev, NS); - - // Location information SourceRange Range = ReadSourceRange(F, Record, Idx); - unsigned RawStart = Range.getBegin().getRawEncoding(); - unsigned RawEnd = Range.getEnd().getRawEncoding(); - LocationData.append(reinterpret_cast<char*>(&RawStart), - reinterpret_cast<char*>(&RawStart) +sizeof(unsigned)); - LocationData.append(reinterpret_cast<char*>(&RawEnd), - reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned)); + Builder.Extend(*Context, NS, Range.getBegin(), Range.getEnd()); break; } case NestedNameSpecifier::NamespaceAlias: { - // Nested-name-specifier NamespaceAliasDecl *Alias = cast<NamespaceAliasDecl>(GetDecl(Record[Idx++])); - NNS = NestedNameSpecifier::Create(*Context, Prev, Alias); - - // Location information SourceRange Range = ReadSourceRange(F, Record, Idx); - unsigned RawStart = Range.getBegin().getRawEncoding(); - unsigned RawEnd = Range.getEnd().getRawEncoding(); - LocationData.append(reinterpret_cast<char*>(&RawStart), - reinterpret_cast<char*>(&RawStart) +sizeof(unsigned)); - LocationData.append(reinterpret_cast<char*>(&RawEnd), - reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned)); - + Builder.Extend(*Context, Alias, Range.getBegin(), Range.getEnd()); break; } case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: { - // Nested-name-specifier bool Template = Record[Idx++]; TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx); if (!T) return NestedNameSpecifierLoc(); - NNS = NestedNameSpecifier::Create(*Context, Prev, Template, - T->getType().getTypePtr()); - - // Location information. SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx); - unsigned RawLocation = ColonColonLoc.getRawEncoding(); - void *OpaqueTypeData = T->getTypeLoc().getOpaqueData(); - LocationData.append(reinterpret_cast<char*>(&OpaqueTypeData), - (reinterpret_cast<char*>(&OpaqueTypeData) - + sizeof(void *))); - LocationData.append(reinterpret_cast<char*>(&RawLocation), - (reinterpret_cast<char*>(&RawLocation) + - sizeof(unsigned))); + + // FIXME: 'template' keyword location not saved anywhere, so we fake it. + Builder.Extend(*Context, + Template? T->getTypeLoc().getBeginLoc() : SourceLocation(), + T->getTypeLoc(), ColonColonLoc); break; } case NestedNameSpecifier::Global: { - // Nested-name-specifier - NNS = NestedNameSpecifier::GlobalSpecifier(*Context); - SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx); - unsigned RawLocation = ColonColonLoc.getRawEncoding(); - LocationData.append(reinterpret_cast<char*>(&RawLocation), - (reinterpret_cast<char*>(&RawLocation) + - sizeof(unsigned))); + Builder.MakeGlobal(*Context, ColonColonLoc); break; } } - Prev = NNS; } - void *Mem = Context->Allocate(LocationData.size(), llvm::alignOf<void*>()); - memcpy(Mem, LocationData.data(), LocationData.size()); - return NestedNameSpecifierLoc(NNS, Mem); + return Builder.getWithLocInContext(*Context); } SourceRange @@ -4897,6 +4908,18 @@ std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) { return Result; } +VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, + unsigned &Idx) { + unsigned Major = Record[Idx++]; + unsigned Minor = Record[Idx++]; + unsigned Subminor = Record[Idx++]; + if (Minor == 0) + return VersionTuple(Major); + if (Subminor == 0) + return VersionTuple(Major, Minor - 1); + return VersionTuple(Major, Minor - 1, Subminor - 1); +} + CXXTemporary *ASTReader::ReadCXXTemporary(const RecordData &Record, unsigned &Idx) { CXXDestructorDecl *Decl = cast<CXXDestructorDecl>(GetDecl(Record[Idx++])); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 493ccba..3a825de 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -38,6 +38,9 @@ namespace clang { const RecordData &Record; unsigned &Idx; TypeID TypeIDForTypeDecl; + + DeclID DeclContextIDForTemplateParmDecl; + DeclID LexicalDeclContextIDForTemplateParmDecl; uint64_t GetCurrentCursorOffset(); SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) { @@ -79,7 +82,8 @@ namespace clang { void Visit(Decl *D); - void UpdateDecl(Decl *D, const RecordData &Record); + void UpdateDecl(Decl *D, ASTReader::PerFileData &Module, + const RecordData &Record); void VisitDecl(Decl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *TU); @@ -90,6 +94,7 @@ namespace clang { void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); void VisitTypeDecl(TypeDecl *TD); void VisitTypedefDecl(TypedefDecl *TD); + void VisitTypeAliasDecl(TypeAliasDecl *TD); void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); void VisitTagDecl(TagDecl *TD); void VisitEnumDecl(EnumDecl *ED); @@ -175,13 +180,32 @@ void ASTDeclReader::Visit(Decl *D) { // FunctionDecl's body was written last after all other Stmts/Exprs. if (Record[Idx++]) FD->setLazyBody(GetCurrentCursorOffset()); + } else if (D->isTemplateParameter()) { + // If we have a fully initialized template parameter, we can now + // set its DeclContext. + D->setDeclContext( + cast_or_null<DeclContext>( + Reader.GetDecl(DeclContextIDForTemplateParmDecl))); + D->setLexicalDeclContext( + cast_or_null<DeclContext>( + Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl))); } } void ASTDeclReader::VisitDecl(Decl *D) { - D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); - D->setLexicalDeclContext( + if (D->isTemplateParameter()) { + // We don't want to deserialize the DeclContext of a template + // 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()); + } else { + D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); + D->setLexicalDeclContext( cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]))); + } D->setLocation(ReadSourceLocation(Record, Idx)); D->setInvalidDecl(Record[Idx++]); if (Record[Idx++]) { // hasAttrs @@ -191,6 +215,7 @@ void ASTDeclReader::VisitDecl(Decl *D) { } D->setImplicit(Record[Idx++]); D->setUsed(Record[Idx++]); + D->setReferenced(Record[Idx++]); D->setAccess((AccessSpecifier)Record[Idx++]); D->setPCHLevel(Record[Idx++] + (F.Type <= ASTReader::PCH)); } @@ -208,6 +233,7 @@ void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) { 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++]; } @@ -217,6 +243,11 @@ void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) { TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); } +void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) { + VisitTypeDecl(TD); + TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); +} + void ASTDeclReader::VisitTagDecl(TagDecl *TD) { VisitTypeDecl(TD); VisitRedeclarable(TD); @@ -225,14 +256,13 @@ void ASTDeclReader::VisitTagDecl(TagDecl *TD) { TD->setDefinition(Record[Idx++]); TD->setEmbeddedInDeclarator(Record[Idx++]); TD->setRBraceLoc(ReadSourceLocation(Record, Idx)); - TD->setTagKeywordLoc(ReadSourceLocation(Record, Idx)); if (Record[Idx++]) { // hasExtInfo TagDecl::ExtInfo *Info = new (*Reader.getContext()) TagDecl::ExtInfo(); ReadQualifierInfo(*Info, Record, Idx); - TD->TypedefDeclOrQualifier = Info; + TD->TypedefNameDeclOrQualifier = Info; } else - TD->setTypedefForAnonDecl( - cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++]))); + TD->setTypedefNameForAnonDecl( + cast_or_null<TypedefNameDecl>(Reader.GetDecl(Record[Idx++]))); } void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { @@ -272,6 +302,7 @@ void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) { void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) { VisitValueDecl(DD); + DD->setInnerLocStart(ReadSourceLocation(Record, Idx)); if (Record[Idx++]) { // hasExtInfo DeclaratorDecl::ExtInfo *Info = new (*Reader.getContext()) DeclaratorDecl::ExtInfo(); @@ -655,12 +686,13 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { void ASTDeclReader::VisitVarDecl(VarDecl *VD) { VisitDeclaratorDecl(VD); VisitRedeclarable(VD); - VD->SClass = (StorageClass)Record[Idx++]; - VD->setStorageClassAsWritten((StorageClass)Record[Idx++]); - VD->setThreadSpecified(Record[Idx++]); - VD->setCXXDirectInitializer(Record[Idx++]); - VD->setExceptionVariable(Record[Idx++]); - VD->setNRVOVariable(Record[Idx++]); + VD->VarDeclBits.SClass = (StorageClass)Record[Idx++]; + VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++]; + VD->VarDeclBits.ThreadSpecified = Record[Idx++]; + VD->VarDeclBits.HasCXXDirectInit = Record[Idx++]; + VD->VarDeclBits.ExceptionVar = Record[Idx++]; + VD->VarDeclBits.NRVOVariable = Record[Idx++]; + VD->VarDeclBits.CXXForRangeDecl = Record[Idx++]; if (Record[Idx++]) VD->setInit(Reader.ReadExpr(F)); @@ -678,8 +710,19 @@ void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) { void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { VisitVarDecl(PD); - PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]); - PD->setHasInheritedDefaultArg(Record[Idx++]); + unsigned isObjCMethodParam = Record[Idx++]; + unsigned scopeDepth = Record[Idx++]; + unsigned scopeIndex = Record[Idx++]; + unsigned declQualifier = Record[Idx++]; + if (isObjCMethodParam) { + assert(scopeDepth == 0); + PD->setObjCMethodScopeInfo(scopeIndex); + PD->ParmVarDeclBits.ScopeDepthOrObjCQuals = declQualifier; + } else { + PD->setScopeInfo(scopeDepth, scopeIndex); + } + PD->ParmVarDeclBits.IsKNRPromoted = Record[Idx++]; + PD->ParmVarDeclBits.HasInheritedDefaultArg = Record[Idx++]; if (Record[Idx++]) // hasUninstantiatedDefaultArg. PD->setUninstantiatedDefaultArg(Reader.ReadExpr(F)); } @@ -687,6 +730,7 @@ void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) { VisitDecl(AD); AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr(F))); + AD->setRParenLoc(ReadSourceLocation(Record, Idx)); } void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { @@ -720,19 +764,21 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) { VisitDecl(D); D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]); - D->setHasBraces(Record[Idx++]); + D->setExternLoc(ReadSourceLocation(Record, Idx)); + D->setRBraceLoc(ReadSourceLocation(Record, Idx)); } void ASTDeclReader::VisitLabelDecl(LabelDecl *D) { VisitNamedDecl(D); + D->setLocStart(ReadSourceLocation(Record, Idx)); } void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { VisitNamedDecl(D); D->IsInline = Record[Idx++]; - D->LBracLoc = ReadSourceLocation(Record, Idx); - D->RBracLoc = ReadSourceLocation(Record, Idx); + D->LocStart = ReadSourceLocation(Record, Idx); + D->RBraceLoc = ReadSourceLocation(Record, Idx); D->NextNamespace = Record[Idx++]; bool IsOriginal = Record[Idx++]; @@ -790,7 +836,6 @@ void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { void ASTDeclReader::VisitUnresolvedUsingTypenameDecl( UnresolvedUsingTypenameDecl *D) { VisitTypeDecl(D); - D->UsingLocation = ReadSourceLocation(Record, Idx); D->TypenameLocation = ReadSourceLocation(Record, Idx); D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); } @@ -807,10 +852,19 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.Empty = Record[Idx++]; Data.Polymorphic = Record[Idx++]; Data.Abstract = Record[Idx++]; + Data.IsStandardLayout = Record[Idx++]; + Data.HasNoNonEmptyBases = Record[Idx++]; + Data.HasPrivateFields = Record[Idx++]; + Data.HasProtectedFields = Record[Idx++]; + Data.HasPublicFields = Record[Idx++]; Data.HasTrivialConstructor = Record[Idx++]; + Data.HasConstExprNonCopyMoveConstructor = Record[Idx++]; Data.HasTrivialCopyConstructor = Record[Idx++]; + Data.HasTrivialMoveConstructor = Record[Idx++]; Data.HasTrivialCopyAssignment = Record[Idx++]; + Data.HasTrivialMoveAssignment = Record[Idx++]; Data.HasTrivialDestructor = Record[Idx++]; + Data.HasNonLiteralTypeFieldsOrBases = Record[Idx++]; Data.ComputedVisibleConversions = Record[Idx++]; Data.DeclaredDefaultConstructor = Record[Idx++]; Data.DeclaredCopyConstructor = Record[Idx++]; @@ -1172,7 +1226,6 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { VisitTypeDecl(D); D->setDeclaredWithTypename(Record[Idx++]); - D->setParameterPack(Record[Idx++]); bool Inherited = Record[Idx++]; TypeSourceInfo *DefArg = GetTypeSourceInfo(Record, Idx); @@ -1217,6 +1270,7 @@ void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) { VisitDecl(D); D->AssertExpr = Reader.ReadExpr(F); D->Message = cast<StringLiteral>(Reader.ReadExpr(F)); + D->RParenLoc = ReadSourceLocation(Record, Idx); } std::pair<uint64_t, uint64_t> @@ -1398,7 +1452,12 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { D = Context->getTranslationUnitDecl(); break; case DECL_TYPEDEF: - D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, 0); + D = TypedefDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), + 0, 0); + break; + case DECL_TYPEALIAS: + D = TypeAliasDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), + 0, 0); break; case DECL_ENUM: D = EnumDecl::Create(*Context, Decl::EmptyShell()); @@ -1411,19 +1470,20 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { 0, llvm::APSInt()); break; case DECL_FUNCTION: - D = FunctionDecl::Create(*Context, 0, SourceLocation(), DeclarationName(), - QualType(), 0); + D = FunctionDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), + DeclarationName(), QualType(), 0); break; case DECL_LINKAGE_SPEC: - D = LinkageSpecDecl::Create(*Context, 0, SourceLocation(), + D = LinkageSpecDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), (LinkageSpecDecl::LanguageIDs)0, - false); + SourceLocation()); break; case DECL_LABEL: D = LabelDecl::Create(*Context, 0, SourceLocation(), 0); break; case DECL_NAMESPACE: - D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0); + D = NamespaceDecl::Create(*Context, 0, SourceLocation(), + SourceLocation(), 0); break; case DECL_NAMESPACE_ALIAS: D = NamespaceAliasDecl::Create(*Context, 0, SourceLocation(), @@ -1460,8 +1520,9 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { D = CXXRecordDecl::Create(*Context, Decl::EmptyShell()); break; case DECL_CXX_METHOD: - D = CXXMethodDecl::Create(*Context, 0, DeclarationNameInfo(), - QualType(), 0); + D = CXXMethodDecl::Create(*Context, 0, SourceLocation(), + DeclarationNameInfo(), QualType(), 0, + false, SC_None, false, SourceLocation()); break; case DECL_CXX_CONSTRUCTOR: D = CXXConstructorDecl::Create(*Context, Decl::EmptyShell()); @@ -1482,38 +1543,38 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { D = FriendTemplateDecl::Create(*Context, Decl::EmptyShell()); break; case DECL_CLASS_TEMPLATE: - D = ClassTemplateDecl::Create(*Context, 0, SourceLocation(), - DeclarationName(), 0, 0, 0); + D = ClassTemplateDecl::Create(*Context, Decl::EmptyShell()); break; case DECL_CLASS_TEMPLATE_SPECIALIZATION: D = ClassTemplateSpecializationDecl::Create(*Context, Decl::EmptyShell()); break; case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION: D = ClassTemplatePartialSpecializationDecl::Create(*Context, - Decl::EmptyShell()); + Decl::EmptyShell()); break; case DECL_FUNCTION_TEMPLATE: - D = FunctionTemplateDecl::Create(*Context, 0, SourceLocation(), - DeclarationName(), 0, 0); + D = FunctionTemplateDecl::Create(*Context, Decl::EmptyShell()); break; case DECL_TEMPLATE_TYPE_PARM: D = TemplateTypeParmDecl::Create(*Context, Decl::EmptyShell()); break; case DECL_NON_TYPE_TEMPLATE_PARM: - D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0, - QualType(), false, 0); + 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(), 0, 0, - 0, QualType(), 0, 0, Record[Idx++], - 0); + 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, false, 0, 0); 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: @@ -1524,15 +1585,15 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { D = ObjCInterfaceDecl::Create(*Context, 0, SourceLocation(), 0); break; case DECL_OBJC_IVAR: - D = ObjCIvarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, - ObjCIvarDecl::None); + D = ObjCIvarDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), + 0, QualType(), 0, ObjCIvarDecl::None); break; case DECL_OBJC_PROTOCOL: D = ObjCProtocolDecl::Create(*Context, 0, SourceLocation(), 0); break; case DECL_OBJC_AT_DEFS_FIELD: - D = ObjCAtDefsFieldDecl::Create(*Context, 0, SourceLocation(), 0, - QualType(), 0); + D = ObjCAtDefsFieldDecl::Create(*Context, 0, SourceLocation(), + SourceLocation(), 0, QualType(), 0); break; case DECL_OBJC_CLASS: D = ObjCClassDecl::Create(*Context, 0, SourceLocation()); @@ -1564,16 +1625,16 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { SourceLocation()); break; case DECL_FIELD: - D = FieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, 0, - false); + D = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 0, + QualType(), 0, 0, false); break; case DECL_INDIRECTFIELD: D = IndirectFieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, 0); break; case DECL_VAR: - D = VarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, - SC_None, SC_None); + D = VarDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 0, + QualType(), 0, SC_None, SC_None); break; case DECL_IMPLICIT_PARAM: @@ -1581,11 +1642,12 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { break; case DECL_PARM_VAR: - D = ParmVarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, - SC_None, SC_None, 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, SourceLocation(), 0); + D = FileScopeAsmDecl::Create(*Context, 0, 0, SourceLocation(), + SourceLocation()); break; case DECL_BLOCK: D = BlockDecl::Create(*Context, 0, SourceLocation()); @@ -1614,22 +1676,26 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { // 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. - DeclContextVisibleUpdatesPending::iterator I = - PendingVisibleUpdates.find(ID); - if (I != PendingVisibleUpdates.end()) { - DeclContextVisibleUpdates &U = I->second; - 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); - } - PendingVisibleUpdates.erase(I); + // Now add the pending visible updates for this decl context, if it has any. + DeclContextVisibleUpdatesPending::iterator I = + PendingVisibleUpdates.find(ID); + if (I != PendingVisibleUpdates.end()) { + // There are updates. This means the context has external visible + // 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); } + PendingVisibleUpdates.erase(I); } } assert(Idx == Record.size()); @@ -1652,7 +1718,7 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { unsigned RecCode = Cursor.ReadRecord(Code, Record); (void)RecCode; assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!"); - Reader.UpdateDecl(D, Record); + Reader.UpdateDecl(D, *F, Record); } } @@ -1666,7 +1732,8 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { return D; } -void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) { +void ASTDeclReader::UpdateDecl(Decl *D, ASTReader::PerFileData &Module, + const RecordData &Record) { unsigned Idx = 0; while (Idx < Record.size()) { switch ((DeclUpdateKind)Record[Idx++]) { @@ -1686,6 +1753,26 @@ void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) { case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: // It will be added to the template's specializations set when loaded. Reader.GetDecl(Record[Idx++]); + break; + + case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: { + NamespaceDecl *Anon = cast<NamespaceDecl>(Reader.GetDecl(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. + if (!Anon->NextNamespace) { + if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D)) + TU->setAnonymousNamespace(Anon); + else + cast<NamespaceDecl>(D)->OrigOrAnonNamespace.setPointer(Anon); + } + break; + } + + case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER: + cast<VarDecl>(D)->getMemberSpecializationInfo()->setPointOfInstantiation( + Reader.ReadSourceLocation(Module, Record, Idx)); + break; } } } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 42f0b1a..918db7e 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -97,7 +97,7 @@ namespace clang { void VisitParenListExpr(ParenListExpr *E); void VisitUnaryOperator(UnaryOperator *E); void VisitOffsetOfExpr(OffsetOfExpr *E); - void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); + void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); void VisitArraySubscriptExpr(ArraySubscriptExpr *E); void VisitCallExpr(CallExpr *E); void VisitMemberExpr(MemberExpr *E); @@ -122,6 +122,7 @@ namespace clang { void VisitShuffleVectorExpr(ShuffleVectorExpr *E); void VisitBlockExpr(BlockExpr *E); void VisitBlockDeclRefExpr(BlockDeclRefExpr *E); + void VisitGenericSelectionExpr(GenericSelectionExpr *E); void VisitObjCStringLiteral(ObjCStringLiteral *E); void VisitObjCEncodeExpr(ObjCEncodeExpr *E); void VisitObjCSelectorExpr(ObjCSelectorExpr *E); @@ -141,6 +142,7 @@ namespace clang { // C++ Statements void VisitCXXCatchStmt(CXXCatchStmt *S); void VisitCXXTryStmt(CXXTryStmt *S); + void VisitCXXForRangeStmt(CXXForRangeStmt *); void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); void VisitCXXConstructExpr(CXXConstructExpr *E); @@ -177,6 +179,8 @@ namespace clang { void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); + void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E); + void VisitExpressionTraitExpr(ExpressionTraitExpr *E); void VisitCXXNoexceptExpr(CXXNoexceptExpr *E); void VisitPackExpansionExpr(PackExpansionExpr *E); void VisitSizeOfPackExpr(SizeOfPackExpr *E); @@ -208,7 +212,7 @@ void ASTStmtReader::VisitStmt(Stmt *S) { void ASTStmtReader::VisitNullStmt(NullStmt *S) { VisitStmt(S); S->setSemiLoc(ReadSourceLocation(Record, Idx)); - S->LeadingEmptyMacro = Record[Idx++]; + S->LeadingEmptyMacro = ReadSourceLocation(Record, Idx); } void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) { @@ -421,23 +425,23 @@ void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) { void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); - bool HasQualifier = Record[Idx++]; - bool HasExplicitTemplateArgs = Record[Idx++]; - - E->DecoratedD.setInt((HasQualifier? DeclRefExpr::HasQualifierFlag : 0) | - (HasExplicitTemplateArgs - ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0)); - - if (HasQualifier) { - E->getNameQualifier()->NNS = Reader.ReadNestedNameSpecifier(Record, Idx); - E->getNameQualifier()->Range = ReadSourceRange(Record, Idx); - } + E->DeclRefExprBits.HasQualifier = Record[Idx++]; + E->DeclRefExprBits.HasFoundDecl = Record[Idx++]; + E->DeclRefExprBits.HasExplicitTemplateArgs = Record[Idx++]; + unsigned NumTemplateArgs = 0; + if (E->hasExplicitTemplateArgs()) + NumTemplateArgs = Record[Idx++]; + + if (E->hasQualifier()) + E->getInternalQualifierLoc() + = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); + + if (E->hasFoundDecl()) + E->getInternalFoundDecl() = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); - if (HasExplicitTemplateArgs) { - unsigned NumTemplateArgs = Record[Idx++]; + if (E->hasExplicitTemplateArgs()) ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), NumTemplateArgs); - } E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++]))); E->setLocation(ReadSourceLocation(Record, Idx)); @@ -468,7 +472,8 @@ void ASTStmtReader::VisitStringLiteral(StringLiteral *E) { assert(Record[Idx] == E->getNumConcatenated() && "Wrong number of concatenated tokens!"); ++Idx; - E->setWide(Record[Idx++]); + E->IsWide = Record[Idx++]; + E->IsPascal = Record[Idx++]; // Read string data llvm::SmallString<16> Str(&Record[Idx], &Record[Idx] + Len); @@ -555,9 +560,9 @@ void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) { E->setIndexExpr(I, Reader.ReadSubExpr()); } -void ASTStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { +void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { VisitExpr(E); - E->setSizeof(Record[Idx++]); + E->setKind(static_cast<UnaryExprOrTypeTrait>(Record[Idx++])); if (Record[Idx] == 0) { E->setArgument(Reader.ReadSubExpr()); ++Idx; @@ -680,16 +685,29 @@ void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { void ASTStmtReader::VisitInitListExpr(InitListExpr *E) { VisitExpr(E); - unsigned NumInits = Record[Idx++]; - E->reserveInits(*Reader.getContext(), NumInits); - for (unsigned I = 0; I != NumInits; ++I) - E->updateInit(*Reader.getContext(), I, Reader.ReadSubExpr()); E->setSyntacticForm(cast_or_null<InitListExpr>(Reader.ReadSubStmt())); E->setLBraceLoc(ReadSourceLocation(Record, Idx)); E->setRBraceLoc(ReadSourceLocation(Record, Idx)); - E->setInitializedFieldInUnion( - cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++]))); + bool isArrayFiller = Record[Idx++]; + Expr *filler = 0; + if (isArrayFiller) { + filler = Reader.ReadSubExpr(); + E->ArrayFillerOrUnionFieldInit = filler; + } else + E->ArrayFillerOrUnionFieldInit + = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])); E->sawArrayRangeDesignator(Record[Idx++]); + unsigned NumInits = Record[Idx++]; + 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); + } + } else { + for (unsigned I = 0; I != NumInits; ++I) + E->updateInit(*Reader.getContext(), I, Reader.ReadSubExpr()); + } } void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) { @@ -820,6 +838,25 @@ void ASTStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { E->setConstQualAdded(Record[Idx++]); } +void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) { + VisitExpr(E); + E->NumAssocs = Record[Idx++]; + E->AssocTypes = new (*Reader.getContext()) TypeSourceInfo*[E->NumAssocs]; + E->SubExprs = + 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) { + E->AssocTypes[I] = GetTypeSourceInfo(Record, Idx); + E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Reader.ReadSubExpr(); + } + E->ResultIndex = Record[Idx++]; + + E->GenericLoc = ReadSourceLocation(Record, Idx); + E->DefaultLoc = ReadSourceLocation(Record, Idx); + E->RParenLoc = ReadSourceLocation(Record, Idx); +} + //===----------------------------------------------------------------------===// // Objective-C Expressions and Statements @@ -998,6 +1035,19 @@ void ASTStmtReader::VisitCXXTryStmt(CXXTryStmt *S) { S->getStmts()[i + 1] = Reader.ReadSubStmt(); } +void ASTStmtReader::VisitCXXForRangeStmt(CXXForRangeStmt *S) { + VisitStmt(S); + S->setForLoc(ReadSourceLocation(Record, Idx)); + S->setColonLoc(ReadSourceLocation(Record, Idx)); + S->setRParenLoc(ReadSourceLocation(Record, Idx)); + S->setRangeStmt(Reader.ReadSubStmt()); + S->setBeginEndStmt(Reader.ReadSubStmt()); + S->setCond(Reader.ReadSubExpr()); + S->setInc(Reader.ReadSubExpr()); + S->setLoopVarStmt(Reader.ReadSubStmt()); + S->setBody(Reader.ReadSubStmt()); +} + void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); E->setOperator((OverloadedOperatorKind)Record[Idx++]); @@ -1201,14 +1251,13 @@ ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), Record[Idx++]); - E->setBase(Reader.ReadSubExpr()); - E->setBaseType(Reader.GetType(Record[Idx++])); - E->setArrow(Record[Idx++]); - E->setOperatorLoc(ReadSourceLocation(Record, Idx)); - E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - E->setQualifierRange(ReadSourceRange(Record, Idx)); - E->setFirstQualifierFoundInScope( - cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]))); + E->Base = Reader.ReadSubExpr(); + E->BaseType = Reader.GetType(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++])); ReadDeclarationNameInfo(E->MemberNameInfo, Record, Idx); } @@ -1254,24 +1303,25 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { E->initializeResults(*Reader.getContext(), Decls.begin(), Decls.end()); ReadDeclarationNameInfo(E->NameInfo, Record, Idx); - E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - E->setQualifierRange(ReadSourceRange(Record, Idx)); + E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); } void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { VisitOverloadExpr(E); - E->setArrow(Record[Idx++]); - E->setHasUnresolvedUsing(Record[Idx++]); - E->setBase(Reader.ReadSubExpr()); - E->setBaseType(Reader.GetType(Record[Idx++])); - E->setOperatorLoc(ReadSourceLocation(Record, Idx)); + E->IsArrow = Record[Idx++]; + E->HasUnresolvedUsing = Record[Idx++]; + E->Base = Reader.ReadSubExpr(); + E->BaseType = Reader.GetType(Record[Idx++]); + E->OperatorLoc = ReadSourceLocation(Record, Idx); } void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); - E->setRequiresADL(Record[Idx++]); - E->setOverloaded(Record[Idx++]); - E->setNamingClass(cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))); + E->RequiresADL = Record[Idx++]; + if (E->RequiresADL) + E->StdIsAssociatedNamespace = Record[Idx++]; + E->Overloaded = Record[Idx++]; + E->NamingClass = cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])); } void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { @@ -1295,6 +1345,26 @@ void ASTStmtReader::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { E->RhsType = GetTypeSourceInfo(Record, Idx); } +void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { + VisitExpr(E); + E->ATT = (ArrayTypeTrait)Record[Idx++]; + E->Value = (unsigned int)Record[Idx++]; + SourceRange Range = ReadSourceRange(Record, Idx); + E->Loc = Range.getBegin(); + E->RParen = Range.getEnd(); + E->QueriedType = GetTypeSourceInfo(Record, Idx); +} + +void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { + VisitExpr(E); + E->ET = (ExpressionTrait)Record[Idx++]; + E->Value = (bool)Record[Idx++]; + SourceRange Range = ReadSourceRange(Record, Idx); + E->QueriedExpression = Reader.ReadSubExpr(); + E->Loc = Range.getBegin(); + E->RParen = Range.getEnd(); +} + void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { VisitExpr(E); E->Value = (bool)Record[Idx++]; @@ -1500,12 +1570,13 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { break; case EXPR_DECL_REF: - S = DeclRefExpr::CreateEmpty(*Context, - /*HasQualifier=*/Record[ASTStmtReader::NumExprFields], - /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1], - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1] - ? Record[ASTStmtReader::NumExprFields + 2] - : 0); + S = DeclRefExpr::CreateEmpty( + *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); break; case EXPR_INTEGER_LITERAL: @@ -1548,7 +1619,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { break; case EXPR_SIZEOF_ALIGN_OF: - S = new (Context) SizeOfAlignOfExpr(Empty); + S = new (Context) UnaryExprOrTypeTraitExpr(Empty); break; case EXPR_ARRAY_SUBSCRIPT: @@ -1565,11 +1636,9 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { // logic with a MemberExpr::CreateEmpty. assert(Idx == 0); - NestedNameSpecifier *NNS = 0; - SourceRange QualifierRange; + NestedNameSpecifierLoc QualifierLoc; if (Record[Idx++]) { // HasQualifier. - NNS = ReadNestedNameSpecifier(Record, Idx); - QualifierRange = ReadSourceRange(F, Record, Idx); + QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx); } TemplateArgumentListInfo ArgInfo; @@ -1595,7 +1664,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc); bool IsArrow = Record[Idx++]; - S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange, + S = MemberExpr::Create(*Context, Base, IsArrow, QualifierLoc, MemberD, FoundDecl, MemberNameInfo, HasExplicitTemplateArgs ? &ArgInfo : 0, T, VK, OK); ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc, @@ -1683,6 +1752,10 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { S = new (Context) BlockDeclRefExpr(Empty); break; + case EXPR_GENERIC_SELECTION: + S = new (Context) GenericSelectionExpr(Empty); + break; + case EXPR_OBJC_STRING_LITERAL: S = new (Context) ObjCStringLiteral(Empty); break; @@ -1741,6 +1814,10 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { /*NumHandlers=*/Record[ASTStmtReader::NumStmtFields]); break; + case STMT_CXX_FOR_RANGE: + S = new (Context) CXXForRangeStmt(Empty); + break; + case EXPR_CXX_OPERATOR_CALL: S = new (Context) CXXOperatorCallExpr(*Context, Empty); break; @@ -1881,6 +1958,14 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { S = new (Context) BinaryTypeTraitExpr(Empty); break; + case EXPR_ARRAY_TYPE_TRAIT: + S = new (Context) ArrayTypeTraitExpr(Empty); + break; + + case EXPR_CXX_EXPRESSION_TRAIT: + S = new (Context) ExpressionTraitExpr(Empty); + break; + case EXPR_CXX_NOEXCEPT: S = new (Context) CXXNoexceptExpr(Empty); break; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 383ca3d..6d44fb6 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -37,6 +37,7 @@ #include "clang/Basic/SourceManagerInternals.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" +#include "clang/Basic/VersionTuple.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/StringExtras.h" @@ -50,12 +51,16 @@ using namespace clang; using namespace clang::serialization; template <typename T, typename Allocator> -T *data(std::vector<T, Allocator> &v) { - return v.empty() ? 0 : &v.front(); +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]), + sizeof(T) * v.size()); } -template <typename T, typename Allocator> -const T *data(const std::vector<T, Allocator> &v) { - return v.empty() ? 0 : &v.front(); + +template <typename T> +static llvm::StringRef data(const llvm::SmallVectorImpl<T> &v) { + return llvm::StringRef(reinterpret_cast<const char*>(v.data()), + sizeof(T) * v.size()); } //===----------------------------------------------------------------------===// @@ -104,12 +109,13 @@ void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { } void ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) { - Writer.AddTypeRef(T->getPointeeType(), Record); + Writer.AddTypeRef(T->getPointeeTypeAsWritten(), Record); + Record.push_back(T->isSpelledAsLValue()); Code = TYPE_LVALUE_REFERENCE; } void ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) { - Writer.AddTypeRef(T->getPointeeType(), Record); + Writer.AddTypeRef(T->getPointeeTypeAsWritten(), Record); Code = TYPE_RVALUE_REFERENCE; } @@ -160,6 +166,7 @@ void ASTTypeWriter::VisitFunctionType(const FunctionType *T) { Writer.AddTypeRef(T->getResultType(), Record); FunctionType::ExtInfo C = T->getExtInfo(); Record.push_back(C.getNoReturn()); + Record.push_back(C.getHasRegParm()); Record.push_back(C.getRegParm()); // FIXME: need to stabilize encoding of calling convention... Record.push_back(C.getCC()); @@ -178,11 +185,14 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { Record.push_back(T->isVariadic()); Record.push_back(T->getTypeQuals()); Record.push_back(static_cast<unsigned>(T->getRefQualifier())); - Record.push_back(T->hasExceptionSpec()); - Record.push_back(T->hasAnyExceptionSpec()); - Record.push_back(T->getNumExceptions()); - for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) - Writer.AddTypeRef(T->getExceptionType(I), Record); + Record.push_back(T->getExceptionSpecType()); + if (T->getExceptionSpecType() == EST_Dynamic) { + Record.push_back(T->getNumExceptions()); + for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) + Writer.AddTypeRef(T->getExceptionType(I), Record); + } else if (T->getExceptionSpecType() == EST_ComputedNoexcept) { + Writer.AddStmt(T->getNoexceptExpr()); + } Code = TYPE_FUNCTION_PROTO; } @@ -293,7 +303,7 @@ ASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { Record.push_back(T->getDepth()); Record.push_back(T->getIndex()); Record.push_back(T->isParameterPack()); - Writer.AddIdentifierRef(T->getName(), Record); + Writer.AddDeclRef(T->getDecl(), Record); Code = TYPE_TEMPLATE_TYPE_PARM; } @@ -418,6 +428,7 @@ void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { } void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { Writer.AddSourceLocation(TL.getStarLoc(), Record); + Writer.AddTypeSourceInfo(TL.getClassTInfo(), Record); } void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) { Writer.AddSourceLocation(TL.getLBracketLoc(), Record); @@ -450,8 +461,8 @@ void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { - Writer.AddSourceLocation(TL.getLParenLoc(), Record); - Writer.AddSourceLocation(TL.getRParenLoc(), Record); + Writer.AddSourceLocation(TL.getLocalRangeBegin(), Record); + Writer.AddSourceLocation(TL.getLocalRangeEnd(), Record); Record.push_back(TL.getTrailingReturn()); for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) Writer.AddDeclRef(TL.getArg(i), Record); @@ -532,20 +543,20 @@ void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) { } void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { Writer.AddSourceLocation(TL.getKeywordLoc(), Record); - Writer.AddSourceRange(TL.getQualifierRange(), Record); + Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record); } void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { Writer.AddSourceLocation(TL.getKeywordLoc(), Record); - Writer.AddSourceRange(TL.getQualifierRange(), Record); + Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record); Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc TL) { Writer.AddSourceLocation(TL.getKeywordLoc(), Record); - Writer.AddSourceRange(TL.getQualifierRange(), Record); + Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record); Writer.AddSourceLocation(TL.getNameLoc(), Record); Writer.AddSourceLocation(TL.getLAngleLoc(), Record); Writer.AddSourceLocation(TL.getRAngleLoc(), Record); @@ -652,6 +663,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_SHUFFLE_VECTOR); RECORD(EXPR_BLOCK); RECORD(EXPR_BLOCK_DECL_REF); + RECORD(EXPR_GENERIC_SELECTION); RECORD(EXPR_OBJC_STRING_LITERAL); RECORD(EXPR_OBJC_ENCODE); RECORD(EXPR_OBJC_SELECTOR_EXPR); @@ -1000,6 +1012,7 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { 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. @@ -1054,6 +1067,7 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { 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 @@ -1072,6 +1086,7 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.DefaultFPContract); Record.push_back(LangOpts.ElideConstructors); Record.push_back(LangOpts.SpellChecking); + Record.push_back(LangOpts.MRTD); Stream.EmitRecord(LANGUAGE_OPTIONS, Record); } @@ -1427,7 +1442,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // Figure out which record code to use. unsigned Code; if (SLoc->isFile()) { - if (SLoc->getFile().getContentCache()->Entry) + if (SLoc->getFile().getContentCache()->OrigEntry) Code = SM_SLOC_FILE_ENTRY; else Code = SM_SLOC_BUFFER_ENTRY; @@ -1444,17 +1459,27 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.push_back(File.hasLineDirectives()); const SrcMgr::ContentCache *Content = File.getContentCache(); - if (Content->Entry) { + if (Content->OrigEntry) { + assert(Content->OrigEntry == Content->ContentsEntry && + "Writing to AST an overriden file is not supported"); + // The source location entry is a file. The blob associated // with this entry is the file name. // Emit size/modification time for this file. - Record.push_back(Content->Entry->getSize()); - Record.push_back(Content->Entry->getModificationTime()); + Record.push_back(Content->OrigEntry->getSize()); + Record.push_back(Content->OrigEntry->getModificationTime()); // Turn the file name into an absolute path, if it isn't already. - const char *Filename = Content->Entry->getName(); + const char *Filename = Content->OrigEntry->getName(); llvm::SmallString<128> FilePath(Filename); + + // Ask the file manager to fixup the relative path for us. This will + // honor the working directory. + SourceMgr.getFileManager().FixupRelativePath(FilePath); + + // FIXME: This call to make_absolute shouldn't be necessary, the + // call to FixupRelativePath should always return an absolute path. llvm::sys::fs::make_absolute(FilePath); Filename = FilePath.c_str(); @@ -1517,9 +1542,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.push_back(SLocEntryOffsets.size()); unsigned BaseOffset = Chain ? Chain->getNextSLocOffset() : 0; Record.push_back(SourceMgr.getNextOffset() - BaseOffset); - Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, - (const char *)data(SLocEntryOffsets), - SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0])); + Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, data(SLocEntryOffsets)); // Write the source location entry preloads array, telling the AST // reader which source locations entries it should load eagerly. @@ -1778,8 +1801,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { Record.push_back(NumPreprocessingRecords); Record.push_back(MacroDefinitionOffsets.size()); Stream.EmitRecordWithBlob(MacroDefOffsetAbbrev, Record, - (const char *)data(MacroDefinitionOffsets), - MacroDefinitionOffsets.size() * sizeof(uint32_t)); + data(MacroDefinitionOffsets)); } } @@ -1809,6 +1831,29 @@ void ASTWriter::WritePragmaDiagnosticMappings(const Diagnostic &Diag) { Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record); } +void ASTWriter::WriteCXXBaseSpecifiersOffsets() { + if (CXXBaseSpecifiersOffsets.empty()) + return; + + RecordData Record; + + // Create a blob abbreviation for the C++ base specifiers offsets. + using namespace llvm; + + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(CXX_BASE_SPECIFIER_OFFSETS)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); + + // Write the selector offsets table. + Record.clear(); + Record.push_back(CXX_BASE_SPECIFIER_OFFSETS); + Record.push_back(CXXBaseSpecifiersOffsets.size()); + Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record, + data(CXXBaseSpecifiersOffsets)); +} + //===----------------------------------------------------------------------===// // Type Serialization //===----------------------------------------------------------------------===// @@ -1881,9 +1926,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D))); ++NumLexicalDeclContexts; - Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, - reinterpret_cast<char*>(Decls.data()), - Decls.size() * sizeof(KindDeclIDPair)); + Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, data(Decls)); return Offset; } @@ -1900,9 +1943,7 @@ void ASTWriter::WriteTypeDeclOffsets() { Record.clear(); Record.push_back(TYPE_OFFSET); Record.push_back(TypeOffsets.size()); - Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, - (const char *)data(TypeOffsets), - TypeOffsets.size() * sizeof(TypeOffsets[0])); + Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, data(TypeOffsets)); // Write the declaration offsets array Abbrev = new BitCodeAbbrev(); @@ -1913,9 +1954,7 @@ void ASTWriter::WriteTypeDeclOffsets() { Record.clear(); Record.push_back(DECL_OFFSET); Record.push_back(DeclOffsets.size()); - Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, - (const char *)data(DeclOffsets), - DeclOffsets.size() * sizeof(DeclOffsets[0])); + Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets)); } //===----------------------------------------------------------------------===// @@ -2102,8 +2141,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { Record.push_back(SELECTOR_OFFSETS); Record.push_back(SelectorOffsets.size()); Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record, - (const char *)data(SelectorOffsets), - SelectorOffsets.size() * 4); + data(SelectorOffsets)); } } @@ -2305,8 +2343,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { Record.push_back(IDENTIFIER_OFFSET); Record.push_back(IdentifierOffsets.size()); Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, - (const char *)data(IdentifierOffsets), - IdentifierOffsets.size() * sizeof(uint32_t)); + data(IdentifierOffsets)); } //===----------------------------------------------------------------------===// @@ -2583,6 +2620,19 @@ void ASTWriter::AddString(llvm::StringRef Str, RecordDataImpl &Record) { Record.insert(Record.end(), Str.begin(), Str.end()); } +void ASTWriter::AddVersionTuple(const VersionTuple &Version, + RecordDataImpl &Record) { + Record.push_back(Version.getMajor()); + if (llvm::Optional<unsigned> Minor = Version.getMinor()) + Record.push_back(*Minor + 1); + else + Record.push_back(0); + if (llvm::Optional<unsigned> Subminor = Version.getSubminor()) + Record.push_back(*Subminor + 1); + else + Record.push_back(0); +} + /// \brief Note that the identifier II occurs at the given offset /// within the identifier table. void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) { @@ -2770,6 +2820,8 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, 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 @@ -2797,25 +2849,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, WriteTypeDeclOffsets(); WritePragmaDiagnosticMappings(Context.getDiagnostics()); - // Write the C++ base-specifier set offsets. - if (!CXXBaseSpecifiersOffsets.empty()) { - // Create a blob abbreviation for the C++ base specifiers offsets. - using namespace llvm; - - BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); - Abbrev->Add(BitCodeAbbrevOp(CXX_BASE_SPECIFIER_OFFSETS)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); - unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); - - // Write the selector offsets table. - Record.clear(); - Record.push_back(CXX_BASE_SPECIFIER_OFFSETS); - Record.push_back(CXXBaseSpecifiersOffsets.size()); - Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record, - (const char *)CXXBaseSpecifiersOffsets.data(), - CXXBaseSpecifiersOffsets.size() * sizeof(uint32_t)); - } + WriteCXXBaseSpecifiersOffsets(); // Write the record containing external, unnamed definitions. if (!ExternalDefinitions.empty()) @@ -2911,8 +2945,7 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, Record.clear(); Record.push_back(TU_UPDATE_LEXICAL); Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, - reinterpret_cast<const char*>(NewGlobalDecls.data()), - NewGlobalDecls.size() * sizeof(KindDeclIDPair)); + data(NewGlobalDecls)); // And a visible updates block for the DeclContexts. Abv = new llvm::BitCodeAbbrev(); Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); @@ -2997,10 +3030,8 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, for (std::deque<Sema::PendingImplicitInstantiation>::iterator I = SemaRef.PendingInstantiations.begin(), N = SemaRef.PendingInstantiations.end(); I != N; ++I) { - if (I->first->getPCHLevel() == 0) { - AddDeclRef(I->first, PendingInstantiations); - AddSourceLocation(I->second, PendingInstantiations); - } + AddDeclRef(I->first, PendingInstantiations); + AddSourceLocation(I->second, PendingInstantiations); } assert(SemaRef.PendingLocalImplicitInstantiations.empty() && "There are local ones at end of translation unit!"); @@ -3040,6 +3071,8 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, // write all of them again). WritePragmaDiagnosticMappings(Context.getDiagnostics()); + WriteCXXBaseSpecifiersOffsets(); + /// Build a record containing first declarations from a chained PCH and the /// most recent declarations in this AST that they point to. RecordData FirstLatestDeclIDs; @@ -3245,11 +3278,11 @@ void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record); break; case TemplateArgument::Template: - AddSourceRange(Arg.getTemplateQualifierRange(), Record); + AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record); AddSourceLocation(Arg.getTemplateNameLoc(), Record); break; case TemplateArgument::TemplateExpansion: - AddSourceRange(Arg.getTemplateQualifierRange(), Record); + AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record); AddSourceLocation(Arg.getTemplateNameLoc(), Record); AddSourceLocation(Arg.getTemplateEllipsisLoc(), Record); break; @@ -3452,7 +3485,7 @@ void ASTWriter::AddQualifierInfo(const QualifierInfo &Info, void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record) { // Nested name specifiers usually aren't too long. I think that 8 would - // typically accomodate the vast majority. + // typically accommodate the vast majority. llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames; // Push each of the NNS's onto a stack for serialization in reverse order. @@ -3495,7 +3528,7 @@ void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, RecordDataImpl &Record) { // Nested name specifiers usually aren't too long. I think that 8 would - // typically accomodate the vast majority. + // typically accommodate the vast majority. llvm::SmallVector<NestedNameSpecifierLoc , 8> NestedNames; // Push each of the nested-name-specifiers's onto a stack for @@ -3749,10 +3782,19 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec Record.push_back(Data.Empty); Record.push_back(Data.Polymorphic); Record.push_back(Data.Abstract); + Record.push_back(Data.IsStandardLayout); + Record.push_back(Data.HasNoNonEmptyBases); + Record.push_back(Data.HasPrivateFields); + Record.push_back(Data.HasProtectedFields); + Record.push_back(Data.HasPublicFields); Record.push_back(Data.HasTrivialConstructor); + Record.push_back(Data.HasConstExprNonCopyMoveConstructor); Record.push_back(Data.HasTrivialCopyConstructor); + Record.push_back(Data.HasTrivialMoveConstructor); Record.push_back(Data.HasTrivialCopyAssignment); + Record.push_back(Data.HasTrivialMoveAssignment); Record.push_back(Data.HasTrivialDestructor); + Record.push_back(Data.HasNonLiteralTypeFieldsOrBases); Record.push_back(Data.ComputedVisibleConversions); Record.push_back(Data.DeclaredDefaultConstructor); Record.push_back(Data.DeclaredCopyConstructor); @@ -3897,4 +3939,37 @@ void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, AddDeclRef(D, Record); } +void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, + const FunctionDecl *D) { + // The specializations set is kept in the canonical template. + TD = TD->getCanonicalDecl(); + if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0)) + return; // Not a source specialization added to a template from PCH. + + UpdateRecord &Record = DeclUpdates[TD]; + Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); + AddDeclRef(D, Record); +} + +void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { + if (D->getPCHLevel() == 0) + return; // Declaration not imported from PCH. + + // Implicit decl from a PCH was defined. + // FIXME: Should implicit definition be a separate FunctionDecl? + RewriteDecl(D); +} + +void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) { + if (D->getPCHLevel() == 0) + return; + + // Since the actual instantiation is delayed, this really means that we need + // to update the instantiation location. + UpdateRecord &Record = DeclUpdates[D]; + Record.push_back(UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER); + AddSourceLocation( + D->getMemberSpecializationInfo()->getPointOfInstantiation(), Record); +} + ASTSerializationListener::~ASTSerializationListener() { } diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 12d1226..1ca00a3 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Serialization/ASTWriter.h" +#include "ASTCommon.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" @@ -21,6 +22,7 @@ #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; +using namespace serialization; //===----------------------------------------------------------------------===// // Declaration serialization @@ -53,6 +55,7 @@ namespace clang { void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); void VisitTypeDecl(TypeDecl *D); void VisitTypedefDecl(TypedefDecl *D); + void VisitTypeAliasDecl(TypeAliasDecl *D); void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); void VisitTagDecl(TagDecl *D); void VisitEnumDecl(EnumDecl *D); @@ -140,6 +143,7 @@ void ASTDeclWriter::VisitDecl(Decl *D) { Writer.WriteAttributes(D->getAttrs(), Record); Record.push_back(D->isImplicit()); Record.push_back(D->isUsed(false)); + Record.push_back(D->isReferenced()); Record.push_back(D->getAccess()); Record.push_back(D->getPCHLevel()); } @@ -157,6 +161,7 @@ void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) { void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) { VisitNamedDecl(D); + Writer.AddSourceLocation(D->getLocStart(), Record); Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record); } @@ -166,6 +171,12 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { Code = serialization::DECL_TYPEDEF; } +void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) { + VisitTypeDecl(D); + Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record); + Code = serialization::DECL_TYPEALIAS; +} + void ASTDeclWriter::VisitTagDecl(TagDecl *D) { VisitTypeDecl(D); VisitRedeclarable(D); @@ -174,12 +185,11 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) { Record.push_back(D->isDefinition()); Record.push_back(D->isEmbeddedInDeclarator()); Writer.AddSourceLocation(D->getRBraceLoc(), Record); - Writer.AddSourceLocation(D->getTagKeywordLoc(), Record); Record.push_back(D->hasExtInfo()); if (D->hasExtInfo()) Writer.AddQualifierInfo(*D->getExtInfo(), Record); else - Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record); + Writer.AddDeclRef(D->getTypedefNameForAnonDecl(), Record); } void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { @@ -221,6 +231,7 @@ void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) { void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) { VisitValueDecl(D); + Writer.AddSourceLocation(D->getInnerLocStart(), Record); Record.push_back(D->hasExtInfo()); if (D->hasExtInfo()) Writer.AddQualifierInfo(*D->getExtInfo(), Record); @@ -552,6 +563,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(D->hasCXXDirectInitializer()); Record.push_back(D->isExceptionVariable()); Record.push_back(D->isNRVOVariable()); + Record.push_back(D->isCXXForRangeDecl()); Record.push_back(D->getInit() ? 1 : 0); if (D->getInit()) Writer.AddStmt(D->getInit()); @@ -575,7 +587,11 @@ void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) { void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { VisitVarDecl(D); + Record.push_back(D->isObjCMethodParameter()); + Record.push_back(D->getFunctionScopeDepth()); + Record.push_back(D->getFunctionScopeIndex()); Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding + Record.push_back(D->isKNRPromoted()); Record.push_back(D->hasInheritedDefaultArg()); Record.push_back(D->hasUninstantiatedDefaultArg()); if (D->hasUninstantiatedDefaultArg()) @@ -593,7 +609,9 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { D->getPCHLevel() == 0 && D->getStorageClass() == 0 && !D->hasCXXDirectInitializer() && // Can params have this ever? + D->getFunctionScopeDepth() == 0 && D->getObjCDeclQualifier() == 0 && + !D->isKNRPromoted() && !D->hasInheritedDefaultArg() && D->getInit() == 0 && !D->hasUninstantiatedDefaultArg()) // No default expr. @@ -613,6 +631,7 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { VisitDecl(D); Writer.AddStmt(D->getAsmString()); + Writer.AddSourceLocation(D->getRParenLoc(), Record); Code = serialization::DECL_FILE_SCOPE_ASM; } @@ -645,15 +664,15 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) { void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { VisitDecl(D); - // FIXME: It might be nice to serialize the brace locations for this - // declaration, which don't seem to be readily available in the AST. Record.push_back(D->getLanguage()); - Record.push_back(D->hasBraces()); + Writer.AddSourceLocation(D->getExternLoc(), Record); + Writer.AddSourceLocation(D->getRBraceLoc(), Record); Code = serialization::DECL_LINKAGE_SPEC; } void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) { VisitNamedDecl(D); + Writer.AddSourceLocation(D->getLocStart(), Record); Code = serialization::DECL_LABEL; } @@ -661,8 +680,8 @@ void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) { void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { VisitNamedDecl(D); Record.push_back(D->isInline()); - Writer.AddSourceLocation(D->getLBracLoc(), Record); - Writer.AddSourceLocation(D->getRBracLoc(), Record); + Writer.AddSourceLocation(D->getLocStart(), Record); + Writer.AddSourceLocation(D->getRBraceLoc(), Record); Writer.AddDeclRef(D->getNextNamespace(), Record); // Only write one reference--original or anonymous @@ -692,6 +711,20 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { } } } + + if (Writer.hasChain() && D->isAnonymousNamespace() && !D->getNextNamespace()){ + // This is a most recent reopening of the anonymous namespace. If its parent + // is in a previous PCH (or is the TU), mark that parent for update, because + // the original namespace always points to the latest re-opening of its + // anonymous namespace. + Decl *Parent = cast<Decl>( + D->getParent()->getRedeclContext()->getPrimaryContext()); + if (Parent->getPCHLevel() > 0) { + ASTWriter::UpdateRecord &Record = Writer.DeclUpdates[Parent]; + Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE); + Writer.AddDeclRef(D, Record); + } + } } void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { @@ -743,7 +776,6 @@ void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl( UnresolvedUsingTypenameDecl *D) { VisitTypeDecl(D); - Writer.AddSourceLocation(D->getUsingLoc(), Record); Writer.AddSourceLocation(D->getTypenameLoc(), Record); Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record); Code = serialization::DECL_UNRESOLVED_USING_TYPENAME; @@ -1001,7 +1033,6 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { VisitTypeDecl(D); Record.push_back(D->wasDeclaredWithTypename()); - Record.push_back(D->isParameterPack()); Record.push_back(D->defaultArgumentWasInherited()); Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record); @@ -1054,6 +1085,7 @@ void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) { VisitDecl(D); Writer.AddStmt(D->getAssertExpr()); Writer.AddStmt(D->getMessage()); + Writer.AddSourceLocation(D->getRParenLoc(), Record); Code = serialization::DECL_STATIC_ASSERT; } @@ -1121,6 +1153,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit Abv->Add(BitCodeAbbrevOp(0)); // isUsed + Abv->Add(BitCodeAbbrevOp(0)); // isReferenced Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier Abv->Add(BitCodeAbbrevOp(0)); // PCH level @@ -1130,6 +1163,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { // ValueDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DeclaratorDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo Abv->Add(BitCodeAbbrevOp(serialization::PREDEF_TYPE_NULL_ID)); // InfoType // VarDecl @@ -1140,10 +1174,15 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer Abv->Add(BitCodeAbbrevOp(0)); // isExceptionVariable Abv->Add(BitCodeAbbrevOp(0)); // isNRVOVariable + Abv->Add(BitCodeAbbrevOp(0)); // isCXXForRangeDecl Abv->Add(BitCodeAbbrevOp(0)); // HasInit Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo // ParmVarDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsObjCMethodParameter + Abv->Add(BitCodeAbbrevOp(0)); // ScopeDepth + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex Abv->Add(BitCodeAbbrevOp(0)); // ObjCDeclQualifier + Abv->Add(BitCodeAbbrevOp(0)); // KNRPromoted Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedDefaultArg Abv->Add(BitCodeAbbrevOp(0)); // HasUninstantiatedDefaultArg diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index af846a9..bd5889a 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -68,7 +68,7 @@ namespace clang { void VisitParenListExpr(ParenListExpr *E); void VisitUnaryOperator(UnaryOperator *E); void VisitOffsetOfExpr(OffsetOfExpr *E); - void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); + void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); void VisitArraySubscriptExpr(ArraySubscriptExpr *E); void VisitCallExpr(CallExpr *E); void VisitMemberExpr(MemberExpr *E); @@ -93,6 +93,7 @@ namespace clang { void VisitShuffleVectorExpr(ShuffleVectorExpr *E); void VisitBlockExpr(BlockExpr *E); void VisitBlockDeclRefExpr(BlockDeclRefExpr *E); + void VisitGenericSelectionExpr(GenericSelectionExpr *E); // Objective-C Expressions void VisitObjCStringLiteral(ObjCStringLiteral *E); @@ -115,6 +116,7 @@ namespace clang { // C++ Statements void VisitCXXCatchStmt(CXXCatchStmt *S); void VisitCXXTryStmt(CXXTryStmt *S); + void VisitCXXForRangeStmt(CXXForRangeStmt *); void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); void VisitCXXMemberCallExpr(CXXMemberCallExpr *E); @@ -151,6 +153,8 @@ namespace clang { void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); + void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E); + void VisitExpressionTraitExpr(ExpressionTraitExpr *E); void VisitCXXNoexceptExpr(CXXNoexceptExpr *E); void VisitPackExpansionExpr(PackExpansionExpr *E); void VisitSizeOfPackExpr(SizeOfPackExpr *E); @@ -177,7 +181,7 @@ void ASTStmtWriter::VisitStmt(Stmt *S) { void ASTStmtWriter::VisitNullStmt(NullStmt *S) { VisitStmt(S); Writer.AddSourceLocation(S->getSemiLoc(), Record); - Record.push_back(S->LeadingEmptyMacro); + Writer.AddSourceLocation(S->LeadingEmptyMacro, Record); Code = serialization::STMT_NULL; } @@ -380,19 +384,23 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); Record.push_back(E->hasQualifier()); + Record.push_back(E->getDecl() != E->getFoundDecl()); Record.push_back(E->hasExplicitTemplateArgs()); - if (E->hasQualifier()) { - Writer.AddNestedNameSpecifier(E->getQualifier(), Record); - Writer.AddSourceRange(E->getQualifierRange(), Record); - } - if (E->hasExplicitTemplateArgs()) { unsigned NumTemplateArgs = E->getNumTemplateArgs(); Record.push_back(NumTemplateArgs); - AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs()); } + if (E->hasQualifier()) + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); + + if (E->getDecl() != E->getFoundDecl()) + Writer.AddDeclRef(E->getFoundDecl(), Record); + + if (E->hasExplicitTemplateArgs()) + AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs()); + Writer.AddDeclRef(E->getDecl(), Record); Writer.AddSourceLocation(E->getLocation(), Record); Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record); @@ -425,6 +433,7 @@ void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) { Record.push_back(E->getByteLength()); Record.push_back(E->getNumConcatenated()); Record.push_back(E->isWide()); + 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 // provision for coping with abbreviations when we're jumping around @@ -479,8 +488,8 @@ void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) { for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) { const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I); Record.push_back(ON.getKind()); // FIXME: Stable encoding - Writer.AddSourceLocation(ON.getRange().getBegin(), Record); - Writer.AddSourceLocation(ON.getRange().getEnd(), Record); + Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record); + Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record); switch (ON.getKind()) { case OffsetOfExpr::OffsetOfNode::Array: Record.push_back(ON.getArrayExprIndex()); @@ -504,9 +513,9 @@ void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) { Code = serialization::EXPR_OFFSETOF; } -void ASTStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { +void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { VisitExpr(E); - Record.push_back(E->isSizeOf()); + Record.push_back(E->getKind()); if (E->isArgumentType()) Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record); else { @@ -541,10 +550,8 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { // Don't call VisitExpr, we'll write everything here. Record.push_back(E->hasQualifier()); - if (E->hasQualifier()) { - Writer.AddNestedNameSpecifier(E->getQualifier(), Record); - Writer.AddSourceRange(E->getQualifierRange(), Record); - } + if (E->hasQualifier()) + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); Record.push_back(E->hasExplicitTemplateArgs()); if (E->hasExplicitTemplateArgs()) { @@ -666,14 +673,27 @@ void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) { VisitExpr(E); - Record.push_back(E->getNumInits()); - for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) - Writer.AddStmt(E->getInit(I)); Writer.AddStmt(E->getSyntacticForm()); Writer.AddSourceLocation(E->getLBraceLoc(), Record); Writer.AddSourceLocation(E->getRBraceLoc(), Record); - Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record); + bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>(); + Record.push_back(isArrayFiller); + if (isArrayFiller) + Writer.AddStmt(E->getArrayFiller()); + else + Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record); Record.push_back(E->hadArrayRangeDesignator()); + Record.push_back(E->getNumInits()); + if (isArrayFiller) { + // ArrayFiller may have filled "holes" due to designated initializer. + // Replace them by 0 to indicate that the filler goes in that place. + Expr *filler = E->getArrayFiller(); + for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) + Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : 0); + } else { + for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) + Writer.AddStmt(E->getInit(I)); + } Code = serialization::EXPR_INIT_LIST; } @@ -785,6 +805,23 @@ void ASTStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { Code = serialization::EXPR_BLOCK_DECL_REF; } +void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) { + VisitExpr(E); + Record.push_back(E->getNumAssocs()); + + Writer.AddStmt(E->getControllingExpr()); + for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) { + Writer.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I), Record); + Writer.AddStmt(E->getAssocExpr(I)); + } + Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex()); + + Writer.AddSourceLocation(E->getGenericLoc(), Record); + Writer.AddSourceLocation(E->getDefaultLoc(), Record); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Code = serialization::EXPR_GENERIC_SELECTION; +} + //===----------------------------------------------------------------------===// // Objective-C Expressions and Statements. //===----------------------------------------------------------------------===// @@ -964,6 +1001,20 @@ void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) { Code = serialization::STMT_CXX_TRY; } +void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) { + VisitStmt(S); + Writer.AddSourceLocation(S->getForLoc(), Record); + Writer.AddSourceLocation(S->getColonLoc(), Record); + Writer.AddSourceLocation(S->getRParenLoc(), Record); + Writer.AddStmt(S->getRangeStmt()); + Writer.AddStmt(S->getBeginEndStmt()); + Writer.AddStmt(S->getCond()); + Writer.AddStmt(S->getInc()); + Writer.AddStmt(S->getLoopVarStmt()); + Writer.AddStmt(S->getBody()); + Code = serialization::STMT_CXX_FOR_RANGE; +} + void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); Record.push_back(E->getOperator()); @@ -1196,8 +1247,7 @@ ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ Writer.AddTypeRef(E->getBaseType(), Record); Record.push_back(E->isArrow()); Writer.AddSourceLocation(E->getOperatorLoc(), Record); - Writer.AddNestedNameSpecifier(E->getQualifier(), Record); - Writer.AddSourceRange(E->getQualifierRange(), Record); + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record); Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record); Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER; @@ -1253,8 +1303,7 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { } Writer.AddDeclarationNameInfo(E->NameInfo, Record); - Writer.AddNestedNameSpecifier(E->getQualifier(), Record); - Writer.AddSourceRange(E->getQualifierRange(), Record); + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); } void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { @@ -1270,6 +1319,8 @@ void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); Record.push_back(E->requiresADL()); + if (E->requiresADL()) + Record.push_back(E->isStdAssociatedNamespace()); Record.push_back(E->isOverloaded()); Writer.AddDeclRef(E->getNamingClass(), Record); Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP; @@ -1294,6 +1345,24 @@ void ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { Code = serialization::EXPR_BINARY_TYPE_TRAIT; } +void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { + VisitExpr(E); + Record.push_back(E->getTrait()); + Record.push_back(E->getValue()); + Writer.AddSourceRange(E->getSourceRange(), Record); + Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record); + Code = serialization::EXPR_ARRAY_TYPE_TRAIT; +} + +void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { + VisitExpr(E); + Record.push_back(E->getTrait()); + Record.push_back(E->getValue()); + Writer.AddSourceRange(E->getSourceRange(), Record); + Writer.AddStmt(E->getQueriedExpression()); + Code = serialization::EXPR_CXX_EXPRESSION_TRAIT; +} + void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { VisitExpr(E); Record.push_back(E->getValue()); @@ -1424,7 +1493,7 @@ void ASTWriter::FlushStmts() { WriteSubStmt(StmtsToEmit[I]); assert(N == StmtsToEmit.size() && - "Substatement writen via AddStmt rather than WriteSubStmt!"); + "Substatement written via AddStmt rather than WriteSubStmt!"); // Note that we are at the end of a full expression. Any // expression records that follow this one are part of a different diff --git a/lib/Serialization/CMakeLists.txt b/lib/Serialization/CMakeLists.txt index 10c8904..66a72ee 100644 --- a/lib/Serialization/CMakeLists.txt +++ b/lib/Serialization/CMakeLists.txt @@ -2,7 +2,6 @@ #set(LLVM_USED_LIBS ???) add_clang_library(clangSerialization - GeneratePCH.cpp ASTCommon.cpp ASTReader.cpp ASTReaderDecl.cpp @@ -10,6 +9,8 @@ add_clang_library(clangSerialization ASTWriter.cpp ASTWriterDecl.cpp ASTWriterStmt.cpp + ChainedIncludesSource.cpp + GeneratePCH.cpp ) add_dependencies(clangSerialization diff --git a/lib/Serialization/ChainedIncludesSource.cpp b/lib/Serialization/ChainedIncludesSource.cpp new file mode 100644 index 0000000..da5be95 --- /dev/null +++ b/lib/Serialization/ChainedIncludesSource.cpp @@ -0,0 +1,235 @@ +//===- ChainedIncludesSource.cpp - Chained PCHs in Memory -------*- 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 ChainedIncludesSource class, which converts headers +// to chained PCHs in memory, mainly used for testing. +// +//===----------------------------------------------------------------------===// + +#include "clang/Serialization/ChainedIncludesSource.h" +#include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/ASTWriter.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/ASTUnit.h" +#include "clang/Parse/ParseAST.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace clang; + +static ASTReader *createASTReader(CompilerInstance &CI, + llvm::StringRef pchFile, + llvm::MemoryBuffer **memBufs, + unsigned numBufs, + ASTDeserializationListener *deserialListener = 0) { + Preprocessor &PP = CI.getPreprocessor(); + llvm::OwningPtr<ASTReader> Reader; + Reader.reset(new ASTReader(PP, &CI.getASTContext(), /*isysroot=*/0, + /*DisableValidation=*/true)); + Reader->setASTMemoryBuffers(memBufs, numBufs); + Reader->setDeserializationListener(deserialListener); + switch (Reader->ReadAST(pchFile, ASTReader::PCH)) { + case ASTReader::Success: + // Set the predefines buffer as suggested by the PCH reader. + PP.setPredefines(Reader->getSuggestedPredefines()); + return Reader.take(); + + case ASTReader::Failure: + case ASTReader::IgnorePCH: + break; + } + return 0; +} + +ChainedIncludesSource::~ChainedIncludesSource() { + for (unsigned i = 0, e = CIs.size(); i != e; ++i) + delete CIs[i]; +} + +ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) { + + std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes; + assert(!includes.empty() && "No '-chain-include' in options!"); + + llvm::OwningPtr<ChainedIncludesSource> source(new ChainedIncludesSource()); + InputKind IK = CI.getFrontendOpts().Inputs[0].first; + + llvm::SmallVector<llvm::MemoryBuffer *, 4> serialBufs; + + for (unsigned i = 0, e = includes.size(); i != e; ++i) { + bool firstInclude = (i == 0); + llvm::OwningPtr<CompilerInvocation> CInvok; + CInvok.reset(new CompilerInvocation(CI.getInvocation())); + + CInvok->getPreprocessorOpts().ChainedIncludes.clear(); + CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear(); + CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear(); + CInvok->getPreprocessorOpts().DisablePCHValidation = true; + CInvok->getPreprocessorOpts().Includes.clear(); + CInvok->getPreprocessorOpts().MacroIncludes.clear(); + CInvok->getPreprocessorOpts().Macros.clear(); + + CInvok->getFrontendOpts().Inputs.clear(); + CInvok->getFrontendOpts().Inputs.push_back(std::make_pair(IK, includes[i])); + + TextDiagnosticPrinter *DiagClient = + new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions()); + llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic(DiagID, + DiagClient)); + + llvm::OwningPtr<CompilerInstance> Clang(new CompilerInstance()); + Clang->setInvocation(CInvok.take()); + Clang->setDiagnostics(Diags.getPtr()); + Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), + Clang->getTargetOpts())); + Clang->createFileManager(); + Clang->createSourceManager(Clang->getFileManager()); + Clang->createPreprocessor(); + Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(), + &Clang->getPreprocessor()); + Clang->createASTContext(); + + llvm::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)); + Clang->getASTContext().setASTMutationListener( + consumer->GetASTMutationListener()); + Clang->setASTConsumer(consumer.take()); + Clang->createSema(/*CompleteTranslationUnit=*/false, 0); + + if (firstInclude) { + Preprocessor &PP = Clang->getPreprocessor(); + PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), + PP.getLangOptions()); + } else { + assert(!serialBufs.empty()); + llvm::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(), + serialBufs[si]->getBufferSize()))); + } + std::string pchName = includes[i-1]; + llvm::raw_string_ostream os(pchName); + os << ".pch" << i-1; + os.flush(); + llvm::OwningPtr<ExternalASTSource> Reader; + Reader.reset(createASTReader(*Clang, pchName, bufs.data(), bufs.size(), + Clang->getASTConsumer().GetASTDeserializationListener())); + if (!Reader) + return 0; + Clang->getASTContext().setExternalSource(Reader); + } + + if (!Clang->InitializeSourceManager(includes[i])) + return 0; + + ParseAST(Clang->getSema()); + OS.flush(); + Clang->getDiagnosticClient().EndSourceFile(); + serialBufs.push_back( + llvm::MemoryBuffer::getMemBufferCopy(llvm::StringRef(serialAST.data(), + serialAST.size()))); + source->CIs.push_back(Clang.take()); + } + + assert(!serialBufs.empty()); + std::string pchName = includes.back() + ".pch-final"; + llvm::OwningPtr<ASTReader> Reader; + Reader.reset(createASTReader(CI, pchName, + serialBufs.data(), serialBufs.size())); + if (!Reader) + return 0; + + source->FinalReader.reset(Reader.take()); + return source.take(); +} + +//===----------------------------------------------------------------------===// +// ExternalASTSource interface. +//===----------------------------------------------------------------------===// + +Decl *ChainedIncludesSource::GetExternalDecl(uint32_t ID) { + return getFinalReader().GetExternalDecl(ID); +} +Selector ChainedIncludesSource::GetExternalSelector(uint32_t ID) { + return getFinalReader().GetExternalSelector(ID); +} +uint32_t ChainedIncludesSource::GetNumExternalSelectors() { + return getFinalReader().GetNumExternalSelectors(); +} +Stmt *ChainedIncludesSource::GetExternalDeclStmt(uint64_t Offset) { + return getFinalReader().GetExternalDeclStmt(Offset); +} +CXXBaseSpecifier * +ChainedIncludesSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) { + return getFinalReader().GetExternalCXXBaseSpecifiers(Offset); +} +DeclContextLookupResult +ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC, + DeclarationName Name) { + return getFinalReader().FindExternalVisibleDeclsByName(DC, Name); +} +void ChainedIncludesSource::MaterializeVisibleDecls(const DeclContext *DC) { + return getFinalReader().MaterializeVisibleDecls(DC); +} +bool ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC, + bool (*isKindWeWant)(Decl::Kind), + llvm::SmallVectorImpl<Decl*> &Result) { + return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result); +} +void ChainedIncludesSource::CompleteType(TagDecl *Tag) { + return getFinalReader().CompleteType(Tag); +} +void ChainedIncludesSource::CompleteType(ObjCInterfaceDecl *Class) { + return getFinalReader().CompleteType(Class); +} +void ChainedIncludesSource::StartedDeserializing() { + return getFinalReader().StartedDeserializing(); +} +void ChainedIncludesSource::FinishedDeserializing() { + return getFinalReader().FinishedDeserializing(); +} +void ChainedIncludesSource::StartTranslationUnit(ASTConsumer *Consumer) { + return getFinalReader().StartTranslationUnit(Consumer); +} +void ChainedIncludesSource::PrintStats() { + return getFinalReader().PrintStats(); +} +void ChainedIncludesSource::getMemoryBufferSizes(MemoryBufferSizes &sizes)const{ + for (unsigned i = 0, e = CIs.size(); i != e; ++i) { + if (const ExternalASTSource *eSrc = + CIs[i]->getASTContext().getExternalSource()) { + eSrc->getMemoryBufferSizes(sizes); + } + } + + getFinalReader().getMemoryBufferSizes(sizes); +} + +void ChainedIncludesSource::InitializeSema(Sema &S) { + return getFinalReader().InitializeSema(S); +} +void ChainedIncludesSource::ForgetSema() { + return getFinalReader().ForgetSema(); +} +std::pair<ObjCMethodList,ObjCMethodList> +ChainedIncludesSource::ReadMethodPool(Selector Sel) { + return getFinalReader().ReadMethodPool(Sel); +} +bool ChainedIncludesSource::LookupUnqualified(LookupResult &R, Scope *S) { + return getFinalReader().LookupUnqualified(R, S); +} + |