summaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp102
1 files changed, 68 insertions, 34 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index b23c33c55188..1a0c5b58e7f6 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -128,20 +128,22 @@ namespace clang {
GlobalDeclID FirstID;
Decl *MergeWith;
mutable bool Owning;
+ bool IsKeyDecl;
Decl::Kind DeclKind;
void operator=(RedeclarableResult &) = delete;
public:
RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID,
- Decl *MergeWith, Decl::Kind DeclKind)
+ Decl *MergeWith, Decl::Kind DeclKind,
+ bool IsKeyDecl)
: Reader(Reader), FirstID(FirstID), MergeWith(MergeWith),
- Owning(true), DeclKind(DeclKind) {}
+ Owning(true), IsKeyDecl(IsKeyDecl), DeclKind(DeclKind) {}
RedeclarableResult(RedeclarableResult &&Other)
: Reader(Other.Reader), FirstID(Other.FirstID),
MergeWith(Other.MergeWith), Owning(Other.Owning),
- DeclKind(Other.DeclKind) {
+ IsKeyDecl(Other.IsKeyDecl), DeclKind(Other.DeclKind) {
Other.Owning = false;
}
@@ -156,6 +158,9 @@ namespace clang {
/// \brief Retrieve the first ID.
GlobalDeclID getFirstID() const { return FirstID; }
+ /// \brief Is this declaration the key declaration?
+ bool isKeyDecl() const { return IsKeyDecl; }
+
/// \brief Get a known declaration that this should be merged with, if
/// any.
Decl *getKnownMergeTarget() const { return MergeWith; }
@@ -348,10 +353,13 @@ namespace clang {
void mergeTemplatePattern(RedeclarableTemplateDecl *D,
RedeclarableTemplateDecl *Existing,
- DeclID DsID);
+ DeclID DsID, bool IsKeyDecl);
+
+ ObjCTypeParamList *ReadObjCTypeParamList();
// FIXME: Reorder according to DeclNodes.td?
void VisitObjCMethodDecl(ObjCMethodDecl *D);
+ void VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
void VisitObjCContainerDecl(ObjCContainerDecl *D);
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
void VisitObjCIvarDecl(ObjCIvarDecl *D);
@@ -899,18 +907,49 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs);
}
+void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
+ VisitTypedefNameDecl(D);
+ D->Variance = Record[Idx++];
+ D->Index = Record[Idx++];
+ D->VarianceLoc = ReadSourceLocation(Record, Idx);
+ D->ColonLoc = ReadSourceLocation(Record, Idx);
+}
+
void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
VisitNamedDecl(CD);
CD->setAtStartLoc(ReadSourceLocation(Record, Idx));
CD->setAtEndRange(ReadSourceRange(Record, Idx));
}
+ObjCTypeParamList *ASTDeclReader::ReadObjCTypeParamList() {
+ unsigned numParams = Record[Idx++];
+ if (numParams == 0)
+ return nullptr;
+
+ SmallVector<ObjCTypeParamDecl *, 4> typeParams;
+ typeParams.reserve(numParams);
+ for (unsigned i = 0; i != numParams; ++i) {
+ auto typeParam = ReadDeclAs<ObjCTypeParamDecl>(Record, Idx);
+ if (!typeParam)
+ return nullptr;
+
+ typeParams.push_back(typeParam);
+ }
+
+ SourceLocation lAngleLoc = ReadSourceLocation(Record, Idx);
+ SourceLocation rAngleLoc = ReadSourceLocation(Record, Idx);
+
+ return ObjCTypeParamList::create(Reader.getContext(), lAngleLoc,
+ typeParams, rAngleLoc);
+}
+
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
RedeclarableResult Redecl = VisitRedeclarable(ID);
VisitObjCContainerDecl(ID);
TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
mergeRedeclarable(ID, Redecl);
-
+
+ ID->TypeParamList = ReadObjCTypeParamList();
if (Record[Idx++]) {
// Read the definition.
ID->allocateDefinitionData();
@@ -922,8 +961,7 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
ObjCInterfaceDecl::DefinitionData &Data = ID->data();
// Read the superclass.
- Data.SuperClass = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
- Data.SuperClassLoc = ReadSourceLocation(Record, Idx);
+ Data.SuperClassTInfo = GetTypeSourceInfo(Record, Idx);
Data.EndLoc = ReadSourceLocation(Record, Idx);
Data.HasDesignatedInitializers = Record[Idx++];
@@ -1020,6 +1058,7 @@ void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
Reader.CategoriesDeserialized.insert(CD);
CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
+ CD->TypeParamList = ReadObjCTypeParamList();
unsigned NumProtoRefs = Record[Idx++];
SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
ProtoRefs.reserve(NumProtoRefs);
@@ -2139,12 +2178,16 @@ ASTDeclReader::RedeclarableResult
ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
DeclID FirstDeclID = ReadDeclID(Record, Idx);
Decl *MergeWith = nullptr;
+ bool IsKeyDecl = ThisDeclID == FirstDeclID;
// 0 indicates that this declaration was the only declaration of its entity,
// and is used for space optimization.
- if (FirstDeclID == 0)
+ if (FirstDeclID == 0) {
FirstDeclID = ThisDeclID;
- else if (unsigned N = Record[Idx++]) {
+ IsKeyDecl = true;
+ } else if (unsigned N = Record[Idx++]) {
+ IsKeyDecl = false;
+
// We have some declarations that must be before us in our redeclaration
// chain. Read them now, and remember that we ought to merge with one of
// them.
@@ -2170,7 +2213,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
// The result structure takes care to note that we need to load the
// other declaration chains for this ID.
return RedeclarableResult(Reader, FirstDeclID, MergeWith,
- static_cast<T *>(D)->getKind());
+ static_cast<T *>(D)->getKind(), IsKeyDecl);
}
/// \brief Attempts to merge the given declaration (D) with another declaration
@@ -2209,11 +2252,12 @@ template<typename T> static T assert_cast(...) {
/// declarations.
void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
RedeclarableTemplateDecl *Existing,
- DeclID DsID) {
+ DeclID DsID, bool IsKeyDecl) {
auto *DPattern = D->getTemplatedDecl();
auto *ExistingPattern = Existing->getTemplatedDecl();
RedeclarableResult Result(Reader, DPattern->getCanonicalDecl()->getGlobalID(),
- /*MergeWith*/ExistingPattern, DPattern->getKind());
+ /*MergeWith*/ExistingPattern, DPattern->getKind(),
+ IsKeyDecl);
if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
// Merge with any existing definition.
@@ -2276,11 +2320,11 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D))
mergeTemplatePattern(
DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon),
- TemplatePatternID);
+ TemplatePatternID, Redecl.isKeyDecl());
- // If this declaration was the canonical declaration, make a note of that.
- if (DCanon == D) {
- Reader.MergedDecls[ExistingCanon].push_back(Redecl.getFirstID());
+ // If this declaration is a key declaration, make a note of that.
+ if (Redecl.isKeyDecl()) {
+ Reader.KeyDecls[ExistingCanon].push_back(Redecl.getFirstID());
if (Reader.PendingDeclChainsKnown.insert(ExistingCanon).second)
Reader.PendingDeclChains.push_back(ExistingCanon);
}
@@ -3259,6 +3303,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
case DECL_EMPTY:
D = EmptyDecl::CreateDeserialized(Context, ID);
break;
+ case DECL_OBJC_TYPE_PARAM:
+ D = ObjCTypeParamDecl::CreateDeserialized(Context, ID);
+ break;
}
assert(D && "Unknown declaration reading AST file");
@@ -3418,20 +3465,9 @@ namespace {
M.RedeclarationsMap + M.LocalNumRedeclarationsInMap,
Compare);
if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap ||
- Result->FirstID != ID) {
- // If we have a previously-canonical singleton declaration that was
- // merged into another redeclaration chain, create a trivial chain
- // for this single declaration so that it will get wired into the
- // complete redeclaration chain.
- if (GlobalID != CanonID &&
- GlobalID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID &&
- GlobalID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls) {
- addToChain(Reader.GetDecl(GlobalID));
- }
-
+ Result->FirstID != ID)
return;
- }
-
+
// Dig out all of the redeclarations.
unsigned Offset = Result->Offset;
unsigned N = M.RedeclarationChains[Offset];
@@ -3472,8 +3508,6 @@ namespace {
// Visit each of the declarations.
for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I)
searchForID(M, SearchDecls[I]);
- // FIXME: If none of the SearchDecls had local IDs in this module, can
- // we avoid searching any ancestor module files?
return false;
}
@@ -3494,9 +3528,9 @@ void ASTReader::loadPendingDeclChain(Decl *CanonDecl) {
GlobalDeclID CanonID = CanonDecl->getGlobalID();
if (CanonID)
SearchDecls.push_back(CanonDecl->getGlobalID()); // Always first.
- MergedDeclsMap::iterator MergedPos = MergedDecls.find(CanonDecl);
- if (MergedPos != MergedDecls.end())
- SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());
+ KeyDeclsMap::iterator KeyPos = KeyDecls.find(CanonDecl);
+ if (KeyPos != KeyDecls.end())
+ SearchDecls.append(KeyPos->second.begin(), KeyPos->second.end());
// Build up the list of redeclarations.
RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);