diff options
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 1084 |
1 files changed, 322 insertions, 762 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 31b96ea7d6..3f4b9cf5fb 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -13,7 +13,9 @@ #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTDeserializationListener.h" +#include "clang/Serialization/ModuleManager.h" #include "ASTCommon.h" +#include "ASTReaderInternals.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/Utils.h" #include "clang/Sema/Sema.h" @@ -52,6 +54,7 @@ using namespace clang; using namespace clang::serialization; +using namespace clang::serialization::reader; //===----------------------------------------------------------------------===// // PCH validator implementation @@ -479,425 +482,321 @@ ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) { } -namespace { -class ASTSelectorLookupTrait { - ASTReader &Reader; - Module &F; - -public: - struct data_type { - SelectorID ID; - llvm::SmallVector<ObjCMethodDecl *, 2> Instance; - llvm::SmallVector<ObjCMethodDecl *, 2> Factory; - }; - - typedef Selector external_key_type; - typedef external_key_type internal_key_type; - - ASTSelectorLookupTrait(ASTReader &Reader, Module &F) - : Reader(Reader), F(F) { } - - static bool EqualKey(const internal_key_type& a, - const internal_key_type& b) { - return a == b; - } - - static unsigned ComputeHash(Selector Sel) { - return serialization::ComputeHash(Sel); - } - // This hopefully will just get inlined and removed by the optimizer. - static const internal_key_type& - GetInternalKey(const external_key_type& x) { return x; } - - static std::pair<unsigned, unsigned> - ReadKeyDataLength(const unsigned char*& d) { - using namespace clang::io; - unsigned KeyLen = ReadUnalignedLE16(d); - unsigned DataLen = ReadUnalignedLE16(d); - return std::make_pair(KeyLen, DataLen); - } +unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) { + return serialization::ComputeHash(Sel); +} - internal_key_type ReadKey(const unsigned char* d, unsigned) { - using namespace clang::io; - SelectorTable &SelTable = Reader.getContext()->Selectors; - unsigned N = ReadUnalignedLE16(d); - IdentifierInfo *FirstII - = Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)); - if (N == 0) - return SelTable.getNullarySelector(FirstII); - else if (N == 1) - return SelTable.getUnarySelector(FirstII); - SmallVector<IdentifierInfo *, 16> Args; - Args.push_back(FirstII); - for (unsigned I = 1; I != N; ++I) - Args.push_back(Reader.getLocalIdentifier(F, ReadUnalignedLE32(d))); +std::pair<unsigned, unsigned> +ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) { + using namespace clang::io; + unsigned KeyLen = ReadUnalignedLE16(d); + unsigned DataLen = ReadUnalignedLE16(d); + return std::make_pair(KeyLen, DataLen); +} - return SelTable.getSelector(N, Args.data()); - } +ASTSelectorLookupTrait::internal_key_type +ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) { + using namespace clang::io; + SelectorTable &SelTable = Reader.getContext()->Selectors; + unsigned N = ReadUnalignedLE16(d); + IdentifierInfo *FirstII + = Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)); + if (N == 0) + return SelTable.getNullarySelector(FirstII); + else if (N == 1) + return SelTable.getUnarySelector(FirstII); - data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) { - using namespace clang::io; + SmallVector<IdentifierInfo *, 16> Args; + Args.push_back(FirstII); + for (unsigned I = 1; I != N; ++I) + Args.push_back(Reader.getLocalIdentifier(F, ReadUnalignedLE32(d))); - data_type Result; + return SelTable.getSelector(N, Args.data()); +} - Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d)); - unsigned NumInstanceMethods = ReadUnalignedLE16(d); - unsigned NumFactoryMethods = ReadUnalignedLE16(d); +ASTSelectorLookupTrait::data_type +ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, + unsigned DataLen) { + using namespace clang::io; - // Load instance methods - ObjCMethodList *Prev = 0; - for (unsigned I = 0; I != NumInstanceMethods; ++I) { - if (ObjCMethodDecl *Method - = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d))) - Result.Instance.push_back(Method); - } + data_type Result; - // Load factory methods - Prev = 0; - for (unsigned I = 0; I != NumFactoryMethods; ++I) { - if (ObjCMethodDecl *Method - = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d))) - Result.Factory.push_back(Method); - } + Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d)); + unsigned NumInstanceMethods = ReadUnalignedLE16(d); + unsigned NumFactoryMethods = ReadUnalignedLE16(d); - return Result; + // Load instance methods + ObjCMethodList *Prev = 0; + for (unsigned I = 0; I != NumInstanceMethods; ++I) { + if (ObjCMethodDecl *Method + = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d))) + Result.Instance.push_back(Method); } -}; - -} // end anonymous namespace - -/// \brief The on-disk hash table used for the global method pool. -typedef OnDiskChainedHashTable<ASTSelectorLookupTrait> - ASTSelectorLookupTable; - -namespace clang { -class ASTIdentifierLookupTrait { - ASTReader &Reader; - Module &F; - - // If we know the IdentifierInfo in advance, it is here and we will - // not build a new one. Used when deserializing information about an - // identifier that was constructed before the AST file was read. - IdentifierInfo *KnownII; - -public: - typedef IdentifierInfo * data_type; - typedef const std::pair<const char*, unsigned> external_key_type; - - typedef external_key_type internal_key_type; - - ASTIdentifierLookupTrait(ASTReader &Reader, Module &F, - IdentifierInfo *II = 0) - : Reader(Reader), F(F), KnownII(II) { } - - static bool EqualKey(const internal_key_type& a, - const internal_key_type& b) { - return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0 - : false; + // Load factory methods + Prev = 0; + for (unsigned I = 0; I != NumFactoryMethods; ++I) { + if (ObjCMethodDecl *Method + = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d))) + Result.Factory.push_back(Method); } - static unsigned ComputeHash(const internal_key_type& a) { - return llvm::HashString(StringRef(a.first, a.second)); - } + return Result; +} - // This hopefully will just get inlined and removed by the optimizer. - static const internal_key_type& - GetInternalKey(const external_key_type& x) { return x; } +unsigned ASTIdentifierLookupTrait::ComputeHash(const internal_key_type& a) { + return llvm::HashString(StringRef(a.first, a.second)); +} - // This hopefully will just get inlined and removed by the optimizer. - static const external_key_type& - GetExternalKey(const internal_key_type& x) { return x; } +std::pair<unsigned, unsigned> +ASTIdentifierLookupTrait::ReadKeyDataLength(const unsigned char*& d) { + using namespace clang::io; + unsigned DataLen = ReadUnalignedLE16(d); + unsigned KeyLen = ReadUnalignedLE16(d); + return std::make_pair(KeyLen, DataLen); +} - static std::pair<unsigned, unsigned> - ReadKeyDataLength(const unsigned char*& d) { - using namespace clang::io; - unsigned DataLen = ReadUnalignedLE16(d); - unsigned KeyLen = ReadUnalignedLE16(d); - return std::make_pair(KeyLen, DataLen); - } +std::pair<const char*, unsigned> +ASTIdentifierLookupTrait::ReadKey(const unsigned char* d, unsigned n) { + assert(n >= 2 && d[n-1] == '\0'); + return std::make_pair((const char*) d, n-1); +} - static std::pair<const char*, unsigned> - ReadKey(const unsigned char* d, unsigned n) { - assert(n >= 2 && d[n-1] == '\0'); - return std::make_pair((const char*) d, n-1); - } +IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, + const unsigned char* d, + unsigned DataLen) { + using namespace clang::io; + unsigned RawID = ReadUnalignedLE32(d); + bool IsInteresting = RawID & 0x01; - IdentifierInfo *ReadData(const internal_key_type& k, - const unsigned char* d, - unsigned DataLen) { - using namespace clang::io; - unsigned RawID = ReadUnalignedLE32(d); - bool IsInteresting = RawID & 0x01; - - // Wipe out the "is interesting" bit. - RawID = RawID >> 1; - - IdentID ID = Reader.getGlobalIdentifierID(F, RawID); - if (!IsInteresting) { - // For uninteresting identifiers, just build the IdentifierInfo - // and associate it with the persistent ID. - IdentifierInfo *II = KnownII; - if (!II) - II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second)); - Reader.SetIdentifierInfo(ID, II); - II->setIsFromAST(); - return II; - } + // Wipe out the "is interesting" bit. + RawID = RawID >> 1; - unsigned Bits = ReadUnalignedLE16(d); - bool CPlusPlusOperatorKeyword = Bits & 0x01; - Bits >>= 1; - bool HasRevertedTokenIDToIdentifier = Bits & 0x01; - Bits >>= 1; - bool Poisoned = Bits & 0x01; - Bits >>= 1; - bool ExtensionToken = Bits & 0x01; - Bits >>= 1; - bool hasMacroDefinition = Bits & 0x01; - Bits >>= 1; - unsigned ObjCOrBuiltinID = Bits & 0x3FF; - Bits >>= 10; - - assert(Bits == 0 && "Extra bits in the identifier?"); - DataLen -= 6; - - // Build the IdentifierInfo itself and link the identifier ID with - // the new IdentifierInfo. + IdentID ID = Reader.getGlobalIdentifierID(F, RawID); + if (!IsInteresting) { + // For uninteresting identifiers, just build the IdentifierInfo + // and associate it with the persistent ID. IdentifierInfo *II = KnownII; if (!II) II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second)); Reader.SetIdentifierInfo(ID, II); - - // Set or check the various bits in the IdentifierInfo structure. - // Token IDs are read-only. - if (HasRevertedTokenIDToIdentifier) - II->RevertTokenIDToIdentifier(); - II->setObjCOrBuiltinID(ObjCOrBuiltinID); - assert(II->isExtensionToken() == ExtensionToken && - "Incorrect extension token flag"); - (void)ExtensionToken; - if (Poisoned) - II->setIsPoisoned(true); - assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword && - "Incorrect C++ operator keyword flag"); - (void)CPlusPlusOperatorKeyword; - - // If this identifier is a macro, deserialize the macro - // definition. - if (hasMacroDefinition) { - // FIXME: Check for conflicts? - uint32_t Offset = ReadUnalignedLE32(d); - Reader.SetIdentifierIsMacro(II, F, Offset); - DataLen -= 4; - } - - // Read all of the declarations visible at global scope with this - // name. - if (Reader.getContext() == 0) return II; - if (DataLen > 0) { - SmallVector<uint32_t, 4> DeclIDs; - for (; DataLen > 0; DataLen -= 4) - DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d))); - Reader.SetGloballyVisibleDecls(II, DeclIDs); - } - II->setIsFromAST(); return II; } -}; - -} // end anonymous namespace - -/// \brief The on-disk hash table used to contain information about -/// all of the identifiers in the program. -typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait> - ASTIdentifierLookupTable; - -namespace { -class ASTDeclContextNameLookupTrait { - ASTReader &Reader; - Module &F; - -public: - /// \brief Pair of begin/end iterators for DeclIDs. - /// - /// Note that these declaration IDs are local to the module that contains this - /// particular lookup t - typedef std::pair<DeclID *, DeclID *> data_type; - - /// \brief Special internal key for declaration names. - /// The hash table creates keys for comparison; we do not create - /// a DeclarationName for the internal key to avoid deserializing types. - struct DeclNameKey { - DeclarationName::NameKind Kind; - uint64_t Data; - DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { } - }; - - typedef DeclarationName external_key_type; - typedef DeclNameKey internal_key_type; - - explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, - Module &F) - : Reader(Reader), F(F) { } - - static bool EqualKey(const internal_key_type& a, - const internal_key_type& b) { - return a.Kind == b.Kind && a.Data == b.Data; - } - unsigned ComputeHash(const DeclNameKey &Key) const { - llvm::FoldingSetNodeID ID; - ID.AddInteger(Key.Kind); - - switch (Key.Kind) { - case DeclarationName::Identifier: - case DeclarationName::CXXLiteralOperatorName: - ID.AddString(((IdentifierInfo*)Key.Data)->getName()); - break; - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - ID.AddInteger(serialization::ComputeHash(Selector(Key.Data))); - break; - case DeclarationName::CXXOperatorName: - ID.AddInteger((OverloadedOperatorKind)Key.Data); - break; - case DeclarationName::CXXConstructorName: - case DeclarationName::CXXDestructorName: - case DeclarationName::CXXConversionFunctionName: - case DeclarationName::CXXUsingDirective: - break; - } - - return ID.ComputeHash(); + unsigned Bits = ReadUnalignedLE16(d); + bool CPlusPlusOperatorKeyword = Bits & 0x01; + Bits >>= 1; + bool HasRevertedTokenIDToIdentifier = Bits & 0x01; + Bits >>= 1; + bool Poisoned = Bits & 0x01; + Bits >>= 1; + bool ExtensionToken = Bits & 0x01; + Bits >>= 1; + bool hasMacroDefinition = Bits & 0x01; + Bits >>= 1; + unsigned ObjCOrBuiltinID = Bits & 0x3FF; + Bits >>= 10; + + assert(Bits == 0 && "Extra bits in the identifier?"); + DataLen -= 6; + + // Build the IdentifierInfo itself and link the identifier ID with + // the new IdentifierInfo. + IdentifierInfo *II = KnownII; + if (!II) + II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second)); + Reader.SetIdentifierInfo(ID, II); + + // Set or check the various bits in the IdentifierInfo structure. + // Token IDs are read-only. + if (HasRevertedTokenIDToIdentifier) + II->RevertTokenIDToIdentifier(); + II->setObjCOrBuiltinID(ObjCOrBuiltinID); + assert(II->isExtensionToken() == ExtensionToken && + "Incorrect extension token flag"); + (void)ExtensionToken; + if (Poisoned) + II->setIsPoisoned(true); + assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword && + "Incorrect C++ operator keyword flag"); + (void)CPlusPlusOperatorKeyword; + + // If this identifier is a macro, deserialize the macro + // definition. + if (hasMacroDefinition) { + // FIXME: Check for conflicts? + uint32_t Offset = ReadUnalignedLE32(d); + Reader.SetIdentifierIsMacro(II, F, Offset); + DataLen -= 4; + } + + // Read all of the declarations visible at global scope with this + // name. + if (Reader.getContext() == 0) return II; + if (DataLen > 0) { + SmallVector<uint32_t, 4> DeclIDs; + for (; DataLen > 0; DataLen -= 4) + DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d))); + Reader.SetGloballyVisibleDecls(II, DeclIDs); + } + + II->setIsFromAST(); + return II; +} + +unsigned +ASTDeclContextNameLookupTrait::ComputeHash(const DeclNameKey &Key) const { + llvm::FoldingSetNodeID ID; + ID.AddInteger(Key.Kind); + + switch (Key.Kind) { + case DeclarationName::Identifier: + case DeclarationName::CXXLiteralOperatorName: + ID.AddString(((IdentifierInfo*)Key.Data)->getName()); + break; + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + ID.AddInteger(serialization::ComputeHash(Selector(Key.Data))); + break; + case DeclarationName::CXXOperatorName: + ID.AddInteger((OverloadedOperatorKind)Key.Data); + break; + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + case DeclarationName::CXXUsingDirective: + break; } - internal_key_type GetInternalKey(const external_key_type& Name) const { - DeclNameKey Key; - Key.Kind = Name.getNameKind(); - switch (Name.getNameKind()) { - case DeclarationName::Identifier: - Key.Data = (uint64_t)Name.getAsIdentifierInfo(); - break; - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr(); - break; - case DeclarationName::CXXOperatorName: - Key.Data = Name.getCXXOverloadedOperator(); - break; - case DeclarationName::CXXLiteralOperatorName: - Key.Data = (uint64_t)Name.getCXXLiteralIdentifier(); - break; - case DeclarationName::CXXConstructorName: - case DeclarationName::CXXDestructorName: - case DeclarationName::CXXConversionFunctionName: - case DeclarationName::CXXUsingDirective: - Key.Data = 0; - break; - } + return ID.ComputeHash(); +} - return Key; +ASTDeclContextNameLookupTrait::internal_key_type +ASTDeclContextNameLookupTrait::GetInternalKey( + const external_key_type& Name) const { + DeclNameKey Key; + Key.Kind = Name.getNameKind(); + switch (Name.getNameKind()) { + case DeclarationName::Identifier: + Key.Data = (uint64_t)Name.getAsIdentifierInfo(); + break; + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr(); + break; + case DeclarationName::CXXOperatorName: + Key.Data = Name.getCXXOverloadedOperator(); + break; + case DeclarationName::CXXLiteralOperatorName: + Key.Data = (uint64_t)Name.getCXXLiteralIdentifier(); + break; + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + case DeclarationName::CXXUsingDirective: + Key.Data = 0; + break; } - external_key_type GetExternalKey(const internal_key_type& Key) const { - ASTContext *Context = Reader.getContext(); - switch (Key.Kind) { - case DeclarationName::Identifier: - return DeclarationName((IdentifierInfo*)Key.Data); - - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - return DeclarationName(Selector(Key.Data)); + return Key; +} - case DeclarationName::CXXConstructorName: - return Context->DeclarationNames.getCXXConstructorName( - Context->getCanonicalType(Reader.getLocalType(F, Key.Data))); +ASTDeclContextNameLookupTrait::external_key_type +ASTDeclContextNameLookupTrait::GetExternalKey( + const internal_key_type& Key) const { + ASTContext *Context = Reader.getContext(); + switch (Key.Kind) { + case DeclarationName::Identifier: + return DeclarationName((IdentifierInfo*)Key.Data); - case DeclarationName::CXXDestructorName: - return Context->DeclarationNames.getCXXDestructorName( - Context->getCanonicalType(Reader.getLocalType(F, Key.Data))); + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + return DeclarationName(Selector(Key.Data)); - case DeclarationName::CXXConversionFunctionName: - return Context->DeclarationNames.getCXXConversionFunctionName( - Context->getCanonicalType(Reader.getLocalType(F, Key.Data))); + case DeclarationName::CXXConstructorName: + return Context->DeclarationNames.getCXXConstructorName( + Context->getCanonicalType(Reader.getLocalType(F, Key.Data))); - case DeclarationName::CXXOperatorName: - return Context->DeclarationNames.getCXXOperatorName( - (OverloadedOperatorKind)Key.Data); + case DeclarationName::CXXDestructorName: + return Context->DeclarationNames.getCXXDestructorName( + Context->getCanonicalType(Reader.getLocalType(F, Key.Data))); - case DeclarationName::CXXLiteralOperatorName: - return Context->DeclarationNames.getCXXLiteralOperatorName( - (IdentifierInfo*)Key.Data); + case DeclarationName::CXXConversionFunctionName: + return Context->DeclarationNames.getCXXConversionFunctionName( + Context->getCanonicalType(Reader.getLocalType(F, Key.Data))); - case DeclarationName::CXXUsingDirective: - return DeclarationName::getUsingDirectiveName(); - } + case DeclarationName::CXXOperatorName: + return Context->DeclarationNames.getCXXOperatorName( + (OverloadedOperatorKind)Key.Data); - llvm_unreachable("Invalid Name Kind ?"); - } + case DeclarationName::CXXLiteralOperatorName: + return Context->DeclarationNames.getCXXLiteralOperatorName( + (IdentifierInfo*)Key.Data); - static std::pair<unsigned, unsigned> - ReadKeyDataLength(const unsigned char*& d) { - using namespace clang::io; - unsigned KeyLen = ReadUnalignedLE16(d); - unsigned DataLen = ReadUnalignedLE16(d); - return std::make_pair(KeyLen, DataLen); + case DeclarationName::CXXUsingDirective: + return DeclarationName::getUsingDirectiveName(); } - internal_key_type ReadKey(const unsigned char* d, unsigned) { - using namespace clang::io; + llvm_unreachable("Invalid Name Kind ?"); +} - DeclNameKey Key; - Key.Kind = (DeclarationName::NameKind)*d++; - switch (Key.Kind) { - case DeclarationName::Identifier: - Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)); - break; - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - Key.Data = - (uint64_t)Reader.getLocalSelector(F, ReadUnalignedLE32(d)) - .getAsOpaquePtr(); - break; - case DeclarationName::CXXOperatorName: - Key.Data = *d++; // OverloadedOperatorKind - break; - case DeclarationName::CXXLiteralOperatorName: - Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)); - break; - case DeclarationName::CXXConstructorName: - case DeclarationName::CXXDestructorName: - case DeclarationName::CXXConversionFunctionName: - case DeclarationName::CXXUsingDirective: - Key.Data = 0; - break; - } +std::pair<unsigned, unsigned> +ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) { + using namespace clang::io; + unsigned KeyLen = ReadUnalignedLE16(d); + unsigned DataLen = ReadUnalignedLE16(d); + return std::make_pair(KeyLen, DataLen); +} - return Key; - } +ASTDeclContextNameLookupTrait::internal_key_type +ASTDeclContextNameLookupTrait::ReadKey(const unsigned char* d, unsigned) { + using namespace clang::io; - data_type ReadData(internal_key_type, const unsigned char* d, - unsigned DataLen) { - using namespace clang::io; - unsigned NumDecls = ReadUnalignedLE16(d); - DeclID *Start = (DeclID *)d; - return std::make_pair(Start, Start + NumDecls); + DeclNameKey Key; + Key.Kind = (DeclarationName::NameKind)*d++; + switch (Key.Kind) { + case DeclarationName::Identifier: + Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)); + break; + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + Key.Data = + (uint64_t)Reader.getLocalSelector(F, ReadUnalignedLE32(d)) + .getAsOpaquePtr(); + break; + case DeclarationName::CXXOperatorName: + Key.Data = *d++; // OverloadedOperatorKind + break; + case DeclarationName::CXXLiteralOperatorName: + Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)); + break; + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + case DeclarationName::CXXUsingDirective: + Key.Data = 0; + break; } -}; -} // end anonymous namespace + return Key; +} -/// \brief The on-disk hash table used for the DeclContext's Name lookup table. -typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait> - ASTDeclContextNameLookupTable; +ASTDeclContextNameLookupTrait::data_type +ASTDeclContextNameLookupTrait::ReadData(internal_key_type, + const unsigned char* d, + unsigned DataLen) { + using namespace clang::io; + unsigned NumDecls = ReadUnalignedLE16(d); + DeclID *Start = (DeclID *)d; + return std::make_pair(Start, Start + NumDecls); +} bool ASTReader::ReadDeclContextStorage(Module &M, llvm::BitstreamCursor &Cursor, @@ -1631,116 +1530,65 @@ ASTReader::getGlobalPreprocessedEntityID(Module &M, unsigned LocalID) { return LocalID + I->second; } -namespace { - /// \brief Trait class used to search the on-disk hash table containing all of - /// the header search information. - /// - /// The on-disk hash table contains a mapping from each header path to - /// information about that header (how many times it has been included, its - /// controlling macro, etc.). Note that we actually hash based on the - /// filename, and support "deep" comparisons of file names based on current - /// inode numbers, so that the search can cope with non-normalized path names - /// and symlinks. - class HeaderFileInfoTrait { - ASTReader &Reader; - Module &M; - HeaderSearch *HS; - const char *FrameworkStrings; - const char *SearchPath; - struct stat SearchPathStatBuf; - llvm::Optional<int> SearchPathStatResult; - - int StatSimpleCache(const char *Path, struct stat *StatBuf) { - if (Path == SearchPath) { - if (!SearchPathStatResult) - SearchPathStatResult = stat(Path, &SearchPathStatBuf); - - *StatBuf = SearchPathStatBuf; - return *SearchPathStatResult; - } - - return stat(Path, StatBuf); - } - - public: - typedef const char *external_key_type; - typedef const char *internal_key_type; - - typedef HeaderFileInfo data_type; - - HeaderFileInfoTrait(ASTReader &Reader, Module &M, HeaderSearch *HS, - const char *FrameworkStrings, - const char *SearchPath = 0) - : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings), - SearchPath(SearchPath) { } - - static unsigned ComputeHash(const char *path) { - return llvm::HashString(llvm::sys::path::filename(path)); - } - - static internal_key_type GetInternalKey(const char *path) { return path; } +unsigned HeaderFileInfoTrait::ComputeHash(const char *path) { + return llvm::HashString(llvm::sys::path::filename(path)); +} - bool EqualKey(internal_key_type a, internal_key_type b) { - if (strcmp(a, b) == 0) - return true; - - if (llvm::sys::path::filename(a) != llvm::sys::path::filename(b)) - return false; - - // The file names match, but the path names don't. stat() the files to - // see if they are the same. - struct stat StatBufA, StatBufB; - if (StatSimpleCache(a, &StatBufA) || StatSimpleCache(b, &StatBufB)) - return false; - - return StatBufA.st_ino == StatBufB.st_ino; - } +HeaderFileInfoTrait::internal_key_type +HeaderFileInfoTrait::GetInternalKey(const char *path) { return path; } - static std::pair<unsigned, unsigned> - ReadKeyDataLength(const unsigned char*& d) { - unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d); - unsigned DataLen = (unsigned) *d++; - return std::make_pair(KeyLen + 1, DataLen); - } +bool HeaderFileInfoTrait::EqualKey(internal_key_type a, internal_key_type b) { + if (strcmp(a, b) == 0) + return true; + + if (llvm::sys::path::filename(a) != llvm::sys::path::filename(b)) + return false; + + // The file names match, but the path names don't. stat() the files to + // see if they are the same. + struct stat StatBufA, StatBufB; + if (StatSimpleCache(a, &StatBufA) || StatSimpleCache(b, &StatBufB)) + return false; + + return StatBufA.st_ino == StatBufB.st_ino; +} - static internal_key_type ReadKey(const unsigned char *d, unsigned) { - return (const char *)d; - } +std::pair<unsigned, unsigned> +HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) { + unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d); + unsigned DataLen = (unsigned) *d++; + return std::make_pair(KeyLen + 1, DataLen); +} - data_type ReadData(const internal_key_type, const unsigned char *d, - unsigned DataLen) { - const unsigned char *End = d + DataLen; - using namespace clang::io; - HeaderFileInfo HFI; - unsigned Flags = *d++; - HFI.isImport = (Flags >> 5) & 0x01; - HFI.isPragmaOnce = (Flags >> 4) & 0x01; - HFI.DirInfo = (Flags >> 2) & 0x03; - HFI.Resolved = (Flags >> 1) & 0x01; - HFI.IndexHeaderMapHeader = Flags & 0x01; - HFI.NumIncludes = ReadUnalignedLE16(d); - HFI.ControllingMacroID = Reader.getGlobalDeclID(M, ReadUnalignedLE32(d)); - if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) { - // The framework offset is 1 greater than the actual offset, - // since 0 is used as an indicator for "no framework name". - StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1); - HFI.Framework = HS->getUniqueFrameworkName(FrameworkName); - } - - assert(End == d && "Wrong data length in HeaderFileInfo deserialization"); - (void)End; - - // This HeaderFileInfo was externally loaded. - HFI.External = true; - return HFI; - } - }; +HeaderFileInfoTrait::data_type +HeaderFileInfoTrait::ReadData(const internal_key_type, const unsigned char *d, + unsigned DataLen) { + const unsigned char *End = d + DataLen; + using namespace clang::io; + HeaderFileInfo HFI; + unsigned Flags = *d++; + HFI.isImport = (Flags >> 5) & 0x01; + HFI.isPragmaOnce = (Flags >> 4) & 0x01; + HFI.DirInfo = (Flags >> 2) & 0x03; + HFI.Resolved = (Flags >> 1) & 0x01; + HFI.IndexHeaderMapHeader = Flags & 0x01; + HFI.NumIncludes = ReadUnalignedLE16(d); + HFI.ControllingMacroID = Reader.getGlobalDeclID(M, ReadUnalignedLE32(d)); + if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) { + // The framework offset is 1 greater than the actual offset, + // since 0 is used as an indicator for "no framework name". + StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1); + HFI.Framework = HS->getUniqueFrameworkName(FrameworkName); + } + + assert(End == d && "Wrong data length in HeaderFileInfo deserialization"); + (void)End; + + // This HeaderFileInfo was externally loaded. + HFI.External = true; + return HFI; } -/// \brief The on-disk hash table used for the global method pool. -typedef OnDiskChainedHashTable<HeaderFileInfoTrait> - HeaderFileInfoLookupTable; - void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, Module &F, uint64_t LocalOffset) { // Note that this identifier has a macro definition. @@ -5718,291 +5566,3 @@ ASTReader::~ASTReader() { delete static_cast<ASTDeclContextNameLookupTable*>(J->first); } } - -//===----------------------------------------------------------------------===// -// Module implementation -//===----------------------------------------------------------------------===// -Module::Module(ModuleKind Kind) - : Kind(Kind), DirectlyImported(false), SizeInBits(0), - LocalNumSLocEntries(0), SLocEntryBaseID(0), - SLocEntryBaseOffset(0), SLocEntryOffsets(0), - SLocFileOffsets(0), LocalNumIdentifiers(0), - IdentifierOffsets(0), BaseIdentifierID(0), IdentifierTableData(0), - IdentifierLookupTable(0), BasePreprocessedEntityID(0), - LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0), - BaseMacroDefinitionID(0), LocalNumHeaderFileInfos(0), - HeaderFileInfoTableData(0), HeaderFileInfoTable(0), - HeaderFileFrameworkStrings(0), - LocalNumSelectors(0), SelectorOffsets(0), BaseSelectorID(0), - SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0), - DeclOffsets(0), BaseDeclID(0), - LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0), - LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0), StatCache(0), - NumPreallocatedPreprocessingEntities(0) -{} - -Module::~Module() { - for (DeclContextInfosMap::iterator I = DeclContextInfos.begin(), - E = DeclContextInfos.end(); - I != E; ++I) { - if (I->second.NameLookupTableData) - delete static_cast<ASTDeclContextNameLookupTable*>( - I->second.NameLookupTableData); - } - - delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable); - delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable); - delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable); -} - -template<typename Key, typename Offset, unsigned InitialCapacity> -static void -dumpLocalRemap(StringRef Name, - const ContinuousRangeMap<Key, Offset, InitialCapacity> &Map) { - if (Map.begin() == Map.end()) - return; - - typedef ContinuousRangeMap<Key, Offset, InitialCapacity> MapType; - llvm::errs() << " " << Name << ":\n"; - for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); - I != IEnd; ++I) { - llvm::errs() << " " << I->first << " -> " << I->second - << "\n"; - } -} - -void Module::dump() { - llvm::errs() << "\nModule: " << FileName << "\n"; - if (!Imports.empty()) { - llvm::errs() << " Imports: "; - for (unsigned I = 0, N = Imports.size(); I != N; ++I) { - if (I) - llvm::errs() << ", "; - llvm::errs() << Imports[I]->FileName; - } - llvm::errs() << "\n"; - } - - // Remapping tables. - llvm::errs() << " Base source location offset: " << SLocEntryBaseOffset - << '\n'; - dumpLocalRemap("Source location offset local -> global map", SLocRemap); - - llvm::errs() << " Base identifier ID: " << BaseIdentifierID << '\n' - << " Number of identifiers: " << LocalNumIdentifiers << '\n'; - dumpLocalRemap("Identifier ID local -> global map", IdentifierRemap); - - llvm::errs() << " Base selector ID: " << BaseSelectorID << '\n' - << " Number of selectors: " << LocalNumSelectors << '\n'; - dumpLocalRemap("Selector ID local -> global map", SelectorRemap); - - llvm::errs() << " Base preprocessed entity ID: " << BasePreprocessedEntityID - << '\n' - << " Number of preprocessed entities: " - << NumPreallocatedPreprocessingEntities << '\n'; - dumpLocalRemap("Preprocessed entity ID local -> global map", - PreprocessedEntityRemap); - - llvm::errs() << " Base macro definition ID: " << BaseMacroDefinitionID - << '\n' - << " Number of macro definitions: " << LocalNumMacroDefinitions - << '\n'; - dumpLocalRemap("Macro definition ID local -> global map", - MacroDefinitionRemap); - - llvm::errs() << " Base type index: " << BaseTypeIndex << '\n' - << " Number of types: " << LocalNumTypes << '\n'; - dumpLocalRemap("Type index local -> global map", TypeRemap); - - llvm::errs() << " Base decl ID: " << BaseDeclID << '\n' - << " Number of decls: " << LocalNumDecls << '\n'; - dumpLocalRemap("Decl ID local -> global map", DeclRemap); -} - -//===----------------------------------------------------------------------===// -// Module manager implementation |