2018-04-12 04:57:28 +08:00
|
|
|
//===- ASTReaderDecl.cpp - Decl Deserialization ---------------------------===//
|
2009-04-27 13:27:42 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2010-08-19 07:56:43 +08:00
|
|
|
// This file implements the ASTReader::ReadDeclRecord method, which is the
|
2009-04-27 13:27:42 +08:00
|
|
|
// entrypoint for loading a decl.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-10-25 01:26:36 +08:00
|
|
|
#include "ASTCommon.h"
|
2012-04-15 20:36:49 +08:00
|
|
|
#include "ASTReaderInternals.h"
|
2009-04-27 13:27:42 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2018-04-12 04:57:28 +08:00
|
|
|
#include "clang/AST/Attr.h"
|
|
|
|
#include "clang/AST/AttrIterator.h"
|
|
|
|
#include "clang/AST/Decl.h"
|
|
|
|
#include "clang/AST/DeclBase.h"
|
2010-05-08 05:43:38 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2018-04-12 04:57:28 +08:00
|
|
|
#include "clang/AST/DeclFriend.h"
|
|
|
|
#include "clang/AST/DeclObjC.h"
|
|
|
|
#include "clang/AST/DeclOpenMP.h"
|
2010-05-08 05:43:38 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/AST/DeclVisitor.h"
|
2018-04-12 04:57:28 +08:00
|
|
|
#include "clang/AST/DeclarationName.h"
|
2009-04-27 13:27:42 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2018-04-12 04:57:28 +08:00
|
|
|
#include "clang/AST/ExternalASTSource.h"
|
|
|
|
#include "clang/AST/LambdaCapture.h"
|
|
|
|
#include "clang/AST/NestedNameSpecifier.h"
|
2018-09-26 12:28:39 +08:00
|
|
|
#include "clang/AST/OpenMPClause.h"
|
2018-04-12 04:57:28 +08:00
|
|
|
#include "clang/AST/Redeclarable.h"
|
|
|
|
#include "clang/AST/Stmt.h"
|
|
|
|
#include "clang/AST/TemplateBase.h"
|
|
|
|
#include "clang/AST/Type.h"
|
|
|
|
#include "clang/AST/UnresolvedSet.h"
|
|
|
|
#include "clang/Basic/AttrKinds.h"
|
|
|
|
#include "clang/Basic/ExceptionSpecificationType.h"
|
|
|
|
#include "clang/Basic/IdentifierTable.h"
|
|
|
|
#include "clang/Basic/LLVM.h"
|
|
|
|
#include "clang/Basic/Lambda.h"
|
|
|
|
#include "clang/Basic/LangOptions.h"
|
|
|
|
#include "clang/Basic/Linkage.h"
|
|
|
|
#include "clang/Basic/Module.h"
|
|
|
|
#include "clang/Basic/PragmaKinds.h"
|
|
|
|
#include "clang/Basic/SourceLocation.h"
|
|
|
|
#include "clang/Basic/Specifiers.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Sema/IdentifierResolver.h"
|
|
|
|
#include "clang/Sema/SemaDiagnostic.h"
|
2018-04-12 04:57:28 +08:00
|
|
|
#include "clang/Serialization/ASTBitCodes.h"
|
2016-07-19 03:02:11 +08:00
|
|
|
#include "clang/Serialization/ASTReader.h"
|
2018-04-12 04:57:28 +08:00
|
|
|
#include "clang/Serialization/ContinuousRangeMap.h"
|
|
|
|
#include "clang/Serialization/Module.h"
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
#include "llvm/ADT/FoldingSet.h"
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
#include "llvm/ADT/iterator_range.h"
|
|
|
|
#include "llvm/Bitcode/BitstreamReader.h"
|
|
|
|
#include "llvm/Support/Casting.h"
|
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2012-05-04 09:49:36 +08:00
|
|
|
#include "llvm/Support/SaveAndRestore.h"
|
2018-04-12 04:57:28 +08:00
|
|
|
#include <algorithm>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <cstring>
|
|
|
|
#include <string>
|
|
|
|
#include <utility>
|
2015-10-07 07:40:43 +08:00
|
|
|
|
2009-04-27 13:27:42 +08:00
|
|
|
using namespace clang;
|
2018-04-12 04:57:28 +08:00
|
|
|
using namespace serialization;
|
2009-04-27 13:27:42 +08:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Declaration deserialization
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-30 06:47:00 +08:00
|
|
|
namespace clang {
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {
|
2010-08-19 07:56:43 +08:00
|
|
|
ASTReader &Reader;
|
2016-12-21 08:17:49 +08:00
|
|
|
ASTRecordReader &Record;
|
2016-12-16 04:53:26 +08:00
|
|
|
ASTReader::RecordLocation Loc;
|
2010-08-19 07:57:32 +08:00
|
|
|
const DeclID ThisDeclID;
|
2016-03-27 15:28:06 +08:00
|
|
|
const SourceLocation ThisDeclLoc;
|
2018-04-12 04:57:28 +08:00
|
|
|
|
|
|
|
using RecordData = ASTReader::RecordData;
|
|
|
|
|
2018-07-04 10:25:38 +08:00
|
|
|
TypeID DeferredTypeID = 0;
|
2014-08-28 09:33:39 +08:00
|
|
|
unsigned AnonymousDeclNumber;
|
2018-04-12 04:57:28 +08:00
|
|
|
GlobalDeclID NamedDeclForTagDecl = 0;
|
|
|
|
IdentifierInfo *TypedefNameForLinkage = nullptr;
|
2016-02-26 18:43:34 +08:00
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
bool HasPendingBody = false;
|
2017-10-11 15:47:54 +08:00
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
///A flag to carry the information for a decl from the entity is
|
2016-04-28 22:13:28 +08:00
|
|
|
/// used. We use it to delay the marking of the canonical decl as used until
|
|
|
|
/// the entire declaration is deserialized and merged.
|
2018-04-12 04:57:28 +08:00
|
|
|
bool IsDeclMarkedUsed = false;
|
2016-04-28 22:13:28 +08:00
|
|
|
|
2010-07-23 06:43:28 +08:00
|
|
|
uint64_t GetCurrentCursorOffset();
|
2016-02-26 18:43:34 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
uint64_t ReadLocalOffset() {
|
2016-12-21 08:17:49 +08:00
|
|
|
uint64_t LocalOffset = Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
assert(LocalOffset < Loc.Offset && "offset point after current record");
|
|
|
|
return LocalOffset ? Loc.Offset - LocalOffset : 0;
|
2016-03-25 09:17:43 +08:00
|
|
|
}
|
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
uint64_t ReadGlobalOffset() {
|
|
|
|
uint64_t Local = ReadLocalOffset();
|
|
|
|
return Local ? Record.getGlobalBitOffset(Local) : 0;
|
2016-04-14 05:57:08 +08:00
|
|
|
}
|
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation ReadSourceLocation() {
|
2016-12-21 12:34:52 +08:00
|
|
|
return Record.readSourceLocation();
|
2010-10-05 23:59:54 +08:00
|
|
|
}
|
2016-02-26 18:43:34 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceRange ReadSourceRange() {
|
2016-12-21 12:34:52 +08:00
|
|
|
return Record.readSourceRange();
|
2010-10-05 23:59:54 +08:00
|
|
|
}
|
2016-02-26 18:43:34 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
TypeSourceInfo *GetTypeSourceInfo() {
|
2016-12-21 12:34:52 +08:00
|
|
|
return Record.getTypeSourceInfo();
|
2010-10-05 23:59:54 +08:00
|
|
|
}
|
2016-02-26 18:43:34 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
serialization::DeclID ReadDeclID() {
|
2016-12-21 12:34:52 +08:00
|
|
|
return Record.readDeclID();
|
2011-07-22 06:35:25 +08:00
|
|
|
}
|
2015-02-27 08:25:58 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
std::string ReadString() {
|
2016-12-21 12:34:52 +08:00
|
|
|
return Record.readString();
|
2016-03-03 01:28:48 +08:00
|
|
|
}
|
|
|
|
|
2015-02-27 08:25:58 +08:00
|
|
|
void ReadDeclIDList(SmallVectorImpl<DeclID> &IDs) {
|
2016-12-21 08:17:49 +08:00
|
|
|
for (unsigned I = 0, Size = Record.readInt(); I != Size; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
IDs.push_back(ReadDeclID());
|
2015-02-27 08:25:58 +08:00
|
|
|
}
|
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
Decl *ReadDecl() {
|
2016-12-21 12:34:52 +08:00
|
|
|
return Record.readDecl();
|
2011-07-22 06:35:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
2016-12-16 04:53:26 +08:00
|
|
|
T *ReadDeclAs() {
|
2016-12-21 12:34:52 +08:00
|
|
|
return Record.readDeclAs<T>();
|
2011-07-22 06:35:25 +08:00
|
|
|
}
|
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
void ReadQualifierInfo(QualifierInfo &Info) {
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readQualifierInfo(Info);
|
2010-10-16 02:21:24 +08:00
|
|
|
}
|
2016-12-16 04:53:26 +08:00
|
|
|
|
|
|
|
void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name) {
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readDeclarationNameLoc(DNLoc, Name);
|
2010-10-16 02:21:24 +08:00
|
|
|
}
|
2010-07-23 06:43:28 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
serialization::SubmoduleID readSubmoduleID() {
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.getIdx() == Record.size())
|
2011-12-02 06:20:10 +08:00
|
|
|
return 0;
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
return Record.getGlobalSubmoduleID(Record.readInt());
|
2011-12-02 06:20:10 +08:00
|
|
|
}
|
2016-12-16 04:53:26 +08:00
|
|
|
|
|
|
|
Module *readModule() {
|
|
|
|
return Record.getSubmodule(readSubmoduleID());
|
2011-12-03 07:23:56 +08:00
|
|
|
}
|
2014-04-19 11:48:30 +08:00
|
|
|
|
2015-02-03 11:32:14 +08:00
|
|
|
void ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update);
|
2017-04-12 05:13:37 +08:00
|
|
|
void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data,
|
|
|
|
const CXXRecordDecl *D);
|
2014-04-19 11:48:30 +08:00
|
|
|
void MergeDefinitionData(CXXRecordDecl *D,
|
2015-01-24 09:07:20 +08:00
|
|
|
struct CXXRecordDecl::DefinitionData &&NewDD);
|
2016-12-21 08:17:49 +08:00
|
|
|
void ReadObjCDefinitionData(struct ObjCInterfaceDecl::DefinitionData &Data);
|
2016-09-10 07:48:27 +08:00
|
|
|
void MergeDefinitionData(ObjCInterfaceDecl *D,
|
|
|
|
struct ObjCInterfaceDecl::DefinitionData &&NewDD);
|
[ASTReader] Treat multiple defns of ObjC protocols the same as interfaces.
Summary:
In change 2ba19793512, the ASTReader logic for ObjC interfaces was modified to
preserve the first definition-data read, "merging" later definitions into it
rather than overwriting it (though this "merging" is, in practice, a no-op that
discards the later definition-data).
Unfortunately this change was only made to ObjC interfaces, not protocols; this
means that when (for example) loading a protocol that references an interface,
if both the protocol and interface are multiply defined (as can easily happen
if the same header is read from multiple contexts), an _inconsistent_ pair of
definitions is loaded: first-read for the interface and last-read for the
protocol.
This in turn causes very subtle downstream bugs in the Swift ClangImporter,
which filters the results of name lookups based on the owning module of a
definition; inconsistency between a pair of related definitions causes name
lookup failures at various stages of compilation.
To fix these downstream issues, this change replicates the logic applied to
interfaces in change 2ba19793512, but for ObjC protocols.
rdar://30851899
Reviewers: doug.gregor, rsmith
Reviewed By: doug.gregor
Subscribers: jordan_rose, cfe-commits
Differential Revision: https://reviews.llvm.org/D34741
llvm-svn: 306583
2017-06-29 02:36:27 +08:00
|
|
|
void ReadObjCDefinitionData(struct ObjCProtocolDecl::DefinitionData &Data);
|
|
|
|
void MergeDefinitionData(ObjCProtocolDecl *D,
|
|
|
|
struct ObjCProtocolDecl::DefinitionData &&NewDD);
|
2010-10-25 01:26:40 +08:00
|
|
|
|
2018-07-04 10:25:38 +08:00
|
|
|
static DeclContext *getPrimaryDCForAnonymousDecl(DeclContext *LexicalDC);
|
|
|
|
|
2014-08-28 09:33:39 +08:00
|
|
|
static NamedDecl *getAnonymousDeclForMerging(ASTReader &Reader,
|
|
|
|
DeclContext *DC,
|
|
|
|
unsigned Index);
|
|
|
|
static void setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC,
|
|
|
|
unsigned Index, NamedDecl *D);
|
|
|
|
|
2015-08-22 10:09:38 +08:00
|
|
|
/// Results from loading a RedeclarableDecl.
|
2011-12-22 09:48:48 +08:00
|
|
|
class RedeclarableResult {
|
2015-02-06 10:42:59 +08:00
|
|
|
Decl *MergeWith;
|
2016-09-24 12:21:53 +08:00
|
|
|
GlobalDeclID FirstID;
|
2015-07-13 07:43:21 +08:00
|
|
|
bool IsKeyDecl;
|
2015-02-25 09:11:29 +08:00
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
public:
|
2016-09-24 12:21:53 +08:00
|
|
|
RedeclarableResult(Decl *MergeWith, GlobalDeclID FirstID, bool IsKeyDecl)
|
2018-04-12 04:57:28 +08:00
|
|
|
: MergeWith(MergeWith), FirstID(FirstID), IsKeyDecl(IsKeyDecl) {}
|
2015-07-27 13:40:23 +08:00
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Retrieve the first ID.
|
2011-12-22 09:48:48 +08:00
|
|
|
GlobalDeclID getFirstID() const { return FirstID; }
|
2015-02-06 10:42:59 +08:00
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Is this declaration a key declaration?
|
2015-07-13 07:43:21 +08:00
|
|
|
bool isKeyDecl() const { return IsKeyDecl; }
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Get a known declaration that this should be merged with, if
|
2015-02-06 10:42:59 +08:00
|
|
|
/// any.
|
|
|
|
Decl *getKnownMergeTarget() const { return MergeWith; }
|
2011-12-22 09:48:48 +08:00
|
|
|
};
|
2013-01-22 00:16:40 +08:00
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Class used to capture the result of searching for an existing
|
2011-12-22 09:48:48 +08:00
|
|
|
/// declaration of a specific kind and name, along with the ability
|
|
|
|
/// to update the place where this result was found (the declaration
|
|
|
|
/// chain hanging off an identifier or the DeclContext we searched in)
|
|
|
|
/// if requested.
|
|
|
|
class FindExistingResult {
|
|
|
|
ASTReader &Reader;
|
2018-04-12 04:57:28 +08:00
|
|
|
NamedDecl *New = nullptr;
|
|
|
|
NamedDecl *Existing = nullptr;
|
|
|
|
bool AddResult = false;
|
|
|
|
unsigned AnonymousDeclNumber = 0;
|
|
|
|
IdentifierInfo *TypedefNameForLinkage = nullptr;
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
public:
|
2018-04-12 04:57:28 +08:00
|
|
|
FindExistingResult(ASTReader &Reader) : Reader(Reader) {}
|
2014-08-28 09:33:39 +08:00
|
|
|
|
|
|
|
FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing,
|
2014-08-30 08:04:23 +08:00
|
|
|
unsigned AnonymousDeclNumber,
|
|
|
|
IdentifierInfo *TypedefNameForLinkage)
|
2014-08-28 09:33:39 +08:00
|
|
|
: Reader(Reader), New(New), Existing(Existing), AddResult(true),
|
2014-08-30 08:04:23 +08:00
|
|
|
AnonymousDeclNumber(AnonymousDeclNumber),
|
|
|
|
TypedefNameForLinkage(TypedefNameForLinkage) {}
|
2014-05-22 13:54:18 +08:00
|
|
|
|
2016-08-06 20:45:16 +08:00
|
|
|
FindExistingResult(FindExistingResult &&Other)
|
2014-08-28 09:33:39 +08:00
|
|
|
: Reader(Other.Reader), New(Other.New), Existing(Other.Existing),
|
|
|
|
AddResult(Other.AddResult),
|
2014-08-30 08:04:23 +08:00
|
|
|
AnonymousDeclNumber(Other.AnonymousDeclNumber),
|
|
|
|
TypedefNameForLinkage(Other.TypedefNameForLinkage) {
|
2011-12-22 09:48:48 +08:00
|
|
|
Other.AddResult = false;
|
|
|
|
}
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
FindExistingResult &operator=(FindExistingResult &&) = delete;
|
2011-12-22 09:48:48 +08:00
|
|
|
~FindExistingResult();
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Suppress the addition of this result into the known set of
|
2012-01-04 06:46:00 +08:00
|
|
|
/// names.
|
|
|
|
void suppress() { AddResult = false; }
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
operator NamedDecl*() const { return Existing; }
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
template<typename T>
|
|
|
|
operator T*() const { return dyn_cast_or_null<T>(Existing); }
|
|
|
|
};
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2015-01-24 09:07:20 +08:00
|
|
|
static DeclContext *getPrimaryContextForMerging(ASTReader &Reader,
|
|
|
|
DeclContext *DC);
|
2011-12-22 09:48:48 +08:00
|
|
|
FindExistingResult findExisting(NamedDecl *D);
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2009-04-27 13:27:42 +08:00
|
|
|
public:
|
2016-12-21 08:17:49 +08:00
|
|
|
ASTDeclReader(ASTReader &Reader, ASTRecordReader &Record,
|
|
|
|
ASTReader::RecordLocation Loc,
|
|
|
|
DeclID thisDeclID, SourceLocation ThisDeclLoc)
|
2018-04-12 04:57:28 +08:00
|
|
|
: Reader(Reader), Record(Record), Loc(Loc), ThisDeclID(thisDeclID),
|
|
|
|
ThisDeclLoc(ThisDeclLoc) {}
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2017-07-01 06:40:17 +08:00
|
|
|
template <typename T> static
|
|
|
|
void AddLazySpecializations(T *D,
|
|
|
|
SmallVectorImpl<serialization::DeclID>& IDs) {
|
|
|
|
if (IDs.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// FIXME: We should avoid this pattern of getting the ASTContext.
|
|
|
|
ASTContext &C = D->getASTContext();
|
|
|
|
|
|
|
|
auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations;
|
|
|
|
|
|
|
|
if (auto &Old = LazySpecializations) {
|
|
|
|
IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
|
2018-09-27 06:16:28 +08:00
|
|
|
llvm::sort(IDs);
|
2017-07-01 06:40:17 +08:00
|
|
|
IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
auto *Result = new (C) serialization::DeclID[1 + IDs.size()];
|
|
|
|
*Result = IDs.size();
|
|
|
|
std::copy(IDs.begin(), IDs.end(), Result + 1);
|
|
|
|
|
|
|
|
LazySpecializations = Result;
|
|
|
|
}
|
|
|
|
|
2015-02-28 13:57:02 +08:00
|
|
|
template <typename DeclT>
|
|
|
|
static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
|
|
|
|
static Decl *getMostRecentDeclImpl(...);
|
|
|
|
static Decl *getMostRecentDecl(Decl *D);
|
|
|
|
|
2014-05-13 09:15:00 +08:00
|
|
|
template <typename DeclT>
|
2014-08-01 07:46:44 +08:00
|
|
|
static void attachPreviousDeclImpl(ASTReader &Reader,
|
2015-03-23 11:25:59 +08:00
|
|
|
Redeclarable<DeclT> *D, Decl *Previous,
|
|
|
|
Decl *Canon);
|
2014-08-01 07:46:44 +08:00
|
|
|
static void attachPreviousDeclImpl(ASTReader &Reader, ...);
|
2015-03-23 11:25:59 +08:00
|
|
|
static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous,
|
|
|
|
Decl *Canon);
|
2014-05-13 09:15:00 +08:00
|
|
|
|
|
|
|
template <typename DeclT>
|
|
|
|
static void attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest);
|
|
|
|
static void attachLatestDeclImpl(...);
|
Completely re-implement (de-)serialization of declaration
chains. The previous implementation relied heavily on the declaration
chain being stored as a (circular) linked list on disk, as it is in
memory. However, when deserializing from multiple modules, the
different chains could get mixed up, leading to broken declaration chains.
The new solution keeps track of the first and last declarations in the
chain for each module file. When we load a declaration, we search all
of the module files for redeclarations of that declaration, then
splice together all of the lists into a coherent whole (along with any
redeclarations that were actually parsed).
As a drive-by fix, (de-)serialize the redeclaration chains of
TypedefNameDecls, which had somehow gotten missed previously. Add a
test of this serialization.
This new scheme creates a redeclaration table that is fairly large in
the PCH file (on the order of 400k for Cocoa.h's 12MB PCH file). The
table is mmap'd in and searched via a binary search, but it's still
quite large. A future tweak will eliminate entries for declarations
that have no redeclarations anywhere, and should
drastically reduce the size of this table.
llvm-svn: 146841
2011-12-18 07:38:30 +08:00
|
|
|
static void attachLatestDecl(Decl *D, Decl *latest);
|
2011-02-12 15:50:47 +08:00
|
|
|
|
2014-05-20 04:59:20 +08:00
|
|
|
template <typename DeclT>
|
|
|
|
static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D);
|
|
|
|
static void markIncompleteDeclChainImpl(...);
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Determine whether this declaration has a pending body.
|
2017-10-11 15:47:54 +08:00
|
|
|
bool hasPendingBody() const { return HasPendingBody; }
|
|
|
|
|
2017-02-13 02:45:31 +08:00
|
|
|
void ReadFunctionDefinition(FunctionDecl *FD);
|
2010-07-02 19:55:01 +08:00
|
|
|
void Visit(Decl *D);
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
void UpdateDecl(Decl *D, SmallVectorImpl<serialization::DeclID> &);
|
2010-10-25 01:26:36 +08:00
|
|
|
|
2011-09-01 08:58:55 +08:00
|
|
|
static void setNextObjCCategory(ObjCCategoryDecl *Cat,
|
|
|
|
ObjCCategoryDecl *Next) {
|
|
|
|
Cat->NextClassCategory = Next;
|
|
|
|
}
|
|
|
|
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitDecl(Decl *D);
|
2016-03-03 01:28:48 +08:00
|
|
|
void VisitPragmaCommentDecl(PragmaCommentDecl *D);
|
2016-03-03 03:28:54 +08:00
|
|
|
void VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
|
|
|
|
void VisitNamedDecl(NamedDecl *ND);
|
2011-02-17 15:39:24 +08:00
|
|
|
void VisitLabelDecl(LabelDecl *LD);
|
2010-02-22 02:22:14 +08:00
|
|
|
void VisitNamespaceDecl(NamespaceDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
|
|
|
|
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitTypeDecl(TypeDecl *TD);
|
2014-08-26 11:52:16 +08:00
|
|
|
RedeclarableResult VisitTypedefNameDecl(TypedefNameDecl *TD);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitTypedefDecl(TypedefDecl *TD);
|
2011-04-15 22:24:37 +08:00
|
|
|
void VisitTypeAliasDecl(TypeAliasDecl *TD);
|
2010-06-30 16:49:30 +08:00
|
|
|
void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
|
2013-05-23 09:49:11 +08:00
|
|
|
RedeclarableResult VisitTagDecl(TagDecl *TD);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitEnumDecl(EnumDecl *ED);
|
2013-05-23 09:49:11 +08:00
|
|
|
RedeclarableResult VisitRecordDeclImpl(RecordDecl *RD);
|
|
|
|
void VisitRecordDecl(RecordDecl *RD) { VisitRecordDeclImpl(RD); }
|
|
|
|
RedeclarableResult VisitCXXRecordDeclImpl(CXXRecordDecl *D);
|
|
|
|
void VisitCXXRecordDecl(CXXRecordDecl *D) { VisitCXXRecordDeclImpl(D); }
|
|
|
|
RedeclarableResult VisitClassTemplateSpecializationDeclImpl(
|
2010-05-08 05:43:38 +08:00
|
|
|
ClassTemplateSpecializationDecl *D);
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2013-05-23 09:49:11 +08:00
|
|
|
void VisitClassTemplateSpecializationDecl(
|
|
|
|
ClassTemplateSpecializationDecl *D) {
|
|
|
|
VisitClassTemplateSpecializationDeclImpl(D);
|
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitClassTemplatePartialSpecializationDecl(
|
|
|
|
ClassTemplatePartialSpecializationDecl *D);
|
2011-08-31 21:59:56 +08:00
|
|
|
void VisitClassScopeFunctionSpecializationDecl(
|
|
|
|
ClassScopeFunctionSpecializationDecl *D);
|
2013-08-06 09:03:05 +08:00
|
|
|
RedeclarableResult
|
|
|
|
VisitVarTemplateSpecializationDeclImpl(VarTemplateSpecializationDecl *D);
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2013-08-06 09:03:05 +08:00
|
|
|
void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) {
|
|
|
|
VisitVarTemplateSpecializationDeclImpl(D);
|
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2013-08-06 09:03:05 +08:00
|
|
|
void VisitVarTemplatePartialSpecializationDecl(
|
|
|
|
VarTemplatePartialSpecializationDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitValueDecl(ValueDecl *VD);
|
|
|
|
void VisitEnumConstantDecl(EnumConstantDecl *ECD);
|
2010-06-30 16:49:30 +08:00
|
|
|
void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
|
2009-08-19 09:28:35 +08:00
|
|
|
void VisitDeclaratorDecl(DeclaratorDecl *DD);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitFunctionDecl(FunctionDecl *FD);
|
2017-02-18 04:05:37 +08:00
|
|
|
void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *GD);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitCXXMethodDecl(CXXMethodDecl *D);
|
|
|
|
void VisitCXXConstructorDecl(CXXConstructorDecl *D);
|
|
|
|
void VisitCXXDestructorDecl(CXXDestructorDecl *D);
|
|
|
|
void VisitCXXConversionDecl(CXXConversionDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitFieldDecl(FieldDecl *FD);
|
2013-04-16 15:28:30 +08:00
|
|
|
void VisitMSPropertyDecl(MSPropertyDecl *FD);
|
2010-11-21 14:08:52 +08:00
|
|
|
void VisitIndirectFieldDecl(IndirectFieldDecl *FD);
|
2013-08-06 09:03:05 +08:00
|
|
|
RedeclarableResult VisitVarDeclImpl(VarDecl *D);
|
|
|
|
void VisitVarDecl(VarDecl *VD) { VisitVarDeclImpl(VD); }
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitImplicitParamDecl(ImplicitParamDecl *PD);
|
|
|
|
void VisitParmVarDecl(ParmVarDecl *PD);
|
2016-08-12 10:21:25 +08:00
|
|
|
void VisitDecompositionDecl(DecompositionDecl *DD);
|
|
|
|
void VisitBindingDecl(BindingDecl *BD);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
|
2014-04-24 10:25:27 +08:00
|
|
|
DeclID VisitTemplateDecl(TemplateDecl *D);
|
2012-01-07 06:05:37 +08:00
|
|
|
RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitClassTemplateDecl(ClassTemplateDecl *D);
|
2015-11-04 11:40:30 +08:00
|
|
|
void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D);
|
2013-08-06 09:03:05 +08:00
|
|
|
void VisitVarTemplateDecl(VarTemplateDecl *D);
|
2010-06-22 17:55:07 +08:00
|
|
|
void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
|
2011-05-06 05:57:07 +08:00
|
|
|
void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
|
2010-06-20 22:40:59 +08:00
|
|
|
void VisitUsingDecl(UsingDecl *D);
|
2016-12-21 05:35:28 +08:00
|
|
|
void VisitUsingPackDecl(UsingPackDecl *D);
|
2010-06-20 22:40:59 +08:00
|
|
|
void VisitUsingShadowDecl(UsingShadowDecl *D);
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
|
2016-09-09 07:14:54 +08:00
|
|
|
void VisitExportDecl(ExportDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
|
2011-12-03 07:23:56 +08:00
|
|
|
void VisitImportDecl(ImportDecl *D);
|
2010-06-05 13:09:32 +08:00
|
|
|
void VisitAccessSpecDecl(AccessSpecDecl *D);
|
2010-06-30 06:47:00 +08:00
|
|
|
void VisitFriendDecl(FriendDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
|
|
|
|
void VisitStaticAssertDecl(StaticAssertDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitBlockDecl(BlockDecl *BD);
|
2013-04-17 03:37:38 +08:00
|
|
|
void VisitCapturedDecl(CapturedDecl *CD);
|
2013-02-23 01:15:32 +08:00
|
|
|
void VisitEmptyDecl(EmptyDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
|
2009-04-27 13:27:42 +08:00
|
|
|
std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
|
2014-04-24 10:25:27 +08:00
|
|
|
|
|
|
|
template<typename T>
|
2011-12-22 09:48:48 +08:00
|
|
|
RedeclarableResult VisitRedeclarable(Redeclarable<T> *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
|
2012-01-04 01:27:13 +08:00
|
|
|
template<typename T>
|
2014-04-24 10:25:27 +08:00
|
|
|
void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl,
|
|
|
|
DeclID TemplatePatternID = 0);
|
2013-09-10 00:55:27 +08:00
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
void mergeRedeclarable(Redeclarable<T> *D, T *Existing,
|
2014-04-24 10:25:27 +08:00
|
|
|
RedeclarableResult &Redecl,
|
|
|
|
DeclID TemplatePatternID = 0);
|
2013-09-10 00:55:27 +08:00
|
|
|
|
2013-10-07 16:02:11 +08:00
|
|
|
template<typename T>
|
|
|
|
void mergeMergeable(Mergeable<T> *D);
|
|
|
|
|
2014-04-24 10:25:27 +08:00
|
|
|
void mergeTemplatePattern(RedeclarableTemplateDecl *D,
|
|
|
|
RedeclarableTemplateDecl *Existing,
|
2015-07-13 07:43:21 +08:00
|
|
|
DeclID DsID, bool IsKeyDecl);
|
2014-04-24 10:25:27 +08:00
|
|
|
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
ObjCTypeParamList *ReadObjCTypeParamList();
|
|
|
|
|
2010-05-30 15:21:58 +08:00
|
|
|
// FIXME: Reorder according to DeclNodes.td?
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitObjCMethodDecl(ObjCMethodDecl *D);
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
void VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitObjCContainerDecl(ObjCContainerDecl *D);
|
|
|
|
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
|
|
|
|
void VisitObjCIvarDecl(ObjCIvarDecl *D);
|
|
|
|
void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
|
|
|
|
void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
|
|
|
|
void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
|
|
|
|
void VisitObjCImplDecl(ObjCImplDecl *D);
|
|
|
|
void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
|
|
|
|
void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
|
|
|
|
void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
|
|
|
|
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
|
|
|
|
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
|
2013-03-22 14:34:35 +08:00
|
|
|
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
|
2016-03-03 13:21:39 +08:00
|
|
|
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
|
2018-09-26 12:28:39 +08:00
|
|
|
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
|
2016-02-11 13:35:55 +08:00
|
|
|
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
};
|
2018-04-12 04:57:28 +08:00
|
|
|
|
|
|
|
} // namespace clang
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2015-06-19 06:07:00 +08:00
|
|
|
namespace {
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2015-06-19 06:07:00 +08:00
|
|
|
/// Iterator over the redeclarations of a declaration that have already
|
|
|
|
/// been merged into the same redeclaration chain.
|
|
|
|
template<typename DeclT>
|
|
|
|
class MergedRedeclIterator {
|
2018-04-12 04:57:28 +08:00
|
|
|
DeclT *Start;
|
|
|
|
DeclT *Canonical = nullptr;
|
|
|
|
DeclT *Current = nullptr;
|
|
|
|
|
2015-06-19 06:07:00 +08:00
|
|
|
public:
|
2018-04-12 04:57:28 +08:00
|
|
|
MergedRedeclIterator() = default;
|
|
|
|
MergedRedeclIterator(DeclT *Start) : Start(Start), Current(Start) {}
|
2015-06-19 06:07:00 +08:00
|
|
|
|
|
|
|
DeclT *operator*() { return Current; }
|
|
|
|
|
|
|
|
MergedRedeclIterator &operator++() {
|
|
|
|
if (Current->isFirstDecl()) {
|
|
|
|
Canonical = Current;
|
2017-10-11 15:47:54 +08:00
|
|
|
Current = Current->getMostRecentDecl();
|
2015-06-19 06:07:00 +08:00
|
|
|
} else
|
|
|
|
Current = Current->getPreviousDecl();
|
|
|
|
|
|
|
|
// If we started in the merged portion, we'll reach our start position
|
|
|
|
// eventually. Otherwise, we'll never reach it, but the second declaration
|
|
|
|
// we reached was the canonical declaration, so stop when we see that one
|
|
|
|
// again.
|
|
|
|
if (Current == Start || Current == Canonical)
|
|
|
|
Current = nullptr;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
friend bool operator!=(const MergedRedeclIterator &A,
|
|
|
|
const MergedRedeclIterator &B) {
|
|
|
|
return A.Current != B.Current;
|
|
|
|
}
|
|
|
|
};
|
2018-04-12 04:57:28 +08:00
|
|
|
|
|
|
|
} // namespace
|
2015-10-07 07:40:43 +08:00
|
|
|
|
2016-08-06 19:21:04 +08:00
|
|
|
template <typename DeclT>
|
|
|
|
static llvm::iterator_range<MergedRedeclIterator<DeclT>>
|
|
|
|
merged_redecls(DeclT *D) {
|
2015-12-06 13:07:12 +08:00
|
|
|
return llvm::make_range(MergedRedeclIterator<DeclT>(D),
|
|
|
|
MergedRedeclIterator<DeclT>());
|
2015-06-19 06:07:00 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
uint64_t ASTDeclReader::GetCurrentCursorOffset() {
|
2016-12-16 04:53:26 +08:00
|
|
|
return Loc.F->DeclsCursor.GetCurrentBitNo() + Loc.F->GlobalBitOffset;
|
2010-07-23 06:43:28 +08:00
|
|
|
}
|
|
|
|
|
2017-02-13 02:45:31 +08:00
|
|
|
void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
|
2017-10-11 15:47:54 +08:00
|
|
|
if (Record.readInt())
|
2017-09-07 04:01:14 +08:00
|
|
|
Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
2017-02-13 02:45:31 +08:00
|
|
|
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
|
2018-08-02 05:02:40 +08:00
|
|
|
CD->setNumCtorInitializers(Record.readInt());
|
|
|
|
if (CD->getNumCtorInitializers())
|
2017-02-13 02:45:31 +08:00
|
|
|
CD->CtorInitializers = ReadGlobalOffset();
|
|
|
|
}
|
|
|
|
// Store the offset of the body so we can lazily load it later.
|
2017-10-11 15:47:54 +08:00
|
|
|
Reader.PendingBodies[FD] = GetCurrentCursorOffset();
|
|
|
|
HasPendingBody = true;
|
2017-02-13 02:45:31 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::Visit(Decl *D) {
|
|
|
|
DeclVisitor<ASTDeclReader, void>::Visit(D);
|
2010-07-02 19:55:01 +08:00
|
|
|
|
2016-04-28 22:13:28 +08:00
|
|
|
// At this point we have deserialized and merged the decl and it is safe to
|
|
|
|
// update its canonical decl to signal that the entire entity is used.
|
|
|
|
D->getCanonicalDecl()->Used |= IsDeclMarkedUsed;
|
|
|
|
IsDeclMarkedUsed = false;
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *DD = dyn_cast<DeclaratorDecl>(D)) {
|
2018-06-30 04:46:25 +08:00
|
|
|
if (auto *TInfo = DD->getTypeSourceInfo())
|
|
|
|
Record.readTypeLoc(TInfo->getTypeLoc());
|
2011-06-04 07:11:16 +08:00
|
|
|
}
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *TD = dyn_cast<TypeDecl>(D)) {
|
2014-04-24 10:25:27 +08:00
|
|
|
// We have a fully initialized TypeDecl. Read its type now.
|
2018-07-04 10:25:38 +08:00
|
|
|
TD->setTypeForDecl(Reader.GetType(DeferredTypeID).getTypePtrOrNull());
|
2014-08-30 08:04:23 +08:00
|
|
|
|
|
|
|
// If this is a tag declaration with a typedef name for linkage, it's safe
|
|
|
|
// to load that typedef now.
|
|
|
|
if (NamedDeclForTagDecl)
|
2015-09-01 02:48:39 +08:00
|
|
|
cast<TagDecl>(D)->TypedefNameDeclOrQualifier =
|
|
|
|
cast<TypedefNameDecl>(Reader.GetDecl(NamedDeclForTagDecl));
|
2018-04-12 04:57:28 +08:00
|
|
|
} else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
|
2011-12-16 11:12:41 +08:00
|
|
|
// if we have a fully initialized TypeDecl, we can safely read its type now.
|
2018-07-04 10:25:38 +08:00
|
|
|
ID->TypeForDecl = Reader.GetType(DeferredTypeID).getTypePtrOrNull();
|
2018-04-12 04:57:28 +08:00
|
|
|
} else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
|
2010-07-02 23:58:43 +08:00
|
|
|
// FunctionDecl's body was written last after all other Stmts/Exprs.
|
2012-10-04 02:34:48 +08:00
|
|
|
// We only read it if FD doesn't already have a body (e.g., from another
|
|
|
|
// module).
|
2012-10-04 02:36:10 +08:00
|
|
|
// FIXME: Can we diagnose ODR violations somehow?
|
2017-02-13 02:45:31 +08:00
|
|
|
if (Record.readInt())
|
|
|
|
ReadFunctionDefinition(FD);
|
2010-07-02 23:58:43 +08:00
|
|
|
}
|
2010-07-02 19:55:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitDecl(Decl *D) {
|
2013-12-19 10:05:20 +08:00
|
|
|
if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
|
|
|
|
isa<ParmVarDecl>(D)) {
|
2011-03-05 09:35:54 +08:00
|
|
|
// We don't want to deserialize the DeclContext of a template
|
2013-12-19 10:05:20 +08:00
|
|
|
// parameter or of a parameter of a function template immediately. These
|
|
|
|
// entities might be used in the formulation of its DeclContext (for
|
|
|
|
// example, a function parameter can be used in decltype() in trailing
|
|
|
|
// return type of the function). Use the translation unit DeclContext as a
|
|
|
|
// placeholder.
|
2016-12-16 04:53:26 +08:00
|
|
|
GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID();
|
|
|
|
GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID();
|
2015-12-12 06:41:00 +08:00
|
|
|
if (!LexicalDCIDForTemplateParmDecl)
|
|
|
|
LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl;
|
2013-02-16 08:48:59 +08:00
|
|
|
Reader.addPendingDeclContextInfo(D,
|
|
|
|
SemaDCIDForTemplateParmDecl,
|
|
|
|
LexicalDCIDForTemplateParmDecl);
|
2018-07-31 03:24:48 +08:00
|
|
|
D->setDeclContext(Reader.getContext().getTranslationUnitDecl());
|
2011-03-05 09:35:54 +08:00
|
|
|
} else {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *SemaDC = ReadDeclAs<DeclContext>();
|
|
|
|
auto *LexicalDC = ReadDeclAs<DeclContext>();
|
2015-12-12 06:41:00 +08:00
|
|
|
if (!LexicalDC)
|
|
|
|
LexicalDC = SemaDC;
|
2013-09-10 00:55:27 +08:00
|
|
|
DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC);
|
2012-02-09 15:46:54 +08:00
|
|
|
// Avoid calling setLexicalDeclContext() directly because it uses
|
|
|
|
// Decl::getASTContext() internally which is unsafe during derialization.
|
2013-09-10 00:55:27 +08:00
|
|
|
D->setDeclContextsImpl(MergedSemaDC ? MergedSemaDC : SemaDC, LexicalDC,
|
|
|
|
Reader.getContext());
|
2011-03-05 09:35:54 +08:00
|
|
|
}
|
2016-03-27 15:28:06 +08:00
|
|
|
D->setLocation(ThisDeclLoc);
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setInvalidDecl(Record.readInt());
|
|
|
|
if (Record.readInt()) { // hasAttrs
|
2010-08-19 07:23:40 +08:00
|
|
|
AttrVec Attrs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readAttributes(Attrs);
|
2012-02-09 15:46:54 +08:00
|
|
|
// Avoid calling setAttrs() directly because it uses Decl::getASTContext()
|
|
|
|
// internally which is unsafe during derialization.
|
2012-02-09 10:44:08 +08:00
|
|
|
D->setAttrsImpl(Attrs, Reader.getContext());
|
2010-08-19 07:23:40 +08:00
|
|
|
}
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setImplicit(Record.readInt());
|
|
|
|
D->Used = Record.readInt();
|
2016-04-28 22:13:28 +08:00
|
|
|
IsDeclMarkedUsed |= D->Used;
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setReferenced(Record.readInt());
|
|
|
|
D->setTopLevelDeclInObjCContainer(Record.readInt());
|
|
|
|
D->setAccess((AccessSpecifier)Record.readInt());
|
2011-09-10 08:09:20 +08:00
|
|
|
D->FromASTFile = true;
|
2017-06-23 09:04:34 +08:00
|
|
|
bool ModulePrivate = Record.readInt();
|
2015-05-16 04:05:43 +08:00
|
|
|
|
2011-12-02 06:20:10 +08:00
|
|
|
// Determine whether this declaration is part of a (sub)module. If so, it
|
|
|
|
// may not yet be visible.
|
2016-12-16 04:53:26 +08:00
|
|
|
if (unsigned SubmoduleID = readSubmoduleID()) {
|
2012-01-10 01:30:44 +08:00
|
|
|
// Store the owning submodule ID in the declaration.
|
2017-06-23 09:04:34 +08:00
|
|
|
D->setModuleOwnershipKind(
|
|
|
|
ModulePrivate ? Decl::ModuleOwnershipKind::ModulePrivate
|
|
|
|
: Decl::ModuleOwnershipKind::VisibleWhenImported);
|
2012-01-10 01:30:44 +08:00
|
|
|
D->setOwningModuleID(SubmoduleID);
|
2015-05-16 04:05:43 +08:00
|
|
|
|
2017-06-23 09:04:34 +08:00
|
|
|
if (ModulePrivate) {
|
|
|
|
// Module-private declarations are never visible, so there is no work to
|
|
|
|
// do.
|
2015-05-16 04:05:43 +08:00
|
|
|
} else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
|
|
|
|
// If local visibility is being tracked, this declaration will become
|
2017-06-23 09:04:34 +08:00
|
|
|
// hidden and visible as the owning module does.
|
2015-05-16 04:05:43 +08:00
|
|
|
} else if (Module *Owner = Reader.getSubmodule(SubmoduleID)) {
|
2017-06-23 09:04:34 +08:00
|
|
|
// Mark the declaration as visible when its owning module becomes visible.
|
|
|
|
if (Owner->NameVisibility == Module::AllVisible)
|
|
|
|
D->setVisibleDespiteOwningModule();
|
|
|
|
else
|
2015-05-16 04:05:43 +08:00
|
|
|
Reader.HiddenNamesMap[Owner].push_back(D);
|
2011-12-02 06:20:10 +08:00
|
|
|
}
|
2017-07-05 15:47:11 +08:00
|
|
|
} else if (ModulePrivate) {
|
|
|
|
D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
|
2011-12-02 06:20:10 +08:00
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2016-03-03 01:28:48 +08:00
|
|
|
void ASTDeclReader::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
|
|
|
|
VisitDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setLocation(ReadSourceLocation());
|
2016-12-21 08:17:49 +08:00
|
|
|
D->CommentKind = (PragmaMSCommentKind)Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
std::string Arg = ReadString();
|
2016-03-03 01:28:48 +08:00
|
|
|
memcpy(D->getTrailingObjects<char>(), Arg.data(), Arg.size());
|
|
|
|
D->getTrailingObjects<char>()[Arg.size()] = '\0';
|
|
|
|
}
|
|
|
|
|
2016-03-03 03:28:54 +08:00
|
|
|
void ASTDeclReader::VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D) {
|
|
|
|
VisitDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setLocation(ReadSourceLocation());
|
|
|
|
std::string Name = ReadString();
|
2016-03-03 03:28:54 +08:00
|
|
|
memcpy(D->getTrailingObjects<char>(), Name.data(), Name.size());
|
|
|
|
D->getTrailingObjects<char>()[Name.size()] = '\0';
|
|
|
|
|
|
|
|
D->ValueStart = Name.size() + 1;
|
2016-12-16 04:53:26 +08:00
|
|
|
std::string Value = ReadString();
|
2016-03-03 03:28:54 +08:00
|
|
|
memcpy(D->getTrailingObjects<char>() + D->ValueStart, Value.data(),
|
|
|
|
Value.size());
|
|
|
|
D->getTrailingObjects<char>()[D->ValueStart + Value.size()] = '\0';
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
|
2011-08-12 08:15:20 +08:00
|
|
|
llvm_unreachable("Translation units are not serialized");
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(ND);
|
2016-12-21 12:34:52 +08:00
|
|
|
ND->setDeclName(Record.readDeclarationName());
|
2016-12-21 08:17:49 +08:00
|
|
|
AnonymousDeclNumber = Record.readInt();
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(TD);
|
2016-12-16 04:53:26 +08:00
|
|
|
TD->setLocStart(ReadSourceLocation());
|
2010-07-02 19:55:01 +08:00
|
|
|
// Delay type reading until after we have fully initialized the decl.
|
2018-07-04 10:25:38 +08:00
|
|
|
DeferredTypeID = Record.getGlobalTypeID(Record.readInt());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2014-08-26 11:52:16 +08:00
|
|
|
ASTDeclReader::RedeclarableResult
|
|
|
|
ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
|
2012-01-05 00:44:10 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(TD);
|
2010-07-02 19:55:01 +08:00
|
|
|
VisitTypeDecl(TD);
|
2016-12-16 04:53:26 +08:00
|
|
|
TypeSourceInfo *TInfo = GetTypeSourceInfo();
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) { // isModed
|
|
|
|
QualType modedT = Record.readType();
|
2013-06-20 20:46:19 +08:00
|
|
|
TD->setModedTypeSourceInfo(TInfo, modedT);
|
|
|
|
} else
|
|
|
|
TD->setTypeSourceInfo(TInfo);
|
2017-01-27 06:39:55 +08:00
|
|
|
// Read and discard the declaration for which this is a typedef name for
|
|
|
|
// linkage, if it exists. We cannot rely on our type to pull in this decl,
|
|
|
|
// because it might have been merged with a type from another module and
|
|
|
|
// thus might not refer to our version of the declaration.
|
|
|
|
ReadDecl();
|
2014-08-26 11:52:16 +08:00
|
|
|
return Redecl;
|
2011-12-19 22:40:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
|
2014-08-26 11:52:16 +08:00
|
|
|
RedeclarableResult Redecl = VisitTypedefNameDecl(TD);
|
|
|
|
mergeRedeclarable(TD, Redecl);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 22:24:37 +08:00
|
|
|
void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) {
|
2014-08-26 11:52:16 +08:00
|
|
|
RedeclarableResult Redecl = VisitTypedefNameDecl(TD);
|
2016-12-16 04:53:26 +08:00
|
|
|
if (auto *Template = ReadDeclAs<TypeAliasTemplateDecl>())
|
2014-08-26 11:52:16 +08:00
|
|
|
// Merged when we merge the template.
|
|
|
|
TD->setDescribedAliasTemplate(Template);
|
|
|
|
else
|
|
|
|
mergeRedeclarable(TD, Redecl);
|
2011-04-15 22:24:37 +08:00
|
|
|
}
|
|
|
|
|
2013-05-23 09:49:11 +08:00
|
|
|
ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) {
|
2012-01-04 06:46:00 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(TD);
|
2011-10-27 01:53:41 +08:00
|
|
|
VisitTypeDecl(TD);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
TD->IdentifierNamespace = Record.readInt();
|
|
|
|
TD->setTagKind((TagDecl::TagKind)Record.readInt());
|
2014-08-28 07:11:59 +08:00
|
|
|
if (!isa<CXXRecordDecl>(TD))
|
2016-12-21 08:17:49 +08:00
|
|
|
TD->setCompleteDefinition(Record.readInt());
|
|
|
|
TD->setEmbeddedInDeclarator(Record.readInt());
|
|
|
|
TD->setFreeStanding(Record.readInt());
|
|
|
|
TD->setCompleteDefinitionRequired(Record.readInt());
|
2016-12-16 04:53:26 +08:00
|
|
|
TD->setBraceRange(ReadSourceRange());
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
switch (Record.readInt()) {
|
2014-08-30 08:04:23 +08:00
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
case 1: { // ExtInfo
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Info = new (Reader.getContext()) TagDecl::ExtInfo();
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadQualifierInfo(*Info);
|
2015-09-01 02:48:39 +08:00
|
|
|
TD->TypedefNameDeclOrQualifier = Info;
|
2014-08-30 08:04:23 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2: // TypedefNameForAnonDecl
|
2016-12-16 04:53:26 +08:00
|
|
|
NamedDeclForTagDecl = ReadDeclID();
|
2016-12-21 12:34:52 +08:00
|
|
|
TypedefNameForLinkage = Record.getIdentifierInfo();
|
2014-08-30 08:04:23 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("unexpected tag info kind");
|
|
|
|
}
|
2012-01-04 06:46:00 +08:00
|
|
|
|
2014-04-19 11:48:30 +08:00
|
|
|
if (!isa<CXXRecordDecl>(TD))
|
|
|
|
mergeRedeclarable(TD, Redecl);
|
2013-05-23 09:49:11 +08:00
|
|
|
return Redecl;
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitTagDecl(ED);
|
2016-12-16 04:53:26 +08:00
|
|
|
if (TypeSourceInfo *TI = GetTypeSourceInfo())
|
2010-10-09 07:50:27 +08:00
|
|
|
ED->setIntegerTypeSourceInfo(TI);
|
|
|
|
else
|
2016-12-21 08:17:49 +08:00
|
|
|
ED->setIntegerType(Record.readType());
|
|
|
|
ED->setPromotionType(Record.readType());
|
|
|
|
ED->setNumPositiveBits(Record.readInt());
|
|
|
|
ED->setNumNegativeBits(Record.readInt());
|
2018-08-02 04:48:16 +08:00
|
|
|
ED->setScoped(Record.readInt());
|
|
|
|
ED->setScopedUsingClassTag(Record.readInt());
|
|
|
|
ED->setFixed(Record.readInt());
|
2012-03-15 07:13:10 +08:00
|
|
|
|
2018-08-02 04:48:16 +08:00
|
|
|
ED->setHasODRHash(true);
|
2018-07-26 06:52:05 +08:00
|
|
|
ED->ODRHash = Record.readInt();
|
|
|
|
|
2013-10-16 06:02:41 +08:00
|
|
|
// If this is a definition subject to the ODR, and we already have a
|
|
|
|
// definition, merge this one into it.
|
2018-08-02 04:48:16 +08:00
|
|
|
if (ED->isCompleteDefinition() &&
|
2013-10-16 06:02:41 +08:00
|
|
|
Reader.getContext().getLangOpts().Modules &&
|
|
|
|
Reader.getContext().getLangOpts().CPlusPlus) {
|
2015-06-19 06:07:00 +08:00
|
|
|
EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
|
|
|
|
if (!OldDef) {
|
|
|
|
// This is the first time we've seen an imported definition. Look for a
|
|
|
|
// local definition before deciding that we are the first definition.
|
|
|
|
for (auto *D : merged_redecls(ED->getCanonicalDecl())) {
|
|
|
|
if (!D->isFromASTFile() && D->isCompleteDefinition()) {
|
|
|
|
OldDef = D;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (OldDef) {
|
2013-10-16 06:02:41 +08:00
|
|
|
Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
|
2018-08-02 04:48:16 +08:00
|
|
|
ED->setCompleteDefinition(false);
|
2016-09-13 05:06:40 +08:00
|
|
|
Reader.mergeDefinitionVisibility(OldDef, ED);
|
2018-07-26 06:52:05 +08:00
|
|
|
if (OldDef->getODRHash() != ED->getODRHash())
|
|
|
|
Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);
|
2013-10-16 06:02:41 +08:00
|
|
|
} else {
|
|
|
|
OldDef = ED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *InstED = ReadDeclAs<EnumDecl>()) {
|
|
|
|
auto TSK = (TemplateSpecializationKind)Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation();
|
2012-03-15 07:13:10 +08:00
|
|
|
ED->setInstantiationOfMemberEnum(Reader.getContext(), InstED, TSK);
|
|
|
|
ED->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
|
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2013-05-23 09:49:11 +08:00
|
|
|
ASTDeclReader::RedeclarableResult
|
|
|
|
ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
|
|
|
|
RedeclarableResult Redecl = VisitTagDecl(RD);
|
2016-12-21 08:17:49 +08:00
|
|
|
RD->setHasFlexibleArrayMember(Record.readInt());
|
|
|
|
RD->setAnonymousStructOrUnion(Record.readInt());
|
|
|
|
RD->setHasObjectMember(Record.readInt());
|
|
|
|
RD->setHasVolatileMember(Record.readInt());
|
2018-03-14 02:58:25 +08:00
|
|
|
RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt());
|
|
|
|
RD->setNonTrivialToPrimitiveCopy(Record.readInt());
|
|
|
|
RD->setNonTrivialToPrimitiveDestroy(Record.readInt());
|
2018-03-29 05:13:14 +08:00
|
|
|
RD->setParamDestroyedInCallee(Record.readInt());
|
2018-04-10 06:48:22 +08:00
|
|
|
RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind)Record.readInt());
|
2013-05-23 09:49:11 +08:00
|
|
|
return Redecl;
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(VD);
|
2018-07-04 10:25:38 +08:00
|
|
|
// For function declarations, defer reading the type in case the function has
|
|
|
|
// a deduced return type that references an entity declared within the
|
|
|
|
// function.
|
|
|
|
if (isa<FunctionDecl>(VD))
|
|
|
|
DeferredTypeID = Record.getGlobalTypeID(Record.readInt());
|
|
|
|
else
|
|
|
|
VD->setType(Record.readType());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitValueDecl(ECD);
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt())
|
2016-12-21 12:34:52 +08:00
|
|
|
ECD->setInitExpr(Record.readExpr());
|
|
|
|
ECD->setInitVal(Record.readAPSInt());
|
2013-10-16 06:02:41 +08:00
|
|
|
mergeMergeable(ECD);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
|
2009-08-19 09:28:35 +08:00
|
|
|
VisitValueDecl(DD);
|
2016-12-16 04:53:26 +08:00
|
|
|
DD->setInnerLocStart(ReadSourceLocation());
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) { // hasExtInfo
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Info = new (Reader.getContext()) DeclaratorDecl::ExtInfo();
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadQualifierInfo(*Info);
|
2010-10-16 02:21:24 +08:00
|
|
|
DD->DeclInfo = Info;
|
2011-06-04 07:11:16 +08:00
|
|
|
}
|
2018-06-30 04:46:25 +08:00
|
|
|
QualType TSIType = Record.readType();
|
|
|
|
DD->setTypeSourceInfo(
|
|
|
|
TSIType.isNull() ? nullptr
|
|
|
|
: Reader.getContext().CreateTypeSourceInfo(TSIType));
|
2009-08-19 09:28:35 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
|
Implement declaration merging for non-template functions from
different modules. This implementation is a first approximation of
what we want, using only the function type to determine
equivalence. Later, we'll want to deal with some of the more subtle
issues, including:
- C allows a prototyped declaration and a non-prototyped declaration
to be merged, which we should support
- We may want to ignore the return type when merging, then
complain if the return types differ. Or, we may want to leave it
as it us, so that we only complain if overload resolution
eventually fails.
- C++ non-static member functions need to consider cv-qualifiers
and ref-qualifiers.
- Function templates need to consider the template parameters and
return type.
- Function template specializations will have special rules.
- We can now (accidentally!) end up overloading in C, even without
the "overloadable" attribute, and will need to detect this at some
point.
The actual detection of "is this an overload?" is implemented by
Sema::IsOverload(), which will need to be moved into the AST library
for re-use here. That will be a future refactor.
llvm-svn: 147534
2012-01-05 01:13:46 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(FD);
|
2011-10-27 01:53:41 +08:00
|
|
|
VisitDeclaratorDecl(FD);
|
2010-05-08 05:43:38 +08:00
|
|
|
|
2018-07-04 10:25:38 +08:00
|
|
|
// Attach a type to this function. Use the real type if possible, but fall
|
|
|
|
// back to the type as written if it involves a deduced return type.
|
|
|
|
if (FD->getTypeSourceInfo() &&
|
|
|
|
FD->getTypeSourceInfo()->getType()->castAs<FunctionType>()
|
|
|
|
->getReturnType()->getContainedAutoType()) {
|
|
|
|
// We'll set up the real type in Visit, once we've finished loading the
|
|
|
|
// function.
|
|
|
|
FD->setType(FD->getTypeSourceInfo()->getType());
|
2018-08-03 09:00:01 +08:00
|
|
|
Reader.PendingFunctionTypes.push_back({FD, DeferredTypeID});
|
2018-07-04 10:25:38 +08:00
|
|
|
} else {
|
|
|
|
FD->setType(Reader.GetType(DeferredTypeID));
|
|
|
|
}
|
2018-08-03 09:00:01 +08:00
|
|
|
DeferredTypeID = 0;
|
2018-07-04 10:25:38 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName());
|
2016-12-21 08:17:49 +08:00
|
|
|
FD->IdentifierNamespace = Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
|
Implement declaration merging for non-template functions from
different modules. This implementation is a first approximation of
what we want, using only the function type to determine
equivalence. Later, we'll want to deal with some of the more subtle
issues, including:
- C allows a prototyped declaration and a non-prototyped declaration
to be merged, which we should support
- We may want to ignore the return type when merging, then
complain if the return types differ. Or, we may want to leave it
as it us, so that we only complain if overload resolution
eventually fails.
- C++ non-static member functions need to consider cv-qualifiers
and ref-qualifiers.
- Function templates need to consider the template parameters and
return type.
- Function template specializations will have special rules.
- We can now (accidentally!) end up overloading in C, even without
the "overloadable" attribute, and will need to detect this at some
point.
The actual detection of "is this an overload?" is implemented by
Sema::IsOverload(), which will need to be moved into the AST library
for re-use here. That will be a future refactor.
llvm-svn: 147534
2012-01-05 01:13:46 +08:00
|
|
|
// FunctionDecl's body is handled last at ASTDeclReader::Visit,
|
|
|
|
// after everything else is read.
|
2013-04-04 03:27:57 +08:00
|
|
|
|
2018-08-02 05:02:40 +08:00
|
|
|
FD->setStorageClass(static_cast<StorageClass>(Record.readInt()));
|
|
|
|
FD->setInlineSpecified(Record.readInt());
|
|
|
|
FD->setImplicitlyInline(Record.readInt());
|
|
|
|
FD->setExplicitSpecified(Record.readInt());
|
|
|
|
FD->setVirtualAsWritten(Record.readInt());
|
|
|
|
FD->setPure(Record.readInt());
|
|
|
|
FD->setHasInheritedPrototype(Record.readInt());
|
|
|
|
FD->setHasWrittenPrototype(Record.readInt());
|
|
|
|
FD->setDeletedAsWritten(Record.readInt());
|
|
|
|
FD->setTrivial(Record.readInt());
|
|
|
|
FD->setTrivialForCall(Record.readInt());
|
|
|
|
FD->setDefaulted(Record.readInt());
|
|
|
|
FD->setExplicitlyDefaulted(Record.readInt());
|
|
|
|
FD->setHasImplicitReturnZero(Record.readInt());
|
|
|
|
FD->setConstexpr(Record.readInt());
|
|
|
|
FD->setUsesSEHTry(Record.readInt());
|
|
|
|
FD->setHasSkippedBody(Record.readInt());
|
|
|
|
FD->setIsMultiVersion(Record.readInt());
|
|
|
|
FD->setLateTemplateParsed(Record.readInt());
|
|
|
|
|
|
|
|
FD->setCachedLinkage(static_cast<Linkage>(Record.readInt()));
|
2016-12-16 04:53:26 +08:00
|
|
|
FD->EndRangeLoc = ReadSourceLocation();
|
Implement declaration merging for non-template functions from
different modules. This implementation is a first approximation of
what we want, using only the function type to determine
equivalence. Later, we'll want to deal with some of the more subtle
issues, including:
- C allows a prototyped declaration and a non-prototyped declaration
to be merged, which we should support
- We may want to ignore the return type when merging, then
complain if the return types differ. Or, we may want to leave it
as it us, so that we only complain if overload resolution
eventually fails.
- C++ non-static member functions need to consider cv-qualifiers
and ref-qualifiers.
- Function templates need to consider the template parameters and
return type.
- Function template specializations will have special rules.
- We can now (accidentally!) end up overloading in C, even without
the "overloadable" attribute, and will need to detect this at some
point.
The actual detection of "is this an overload?" is implemented by
Sema::IsOverload(), which will need to be moved into the AST library
for re-use here. That will be a future refactor.
llvm-svn: 147534
2012-01-05 01:13:46 +08:00
|
|
|
|
2017-12-23 08:41:01 +08:00
|
|
|
FD->ODRHash = Record.readInt();
|
2018-08-02 05:02:40 +08:00
|
|
|
FD->setHasODRHash(true);
|
2017-12-23 08:41:01 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
switch ((FunctionDecl::TemplatedKind)Record.readInt()) {
|
2010-06-22 17:55:07 +08:00
|
|
|
case FunctionDecl::TK_NonTemplate:
|
2014-04-19 11:48:30 +08:00
|
|
|
mergeRedeclarable(FD, Redecl);
|
2010-06-22 17:55:07 +08:00
|
|
|
break;
|
|
|
|
case FunctionDecl::TK_FunctionTemplate:
|
2014-04-19 11:48:30 +08:00
|
|
|
// Merged when we merge the template.
|
2016-12-16 04:53:26 +08:00
|
|
|
FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>());
|
2010-06-22 17:55:07 +08:00
|
|
|
break;
|
|
|
|
case FunctionDecl::TK_MemberSpecialization: {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *InstFD = ReadDeclAs<FunctionDecl>();
|
|
|
|
auto TSK = (TemplateSpecializationKind)Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation();
|
2011-09-10 05:34:22 +08:00
|
|
|
FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
|
2010-06-22 17:55:07 +08:00
|
|
|
FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
|
2014-04-19 11:48:30 +08:00
|
|
|
mergeRedeclarable(FD, Redecl);
|
2010-06-22 17:55:07 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case FunctionDecl::TK_FunctionTemplateSpecialization: {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Template = ReadDeclAs<FunctionTemplateDecl>();
|
|
|
|
auto TSK = (TemplateSpecializationKind)Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2010-06-22 17:55:07 +08:00
|
|
|
// Template arguments.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
|
2015-08-09 09:05:31 +08:00
|
|
|
|
2010-06-22 17:55:07 +08:00
|
|
|
// Template args as written.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
|
2010-06-22 17:55:07 +08:00
|
|
|
SourceLocation LAngleLoc, RAngleLoc;
|
2016-12-21 08:17:49 +08:00
|
|
|
bool HasTemplateArgumentsAsWritten = Record.readInt();
|
2011-09-23 04:07:09 +08:00
|
|
|
if (HasTemplateArgumentsAsWritten) {
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumTemplateArgLocs = Record.readInt();
|
2010-07-02 19:55:40 +08:00
|
|
|
TemplArgLocs.reserve(NumTemplateArgLocs);
|
2018-04-12 04:57:28 +08:00
|
|
|
for (unsigned i = 0; i != NumTemplateArgLocs; ++i)
|
2016-12-21 12:34:52 +08:00
|
|
|
TemplArgLocs.push_back(Record.readTemplateArgumentLoc());
|
2016-12-16 04:53:26 +08:00
|
|
|
|
|
|
|
LAngleLoc = ReadSourceLocation();
|
|
|
|
RAngleLoc = ReadSourceLocation();
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
2016-12-16 04:53:26 +08:00
|
|
|
|
|
|
|
SourceLocation POI = ReadSourceLocation();
|
2010-06-22 17:55:07 +08:00
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
ASTContext &C = Reader.getContext();
|
2010-09-09 19:28:23 +08:00
|
|
|
TemplateArgumentList *TemplArgList
|
2016-07-04 05:17:51 +08:00
|
|
|
= TemplateArgumentList::CreateCopy(C, TemplArgs);
|
2011-09-23 04:07:09 +08:00
|
|
|
TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
|
2018-04-12 04:57:28 +08:00
|
|
|
for (unsigned i = 0, e = TemplArgLocs.size(); i != e; ++i)
|
2011-09-23 04:07:09 +08:00
|
|
|
TemplArgsInfo.addArgument(TemplArgLocs[i]);
|
2010-09-09 19:28:23 +08:00
|
|
|
FunctionTemplateSpecializationInfo *FTInfo
|
|
|
|
= FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK,
|
|
|
|
TemplArgList,
|
2014-05-22 13:54:18 +08:00
|
|
|
HasTemplateArgumentsAsWritten ? &TemplArgsInfo
|
|
|
|
: nullptr,
|
2011-09-23 04:07:09 +08:00
|
|
|
POI);
|
2010-09-09 19:28:23 +08:00
|
|
|
FD->TemplateOrSpecialization = FTInfo;
|
2010-09-09 03:31:22 +08:00
|
|
|
|
2010-09-09 19:28:23 +08:00
|
|
|
if (FD->isCanonicalDecl()) { // if canonical add to template's set.
|
2010-09-13 19:45:48 +08:00
|
|
|
// The template that contains the specializations set. It's not safe to
|
|
|
|
// use getCanonicalDecl on Template since it may still be initializing.
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *CanonTemplate = ReadDeclAs<FunctionTemplateDecl>();
|
2010-09-09 19:28:23 +08:00
|
|
|
// Get the InsertPos by FindNodeOrInsertPos() instead of calling
|
|
|
|
// InsertNode(FTInfo) directly to avoid the getASTContext() call in
|
|
|
|
// FunctionTemplateSpecializationInfo's Profile().
|
|
|
|
// We avoid getASTContext because a decl in the parent hierarchy may
|
|
|
|
// be initializing.
|
2010-09-09 03:31:22 +08:00
|
|
|
llvm::FoldingSetNodeID ID;
|
2014-06-26 12:58:53 +08:00
|
|
|
FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs, C);
|
2014-05-22 13:54:18 +08:00
|
|
|
void *InsertPos = nullptr;
|
2013-06-28 12:37:53 +08:00
|
|
|
FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr();
|
2015-07-02 07:19:58 +08:00
|
|
|
FunctionTemplateSpecializationInfo *ExistingInfo =
|
|
|
|
CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos);
|
2012-09-11 07:28:22 +08:00
|
|
|
if (InsertPos)
|
2013-06-28 12:37:53 +08:00
|
|
|
CommonPtr->Specializations.InsertNode(FTInfo, InsertPos);
|
|
|
|
else {
|
|
|
|
assert(Reader.getContext().getLangOpts().Modules &&
|
|
|
|
"already deserialized this template specialization");
|
2015-07-02 07:19:58 +08:00
|
|
|
mergeRedeclarable(FD, ExistingInfo->Function, Redecl);
|
2013-06-28 12:37:53 +08:00
|
|
|
}
|
2010-09-09 03:31:22 +08:00
|
|
|
}
|
2010-06-28 17:31:34 +08:00
|
|
|
break;
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
|
|
|
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
|
|
|
|
// Templates.
|
|
|
|
UnresolvedSet<8> TemplDecls;
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumTemplates = Record.readInt();
|
2010-06-22 17:55:07 +08:00
|
|
|
while (NumTemplates--)
|
2016-12-16 04:53:26 +08:00
|
|
|
TemplDecls.addDecl(ReadDeclAs<NamedDecl>());
|
|
|
|
|
2010-06-22 17:55:07 +08:00
|
|
|
// Templates args.
|
|
|
|
TemplateArgumentListInfo TemplArgs;
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumArgs = Record.readInt();
|
2010-06-22 17:55:07 +08:00
|
|
|
while (NumArgs--)
|
2016-12-21 12:34:52 +08:00
|
|
|
TemplArgs.addArgument(Record.readTemplateArgumentLoc());
|
2016-12-16 04:53:26 +08:00
|
|
|
TemplArgs.setLAngleLoc(ReadSourceLocation());
|
|
|
|
TemplArgs.setRAngleLoc(ReadSourceLocation());
|
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
FD->setDependentTemplateSpecialization(Reader.getContext(),
|
2010-06-22 17:55:07 +08:00
|
|
|
TemplDecls, TemplArgs);
|
2015-07-02 07:19:58 +08:00
|
|
|
// These are not merged; we don't need to merge redeclarations of dependent
|
|
|
|
// template friends.
|
2010-06-28 17:31:34 +08:00
|
|
|
break;
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
|
|
|
}
|
2010-07-02 19:55:40 +08:00
|
|
|
|
2010-05-08 05:43:38 +08:00
|
|
|
// Read in the parameters.
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumParams = Record.readInt();
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ParmVarDecl *, 16> Params;
|
2009-04-27 13:27:42 +08:00
|
|
|
Params.reserve(NumParams);
|
|
|
|
for (unsigned I = 0; I != NumParams; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
Params.push_back(ReadDeclAs<ParmVarDecl>());
|
2011-09-22 02:16:56 +08:00
|
|
|
FD->setParams(Reader.getContext(), Params);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(MD);
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) {
|
2017-10-11 15:47:54 +08:00
|
|
|
// Load the body on-demand. Most clients won't care, because method
|
|
|
|
// definitions rarely show up in headers.
|
|
|
|
Reader.PendingBodies[MD] = GetCurrentCursorOffset();
|
|
|
|
HasPendingBody = true;
|
2016-12-16 04:53:26 +08:00
|
|
|
MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>());
|
|
|
|
MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
2016-12-21 08:17:49 +08:00
|
|
|
MD->setInstanceMethod(Record.readInt());
|
|
|
|
MD->setVariadic(Record.readInt());
|
|
|
|
MD->setPropertyAccessor(Record.readInt());
|
|
|
|
MD->setDefined(Record.readInt());
|
2018-08-02 05:31:08 +08:00
|
|
|
MD->setOverriding(Record.readInt());
|
|
|
|
MD->setHasSkippedBody(Record.readInt());
|
2011-10-15 01:41:52 +08:00
|
|
|
|
2018-08-02 05:31:08 +08:00
|
|
|
MD->setIsRedeclaration(Record.readInt());
|
|
|
|
MD->setHasRedeclaration(Record.readInt());
|
|
|
|
if (MD->hasRedeclaration())
|
2011-10-15 01:41:52 +08:00
|
|
|
Reader.getContext().setObjCMethodRedeclaration(MD,
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadDeclAs<ObjCMethodDecl>());
|
2011-10-15 01:41:52 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record.readInt());
|
|
|
|
MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record.readInt());
|
2018-08-02 05:31:08 +08:00
|
|
|
MD->setRelatedResultType(Record.readInt());
|
2016-12-21 08:17:49 +08:00
|
|
|
MD->setReturnType(Record.readType());
|
2016-12-16 04:53:26 +08:00
|
|
|
MD->setReturnTypeSourceInfo(GetTypeSourceInfo());
|
|
|
|
MD->DeclEndLoc = ReadSourceLocation();
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumParams = Record.readInt();
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ParmVarDecl *, 16> Params;
|
2009-04-27 13:27:42 +08:00
|
|
|
Params.reserve(NumParams);
|
|
|
|
for (unsigned I = 0; I != NumParams; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
Params.push_back(ReadDeclAs<ParmVarDecl>());
|
2011-10-03 14:37:04 +08:00
|
|
|
|
2018-08-02 05:31:08 +08:00
|
|
|
MD->setSelLocsKind((SelectorLocationsKind)Record.readInt());
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumStoredSelLocs = Record.readInt();
|
2011-10-03 14:37:04 +08:00
|
|
|
SmallVector<SourceLocation, 16> SelLocs;
|
|
|
|
SelLocs.reserve(NumStoredSelLocs);
|
|
|
|
for (unsigned i = 0; i != NumStoredSelLocs; ++i)
|
2016-12-16 04:53:26 +08:00
|
|
|
SelLocs.push_back(ReadSourceLocation());
|
2011-10-03 14:37:04 +08:00
|
|
|
|
|
|
|
MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
|
2015-09-29 07:48:49 +08:00
|
|
|
VisitTypedefNameDecl(D);
|
2015-07-27 13:40:23 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
D->Variance = Record.readInt();
|
|
|
|
D->Index = Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
D->VarianceLoc = ReadSourceLocation();
|
|
|
|
D->ColonLoc = ReadSourceLocation();
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(CD);
|
2016-12-16 04:53:26 +08:00
|
|
|
CD->setAtStartLoc(ReadSourceLocation());
|
|
|
|
CD->setAtEndRange(ReadSourceRange());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
ObjCTypeParamList *ASTDeclReader::ReadObjCTypeParamList() {
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned numParams = Record.readInt();
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
if (numParams == 0)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
SmallVector<ObjCTypeParamDecl *, 4> typeParams;
|
|
|
|
typeParams.reserve(numParams);
|
|
|
|
for (unsigned i = 0; i != numParams; ++i) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *typeParam = ReadDeclAs<ObjCTypeParamDecl>();
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
if (!typeParam)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
typeParams.push_back(typeParam);
|
|
|
|
}
|
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation lAngleLoc = ReadSourceLocation();
|
|
|
|
SourceLocation rAngleLoc = ReadSourceLocation();
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
|
|
|
|
return ObjCTypeParamList::create(Reader.getContext(), lAngleLoc,
|
|
|
|
typeParams, rAngleLoc);
|
|
|
|
}
|
|
|
|
|
2016-09-10 07:48:27 +08:00
|
|
|
void ASTDeclReader::ReadObjCDefinitionData(
|
2016-12-21 08:17:49 +08:00
|
|
|
struct ObjCInterfaceDecl::DefinitionData &Data) {
|
2016-09-10 07:48:27 +08:00
|
|
|
// Read the superclass.
|
2016-12-16 04:53:26 +08:00
|
|
|
Data.SuperClassTInfo = GetTypeSourceInfo();
|
2016-09-10 07:48:27 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
Data.EndLoc = ReadSourceLocation();
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.HasDesignatedInitializers = Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2016-09-10 07:48:27 +08:00
|
|
|
// Read the directly referenced protocols and their SourceLocations.
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumProtocols = Record.readInt();
|
2016-09-10 07:48:27 +08:00
|
|
|
SmallVector<ObjCProtocolDecl *, 16> Protocols;
|
|
|
|
Protocols.reserve(NumProtocols);
|
|
|
|
for (unsigned I = 0; I != NumProtocols; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>());
|
2016-09-10 07:48:27 +08:00
|
|
|
SmallVector<SourceLocation, 16> ProtoLocs;
|
|
|
|
ProtoLocs.reserve(NumProtocols);
|
|
|
|
for (unsigned I = 0; I != NumProtocols; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
ProtoLocs.push_back(ReadSourceLocation());
|
2016-09-10 07:48:27 +08:00
|
|
|
Data.ReferencedProtocols.set(Protocols.data(), NumProtocols, ProtoLocs.data(),
|
|
|
|
Reader.getContext());
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2016-09-10 07:48:27 +08:00
|
|
|
// Read the transitive closure of protocols referenced by this class.
|
2016-12-21 08:17:49 +08:00
|
|
|
NumProtocols = Record.readInt();
|
2016-09-10 07:48:27 +08:00
|
|
|
Protocols.clear();
|
|
|
|
Protocols.reserve(NumProtocols);
|
|
|
|
for (unsigned I = 0; I != NumProtocols; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>());
|
2016-09-10 07:48:27 +08:00
|
|
|
Data.AllReferencedProtocols.set(Protocols.data(), NumProtocols,
|
|
|
|
Reader.getContext());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl *D,
|
|
|
|
struct ObjCInterfaceDecl::DefinitionData &&NewDD) {
|
|
|
|
// FIXME: odr checking?
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
|
2011-12-22 09:48:48 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCContainerDecl(ID);
|
2018-07-04 10:25:38 +08:00
|
|
|
DeferredTypeID = Record.getGlobalTypeID(Record.readInt());
|
2012-01-04 01:27:13 +08:00
|
|
|
mergeRedeclarable(ID, Redecl);
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
|
|
|
|
ID->TypeParamList = ReadObjCTypeParamList();
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) {
|
2011-12-15 13:27:12 +08:00
|
|
|
// Read the definition.
|
|
|
|
ID->allocateDefinitionData();
|
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
ReadObjCDefinitionData(ID->data());
|
2016-09-10 07:48:27 +08:00
|
|
|
ObjCInterfaceDecl *Canon = ID->getCanonicalDecl();
|
|
|
|
if (Canon->Data.getPointer()) {
|
|
|
|
// If we already have a definition, keep the definition invariant and
|
|
|
|
// merge the data.
|
|
|
|
MergeDefinitionData(Canon, std::move(ID->data()));
|
|
|
|
ID->Data = Canon->Data;
|
|
|
|
} else {
|
|
|
|
// Set the definition data of the canonical declaration, so other
|
|
|
|
// redeclarations will see it.
|
|
|
|
ID->getCanonicalDecl()->Data = ID->Data;
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2016-09-10 07:48:27 +08:00
|
|
|
// We will rebuild this list lazily.
|
|
|
|
ID->setIvarList(nullptr);
|
|
|
|
}
|
2014-05-22 13:54:18 +08:00
|
|
|
|
2011-12-20 04:51:16 +08:00
|
|
|
// Note that we have deserialized a definition.
|
|
|
|
Reader.PendingDefinitions.insert(ID);
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
// Note that we've loaded this Objective-C class.
|
|
|
|
Reader.ObjCClassesLoaded.push_back(ID);
|
2012-01-16 02:08:05 +08:00
|
|
|
} else {
|
|
|
|
ID->Data = ID->getCanonicalDecl()->Data;
|
2011-12-15 13:27:12 +08:00
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitFieldDecl(IVD);
|
2016-12-21 08:17:49 +08:00
|
|
|
IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record.readInt());
|
2010-08-21 05:21:08 +08:00
|
|
|
// This field will be built lazily.
|
2014-05-22 13:54:18 +08:00
|
|
|
IVD->setNextIvar(nullptr);
|
2016-12-21 08:17:49 +08:00
|
|
|
bool synth = Record.readInt();
|
2010-07-18 02:35:47 +08:00
|
|
|
IVD->setSynthesize(synth);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
[ASTReader] Treat multiple defns of ObjC protocols the same as interfaces.
Summary:
In change 2ba19793512, the ASTReader logic for ObjC interfaces was modified to
preserve the first definition-data read, "merging" later definitions into it
rather than overwriting it (though this "merging" is, in practice, a no-op that
discards the later definition-data).
Unfortunately this change was only made to ObjC interfaces, not protocols; this
means that when (for example) loading a protocol that references an interface,
if both the protocol and interface are multiply defined (as can easily happen
if the same header is read from multiple contexts), an _inconsistent_ pair of
definitions is loaded: first-read for the interface and last-read for the
protocol.
This in turn causes very subtle downstream bugs in the Swift ClangImporter,
which filters the results of name lookups based on the owning module of a
definition; inconsistency between a pair of related definitions causes name
lookup failures at various stages of compilation.
To fix these downstream issues, this change replicates the logic applied to
interfaces in change 2ba19793512, but for ObjC protocols.
rdar://30851899
Reviewers: doug.gregor, rsmith
Reviewed By: doug.gregor
Subscribers: jordan_rose, cfe-commits
Differential Revision: https://reviews.llvm.org/D34741
llvm-svn: 306583
2017-06-29 02:36:27 +08:00
|
|
|
void ASTDeclReader::ReadObjCDefinitionData(
|
|
|
|
struct ObjCProtocolDecl::DefinitionData &Data) {
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumProtoRefs = Record.readInt();
|
2012-01-02 03:29:29 +08:00
|
|
|
SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
|
|
|
|
ProtoRefs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>());
|
2012-01-02 03:29:29 +08:00
|
|
|
SmallVector<SourceLocation, 16> ProtoLocs;
|
|
|
|
ProtoLocs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
ProtoLocs.push_back(ReadSourceLocation());
|
[ASTReader] Treat multiple defns of ObjC protocols the same as interfaces.
Summary:
In change 2ba19793512, the ASTReader logic for ObjC interfaces was modified to
preserve the first definition-data read, "merging" later definitions into it
rather than overwriting it (though this "merging" is, in practice, a no-op that
discards the later definition-data).
Unfortunately this change was only made to ObjC interfaces, not protocols; this
means that when (for example) loading a protocol that references an interface,
if both the protocol and interface are multiply defined (as can easily happen
if the same header is read from multiple contexts), an _inconsistent_ pair of
definitions is loaded: first-read for the interface and last-read for the
protocol.
This in turn causes very subtle downstream bugs in the Swift ClangImporter,
which filters the results of name lookups based on the owning module of a
definition; inconsistency between a pair of related definitions causes name
lookup failures at various stages of compilation.
To fix these downstream issues, this change replicates the logic applied to
interfaces in change 2ba19793512, but for ObjC protocols.
rdar://30851899
Reviewers: doug.gregor, rsmith
Reviewed By: doug.gregor
Subscribers: jordan_rose, cfe-commits
Differential Revision: https://reviews.llvm.org/D34741
llvm-svn: 306583
2017-06-29 02:36:27 +08:00
|
|
|
Data.ReferencedProtocols.set(ProtoRefs.data(), NumProtoRefs,
|
|
|
|
ProtoLocs.data(), Reader.getContext());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDeclReader::MergeDefinitionData(ObjCProtocolDecl *D,
|
|
|
|
struct ObjCProtocolDecl::DefinitionData &&NewDD) {
|
|
|
|
// FIXME: odr checking?
|
|
|
|
}
|
2016-12-16 04:53:26 +08:00
|
|
|
|
[ASTReader] Treat multiple defns of ObjC protocols the same as interfaces.
Summary:
In change 2ba19793512, the ASTReader logic for ObjC interfaces was modified to
preserve the first definition-data read, "merging" later definitions into it
rather than overwriting it (though this "merging" is, in practice, a no-op that
discards the later definition-data).
Unfortunately this change was only made to ObjC interfaces, not protocols; this
means that when (for example) loading a protocol that references an interface,
if both the protocol and interface are multiply defined (as can easily happen
if the same header is read from multiple contexts), an _inconsistent_ pair of
definitions is loaded: first-read for the interface and last-read for the
protocol.
This in turn causes very subtle downstream bugs in the Swift ClangImporter,
which filters the results of name lookups based on the owning module of a
definition; inconsistency between a pair of related definitions causes name
lookup failures at various stages of compilation.
To fix these downstream issues, this change replicates the logic applied to
interfaces in change 2ba19793512, but for ObjC protocols.
rdar://30851899
Reviewers: doug.gregor, rsmith
Reviewed By: doug.gregor
Subscribers: jordan_rose, cfe-commits
Differential Revision: https://reviews.llvm.org/D34741
llvm-svn: 306583
2017-06-29 02:36:27 +08:00
|
|
|
void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
|
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(PD);
|
|
|
|
VisitObjCContainerDecl(PD);
|
|
|
|
mergeRedeclarable(PD, Redecl);
|
|
|
|
|
|
|
|
if (Record.readInt()) {
|
|
|
|
// Read the definition.
|
|
|
|
PD->allocateDefinitionData();
|
|
|
|
|
|
|
|
ReadObjCDefinitionData(PD->data());
|
|
|
|
|
|
|
|
ObjCProtocolDecl *Canon = PD->getCanonicalDecl();
|
|
|
|
if (Canon->Data.getPointer()) {
|
|
|
|
// If we already have a definition, keep the definition invariant and
|
|
|
|
// merge the data.
|
|
|
|
MergeDefinitionData(Canon, std::move(PD->data()));
|
|
|
|
PD->Data = Canon->Data;
|
|
|
|
} else {
|
|
|
|
// Set the definition data of the canonical declaration, so other
|
|
|
|
// redeclarations will see it.
|
|
|
|
PD->getCanonicalDecl()->Data = PD->Data;
|
|
|
|
}
|
2012-01-02 03:51:50 +08:00
|
|
|
// Note that we have deserialized a definition.
|
|
|
|
Reader.PendingDefinitions.insert(PD);
|
2012-01-16 02:08:05 +08:00
|
|
|
} else {
|
|
|
|
PD->Data = PD->getCanonicalDecl()->Data;
|
2012-01-02 03:29:29 +08:00
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitFieldDecl(FD);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCContainerDecl(CD);
|
2016-12-16 04:53:26 +08:00
|
|
|
CD->setCategoryNameLoc(ReadSourceLocation());
|
|
|
|
CD->setIvarLBraceLoc(ReadSourceLocation());
|
|
|
|
CD->setIvarRBraceLoc(ReadSourceLocation());
|
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
// Note that this category has been deserialized. We do this before
|
|
|
|
// deserializing the interface declaration, so that it will consider this
|
|
|
|
/// category.
|
|
|
|
Reader.CategoriesDeserialized.insert(CD);
|
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>();
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
CD->TypeParamList = ReadObjCTypeParamList();
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumProtoRefs = Record.readInt();
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
|
2009-04-27 13:27:42 +08:00
|
|
|
ProtoRefs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>());
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<SourceLocation, 16> ProtoLocs;
|
2010-01-16 23:02:53 +08:00
|
|
|
ProtoLocs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
ProtoLocs.push_back(ReadSourceLocation());
|
2010-01-16 23:02:53 +08:00
|
|
|
CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext());
|
2018-04-28 02:01:23 +08:00
|
|
|
|
|
|
|
// Protocols in the class extension belong to the class.
|
|
|
|
if (NumProtoRefs > 0 && CD->ClassInterface && CD->IsClassExtension())
|
|
|
|
CD->ClassInterface->mergeClassExtensionProtocolList(
|
|
|
|
(ObjCProtocolDecl *const *)ProtoRefs.data(), NumProtoRefs,
|
|
|
|
Reader.getContext());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(CAD);
|
2016-12-16 04:53:26 +08:00
|
|
|
CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setAtLoc(ReadSourceLocation());
|
|
|
|
D->setLParenLoc(ReadSourceLocation());
|
2016-12-21 08:17:49 +08:00
|
|
|
QualType T = Record.readType();
|
2016-12-16 04:53:26 +08:00
|
|
|
TypeSourceInfo *TSI = GetTypeSourceInfo();
|
2015-06-20 02:14:38 +08:00
|
|
|
D->setType(T, TSI);
|
2009-04-27 13:27:42 +08:00
|
|
|
D->setPropertyAttributes(
|
2016-12-21 08:17:49 +08:00
|
|
|
(ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
|
2010-06-23 07:20:40 +08:00
|
|
|
D->setPropertyAttributesAsWritten(
|
2016-12-21 08:17:49 +08:00
|
|
|
(ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
|
2009-04-27 13:27:42 +08:00
|
|
|
D->setPropertyImplementation(
|
2016-12-21 08:17:49 +08:00
|
|
|
(ObjCPropertyDecl::PropertyControl)Record.readInt());
|
2017-03-17 08:49:42 +08:00
|
|
|
DeclarationName GetterName = Record.readDeclarationName();
|
|
|
|
SourceLocation GetterLoc = ReadSourceLocation();
|
|
|
|
D->setGetterName(GetterName.getObjCSelector(), GetterLoc);
|
|
|
|
DeclarationName SetterName = Record.readDeclarationName();
|
|
|
|
SourceLocation SetterLoc = ReadSourceLocation();
|
|
|
|
D->setSetterName(SetterName.getObjCSelector(), SetterLoc);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>());
|
|
|
|
D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>());
|
|
|
|
D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
|
2009-07-28 03:04:32 +08:00
|
|
|
VisitObjCContainerDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCImplDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->CategoryNameLoc = ReadSourceLocation();
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCImplDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>());
|
|
|
|
D->SuperLoc = ReadSourceLocation();
|
|
|
|
D->setIvarLBraceLoc(ReadSourceLocation());
|
|
|
|
D->setIvarRBraceLoc(ReadSourceLocation());
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setHasNonZeroConstructors(Record.readInt());
|
|
|
|
D->setHasDestructors(Record.readInt());
|
|
|
|
D->NumIvarInitializers = Record.readInt();
|
2015-03-24 14:36:48 +08:00
|
|
|
if (D->NumIvarInitializers)
|
2016-12-16 04:53:26 +08:00
|
|
|
D->IvarInitializers = ReadGlobalOffset();
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setAtLoc(ReadSourceLocation());
|
|
|
|
D->setPropertyDecl(ReadDeclAs<ObjCPropertyDecl>());
|
|
|
|
D->PropertyIvarDecl = ReadDeclAs<ObjCIvarDecl>();
|
|
|
|
D->IvarLoc = ReadSourceLocation();
|
2016-12-21 12:34:52 +08:00
|
|
|
D->setGetterCXXConstructor(Record.readExpr());
|
|
|
|
D->setSetterCXXAssignment(Record.readExpr());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
|
2009-08-19 09:28:35 +08:00
|
|
|
VisitDeclaratorDecl(FD);
|
2016-12-21 08:17:49 +08:00
|
|
|
FD->Mutable = Record.readInt();
|
2017-08-28 08:28:14 +08:00
|
|
|
|
|
|
|
if (auto ISK = static_cast<FieldDecl::InitStorageKind>(Record.readInt())) {
|
|
|
|
FD->InitStorage.setInt(ISK);
|
|
|
|
FD->InitStorage.setPointer(ISK == FieldDecl::ISK_CapturedVLAType
|
|
|
|
? Record.readType().getAsOpaquePtr()
|
|
|
|
: Record.readExpr());
|
2012-06-10 11:12:00 +08:00
|
|
|
}
|
2017-08-28 08:28:14 +08:00
|
|
|
|
|
|
|
if (auto *BW = Record.readExpr())
|
|
|
|
FD->setBitWidth(BW);
|
|
|
|
|
2010-07-05 05:44:35 +08:00
|
|
|
if (!FD->getDeclName()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *Tmpl = ReadDeclAs<FieldDecl>())
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
|
2010-07-05 05:44:35 +08:00
|
|
|
}
|
2013-10-07 16:02:11 +08:00
|
|
|
mergeMergeable(FD);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2013-04-16 15:28:30 +08:00
|
|
|
void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) {
|
|
|
|
VisitDeclaratorDecl(PD);
|
2016-12-21 12:34:52 +08:00
|
|
|
PD->GetterId = Record.getIdentifierInfo();
|
|
|
|
PD->SetterId = Record.getIdentifierInfo();
|
2013-04-16 15:28:30 +08:00
|
|
|
}
|
|
|
|
|
2010-11-21 14:08:52 +08:00
|
|
|
void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
|
|
|
|
VisitValueDecl(FD);
|
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
FD->ChainingSize = Record.readInt();
|
2010-11-21 14:08:52 +08:00
|
|
|
assert(FD->ChainingSize >= 2 && "Anonymous chaining must be >= 2");
|
2011-09-10 05:34:22 +08:00
|
|
|
FD->Chaining = new (Reader.getContext())NamedDecl*[FD->ChainingSize];
|
2010-11-21 14:08:52 +08:00
|
|
|
|
|
|
|
for (unsigned I = 0; I != FD->ChainingSize; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
FD->Chaining[I] = ReadDeclAs<NamedDecl>();
|
2015-08-04 10:05:09 +08:00
|
|
|
|
|
|
|
mergeMergeable(FD);
|
2010-11-21 14:08:52 +08:00
|
|
|
}
|
|
|
|
|
2013-08-06 09:03:05 +08:00
|
|
|
ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
|
2012-01-05 01:21:36 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(VD);
|
2011-10-27 01:53:41 +08:00
|
|
|
VisitDeclaratorDecl(VD);
|
2013-04-04 03:27:57 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
VD->VarDeclBits.SClass = (StorageClass)Record.readInt();
|
|
|
|
VD->VarDeclBits.TSCSpec = Record.readInt();
|
|
|
|
VD->VarDeclBits.InitStyle = Record.readInt();
|
2015-05-19 08:57:16 +08:00
|
|
|
if (!isa<ParmVarDecl>(VD)) {
|
2016-12-21 08:17:49 +08:00
|
|
|
VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition =
|
|
|
|
Record.readInt();
|
|
|
|
VD->NonParmVarDeclBits.ExceptionVar = Record.readInt();
|
2018-06-19 13:35:30 +08:00
|
|
|
VD->NonParmVarDeclBits.NRVOVariable = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt();
|
[ast] Do not auto-initialize Objective-C for-loop variables in Objective-C++ in templatized code under ARC
The AST for the fragment
```
@interface I
@end
template <typename>
void decode(I *p) {
for (I *k in p) {}
}
void decode(I *p) {
decode<int>(p);
}
```
differs heavily when templatized and non-templatized:
```
|-FunctionTemplateDecl 0x7fbfe0863940 <line:4:1, line:7:1> line:5:6 decode
| |-TemplateTypeParmDecl 0x7fbfe0863690 <line:4:11> col:11 typename depth 0 index 0
| |-FunctionDecl 0x7fbfe08638a0 <line:5:1, line:7:1> line:5:6 decode 'void (I *__strong)'
| | |-ParmVarDecl 0x7fbfe08637a0 <col:13, col:16> col:16 referenced p 'I *__strong'
| | `-CompoundStmt 0x7fbfe0863b88 <col:19, line:7:1>
| | `-ObjCForCollectionStmt 0x7fbfe0863b50 <line:6:3, col:20>
| | |-DeclStmt 0x7fbfe0863a50 <col:8, col:13>
| | | `-VarDecl 0x7fbfe08639f0 <col:8, col:11> col:11 k 'I *const __strong'
| | |-ImplicitCastExpr 0x7fbfe0863a90 <col:16> 'I *' <LValueToRValue>
| | | `-DeclRefExpr 0x7fbfe0863a68 <col:16> 'I *__strong' lvalue ParmVar 0x7fbfe08637a0 'p' 'I *__strong'
| | `-CompoundStmt 0x7fbfe0863b78 <col:19, col:20>
| `-FunctionDecl 0x7fbfe0863f80 <line:5:1, line:7:1> line:5:6 used decode 'void (I *__strong)'
| |-TemplateArgument type 'int'
| |-ParmVarDecl 0x7fbfe0863ef8 <col:13, col:16> col:16 used p 'I *__strong'
| `-CompoundStmt 0x7fbfe0890cf0 <col:19, line:7:1>
| `-ObjCForCollectionStmt 0x7fbfe0890cc8 <line:6:3, col:20>
| |-DeclStmt 0x7fbfe0890c70 <col:8, col:13>
| | `-VarDecl 0x7fbfe0890c00 <col:8, col:11> col:11 k 'I *__strong' callinit
| | `-ImplicitValueInitExpr 0x7fbfe0890c60 <<invalid sloc>> 'I *__strong'
| |-ImplicitCastExpr 0x7fbfe0890cb0 <col:16> 'I *' <LValueToRValue>
| | `-DeclRefExpr 0x7fbfe0890c88 <col:16> 'I *__strong' lvalue ParmVar 0x7fbfe0863ef8 'p' 'I *__strong'
| `-CompoundStmt 0x7fbfe0863b78 <col:19, col:20>
```
Note how in the instantiated version ImplicitValueInitExpr unexpectedly appears.
While objects are auto-initialized under ARC, it does not make sense to
have an initializer for a for-loop variable, and it makes even less
sense to have such a different AST for instantiated and non-instantiated
version.
Digging deeper, I have found that there are two separate Sema* files for
dealing with templates and for dealing with non-templatized code.
In a non-templatized version, an initialization was performed only for
variables which are not loop variables for an Objective-C loop and not
variables for a C++ for-in loop:
```
if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
bool IsForRangeLoop = false;
if (TryConsumeToken(tok::colon, FRI->ColonLoc)) {
IsForRangeLoop = true;
if (Tok.is(tok::l_brace))
FRI->RangeExpr = ParseBraceInitializer();
else
FRI->RangeExpr = ParseExpression();
}
Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
if (IsForRangeLoop)
Actions.ActOnCXXForRangeDecl(ThisDecl);
Actions.FinalizeDeclaration(ThisDecl);
D.complete(ThisDecl);
return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl);
}
SmallVector<Decl *, 8> DeclsInGroup;
Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(
D, ParsedTemplateInfo(), FRI);
```
However the code in SemaTemplateInstantiateDecl was inconsistent,
guarding only against C++ for-in loops.
rdar://38391075
Differential Revision: https://reviews.llvm.org/D44989
llvm-svn: 328749
2018-03-29 08:56:24 +08:00
|
|
|
VD->NonParmVarDeclBits.ObjCForDecl = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
VD->NonParmVarDeclBits.ARCPseudoStrong = Record.readInt();
|
|
|
|
VD->NonParmVarDeclBits.IsInline = Record.readInt();
|
|
|
|
VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt();
|
|
|
|
VD->NonParmVarDeclBits.IsConstexpr = Record.readInt();
|
|
|
|
VD->NonParmVarDeclBits.IsInitCapture = Record.readInt();
|
|
|
|
VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record.readInt();
|
2017-06-09 21:40:18 +08:00
|
|
|
VD->NonParmVarDeclBits.ImplicitParamKind = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
auto VarLinkage = Linkage(Record.readInt());
|
2013-09-20 09:15:31 +08:00
|
|
|
VD->setCachedLinkage(VarLinkage);
|
|
|
|
|
|
|
|
// Reconstruct the one piece of the IdentifierNamespace that we need.
|
2014-02-11 14:29:29 +08:00
|
|
|
if (VD->getStorageClass() == SC_Extern && VarLinkage != NoLinkage &&
|
2013-09-20 09:15:31 +08:00
|
|
|
VD->getLexicalDeclContext()->isFunctionOrMethod())
|
|
|
|
VD->setLocalExternDecl();
|
2013-05-26 01:16:20 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
if (uint64_t Val = Record.readInt()) {
|
2016-12-21 12:34:52 +08:00
|
|
|
VD->setInit(Record.readExpr());
|
2016-10-06 21:04:54 +08:00
|
|
|
if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3
|
2011-12-19 14:19:21 +08:00
|
|
|
EvaluatedStmt *Eval = VD->ensureEvaluatedStmt();
|
|
|
|
Eval->CheckedICE = true;
|
|
|
|
Eval->IsICE = Val == 3;
|
|
|
|
}
|
|
|
|
}
|
2010-07-05 05:44:00 +08:00
|
|
|
|
2018-08-10 23:09:24 +08:00
|
|
|
if (VD->hasAttr<BlocksAttr>() && VD->getType()->getAsCXXRecordDecl()) {
|
|
|
|
Expr *CopyExpr = Record.readExpr();
|
|
|
|
if (CopyExpr)
|
|
|
|
Reader.getContext().setBlockVarCopyInit(VD, CopyExpr, Record.readInt());
|
|
|
|
}
|
|
|
|
|
2017-09-07 04:01:14 +08:00
|
|
|
if (VD->getStorageDuration() == SD_Static && Record.readInt())
|
|
|
|
Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
|
|
|
|
2013-08-14 11:09:19 +08:00
|
|
|
enum VarKind {
|
|
|
|
VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
|
|
|
|
};
|
2016-12-21 08:17:49 +08:00
|
|
|
switch ((VarKind)Record.readInt()) {
|
2013-08-14 11:09:19 +08:00
|
|
|
case VarNotTemplate:
|
2015-07-27 13:40:23 +08:00
|
|
|
// Only true variables (not parameters or implicit parameters) can be
|
|
|
|
// merged; the other kinds are not really redeclarable at all.
|
2015-08-22 10:09:38 +08:00
|
|
|
if (!isa<ParmVarDecl>(VD) && !isa<ImplicitParamDecl>(VD) &&
|
|
|
|
!isa<VarTemplateSpecializationDecl>(VD))
|
2014-04-24 10:25:27 +08:00
|
|
|
mergeRedeclarable(VD, Redecl);
|
2013-08-14 11:09:19 +08:00
|
|
|
break;
|
|
|
|
case VarTemplate:
|
2014-04-24 10:25:27 +08:00
|
|
|
// Merged when we merge the template.
|
2016-12-16 04:53:26 +08:00
|
|
|
VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>());
|
2013-08-14 11:09:19 +08:00
|
|
|
break;
|
|
|
|
case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo.
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Tmpl = ReadDeclAs<VarDecl>();
|
|
|
|
auto TSK = (TemplateSpecializationKind)Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation();
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
|
2014-04-24 10:25:27 +08:00
|
|
|
mergeRedeclarable(VD, Redecl);
|
2013-08-14 11:09:19 +08:00
|
|
|
break;
|
|
|
|
}
|
2010-07-05 05:44:00 +08:00
|
|
|
}
|
2013-08-06 09:03:05 +08:00
|
|
|
|
|
|
|
return Redecl;
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitVarDecl(PD);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitVarDecl(PD);
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned isObjCMethodParam = Record.readInt();
|
|
|
|
unsigned scopeDepth = Record.readInt();
|
|
|
|
unsigned scopeIndex = Record.readInt();
|
|
|
|
unsigned declQualifier = Record.readInt();
|
2011-05-02 08:30:12 +08:00
|
|
|
if (isObjCMethodParam) {
|
|
|
|
assert(scopeDepth == 0);
|
|
|
|
PD->setObjCMethodScopeInfo(scopeIndex);
|
|
|
|
PD->ParmVarDeclBits.ScopeDepthOrObjCQuals = declQualifier;
|
|
|
|
} else {
|
|
|
|
PD->setScopeInfo(scopeDepth, scopeIndex);
|
|
|
|
}
|
2016-12-21 08:17:49 +08:00
|
|
|
PD->ParmVarDeclBits.IsKNRPromoted = Record.readInt();
|
|
|
|
PD->ParmVarDeclBits.HasInheritedDefaultArg = Record.readInt();
|
|
|
|
if (Record.readInt()) // hasUninstantiatedDefaultArg.
|
2016-12-21 12:34:52 +08:00
|
|
|
PD->setUninstantiatedDefaultArg(Record.readExpr());
|
2013-06-25 06:51:00 +08:00
|
|
|
|
|
|
|
// FIXME: If this is a redeclaration of a function from another module, handle
|
|
|
|
// inheritance of default arguments.
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2016-08-12 10:21:25 +08:00
|
|
|
void ASTDeclReader::VisitDecompositionDecl(DecompositionDecl *DD) {
|
|
|
|
VisitVarDecl(DD);
|
2018-04-12 04:57:28 +08:00
|
|
|
auto **BDs = DD->getTrailingObjects<BindingDecl *>();
|
2016-08-12 10:21:25 +08:00
|
|
|
for (unsigned I = 0; I != DD->NumBindings; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
BDs[I] = ReadDeclAs<BindingDecl>();
|
2016-08-12 10:21:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDeclReader::VisitBindingDecl(BindingDecl *BD) {
|
|
|
|
VisitValueDecl(BD);
|
2016-12-21 12:34:52 +08:00
|
|
|
BD->Binding = Record.readExpr();
|
2016-08-12 10:21:25 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(AD);
|
2016-12-21 12:34:52 +08:00
|
|
|
AD->setAsmString(cast<StringLiteral>(Record.readExpr()));
|
2016-12-16 04:53:26 +08:00
|
|
|
AD->setRParenLoc(ReadSourceLocation());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(BD);
|
2016-12-21 12:34:52 +08:00
|
|
|
BD->setBody(cast_or_null<CompoundStmt>(Record.readStmt()));
|
2016-12-16 04:53:26 +08:00
|
|
|
BD->setSignatureAsWritten(GetTypeSourceInfo());
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumParams = Record.readInt();
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ParmVarDecl *, 16> Params;
|
2009-04-27 13:27:42 +08:00
|
|
|
Params.reserve(NumParams);
|
|
|
|
for (unsigned I = 0; I != NumParams; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
Params.push_back(ReadDeclAs<ParmVarDecl>());
|
2011-09-22 02:16:56 +08:00
|
|
|
BD->setParams(Params);
|
2011-02-02 21:00:07 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
BD->setIsVariadic(Record.readInt());
|
|
|
|
BD->setBlockMissingReturnType(Record.readInt());
|
|
|
|
BD->setIsConversionFromLambda(Record.readInt());
|
2018-08-02 07:51:53 +08:00
|
|
|
BD->setDoesNotEscape(Record.readInt());
|
2012-04-14 01:33:29 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
bool capturesCXXThis = Record.readInt();
|
|
|
|
unsigned numCaptures = Record.readInt();
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<BlockDecl::Capture, 16> captures;
|
2011-02-07 18:33:21 +08:00
|
|
|
captures.reserve(numCaptures);
|
|
|
|
for (unsigned i = 0; i != numCaptures; ++i) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *decl = ReadDeclAs<VarDecl>();
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned flags = Record.readInt();
|
2011-02-07 18:33:21 +08:00
|
|
|
bool byRef = (flags & 1);
|
|
|
|
bool nested = (flags & 2);
|
2016-12-21 12:34:52 +08:00
|
|
|
Expr *copyExpr = ((flags & 4) ? Record.readExpr() : nullptr);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr));
|
|
|
|
}
|
2015-08-05 17:40:35 +08:00
|
|
|
BD->setCaptures(Reader.getContext(), captures, capturesCXXThis);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2013-05-04 03:20:19 +08:00
|
|
|
void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) {
|
|
|
|
VisitDecl(CD);
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned ContextParamPos = Record.readInt();
|
|
|
|
CD->setNothrow(Record.readInt() != 0);
|
2013-05-04 03:20:19 +08:00
|
|
|
// Body is set by VisitCapturedStmt.
|
2014-05-06 18:08:46 +08:00
|
|
|
for (unsigned I = 0; I < CD->NumParams; ++I) {
|
|
|
|
if (I != ContextParamPos)
|
2016-12-16 04:53:26 +08:00
|
|
|
CD->setParam(I, ReadDeclAs<ImplicitParamDecl>());
|
2014-05-06 18:08:46 +08:00
|
|
|
else
|
2016-12-16 04:53:26 +08:00
|
|
|
CD->setContextParam(I, ReadDeclAs<ImplicitParamDecl>());
|
2014-05-06 18:08:46 +08:00
|
|
|
}
|
2013-04-17 03:37:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitDecl(D);
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setLanguage((LinkageSpecDecl::LanguageIDs)Record.readInt());
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setExternLoc(ReadSourceLocation());
|
|
|
|
D->setRBraceLoc(ReadSourceLocation());
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2016-09-09 07:14:54 +08:00
|
|
|
void ASTDeclReader::VisitExportDecl(ExportDecl *D) {
|
|
|
|
VisitDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->RBraceLoc = ReadSourceLocation();
|
2016-09-09 07:14:54 +08:00
|
|
|
}
|
|
|
|
|
2011-02-17 15:39:24 +08:00
|
|
|
void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
|
|
|
|
VisitNamedDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setLocStart(ReadSourceLocation());
|
2011-02-17 15:39:24 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
|
2012-01-07 17:11:48 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setInline(Record.readInt());
|
2016-12-16 04:53:26 +08:00
|
|
|
D->LocStart = ReadSourceLocation();
|
|
|
|
D->RBraceLoc = ReadSourceLocation();
|
2012-01-10 01:30:44 +08:00
|
|
|
|
2015-03-17 10:23:11 +08:00
|
|
|
// Defer loading the anonymous namespace until we've finished merging
|
|
|
|
// this namespace; loading it might load a later declaration of the
|
|
|
|
// same namespace, and we have an invariant that older declarations
|
|
|
|
// get merged before newer ones try to merge.
|
|
|
|
GlobalDeclID AnonNamespace = 0;
|
2012-01-07 17:11:48 +08:00
|
|
|
if (Redecl.getFirstID() == ThisDeclID) {
|
2016-12-16 04:53:26 +08:00
|
|
|
AnonNamespace = ReadDeclID();
|
2012-01-07 17:11:48 +08:00
|
|
|
} else {
|
|
|
|
// Link this namespace back to the first declaration, which has already
|
|
|
|
// been deserialized.
|
2013-10-17 23:37:26 +08:00
|
|
|
D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDecl());
|
2012-01-07 17:11:48 +08:00
|
|
|
}
|
2014-07-15 11:37:06 +08:00
|
|
|
|
|
|
|
mergeRedeclarable(D, Redecl);
|
2015-03-17 10:23:11 +08:00
|
|
|
|
|
|
|
if (AnonNamespace) {
|
|
|
|
// Each module has its own anonymous namespace, which is disjoint from
|
|
|
|
// any other module's anonymous namespaces, so don't attach the anonymous
|
|
|
|
// namespace at all.
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Anon = cast<NamespaceDecl>(Reader.GetDecl(AnonNamespace));
|
2016-12-16 04:53:26 +08:00
|
|
|
if (!Record.isModule())
|
2015-03-17 10:23:11 +08:00
|
|
|
D->setAnonymousNamespace(Anon);
|
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
|
2014-09-04 07:11:22 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->NamespaceLoc = ReadSourceLocation();
|
|
|
|
D->IdentLoc = ReadSourceLocation();
|
2016-12-21 12:34:52 +08:00
|
|
|
D->QualifierLoc = Record.readNestedNameSpecifierLoc();
|
2016-12-16 04:53:26 +08:00
|
|
|
D->Namespace = ReadDeclAs<NamedDecl>();
|
2014-09-04 07:11:22 +08:00
|
|
|
mergeRedeclarable(D, Redecl);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setUsingLoc(ReadSourceLocation());
|
2016-12-21 12:34:52 +08:00
|
|
|
D->QualifierLoc = Record.readNestedNameSpecifierLoc();
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName());
|
|
|
|
D->FirstUsingShadow.setPointer(ReadDeclAs<UsingShadowDecl>());
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setTypename(Record.readInt());
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *Pattern = ReadDeclAs<NamedDecl>())
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern);
|
2014-10-14 10:00:47 +08:00
|
|
|
mergeMergeable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2016-12-21 05:35:28 +08:00
|
|
|
void ASTDeclReader::VisitUsingPackDecl(UsingPackDecl *D) {
|
|
|
|
VisitNamedDecl(D);
|
|
|
|
D->InstantiatedFrom = ReadDeclAs<NamedDecl>();
|
2018-04-12 04:57:28 +08:00
|
|
|
auto **Expansions = D->getTrailingObjects<NamedDecl *>();
|
2016-12-21 05:35:28 +08:00
|
|
|
for (unsigned I = 0; I != D->NumExpansions; ++I)
|
|
|
|
Expansions[I] = ReadDeclAs<NamedDecl>();
|
|
|
|
mergeMergeable(D);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
|
2013-10-23 10:17:46 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2018-01-06 09:07:05 +08:00
|
|
|
D->Underlying = ReadDeclAs<NamedDecl>();
|
|
|
|
D->IdentifierNamespace = Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
D->UsingOrNextShadow = ReadDeclAs<NamedDecl>();
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Pattern = ReadDeclAs<UsingShadowDecl>();
|
2010-07-05 05:44:35 +08:00
|
|
|
if (Pattern)
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern);
|
2013-10-23 10:17:46 +08:00
|
|
|
mergeRedeclarable(D, Redecl);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
void ASTDeclReader::VisitConstructorUsingShadowDecl(
|
|
|
|
ConstructorUsingShadowDecl *D) {
|
|
|
|
VisitUsingShadowDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->NominatedBaseClassShadowDecl = ReadDeclAs<ConstructorUsingShadowDecl>();
|
|
|
|
D->ConstructedBaseClassShadowDecl = ReadDeclAs<ConstructorUsingShadowDecl>();
|
2016-12-21 08:17:49 +08:00
|
|
|
D->IsVirtual = Record.readInt();
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->UsingLoc = ReadSourceLocation();
|
|
|
|
D->NamespaceLoc = ReadSourceLocation();
|
2016-12-21 12:34:52 +08:00
|
|
|
D->QualifierLoc = Record.readNestedNameSpecifierLoc();
|
2016-12-16 04:53:26 +08:00
|
|
|
D->NominatedNamespace = ReadDeclAs<NamedDecl>();
|
|
|
|
D->CommonAncestor = ReadDeclAs<DeclContext>();
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitValueDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setUsingLoc(ReadSourceLocation());
|
2016-12-21 12:34:52 +08:00
|
|
|
D->QualifierLoc = Record.readNestedNameSpecifierLoc();
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName());
|
2016-12-21 05:35:28 +08:00
|
|
|
D->EllipsisLoc = ReadSourceLocation();
|
2014-10-14 10:00:47 +08:00
|
|
|
mergeMergeable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
|
2010-05-08 05:43:38 +08:00
|
|
|
UnresolvedUsingTypenameDecl *D) {
|
|
|
|
VisitTypeDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->TypenameLocation = ReadSourceLocation();
|
2016-12-21 12:34:52 +08:00
|
|
|
D->QualifierLoc = Record.readNestedNameSpecifierLoc();
|
2016-12-21 05:35:28 +08:00
|
|
|
D->EllipsisLoc = ReadSourceLocation();
|
2014-10-14 10:00:47 +08:00
|
|
|
mergeMergeable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-10-25 01:26:27 +08:00
|
|
|
void ASTDeclReader::ReadCXXDefinitionData(
|
2017-04-12 05:13:37 +08:00
|
|
|
struct CXXRecordDecl::DefinitionData &Data, const CXXRecordDecl *D) {
|
2012-02-15 01:54:36 +08:00
|
|
|
// Note: the caller has deserialized the IsLambda bit already.
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.UserDeclaredConstructor = Record.readInt();
|
|
|
|
Data.UserDeclaredSpecialMembers = Record.readInt();
|
|
|
|
Data.Aggregate = Record.readInt();
|
|
|
|
Data.PlainOldData = Record.readInt();
|
|
|
|
Data.Empty = Record.readInt();
|
|
|
|
Data.Polymorphic = Record.readInt();
|
|
|
|
Data.Abstract = Record.readInt();
|
|
|
|
Data.IsStandardLayout = Record.readInt();
|
2018-04-06 02:55:37 +08:00
|
|
|
Data.IsCXX11StandardLayout = Record.readInt();
|
|
|
|
Data.HasBasesWithFields = Record.readInt();
|
|
|
|
Data.HasBasesWithNonStaticDataMembers = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.HasPrivateFields = Record.readInt();
|
|
|
|
Data.HasProtectedFields = Record.readInt();
|
|
|
|
Data.HasPublicFields = Record.readInt();
|
|
|
|
Data.HasMutableFields = Record.readInt();
|
|
|
|
Data.HasVariantMembers = Record.readInt();
|
|
|
|
Data.HasOnlyCMembers = Record.readInt();
|
|
|
|
Data.HasInClassInitializer = Record.readInt();
|
|
|
|
Data.HasUninitializedReferenceMember = Record.readInt();
|
|
|
|
Data.HasUninitializedFields = Record.readInt();
|
|
|
|
Data.HasInheritedConstructor = Record.readInt();
|
|
|
|
Data.HasInheritedAssignment = Record.readInt();
|
PR19668, PR23034: Fix handling of move constructors and deleted copy
constructors when deciding whether classes should be passed indirectly.
This fixes ABI differences between Clang and GCC:
* Previously, Clang ignored the move constructor when making this
determination. It now takes the move constructor into account, per
https://github.com/itanium-cxx-abi/cxx-abi/pull/17 (this change may
seem recent, but the ABI change was agreed on the Itanium C++ ABI
list a long time ago).
* Previously, Clang's behavior when the copy constructor was deleted
was unstable -- depending on whether the lazy declaration of the
copy constructor had been triggered, you might get different behavior.
We now eagerly declare the copy constructor whenever its deletedness
is unclear, and ignore deleted copy/move constructors when looking for
a trivial such constructor.
This also fixes an ABI difference between Clang and MSVC:
* If the copy constructor would be implicitly deleted (but has not been
lazily declared yet), for instance because the class has an rvalue
reference member, we would pass it directly. We now pass such a class
indirectly, matching MSVC.
Based on a patch by Vassil Vassilev, which was based on a patch by Bernd
Schmidt, which was based on a patch by Reid Kleckner!
This is a re-commit of r310401, which was reverted in r310464 due to ARM
failures (which should now be fixed).
llvm-svn: 310983
2017-08-16 09:49:53 +08:00
|
|
|
Data.NeedOverloadResolutionForCopyConstructor = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.NeedOverloadResolutionForMoveConstructor = Record.readInt();
|
|
|
|
Data.NeedOverloadResolutionForMoveAssignment = Record.readInt();
|
|
|
|
Data.NeedOverloadResolutionForDestructor = Record.readInt();
|
PR19668, PR23034: Fix handling of move constructors and deleted copy
constructors when deciding whether classes should be passed indirectly.
This fixes ABI differences between Clang and GCC:
* Previously, Clang ignored the move constructor when making this
determination. It now takes the move constructor into account, per
https://github.com/itanium-cxx-abi/cxx-abi/pull/17 (this change may
seem recent, but the ABI change was agreed on the Itanium C++ ABI
list a long time ago).
* Previously, Clang's behavior when the copy constructor was deleted
was unstable -- depending on whether the lazy declaration of the
copy constructor had been triggered, you might get different behavior.
We now eagerly declare the copy constructor whenever its deletedness
is unclear, and ignore deleted copy/move constructors when looking for
a trivial such constructor.
This also fixes an ABI difference between Clang and MSVC:
* If the copy constructor would be implicitly deleted (but has not been
lazily declared yet), for instance because the class has an rvalue
reference member, we would pass it directly. We now pass such a class
indirectly, matching MSVC.
Based on a patch by Vassil Vassilev, which was based on a patch by Bernd
Schmidt, which was based on a patch by Reid Kleckner!
This is a re-commit of r310401, which was reverted in r310464 due to ARM
failures (which should now be fixed).
llvm-svn: 310983
2017-08-16 09:49:53 +08:00
|
|
|
Data.DefaultedCopyConstructorIsDeleted = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.DefaultedMoveConstructorIsDeleted = Record.readInt();
|
|
|
|
Data.DefaultedMoveAssignmentIsDeleted = Record.readInt();
|
|
|
|
Data.DefaultedDestructorIsDeleted = Record.readInt();
|
|
|
|
Data.HasTrivialSpecialMembers = Record.readInt();
|
2018-02-06 04:23:22 +08:00
|
|
|
Data.HasTrivialSpecialMembersForCall = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.DeclaredNonTrivialSpecialMembers = Record.readInt();
|
2018-02-06 04:23:22 +08:00
|
|
|
Data.DeclaredNonTrivialSpecialMembersForCall = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.HasIrrelevantDestructor = Record.readInt();
|
|
|
|
Data.HasConstexprNonCopyMoveConstructor = Record.readInt();
|
|
|
|
Data.HasDefaultedDefaultConstructor = Record.readInt();
|
|
|
|
Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt();
|
|
|
|
Data.HasConstexprDefaultConstructor = Record.readInt();
|
|
|
|
Data.HasNonLiteralTypeFieldsOrBases = Record.readInt();
|
|
|
|
Data.ComputedVisibleConversions = Record.readInt();
|
|
|
|
Data.UserProvidedDefaultConstructor = Record.readInt();
|
|
|
|
Data.DeclaredSpecialMembers = Record.readInt();
|
C++ DR1611, 1658, 2180: implement "potentially constructed subobject" rules for special member functions.
Essentially, as a base class constructor does not construct virtual bases, such
a constructor for an abstract class does not need the corresponding base class
construction to be valid, and likewise for destructors.
This creates an awkward situation: clang will sometimes generate references to
the complete object and deleting destructors for an abstract class (it puts
them in the construction vtable for a derived class). But we can't generate a
"correct" version of these because we can't generate references to base class
constructors any more (if they're template specializations, say, we might not
have instantiated them and can't assume any other TU will emit a copy).
Fortunately, we don't need to, since no correct program can ever invoke them,
so instead emit symbols that just trap.
We should stop emitting references to these symbols, but still need to emit
definitions for compatibility.
llvm-svn: 296275
2017-02-26 07:53:05 +08:00
|
|
|
Data.ImplicitCopyConstructorCanHaveConstParamForVBase = Record.readInt();
|
|
|
|
Data.ImplicitCopyConstructorCanHaveConstParamForNonVBase = Record.readInt();
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.ImplicitCopyAssignmentHasConstParam = Record.readInt();
|
|
|
|
Data.HasDeclaredCopyConstructorWithConstParam = Record.readInt();
|
|
|
|
Data.HasDeclaredCopyAssignmentWithConstParam = Record.readInt();
|
2017-02-18 10:09:28 +08:00
|
|
|
Data.ODRHash = Record.readInt();
|
2017-04-12 05:31:00 +08:00
|
|
|
Data.HasODRHash = true;
|
2016-12-21 08:17:49 +08:00
|
|
|
|
2017-09-07 08:55:55 +08:00
|
|
|
if (Record.readInt())
|
|
|
|
Reader.DefinitionSource[D] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
2017-04-12 05:13:37 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.NumBases = Record.readInt();
|
2010-10-30 06:39:52 +08:00
|
|
|
if (Data.NumBases)
|
2016-12-16 04:53:26 +08:00
|
|
|
Data.Bases = ReadGlobalOffset();
|
2016-12-21 08:17:49 +08:00
|
|
|
Data.NumVBases = Record.readInt();
|
2010-10-30 06:39:52 +08:00
|
|
|
if (Data.NumVBases)
|
2016-12-16 04:53:26 +08:00
|
|
|
Data.VBases = ReadGlobalOffset();
|
|
|
|
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readUnresolvedSet(Data.Conversions);
|
|
|
|
Record.readUnresolvedSet(Data.VisibleConversions);
|
2010-10-25 01:26:27 +08:00
|
|
|
assert(Data.Definition && "Data.Definition should be already set!");
|
2016-12-16 04:53:26 +08:00
|
|
|
Data.FirstFriend = ReadDeclID();
|
2013-08-30 08:23:29 +08:00
|
|
|
|
2012-02-15 01:54:36 +08:00
|
|
|
if (Data.IsLambda) {
|
2018-04-12 04:57:28 +08:00
|
|
|
using Capture = LambdaCapture;
|
|
|
|
|
|
|
|
auto &Lambda = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data);
|
2016-12-21 08:17:49 +08:00
|
|
|
Lambda.Dependent = Record.readInt();
|
|
|
|
Lambda.IsGenericLambda = Record.readInt();
|
|
|
|
Lambda.CaptureDefault = Record.readInt();
|
|
|
|
Lambda.NumCaptures = Record.readInt();
|
|
|
|
Lambda.NumExplicitCaptures = Record.readInt();
|
|
|
|
Lambda.ManglingNumber = Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
Lambda.ContextDecl = ReadDeclID();
|
2017-06-30 07:23:46 +08:00
|
|
|
Lambda.Captures = (Capture *)Reader.getContext().Allocate(
|
|
|
|
sizeof(Capture) * Lambda.NumCaptures);
|
2012-02-15 01:54:36 +08:00
|
|
|
Capture *ToCapture = Lambda.Captures;
|
2016-12-16 04:53:26 +08:00
|
|
|
Lambda.MethodTyInfo = GetTypeSourceInfo();
|
2012-02-15 01:54:36 +08:00
|
|
|
for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation Loc = ReadSourceLocation();
|
2016-12-21 08:17:49 +08:00
|
|
|
bool IsImplicit = Record.readInt();
|
2018-04-12 04:57:28 +08:00
|
|
|
auto Kind = static_cast<LambdaCaptureKind>(Record.readInt());
|
2013-05-16 14:20:58 +08:00
|
|
|
switch (Kind) {
|
2018-07-31 03:24:48 +08:00
|
|
|
case LCK_StarThis:
|
2013-05-16 14:20:58 +08:00
|
|
|
case LCK_This:
|
2014-08-28 12:28:19 +08:00
|
|
|
case LCK_VLAType:
|
2014-05-22 13:54:18 +08:00
|
|
|
*ToCapture++ = Capture(Loc, IsImplicit, Kind, nullptr,SourceLocation());
|
2013-05-16 14:20:58 +08:00
|
|
|
break;
|
|
|
|
case LCK_ByCopy:
|
2013-09-28 12:02:39 +08:00
|
|
|
case LCK_ByRef:
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Var = ReadDeclAs<VarDecl>();
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation EllipsisLoc = ReadSourceLocation();
|
2013-05-16 14:20:58 +08:00
|
|
|
*ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc);
|
|
|
|
break;
|
|
|
|
}
|
2012-02-15 01:54:36 +08:00
|
|
|
}
|
|
|
|
}
|
2010-10-25 01:26:27 +08:00
|
|
|
}
|
|
|
|
|
2014-04-19 11:48:30 +08:00
|
|
|
void ASTDeclReader::MergeDefinitionData(
|
2015-01-24 09:07:20 +08:00
|
|
|
CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &&MergeDD) {
|
2016-05-18 06:44:15 +08:00
|
|
|
assert(D->DefinitionData &&
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
"merging class definition into non-definition");
|
2016-05-18 06:44:15 +08:00
|
|
|
auto &DD = *D->DefinitionData;
|
2014-04-19 11:48:30 +08:00
|
|
|
|
2015-03-28 05:16:39 +08:00
|
|
|
if (DD.Definition != MergeDD.Definition) {
|
2015-06-20 08:22:34 +08:00
|
|
|
// Track that we merged the definitions.
|
|
|
|
Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
|
|
|
|
DD.Definition));
|
|
|
|
Reader.PendingDefinitions.erase(MergeDD.Definition);
|
2018-08-02 04:48:16 +08:00
|
|
|
MergeDD.Definition->setCompleteDefinition(false);
|
2016-09-13 05:06:40 +08:00
|
|
|
Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
|
2015-09-02 04:35:42 +08:00
|
|
|
assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
|
|
|
|
"already loaded pending lookups for merged definition");
|
2015-03-28 05:16:39 +08:00
|
|
|
}
|
|
|
|
|
2015-02-03 11:32:14 +08:00
|
|
|
auto PFDI = Reader.PendingFakeDefinitionData.find(&DD);
|
|
|
|
if (PFDI != Reader.PendingFakeDefinitionData.end() &&
|
|
|
|
PFDI->second == ASTReader::PendingFakeDefinitionKind::Fake) {
|
2015-01-24 09:07:20 +08:00
|
|
|
// We faked up this definition data because we found a class for which we'd
|
|
|
|
// not yet loaded the definition. Replace it with the real thing now.
|
|
|
|
assert(!DD.IsLambda && !MergeDD.IsLambda && "faked up lambda definition?");
|
2015-02-03 11:32:14 +08:00
|
|
|
PFDI->second = ASTReader::PendingFakeDefinitionKind::FakeLoaded;
|
2015-01-24 09:07:20 +08:00
|
|
|
|
|
|
|
// Don't change which declaration is the definition; that is required
|
|
|
|
// to be invariant once we select it.
|
|
|
|
auto *Def = DD.Definition;
|
|
|
|
DD = std::move(MergeDD);
|
|
|
|
DD.Definition = Def;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-19 11:48:30 +08:00
|
|
|
// FIXME: Move this out into a .def file?
|
|
|
|
bool DetectedOdrViolation = false;
|
|
|
|
#define OR_FIELD(Field) DD.Field |= MergeDD.Field;
|
|
|
|
#define MATCH_FIELD(Field) \
|
|
|
|
DetectedOdrViolation |= DD.Field != MergeDD.Field; \
|
|
|
|
OR_FIELD(Field)
|
|
|
|
MATCH_FIELD(UserDeclaredConstructor)
|
|
|
|
MATCH_FIELD(UserDeclaredSpecialMembers)
|
|
|
|
MATCH_FIELD(Aggregate)
|
|
|
|
MATCH_FIELD(PlainOldData)
|
|
|
|
MATCH_FIELD(Empty)
|
|
|
|
MATCH_FIELD(Polymorphic)
|
|
|
|
MATCH_FIELD(Abstract)
|
|
|
|
MATCH_FIELD(IsStandardLayout)
|
2018-04-06 02:55:37 +08:00
|
|
|
MATCH_FIELD(IsCXX11StandardLayout)
|
|
|
|
MATCH_FIELD(HasBasesWithFields)
|
|
|
|
MATCH_FIELD(HasBasesWithNonStaticDataMembers)
|
2014-04-19 11:48:30 +08:00
|
|
|
MATCH_FIELD(HasPrivateFields)
|
|
|
|
MATCH_FIELD(HasProtectedFields)
|
|
|
|
MATCH_FIELD(HasPublicFields)
|
|
|
|
MATCH_FIELD(HasMutableFields)
|
|
|
|
MATCH_FIELD(HasVariantMembers)
|
|
|
|
MATCH_FIELD(HasOnlyCMembers)
|
|
|
|
MATCH_FIELD(HasInClassInitializer)
|
|
|
|
MATCH_FIELD(HasUninitializedReferenceMember)
|
2016-02-19 09:52:46 +08:00
|
|
|
MATCH_FIELD(HasUninitializedFields)
|
2016-05-13 14:47:56 +08:00
|
|
|
MATCH_FIELD(HasInheritedConstructor)
|
|
|
|
MATCH_FIELD(HasInheritedAssignment)
|
PR19668, PR23034: Fix handling of move constructors and deleted copy
constructors when deciding whether classes should be passed indirectly.
This fixes ABI differences between Clang and GCC:
* Previously, Clang ignored the move constructor when making this
determination. It now takes the move constructor into account, per
https://github.com/itanium-cxx-abi/cxx-abi/pull/17 (this change may
seem recent, but the ABI change was agreed on the Itanium C++ ABI
list a long time ago).
* Previously, Clang's behavior when the copy constructor was deleted
was unstable -- depending on whether the lazy declaration of the
copy constructor had been triggered, you might get different behavior.
We now eagerly declare the copy constructor whenever its deletedness
is unclear, and ignore deleted copy/move constructors when looking for
a trivial such constructor.
This also fixes an ABI difference between Clang and MSVC:
* If the copy constructor would be implicitly deleted (but has not been
lazily declared yet), for instance because the class has an rvalue
reference member, we would pass it directly. We now pass such a class
indirectly, matching MSVC.
Based on a patch by Vassil Vassilev, which was based on a patch by Bernd
Schmidt, which was based on a patch by Reid Kleckner!
This is a re-commit of r310401, which was reverted in r310464 due to ARM
failures (which should now be fixed).
llvm-svn: 310983
2017-08-16 09:49:53 +08:00
|
|
|
MATCH_FIELD(NeedOverloadResolutionForCopyConstructor)
|
2014-04-19 11:48:30 +08:00
|
|
|
MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
|
|
|
|
MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
|
|
|
|
MATCH_FIELD(NeedOverloadResolutionForDestructor)
|
PR19668, PR23034: Fix handling of move constructors and deleted copy
constructors when deciding whether classes should be passed indirectly.
This fixes ABI differences between Clang and GCC:
* Previously, Clang ignored the move constructor when making this
determination. It now takes the move constructor into account, per
https://github.com/itanium-cxx-abi/cxx-abi/pull/17 (this change may
seem recent, but the ABI change was agreed on the Itanium C++ ABI
list a long time ago).
* Previously, Clang's behavior when the copy constructor was deleted
was unstable -- depending on whether the lazy declaration of the
copy constructor had been triggered, you might get different behavior.
We now eagerly declare the copy constructor whenever its deletedness
is unclear, and ignore deleted copy/move constructors when looking for
a trivial such constructor.
This also fixes an ABI difference between Clang and MSVC:
* If the copy constructor would be implicitly deleted (but has not been
lazily declared yet), for instance because the class has an rvalue
reference member, we would pass it directly. We now pass such a class
indirectly, matching MSVC.
Based on a patch by Vassil Vassilev, which was based on a patch by Bernd
Schmidt, which was based on a patch by Reid Kleckner!
This is a re-commit of r310401, which was reverted in r310464 due to ARM
failures (which should now be fixed).
llvm-svn: 310983
2017-08-16 09:49:53 +08:00
|
|
|
MATCH_FIELD(DefaultedCopyConstructorIsDeleted)
|
2014-04-19 11:48:30 +08:00
|
|
|
MATCH_FIELD(DefaultedMoveConstructorIsDeleted)
|
|
|
|
MATCH_FIELD(DefaultedMoveAssignmentIsDeleted)
|
|
|
|
MATCH_FIELD(DefaultedDestructorIsDeleted)
|
|
|
|
OR_FIELD(HasTrivialSpecialMembers)
|
2018-02-06 04:23:22 +08:00
|
|
|
OR_FIELD(HasTrivialSpecialMembersForCall)
|
2014-04-19 11:48:30 +08:00
|
|
|
OR_FIELD(DeclaredNonTrivialSpecialMembers)
|
2018-02-06 04:23:22 +08:00
|
|
|
OR_FIELD(DeclaredNonTrivialSpecialMembersForCall)
|
2014-04-19 11:48:30 +08:00
|
|
|
MATCH_FIELD(HasIrrelevantDestructor)
|
|
|
|
OR_FIELD(HasConstexprNonCopyMoveConstructor)
|
2016-02-25 04:58:14 +08:00
|
|
|
OR_FIELD(HasDefaultedDefaultConstructor)
|
2014-04-19 11:48:30 +08:00
|
|
|
MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
|
|
|
|
OR_FIELD(HasConstexprDefaultConstructor)
|
|
|
|
MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)
|
|
|
|
// ComputedVisibleConversions is handled below.
|
|
|
|
MATCH_FIELD(UserProvidedDefaultConstructor)
|
|
|
|
OR_FIELD(DeclaredSpecialMembers)
|
C++ DR1611, 1658, 2180: implement "potentially constructed subobject" rules for special member functions.
Essentially, as a base class constructor does not construct virtual bases, such
a constructor for an abstract class does not need the corresponding base class
construction to be valid, and likewise for destructors.
This creates an awkward situation: clang will sometimes generate references to
the complete object and deleting destructors for an abstract class (it puts
them in the construction vtable for a derived class). But we can't generate a
"correct" version of these because we can't generate references to base class
constructors any more (if they're template specializations, say, we might not
have instantiated them and can't assume any other TU will emit a copy).
Fortunately, we don't need to, since no correct program can ever invoke them,
so instead emit symbols that just trap.
We should stop emitting references to these symbols, but still need to emit
definitions for compatibility.
llvm-svn: 296275
2017-02-26 07:53:05 +08:00
|
|
|
MATCH_FIELD(ImplicitCopyConstructorCanHaveConstParamForVBase)
|
|
|
|
MATCH_FIELD(ImplicitCopyConstructorCanHaveConstParamForNonVBase)
|
2014-04-19 11:48:30 +08:00
|
|
|
MATCH_FIELD(ImplicitCopyAssignmentHasConstParam)
|
|
|
|
OR_FIELD(HasDeclaredCopyConstructorWithConstParam)
|
|
|
|
OR_FIELD(HasDeclaredCopyAssignmentWithConstParam)
|
|
|
|
MATCH_FIELD(IsLambda)
|
|
|
|
#undef OR_FIELD
|
|
|
|
#undef MATCH_FIELD
|
|
|
|
|
|
|
|
if (DD.NumBases != MergeDD.NumBases || DD.NumVBases != MergeDD.NumVBases)
|
|
|
|
DetectedOdrViolation = true;
|
|
|
|
// FIXME: Issue a diagnostic if the base classes don't match when we come
|
|
|
|
// to lazily load them.
|
|
|
|
|
|
|
|
// FIXME: Issue a diagnostic if the list of conversion functions doesn't
|
|
|
|
// match when we come to lazily load them.
|
|
|
|
if (MergeDD.ComputedVisibleConversions && !DD.ComputedVisibleConversions) {
|
|
|
|
DD.VisibleConversions = std::move(MergeDD.VisibleConversions);
|
|
|
|
DD.ComputedVisibleConversions = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Issue a diagnostic if FirstFriend doesn't match when we come to
|
|
|
|
// lazily load it.
|
|
|
|
|
|
|
|
if (DD.IsLambda) {
|
|
|
|
// FIXME: ODR-checking for merging lambdas (this happens, for instance,
|
|
|
|
// when they occur within the body of a function template specialization).
|
|
|
|
}
|
|
|
|
|
2017-04-12 05:31:00 +08:00
|
|
|
if (D->getODRHash() != MergeDD.ODRHash) {
|
|
|
|
DetectedOdrViolation = true;
|
|
|
|
}
|
|
|
|
|
2014-04-19 11:48:30 +08:00
|
|
|
if (DetectedOdrViolation)
|
2017-09-30 10:19:17 +08:00
|
|
|
Reader.PendingOdrMergeFailures[DD.Definition].push_back(
|
|
|
|
{MergeDD.Definition, &MergeDD});
|
2014-04-19 11:48:30 +08:00
|
|
|
}
|
|
|
|
|
2015-02-03 11:32:14 +08:00
|
|
|
void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update) {
|
2014-04-19 11:48:30 +08:00
|
|
|
struct CXXRecordDecl::DefinitionData *DD;
|
|
|
|
ASTContext &C = Reader.getContext();
|
|
|
|
|
|
|
|
// Determine whether this is a lambda closure type, so that we can
|
|
|
|
// allocate the appropriate DefinitionData structure.
|
2016-12-21 08:17:49 +08:00
|
|
|
bool IsLambda = Record.readInt();
|
2014-04-19 11:48:30 +08:00
|
|
|
if (IsLambda)
|
2014-05-22 13:54:18 +08:00
|
|
|
DD = new (C) CXXRecordDecl::LambdaDefinitionData(D, nullptr, false, false,
|
2014-04-19 11:48:30 +08:00
|
|
|
LCD_None);
|
|
|
|
else
|
|
|
|
DD = new (C) struct CXXRecordDecl::DefinitionData(D);
|
|
|
|
|
2018-03-22 05:28:54 +08:00
|
|
|
CXXRecordDecl *Canon = D->getCanonicalDecl();
|
|
|
|
// Set decl definition data before reading it, so that during deserialization
|
|
|
|
// when we read CXXRecordDecl, it already has definition data and we don't
|
|
|
|
// set fake one.
|
|
|
|
if (!Canon->DefinitionData)
|
|
|
|
Canon->DefinitionData = DD;
|
|
|
|
D->DefinitionData = Canon->DefinitionData;
|
2017-04-12 05:13:37 +08:00
|
|
|
ReadCXXDefinitionData(*DD, D);
|
2014-04-19 11:48:30 +08:00
|
|
|
|
2018-03-22 05:28:54 +08:00
|
|
|
// We might already have a different definition for this record. This can
|
|
|
|
// happen either because we're reading an update record, or because we've
|
|
|
|
// already done some merging. Either way, just merge into it.
|
|
|
|
if (Canon->DefinitionData != DD) {
|
2015-01-24 09:07:20 +08:00
|
|
|
MergeDefinitionData(Canon, std::move(*DD));
|
2014-04-19 11:48:30 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-06-20 08:22:34 +08:00
|
|
|
// Mark this declaration as being a definition.
|
2018-08-02 04:48:16 +08:00
|
|
|
D->setCompleteDefinition(true);
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
|
2015-06-20 08:22:34 +08:00
|
|
|
// If this is not the first declaration or is an update record, we can have
|
|
|
|
// other redeclarations already. Make a note that we need to propagate the
|
|
|
|
// DefinitionData pointer onto them.
|
2018-03-22 05:28:54 +08:00
|
|
|
if (Update || Canon != D)
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
Reader.PendingDefinitions.insert(D);
|
2014-04-19 11:48:30 +08:00
|
|
|
}
|
|
|
|
|
2013-05-23 09:49:11 +08:00
|
|
|
ASTDeclReader::RedeclarableResult
|
|
|
|
ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
|
|
|
|
RedeclarableResult Redecl = VisitRecordDeclImpl(D);
|
2010-10-20 08:11:15 +08:00
|
|
|
|
2012-01-16 02:17:48 +08:00
|
|
|
ASTContext &C = Reader.getContext();
|
2010-07-02 19:55:32 +08:00
|
|
|
|
2010-06-20 03:29:09 +08:00
|
|
|
enum CXXRecKind {
|
|
|
|
CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
|
|
|
|
};
|
2016-12-21 08:17:49 +08:00
|
|
|
switch ((CXXRecKind)Record.readInt()) {
|
2010-06-20 03:29:09 +08:00
|
|
|
case CXXRecNotTemplate:
|
2014-07-11 08:20:06 +08:00
|
|
|
// Merged when we merge the folding set entry in the primary template.
|
|
|
|
if (!isa<ClassTemplateSpecializationDecl>(D))
|
|
|
|
mergeRedeclarable(D, Redecl);
|
2010-06-20 03:29:09 +08:00
|
|
|
break;
|
2014-04-24 10:25:27 +08:00
|
|
|
case CXXRecTemplate: {
|
|
|
|
// Merged when we merge the template.
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Template = ReadDeclAs<ClassTemplateDecl>();
|
2014-04-24 10:25:27 +08:00
|
|
|
D->TemplateOrInstantiation = Template;
|
|
|
|
if (!Template->getTemplatedDecl()) {
|
|
|
|
// We've not actually loaded the ClassTemplateDecl yet, because we're
|
|
|
|
// currently being loaded as its pattern. Rely on it to set up our
|
|
|
|
// TypeForDecl (see VisitClassTemplateDecl).
|
|
|
|
//
|
|
|
|
// Beware: we do not yet know our canonical declaration, and may still
|
|
|
|
// get merged once the surrounding class template has got off the ground.
|
2018-07-04 10:25:38 +08:00
|
|
|
DeferredTypeID = 0;
|
2014-04-24 10:25:27 +08:00
|
|
|
}
|
2010-06-20 03:29:09 +08:00
|
|
|
break;
|
2014-04-24 10:25:27 +08:00
|
|
|
}
|
2010-06-20 03:29:09 +08:00
|
|
|
case CXXRecMemberSpecialization: {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *RD = ReadDeclAs<CXXRecordDecl>();
|
|
|
|
auto TSK = (TemplateSpecializationKind)Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation();
|
2010-09-13 19:45:25 +08:00
|
|
|
MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK);
|
|
|
|
MSI->setPointOfInstantiation(POI);
|
|
|
|
D->TemplateOrInstantiation = MSI;
|
2014-04-19 11:48:30 +08:00
|
|
|
mergeRedeclarable(D, Redecl);
|
2010-06-20 03:29:09 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-10-15 04:14:38 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
bool WasDefinition = Record.readInt();
|
2014-04-19 11:48:30 +08:00
|
|
|
if (WasDefinition)
|
2015-02-03 11:32:14 +08:00
|
|
|
ReadCXXRecordDefinition(D, /*Update*/false);
|
2014-04-19 11:48:30 +08:00
|
|
|
else
|
|
|
|
// Propagate DefinitionData pointer from the canonical declaration.
|
|
|
|
D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
|
|
|
|
|
2013-08-30 07:59:27 +08:00
|
|
|
// Lazily load the key function to avoid deserializing every method so we can
|
2010-10-15 04:14:38 +08:00
|
|
|
// compute it.
|
2013-09-10 00:55:27 +08:00
|
|
|
if (WasDefinition) {
|
2016-12-16 04:53:26 +08:00
|
|
|
DeclID KeyFn = ReadDeclID();
|
2018-08-02 04:48:16 +08:00
|
|
|
if (KeyFn && D->isCompleteDefinition())
|
2014-07-07 14:38:20 +08:00
|
|
|
// FIXME: This is wrong for the ARM ABI, where some other module may have
|
|
|
|
// made this function no longer be a key function. We need an update
|
|
|
|
// record or similar for that case.
|
2013-08-30 07:59:27 +08:00
|
|
|
C.KeyFunctions[D] = KeyFn;
|
2010-10-15 04:14:38 +08:00
|
|
|
}
|
2013-05-23 09:49:11 +08:00
|
|
|
|
|
|
|
return Redecl;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2017-02-18 04:05:37 +08:00
|
|
|
void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
|
|
|
|
VisitFunctionDecl(D);
|
2018-08-02 05:02:40 +08:00
|
|
|
D->setIsCopyDeductionCandidate(Record.readInt());
|
2017-02-18 04:05:37 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitFunctionDecl(D);
|
2014-08-27 07:29:11 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumOverridenMethods = Record.readInt();
|
2014-08-27 07:29:11 +08:00
|
|
|
if (D->isCanonicalDecl()) {
|
|
|
|
while (NumOverridenMethods--) {
|
|
|
|
// Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
|
|
|
|
// MD may be initializing.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *MD = ReadDeclAs<CXXMethodDecl>())
|
2014-08-27 07:29:11 +08:00
|
|
|
Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// We don't care about which declarations this used to override; we get
|
|
|
|
// the relevant information from the canonical declaration.
|
2016-12-21 08:17:49 +08:00
|
|
|
Record.skipInts(NumOverridenMethods);
|
2010-07-05 05:44:35 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
// We need the inherited constructor information to merge the declaration,
|
|
|
|
// so we have to read it before we call VisitCXXMethodDecl.
|
|
|
|
if (D->isInheritingConstructor()) {
|
2016-12-16 04:53:26 +08:00
|
|
|
auto *Shadow = ReadDeclAs<ConstructorUsingShadowDecl>();
|
|
|
|
auto *Ctor = ReadDeclAs<CXXConstructorDecl>();
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
*D->getTrailingObjects<InheritedConstructor>() =
|
|
|
|
InheritedConstructor(Shadow, Ctor);
|
|
|
|
}
|
|
|
|
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
2010-07-02 23:58:43 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
if (auto *OperatorDelete = ReadDeclAs<FunctionDecl>()) {
|
2018-03-01 13:43:23 +08:00
|
|
|
CXXDestructorDecl *Canon = D->getCanonicalDecl();
|
2017-10-13 09:55:36 +08:00
|
|
|
auto *ThisArg = Record.readExpr();
|
2015-03-10 09:41:22 +08:00
|
|
|
// FIXME: Check consistency if we have an old and new operator delete.
|
2017-10-13 09:55:36 +08:00
|
|
|
if (!Canon->OperatorDelete) {
|
2015-03-10 09:41:22 +08:00
|
|
|
Canon->OperatorDelete = OperatorDelete;
|
2017-10-13 09:55:36 +08:00
|
|
|
Canon->OperatorDeleteThisArg = ThisArg;
|
|
|
|
}
|
2015-03-10 09:41:22 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
|
|
|
}
|
|
|
|
|
2011-12-03 07:23:56 +08:00
|
|
|
void ASTDeclReader::VisitImportDecl(ImportDecl *D) {
|
|
|
|
VisitDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->ImportedAndComplete.setPointer(readModule());
|
2016-12-21 08:17:49 +08:00
|
|
|
D->ImportedAndComplete.setInt(Record.readInt());
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *StoredLocs = D->getTrailingObjects<SourceLocation>();
|
2011-12-03 07:23:56 +08:00
|
|
|
for (unsigned I = 0, N = Record.back(); I != N; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
StoredLocs[I] = ReadSourceLocation();
|
2017-01-24 09:04:30 +08:00
|
|
|
Record.skipInts(1); // The number of stored source locations.
|
2011-12-03 07:23:56 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
|
2010-06-05 13:09:32 +08:00
|
|
|
VisitDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setColonLoc(ReadSourceLocation());
|
2010-06-05 13:09:32 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
|
2010-07-05 18:38:01 +08:00
|
|
|
VisitDecl(D);
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) // hasFriendDecl
|
2016-12-16 04:53:26 +08:00
|
|
|
D->Friend = ReadDeclAs<NamedDecl>();
|
2013-01-31 17:54:08 +08:00
|
|
|
else
|
2016-12-16 04:53:26 +08:00
|
|
|
D->Friend = GetTypeSourceInfo();
|
2013-01-31 17:54:08 +08:00
|
|
|
for (unsigned i = 0; i != D->NumTPLists; ++i)
|
2015-12-30 06:13:13 +08:00
|
|
|
D->getTrailingObjects<TemplateParameterList *>()[i] =
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readTemplateParameterList();
|
2016-12-16 04:53:26 +08:00
|
|
|
D->NextFriend = ReadDeclID();
|
2016-12-21 08:17:49 +08:00
|
|
|
D->UnsupportedFriend = (Record.readInt() != 0);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->FriendLoc = ReadSourceLocation();
|
2010-06-30 06:47:00 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
|
2010-07-23 00:04:10 +08:00
|
|
|
VisitDecl(D);
|
2016-12-21 08:17:49 +08:00
|
|
|
unsigned NumParams = Record.readInt();
|
2010-07-23 00:04:10 +08:00
|
|
|
D->NumParams = NumParams;
|
|
|
|
D->Params = new TemplateParameterList*[NumParams];
|
|
|
|
for (unsigned i = 0; i != NumParams; ++i)
|
2016-12-21 12:34:52 +08:00
|
|
|
D->Params[i] = Record.readTemplateParameterList();
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) // HasFriendDecl
|
2016-12-16 04:53:26 +08:00
|
|
|
D->Friend = ReadDeclAs<NamedDecl>();
|
2010-07-23 00:04:10 +08:00
|
|
|
else
|
2016-12-16 04:53:26 +08:00
|
|
|
D->Friend = GetTypeSourceInfo();
|
|
|
|
D->FriendLoc = ReadSourceLocation();
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2014-04-24 10:25:27 +08:00
|
|
|
DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
|
2010-06-20 03:29:09 +08:00
|
|
|
VisitNamedDecl(D);
|
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
DeclID PatternID = ReadDeclID();
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID));
|
2016-12-21 12:34:52 +08:00
|
|
|
TemplateParameterList *TemplateParams = Record.readTemplateParameterList();
|
2017-02-10 10:46:19 +08:00
|
|
|
// FIXME handle associated constraints
|
2010-06-20 03:29:09 +08:00
|
|
|
D->init(TemplatedDecl, TemplateParams);
|
2013-06-25 06:51:00 +08:00
|
|
|
|
2014-04-24 10:25:27 +08:00
|
|
|
return PatternID;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
ASTDeclReader::RedeclarableResult
|
2012-01-07 06:05:37 +08:00
|
|
|
ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
|
2012-01-14 23:13:49 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarable(D);
|
2011-12-20 02:19:24 +08:00
|
|
|
|
2012-01-14 23:13:49 +08:00
|
|
|
// Make sure we've allocated the Common pointer first. We do this before
|
|
|
|
// VisitTemplateDecl so that getCommonPtr() can be used during initialization.
|
|
|
|
RedeclarableTemplateDecl *CanonD = D->getCanonicalDecl();
|
|
|
|
if (!CanonD->Common) {
|
|
|
|
CanonD->Common = CanonD->newCommon(Reader.getContext());
|
|
|
|
Reader.PendingDefinitions.insert(CanonD);
|
|
|
|
}
|
|
|
|
D->Common = CanonD->Common;
|
2011-12-22 09:48:48 +08:00
|
|
|
|
2012-01-14 23:13:49 +08:00
|
|
|
// If this is the first declaration of the template, fill in the information
|
|
|
|
// for the 'common' pointer.
|
|
|
|
if (ThisDeclID == Redecl.getFirstID()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *RTD = ReadDeclAs<RedeclarableTemplateDecl>()) {
|
2010-07-30 00:11:51 +08:00
|
|
|
assert(RTD->getKind() == D->getKind() &&
|
|
|
|
"InstantiatedFromMemberTemplate kind mismatch");
|
2012-01-14 23:13:49 +08:00
|
|
|
D->setInstantiatedFromMemberTemplate(RTD);
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt())
|
2010-07-30 00:11:51 +08:00
|
|
|
D->setMemberSpecialization();
|
|
|
|
}
|
|
|
|
}
|
2012-10-01 17:18:00 +08:00
|
|
|
|
2014-04-24 10:25:27 +08:00
|
|
|
DeclID PatternID = VisitTemplateDecl(D);
|
2016-12-21 08:17:49 +08:00
|
|
|
D->IdentifierNamespace = Record.readInt();
|
2012-10-01 17:18:00 +08:00
|
|
|
|
2014-04-24 10:25:27 +08:00
|
|
|
mergeRedeclarable(D, Redecl, PatternID);
|
2012-10-01 17:18:00 +08:00
|
|
|
|
2013-10-14 07:50:45 +08:00
|
|
|
// If we merged the template with a prior declaration chain, merge the common
|
|
|
|
// pointer.
|
|
|
|
// FIXME: Actually merge here, don't just overwrite.
|
|
|
|
D->Common = D->getCanonicalDecl()->Common;
|
|
|
|
|
2012-01-14 23:13:49 +08:00
|
|
|
return Redecl;
|
2010-07-30 00:11:51 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
2012-01-14 23:13:49 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
|
2010-07-30 00:11:51 +08:00
|
|
|
|
2012-01-14 23:13:49 +08:00
|
|
|
if (ThisDeclID == Redecl.getFirstID()) {
|
2010-10-28 06:21:36 +08:00
|
|
|
// This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
|
|
|
|
// the specializations.
|
2015-02-27 08:25:58 +08:00
|
|
|
SmallVector<serialization::DeclID, 32> SpecIDs;
|
|
|
|
ReadDeclIDList(SpecIDs);
|
2017-07-01 06:40:17 +08:00
|
|
|
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
2010-06-20 03:29:09 +08:00
|
|
|
}
|
2014-04-24 10:25:27 +08:00
|
|
|
|
|
|
|
if (D->getTemplatedDecl()->TemplateOrInstantiation) {
|
|
|
|
// We were loaded before our templated declaration was. We've not set up
|
|
|
|
// its corresponding type yet (see VisitCXXRecordDeclImpl), so reconstruct
|
|
|
|
// it now.
|
2017-06-30 07:23:46 +08:00
|
|
|
Reader.getContext().getInjectedClassNameType(
|
2014-05-24 05:31:59 +08:00
|
|
|
D->getTemplatedDecl(), D->getInjectedClassNameSpecialization());
|
2014-04-24 10:25:27 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2015-11-04 11:40:30 +08:00
|
|
|
void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
|
|
|
|
llvm_unreachable("BuiltinTemplates are not serialized");
|
|
|
|
}
|
|
|
|
|
2013-08-24 06:21:36 +08:00
|
|
|
/// TODO: Unify with ClassTemplateDecl version?
|
|
|
|
/// May require unifying ClassTemplateDecl and
|
|
|
|
/// VarTemplateDecl beyond TemplateDecl...
|
2013-08-06 09:03:05 +08:00
|
|
|
void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
|
|
|
|
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
|
|
|
|
|
|
|
|
if (ThisDeclID == Redecl.getFirstID()) {
|
2013-08-14 11:09:19 +08:00
|
|
|
// This VarTemplateDecl owns a CommonPtr; read it to keep track of all of
|
2013-08-06 09:03:05 +08:00
|
|
|
// the specializations.
|
2015-02-27 08:25:58 +08:00
|
|
|
SmallVector<serialization::DeclID, 32> SpecIDs;
|
|
|
|
ReadDeclIDList(SpecIDs);
|
2017-07-01 06:40:17 +08:00
|
|
|
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
2013-08-06 09:03:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-23 09:49:11 +08:00
|
|
|
ASTDeclReader::RedeclarableResult
|
|
|
|
ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
|
|
|
|
ClassTemplateSpecializationDecl *D) {
|
|
|
|
RedeclarableResult Redecl = VisitCXXRecordDeclImpl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
ASTContext &C = Reader.getContext();
|
2016-12-16 04:53:26 +08:00
|
|
|
if (Decl *InstD = ReadDecl()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
|
2010-09-13 19:45:32 +08:00
|
|
|
D->SpecializedTemplate = CTD;
|
2010-06-23 21:48:30 +08:00
|
|
|
} else {
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readTemplateArgumentList(TemplArgs);
|
2010-09-13 19:45:32 +08:00
|
|
|
TemplateArgumentList *ArgList
|
2016-07-04 05:17:51 +08:00
|
|
|
= TemplateArgumentList::CreateCopy(C, TemplArgs);
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *PS =
|
|
|
|
new (C) ClassTemplateSpecializationDecl::
|
2010-09-13 19:45:32 +08:00
|
|
|
SpecializedPartialSpecialization();
|
|
|
|
PS->PartialSpecialization
|
|
|
|
= cast<ClassTemplatePartialSpecializationDecl>(InstD);
|
|
|
|
PS->TemplateArgs = ArgList;
|
|
|
|
D->SpecializedTemplate = PS;
|
2010-06-23 21:48:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
|
2016-07-04 05:17:51 +08:00
|
|
|
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->PointOfInstantiation = ReadSourceLocation();
|
2016-12-21 08:17:49 +08:00
|
|
|
D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
|
2012-10-01 15:34:47 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
bool writtenAsCanonicalDecl = Record.readInt();
|
2012-10-01 15:34:47 +08:00
|
|
|
if (writtenAsCanonicalDecl) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *CanonPattern = ReadDeclAs<ClassTemplateDecl>();
|
2012-10-01 15:34:47 +08:00
|
|
|
if (D->isCanonicalDecl()) { // It's kept in the folding set.
|
2013-09-10 00:55:27 +08:00
|
|
|
// Set this as, or find, the canonical declaration for this specialization
|
|
|
|
ClassTemplateSpecializationDecl *CanonSpec;
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *Partial = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
|
2013-09-10 00:55:27 +08:00
|
|
|
CanonSpec = CanonPattern->getCommonPtr()->PartialSpecializations
|
2013-06-25 09:25:15 +08:00
|
|
|
.GetOrInsertNode(Partial);
|
2012-10-01 15:34:47 +08:00
|
|
|
} else {
|
2013-09-10 00:55:27 +08:00
|
|
|
CanonSpec =
|
|
|
|
CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D);
|
|
|
|
}
|
|
|
|
// If there was already a canonical specialization, merge into it.
|
|
|
|
if (CanonSpec != D) {
|
|
|
|
mergeRedeclarable<TagDecl>(D, CanonSpec, Redecl);
|
|
|
|
|
|
|
|
// This declaration might be a definition. Merge with any existing
|
|
|
|
// definition.
|
2016-05-18 06:44:15 +08:00
|
|
|
if (auto *DDD = D->DefinitionData) {
|
|
|
|
if (CanonSpec->DefinitionData)
|
2015-01-24 09:07:20 +08:00
|
|
|
MergeDefinitionData(CanonSpec, std::move(*DDD));
|
2015-06-20 08:22:34 +08:00
|
|
|
else
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
CanonSpec->DefinitionData = D->DefinitionData;
|
2013-09-10 00:55:27 +08:00
|
|
|
}
|
2014-07-12 02:22:58 +08:00
|
|
|
D->DefinitionData = CanonSpec->DefinitionData;
|
2012-10-01 15:34:47 +08:00
|
|
|
}
|
2010-07-10 05:11:43 +08:00
|
|
|
}
|
|
|
|
}
|
2013-05-23 09:49:11 +08:00
|
|
|
|
2013-09-10 00:55:27 +08:00
|
|
|
// Explicit info.
|
2016-12-16 04:53:26 +08:00
|
|
|
if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *ExplicitInfo =
|
|
|
|
new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo;
|
2013-09-10 00:55:27 +08:00
|
|
|
ExplicitInfo->TypeAsWritten = TyInfo;
|
2016-12-16 04:53:26 +08:00
|
|
|
ExplicitInfo->ExternLoc = ReadSourceLocation();
|
|
|
|
ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation();
|
2013-09-10 00:55:27 +08:00
|
|
|
D->ExplicitInfo = ExplicitInfo;
|
|
|
|
}
|
|
|
|
|
2013-05-23 09:49:11 +08:00
|
|
|
return Redecl;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
|
2010-05-08 05:43:38 +08:00
|
|
|
ClassTemplatePartialSpecializationDecl *D) {
|
2013-05-23 09:49:11 +08:00
|
|
|
RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
|
2010-06-23 21:48:30 +08:00
|
|
|
|
2016-12-21 12:34:52 +08:00
|
|
|
D->TemplateParams = Record.readTemplateParameterList();
|
|
|
|
D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
|
2010-09-13 19:45:41 +08:00
|
|
|
|
2010-06-23 21:48:30 +08:00
|
|
|
// These are read/set from/to the first declaration.
|
2013-05-23 09:49:11 +08:00
|
|
|
if (ThisDeclID == Redecl.getFirstID()) {
|
2010-09-13 19:45:41 +08:00
|
|
|
D->InstantiatedFromMember.setPointer(
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadDeclAs<ClassTemplatePartialSpecializationDecl>());
|
2016-12-21 08:17:49 +08:00
|
|
|
D->InstantiatedFromMember.setInt(Record.readInt());
|
2010-06-23 21:48:30 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2011-08-31 21:59:56 +08:00
|
|
|
void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
|
|
|
|
ClassScopeFunctionSpecializationDecl *D) {
|
2011-08-17 09:06:54 +08:00
|
|
|
VisitDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->Specialization = ReadDeclAs<CXXMethodDecl>();
|
2011-08-17 09:06:54 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
2012-01-14 23:13:49 +08:00
|
|
|
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
|
2010-06-22 17:55:07 +08:00
|
|
|
|
2012-01-14 23:13:49 +08:00
|
|
|
if (ThisDeclID == Redecl.getFirstID()) {
|
2010-06-22 17:55:07 +08:00
|
|
|
// This FunctionTemplateDecl owns a CommonPtr; read it.
|
2015-02-27 08:25:58 +08:00
|
|
|
SmallVector<serialization::DeclID, 32> SpecIDs;
|
|
|
|
ReadDeclIDList(SpecIDs);
|
2017-07-01 06:40:17 +08:00
|
|
|
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2013-08-24 06:21:36 +08:00
|
|
|
/// TODO: Unify with ClassTemplateSpecializationDecl version?
|
|
|
|
/// May require unifying ClassTemplate(Partial)SpecializationDecl and
|
|
|
|
/// VarTemplate(Partial)SpecializationDecl with a new data
|
|
|
|
/// structure Template(Partial)SpecializationDecl, and
|
|
|
|
/// using Template(Partial)SpecializationDecl as input type.
|
2013-08-06 09:03:05 +08:00
|
|
|
ASTDeclReader::RedeclarableResult
|
|
|
|
ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
|
|
|
|
VarTemplateSpecializationDecl *D) {
|
|
|
|
RedeclarableResult Redecl = VisitVarDeclImpl(D);
|
|
|
|
|
|
|
|
ASTContext &C = Reader.getContext();
|
2016-12-16 04:53:26 +08:00
|
|
|
if (Decl *InstD = ReadDecl()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *VTD = dyn_cast<VarTemplateDecl>(InstD)) {
|
2013-08-06 09:03:05 +08:00
|
|
|
D->SpecializedTemplate = VTD;
|
|
|
|
} else {
|
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readTemplateArgumentList(TemplArgs);
|
2013-08-06 09:03:05 +08:00
|
|
|
TemplateArgumentList *ArgList = TemplateArgumentList::CreateCopy(
|
2016-07-04 05:17:51 +08:00
|
|
|
C, TemplArgs);
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *PS =
|
2013-08-06 09:03:05 +08:00
|
|
|
new (C)
|
|
|
|
VarTemplateSpecializationDecl::SpecializedPartialSpecialization();
|
|
|
|
PS->PartialSpecialization =
|
|
|
|
cast<VarTemplatePartialSpecializationDecl>(InstD);
|
|
|
|
PS->TemplateArgs = ArgList;
|
|
|
|
D->SpecializedTemplate = PS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Explicit info.
|
2016-12-16 04:53:26 +08:00
|
|
|
if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *ExplicitInfo =
|
2013-08-06 09:03:05 +08:00
|
|
|
new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo;
|
|
|
|
ExplicitInfo->TypeAsWritten = TyInfo;
|
2016-12-16 04:53:26 +08:00
|
|
|
ExplicitInfo->ExternLoc = ReadSourceLocation();
|
|
|
|
ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation();
|
2013-08-06 09:03:05 +08:00
|
|
|
D->ExplicitInfo = ExplicitInfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
|
2016-07-04 05:17:51 +08:00
|
|
|
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->PointOfInstantiation = ReadSourceLocation();
|
2016-12-21 08:17:49 +08:00
|
|
|
D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
|
2017-12-02 10:48:42 +08:00
|
|
|
D->IsCompleteDefinition = Record.readInt();
|
2013-08-06 09:03:05 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
bool writtenAsCanonicalDecl = Record.readInt();
|
2013-08-06 09:03:05 +08:00
|
|
|
if (writtenAsCanonicalDecl) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *CanonPattern = ReadDeclAs<VarTemplateDecl>();
|
2013-08-06 09:03:05 +08:00
|
|
|
if (D->isCanonicalDecl()) { // It's kept in the folding set.
|
2015-07-27 13:40:23 +08:00
|
|
|
// FIXME: If it's already present, merge it.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *Partial = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
|
2013-08-06 09:03:05 +08:00
|
|
|
CanonPattern->getCommonPtr()->PartialSpecializations
|
|
|
|
.GetOrInsertNode(Partial);
|
|
|
|
} else {
|
|
|
|
CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Redecl;
|
|
|
|
}
|
|
|
|
|
2013-08-24 06:21:36 +08:00
|
|
|
/// TODO: Unify with ClassTemplatePartialSpecializationDecl version?
|
|
|
|
/// May require unifying ClassTemplate(Partial)SpecializationDecl and
|
|
|
|
/// VarTemplate(Partial)SpecializationDecl with a new data
|
|
|
|
/// structure Template(Partial)SpecializationDecl, and
|
|
|
|
/// using Template(Partial)SpecializationDecl as input type.
|
2013-08-06 09:03:05 +08:00
|
|
|
void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl(
|
|
|
|
VarTemplatePartialSpecializationDecl *D) {
|
|
|
|
RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D);
|
|
|
|
|
2016-12-21 12:34:52 +08:00
|
|
|
D->TemplateParams = Record.readTemplateParameterList();
|
|
|
|
D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
|
2013-08-06 09:03:05 +08:00
|
|
|
|
|
|
|
// These are read/set from/to the first declaration.
|
|
|
|
if (ThisDeclID == Redecl.getFirstID()) {
|
|
|
|
D->InstantiatedFromMember.setPointer(
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadDeclAs<VarTemplatePartialSpecializationDecl>());
|
2016-12-21 08:17:49 +08:00
|
|
|
D->InstantiatedFromMember.setInt(Record.readInt());
|
2013-08-06 09:03:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
|
2010-06-20 03:29:09 +08:00
|
|
|
VisitTypeDecl(D);
|
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setDeclaredWithTypename(Record.readInt());
|
2010-06-20 03:29:09 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt())
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setDefaultArgument(GetTypeSourceInfo());
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
|
2011-02-09 09:13:10 +08:00
|
|
|
VisitDeclaratorDecl(D);
|
2010-06-26 00:25:09 +08:00
|
|
|
// TemplateParmPosition.
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setDepth(Record.readInt());
|
|
|
|
D->setPosition(Record.readInt());
|
2011-01-20 04:10:05 +08:00
|
|
|
if (D->isExpandedParameterPack()) {
|
2015-12-30 06:13:13 +08:00
|
|
|
auto TypesAndInfos =
|
|
|
|
D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
|
2011-01-20 04:10:05 +08:00
|
|
|
for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
|
2016-12-21 08:17:49 +08:00
|
|
|
new (&TypesAndInfos[I].first) QualType(Record.readType());
|
2016-12-16 04:53:26 +08:00
|
|
|
TypesAndInfos[I].second = GetTypeSourceInfo();
|
2011-01-20 04:10:05 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Rest of NonTypeTemplateParmDecl.
|
2016-12-21 08:17:49 +08:00
|
|
|
D->ParameterPack = Record.readInt();
|
|
|
|
if (Record.readInt())
|
2016-12-21 12:34:52 +08:00
|
|
|
D->setDefaultArgument(Record.readExpr());
|
2011-01-20 04:10:05 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
|
2010-07-09 01:12:57 +08:00
|
|
|
VisitTemplateDecl(D);
|
|
|
|
// TemplateParmPosition.
|
2016-12-21 08:17:49 +08:00
|
|
|
D->setDepth(Record.readInt());
|
|
|
|
D->setPosition(Record.readInt());
|
2012-09-07 10:06:42 +08:00
|
|
|
if (D->isExpandedParameterPack()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto **Data = D->getTrailingObjects<TemplateParameterList *>();
|
2012-09-07 10:06:42 +08:00
|
|
|
for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
|
|
|
|
I != N; ++I)
|
2016-12-21 12:34:52 +08:00
|
|
|
Data[I] = Record.readTemplateParameterList();
|
2012-09-07 10:06:42 +08:00
|
|
|
} else {
|
|
|
|
// Rest of TemplateTemplateParmDecl.
|
2016-12-21 08:17:49 +08:00
|
|
|
D->ParameterPack = Record.readInt();
|
|
|
|
if (Record.readInt())
|
2015-06-10 08:29:03 +08:00
|
|
|
D->setDefaultArgument(Reader.getContext(),
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readTemplateArgumentLoc());
|
2012-09-07 10:06:42 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2011-05-06 05:57:07 +08:00
|
|
|
void ASTDeclReader::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
|
|
|
|
VisitRedeclarableTemplateDecl(D);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
|
2010-07-23 01:28:12 +08:00
|
|
|
VisitDecl(D);
|
2016-12-21 12:34:52 +08:00
|
|
|
D->AssertExprAndFailed.setPointer(Record.readExpr());
|
2016-12-21 08:17:49 +08:00
|
|
|
D->AssertExprAndFailed.setInt(Record.readInt());
|
2016-12-21 12:34:52 +08:00
|
|
|
D->Message = cast_or_null<StringLiteral>(Record.readExpr());
|
2016-12-16 04:53:26 +08:00
|
|
|
D->RParenLoc = ReadSourceLocation();
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2013-02-23 01:15:32 +08:00
|
|
|
void ASTDeclReader::VisitEmptyDecl(EmptyDecl *D) {
|
|
|
|
VisitDecl(D);
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
std::pair<uint64_t, uint64_t>
|
2010-08-19 07:56:48 +08:00
|
|
|
ASTDeclReader::VisitDeclContext(DeclContext *DC) {
|
2016-12-16 04:53:26 +08:00
|
|
|
uint64_t LexicalOffset = ReadLocalOffset();
|
|
|
|
uint64_t VisibleOffset = ReadLocalOffset();
|
2009-04-27 13:27:42 +08:00
|
|
|
return std::make_pair(LexicalOffset, VisibleOffset);
|
|
|
|
}
|
|
|
|
|
2010-08-04 01:30:10 +08:00
|
|
|
template <typename T>
|
2015-02-06 10:42:59 +08:00
|
|
|
ASTDeclReader::RedeclarableResult
|
2011-12-22 09:48:48 +08:00
|
|
|
ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
|
2016-12-16 04:53:26 +08:00
|
|
|
DeclID FirstDeclID = ReadDeclID();
|
2015-02-06 10:42:59 +08:00
|
|
|
Decl *MergeWith = nullptr;
|
2015-08-22 09:47:18 +08:00
|
|
|
|
2015-07-13 07:43:21 +08:00
|
|
|
bool IsKeyDecl = ThisDeclID == FirstDeclID;
|
2015-08-22 09:47:18 +08:00
|
|
|
bool IsFirstLocalDecl = false;
|
2015-02-06 10:42:59 +08:00
|
|
|
|
2015-08-23 04:13:39 +08:00
|
|
|
uint64_t RedeclOffset = 0;
|
|
|
|
|
2012-01-16 00:58:34 +08:00
|
|
|
// 0 indicates that this declaration was the only declaration of its entity,
|
|
|
|
// and is used for space optimization.
|
2015-07-13 07:43:21 +08:00
|
|
|
if (FirstDeclID == 0) {
|
2011-12-20 02:19:24 +08:00
|
|
|
FirstDeclID = ThisDeclID;
|
2015-07-13 07:43:21 +08:00
|
|
|
IsKeyDecl = true;
|
2015-08-22 09:47:18 +08:00
|
|
|
IsFirstLocalDecl = true;
|
2016-12-21 08:17:49 +08:00
|
|
|
} else if (unsigned N = Record.readInt()) {
|
2015-08-22 09:47:18 +08:00
|
|
|
// This declaration was the first local declaration, but may have imported
|
|
|
|
// other declarations.
|
|
|
|
IsKeyDecl = N == 1;
|
|
|
|
IsFirstLocalDecl = true;
|
2015-07-13 07:43:21 +08:00
|
|
|
|
2015-03-06 07:24:12 +08:00
|
|
|
// 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.
|
|
|
|
// FIXME: Provide a known merge target to the second and subsequent such
|
|
|
|
// declaration.
|
2015-08-22 09:47:18 +08:00
|
|
|
for (unsigned I = 0; I != N - 1; ++I)
|
2016-12-16 04:53:26 +08:00
|
|
|
MergeWith = ReadDecl();
|
2015-08-23 04:13:39 +08:00
|
|
|
|
2016-12-16 04:53:26 +08:00
|
|
|
RedeclOffset = ReadLocalOffset();
|
2015-08-22 09:47:18 +08:00
|
|
|
} else {
|
|
|
|
// This declaration was not the first local declaration. Read the first
|
|
|
|
// local declaration now, to trigger the import of other redeclarations.
|
2016-12-16 04:53:26 +08:00
|
|
|
(void)ReadDecl();
|
2015-02-06 10:42:59 +08:00
|
|
|
}
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
|
2012-01-16 00:58:34 +08:00
|
|
|
if (FirstDecl != D) {
|
2011-02-12 15:50:47 +08:00
|
|
|
// We delay loading of the redeclaration chain to avoid deeply nested calls.
|
|
|
|
// We temporarily set the first (canonical) declaration as the previous one
|
|
|
|
// which is the one that matters and mark the real previous DeclID to be
|
|
|
|
// loaded & attached later on.
|
2012-05-29 03:38:42 +08:00
|
|
|
D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl);
|
2015-03-26 07:18:30 +08:00
|
|
|
D->First = FirstDecl->getCanonicalDecl();
|
2016-12-16 04:53:26 +08:00
|
|
|
}
|
2015-08-22 09:47:18 +08:00
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *DAsT = static_cast<T *>(D);
|
2015-08-22 09:47:18 +08:00
|
|
|
|
|
|
|
// Note that we need to load local redeclarations of this decl and build a
|
|
|
|
// decl chain for them. This must happen *after* we perform the preloading
|
|
|
|
// above; this ensures that the redeclaration chain is built in the correct
|
|
|
|
// order.
|
|
|
|
if (IsFirstLocalDecl)
|
2015-08-23 04:13:39 +08:00
|
|
|
Reader.PendingDeclChains.push_back(std::make_pair(DAsT, RedeclOffset));
|
2015-08-22 09:47:18 +08:00
|
|
|
|
2016-09-24 12:21:53 +08:00
|
|
|
return RedeclarableResult(MergeWith, FirstDeclID, IsKeyDecl);
|
2010-08-04 01:30:10 +08:00
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Attempts to merge the given declaration (D) with another declaration
|
2012-01-04 01:27:13 +08:00
|
|
|
/// of the same entity.
|
|
|
|
template<typename T>
|
2014-07-15 11:37:06 +08:00
|
|
|
void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,
|
2014-04-24 10:25:27 +08:00
|
|
|
RedeclarableResult &Redecl,
|
|
|
|
DeclID TemplatePatternID) {
|
2012-01-04 01:31:38 +08:00
|
|
|
// If modules are not available, there is no reason to perform this merge.
|
2012-03-11 15:00:24 +08:00
|
|
|
if (!Reader.getContext().getLangOpts().Modules)
|
2012-01-04 01:31:38 +08:00
|
|
|
return;
|
2013-09-10 00:55:27 +08:00
|
|
|
|
2015-03-10 10:57:50 +08:00
|
|
|
// If we're not the canonical declaration, we don't need to merge.
|
|
|
|
if (!DBase->isFirstDecl())
|
|
|
|
return;
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *D = static_cast<T *>(DBase);
|
2016-10-06 21:18:06 +08:00
|
|
|
|
2015-02-06 10:42:59 +08:00
|
|
|
if (auto *Existing = Redecl.getKnownMergeTarget())
|
|
|
|
// We already know of an existing declaration we should merge with.
|
|
|
|
mergeRedeclarable(D, cast<T>(Existing), Redecl, TemplatePatternID);
|
|
|
|
else if (FindExistingResult ExistingRes = findExisting(D))
|
2013-09-10 00:55:27 +08:00
|
|
|
if (T *Existing = ExistingRes)
|
2014-04-24 10:25:27 +08:00
|
|
|
mergeRedeclarable(D, Existing, Redecl, TemplatePatternID);
|
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// "Cast" to type T, asserting if we don't have an implicit conversion.
|
2014-04-24 10:25:27 +08:00
|
|
|
/// We use this to put code in a template that will only be valid for certain
|
|
|
|
/// instantiations.
|
|
|
|
template<typename T> static T assert_cast(T t) { return t; }
|
|
|
|
template<typename T> static T assert_cast(...) {
|
|
|
|
llvm_unreachable("bad assert_cast");
|
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Merge together the pattern declarations from two template
|
2014-04-24 10:25:27 +08:00
|
|
|
/// declarations.
|
|
|
|
void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
|
|
|
|
RedeclarableTemplateDecl *Existing,
|
2015-07-13 07:43:21 +08:00
|
|
|
DeclID DsID, bool IsKeyDecl) {
|
2014-04-24 10:25:27 +08:00
|
|
|
auto *DPattern = D->getTemplatedDecl();
|
|
|
|
auto *ExistingPattern = Existing->getTemplatedDecl();
|
2016-12-16 04:53:26 +08:00
|
|
|
RedeclarableResult Result(/*MergeWith*/ ExistingPattern,
|
|
|
|
DPattern->getCanonicalDecl()->getGlobalID(),
|
2016-09-24 12:21:53 +08:00
|
|
|
IsKeyDecl);
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2014-07-12 02:22:58 +08:00
|
|
|
if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
|
|
|
|
// Merge with any existing definition.
|
|
|
|
// FIXME: This is duplicated in several places. Refactor.
|
|
|
|
auto *ExistingClass =
|
|
|
|
cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl();
|
2016-05-18 06:44:15 +08:00
|
|
|
if (auto *DDD = DClass->DefinitionData) {
|
|
|
|
if (ExistingClass->DefinitionData) {
|
2015-01-24 09:07:20 +08:00
|
|
|
MergeDefinitionData(ExistingClass, std::move(*DDD));
|
2014-07-12 02:22:58 +08:00
|
|
|
} else {
|
|
|
|
ExistingClass->DefinitionData = DClass->DefinitionData;
|
2015-06-20 08:22:34 +08:00
|
|
|
// We may have skipped this before because we thought that DClass
|
|
|
|
// was the canonical declaration.
|
2015-03-12 02:21:02 +08:00
|
|
|
Reader.PendingDefinitions.insert(DClass);
|
2014-07-12 02:22:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
DClass->DefinitionData = ExistingClass->DefinitionData;
|
|
|
|
|
2014-04-24 10:25:27 +08:00
|
|
|
return mergeRedeclarable(DClass, cast<TagDecl>(ExistingPattern),
|
|
|
|
Result);
|
2014-07-12 02:22:58 +08:00
|
|
|
}
|
2014-04-24 10:25:27 +08:00
|
|
|
if (auto *DFunction = dyn_cast<FunctionDecl>(DPattern))
|
|
|
|
return mergeRedeclarable(DFunction, cast<FunctionDecl>(ExistingPattern),
|
|
|
|
Result);
|
|
|
|
if (auto *DVar = dyn_cast<VarDecl>(DPattern))
|
|
|
|
return mergeRedeclarable(DVar, cast<VarDecl>(ExistingPattern), Result);
|
2014-07-29 05:16:37 +08:00
|
|
|
if (auto *DAlias = dyn_cast<TypeAliasDecl>(DPattern))
|
|
|
|
return mergeRedeclarable(DAlias, cast<TypedefNameDecl>(ExistingPattern),
|
|
|
|
Result);
|
2014-04-24 10:25:27 +08:00
|
|
|
llvm_unreachable("merged an unknown kind of redeclarable template");
|
2013-09-10 00:55:27 +08:00
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Attempts to merge the given declaration (D) with another declaration
|
2013-09-10 00:55:27 +08:00
|
|
|
/// of the same entity.
|
|
|
|
template<typename T>
|
2014-04-24 10:25:27 +08:00
|
|
|
void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
|
|
|
|
RedeclarableResult &Redecl,
|
|
|
|
DeclID TemplatePatternID) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *D = static_cast<T *>(DBase);
|
2013-09-10 00:55:27 +08:00
|
|
|
T *ExistingCanon = Existing->getCanonicalDecl();
|
2014-04-24 10:25:27 +08:00
|
|
|
T *DCanon = D->getCanonicalDecl();
|
2013-09-10 00:55:27 +08:00
|
|
|
if (ExistingCanon != DCanon) {
|
2015-03-10 10:57:50 +08:00
|
|
|
assert(DCanon->getGlobalID() == Redecl.getFirstID() &&
|
|
|
|
"already merged this declaration");
|
2014-07-15 11:37:06 +08:00
|
|
|
|
2013-09-10 00:55:27 +08:00
|
|
|
// Have our redeclaration link point back at the canonical declaration
|
2014-07-15 11:37:06 +08:00
|
|
|
// of the existing declaration, so that this declaration has the
|
2013-09-10 00:55:27 +08:00
|
|
|
// appropriate canonical declaration.
|
|
|
|
D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon);
|
2015-03-26 07:18:30 +08:00
|
|
|
D->First = ExistingCanon;
|
2016-04-28 22:13:28 +08:00
|
|
|
ExistingCanon->Used |= D->Used;
|
|
|
|
D->Used = false;
|
2013-09-10 00:55:27 +08:00
|
|
|
|
|
|
|
// When we merge a namespace, update its pointer to the first namespace.
|
2015-03-17 10:23:11 +08:00
|
|
|
// We cannot have loaded any redeclarations of this declaration yet, so
|
|
|
|
// there's nothing else that needs to be updated.
|
2014-04-24 10:25:27 +08:00
|
|
|
if (auto *Namespace = dyn_cast<NamespaceDecl>(D))
|
2013-09-10 00:55:27 +08:00
|
|
|
Namespace->AnonOrFirstNamespaceAndInline.setPointer(
|
2014-04-24 10:25:27 +08:00
|
|
|
assert_cast<NamespaceDecl*>(ExistingCanon));
|
|
|
|
|
|
|
|
// When we merge a template, merge its pattern.
|
|
|
|
if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D))
|
|
|
|
mergeTemplatePattern(
|
|
|
|
DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon),
|
2015-07-13 07:43:21 +08:00
|
|
|
TemplatePatternID, Redecl.isKeyDecl());
|
2013-09-10 00:55:27 +08:00
|
|
|
|
2015-07-13 07:43:21 +08:00
|
|
|
// If this declaration is a key declaration, make a note of that.
|
2015-08-22 09:47:18 +08:00
|
|
|
if (Redecl.isKeyDecl())
|
2015-07-13 07:43:21 +08:00
|
|
|
Reader.KeyDecls[ExistingCanon].push_back(Redecl.getFirstID());
|
2012-01-04 01:27:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 06:14:29 +08:00
|
|
|
/// ODR-like semantics for C/ObjC allow us to merge tag types and a structural
|
|
|
|
/// check in Sema guarantees the types can be merged (see C11 6.2.7/1 or C89
|
|
|
|
/// 6.1.2.6/1). Although most merging is done in Sema, we need to guarantee
|
|
|
|
/// that some types are mergeable during deserialization, otherwise name
|
|
|
|
/// lookup fails. This is the case for EnumConstantDecl.
|
2018-05-16 05:26:47 +08:00
|
|
|
static bool allowODRLikeMergeInC(NamedDecl *ND) {
|
2018-05-01 06:14:29 +08:00
|
|
|
if (!ND)
|
|
|
|
return false;
|
|
|
|
// TODO: implement merge for other necessary decls.
|
2018-05-16 05:26:47 +08:00
|
|
|
if (isa<EnumConstantDecl>(ND))
|
2018-05-01 06:14:29 +08:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Attempts to merge the given declaration (D) with another declaration
|
2013-10-07 16:02:11 +08:00
|
|
|
/// of the same entity, for the case where the entity is not actually
|
|
|
|
/// redeclarable. This happens, for instance, when merging the fields of
|
|
|
|
/// identical class definitions from two different modules.
|
|
|
|
template<typename T>
|
|
|
|
void ASTDeclReader::mergeMergeable(Mergeable<T> *D) {
|
|
|
|
// If modules are not available, there is no reason to perform this merge.
|
|
|
|
if (!Reader.getContext().getLangOpts().Modules)
|
|
|
|
return;
|
|
|
|
|
2018-05-01 06:14:29 +08:00
|
|
|
// ODR-based merging is performed in C++ and in some cases (tag types) in C.
|
|
|
|
// Note that C identically-named things in different translation units are
|
|
|
|
// not redeclarations, but may still have compatible types, where ODR-like
|
|
|
|
// semantics may apply.
|
|
|
|
if (!Reader.getContext().getLangOpts().CPlusPlus &&
|
|
|
|
!allowODRLikeMergeInC(dyn_cast<NamedDecl>(static_cast<T*>(D))))
|
2013-10-16 06:02:41 +08:00
|
|
|
return;
|
|
|
|
|
2013-10-07 16:02:11 +08:00
|
|
|
if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D)))
|
|
|
|
if (T *Existing = ExistingRes)
|
2017-06-30 07:23:46 +08:00
|
|
|
Reader.getContext().setPrimaryMergedDecl(static_cast<T *>(D),
|
|
|
|
Existing->getCanonicalDecl());
|
2013-10-07 16:02:11 +08:00
|
|
|
}
|
|
|
|
|
2013-03-22 14:34:35 +08:00
|
|
|
void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
|
|
|
|
VisitDecl(D);
|
|
|
|
unsigned NumVars = D->varlist_size();
|
2013-05-13 12:18:18 +08:00
|
|
|
SmallVector<Expr *, 16> Vars;
|
2013-03-22 14:34:35 +08:00
|
|
|
Vars.reserve(NumVars);
|
|
|
|
for (unsigned i = 0; i != NumVars; ++i) {
|
2016-12-21 12:34:52 +08:00
|
|
|
Vars.push_back(Record.readExpr());
|
2013-03-22 14:34:35 +08:00
|
|
|
}
|
|
|
|
D->setVars(Vars);
|
|
|
|
}
|
|
|
|
|
2018-09-26 12:28:39 +08:00
|
|
|
void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) {
|
|
|
|
VisitDecl(D);
|
|
|
|
unsigned NumClauses = D->clauselist_size();
|
|
|
|
SmallVector<OMPClause *, 8> Clauses;
|
|
|
|
Clauses.reserve(NumClauses);
|
|
|
|
OMPClauseReader ClauseReader(Record);
|
|
|
|
for (unsigned I = 0; I != NumClauses; ++I)
|
|
|
|
Clauses.push_back(ClauseReader.readClause());
|
|
|
|
D->setClauses(Clauses);
|
|
|
|
}
|
|
|
|
|
2016-03-03 13:21:39 +08:00
|
|
|
void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
|
2016-03-04 17:22:22 +08:00
|
|
|
VisitValueDecl(D);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->setLocation(ReadSourceLocation());
|
2018-09-14 00:54:05 +08:00
|
|
|
Expr *In = Record.readExpr();
|
|
|
|
Expr *Out = Record.readExpr();
|
|
|
|
D->setCombinerData(In, Out);
|
|
|
|
Expr *Combiner = Record.readExpr();
|
|
|
|
D->setCombiner(Combiner);
|
|
|
|
Expr *Orig = Record.readExpr();
|
|
|
|
Expr *Priv = Record.readExpr();
|
|
|
|
D->setInitializerData(Orig, Priv);
|
|
|
|
Expr *Init = Record.readExpr();
|
|
|
|
auto IK = static_cast<OMPDeclareReductionDecl::InitKind>(Record.readInt());
|
|
|
|
D->setInitializer(Init, IK);
|
2016-12-16 04:53:26 +08:00
|
|
|
D->PrevDeclInScope = ReadDeclID();
|
2016-03-03 13:21:39 +08:00
|
|
|
}
|
|
|
|
|
2016-02-11 13:35:55 +08:00
|
|
|
void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
|
2016-02-08 17:29:13 +08:00
|
|
|
VisitVarDecl(D);
|
|
|
|
}
|
|
|
|
|
2009-04-27 13:27:42 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-04-27 14:01:06 +08:00
|
|
|
// Attribute Reading
|
2009-04-27 13:27:42 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2018-08-21 05:47:29 +08:00
|
|
|
namespace {
|
|
|
|
class AttrReader {
|
|
|
|
ModuleFile *F;
|
|
|
|
ASTReader *Reader;
|
|
|
|
const ASTReader::RecordData &Record;
|
|
|
|
unsigned &Idx;
|
2018-08-14 06:07:09 +08:00
|
|
|
|
2018-08-21 05:47:29 +08:00
|
|
|
public:
|
|
|
|
AttrReader(ModuleFile &F, ASTReader &Reader,
|
|
|
|
const ASTReader::RecordData &Record, unsigned &Idx)
|
|
|
|
: F(&F), Reader(&Reader), Record(Record), Idx(Idx) {}
|
|
|
|
|
|
|
|
const uint64_t &readInt() { return Record[Idx++]; }
|
|
|
|
|
|
|
|
SourceRange readSourceRange() {
|
|
|
|
return Reader->ReadSourceRange(*F, Record, Idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *readExpr() { return Reader->ReadExpr(*F); }
|
|
|
|
|
|
|
|
std::string readString() {
|
|
|
|
return Reader->ReadString(Record, Idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
TypeSourceInfo *getTypeSourceInfo() {
|
|
|
|
return Reader->GetTypeSourceInfo(*F, Record, Idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
IdentifierInfo *getIdentifierInfo() {
|
|
|
|
return Reader->GetIdentifierInfo(*F, Record, Idx);
|
|
|
|
}
|
2018-08-14 06:07:09 +08:00
|
|
|
|
2018-08-21 05:47:29 +08:00
|
|
|
VersionTuple readVersionTuple() {
|
|
|
|
return ASTReader::ReadVersionTuple(Record, Idx);
|
2018-08-14 09:55:37 +08:00
|
|
|
}
|
2018-08-21 05:47:29 +08:00
|
|
|
|
|
|
|
template <typename T> T *GetLocalDeclAs(uint32_t LocalID) {
|
|
|
|
return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
Attr *ASTReader::ReadAttr(ModuleFile &M, const RecordData &Rec,
|
|
|
|
unsigned &Idx) {
|
|
|
|
AttrReader Record(M, *this, Rec, Idx);
|
|
|
|
auto V = Record.readInt();
|
|
|
|
if (!V)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
Attr *New = nullptr;
|
|
|
|
// Kind is stored as a 1-based integer because 0 is used to indicate a null
|
|
|
|
// Attr pointer.
|
|
|
|
auto Kind = static_cast<attr::Kind>(V - 1);
|
|
|
|
SourceRange Range = Record.readSourceRange();
|
|
|
|
ASTContext &Context = getContext();
|
|
|
|
|
|
|
|
#include "clang/Serialization/AttrPCHRead.inc"
|
|
|
|
|
|
|
|
assert(New && "Unable to decode attribute?");
|
|
|
|
return New;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads attributes from the current stream position.
|
|
|
|
void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs) {
|
|
|
|
for (unsigned I = 0, E = Record.readInt(); I != E; ++I)
|
|
|
|
Attrs.push_back(Record.readAttr());
|
2009-04-27 14:01:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2010-08-19 07:56:43 +08:00
|
|
|
// ASTReader Implementation
|
2009-04-27 14:01:06 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Note that we have loaded the declaration with the given
|
2009-04-27 13:27:42 +08:00
|
|
|
/// Index.
|
2009-09-09 23:08:12 +08:00
|
|
|
///
|
2009-04-27 13:27:42 +08:00
|
|
|
/// This routine notes that this declaration has already been loaded,
|
|
|
|
/// so that future GetDecl calls will return this declaration rather
|
|
|
|
/// than trying to load a new declaration.
|
2010-08-19 07:56:43 +08:00
|
|
|
inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
assert(!DeclsLoaded[Index] && "Decl loaded twice?");
|
|
|
|
DeclsLoaded[Index] = D;
|
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Determine whether the consumer will be interested in seeing
|
2009-04-27 13:27:42 +08:00
|
|
|
/// this declaration (via HandleTopLevelDecl).
|
|
|
|
///
|
|
|
|
/// This routine should return true for anything that might affect
|
|
|
|
/// code generation, e.g., inline function definitions, Objective-C
|
|
|
|
/// declarations with metadata, etc.
|
2017-10-11 15:47:54 +08:00
|
|
|
static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
|
2011-09-14 05:35:00 +08:00
|
|
|
// An ObjCMethodDecl is never considered as "interesting" because its
|
|
|
|
// implementation container always is.
|
|
|
|
|
2017-09-07 08:55:55 +08:00
|
|
|
// An ImportDecl or VarDecl imported from a module map module will get
|
|
|
|
// emitted when we import the relevant module.
|
|
|
|
if (isa<ImportDecl>(D) || isa<VarDecl>(D)) {
|
|
|
|
auto *M = D->getImportedOwningModule();
|
|
|
|
if (M && M->Kind == Module::ModuleMapModule &&
|
|
|
|
Ctx.DeclMustBeEmitted(D))
|
|
|
|
return false;
|
|
|
|
}
|
2016-07-21 03:10:16 +08:00
|
|
|
|
2018-07-31 03:24:48 +08:00
|
|
|
if (isa<FileScopeAsmDecl>(D) ||
|
|
|
|
isa<ObjCProtocolDecl>(D) ||
|
2014-01-31 09:06:56 +08:00
|
|
|
isa<ObjCImplDecl>(D) ||
|
2014-11-11 12:05:39 +08:00
|
|
|
isa<ImportDecl>(D) ||
|
2016-03-03 01:28:48 +08:00
|
|
|
isa<PragmaCommentDecl>(D) ||
|
2016-03-04 17:22:22 +08:00
|
|
|
isa<PragmaDetectMismatchDecl>(D))
|
2009-09-17 11:06:44 +08:00
|
|
|
return true;
|
2016-03-04 17:22:22 +08:00
|
|
|
if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D))
|
|
|
|
return !D->getDeclContext()->isFunctionOrMethod();
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *Var = dyn_cast<VarDecl>(D))
|
2010-08-05 17:47:59 +08:00
|
|
|
return Var->isFileVarDecl() &&
|
2018-08-16 03:45:12 +08:00
|
|
|
(Var->isThisDeclarationADefinition() == VarDecl::Definition ||
|
|
|
|
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Var));
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *Func = dyn_cast<FunctionDecl>(D))
|
2017-10-11 15:47:54 +08:00
|
|
|
return Func->doesThisDeclarationHaveABody() || HasBody;
|
2017-04-12 05:13:37 +08:00
|
|
|
|
|
|
|
if (auto *ES = D->getASTContext().getExternalSource())
|
|
|
|
if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never)
|
|
|
|
return true;
|
|
|
|
|
2011-09-10 08:22:34 +08:00
|
|
|
return false;
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Get the correct cursor and offset for loading a declaration.
|
2010-08-19 07:56:43 +08:00
|
|
|
ASTReader::RecordLocation
|
2016-03-27 15:28:06 +08:00
|
|
|
ASTReader::DeclCursorForID(DeclID ID, SourceLocation &Loc) {
|
2011-07-20 08:27:43 +08:00
|
|
|
GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID);
|
|
|
|
assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
|
2011-12-01 07:21:26 +08:00
|
|
|
ModuleFile *M = I->second;
|
2016-03-27 13:52:25 +08:00
|
|
|
const DeclOffset &DOffs =
|
|
|
|
M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS];
|
2016-03-27 15:28:06 +08:00
|
|
|
Loc = TranslateSourceLocation(*M, DOffs.getLocation());
|
2011-10-28 02:47:35 +08:00
|
|
|
return RecordLocation(M, DOffs.BitOffset);
|
2010-07-21 06:46:15 +08:00
|
|
|
}
|
|
|
|
|
Introduce a global bit-offset continuous range map into the ASTReader,
so that we have one, simple way to map from global bit offsets to
local bit offsets. Eliminates a number of loops over the chain, and
generalizes for more interesting bit remappings.
Also, as an amusing oddity, we were computing global bit offsets
*backwards* for preprocessed entities (e.g., the directly included PCH
file in the chain would start at offset zero, rather than the original
PCH that occurs first in translation unit). Even more amusingly, it
made precompiled preambles work, because we were forgetting to adjust
the local bit offset to a global bit offset when storing preprocessed
entity offsets in the ASTUnit. Two wrongs made a right, and now
they're both right.
llvm-svn: 135750
2011-07-22 14:10:01 +08:00
|
|
|
ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto I = GlobalBitOffsetsMap.find(GlobalOffset);
|
Introduce a global bit-offset continuous range map into the ASTReader,
so that we have one, simple way to map from global bit offsets to
local bit offsets. Eliminates a number of loops over the chain, and
generalizes for more interesting bit remappings.
Also, as an amusing oddity, we were computing global bit offsets
*backwards* for preprocessed entities (e.g., the directly included PCH
file in the chain would start at offset zero, rather than the original
PCH that occurs first in translation unit). Even more amusingly, it
made precompiled preambles work, because we were forgetting to adjust
the local bit offset to a global bit offset when storing preprocessed
entity offsets in the ASTUnit. Two wrongs made a right, and now
they're both right.
llvm-svn: 135750
2011-07-22 14:10:01 +08:00
|
|
|
|
|
|
|
assert(I != GlobalBitOffsetsMap.end() && "Corrupted global bit offsets map");
|
|
|
|
return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset);
|
|
|
|
}
|
|
|
|
|
2011-12-01 07:21:26 +08:00
|
|
|
uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) {
|
2011-08-04 08:01:48 +08:00
|
|
|
return LocalOffset + M.GlobalBitOffset;
|
|
|
|
}
|
|
|
|
|
2013-06-25 06:51:00 +08:00
|
|
|
static bool isSameTemplateParameterList(const TemplateParameterList *X,
|
|
|
|
const TemplateParameterList *Y);
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Determine whether two template parameters are similar enough
|
2013-06-25 06:51:00 +08:00
|
|
|
/// that they may be used in declarations of the same template.
|
|
|
|
static bool isSameTemplateParameter(const NamedDecl *X,
|
|
|
|
const NamedDecl *Y) {
|
|
|
|
if (X->getKind() != Y->getKind())
|
|
|
|
return false;
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) {
|
|
|
|
const auto *TY = cast<TemplateTypeParmDecl>(Y);
|
2013-06-25 06:51:00 +08:00
|
|
|
return TX->isParameterPack() == TY->isParameterPack();
|
|
|
|
}
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) {
|
|
|
|
const auto *TY = cast<NonTypeTemplateParmDecl>(Y);
|
2013-06-25 06:51:00 +08:00
|
|
|
return TX->isParameterPack() == TY->isParameterPack() &&
|
|
|
|
TX->getASTContext().hasSameType(TX->getType(), TY->getType());
|
|
|
|
}
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
const auto *TX = cast<TemplateTemplateParmDecl>(X);
|
|
|
|
const auto *TY = cast<TemplateTemplateParmDecl>(Y);
|
2013-06-25 06:51:00 +08:00
|
|
|
return TX->isParameterPack() == TY->isParameterPack() &&
|
|
|
|
isSameTemplateParameterList(TX->getTemplateParameters(),
|
|
|
|
TY->getTemplateParameters());
|
|
|
|
}
|
|
|
|
|
2014-10-14 10:00:47 +08:00
|
|
|
static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) {
|
|
|
|
if (auto *NS = X->getAsNamespace())
|
|
|
|
return NS;
|
|
|
|
if (auto *NAS = X->getAsNamespaceAlias())
|
|
|
|
return NAS->getNamespace();
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isSameQualifier(const NestedNameSpecifier *X,
|
|
|
|
const NestedNameSpecifier *Y) {
|
|
|
|
if (auto *NSX = getNamespace(X)) {
|
|
|
|
auto *NSY = getNamespace(Y);
|
|
|
|
if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl())
|
|
|
|
return false;
|
|
|
|
} else if (X->getKind() != Y->getKind())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// FIXME: For namespaces and types, we're permitted to check that the entity
|
|
|
|
// is named via the same tokens. We should probably do so.
|
|
|
|
switch (X->getKind()) {
|
|
|
|
case NestedNameSpecifier::Identifier:
|
|
|
|
if (X->getAsIdentifier() != Y->getAsIdentifier())
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
case NestedNameSpecifier::Namespace:
|
|
|
|
case NestedNameSpecifier::NamespaceAlias:
|
|
|
|
// We've already checked that we named the same namespace.
|
|
|
|
break;
|
|
|
|
case NestedNameSpecifier::TypeSpec:
|
|
|
|
case NestedNameSpecifier::TypeSpecWithTemplate:
|
|
|
|
if (X->getAsType()->getCanonicalTypeInternal() !=
|
|
|
|
Y->getAsType()->getCanonicalTypeInternal())
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
case NestedNameSpecifier::Global:
|
|
|
|
case NestedNameSpecifier::Super:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Recurse into earlier portion of NNS, if any.
|
|
|
|
auto *PX = X->getPrefix();
|
|
|
|
auto *PY = Y->getPrefix();
|
|
|
|
if (PX && PY)
|
|
|
|
return isSameQualifier(PX, PY);
|
|
|
|
return !PX && !PY;
|
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Determine whether two template parameter lists are similar enough
|
2013-06-25 06:51:00 +08:00
|
|
|
/// that they may be used in declarations of the same template.
|
|
|
|
static bool isSameTemplateParameterList(const TemplateParameterList *X,
|
|
|
|
const TemplateParameterList *Y) {
|
|
|
|
if (X->size() != Y->size())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = X->size(); I != N; ++I)
|
|
|
|
if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I)))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-02-16 06:43:27 +08:00
|
|
|
/// Determine whether the attributes we can overload on are identical for A and
|
2017-02-24 10:49:47 +08:00
|
|
|
/// B. Will ignore any overloadable attrs represented in the type of A and B.
|
2017-02-16 06:43:27 +08:00
|
|
|
static bool hasSameOverloadableAttrs(const FunctionDecl *A,
|
|
|
|
const FunctionDecl *B) {
|
2017-02-24 10:49:47 +08:00
|
|
|
// Note that pass_object_size attributes are represented in the function's
|
|
|
|
// ExtParameterInfo, so we don't need to check them here.
|
|
|
|
|
2018-08-03 09:21:16 +08:00
|
|
|
// Return false if any of the enable_if expressions of A and B are different.
|
2017-02-16 06:43:27 +08:00
|
|
|
llvm::FoldingSetNodeID Cand1ID, Cand2ID;
|
2018-08-03 09:21:16 +08:00
|
|
|
auto AEnableIfAttrs = A->specific_attrs<EnableIfAttr>();
|
|
|
|
auto BEnableIfAttrs = B->specific_attrs<EnableIfAttr>();
|
|
|
|
auto AEnableIf = AEnableIfAttrs.begin();
|
|
|
|
auto BEnableIf = BEnableIfAttrs.begin();
|
|
|
|
for (; AEnableIf != AEnableIfAttrs.end() && BEnableIf != BEnableIfAttrs.end();
|
|
|
|
++BEnableIf, ++AEnableIf) {
|
2017-02-16 06:43:27 +08:00
|
|
|
Cand1ID.clear();
|
|
|
|
Cand2ID.clear();
|
|
|
|
|
2018-08-03 09:21:16 +08:00
|
|
|
AEnableIf->getCond()->Profile(Cand1ID, A->getASTContext(), true);
|
|
|
|
BEnableIf->getCond()->Profile(Cand2ID, B->getASTContext(), true);
|
2017-02-16 06:43:27 +08:00
|
|
|
if (Cand1ID != Cand2ID)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-03 09:21:16 +08:00
|
|
|
// Return false if the number of enable_if attributes was different.
|
|
|
|
return AEnableIf == AEnableIfAttrs.end() && BEnableIf == BEnableIfAttrs.end();
|
2017-02-16 06:43:27 +08:00
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Determine whether the two declarations refer to the same entity.
|
2011-12-22 09:48:48 +08:00
|
|
|
static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
|
|
|
|
assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
|
2014-09-04 07:11:22 +08:00
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
if (X == Y)
|
|
|
|
return true;
|
2014-09-04 07:11:22 +08:00
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
// Must be in the same context.
|
2018-07-04 10:25:38 +08:00
|
|
|
//
|
|
|
|
// Note that we can't use DeclContext::Equals here, because the DeclContexts
|
|
|
|
// could be two different declarations of the same function. (We will fix the
|
|
|
|
// semantic DC to refer to the primary definition after merging.)
|
|
|
|
if (!declaresSameEntity(cast<Decl>(X->getDeclContext()->getRedeclContext()),
|
|
|
|
cast<Decl>(Y->getDeclContext()->getRedeclContext())))
|
2011-12-22 09:48:48 +08:00
|
|
|
return false;
|
2012-01-05 00:44:10 +08:00
|
|
|
|
|
|
|
// Two typedefs refer to the same entity if they have the same underlying
|
|
|
|
// type.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *TypedefX = dyn_cast<TypedefNameDecl>(X))
|
|
|
|
if (const auto *TypedefY = dyn_cast<TypedefNameDecl>(Y))
|
2012-01-05 00:44:10 +08:00
|
|
|
return X->getASTContext().hasSameType(TypedefX->getUnderlyingType(),
|
|
|
|
TypedefY->getUnderlyingType());
|
2014-09-04 07:11:22 +08:00
|
|
|
|
2012-01-05 00:44:10 +08:00
|
|
|
// Must have the same kind.
|
|
|
|
if (X->getKind() != Y->getKind())
|
|
|
|
return false;
|
2014-09-04 07:11:22 +08:00
|
|
|
|
2012-01-02 05:47:52 +08:00
|
|
|
// Objective-C classes and protocols with the same name always match.
|
|
|
|
if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X))
|
2011-12-22 09:48:48 +08:00
|
|
|
return true;
|
2013-05-23 09:49:11 +08:00
|
|
|
|
|
|
|
if (isa<ClassTemplateSpecializationDecl>(X)) {
|
2013-09-10 00:55:27 +08:00
|
|
|
// No need to handle these here: we merge them when adding them to the
|
|
|
|
// template.
|
2013-05-23 09:49:11 +08:00
|
|
|
return false;
|
|
|
|
}
|
2013-09-10 00:55:27 +08:00
|
|
|
|
2012-01-04 06:46:00 +08:00
|
|
|
// Compatible tags match.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *TagX = dyn_cast<TagDecl>(X)) {
|
|
|
|
const auto *TagY = cast<TagDecl>(Y);
|
2012-09-01 06:18:20 +08:00
|
|
|
return (TagX->getTagKind() == TagY->getTagKind()) ||
|
|
|
|
((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class ||
|
|
|
|
TagX->getTagKind() == TTK_Interface) &&
|
|
|
|
(TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class ||
|
|
|
|
TagY->getTagKind() == TTK_Interface));
|
|
|
|
}
|
2013-06-24 12:45:28 +08:00
|
|
|
|
2012-09-01 06:18:20 +08:00
|
|
|
// Functions with the same type and linkage match.
|
2014-09-04 07:11:22 +08:00
|
|
|
// FIXME: This needs to cope with merging of prototyped/non-prototyped
|
|
|
|
// functions, etc.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *FuncX = dyn_cast<FunctionDecl>(X)) {
|
|
|
|
const auto *FuncY = cast<FunctionDecl>(Y);
|
|
|
|
if (const auto *CtorX = dyn_cast<CXXConstructorDecl>(X)) {
|
|
|
|
const auto *CtorY = cast<CXXConstructorDecl>(Y);
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
if (CtorX->getInheritedConstructor() &&
|
|
|
|
!isSameEntity(CtorX->getInheritedConstructor().getConstructor(),
|
|
|
|
CtorY->getInheritedConstructor().getConstructor()))
|
|
|
|
return false;
|
|
|
|
}
|
Implement Attribute Target MultiVersioning
GCC's attribute 'target', in addition to being an optimization hint,
also allows function multiversioning. We currently have the former
implemented, this is the latter's implementation.
This works by enabling functions with the same name/signature to coexist,
so that they can all be emitted. Multiversion state is stored in the
FunctionDecl itself, and SemaDecl manages the definitions.
Note that it ends up having to permit redefinition of functions so
that they can all be emitted. Additionally, all versions of the function
must be emitted, so this also manages that.
Note that this includes some additional rules that GCC does not, since
defining something as a MultiVersion function after a usage has been made illegal.
The only 'history rewriting' that happens is if a function is emitted before
it has been converted to a multiversion'ed function, at which point its name
needs to be changed.
Function templates and virtual functions are NOT yet supported (not supported
in GCC either).
Additionally, constructors/destructors are disallowed, but the former is
planned.
llvm-svn: 322028
2018-01-09 05:34:17 +08:00
|
|
|
|
|
|
|
if (FuncX->isMultiVersion() != FuncY->isMultiVersion())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Multiversioned functions with different feature strings are represented
|
|
|
|
// as separate declarations.
|
|
|
|
if (FuncX->isMultiVersion()) {
|
|
|
|
const auto *TAX = FuncX->getAttr<TargetAttr>();
|
|
|
|
const auto *TAY = FuncY->getAttr<TargetAttr>();
|
|
|
|
assert(TAX && TAY && "Multiversion Function without target attribute");
|
|
|
|
|
|
|
|
if (TAX->getFeaturesStr() != TAY->getFeaturesStr())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-03-09 07:00:26 +08:00
|
|
|
ASTContext &C = FuncX->getASTContext();
|
2018-07-04 10:25:38 +08:00
|
|
|
auto GetTypeAsWritten = [](const FunctionDecl *FD) {
|
|
|
|
// Map to the first declaration that we've already merged into this one.
|
|
|
|
// The TSI of redeclarations might not match (due to calling conventions
|
|
|
|
// being inherited onto the type but not the TSI), but the TSI type of
|
|
|
|
// the first declaration of the function should match across modules.
|
|
|
|
FD = FD->getCanonicalDecl();
|
|
|
|
return FD->getTypeSourceInfo() ? FD->getTypeSourceInfo()->getType()
|
|
|
|
: FD->getType();
|
|
|
|
};
|
|
|
|
QualType XT = GetTypeAsWritten(FuncX), YT = GetTypeAsWritten(FuncY);
|
|
|
|
if (!C.hasSameType(XT, YT)) {
|
2017-03-09 07:00:26 +08:00
|
|
|
// We can get functions with different types on the redecl chain in C++17
|
|
|
|
// if they have differing exception specifications and at least one of
|
|
|
|
// the excpetion specs is unresolved.
|
2018-07-04 10:25:38 +08:00
|
|
|
auto *XFPT = XT->getAs<FunctionProtoType>();
|
|
|
|
auto *YFPT = YT->getAs<FunctionProtoType>();
|
2017-12-05 04:27:34 +08:00
|
|
|
if (C.getLangOpts().CPlusPlus17 && XFPT && YFPT &&
|
2017-03-09 07:00:26 +08:00
|
|
|
(isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) ||
|
|
|
|
isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) &&
|
2018-07-04 10:25:38 +08:00
|
|
|
C.hasSameFunctionTypeIgnoringExceptionSpec(XT, YT))
|
2017-03-09 07:00:26 +08:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
2017-02-16 06:43:27 +08:00
|
|
|
return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() &&
|
|
|
|
hasSameOverloadableAttrs(FuncX, FuncY);
|
Implement declaration merging for non-template functions from
different modules. This implementation is a first approximation of
what we want, using only the function type to determine
equivalence. Later, we'll want to deal with some of the more subtle
issues, including:
- C allows a prototyped declaration and a non-prototyped declaration
to be merged, which we should support
- We may want to ignore the return type when merging, then
complain if the return types differ. Or, we may want to leave it
as it us, so that we only complain if overload resolution
eventually fails.
- C++ non-static member functions need to consider cv-qualifiers
and ref-qualifiers.
- Function templates need to consider the template parameters and
return type.
- Function template specializations will have special rules.
- We can now (accidentally!) end up overloading in C, even without
the "overloadable" attribute, and will need to detect this at some
point.
The actual detection of "is this an overload?" is implemented by
Sema::IsOverload(), which will need to be moved into the AST library
for re-use here. That will be a future refactor.
llvm-svn: 147534
2012-01-05 01:13:46 +08:00
|
|
|
}
|
2012-10-01 17:18:00 +08:00
|
|
|
|
2012-01-05 01:21:36 +08:00
|
|
|
// Variables with the same type and linkage match.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *VarX = dyn_cast<VarDecl>(X)) {
|
|
|
|
const auto *VarY = cast<VarDecl>(Y);
|
2016-01-23 03:03:27 +08:00
|
|
|
if (VarX->getLinkageInternal() == VarY->getLinkageInternal()) {
|
|
|
|
ASTContext &C = VarX->getASTContext();
|
|
|
|
if (C.hasSameType(VarX->getType(), VarY->getType()))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// We can get decls with different types on the redecl chain. Eg.
|
|
|
|
// template <typename T> struct S { static T Var[]; }; // #1
|
|
|
|
// template <typename T> T S<T>::Var[sizeof(T)]; // #2
|
|
|
|
// Only? happens when completing an incomplete array type. In this case
|
2016-02-29 03:08:24 +08:00
|
|
|
// when comparing #1 and #2 we should go through their element type.
|
2016-01-23 03:03:27 +08:00
|
|
|
const ArrayType *VarXTy = C.getAsArrayType(VarX->getType());
|
|
|
|
const ArrayType *VarYTy = C.getAsArrayType(VarY->getType());
|
|
|
|
if (!VarXTy || !VarYTy)
|
|
|
|
return false;
|
|
|
|
if (VarXTy->isIncompleteArrayType() || VarYTy->isIncompleteArrayType())
|
|
|
|
return C.hasSameType(VarXTy->getElementType(), VarYTy->getElementType());
|
|
|
|
}
|
|
|
|
return false;
|
2012-01-05 01:21:36 +08:00
|
|
|
}
|
2013-06-24 12:45:28 +08:00
|
|
|
|
2012-01-10 01:30:44 +08:00
|
|
|
// Namespaces with the same name and inlinedness match.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *NamespaceX = dyn_cast<NamespaceDecl>(X)) {
|
|
|
|
const auto *NamespaceY = cast<NamespaceDecl>(Y);
|
2012-01-10 01:30:44 +08:00
|
|
|
return NamespaceX->isInline() == NamespaceY->isInline();
|
|
|
|
}
|
2012-10-01 17:18:00 +08:00
|
|
|
|
2013-06-24 12:45:28 +08:00
|
|
|
// Identical template names and kinds match if their template parameter lists
|
|
|
|
// and patterns match.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) {
|
|
|
|
const auto *TemplateY = cast<TemplateDecl>(Y);
|
2013-06-24 12:45:28 +08:00
|
|
|
return isSameEntity(TemplateX->getTemplatedDecl(),
|
2013-06-25 06:51:00 +08:00
|
|
|
TemplateY->getTemplatedDecl()) &&
|
|
|
|
isSameTemplateParameterList(TemplateX->getTemplateParameters(),
|
|
|
|
TemplateY->getTemplateParameters());
|
2013-06-24 12:45:28 +08:00
|
|
|
}
|
2012-10-01 17:18:00 +08:00
|
|
|
|
2013-10-07 16:02:11 +08:00
|
|
|
// Fields with the same name and the same type match.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *FDX = dyn_cast<FieldDecl>(X)) {
|
|
|
|
const auto *FDY = cast<FieldDecl>(Y);
|
2013-10-16 06:02:41 +08:00
|
|
|
// FIXME: Also check the bitwidth is odr-equivalent, if any.
|
2013-10-07 16:02:11 +08:00
|
|
|
return X->getASTContext().hasSameType(FDX->getType(), FDY->getType());
|
|
|
|
}
|
|
|
|
|
2015-08-04 10:05:09 +08:00
|
|
|
// Indirect fields with the same target field match.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) {
|
|
|
|
const auto *IFDY = cast<IndirectFieldDecl>(Y);
|
2015-08-04 10:05:09 +08:00
|
|
|
return IFDX->getAnonField()->getCanonicalDecl() ==
|
|
|
|
IFDY->getAnonField()->getCanonicalDecl();
|
|
|
|
}
|
|
|
|
|
2013-10-16 06:02:41 +08:00
|
|
|
// Enumerators with the same name match.
|
|
|
|
if (isa<EnumConstantDecl>(X))
|
|
|
|
// FIXME: Also check the value is odr-equivalent.
|
|
|
|
return true;
|
|
|
|
|
2013-10-23 10:17:46 +08:00
|
|
|
// Using shadow declarations with the same target match.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *USX = dyn_cast<UsingShadowDecl>(X)) {
|
|
|
|
const auto *USY = cast<UsingShadowDecl>(Y);
|
2013-10-23 10:17:46 +08:00
|
|
|
return USX->getTargetDecl() == USY->getTargetDecl();
|
|
|
|
}
|
|
|
|
|
2014-10-14 10:00:47 +08:00
|
|
|
// Using declarations with the same qualifier match. (We already know that
|
|
|
|
// the name matches.)
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *UX = dyn_cast<UsingDecl>(X)) {
|
|
|
|
const auto *UY = cast<UsingDecl>(Y);
|
2014-10-14 10:00:47 +08:00
|
|
|
return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&
|
|
|
|
UX->hasTypename() == UY->hasTypename() &&
|
|
|
|
UX->isAccessDeclaration() == UY->isAccessDeclaration();
|
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) {
|
|
|
|
const auto *UY = cast<UnresolvedUsingValueDecl>(Y);
|
2014-10-14 10:00:47 +08:00
|
|
|
return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&
|
|
|
|
UX->isAccessDeclaration() == UY->isAccessDeclaration();
|
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X))
|
2014-10-14 10:00:47 +08:00
|
|
|
return isSameQualifier(
|
|
|
|
UX->getQualifier(),
|
|
|
|
cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier());
|
|
|
|
|
2014-09-04 07:11:22 +08:00
|
|
|
// Namespace alias definitions with the same target match.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) {
|
|
|
|
const auto *NAY = cast<NamespaceAliasDecl>(Y);
|
2014-09-04 07:11:22 +08:00
|
|
|
return NAX->getNamespace()->Equals(NAY->getNamespace());
|
|
|
|
}
|
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-09-10 00:55:27 +08:00
|
|
|
/// Find the context in which we should search for previous declarations when
|
|
|
|
/// looking for declarations to merge.
|
2015-01-24 09:07:20 +08:00
|
|
|
DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
|
|
|
|
DeclContext *DC) {
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *ND = dyn_cast<NamespaceDecl>(DC))
|
2013-09-10 00:55:27 +08:00
|
|
|
return ND->getOriginalNamespace();
|
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
|
2015-01-24 09:07:20 +08:00
|
|
|
// Try to dig out the definition.
|
2016-05-18 06:44:15 +08:00
|
|
|
auto *DD = RD->DefinitionData;
|
2015-01-24 09:07:20 +08:00
|
|
|
if (!DD)
|
2016-05-18 06:44:15 +08:00
|
|
|
DD = RD->getCanonicalDecl()->DefinitionData;
|
2015-01-24 09:07:20 +08:00
|
|
|
|
|
|
|
// If there's no definition yet, then DC's definition is added by an update
|
|
|
|
// record, but we've not yet loaded that update record. In this case, we
|
|
|
|
// commit to DC being the canonical definition now, and will fix this when
|
|
|
|
// we load the update record.
|
|
|
|
if (!DD) {
|
2017-06-30 07:23:46 +08:00
|
|
|
DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD);
|
2018-08-02 04:48:16 +08:00
|
|
|
RD->setCompleteDefinition(true);
|
2015-01-24 09:07:20 +08:00
|
|
|
RD->DefinitionData = DD;
|
|
|
|
RD->getCanonicalDecl()->DefinitionData = DD;
|
|
|
|
|
|
|
|
// Track that we did this horrible thing so that we can fix it later.
|
2015-02-03 11:32:14 +08:00
|
|
|
Reader.PendingFakeDefinitionData.insert(
|
|
|
|
std::make_pair(DD, ASTReader::PendingFakeDefinitionKind::Fake));
|
2015-01-24 09:07:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return DD->Definition;
|
|
|
|
}
|
2013-09-10 00:55:27 +08:00
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *ED = dyn_cast<EnumDecl>(DC))
|
2014-05-22 13:54:18 +08:00
|
|
|
return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
|
|
|
|
: nullptr;
|
2013-10-16 06:02:41 +08:00
|
|
|
|
2015-02-05 07:37:59 +08:00
|
|
|
// We can see the TU here only if we have no Sema object. In that case,
|
|
|
|
// there's no TU scope to look in, so using the DC alone is sufficient.
|
|
|
|
if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
|
|
|
|
return TU;
|
|
|
|
|
2014-05-22 13:54:18 +08:00
|
|
|
return nullptr;
|
2013-09-10 00:55:27 +08:00
|
|
|
}
|
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
ASTDeclReader::FindExistingResult::~FindExistingResult() {
|
2015-01-22 10:21:23 +08:00
|
|
|
// Record that we had a typedef name for linkage whether or not we merge
|
|
|
|
// with that declaration.
|
|
|
|
if (TypedefNameForLinkage) {
|
|
|
|
DeclContext *DC = New->getDeclContext()->getRedeclContext();
|
|
|
|
Reader.ImportedTypedefNamesForLinkage.insert(
|
|
|
|
std::make_pair(std::make_pair(DC, TypedefNameForLinkage), New));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-10 01:38:47 +08:00
|
|
|
if (!AddResult || Existing)
|
2011-12-22 09:48:48 +08:00
|
|
|
return;
|
2013-07-13 10:00:19 +08:00
|
|
|
|
2014-08-30 08:04:23 +08:00
|
|
|
DeclarationName Name = New->getDeclName();
|
2013-07-13 10:00:19 +08:00
|
|
|
DeclContext *DC = New->getDeclContext()->getRedeclContext();
|
2015-02-07 11:11:11 +08:00
|
|
|
if (needsAnonymousDeclarationNumber(New)) {
|
2014-08-28 09:33:39 +08:00
|
|
|
setAnonymousDeclForMerging(Reader, New->getLexicalDeclContext(),
|
|
|
|
AnonymousDeclNumber, New);
|
2016-05-07 07:14:07 +08:00
|
|
|
} else if (DC->isTranslationUnit() &&
|
2015-03-23 11:25:59 +08:00
|
|
|
!Reader.getContext().getLangOpts().CPlusPlus) {
|
2016-05-07 07:14:07 +08:00
|
|
|
if (Reader.getIdResolver().tryAddTopLevelDecl(New, Name))
|
2015-03-23 11:25:59 +08:00
|
|
|
Reader.PendingFakeLookupResults[Name.getAsIdentifierInfo()]
|
|
|
|
.push_back(New);
|
2015-01-24 09:07:20 +08:00
|
|
|
} else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) {
|
2013-07-13 10:00:19 +08:00
|
|
|
// Add the declaration to its redeclaration context so later merging
|
|
|
|
// lookups will find it.
|
2013-09-10 00:55:27 +08:00
|
|
|
MergeDC->makeDeclVisibleInContextImpl(New, /*Internal*/true);
|
2011-12-22 09:48:48 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-23 09:45:27 +08:00
|
|
|
/// Find the declaration that should be merged into, given the declaration found
|
|
|
|
/// by name lookup. If we're merging an anonymous declaration within a typedef,
|
|
|
|
/// we need a matching typedef, and we merge with the type inside it.
|
|
|
|
static NamedDecl *getDeclForMerging(NamedDecl *Found,
|
|
|
|
bool IsTypedefNameForLinkage) {
|
|
|
|
if (!IsTypedefNameForLinkage)
|
|
|
|
return Found;
|
|
|
|
|
|
|
|
// If we found a typedef declaration that gives a name to some other
|
|
|
|
// declaration, then we want that inner declaration. Declarations from
|
|
|
|
// AST files are handled via ImportedTypedefNamesForLinkage.
|
2015-03-27 09:37:43 +08:00
|
|
|
if (Found->isFromASTFile())
|
2015-10-07 07:40:43 +08:00
|
|
|
return nullptr;
|
2015-03-27 09:37:43 +08:00
|
|
|
|
|
|
|
if (auto *TND = dyn_cast<TypedefNameDecl>(Found))
|
2016-08-31 03:13:18 +08:00
|
|
|
return TND->getAnonDeclWithTypedefName(/*AnyRedecl*/true);
|
2014-08-23 09:45:27 +08:00
|
|
|
|
2015-10-07 07:40:43 +08:00
|
|
|
return nullptr;
|
2014-08-23 09:45:27 +08:00
|
|
|
}
|
|
|
|
|
2018-07-04 10:25:38 +08:00
|
|
|
/// Find the declaration to use to populate the anonymous declaration table
|
|
|
|
/// for the given lexical DeclContext. We only care about finding local
|
|
|
|
/// definitions of the context; we'll merge imported ones as we go.
|
|
|
|
DeclContext *
|
|
|
|
ASTDeclReader::getPrimaryDCForAnonymousDecl(DeclContext *LexicalDC) {
|
|
|
|
// For classes, we track the definition as we merge.
|
|
|
|
if (auto *RD = dyn_cast<CXXRecordDecl>(LexicalDC)) {
|
|
|
|
auto *DD = RD->getCanonicalDecl()->DefinitionData;
|
|
|
|
return DD ? DD->Definition : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// For anything else, walk its merged redeclarations looking for a definition.
|
|
|
|
// Note that we can't just call getDefinition here because the redeclaration
|
|
|
|
// chain isn't wired up.
|
|
|
|
for (auto *D : merged_redecls(cast<Decl>(LexicalDC))) {
|
|
|
|
if (auto *FD = dyn_cast<FunctionDecl>(D))
|
|
|
|
if (FD->isThisDeclarationADefinition())
|
|
|
|
return FD;
|
|
|
|
if (auto *MD = dyn_cast<ObjCMethodDecl>(D))
|
|
|
|
if (MD->isThisDeclarationADefinition())
|
|
|
|
return MD;
|
|
|
|
}
|
|
|
|
|
|
|
|
// No merged definition yet.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2014-08-28 09:33:39 +08:00
|
|
|
NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader,
|
|
|
|
DeclContext *DC,
|
|
|
|
unsigned Index) {
|
|
|
|
// If the lexical context has been merged, look into the now-canonical
|
|
|
|
// definition.
|
2018-07-04 10:25:38 +08:00
|
|
|
auto *CanonDC = cast<Decl>(DC)->getCanonicalDecl();
|
2014-08-28 09:33:39 +08:00
|
|
|
|
|
|
|
// If we've seen this before, return the canonical declaration.
|
2018-07-04 10:25:38 +08:00
|
|
|
auto &Previous = Reader.AnonymousDeclarationsForMerging[CanonDC];
|
2014-08-28 09:33:39 +08:00
|
|
|
if (Index < Previous.size() && Previous[Index])
|
|
|
|
return Previous[Index];
|
|
|
|
|
|
|
|
// If this is the first time, but we have parsed a declaration of the context,
|
|
|
|
// build the anonymous declaration list from the parsed declaration.
|
2018-07-04 10:25:38 +08:00
|
|
|
auto *PrimaryDC = getPrimaryDCForAnonymousDecl(DC);
|
|
|
|
if (PrimaryDC && !cast<Decl>(PrimaryDC)->isFromASTFile()) {
|
|
|
|
numberAnonymousDeclsWithin(PrimaryDC, [&](NamedDecl *ND, unsigned Number) {
|
2015-02-07 11:11:11 +08:00
|
|
|
if (Previous.size() == Number)
|
2014-08-28 09:33:39 +08:00
|
|
|
Previous.push_back(cast<NamedDecl>(ND->getCanonicalDecl()));
|
|
|
|
else
|
2015-02-07 11:11:11 +08:00
|
|
|
Previous[Number] = cast<NamedDecl>(ND->getCanonicalDecl());
|
|
|
|
});
|
2014-08-28 09:33:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Index < Previous.size() ? Previous[Index] : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDeclReader::setAnonymousDeclForMerging(ASTReader &Reader,
|
|
|
|
DeclContext *DC, unsigned Index,
|
|
|
|
NamedDecl *D) {
|
2018-07-04 10:25:38 +08:00
|
|
|
auto *CanonDC = cast<Decl>(DC)->getCanonicalDecl();
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2018-07-04 10:25:38 +08:00
|
|
|
auto &Previous = Reader.AnonymousDeclarationsForMerging[CanonDC];
|
2014-08-28 09:33:39 +08:00
|
|
|
if (Index >= Previous.size())
|
|
|
|
Previous.resize(Index + 1);
|
|
|
|
if (!Previous[Index])
|
|
|
|
Previous[Index] = D;
|
|
|
|
}
|
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
|
2014-08-30 08:04:23 +08:00
|
|
|
DeclarationName Name = TypedefNameForLinkage ? TypedefNameForLinkage
|
|
|
|
: D->getDeclName();
|
2014-08-23 09:45:27 +08:00
|
|
|
|
2014-08-28 09:33:39 +08:00
|
|
|
if (!Name && !needsAnonymousDeclarationNumber(D)) {
|
|
|
|
// Don't bother trying to find unnamed declarations that are in
|
|
|
|
// unmergeable contexts.
|
2014-08-30 08:04:23 +08:00
|
|
|
FindExistingResult Result(Reader, D, /*Existing=*/nullptr,
|
|
|
|
AnonymousDeclNumber, TypedefNameForLinkage);
|
2012-01-04 06:46:00 +08:00
|
|
|
Result.suppress();
|
|
|
|
return Result;
|
|
|
|
}
|
2013-07-13 10:00:19 +08:00
|
|
|
|
2011-12-22 09:48:48 +08:00
|
|
|
DeclContext *DC = D->getDeclContext()->getRedeclContext();
|
2014-08-30 08:04:23 +08:00
|
|
|
if (TypedefNameForLinkage) {
|
2014-08-23 09:45:27 +08:00
|
|
|
auto It = Reader.ImportedTypedefNamesForLinkage.find(
|
2014-08-30 08:04:23 +08:00
|
|
|
std::make_pair(DC, TypedefNameForLinkage));
|
2014-08-23 09:45:27 +08:00
|
|
|
if (It != Reader.ImportedTypedefNamesForLinkage.end())
|
|
|
|
if (isSameEntity(It->second, D))
|
2014-08-30 08:04:23 +08:00
|
|
|
return FindExistingResult(Reader, D, It->second, AnonymousDeclNumber,
|
|
|
|
TypedefNameForLinkage);
|
2014-08-23 09:45:27 +08:00
|
|
|
// Go on to check in other places in case an existing typedef name
|
|
|
|
// was not imported.
|
|
|
|
}
|
2014-08-28 09:33:39 +08:00
|
|
|
|
2015-02-07 11:11:11 +08:00
|
|
|
if (needsAnonymousDeclarationNumber(D)) {
|
2014-08-28 09:33:39 +08:00
|
|
|
// This is an anonymous declaration that we may need to merge. Look it up
|
|
|
|
// in its context by number.
|
|
|
|
if (auto *Existing = getAnonymousDeclForMerging(
|
|
|
|
Reader, D->getLexicalDeclContext(), AnonymousDeclNumber))
|
|
|
|
if (isSameEntity(Existing, D))
|
2014-08-30 08:04:23 +08:00
|
|
|
return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
|
|
|
|
TypedefNameForLinkage);
|
2016-05-07 07:14:07 +08:00
|
|
|
} else if (DC->isTranslationUnit() &&
|
2015-03-23 11:25:59 +08:00
|
|
|
!Reader.getContext().getLangOpts().CPlusPlus) {
|
2016-05-07 07:14:07 +08:00
|
|
|
IdentifierResolver &IdResolver = Reader.getIdResolver();
|
2013-02-18 23:53:43 +08:00
|
|
|
|
|
|
|
// Temporarily consider the identifier to be up-to-date. We don't want to
|
|
|
|
// cause additional lookups here.
|
|
|
|
class UpToDateIdentifierRAII {
|
|
|
|
IdentifierInfo *II;
|
2018-04-12 04:57:28 +08:00
|
|
|
bool WasOutToDate = false;
|
2013-02-18 23:53:43 +08:00
|
|
|
|
|
|
|
public:
|
2018-04-12 04:57:28 +08:00
|
|
|
explicit UpToDateIdentifierRAII(IdentifierInfo *II) : II(II) {
|
2013-02-18 23:53:43 +08:00
|
|
|
if (II) {
|
|
|
|
WasOutToDate = II->isOutOfDate();
|
|
|
|
if (WasOutToDate)
|
|
|
|
II->setOutOfDate(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~UpToDateIdentifierRAII() {
|
|
|
|
if (WasOutToDate)
|
|
|
|
II->setOutOfDate(true);
|
|
|
|
}
|
|
|
|
} UpToDate(Name.getAsIdentifierInfo());
|
|
|
|
|
2018-07-31 03:24:48 +08:00
|
|
|
for (IdentifierResolver::iterator I = IdResolver.begin(Name),
|
2011-12-22 09:48:48 +08:00
|
|
|
IEnd = IdResolver.end();
|
|
|
|
I != IEnd; ++I) {
|
2014-08-30 08:04:23 +08:00
|
|
|
if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage))
|
2014-08-26 07:33:46 +08:00
|
|
|
if (isSameEntity(Existing, D))
|
2014-08-30 08:04:23 +08:00
|
|
|
return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
|
|
|
|
TypedefNameForLinkage);
|
2011-12-22 09:48:48 +08:00
|
|
|
}
|
2015-01-24 09:07:20 +08:00
|
|
|
} else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) {
|
2013-09-10 00:55:27 +08:00
|
|
|
DeclContext::lookup_result R = MergeDC->noload_lookup(Name);
|
2013-07-13 10:00:19 +08:00
|
|
|
for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) {
|
2014-08-30 08:04:23 +08:00
|
|
|
if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage))
|
2014-08-23 09:45:27 +08:00
|
|
|
if (isSameEntity(Existing, D))
|
2014-08-30 08:04:23 +08:00
|
|
|
return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
|
|
|
|
TypedefNameForLinkage);
|
2012-01-10 01:38:47 +08:00
|
|
|
}
|
2013-10-18 14:05:18 +08:00
|
|
|
} else {
|
|
|
|
// Not in a mergeable context.
|
|
|
|
return FindExistingResult(Reader);
|
2012-01-10 01:38:47 +08:00
|
|
|
}
|
2013-09-10 00:55:27 +08:00
|
|
|
|
2013-10-18 14:05:18 +08:00
|
|
|
// If this declaration is from a merged context, make a note that we need to
|
|
|
|
// check that the canonical definition of that context contains the decl.
|
2014-04-19 11:48:30 +08:00
|
|
|
//
|
|
|
|
// FIXME: We should do something similar if we merge two definitions of the
|
|
|
|
// same template specialization into the same CXXRecordDecl.
|
2014-08-25 10:10:01 +08:00
|
|
|
auto MergedDCIt = Reader.MergedDeclContexts.find(D->getLexicalDeclContext());
|
|
|
|
if (MergedDCIt != Reader.MergedDeclContexts.end() &&
|
|
|
|
MergedDCIt->second == D->getDeclContext())
|
2013-10-18 14:05:18 +08:00
|
|
|
Reader.PendingOdrMergeChecks.push_back(D);
|
|
|
|
|
2014-08-28 09:33:39 +08:00
|
|
|
return FindExistingResult(Reader, D, /*Existing=*/nullptr,
|
2014-08-30 08:04:23 +08:00
|
|
|
AnonymousDeclNumber, TypedefNameForLinkage);
|
2011-12-22 09:48:48 +08:00
|
|
|
}
|
|
|
|
|
2015-02-28 13:57:02 +08:00
|
|
|
template<typename DeclT>
|
|
|
|
Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable<DeclT> *D) {
|
|
|
|
return D->RedeclLink.getLatestNotUpdated();
|
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2015-02-28 13:57:02 +08:00
|
|
|
Decl *ASTDeclReader::getMostRecentDeclImpl(...) {
|
|
|
|
llvm_unreachable("getMostRecentDecl on non-redeclarable declaration");
|
|
|
|
}
|
|
|
|
|
|
|
|
Decl *ASTDeclReader::getMostRecentDecl(Decl *D) {
|
|
|
|
assert(D);
|
|
|
|
|
|
|
|
switch (D->getKind()) {
|
|
|
|
#define ABSTRACT_DECL(TYPE)
|
|
|
|
#define DECL(TYPE, BASE) \
|
|
|
|
case Decl::TYPE: \
|
|
|
|
return getMostRecentDeclImpl(cast<TYPE##Decl>(D));
|
|
|
|
#include "clang/AST/DeclNodes.inc"
|
|
|
|
}
|
|
|
|
llvm_unreachable("unknown decl kind");
|
|
|
|
}
|
|
|
|
|
2015-03-11 09:44:51 +08:00
|
|
|
Decl *ASTReader::getMostRecentExistingDecl(Decl *D) {
|
|
|
|
return ASTDeclReader::getMostRecentDecl(D->getCanonicalDecl());
|
|
|
|
}
|
|
|
|
|
2014-05-13 09:15:00 +08:00
|
|
|
template<typename DeclT>
|
2014-08-01 07:46:44 +08:00
|
|
|
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
|
|
|
|
Redeclarable<DeclT> *D,
|
2015-03-23 11:25:59 +08:00
|
|
|
Decl *Previous, Decl *Canon) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
D->RedeclLink.setPrevious(cast<DeclT>(Previous));
|
2015-03-26 07:18:30 +08:00
|
|
|
D->First = cast<DeclT>(Previous)->First;
|
2014-05-13 09:15:00 +08:00
|
|
|
}
|
2015-10-07 07:40:43 +08:00
|
|
|
|
2014-08-01 07:52:38 +08:00
|
|
|
namespace clang {
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2016-10-15 05:41:24 +08:00
|
|
|
template<>
|
|
|
|
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
|
|
|
|
Redeclarable<VarDecl> *D,
|
|
|
|
Decl *Previous, Decl *Canon) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *VD = static_cast<VarDecl *>(D);
|
|
|
|
auto *PrevVD = cast<VarDecl>(Previous);
|
2016-10-15 05:41:24 +08:00
|
|
|
D->RedeclLink.setPrevious(PrevVD);
|
|
|
|
D->First = PrevVD->First;
|
|
|
|
|
|
|
|
// We should keep at most one definition on the chain.
|
|
|
|
// FIXME: Cache the definition once we've found it. Building a chain with
|
|
|
|
// N definitions currently takes O(N^2) time here.
|
|
|
|
if (VD->isThisDeclarationADefinition() == VarDecl::Definition) {
|
|
|
|
for (VarDecl *CurD = PrevVD; CurD; CurD = CurD->getPreviousDecl()) {
|
|
|
|
if (CurD->isThisDeclarationADefinition() == VarDecl::Definition) {
|
|
|
|
Reader.mergeDefinitionVisibility(CurD, VD);
|
|
|
|
VD->demoteThisDefinitionToDeclaration();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-03 09:00:01 +08:00
|
|
|
static bool isUndeducedReturnType(QualType T) {
|
|
|
|
auto *DT = T->getContainedDeducedType();
|
|
|
|
return DT && !DT->isDeduced();
|
|
|
|
}
|
|
|
|
|
2014-08-01 07:46:44 +08:00
|
|
|
template<>
|
|
|
|
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
|
|
|
|
Redeclarable<FunctionDecl> *D,
|
2015-03-23 11:25:59 +08:00
|
|
|
Decl *Previous, Decl *Canon) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *FD = static_cast<FunctionDecl *>(D);
|
|
|
|
auto *PrevFD = cast<FunctionDecl>(Previous);
|
2014-08-01 07:46:44 +08:00
|
|
|
|
|
|
|
FD->RedeclLink.setPrevious(PrevFD);
|
2015-03-26 07:18:30 +08:00
|
|
|
FD->First = PrevFD->First;
|
2014-08-01 07:46:44 +08:00
|
|
|
|
|
|
|
// If the previous declaration is an inline function declaration, then this
|
|
|
|
// declaration is too.
|
2018-08-02 05:02:40 +08:00
|
|
|
if (PrevFD->isInlined() != FD->isInlined()) {
|
2014-08-01 07:46:44 +08:00
|
|
|
// FIXME: [dcl.fct.spec]p4:
|
|
|
|
// If a function with external linkage is declared inline in one
|
|
|
|
// translation unit, it shall be declared inline in all translation
|
|
|
|
// units in which it appears.
|
|
|
|
//
|
|
|
|
// Be careful of this case:
|
|
|
|
//
|
|
|
|
// module A:
|
|
|
|
// template<typename T> struct X { void f(); };
|
|
|
|
// template<typename T> inline void X<T>::f() {}
|
|
|
|
//
|
|
|
|
// module B instantiates the declaration of X<int>::f
|
|
|
|
// module C instantiates the definition of X<int>::f
|
|
|
|
//
|
|
|
|
// If module B and C are merged, we do not have a violation of this rule.
|
2018-08-02 05:02:40 +08:00
|
|
|
FD->setImplicitlyInline(true);
|
2014-08-01 07:46:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
auto *FPT = FD->getType()->getAs<FunctionProtoType>();
|
|
|
|
auto *PrevFPT = PrevFD->getType()->getAs<FunctionProtoType>();
|
2015-03-10 10:00:53 +08:00
|
|
|
if (FPT && PrevFPT) {
|
2018-08-03 09:00:01 +08:00
|
|
|
// If we need to propagate an exception specification along the redecl
|
|
|
|
// chain, make a note of that so that we can do so later.
|
2015-03-23 11:25:59 +08:00
|
|
|
bool IsUnresolved = isUnresolvedExceptionSpec(FPT->getExceptionSpecType());
|
|
|
|
bool WasUnresolved =
|
|
|
|
isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType());
|
|
|
|
if (IsUnresolved != WasUnresolved)
|
|
|
|
Reader.PendingExceptionSpecUpdates.insert(
|
2018-08-03 09:00:01 +08:00
|
|
|
{Canon, IsUnresolved ? PrevFD : FD});
|
|
|
|
|
|
|
|
// If we need to propagate a deduced return type along the redecl chain,
|
|
|
|
// make a note of that so that we can do it later.
|
|
|
|
bool IsUndeduced = isUndeducedReturnType(FPT->getReturnType());
|
|
|
|
bool WasUndeduced = isUndeducedReturnType(PrevFPT->getReturnType());
|
|
|
|
if (IsUndeduced != WasUndeduced)
|
|
|
|
Reader.PendingDeducedTypeUpdates.insert(
|
|
|
|
{cast<FunctionDecl>(Canon),
|
|
|
|
(IsUndeduced ? PrevFPT : FPT)->getReturnType()});
|
2014-08-01 07:46:44 +08:00
|
|
|
}
|
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
|
|
|
|
} // namespace clang
|
2015-10-07 07:40:43 +08:00
|
|
|
|
2014-08-01 07:46:44 +08:00
|
|
|
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {
|
2014-05-13 09:15:00 +08:00
|
|
|
llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
|
|
|
|
}
|
|
|
|
|
2015-06-10 09:47:58 +08:00
|
|
|
/// Inherit the default template argument from \p From to \p To. Returns
|
|
|
|
/// \c false if there is no default template for \p From.
|
|
|
|
template <typename ParmDecl>
|
|
|
|
static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From,
|
|
|
|
Decl *ToD) {
|
|
|
|
auto *To = cast<ParmDecl>(ToD);
|
|
|
|
if (!From->hasDefaultArgument())
|
|
|
|
return false;
|
2015-06-11 04:30:23 +08:00
|
|
|
To->setInheritedDefaultArgument(Context, From);
|
2015-06-10 09:47:58 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void inheritDefaultTemplateArguments(ASTContext &Context,
|
|
|
|
TemplateDecl *From,
|
|
|
|
TemplateDecl *To) {
|
|
|
|
auto *FromTP = From->getTemplateParameters();
|
|
|
|
auto *ToTP = To->getTemplateParameters();
|
|
|
|
assert(FromTP->size() == ToTP->size() && "merged mismatched templates?");
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = FromTP->size(); I != N; ++I) {
|
2018-08-01 05:01:53 +08:00
|
|
|
NamedDecl *FromParam = FromTP->getParam(I);
|
|
|
|
NamedDecl *ToParam = ToTP->getParam(I);
|
2015-06-10 09:47:58 +08:00
|
|
|
|
2018-08-01 05:01:53 +08:00
|
|
|
if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam))
|
|
|
|
inheritDefaultTemplateArgument(Context, FTTP, ToParam);
|
|
|
|
else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam))
|
|
|
|
inheritDefaultTemplateArgument(Context, FNTTP, ToParam);
|
|
|
|
else
|
|
|
|
inheritDefaultTemplateArgument(
|
|
|
|
Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam);
|
2015-06-10 09:47:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-01 07:46:44 +08:00
|
|
|
void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
|
2015-03-23 11:25:59 +08:00
|
|
|
Decl *Previous, Decl *Canon) {
|
2014-05-13 09:15:00 +08:00
|
|
|
assert(D && Previous);
|
|
|
|
|
|
|
|
switch (D->getKind()) {
|
|
|
|
#define ABSTRACT_DECL(TYPE)
|
2015-03-23 11:25:59 +08:00
|
|
|
#define DECL(TYPE, BASE) \
|
|
|
|
case Decl::TYPE: \
|
|
|
|
attachPreviousDeclImpl(Reader, cast<TYPE##Decl>(D), Previous, Canon); \
|
2014-05-13 09:15:00 +08:00
|
|
|
break;
|
|
|
|
#include "clang/AST/DeclNodes.inc"
|
2011-02-12 15:50:47 +08:00
|
|
|
}
|
2013-08-02 09:09:12 +08:00
|
|
|
|
|
|
|
// If the declaration was visible in one module, a redeclaration of it in
|
|
|
|
// another module remains visible even if it wouldn't be visible by itself.
|
|
|
|
//
|
|
|
|
// FIXME: In this case, the declaration should only be visible if a module
|
|
|
|
// that makes it visible has been imported.
|
|
|
|
D->IdentifierNamespace |=
|
2014-05-13 09:15:00 +08:00
|
|
|
Previous->IdentifierNamespace &
|
2013-08-02 09:09:12 +08:00
|
|
|
(Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
|
2014-05-29 11:15:31 +08:00
|
|
|
|
2015-06-10 09:47:58 +08:00
|
|
|
// If the declaration declares a template, it may inherit default arguments
|
|
|
|
// from the previous declaration.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *TD = dyn_cast<TemplateDecl>(D))
|
2015-06-10 09:47:58 +08:00
|
|
|
inheritDefaultTemplateArguments(Reader.getContext(),
|
|
|
|
cast<TemplateDecl>(Previous), TD);
|
2011-02-12 15:50:47 +08:00
|
|
|
}
|
|
|
|
|
2014-05-13 09:15:00 +08:00
|
|
|
template<typename DeclT>
|
|
|
|
void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
D->RedeclLink.setLatest(cast<DeclT>(Latest));
|
2014-05-13 09:15:00 +08:00
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2014-05-13 09:15:00 +08:00
|
|
|
void ASTDeclReader::attachLatestDeclImpl(...) {
|
|
|
|
llvm_unreachable("attachLatestDecl on non-redeclarable declaration");
|
|
|
|
}
|
|
|
|
|
Completely re-implement (de-)serialization of declaration
chains. The previous implementation relied heavily on the declaration
chain being stored as a (circular) linked list on disk, as it is in
memory. However, when deserializing from multiple modules, the
different chains could get mixed up, leading to broken declaration chains.
The new solution keeps track of the first and last declarations in the
chain for each module file. When we load a declaration, we search all
of the module files for redeclarations of that declaration, then
splice together all of the lists into a coherent whole (along with any
redeclarations that were actually parsed).
As a drive-by fix, (de-)serialize the redeclaration chains of
TypedefNameDecls, which had somehow gotten missed previously. Add a
test of this serialization.
This new scheme creates a redeclaration table that is fairly large in
the PCH file (on the order of 400k for Cocoa.h's 12MB PCH file). The
table is mmap'd in and searched via a binary search, but it's still
quite large. A future tweak will eliminate entries for declarations
that have no redeclarations anywhere, and should
drastically reduce the size of this table.
llvm-svn: 146841
2011-12-18 07:38:30 +08:00
|
|
|
void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
|
|
|
|
assert(D && Latest);
|
2014-05-13 09:15:00 +08:00
|
|
|
|
|
|
|
switch (D->getKind()) {
|
|
|
|
#define ABSTRACT_DECL(TYPE)
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
#define DECL(TYPE, BASE) \
|
|
|
|
case Decl::TYPE: \
|
2014-05-13 09:15:00 +08:00
|
|
|
attachLatestDeclImpl(cast<TYPE##Decl>(D), Latest); \
|
|
|
|
break;
|
|
|
|
#include "clang/AST/DeclNodes.inc"
|
Completely re-implement (de-)serialization of declaration
chains. The previous implementation relied heavily on the declaration
chain being stored as a (circular) linked list on disk, as it is in
memory. However, when deserializing from multiple modules, the
different chains could get mixed up, leading to broken declaration chains.
The new solution keeps track of the first and last declarations in the
chain for each module file. When we load a declaration, we search all
of the module files for redeclarations of that declaration, then
splice together all of the lists into a coherent whole (along with any
redeclarations that were actually parsed).
As a drive-by fix, (de-)serialize the redeclaration chains of
TypedefNameDecls, which had somehow gotten missed previously. Add a
test of this serialization.
This new scheme creates a redeclaration table that is fairly large in
the PCH file (on the order of 400k for Cocoa.h's 12MB PCH file). The
table is mmap'd in and searched via a binary search, but it's still
quite large. A future tweak will eliminate entries for declarations
that have no redeclarations anywhere, and should
drastically reduce the size of this table.
llvm-svn: 146841
2011-12-18 07:38:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-20 04:59:20 +08:00
|
|
|
template<typename DeclT>
|
|
|
|
void ASTDeclReader::markIncompleteDeclChainImpl(Redeclarable<DeclT> *D) {
|
|
|
|
D->RedeclLink.markIncomplete();
|
|
|
|
}
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2014-05-20 04:59:20 +08:00
|
|
|
void ASTDeclReader::markIncompleteDeclChainImpl(...) {
|
|
|
|
llvm_unreachable("markIncompleteDeclChain on non-redeclarable declaration");
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTReader::markIncompleteDeclChain(Decl *D) {
|
|
|
|
switch (D->getKind()) {
|
|
|
|
#define ABSTRACT_DECL(TYPE)
|
|
|
|
#define DECL(TYPE, BASE) \
|
|
|
|
case Decl::TYPE: \
|
|
|
|
ASTDeclReader::markIncompleteDeclChainImpl(cast<TYPE##Decl>(D)); \
|
|
|
|
break;
|
|
|
|
#include "clang/AST/DeclNodes.inc"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Read the declaration at the given offset from the AST file.
|
2011-08-03 23:48:04 +08:00
|
|
|
Decl *ASTReader::ReadDeclRecord(DeclID ID) {
|
2011-08-12 08:15:20 +08:00
|
|
|
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
|
2016-03-27 15:28:06 +08:00
|
|
|
SourceLocation DeclLoc;
|
|
|
|
RecordLocation Loc = DeclCursorForID(ID, DeclLoc);
|
2010-10-05 23:59:54 +08:00
|
|
|
llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
|
2009-04-27 13:27:42 +08:00
|
|
|
// Keep track of where we are in the stream, then jump back there
|
|
|
|
// after reading this declaration.
|
2009-04-27 13:58:23 +08:00
|
|
|
SavedStreamPosition SavedPosition(DeclsCursor);
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2010-06-29 06:28:35 +08:00
|
|
|
ReadingKindTracker ReadingKind(Read_Decl, *this);
|
|
|
|
|
2009-07-07 02:54:52 +08:00
|
|
|
// Note that we are loading a declaration record.
|
2010-07-30 18:03:16 +08:00
|
|
|
Deserializing ADecl(this);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-10-05 23:59:54 +08:00
|
|
|
DeclsCursor.JumpToBit(Loc.Offset);
|
2016-12-21 08:17:49 +08:00
|
|
|
ASTRecordReader Record(*this, *Loc.F);
|
|
|
|
ASTDeclReader Reader(*this, Record, Loc, ID, DeclLoc);
|
2009-04-27 13:58:23 +08:00
|
|
|
unsigned Code = DeclsCursor.ReadCode();
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2017-06-30 07:23:46 +08:00
|
|
|
ASTContext &Context = getContext();
|
2014-05-22 13:54:18 +08:00
|
|
|
Decl *D = nullptr;
|
2016-12-21 08:17:49 +08:00
|
|
|
switch ((DeclCode)Record.readRecord(DeclsCursor, Code)) {
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CONTEXT_LEXICAL:
|
|
|
|
case DECL_CONTEXT_VISIBLE:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord");
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_TYPEDEF:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = TypedefDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2011-04-15 22:24:37 +08:00
|
|
|
case DECL_TYPEALIAS:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = TypeAliasDecl::CreateDeserialized(Context, ID);
|
2011-04-15 22:24:37 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_ENUM:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = EnumDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_RECORD:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = RecordDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_ENUM_CONSTANT:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = EnumConstantDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FUNCTION:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = FunctionDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_LINKAGE_SPEC:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = LinkageSpecDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2016-09-09 07:14:54 +08:00
|
|
|
case DECL_EXPORT:
|
|
|
|
D = ExportDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
2011-02-17 15:39:24 +08:00
|
|
|
case DECL_LABEL:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = LabelDecl::CreateDeserialized(Context, ID);
|
2011-02-17 15:39:24 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_NAMESPACE:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = NamespaceDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_NAMESPACE_ALIAS:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = NamespaceAliasDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_USING:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = UsingDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2016-12-21 05:35:28 +08:00
|
|
|
case DECL_USING_PACK:
|
2016-12-21 08:17:49 +08:00
|
|
|
D = UsingPackDecl::CreateDeserialized(Context, ID, Record.readInt());
|
2016-12-21 05:35:28 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_USING_SHADOW:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = UsingShadowDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
case DECL_CONSTRUCTOR_USING_SHADOW:
|
|
|
|
D = ConstructorUsingShadowDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_USING_DIRECTIVE:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = UsingDirectiveDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_UNRESOLVED_USING_VALUE:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = UnresolvedUsingValueDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_UNRESOLVED_USING_TYPENAME:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_RECORD:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = CXXRecordDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2017-02-18 04:05:37 +08:00
|
|
|
case DECL_CXX_DEDUCTION_GUIDE:
|
|
|
|
D = CXXDeductionGuideDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_METHOD:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = CXXMethodDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_CONSTRUCTOR:
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
D = CXXConstructorDecl::CreateDeserialized(Context, ID, false);
|
|
|
|
break;
|
|
|
|
case DECL_CXX_INHERITED_CONSTRUCTOR:
|
|
|
|
D = CXXConstructorDecl::CreateDeserialized(Context, ID, true);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_DESTRUCTOR:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = CXXDestructorDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_CONVERSION:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = CXXConversionDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_ACCESS_SPEC:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = AccessSpecDecl::CreateDeserialized(Context, ID);
|
2010-06-05 13:09:32 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FRIEND:
|
2016-12-21 08:17:49 +08:00
|
|
|
D = FriendDecl::CreateDeserialized(Context, ID, Record.readInt());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FRIEND_TEMPLATE:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = FriendTemplateDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CLASS_TEMPLATE:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ClassTemplateDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CLASS_TEMPLATE_SPECIALIZATION:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2013-08-06 09:03:05 +08:00
|
|
|
case DECL_VAR_TEMPLATE:
|
|
|
|
D = VarTemplateDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
|
|
|
case DECL_VAR_TEMPLATE_SPECIALIZATION:
|
|
|
|
D = VarTemplateSpecializationDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
|
|
|
case DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION:
|
|
|
|
D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
2011-08-14 11:52:19 +08:00
|
|
|
case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ClassScopeFunctionSpecializationDecl::CreateDeserialized(Context, ID);
|
2011-08-14 11:52:19 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FUNCTION_TEMPLATE:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = FunctionTemplateDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_TEMPLATE_TYPE_PARM:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = TemplateTypeParmDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_NON_TYPE_TEMPLATE_PARM:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2011-01-20 04:10:05 +08:00
|
|
|
case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK:
|
2016-12-21 08:17:49 +08:00
|
|
|
D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID,
|
|
|
|
Record.readInt());
|
2011-01-20 04:10:05 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_TEMPLATE_TEMPLATE_PARM:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2012-09-07 10:06:42 +08:00
|
|
|
case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK:
|
|
|
|
D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID,
|
2016-12-21 08:17:49 +08:00
|
|
|
Record.readInt());
|
2012-09-07 10:06:42 +08:00
|
|
|
break;
|
2011-05-06 05:57:07 +08:00
|
|
|
case DECL_TYPE_ALIAS_TEMPLATE:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID);
|
2011-05-06 05:57:07 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_STATIC_ASSERT:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = StaticAssertDecl::CreateDeserialized(Context, ID);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_METHOD:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCMethodDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_INTERFACE:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCInterfaceDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_IVAR:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCIvarDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_PROTOCOL:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCProtocolDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_AT_DEFS_FIELD:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_CATEGORY:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCCategoryDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_CATEGORY_IMPL:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCCategoryImplDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_IMPLEMENTATION:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCImplementationDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_COMPATIBLE_ALIAS:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_PROPERTY:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCPropertyDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_PROPERTY_IMPL:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ObjCPropertyImplDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FIELD:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = FieldDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-11-21 14:08:52 +08:00
|
|
|
case DECL_INDIRECTFIELD:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = IndirectFieldDecl::CreateDeserialized(Context, ID);
|
2010-11-21 14:08:52 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_VAR:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = VarDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_IMPLICIT_PARAM:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ImplicitParamDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_PARM_VAR:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ParmVarDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2016-08-12 10:21:25 +08:00
|
|
|
case DECL_DECOMPOSITION:
|
2016-12-21 08:17:49 +08:00
|
|
|
D = DecompositionDecl::CreateDeserialized(Context, ID, Record.readInt());
|
2016-08-12 10:21:25 +08:00
|
|
|
break;
|
|
|
|
case DECL_BINDING:
|
|
|
|
D = BindingDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FILE_SCOPE_ASM:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = FileScopeAsmDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_BLOCK:
|
2012-01-06 05:55:30 +08:00
|
|
|
D = BlockDecl::CreateDeserialized(Context, ID);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2013-04-16 15:28:30 +08:00
|
|
|
case DECL_MS_PROPERTY:
|
|
|
|
D = MSPropertyDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
2013-04-17 03:37:38 +08:00
|
|
|
case DECL_CAPTURED:
|
2016-12-21 08:17:49 +08:00
|
|
|
D = CapturedDecl::CreateDeserialized(Context, ID, Record.readInt());
|
2013-04-17 03:37:38 +08:00
|
|
|
break;
|
2010-10-30 06:39:52 +08:00
|
|
|
case DECL_CXX_BASE_SPECIFIERS:
|
|
|
|
Error("attempt to read a C++ base-specifier record as a declaration");
|
2014-05-22 13:54:18 +08:00
|
|
|
return nullptr;
|
2015-03-24 14:36:48 +08:00
|
|
|
case DECL_CXX_CTOR_INITIALIZERS:
|
|
|
|
Error("attempt to read a C++ ctor initializer record as a declaration");
|
|
|
|
return nullptr;
|
2011-12-03 07:23:56 +08:00
|
|
|
case DECL_IMPORT:
|
2018-07-31 03:24:48 +08:00
|
|
|
// Note: last entry of the ImportDecl record is the number of stored source
|
2011-12-03 07:23:56 +08:00
|
|
|
// locations.
|
2012-01-06 05:55:30 +08:00
|
|
|
D = ImportDecl::CreateDeserialized(Context, ID, Record.back());
|
2011-12-03 07:23:56 +08:00
|
|
|
break;
|
2013-03-22 14:34:35 +08:00
|
|
|
case DECL_OMP_THREADPRIVATE:
|
2016-12-21 08:17:49 +08:00
|
|
|
D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt());
|
2013-03-22 14:34:35 +08:00
|
|
|
break;
|
2018-09-26 12:28:39 +08:00
|
|
|
case DECL_OMP_REQUIRES:
|
|
|
|
D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt());
|
|
|
|
break;
|
2016-03-03 13:21:39 +08:00
|
|
|
case DECL_OMP_DECLARE_REDUCTION:
|
|
|
|
D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
2016-02-11 13:35:55 +08:00
|
|
|
case DECL_OMP_CAPTUREDEXPR:
|
|
|
|
D = OMPCapturedExprDecl::CreateDeserialized(Context, ID);
|
2016-02-08 17:29:13 +08:00
|
|
|
break;
|
2016-03-03 01:28:48 +08:00
|
|
|
case DECL_PRAGMA_COMMENT:
|
2016-12-21 08:17:49 +08:00
|
|
|
D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record.readInt());
|
2016-03-03 01:28:48 +08:00
|
|
|
break;
|
2016-03-03 03:28:54 +08:00
|
|
|
case DECL_PRAGMA_DETECT_MISMATCH:
|
|
|
|
D = PragmaDetectMismatchDecl::CreateDeserialized(Context, ID,
|
2016-12-21 08:17:49 +08:00
|
|
|
Record.readInt());
|
2016-03-03 03:28:54 +08:00
|
|
|
break;
|
2013-02-23 01:15:32 +08:00
|
|
|
case DECL_EMPTY:
|
|
|
|
D = EmptyDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
case DECL_OBJC_TYPE_PARAM:
|
|
|
|
D = ObjCTypeParamDecl::CreateDeserialized(Context, ID);
|
|
|
|
break;
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
assert(D && "Unknown declaration reading AST file");
|
2009-04-27 14:01:06 +08:00
|
|
|
LoadedDecl(Index, D);
|
2012-02-09 14:02:44 +08:00
|
|
|
// Set the DeclContext before doing any deserialization, to make sure internal
|
|
|
|
// calls to Decl::getASTContext() by Decl's methods will find the
|
|
|
|
// TranslationUnitDecl without crashing.
|
|
|
|
D->setDeclContext(Context.getTranslationUnitDecl());
|
2009-04-27 14:01:06 +08:00
|
|
|
Reader.Visit(D);
|
2009-04-27 13:27:42 +08:00
|
|
|
|
|
|
|
// If this declaration is also a declaration context, get the
|
|
|
|
// offsets for its tables of lexical and visible declarations.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *DC = dyn_cast<DeclContext>(D)) {
|
2009-04-27 13:27:42 +08:00
|
|
|
std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
|
2015-08-06 12:23:48 +08:00
|
|
|
if (Offsets.first &&
|
|
|
|
ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, Offsets.first, DC))
|
|
|
|
return nullptr;
|
|
|
|
if (Offsets.second &&
|
|
|
|
ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, Offsets.second, ID))
|
|
|
|
return nullptr;
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
2016-12-21 08:17:49 +08:00
|
|
|
assert(Record.getIdx() == Record.size());
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2011-08-12 08:15:20 +08:00
|
|
|
// Load any relevant update records.
|
2017-05-20 00:46:06 +08:00
|
|
|
PendingUpdateRecords.push_back(
|
|
|
|
PendingUpdateRecord(ID, D, /*JustLoaded=*/true));
|
2011-11-14 15:07:59 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
// Load the categories after recursive loading is finished.
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *Class = dyn_cast<ObjCInterfaceDecl>(D))
|
2016-09-10 07:48:27 +08:00
|
|
|
// If we already have a definition when deserializing the ObjCInterfaceDecl,
|
|
|
|
// we put the Decl in PendingDefinitions so we can pull the categories here.
|
|
|
|
if (Class->isThisDeclarationADefinition() ||
|
|
|
|
PendingDefinitions.count(Class))
|
2012-01-27 09:47:08 +08:00
|
|
|
loadObjCCategories(ID, Class);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2016-07-16 05:33:46 +08:00
|
|
|
// If we have deserialized a declaration that has a definition the
|
|
|
|
// AST consumer might need to know about, queue it.
|
|
|
|
// We don't pass it to the consumer immediately because we may be in recursive
|
|
|
|
// loading, and some declarations may still be initializing.
|
2017-10-11 15:47:54 +08:00
|
|
|
PotentiallyInterestingDecls.push_back(
|
|
|
|
InterestingDecl(D, Reader.hasPendingBody()));
|
2016-07-16 05:33:46 +08:00
|
|
|
|
2011-08-12 08:15:20 +08:00
|
|
|
return D;
|
|
|
|
}
|
|
|
|
|
2017-04-13 05:56:05 +08:00
|
|
|
void ASTReader::PassInterestingDeclsToConsumer() {
|
|
|
|
assert(Consumer);
|
|
|
|
|
|
|
|
if (PassingDeclsToConsumer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Guard variable to avoid recursively redoing the process of passing
|
|
|
|
// decls to consumer.
|
|
|
|
SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
|
|
|
|
true);
|
|
|
|
|
|
|
|
// Ensure that we've loaded all potentially-interesting declarations
|
|
|
|
// that need to be eagerly loaded.
|
|
|
|
for (auto ID : EagerlyDeserializedDecls)
|
|
|
|
GetDecl(ID);
|
|
|
|
EagerlyDeserializedDecls.clear();
|
|
|
|
|
|
|
|
while (!PotentiallyInterestingDecls.empty()) {
|
2017-10-11 15:47:54 +08:00
|
|
|
InterestingDecl D = PotentiallyInterestingDecls.front();
|
2017-04-13 05:56:05 +08:00
|
|
|
PotentiallyInterestingDecls.pop_front();
|
2017-10-11 15:47:54 +08:00
|
|
|
if (isConsumerInterestedIn(getContext(), D.getDecl(), D.hasPendingBody()))
|
|
|
|
PassInterestingDeclToConsumer(D.getDecl());
|
2017-04-13 05:56:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-20 00:46:06 +08:00
|
|
|
void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
2010-10-25 01:26:36 +08:00
|
|
|
// The declaration may have been modified by files later in the chain.
|
|
|
|
// If this is the case, read the record containing the updates from each file
|
|
|
|
// and pass it to ASTDeclReader to make the modifications.
|
2017-05-20 00:46:06 +08:00
|
|
|
serialization::GlobalDeclID ID = Record.ID;
|
|
|
|
Decl *D = Record.D;
|
2016-07-23 05:08:24 +08:00
|
|
|
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
|
2010-10-25 01:26:36 +08:00
|
|
|
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
|
2017-07-01 06:40:17 +08:00
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs;
|
2017-07-01 06:40:17 +08:00
|
|
|
|
2010-10-25 01:26:36 +08:00
|
|
|
if (UpdI != DeclUpdateOffsets.end()) {
|
2015-08-06 12:23:48 +08:00
|
|
|
auto UpdateOffsets = std::move(UpdI->second);
|
|
|
|
DeclUpdateOffsets.erase(UpdI);
|
|
|
|
|
2017-05-20 00:46:06 +08:00
|
|
|
// Check if this decl was interesting to the consumer. If we just loaded
|
|
|
|
// the declaration, then we know it was interesting and we skip the call
|
|
|
|
// to isConsumerInterestedIn because it is unsafe to call in the
|
|
|
|
// current ASTReader state.
|
|
|
|
bool WasInteresting =
|
2017-10-11 15:47:54 +08:00
|
|
|
Record.JustLoaded || isConsumerInterestedIn(getContext(), D, false);
|
2015-08-06 12:23:48 +08:00
|
|
|
for (auto &FileAndOffset : UpdateOffsets) {
|
|
|
|
ModuleFile *F = FileAndOffset.first;
|
|
|
|
uint64_t Offset = FileAndOffset.second;
|
2010-10-25 01:26:36 +08:00
|
|
|
llvm::BitstreamCursor &Cursor = F->DeclsCursor;
|
|
|
|
SavedStreamPosition SavedPosition(Cursor);
|
|
|
|
Cursor.JumpToBit(Offset);
|
|
|
|
unsigned Code = Cursor.ReadCode();
|
2016-12-21 08:17:49 +08:00
|
|
|
ASTRecordReader Record(*this, *F);
|
|
|
|
unsigned RecCode = Record.readRecord(Cursor, Code);
|
2010-10-25 01:26:36 +08:00
|
|
|
(void)RecCode;
|
|
|
|
assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
|
2014-03-23 08:27:18 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID,
|
|
|
|
SourceLocation());
|
2017-07-01 06:40:17 +08:00
|
|
|
Reader.UpdateDecl(D, PendingLazySpecializationIDs);
|
2014-03-23 08:27:18 +08:00
|
|
|
|
|
|
|
// We might have made this declaration interesting. If so, remember that
|
|
|
|
// we need to hand it off to the consumer.
|
2017-10-11 15:47:54 +08:00
|
|
|
if (!WasInteresting &&
|
|
|
|
isConsumerInterestedIn(getContext(), D, Reader.hasPendingBody())) {
|
|
|
|
PotentiallyInterestingDecls.push_back(
|
|
|
|
InterestingDecl(D, Reader.hasPendingBody()));
|
2014-03-23 08:27:18 +08:00
|
|
|
WasInteresting = true;
|
|
|
|
}
|
2010-10-25 01:26:36 +08:00
|
|
|
}
|
|
|
|
}
|
2017-07-01 06:40:17 +08:00
|
|
|
// Add the lazy specializations to the template.
|
|
|
|
assert((PendingLazySpecializationIDs.empty() || isa<ClassTemplateDecl>(D) ||
|
|
|
|
isa<FunctionTemplateDecl>(D) || isa<VarTemplateDecl>(D)) &&
|
|
|
|
"Must not have pending specializations");
|
|
|
|
if (auto *CTD = dyn_cast<ClassTemplateDecl>(D))
|
|
|
|
ASTDeclReader::AddLazySpecializations(CTD, PendingLazySpecializationIDs);
|
|
|
|
else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
|
|
|
|
ASTDeclReader::AddLazySpecializations(FTD, PendingLazySpecializationIDs);
|
|
|
|
else if (auto *VTD = dyn_cast<VarTemplateDecl>(D))
|
|
|
|
ASTDeclReader::AddLazySpecializations(VTD, PendingLazySpecializationIDs);
|
|
|
|
PendingLazySpecializationIDs.clear();
|
2016-04-09 04:53:26 +08:00
|
|
|
|
|
|
|
// Load the pending visible updates for this decl context, if it has any.
|
|
|
|
auto I = PendingVisibleUpdates.find(ID);
|
|
|
|
if (I != PendingVisibleUpdates.end()) {
|
|
|
|
auto VisibleUpdates = std::move(I->second);
|
|
|
|
PendingVisibleUpdates.erase(I);
|
|
|
|
|
|
|
|
auto *DC = cast<DeclContext>(D)->getPrimaryContext();
|
2018-04-12 04:57:28 +08:00
|
|
|
for (const auto &Update : VisibleUpdates)
|
2016-04-09 04:53:26 +08:00
|
|
|
Lookups[DC].Table.add(
|
|
|
|
Update.Mod, Update.Data,
|
|
|
|
reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
|
|
|
|
DC->setHasExternalVisibleStorage(true);
|
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
2010-10-25 01:26:36 +08:00
|
|
|
|
2015-08-23 04:13:39 +08:00
|
|
|
void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
|
|
|
|
// Attach FirstLocal to the end of the decl chain.
|
|
|
|
Decl *CanonDecl = FirstLocal->getCanonicalDecl();
|
|
|
|
if (FirstLocal != CanonDecl) {
|
|
|
|
Decl *PrevMostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl);
|
|
|
|
ASTDeclReader::attachPreviousDecl(
|
|
|
|
*this, FirstLocal, PrevMostRecent ? PrevMostRecent : CanonDecl,
|
|
|
|
CanonDecl);
|
|
|
|
}
|
2015-08-22 10:09:38 +08:00
|
|
|
|
2015-08-23 04:13:39 +08:00
|
|
|
if (!LocalOffset) {
|
|
|
|
ASTDeclReader::attachLatestDecl(CanonDecl, FirstLocal);
|
|
|
|
return;
|
2015-08-22 10:09:38 +08:00
|
|
|
}
|
|
|
|
|
2015-08-23 04:13:39 +08:00
|
|
|
// Load the list of other redeclarations from this module file.
|
|
|
|
ModuleFile *M = getOwningModuleFile(FirstLocal);
|
|
|
|
assert(M && "imported decl from no module file");
|
|
|
|
|
|
|
|
llvm::BitstreamCursor &Cursor = M->DeclsCursor;
|
|
|
|
SavedStreamPosition SavedPosition(Cursor);
|
|
|
|
Cursor.JumpToBit(LocalOffset);
|
|
|
|
|
|
|
|
RecordData Record;
|
|
|
|
unsigned Code = Cursor.ReadCode();
|
|
|
|
unsigned RecCode = Cursor.readRecord(Code, Record);
|
|
|
|
(void)RecCode;
|
|
|
|
assert(RecCode == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!");
|
|
|
|
|
|
|
|
// FIXME: We have several different dispatches on decl kind here; maybe
|
2015-02-28 13:57:02 +08:00
|
|
|
// we should instead generate one loop per kind and dispatch up-front?
|
2015-08-23 04:13:39 +08:00
|
|
|
Decl *MostRecent = FirstLocal;
|
|
|
|
for (unsigned I = 0, N = Record.size(); I != N; ++I) {
|
|
|
|
auto *D = GetLocalDecl(*M, Record[N - I - 1]);
|
2015-07-15 08:02:40 +08:00
|
|
|
ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
|
|
|
|
MostRecent = D;
|
Completely re-implement (de-)serialization of declaration
chains. The previous implementation relied heavily on the declaration
chain being stored as a (circular) linked list on disk, as it is in
memory. However, when deserializing from multiple modules, the
different chains could get mixed up, leading to broken declaration chains.
The new solution keeps track of the first and last declarations in the
chain for each module file. When we load a declaration, we search all
of the module files for redeclarations of that declaration, then
splice together all of the lists into a coherent whole (along with any
redeclarations that were actually parsed).
As a drive-by fix, (de-)serialize the redeclaration chains of
TypedefNameDecls, which had somehow gotten missed previously. Add a
test of this serialization.
This new scheme creates a redeclaration table that is fairly large in
the PCH file (on the order of 400k for Cocoa.h's 12MB PCH file). The
table is mmap'd in and searched via a binary search, but it's still
quite large. A future tweak will eliminate entries for declarations
that have no redeclarations anywhere, and should
drastically reduce the size of this table.
llvm-svn: 146841
2011-12-18 07:38:30 +08:00
|
|
|
}
|
2015-02-28 13:57:02 +08:00
|
|
|
ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent);
|
Completely re-implement (de-)serialization of declaration
chains. The previous implementation relied heavily on the declaration
chain being stored as a (circular) linked list on disk, as it is in
memory. However, when deserializing from multiple modules, the
different chains could get mixed up, leading to broken declaration chains.
The new solution keeps track of the first and last declarations in the
chain for each module file. When we load a declaration, we search all
of the module files for redeclarations of that declaration, then
splice together all of the lists into a coherent whole (along with any
redeclarations that were actually parsed).
As a drive-by fix, (de-)serialize the redeclaration chains of
TypedefNameDecls, which had somehow gotten missed previously. Add a
test of this serialization.
This new scheme creates a redeclaration table that is fairly large in
the PCH file (on the order of 400k for Cocoa.h's 12MB PCH file). The
table is mmap'd in and searched via a binary search, but it's still
quite large. A future tweak will eliminate entries for declarations
that have no redeclarations anywhere, and should
drastically reduce the size of this table.
llvm-svn: 146841
2011-12-18 07:38:30 +08:00
|
|
|
}
|
|
|
|
|
2011-09-01 08:58:55 +08:00
|
|
|
namespace {
|
2018-04-12 04:57:28 +08:00
|
|
|
|
2018-05-09 09:00:01 +08:00
|
|
|
/// Given an ObjC interface, goes through the modules and links to the
|
2011-09-01 08:58:55 +08:00
|
|
|
/// interface all the categories for it.
|
2012-01-27 09:47:08 +08:00
|
|
|
class ObjCCategoriesVisitor {
|
2011-09-01 08:58:55 +08:00
|
|
|
ASTReader &Reader;
|
|
|
|
ObjCInterfaceDecl *Interface;
|
2014-08-18 07:49:53 +08:00
|
|
|
llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized;
|
2018-04-12 04:57:28 +08:00
|
|
|
ObjCCategoryDecl *Tail = nullptr;
|
2011-09-01 08:58:55 +08:00
|
|
|
llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap;
|
2016-09-24 10:07:19 +08:00
|
|
|
serialization::GlobalDeclID InterfaceID;
|
|
|
|
unsigned PreviousGeneration;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
void add(ObjCCategoryDecl *Cat) {
|
|
|
|
// Only process each category once.
|
2012-08-22 23:37:55 +08:00
|
|
|
if (!Deserialized.erase(Cat))
|
2012-01-27 09:47:08 +08:00
|
|
|
return;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
// Check for duplicate categories.
|
|
|
|
if (Cat->getDeclName()) {
|
|
|
|
ObjCCategoryDecl *&Existing = NameCategoryMap[Cat->getDeclName()];
|
2018-07-31 03:24:48 +08:00
|
|
|
if (Existing &&
|
|
|
|
Reader.getOwningModuleFile(Existing)
|
2012-01-27 09:47:08 +08:00
|
|
|
!= Reader.getOwningModuleFile(Cat)) {
|
|
|
|
// FIXME: We should not warn for duplicates in diamond:
|
|
|
|
//
|
|
|
|
// MT //
|
|
|
|
// / \ //
|
|
|
|
// ML MR //
|
|
|
|
// \ / //
|
|
|
|
// MB //
|
|
|
|
//
|
2018-07-31 03:24:48 +08:00
|
|
|
// If there are duplicates in ML/MR, there will be warning when
|
|
|
|
// creating MB *and* when importing MB. We should not warn when
|
2012-01-27 09:47:08 +08:00
|
|
|
// importing.
|
|
|
|
Reader.Diag(Cat->getLocation(), diag::warn_dup_category_def)
|
|
|
|
<< Interface->getDeclName() << Cat->getDeclName();
|
|
|
|
Reader.Diag(Existing->getLocation(), diag::note_previous_definition);
|
|
|
|
} else if (!Existing) {
|
|
|
|
// Record this category.
|
|
|
|
Existing = Cat;
|
|
|
|
}
|
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
// Add this category to the end of the chain.
|
|
|
|
if (Tail)
|
|
|
|
ASTDeclReader::setNextObjCCategory(Tail, Cat);
|
|
|
|
else
|
2013-01-17 07:00:23 +08:00
|
|
|
Interface->setCategoryListRaw(Cat);
|
2012-01-27 09:47:08 +08:00
|
|
|
Tail = Cat;
|
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2011-09-01 08:58:55 +08:00
|
|
|
public:
|
2012-01-27 09:47:08 +08:00
|
|
|
ObjCCategoriesVisitor(ASTReader &Reader,
|
|
|
|
ObjCInterfaceDecl *Interface,
|
2016-09-24 10:07:19 +08:00
|
|
|
llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized,
|
|
|
|
serialization::GlobalDeclID InterfaceID,
|
2012-01-27 09:47:08 +08:00
|
|
|
unsigned PreviousGeneration)
|
2018-04-12 04:57:28 +08:00
|
|
|
: Reader(Reader), Interface(Interface), Deserialized(Deserialized),
|
|
|
|
InterfaceID(InterfaceID), PreviousGeneration(PreviousGeneration) {
|
2012-01-27 09:47:08 +08:00
|
|
|
// Populate the name -> category map with the set of known categories.
|
2014-03-14 05:35:02 +08:00
|
|
|
for (auto *Cat : Interface->known_categories()) {
|
2012-01-27 09:47:08 +08:00
|
|
|
if (Cat->getDeclName())
|
2014-03-14 05:35:02 +08:00
|
|
|
NameCategoryMap[Cat->getDeclName()] = Cat;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
// Keep track of the tail of the category list.
|
2014-03-14 05:35:02 +08:00
|
|
|
Tail = Cat;
|
2012-01-27 09:47:08 +08:00
|
|
|
}
|
|
|
|
}
|
2011-09-01 08:58:55 +08:00
|
|
|
|
2015-07-25 20:14:04 +08:00
|
|
|
bool operator()(ModuleFile &M) {
|
2012-01-27 09:47:08 +08:00
|
|
|
// If we've loaded all of the category information we care about from
|
|
|
|
// this module file, we're done.
|
|
|
|
if (M.Generation <= PreviousGeneration)
|
|
|
|
return true;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
|
|
|
// Map global ID of the definition down to the local ID used in this
|
2012-01-27 09:47:08 +08:00
|
|
|
// module file. If there is no such mapping, we'll find nothing here
|
|
|
|
// (or in any module it imports).
|
|
|
|
DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID);
|
|
|
|
if (!LocalID)
|
|
|
|
return true;
|
2011-09-01 08:58:55 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
// Perform a binary search to find the local redeclarations for this
|
|
|
|
// declaration (if any).
|
2014-03-15 22:21:58 +08:00
|
|
|
const ObjCCategoriesInfo Compare = { LocalID, 0 };
|
2012-01-27 09:47:08 +08:00
|
|
|
const ObjCCategoriesInfo *Result
|
|
|
|
= std::lower_bound(M.ObjCCategoriesMap,
|
2018-07-31 03:24:48 +08:00
|
|
|
M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap,
|
2014-03-15 22:21:58 +08:00
|
|
|
Compare);
|
2012-01-27 09:47:08 +08:00
|
|
|
if (Result == M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap ||
|
|
|
|
Result->DefinitionID != LocalID) {
|
|
|
|
// We didn't find anything. If the class definition is in this module
|
|
|
|
// file, then the module files it depends on cannot have any categories,
|
|
|
|
// so suppress further lookup.
|
|
|
|
return Reader.isDeclIDFromModule(InterfaceID, M);
|
2011-09-01 08:58:55 +08:00
|
|
|
}
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
// We found something. Dig out all of the categories.
|
|
|
|
unsigned Offset = Result->Offset;
|
|
|
|
unsigned N = M.ObjCCategories[Offset];
|
|
|
|
M.ObjCCategories[Offset++] = 0; // Don't try to deserialize again
|
|
|
|
for (unsigned I = 0; I != N; ++I)
|
|
|
|
add(cast_or_null<ObjCCategoryDecl>(
|
|
|
|
Reader.GetLocalDecl(M, M.ObjCCategories[Offset++])));
|
|
|
|
return true;
|
2011-09-01 08:58:55 +08:00
|
|
|
}
|
|
|
|
};
|
2018-04-12 04:57:28 +08:00
|
|
|
|
|
|
|
} // namespace
|
2011-09-01 08:58:55 +08:00
|
|
|
|
2012-01-27 09:47:08 +08:00
|
|
|
void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID,
|
|
|
|
ObjCInterfaceDecl *D,
|
|
|
|
unsigned PreviousGeneration) {
|
2016-09-24 10:07:19 +08:00
|
|
|
ObjCCategoriesVisitor Visitor(*this, D, CategoriesDeserialized, ID,
|
2012-01-27 09:47:08 +08:00
|
|
|
PreviousGeneration);
|
2015-07-25 20:14:04 +08:00
|
|
|
ModuleMgr.visit(Visitor);
|
2011-09-01 08:58:55 +08:00
|
|
|
}
|
2011-08-12 08:15:20 +08:00
|
|
|
|
2014-08-08 04:58:41 +08:00
|
|
|
template<typename DeclT, typename Fn>
|
|
|
|
static void forAllLaterRedecls(DeclT *D, Fn F) {
|
|
|
|
F(D);
|
|
|
|
|
|
|
|
// Check whether we've already merged D into its redeclaration chain.
|
|
|
|
// MostRecent may or may not be nullptr if D has not been merged. If
|
|
|
|
// not, walk the merged redecl chain and see if it's there.
|
|
|
|
auto *MostRecent = D->getMostRecentDecl();
|
|
|
|
bool Found = false;
|
|
|
|
for (auto *Redecl = MostRecent; Redecl && !Found;
|
|
|
|
Redecl = Redecl->getPreviousDecl())
|
|
|
|
Found = (Redecl == D);
|
|
|
|
|
|
|
|
// If this declaration is merged, apply the functor to all later decls.
|
|
|
|
if (Found) {
|
|
|
|
for (auto *Redecl = MostRecent; Redecl != D;
|
|
|
|
Redecl = Redecl->getPreviousDecl())
|
|
|
|
F(Redecl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-01 06:40:17 +08:00
|
|
|
void ASTDeclReader::UpdateDecl(Decl *D,
|
|
|
|
llvm::SmallVectorImpl<serialization::DeclID> &PendingLazySpecializationIDs) {
|
2016-12-21 08:17:49 +08:00
|
|
|
while (Record.getIdx() < Record.size()) {
|
|
|
|
switch ((DeclUpdateKind)Record.readInt()) {
|
2014-04-19 11:48:30 +08:00
|
|
|
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
|
2015-01-22 11:50:31 +08:00
|
|
|
auto *RD = cast<CXXRecordDecl>(D);
|
2014-08-08 04:58:41 +08:00
|
|
|
// FIXME: If we also have an update record for instantiating the
|
|
|
|
// definition of D, we need that to happen before we get here.
|
2016-12-21 12:34:52 +08:00
|
|
|
Decl *MD = Record.readDecl();
|
2014-04-19 11:48:30 +08:00
|
|
|
assert(MD && "couldn't read decl from update record");
|
2014-08-01 09:56:39 +08:00
|
|
|
// FIXME: We should call addHiddenDecl instead, to add the member
|
|
|
|
// to its DeclContext.
|
2015-01-22 11:50:31 +08:00
|
|
|
RD->addedMember(MD);
|
2010-10-25 01:26:54 +08:00
|
|
|
break;
|
2014-04-19 11:48:30 +08:00
|
|
|
}
|
2010-10-28 15:38:42 +08:00
|
|
|
|
|
|
|
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
|
2017-07-01 06:40:17 +08:00
|
|
|
// It will be added to the template's lazy specialization set.
|
|
|
|
PendingLazySpecializationIDs.push_back(ReadDeclID());
|
2011-04-25 00:28:13 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Anon = ReadDeclAs<NamespaceDecl>();
|
2016-12-16 04:53:26 +08:00
|
|
|
|
2012-01-10 02:07:24 +08:00
|
|
|
// Each module has its own anonymous namespace, which is disjoint from
|
|
|
|
// any other module's anonymous namespaces, so don't attach the anonymous
|
|
|
|
// namespace at all.
|
2016-12-16 04:53:26 +08:00
|
|
|
if (!Record.isModule()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *TU = dyn_cast<TranslationUnitDecl>(D))
|
2012-01-10 02:07:24 +08:00
|
|
|
TU->setAnonymousNamespace(Anon);
|
|
|
|
else
|
|
|
|
cast<NamespaceDecl>(D)->setAnonymousNamespace(Anon);
|
|
|
|
}
|
2011-04-25 00:28:13 +08:00
|
|
|
break;
|
|
|
|
}
|
2011-04-29 16:19:30 +08:00
|
|
|
|
2017-12-05 09:31:47 +08:00
|
|
|
case UPD_CXX_ADDED_VAR_DEFINITION: {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *VD = cast<VarDecl>(D);
|
2017-11-02 09:06:00 +08:00
|
|
|
VD->NonParmVarDeclBits.IsInline = Record.readInt();
|
|
|
|
VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt();
|
2017-06-23 06:18:46 +08:00
|
|
|
uint64_t Val = Record.readInt();
|
|
|
|
if (Val && !VD->getInit()) {
|
|
|
|
VD->setInit(Record.readExpr());
|
|
|
|
if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3
|
|
|
|
EvaluatedStmt *Eval = VD->ensureEvaluatedStmt();
|
|
|
|
Eval->CheckedICE = true;
|
|
|
|
Eval->IsICE = Val == 3;
|
|
|
|
}
|
|
|
|
}
|
2011-04-29 16:19:30 +08:00
|
|
|
break;
|
2017-06-23 06:18:46 +08:00
|
|
|
}
|
2013-05-11 13:45:24 +08:00
|
|
|
|
2017-12-05 09:31:47 +08:00
|
|
|
case UPD_CXX_POINT_OF_INSTANTIATION: {
|
|
|
|
SourceLocation POI = Record.readSourceLocation();
|
2018-04-12 04:57:28 +08:00
|
|
|
if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) {
|
2017-12-05 09:31:47 +08:00
|
|
|
VTSD->setPointOfInstantiation(POI);
|
|
|
|
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
|
|
|
|
VD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
|
|
|
|
} else {
|
|
|
|
auto *FD = cast<FunctionDecl>(D);
|
|
|
|
if (auto *FTSInfo = FD->TemplateOrSpecialization
|
|
|
|
.dyn_cast<FunctionTemplateSpecializationInfo *>())
|
|
|
|
FTSInfo->setPointOfInstantiation(POI);
|
|
|
|
else
|
|
|
|
FD->TemplateOrSpecialization.get<MemberSpecializationInfo *>()
|
|
|
|
->setPointOfInstantiation(POI);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-01-07 06:34:54 +08:00
|
|
|
case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT: {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Param = cast<ParmVarDecl>(D);
|
2016-01-07 06:34:54 +08:00
|
|
|
|
|
|
|
// We have to read the default argument regardless of whether we use it
|
|
|
|
// so that hypothetical further update records aren't messed up.
|
|
|
|
// TODO: Add a function to skip over the next expr record.
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *DefaultArg = Record.readExpr();
|
2016-01-07 06:34:54 +08:00
|
|
|
|
|
|
|
// Only apply the update if the parameter still has an uninstantiated
|
|
|
|
// default argument.
|
|
|
|
if (Param->hasUninstantiatedDefaultArg())
|
|
|
|
Param->setDefaultArg(DefaultArg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-08-25 05:25:37 +08:00
|
|
|
case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER: {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *FD = cast<FieldDecl>(D);
|
|
|
|
auto *DefaultInit = Record.readExpr();
|
2016-08-25 05:25:37 +08:00
|
|
|
|
|
|
|
// Only apply the update if the field still has an uninstantiated
|
|
|
|
// default member initializer.
|
|
|
|
if (FD->hasInClassInitializer() && !FD->getInClassInitializer()) {
|
|
|
|
if (DefaultInit)
|
|
|
|
FD->setInClassInitializer(DefaultInit);
|
|
|
|
else
|
|
|
|
// Instantiation failed. We can get here if we serialized an AST for
|
|
|
|
// an invalid program.
|
|
|
|
FD->removeInClassInitializer();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-08-08 02:53:08 +08:00
|
|
|
case UPD_CXX_ADDED_FUNCTION_DEFINITION: {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *FD = cast<FunctionDecl>(D);
|
2017-10-11 15:47:54 +08:00
|
|
|
if (Reader.PendingBodies[FD]) {
|
|
|
|
// FIXME: Maybe check for ODR violations.
|
|
|
|
// It's safe to stop now because this update record is always last.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) {
|
2014-05-29 11:15:31 +08:00
|
|
|
// Maintain AST consistency: any later redeclarations of this function
|
|
|
|
// are inline if this one is. (We might have merged another declaration
|
|
|
|
// into this one.)
|
2014-08-08 04:58:41 +08:00
|
|
|
forAllLaterRedecls(FD, [](FunctionDecl *FD) {
|
|
|
|
FD->setImplicitlyInline();
|
|
|
|
});
|
2014-05-29 11:15:31 +08:00
|
|
|
}
|
2016-12-16 04:53:26 +08:00
|
|
|
FD->setInnerLocStart(ReadSourceLocation());
|
2017-02-13 02:45:31 +08:00
|
|
|
ReadFunctionDefinition(FD);
|
2016-12-21 08:17:49 +08:00
|
|
|
assert(Record.getIdx() == Record.size() && "lazy body must be last");
|
2014-03-23 07:33:22 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-04-19 11:48:30 +08:00
|
|
|
case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
|
|
|
|
auto *RD = cast<CXXRecordDecl>(D);
|
2016-05-18 06:44:15 +08:00
|
|
|
auto *OldDD = RD->getCanonicalDecl()->DefinitionData;
|
2015-02-03 11:32:14 +08:00
|
|
|
bool HadRealDefinition =
|
2015-02-04 09:23:46 +08:00
|
|
|
OldDD && (OldDD->Definition != RD ||
|
|
|
|
!Reader.PendingFakeDefinitionData.count(OldDD));
|
2018-03-29 05:13:14 +08:00
|
|
|
RD->setParamDestroyedInCallee(Record.readInt());
|
2018-04-10 06:48:22 +08:00
|
|
|
RD->setArgPassingRestrictions(
|
|
|
|
(RecordDecl::ArgPassingKind)Record.readInt());
|
2015-02-03 11:32:14 +08:00
|
|
|
ReadCXXRecordDefinition(RD, /*Update*/true);
|
|
|
|
|
2014-04-19 11:48:30 +08:00
|
|
|
// Visible update is handled separately.
|
2016-12-16 04:53:26 +08:00
|
|
|
uint64_t LexicalOffset = ReadLocalOffset();
|
2015-01-24 09:07:20 +08:00
|
|
|
if (!HadRealDefinition && LexicalOffset) {
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readLexicalDeclContextStorage(LexicalOffset, RD);
|
2015-02-03 11:32:14 +08:00
|
|
|
Reader.PendingFakeDefinitionData.erase(OldDD);
|
2014-04-19 11:48:30 +08:00
|
|
|
}
|
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
auto TSK = (TemplateSpecializationKind)Record.readInt();
|
2016-12-16 04:53:26 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation();
|
2014-04-19 11:48:30 +08:00
|
|
|
if (MemberSpecializationInfo *MSInfo =
|
|
|
|
RD->getMemberSpecializationInfo()) {
|
|
|
|
MSInfo->setTemplateSpecializationKind(TSK);
|
|
|
|
MSInfo->setPointOfInstantiation(POI);
|
|
|
|
} else {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *Spec = cast<ClassTemplateSpecializationDecl>(RD);
|
2014-04-19 11:48:30 +08:00
|
|
|
Spec->setTemplateSpecializationKind(TSK);
|
|
|
|
Spec->setPointOfInstantiation(POI);
|
2014-05-23 04:59:29 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) {
|
2018-04-12 04:57:28 +08:00
|
|
|
auto *PartialSpec =
|
2016-12-16 04:53:26 +08:00
|
|
|
ReadDeclAs<ClassTemplatePartialSpecializationDecl>();
|
2014-05-23 04:59:29 +08:00
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readTemplateArgumentList(TemplArgs);
|
2014-05-23 04:59:29 +08:00
|
|
|
auto *TemplArgList = TemplateArgumentList::CreateCopy(
|
2016-07-04 05:17:51 +08:00
|
|
|
Reader.getContext(), TemplArgs);
|
2014-08-14 11:30:27 +08:00
|
|
|
|
|
|
|
// FIXME: If we already have a partial specialization set,
|
|
|
|
// check that it matches.
|
|
|
|
if (!Spec->getSpecializedTemplateOrPartial()
|
|
|
|
.is<ClassTemplatePartialSpecializationDecl *>())
|
|
|
|
Spec->setInstantiationOf(PartialSpec, TemplArgList);
|
2014-05-23 04:59:29 +08:00
|
|
|
}
|
2014-04-19 11:48:30 +08:00
|
|
|
}
|
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
RD->setTagKind((TagTypeKind)Record.readInt());
|
2016-12-16 04:53:26 +08:00
|
|
|
RD->setLocation(ReadSourceLocation());
|
|
|
|
RD->setLocStart(ReadSourceLocation());
|
|
|
|
RD->setBraceRange(ReadSourceRange());
|
2014-04-19 11:48:30 +08:00
|
|
|
|
2016-12-21 08:17:49 +08:00
|
|
|
if (Record.readInt()) {
|
2014-04-19 11:48:30 +08:00
|
|
|
AttrVec Attrs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readAttributes(Attrs);
|
2016-10-26 10:31:56 +08:00
|
|
|
// If the declaration already has attributes, we assume that some other
|
|
|
|
// AST file already loaded them.
|
|
|
|
if (!D->hasAttrs())
|
|
|
|
D->setAttrsImpl(Attrs, Reader.getContext());
|
2014-04-19 11:48:30 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-03-10 09:41:22 +08:00
|
|
|
case UPD_CXX_RESOLVED_DTOR_DELETE: {
|
|
|
|
// Set the 'operator delete' directly to avoid emitting another update
|
|
|
|
// record.
|
2016-12-16 04:53:26 +08:00
|
|
|
auto *Del = ReadDeclAs<FunctionDecl>();
|
2015-03-10 09:41:22 +08:00
|
|
|
auto *First = cast<CXXDestructorDecl>(D->getCanonicalDecl());
|
2017-10-13 09:55:36 +08:00
|
|
|
auto *ThisArg = Record.readExpr();
|
2015-03-10 09:41:22 +08:00
|
|
|
// FIXME: Check consistency if we have an old and new operator delete.
|
2017-10-13 09:55:36 +08:00
|
|
|
if (!First->OperatorDelete) {
|
2015-03-10 09:41:22 +08:00
|
|
|
First->OperatorDelete = Del;
|
2017-10-13 09:55:36 +08:00
|
|
|
First->OperatorDeleteThisArg = ThisArg;
|
|
|
|
}
|
2015-03-10 09:41:22 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-03-21 05:47:22 +08:00
|
|
|
case UPD_CXX_RESOLVED_EXCEPTION_SPEC: {
|
2014-08-01 05:57:55 +08:00
|
|
|
FunctionProtoType::ExceptionSpecInfo ESI;
|
2014-08-01 07:46:44 +08:00
|
|
|
SmallVector<QualType, 8> ExceptionStorage;
|
2016-12-21 08:17:49 +08:00
|
|
|
Record.readExceptionSpec(ExceptionStorage, ESI);
|
2015-03-23 11:25:59 +08:00
|
|
|
|
|
|
|
// Update this declaration's exception specification, if needed.
|
|
|
|
auto *FD = cast<FunctionDecl>(D);
|
|
|
|
auto *FPT = FD->getType()->castAs<FunctionProtoType>();
|
|
|
|
// FIXME: If the exception specification is already present, check that it
|
|
|
|
// matches.
|
|
|
|
if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
|
2017-06-30 07:23:46 +08:00
|
|
|
FD->setType(Reader.getContext().getFunctionType(
|
2014-08-01 07:46:44 +08:00
|
|
|
FPT->getReturnType(), FPT->getParamTypes(),
|
|
|
|
FPT->getExtProtoInfo().withExceptionSpec(ESI)));
|
2015-03-23 11:25:59 +08:00
|
|
|
|
|
|
|
// When we get to the end of deserializing, see if there are other decls
|
|
|
|
// that we need to propagate this exception specification onto.
|
|
|
|
Reader.PendingExceptionSpecUpdates.insert(
|
|
|
|
std::make_pair(FD->getCanonicalDecl(), FD));
|
2014-08-01 07:46:44 +08:00
|
|
|
}
|
2014-03-21 05:47:22 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-05-11 13:45:24 +08:00
|
|
|
case UPD_CXX_DEDUCED_RETURN_TYPE: {
|
2018-08-03 09:00:01 +08:00
|
|
|
auto *FD = cast<FunctionDecl>(D);
|
2016-12-21 08:17:49 +08:00
|
|
|
QualType DeducedResultType = Record.readType();
|
2018-08-03 09:00:01 +08:00
|
|
|
Reader.PendingDeducedTypeUpdates.insert(
|
|
|
|
{FD->getCanonicalDecl(), DeducedResultType});
|
2013-05-11 13:45:24 +08:00
|
|
|
break;
|
|
|
|
}
|
2013-09-05 08:02:25 +08:00
|
|
|
|
2018-04-12 04:57:28 +08:00
|
|
|
case UPD_DECL_MARKED_USED:
|
2014-06-17 04:26:19 +08:00
|
|
|
// Maintain AST consistency: any later redeclarations are used too.
|
2017-06-30 07:23:46 +08:00
|
|
|
D->markUsed(Reader.getContext());
|
2013-09-05 08:02:25 +08:00
|
|
|
break;
|
2014-03-21 09:48:23 +08:00
|
|
|
|
|
|
|
case UPD_MANGLING_NUMBER:
|
2017-06-30 07:23:46 +08:00
|
|
|
Reader.getContext().setManglingNumber(cast<NamedDecl>(D),
|
|
|
|
Record.readInt());
|
2014-03-21 09:48:23 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case UPD_STATIC_LOCAL_NUMBER:
|
2017-06-30 07:23:46 +08:00
|
|
|
Reader.getContext().setStaticLocalNumber(cast<VarDecl>(D),
|
|
|
|
Record.readInt());
|
2014-03-21 09:48:23 +08:00
|
|
|
break;
|
2015-03-26 12:09:53 +08:00
|
|
|
|
2014-11-11 12:05:39 +08:00
|
|
|
case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:
|
2017-06-30 07:23:46 +08:00
|
|
|
D->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(Reader.getContext(),
|
|
|
|
ReadSourceRange()));
|
2014-11-11 12:05:39 +08:00
|
|
|
break;
|
2015-03-26 12:09:53 +08:00
|
|
|
|
2015-06-26 13:28:36 +08:00
|
|
|
case UPD_DECL_EXPORTED: {
|
2016-12-16 04:53:26 +08:00
|
|
|
unsigned SubmoduleID = readSubmoduleID();
|
2015-06-20 09:05:19 +08:00
|
|
|
auto *Exported = cast<NamedDecl>(D);
|
2015-03-26 12:09:53 +08:00
|
|
|
Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr;
|
2018-09-13 07:37:00 +08:00
|
|
|
Reader.getContext().mergeDefinitionIntoModule(Exported, Owner);
|
|
|
|
Reader.PendingMergedDefinitionsToDeduplicate.insert(Exported);
|
2015-03-26 12:09:53 +08:00
|
|
|
break;
|
2010-10-25 01:26:50 +08:00
|
|
|
}
|
2015-06-26 13:28:36 +08:00
|
|
|
|
2016-05-09 22:59:13 +08:00
|
|
|
case UPD_DECL_MARKED_OPENMP_DECLARETARGET:
|
2018-08-16 03:45:12 +08:00
|
|
|
D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(
|
|
|
|
Reader.getContext(),
|
|
|
|
static_cast<OMPDeclareTargetDeclAttr::MapTypeTy>(Record.readInt()),
|
|
|
|
ReadSourceRange()));
|
|
|
|
break;
|
|
|
|
|
2015-06-26 13:28:36 +08:00
|
|
|
case UPD_ADDED_ATTR_TO_RECORD:
|
|
|
|
AttrVec Attrs;
|
2016-12-21 12:34:52 +08:00
|
|
|
Record.readAttributes(Attrs);
|
2015-06-26 13:28:36 +08:00
|
|
|
assert(Attrs.size() == 1);
|
|
|
|
D->addAttr(Attrs[0]);
|
|
|
|
break;
|
|
|
|
}
|
2010-10-25 01:26:50 +08:00
|
|
|
}
|
2010-10-25 01:26:36 +08:00
|
|
|
}
|