2010-08-19 07:56:31 +08:00
|
|
|
//===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===//
|
2009-04-27 14:16:06 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements serialization for Declarations.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-04-25 00:28:13 +08:00
|
|
|
#include "ASTCommon.h"
|
2010-05-08 05:43:38 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/AST/DeclContextInternals.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"
|
2009-04-27 14:16:06 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2011-10-29 06:54:21 +08:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Serialization/ASTReader.h"
|
2016-07-19 03:02:11 +08:00
|
|
|
#include "clang/Serialization/ASTWriter.h"
|
2009-04-27 14:16:06 +08:00
|
|
|
#include "llvm/Bitcode/BitstreamWriter.h"
|
2009-12-03 17:13:36 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2009-04-27 14:16:06 +08:00
|
|
|
using namespace clang;
|
2011-04-25 00:28:13 +08:00
|
|
|
using namespace serialization;
|
2009-04-27 14:16:06 +08:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Declaration serialization
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-30 06:47:00 +08:00
|
|
|
namespace clang {
|
2010-08-19 07:56:27 +08:00
|
|
|
class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
|
2010-08-19 07:56:21 +08:00
|
|
|
ASTWriter &Writer;
|
2009-04-27 14:16:06 +08:00
|
|
|
ASTContext &Context;
|
2016-04-02 06:52:03 +08:00
|
|
|
ASTRecordWriter Record;
|
2009-04-27 14:16:06 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
serialization::DeclCode Code;
|
2009-04-27 15:35:58 +08:00
|
|
|
unsigned AbbrevToUse;
|
2009-04-27 14:16:06 +08:00
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
public:
|
|
|
|
ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
|
|
|
|
ASTWriter::RecordDataImpl &Record)
|
|
|
|
: Writer(Writer), Context(Context), Record(Writer, Record),
|
|
|
|
Code((serialization::DeclCode)0), AbbrevToUse(0) {}
|
|
|
|
|
|
|
|
uint64_t Emit(Decl *D) {
|
|
|
|
if (!Code)
|
|
|
|
llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
|
|
|
|
D->getDeclKindName() + "'");
|
2016-04-14 08:29:55 +08:00
|
|
|
return Record.Emit(Code, AbbrevToUse);
|
2009-04-27 15:35:58 +08:00
|
|
|
}
|
2010-10-25 01:26:27 +08:00
|
|
|
|
2010-07-02 23:58:43 +08:00
|
|
|
void Visit(Decl *D);
|
2009-04-27 14:16:06 +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 14:16:06 +08:00
|
|
|
void VisitTranslationUnitDecl(TranslationUnitDecl *D);
|
|
|
|
void VisitNamedDecl(NamedDecl *D);
|
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 14:16:06 +08:00
|
|
|
void VisitTypeDecl(TypeDecl *D);
|
2011-12-19 22:40:25 +08:00
|
|
|
void VisitTypedefNameDecl(TypedefNameDecl *D);
|
2009-04-27 14:16:06 +08:00
|
|
|
void VisitTypedefDecl(TypedefDecl *D);
|
2011-04-15 22:24:37 +08:00
|
|
|
void VisitTypeAliasDecl(TypeAliasDecl *D);
|
2010-06-30 16:49:30 +08:00
|
|
|
void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
|
2009-04-27 14:16:06 +08:00
|
|
|
void VisitTagDecl(TagDecl *D);
|
|
|
|
void VisitEnumDecl(EnumDecl *D);
|
|
|
|
void VisitRecordDecl(RecordDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitCXXRecordDecl(CXXRecordDecl *D);
|
|
|
|
void VisitClassTemplateSpecializationDecl(
|
|
|
|
ClassTemplateSpecializationDecl *D);
|
|
|
|
void VisitClassTemplatePartialSpecializationDecl(
|
|
|
|
ClassTemplatePartialSpecializationDecl *D);
|
2013-08-06 09:03:05 +08:00
|
|
|
void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
|
|
|
|
void VisitVarTemplatePartialSpecializationDecl(
|
|
|
|
VarTemplatePartialSpecializationDecl *D);
|
2011-08-28 04:50:59 +08:00
|
|
|
void VisitClassScopeFunctionSpecializationDecl(
|
|
|
|
ClassScopeFunctionSpecializationDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
|
2009-04-27 14:16:06 +08:00
|
|
|
void VisitValueDecl(ValueDecl *D);
|
|
|
|
void VisitEnumConstantDecl(EnumConstantDecl *D);
|
2010-06-30 16:49:30 +08:00
|
|
|
void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
|
2009-08-19 09:28:35 +08:00
|
|
|
void VisitDeclaratorDecl(DeclaratorDecl *D);
|
2009-04-27 14:16:06 +08:00
|
|
|
void VisitFunctionDecl(FunctionDecl *D);
|
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 14:16:06 +08:00
|
|
|
void VisitFieldDecl(FieldDecl *D);
|
2013-04-16 15:28:30 +08:00
|
|
|
void VisitMSPropertyDecl(MSPropertyDecl *D);
|
2010-11-21 14:08:52 +08:00
|
|
|
void VisitIndirectFieldDecl(IndirectFieldDecl *D);
|
2009-04-27 14:16:06 +08:00
|
|
|
void VisitVarDecl(VarDecl *D);
|
|
|
|
void VisitImplicitParamDecl(ImplicitParamDecl *D);
|
|
|
|
void VisitParmVarDecl(ParmVarDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
|
|
|
|
void VisitTemplateDecl(TemplateDecl *D);
|
2010-07-30 00:11:51 +08:00
|
|
|
void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitClassTemplateDecl(ClassTemplateDecl *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);
|
|
|
|
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);
|
2009-04-27 14:16:06 +08:00
|
|
|
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
|
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 14:16:06 +08:00
|
|
|
void VisitBlockDecl(BlockDecl *D);
|
2013-04-17 03:37:38 +08:00
|
|
|
void VisitCapturedDecl(CapturedDecl *D);
|
2013-02-23 01:15:32 +08:00
|
|
|
void VisitEmptyDecl(EmptyDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
|
2016-04-13 10:12:03 +08:00
|
|
|
void VisitDeclContext(DeclContext *DC);
|
2010-08-04 01:30:10 +08:00
|
|
|
template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
|
|
|
|
|
2010-05-30 15:21:58 +08:00
|
|
|
// FIXME: Put in the same order is DeclNodes.td?
|
2009-04-27 14:16:06 +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 14:16:06 +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);
|
2016-02-11 13:35:55 +08:00
|
|
|
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
|
2014-03-23 07:33:22 +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
|
|
|
/// Add an Objective-C type parameter list to the given record.
|
|
|
|
void AddObjCTypeParamList(ObjCTypeParamList *typeParams) {
|
|
|
|
// Empty type parameter list.
|
|
|
|
if (!typeParams) {
|
|
|
|
Record.push_back(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Record.push_back(typeParams->size());
|
|
|
|
for (auto typeParam : *typeParams) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(typeParam);
|
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
|
|
|
}
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(typeParams->getLAngleLoc());
|
|
|
|
Record.AddSourceLocation(typeParams->getRAngleLoc());
|
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
|
|
|
}
|
|
|
|
|
2015-08-22 09:47:18 +08:00
|
|
|
/// Add to the record the first declaration from each module file that
|
|
|
|
/// provides a declaration of D. The intent is to provide a sufficient
|
|
|
|
/// set such that reloading this set will load all current redeclarations.
|
|
|
|
void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
|
|
|
|
llvm::MapVector<ModuleFile*, const Decl*> Firsts;
|
|
|
|
// FIXME: We can skip entries that we know are implied by others.
|
2015-08-28 05:38:25 +08:00
|
|
|
for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
|
|
|
|
if (R->isFromASTFile())
|
2015-08-22 09:47:18 +08:00
|
|
|
Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
|
2015-08-28 05:38:25 +08:00
|
|
|
else if (IncludeLocal)
|
|
|
|
Firsts[nullptr] = R;
|
|
|
|
}
|
2015-08-22 09:47:18 +08:00
|
|
|
for (const auto &F : Firsts)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(F.second);
|
2015-08-22 09:47:18 +08:00
|
|
|
}
|
|
|
|
|
2015-02-28 07:05:10 +08:00
|
|
|
/// Get the specialization decl from an entry in the specialization list.
|
|
|
|
template <typename EntryType>
|
|
|
|
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
|
|
|
|
getSpecializationDecl(EntryType &T) {
|
|
|
|
return RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::getDecl(&T);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the list of partial specializations from a template's common ptr.
|
|
|
|
template<typename T>
|
|
|
|
decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) {
|
|
|
|
return Common->PartialSpecializations;
|
|
|
|
}
|
|
|
|
ArrayRef<Decl> getPartialSpecializations(FunctionTemplateDecl::Common *) {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2016-02-25 05:59:10 +08:00
|
|
|
template<typename DeclTy>
|
|
|
|
void AddTemplateSpecializations(DeclTy *D) {
|
2015-02-28 07:05:10 +08:00
|
|
|
auto *Common = D->getCommonPtr();
|
|
|
|
|
|
|
|
// If we have any lazy specializations, and the external AST source is
|
|
|
|
// our chained AST reader, we can just write out the DeclIDs. Otherwise,
|
|
|
|
// we need to resolve them to actual declarations.
|
|
|
|
if (Writer.Chain != Writer.Context->getExternalSource() &&
|
|
|
|
Common->LazySpecializations) {
|
|
|
|
D->LoadLazySpecializations();
|
|
|
|
assert(!Common->LazySpecializations);
|
|
|
|
}
|
|
|
|
|
|
|
|
ArrayRef<DeclID> LazySpecializations;
|
|
|
|
if (auto *LS = Common->LazySpecializations)
|
2015-09-29 12:53:28 +08:00
|
|
|
LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]);
|
2015-02-28 07:05:10 +08:00
|
|
|
|
2015-08-22 09:47:18 +08:00
|
|
|
// Add a slot to the record for the number of specializations.
|
|
|
|
unsigned I = Record.size();
|
|
|
|
Record.push_back(0);
|
|
|
|
|
2016-02-25 05:59:10 +08:00
|
|
|
// AddFirstDeclFromEachModule might trigger deserialization, invalidating
|
|
|
|
// *Specializations iterators.
|
|
|
|
llvm::SmallVector<const Decl*, 16> Specs;
|
|
|
|
for (auto &Entry : Common->Specializations)
|
|
|
|
Specs.push_back(getSpecializationDecl(Entry));
|
|
|
|
for (auto &Entry : getPartialSpecializations(Common))
|
|
|
|
Specs.push_back(getSpecializationDecl(Entry));
|
|
|
|
|
|
|
|
for (auto *D : Specs) {
|
2015-02-28 07:05:10 +08:00
|
|
|
assert(D->isCanonicalDecl() && "non-canonical decl in set");
|
2015-08-22 09:47:18 +08:00
|
|
|
AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
|
2015-02-28 07:05:10 +08:00
|
|
|
}
|
2015-06-12 23:31:50 +08:00
|
|
|
Record.append(LazySpecializations.begin(), LazySpecializations.end());
|
2015-08-22 09:47:18 +08:00
|
|
|
|
|
|
|
// Update the size entry we added earlier.
|
|
|
|
Record[I] = Record.size() - I - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Ensure that this template specialization is associated with the specified
|
|
|
|
/// template on reload.
|
|
|
|
void RegisterTemplateSpecialization(const Decl *Template,
|
|
|
|
const Decl *Specialization) {
|
|
|
|
Template = Template->getCanonicalDecl();
|
|
|
|
|
|
|
|
// If the canonical template is local, we'll write out this specialization
|
|
|
|
// when we emit it.
|
|
|
|
// FIXME: We can do the same thing if there is any local declaration of
|
|
|
|
// the template, to avoid emitting an update record.
|
|
|
|
if (!Template->isFromASTFile())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// We only need to associate the first local declaration of the
|
|
|
|
// specialization. The other declarations will get pulled in by it.
|
|
|
|
if (Writer.getFirstLocalDecl(Specialization) != Specialization)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Writer.DeclUpdates[Template].push_back(ASTWriter::DeclUpdate(
|
|
|
|
UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, Specialization));
|
2015-02-28 07:05:10 +08:00
|
|
|
}
|
2009-04-27 14:16:06 +08:00
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2009-04-27 14:16:06 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::Visit(Decl *D) {
|
|
|
|
DeclVisitor<ASTDeclWriter>::Visit(D);
|
2010-07-02 23:58:43 +08:00
|
|
|
|
2011-06-04 07:11:16 +08:00
|
|
|
// Source locations require array (variable-length) abbreviations. The
|
|
|
|
// abbreviation infrastructure requires that arrays are encoded last, so
|
|
|
|
// we handle it here in the case of those classes derived from DeclaratorDecl
|
2015-10-19 04:32:12 +08:00
|
|
|
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(DD->getTypeSourceInfo());
|
2011-06-04 07:11:16 +08:00
|
|
|
}
|
|
|
|
|
2010-07-02 23:58:43 +08:00
|
|
|
// Handle FunctionDecl's body here and write it after all other Stmts/Exprs
|
|
|
|
// have been written. We want it last because we will not read it back when
|
2010-08-19 07:56:27 +08:00
|
|
|
// retrieving it from the AST, we'll just lazily set the offset.
|
2010-07-02 23:58:43 +08:00
|
|
|
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
2011-05-07 04:44:56 +08:00
|
|
|
Record.push_back(FD->doesThisDeclarationHaveABody());
|
|
|
|
if (FD->doesThisDeclarationHaveABody())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddFunctionDefinition(FD);
|
2010-07-02 23:58:43 +08:00
|
|
|
}
|
2016-04-13 10:12:03 +08:00
|
|
|
|
|
|
|
// If this declaration is also a DeclContext, write blocks for the
|
|
|
|
// declarations that lexically stored inside its context and those
|
|
|
|
// declarations that are visible from its context.
|
|
|
|
if (DeclContext *DC = dyn_cast<DeclContext>(D))
|
|
|
|
VisitDeclContext(DC);
|
2010-07-02 23:58:43 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitDecl(Decl *D) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()));
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() != D->getLexicalDeclContext())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()));
|
2015-12-12 06:41:00 +08:00
|
|
|
else
|
|
|
|
Record.push_back(0);
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->isInvalidDecl());
|
|
|
|
Record.push_back(D->hasAttrs());
|
2010-10-19 03:20:11 +08:00
|
|
|
if (D->hasAttrs())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddAttributes(D->getAttrs());
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->isImplicit());
|
2010-06-18 07:14:26 +08:00
|
|
|
Record.push_back(D->isUsed(false));
|
2011-04-20 03:51:10 +08:00
|
|
|
Record.push_back(D->isReferenced());
|
2012-01-07 00:59:53 +08:00
|
|
|
Record.push_back(D->isTopLevelDeclInObjCContainer());
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->getAccess());
|
2012-01-07 00:59:53 +08:00
|
|
|
Record.push_back(D->isModulePrivate());
|
2011-12-01 10:07:58 +08:00
|
|
|
Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation()));
|
2014-03-23 10:30:01 +08:00
|
|
|
|
|
|
|
// If this declaration injected a name into a context different from its
|
|
|
|
// lexical context, and that context is an imported namespace, we need to
|
|
|
|
// update its visible declarations to include this name.
|
|
|
|
//
|
|
|
|
// This happens when we instantiate a class with a friend declaration or a
|
|
|
|
// function with a local extern declaration, for instance.
|
2015-07-13 07:43:21 +08:00
|
|
|
//
|
|
|
|
// FIXME: Can we handle this in AddedVisibleDecl instead?
|
2014-03-23 10:30:01 +08:00
|
|
|
if (D->isOutOfLine()) {
|
2014-03-24 04:41:56 +08:00
|
|
|
auto *DC = D->getDeclContext();
|
|
|
|
while (auto *NS = dyn_cast<NamespaceDecl>(DC->getRedeclContext())) {
|
|
|
|
if (!NS->isFromASTFile())
|
|
|
|
break;
|
2015-03-26 12:27:10 +08:00
|
|
|
Writer.UpdatedDeclContexts.insert(NS->getPrimaryContext());
|
2014-03-24 04:41:56 +08:00
|
|
|
if (!NS->isInlineNamespace())
|
|
|
|
break;
|
|
|
|
DC = NS->getParent();
|
|
|
|
}
|
2014-03-23 10:30:01 +08:00
|
|
|
}
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2016-03-03 01:28:48 +08:00
|
|
|
void ASTDeclWriter::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
|
|
|
|
StringRef Arg = D->getArg();
|
|
|
|
Record.push_back(Arg.size());
|
|
|
|
VisitDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocStart());
|
2016-03-03 01:28:48 +08:00
|
|
|
Record.push_back(D->getCommentKind());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddString(Arg);
|
2016-03-03 01:28:48 +08:00
|
|
|
Code = serialization::DECL_PRAGMA_COMMENT;
|
|
|
|
}
|
|
|
|
|
2016-03-03 03:28:54 +08:00
|
|
|
void ASTDeclWriter::VisitPragmaDetectMismatchDecl(
|
|
|
|
PragmaDetectMismatchDecl *D) {
|
|
|
|
StringRef Name = D->getName();
|
|
|
|
StringRef Value = D->getValue();
|
|
|
|
Record.push_back(Name.size() + 1 + Value.size());
|
|
|
|
VisitDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocStart());
|
|
|
|
Record.AddString(Name);
|
|
|
|
Record.AddString(Value);
|
2016-03-03 03:28:54 +08:00
|
|
|
Code = serialization::DECL_PRAGMA_DETECT_MISMATCH;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
|
2011-08-12 08:15:20 +08:00
|
|
|
llvm_unreachable("Translation units aren't directly serialized");
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclarationName(D->getDeclName());
|
2015-02-07 11:11:11 +08:00
|
|
|
Record.push_back(needsAnonymousDeclarationNumber(D)
|
|
|
|
? Writer.getAnonymousDeclarationNumber(D)
|
|
|
|
: 0);
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocStart());
|
|
|
|
Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2011-12-19 22:40:25 +08:00
|
|
|
void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *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
|
|
|
VisitRedeclarable(D);
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitTypeDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getTypeSourceInfo());
|
2013-06-20 20:46:19 +08:00
|
|
|
Record.push_back(D->isModed());
|
|
|
|
if (D->isModed())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeRef(D->getUnderlyingType());
|
2011-12-19 22:40:25 +08:00
|
|
|
}
|
2011-06-04 07:11:16 +08:00
|
|
|
|
2011-12-19 22:40:25 +08:00
|
|
|
void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
|
|
|
|
VisitTypedefNameDecl(D);
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() == D->getLexicalDeclContext() &&
|
|
|
|
!D->hasAttrs() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->isImplicit() &&
|
2013-10-17 23:37:26 +08:00
|
|
|
D->getFirstDecl() == D->getMostRecentDecl() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->isInvalidDecl() &&
|
2011-11-24 05:11:23 +08:00
|
|
|
!D->isTopLevelDeclInObjCContainer() &&
|
2011-09-09 10:06:17 +08:00
|
|
|
!D->isModulePrivate() &&
|
2014-08-28 09:33:39 +08:00
|
|
|
!needsAnonymousDeclarationNumber(D) &&
|
2011-06-04 07:11:16 +08:00
|
|
|
D->getDeclName().getNameKind() == DeclarationName::Identifier)
|
|
|
|
AbbrevToUse = Writer.getDeclTypedefAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_TYPEDEF;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 22:24:37 +08:00
|
|
|
void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
|
2011-12-19 22:40:25 +08:00
|
|
|
VisitTypedefNameDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getDescribedAliasTemplate());
|
2011-04-15 22:24:37 +08:00
|
|
|
Code = serialization::DECL_TYPEALIAS;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
|
2010-08-04 01:30:10 +08:00
|
|
|
VisitRedeclarable(D);
|
2011-10-27 01:53:41 +08:00
|
|
|
VisitTypeDecl(D);
|
2010-09-09 03:31:22 +08:00
|
|
|
Record.push_back(D->getIdentifierNamespace());
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
|
2014-08-28 07:11:59 +08:00
|
|
|
if (!isa<CXXRecordDecl>(D))
|
|
|
|
Record.push_back(D->isCompleteDefinition());
|
2010-02-13 01:40:34 +08:00
|
|
|
Record.push_back(D->isEmbeddedInDeclarator());
|
2011-10-01 06:11:31 +08:00
|
|
|
Record.push_back(D->isFreeStanding());
|
2013-07-14 09:07:41 +08:00
|
|
|
Record.push_back(D->isCompleteDefinitionRequired());
|
2016-07-16 02:11:33 +08:00
|
|
|
Record.AddSourceRange(D->getBraceRange());
|
2014-08-30 08:04:23 +08:00
|
|
|
|
|
|
|
if (D->hasExtInfo()) {
|
|
|
|
Record.push_back(1);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddQualifierInfo(*D->getExtInfo());
|
2014-08-30 08:04:23 +08:00
|
|
|
} else if (auto *TD = D->getTypedefNameForAnonDecl()) {
|
|
|
|
Record.push_back(2);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(TD);
|
|
|
|
Record.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo());
|
2014-08-30 08:04:23 +08:00
|
|
|
} else {
|
|
|
|
Record.push_back(0);
|
|
|
|
}
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitTagDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getIntegerTypeSourceInfo());
|
2010-10-09 07:50:27 +08:00
|
|
|
if (!D->getIntegerTypeSourceInfo())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeRef(D->getIntegerType());
|
|
|
|
Record.AddTypeRef(D->getPromotionType());
|
2010-05-06 16:49:23 +08:00
|
|
|
Record.push_back(D->getNumPositiveBits());
|
|
|
|
Record.push_back(D->getNumNegativeBits());
|
2010-10-09 07:50:27 +08:00
|
|
|
Record.push_back(D->isScoped());
|
2010-12-04 02:54:17 +08:00
|
|
|
Record.push_back(D->isScopedUsingClassTag());
|
2010-10-09 07:50:27 +08:00
|
|
|
Record.push_back(D->isFixed());
|
2012-03-15 07:13:10 +08:00
|
|
|
if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
|
2012-03-15 07:13:10 +08:00
|
|
|
Record.push_back(MemberInfo->getTemplateSpecializationKind());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
|
2012-03-15 07:13:10 +08:00
|
|
|
} else {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(nullptr);
|
2012-03-15 07:13:10 +08:00
|
|
|
}
|
2011-06-04 07:11:16 +08:00
|
|
|
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() == D->getLexicalDeclContext() &&
|
|
|
|
!D->hasAttrs() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->isImplicit() &&
|
|
|
|
!D->isUsed(false) &&
|
|
|
|
!D->hasExtInfo() &&
|
2014-08-30 08:04:23 +08:00
|
|
|
!D->getTypedefNameForAnonDecl() &&
|
2013-10-17 23:37:26 +08:00
|
|
|
D->getFirstDecl() == D->getMostRecentDecl() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->isInvalidDecl() &&
|
|
|
|
!D->isReferenced() &&
|
2011-11-24 05:11:23 +08:00
|
|
|
!D->isTopLevelDeclInObjCContainer() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
D->getAccess() == AS_none &&
|
2011-09-09 10:06:17 +08:00
|
|
|
!D->isModulePrivate() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!CXXRecordDecl::classofKind(D->getKind()) &&
|
|
|
|
!D->getIntegerTypeSourceInfo() &&
|
2013-03-19 06:23:49 +08:00
|
|
|
!D->getMemberSpecializationInfo() &&
|
2014-08-28 09:33:39 +08:00
|
|
|
!needsAnonymousDeclarationNumber(D) &&
|
2011-06-04 07:11:16 +08:00
|
|
|
D->getDeclName().getNameKind() == DeclarationName::Identifier)
|
|
|
|
AbbrevToUse = Writer.getDeclEnumAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_ENUM;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitTagDecl(D);
|
|
|
|
Record.push_back(D->hasFlexibleArrayMember());
|
|
|
|
Record.push_back(D->isAnonymousStructOrUnion());
|
2009-07-09 00:37:44 +08:00
|
|
|
Record.push_back(D->hasObjectMember());
|
2013-01-26 07:57:05 +08:00
|
|
|
Record.push_back(D->hasVolatileMember());
|
2011-06-03 10:27:19 +08:00
|
|
|
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() == D->getLexicalDeclContext() &&
|
|
|
|
!D->hasAttrs() &&
|
2011-06-03 10:27:19 +08:00
|
|
|
!D->isImplicit() &&
|
|
|
|
!D->isUsed(false) &&
|
|
|
|
!D->hasExtInfo() &&
|
2014-08-30 08:04:23 +08:00
|
|
|
!D->getTypedefNameForAnonDecl() &&
|
2013-10-17 23:37:26 +08:00
|
|
|
D->getFirstDecl() == D->getMostRecentDecl() &&
|
2011-06-03 10:27:19 +08:00
|
|
|
!D->isInvalidDecl() &&
|
|
|
|
!D->isReferenced() &&
|
2011-11-24 05:11:23 +08:00
|
|
|
!D->isTopLevelDeclInObjCContainer() &&
|
2011-06-03 10:27:19 +08:00
|
|
|
D->getAccess() == AS_none &&
|
2011-09-09 10:06:17 +08:00
|
|
|
!D->isModulePrivate() &&
|
2011-06-03 10:27:19 +08:00
|
|
|
!CXXRecordDecl::classofKind(D->getKind()) &&
|
2014-08-28 09:33:39 +08:00
|
|
|
!needsAnonymousDeclarationNumber(D) &&
|
2011-06-03 10:27:19 +08:00
|
|
|
D->getDeclName().getNameKind() == DeclarationName::Identifier)
|
|
|
|
AbbrevToUse = Writer.getDeclRecordAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_RECORD;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeRef(D->getType());
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitValueDecl(D);
|
|
|
|
Record.push_back(D->getInitExpr()? 1 : 0);
|
|
|
|
if (D->getInitExpr())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getInitExpr());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddAPSInt(D->getInitVal());
|
2011-06-03 10:27:19 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_ENUM_CONSTANT;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
2009-08-19 09:28:35 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitValueDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getInnerLocStart());
|
2010-10-16 02:21:24 +08:00
|
|
|
Record.push_back(D->hasExtInfo());
|
|
|
|
if (D->hasExtInfo())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddQualifierInfo(*D->getExtInfo());
|
2009-08-19 09:28:35 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
|
2010-09-09 03:31:22 +08:00
|
|
|
VisitRedeclarable(D);
|
2011-10-27 01:53:41 +08:00
|
|
|
VisitDeclaratorDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
|
2010-07-05 18:38:01 +08:00
|
|
|
Record.push_back(D->getIdentifierNamespace());
|
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 ASTWriterDecl::Visit,
|
|
|
|
// after everything else is written.
|
|
|
|
|
2015-02-07 07:20:21 +08:00
|
|
|
Record.push_back((int)D->SClass); // FIXME: stable encoding
|
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
|
|
|
Record.push_back(D->IsInline);
|
2015-02-07 07:20:21 +08:00
|
|
|
Record.push_back(D->IsInlineSpecified);
|
|
|
|
Record.push_back(D->IsVirtualAsWritten);
|
|
|
|
Record.push_back(D->IsPure);
|
|
|
|
Record.push_back(D->HasInheritedPrototype);
|
|
|
|
Record.push_back(D->HasWrittenPrototype);
|
|
|
|
Record.push_back(D->IsDeleted);
|
|
|
|
Record.push_back(D->IsTrivial);
|
|
|
|
Record.push_back(D->IsDefaulted);
|
|
|
|
Record.push_back(D->IsExplicitlyDefaulted);
|
|
|
|
Record.push_back(D->HasImplicitReturnZero);
|
|
|
|
Record.push_back(D->IsConstexpr);
|
2012-12-07 02:59:10 +08:00
|
|
|
Record.push_back(D->HasSkippedBody);
|
2015-02-07 07:20:21 +08:00
|
|
|
Record.push_back(D->IsLateTemplateParsed);
|
2013-05-13 08:12:11 +08:00
|
|
|
Record.push_back(D->getLinkageInternal());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocEnd());
|
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
|
|
|
|
2010-06-22 17:55:07 +08:00
|
|
|
Record.push_back(D->getTemplatedKind());
|
|
|
|
switch (D->getTemplatedKind()) {
|
|
|
|
case FunctionDecl::TK_NonTemplate:
|
|
|
|
break;
|
|
|
|
case FunctionDecl::TK_FunctionTemplate:
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getDescribedFunctionTemplate());
|
2010-06-22 17:55:07 +08:00
|
|
|
break;
|
|
|
|
case FunctionDecl::TK_MemberSpecialization: {
|
|
|
|
MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
|
2010-06-22 17:55:07 +08:00
|
|
|
Record.push_back(MemberInfo->getTemplateSpecializationKind());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
|
2010-06-22 17:55:07 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case FunctionDecl::TK_FunctionTemplateSpecialization: {
|
|
|
|
FunctionTemplateSpecializationInfo *
|
|
|
|
FTSInfo = D->getTemplateSpecializationInfo();
|
2015-08-22 09:47:18 +08:00
|
|
|
|
|
|
|
RegisterTemplateSpecialization(FTSInfo->getTemplate(), D);
|
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(FTSInfo->getTemplate());
|
2010-06-22 17:55:07 +08:00
|
|
|
Record.push_back(FTSInfo->getTemplateSpecializationKind());
|
|
|
|
|
|
|
|
// Template arguments.
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateArgumentList(FTSInfo->TemplateArguments);
|
2010-06-22 17:55:07 +08:00
|
|
|
|
|
|
|
// Template args as written.
|
2014-05-22 13:54:18 +08:00
|
|
|
Record.push_back(FTSInfo->TemplateArgumentsAsWritten != nullptr);
|
2010-06-22 17:55:07 +08:00
|
|
|
if (FTSInfo->TemplateArgumentsAsWritten) {
|
2011-09-23 04:07:09 +08:00
|
|
|
Record.push_back(FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs);
|
|
|
|
for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs;
|
|
|
|
i!=e; ++i)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateArgumentLoc(
|
|
|
|
(*FTSInfo->TemplateArgumentsAsWritten)[i]);
|
|
|
|
Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->LAngleLoc);
|
|
|
|
Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->RAngleLoc);
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
2010-07-05 18:37:55 +08:00
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(FTSInfo->getPointOfInstantiation());
|
2010-09-13 19:45:48 +08:00
|
|
|
|
|
|
|
if (D->isCanonicalDecl()) {
|
|
|
|
// Write the template that contains the specializations set. We will
|
|
|
|
// add a FunctionTemplateSpecializationInfo to it when reading.
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl());
|
2010-09-13 19:45:48 +08:00
|
|
|
}
|
2010-06-26 00:24:51 +08:00
|
|
|
break;
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
|
|
|
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
|
|
|
|
DependentFunctionTemplateSpecializationInfo *
|
|
|
|
DFTSInfo = D->getDependentSpecializationInfo();
|
|
|
|
|
|
|
|
// Templates.
|
|
|
|
Record.push_back(DFTSInfo->getNumTemplates());
|
|
|
|
for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(DFTSInfo->getTemplate(i));
|
2010-06-22 17:55:07 +08:00
|
|
|
|
|
|
|
// Templates args.
|
|
|
|
Record.push_back(DFTSInfo->getNumTemplateArgs());
|
|
|
|
for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i));
|
|
|
|
Record.AddSourceLocation(DFTSInfo->getLAngleLoc());
|
|
|
|
Record.AddSourceLocation(DFTSInfo->getRAngleLoc());
|
2010-06-26 00:24:51 +08:00
|
|
|
break;
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->param_size());
|
2016-06-24 12:05:48 +08:00
|
|
|
for (auto P : D->parameters())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(P);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_FUNCTION;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitNamedDecl(D);
|
|
|
|
// FIXME: convert to LazyStmtPtr?
|
2009-09-09 23:08:12 +08:00
|
|
|
// Unlike C/C++, method bodies will never be in header files.
|
2014-05-22 13:54:18 +08:00
|
|
|
bool HasBodyStuff = D->getBody() != nullptr ||
|
|
|
|
D->getSelfDecl() != nullptr || D->getCmdDecl() != nullptr;
|
2010-08-09 18:54:37 +08:00
|
|
|
Record.push_back(HasBodyStuff);
|
|
|
|
if (HasBodyStuff) {
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getBody());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getSelfDecl());
|
|
|
|
Record.AddDeclRef(D->getCmdDecl());
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
Record.push_back(D->isInstanceMethod());
|
|
|
|
Record.push_back(D->isVariadic());
|
2012-10-11 00:42:25 +08:00
|
|
|
Record.push_back(D->isPropertyAccessor());
|
2010-07-23 02:24:20 +08:00
|
|
|
Record.push_back(D->isDefined());
|
2012-05-10 00:12:57 +08:00
|
|
|
Record.push_back(D->IsOverriding);
|
2012-12-07 02:59:10 +08:00
|
|
|
Record.push_back(D->HasSkippedBody);
|
2011-10-15 01:41:52 +08:00
|
|
|
|
|
|
|
Record.push_back(D->IsRedeclaration);
|
|
|
|
Record.push_back(D->HasRedeclaration);
|
|
|
|
if (D->HasRedeclaration) {
|
|
|
|
assert(Context.getObjCMethodRedeclaration(D));
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
|
2011-10-15 01:41:52 +08:00
|
|
|
}
|
|
|
|
|
2009-04-27 14:16:06 +08:00
|
|
|
// FIXME: stable encoding for @required/@optional
|
2009-09-09 23:08:12 +08:00
|
|
|
Record.push_back(D->getImplementationControl());
|
2015-06-20 02:14:38 +08:00
|
|
|
// FIXME: stable encoding for in/out/inout/bycopy/byref/oneway/nullability
|
2009-09-09 23:08:12 +08:00
|
|
|
Record.push_back(D->getObjCDeclQualifier());
|
2011-06-11 09:09:30 +08:00
|
|
|
Record.push_back(D->hasRelatedResultType());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeRef(D->getReturnType());
|
|
|
|
Record.AddTypeSourceInfo(D->getReturnTypeSourceInfo());
|
|
|
|
Record.AddSourceLocation(D->getLocEnd());
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->param_size());
|
2016-06-24 12:05:48 +08:00
|
|
|
for (const auto *P : D->parameters())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(P);
|
2011-10-03 14:37:04 +08:00
|
|
|
|
|
|
|
Record.push_back(D->SelLocsKind);
|
|
|
|
unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
|
|
|
|
SourceLocation *SelLocs = D->getStoredSelLocs();
|
|
|
|
Record.push_back(NumStoredSelLocs);
|
|
|
|
for (unsigned i = 0; i != NumStoredSelLocs; ++i)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(SelLocs[i]);
|
2011-10-03 14:37:04 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_METHOD;
|
2009-04-27 14:16:06 +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 ASTDeclWriter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
|
|
|
|
VisitTypedefNameDecl(D);
|
2015-07-07 11:58:54 +08:00
|
|
|
Record.push_back(D->Variance);
|
Substitute type arguments into uses of Objective-C interface members.
When messaging a method that was defined in an Objective-C class (or
category or extension thereof) that has type parameters, substitute
the type arguments for those type parameters. Similarly, substitute
into property accesses, instance variables, and other references.
This includes general infrastructure for substituting the type
arguments associated with an ObjCObject(Pointer)Type into a type
referenced within a particular context, handling all of the
substitutions required to deal with (e.g.) inheritance involving
parameterized classes. In cases where no type arguments are available
(e.g., because we're messaging via some unspecialized type, id, etc.),
we substitute in the type bounds for the type parameters instead.
Example:
@interface NSSet<T : id<NSCopying>> : NSObject <NSCopying>
- (T)firstObject;
@end
void f(NSSet<NSString *> *stringSet, NSSet *anySet) {
[stringSet firstObject]; // produces NSString*
[anySet firstObject]; // produces id<NSCopying> (the bound)
}
When substituting for the type parameters given an unspecialized
context (i.e., no specific type arguments were given), substituting
the type bounds unconditionally produces type signatures that are too
strong compared to the pre-generics signatures. Instead, use the
following rule:
- In covariant positions, such as method return types, replace type
parameters with “id” or “Class” (the latter only when the type
parameter bound is “Class” or qualified class, e.g,
“Class<NSCopying>”)
- In other positions (e.g., parameter types), replace type
parameters with their type bounds.
- When a specialized Objective-C object or object pointer type
contains a type parameter in its type arguments (e.g.,
NSArray<T>*, but not NSArray<NSString *> *), replace the entire
object/object pointer type with its unspecialized version (e.g.,
NSArray *).
llvm-svn: 241543
2015-07-07 11:57:53 +08:00
|
|
|
Record.push_back(D->Index);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->VarianceLoc);
|
|
|
|
Record.AddSourceLocation(D->ColonLoc);
|
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
|
|
|
|
|
|
|
Code = serialization::DECL_OBJC_TYPE_PARAM;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getAtStartLoc());
|
|
|
|
Record.AddSourceRange(D->getAtEndRange());
|
2010-08-19 07:57:32 +08:00
|
|
|
// Abstract class (no need to define a stable serialization::DECL code).
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
2011-12-16 02:03:09 +08:00
|
|
|
VisitRedeclarable(D);
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitObjCContainerDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
|
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
|
|
|
AddObjCTypeParamList(D->TypeParamList);
|
2010-09-01 09:21:15 +08:00
|
|
|
|
2012-01-16 02:17:48 +08:00
|
|
|
Record.push_back(D->isThisDeclarationADefinition());
|
|
|
|
if (D->isThisDeclarationADefinition()) {
|
2011-12-15 13:27:12 +08:00
|
|
|
// Write the DefinitionData
|
|
|
|
ObjCInterfaceDecl::DefinitionData &Data = D->data();
|
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getSuperClassTInfo());
|
|
|
|
Record.AddSourceLocation(D->getEndOfDefinitionLoc());
|
2013-12-04 05:11:30 +08:00
|
|
|
Record.push_back(Data.HasDesignatedInitializers);
|
2011-12-16 06:34:59 +08:00
|
|
|
|
2011-12-15 13:27:12 +08:00
|
|
|
// Write out the protocols that are directly referenced by the @interface.
|
|
|
|
Record.push_back(Data.ReferencedProtocols.size());
|
2014-03-14 04:29:09 +08:00
|
|
|
for (const auto *P : D->protocols())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(P);
|
2014-03-14 04:34:24 +08:00
|
|
|
for (const auto &PL : D->protocol_locs())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(PL);
|
2011-12-15 13:27:12 +08:00
|
|
|
|
|
|
|
// Write out the protocols that are transitively referenced.
|
|
|
|
Record.push_back(Data.AllReferencedProtocols.size());
|
|
|
|
for (ObjCList<ObjCProtocolDecl>::iterator
|
|
|
|
P = Data.AllReferencedProtocols.begin(),
|
|
|
|
PEnd = Data.AllReferencedProtocols.end();
|
|
|
|
P != PEnd; ++P)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(*P);
|
2013-01-17 07:00:23 +08:00
|
|
|
|
2011-12-15 13:27:12 +08:00
|
|
|
|
2013-01-17 07:00:23 +08:00
|
|
|
if (ObjCCategoryDecl *Cat = D->getCategoryListRaw()) {
|
2012-01-27 09:47:08 +08:00
|
|
|
// Ensure that we write out the set of categories for this class.
|
|
|
|
Writer.ObjCClassesWithCategories.insert(D);
|
|
|
|
|
|
|
|
// Make sure that the categories get serialized.
|
2013-01-17 07:00:23 +08:00
|
|
|
for (; Cat; Cat = Cat->getNextClassCategoryRaw())
|
2012-01-27 09:47:08 +08:00
|
|
|
(void)Writer.GetDeclRef(Cat);
|
|
|
|
}
|
2011-12-15 13:27:12 +08:00
|
|
|
}
|
2010-09-01 09:21:15 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_INTERFACE;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitFieldDecl(D);
|
|
|
|
// FIXME: stable encoding for @public/@private/@protected/@package
|
2009-09-09 23:08:12 +08:00
|
|
|
Record.push_back(D->getAccessControl());
|
2010-07-18 02:35:47 +08:00
|
|
|
Record.push_back(D->getSynthesize());
|
2011-06-04 07:11:16 +08:00
|
|
|
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() == D->getLexicalDeclContext() &&
|
|
|
|
!D->hasAttrs() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->isImplicit() &&
|
|
|
|
!D->isUsed(false) &&
|
|
|
|
!D->isInvalidDecl() &&
|
|
|
|
!D->isReferenced() &&
|
2011-09-09 10:06:17 +08:00
|
|
|
!D->isModulePrivate() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->getBitWidth() &&
|
|
|
|
!D->hasExtInfo() &&
|
|
|
|
D->getDeclName())
|
|
|
|
AbbrevToUse = Writer.getDeclObjCIvarAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_IVAR;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
|
2012-01-02 03:51:50 +08:00
|
|
|
VisitRedeclarable(D);
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitObjCContainerDecl(D);
|
2012-01-02 03:29:29 +08:00
|
|
|
|
2012-01-16 02:17:48 +08:00
|
|
|
Record.push_back(D->isThisDeclarationADefinition());
|
|
|
|
if (D->isThisDeclarationADefinition()) {
|
2012-01-02 03:29:29 +08:00
|
|
|
Record.push_back(D->protocol_size());
|
2014-03-14 06:58:06 +08:00
|
|
|
for (const auto *I : D->protocols())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(I);
|
2014-03-14 20:38:50 +08:00
|
|
|
for (const auto &PL : D->protocol_locs())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(PL);
|
2012-01-02 03:29:29 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_PROTOCOL;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitFieldDecl(D);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_AT_DEFS_FIELD;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitObjCContainerDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getCategoryNameLoc());
|
|
|
|
Record.AddSourceLocation(D->getIvarLBraceLoc());
|
|
|
|
Record.AddSourceLocation(D->getIvarRBraceLoc());
|
|
|
|
Record.AddDeclRef(D->getClassInterface());
|
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
|
|
|
AddObjCTypeParamList(D->TypeParamList);
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->protocol_size());
|
2014-03-14 20:55:57 +08:00
|
|
|
for (const auto *I : D->protocols())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(I);
|
2014-03-14 21:03:32 +08:00
|
|
|
for (const auto &PL : D->protocol_locs())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(PL);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_CATEGORY;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getClassInterface());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getAtLoc());
|
|
|
|
Record.AddSourceLocation(D->getLParenLoc());
|
|
|
|
Record.AddTypeRef(D->getType());
|
|
|
|
Record.AddTypeSourceInfo(D->getTypeSourceInfo());
|
2009-04-27 14:16:06 +08:00
|
|
|
// FIXME: stable encoding
|
|
|
|
Record.push_back((unsigned)D->getPropertyAttributes());
|
2010-06-23 07:20:40 +08:00
|
|
|
Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
|
2009-04-27 14:16:06 +08:00
|
|
|
// FIXME: stable encoding
|
|
|
|
Record.push_back((unsigned)D->getPropertyImplementation());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclarationName(D->getGetterName());
|
|
|
|
Record.AddDeclarationName(D->getSetterName());
|
|
|
|
Record.AddDeclRef(D->getGetterMethodDecl());
|
|
|
|
Record.AddDeclRef(D->getSetterMethodDecl());
|
|
|
|
Record.AddDeclRef(D->getPropertyIvarDecl());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_PROPERTY;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
|
2009-07-28 03:04:32 +08:00
|
|
|
VisitObjCContainerDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getClassInterface());
|
2010-08-19 07:57:32 +08:00
|
|
|
// Abstract class (no need to define a stable serialization::DECL code).
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitObjCImplDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddIdentifierRef(D->getIdentifier());
|
|
|
|
Record.AddSourceLocation(D->getCategoryNameLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_CATEGORY_IMPL;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitObjCImplDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getSuperClass());
|
|
|
|
Record.AddSourceLocation(D->getSuperClassLoc());
|
|
|
|
Record.AddSourceLocation(D->getIvarLBraceLoc());
|
|
|
|
Record.AddSourceLocation(D->getIvarRBraceLoc());
|
2012-10-17 12:53:31 +08:00
|
|
|
Record.push_back(D->hasNonZeroConstructors());
|
|
|
|
Record.push_back(D->hasDestructors());
|
2015-03-24 14:36:48 +08:00
|
|
|
Record.push_back(D->NumIvarInitializers);
|
|
|
|
if (D->NumIvarInitializers)
|
2016-04-14 05:57:08 +08:00
|
|
|
Record.AddCXXCtorInitializers(
|
2016-04-02 06:52:03 +08:00
|
|
|
llvm::makeArrayRef(D->init_begin(), D->init_end()));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_IMPLEMENTATION;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocStart());
|
|
|
|
Record.AddDeclRef(D->getPropertyDecl());
|
|
|
|
Record.AddDeclRef(D->getPropertyIvarDecl());
|
|
|
|
Record.AddSourceLocation(D->getPropertyIvarDeclLoc());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getGetterCXXConstructor());
|
|
|
|
Record.AddStmt(D->getSetterCXXAssignment());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_OBJC_PROPERTY_IMPL;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
|
2009-08-19 09:28:35 +08:00
|
|
|
VisitDeclaratorDecl(D);
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->isMutable());
|
2014-10-11 02:44:34 +08:00
|
|
|
if (D->InitStorage.getInt() == FieldDecl::ISK_BitWidthOrNothing &&
|
|
|
|
D->InitStorage.getPointer() == nullptr) {
|
|
|
|
Record.push_back(0);
|
|
|
|
} else if (D->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) {
|
|
|
|
Record.push_back(D->InitStorage.getInt() + 1);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeRef(
|
|
|
|
QualType(static_cast<Type *>(D->InitStorage.getPointer()), 0));
|
2012-06-10 11:12:00 +08:00
|
|
|
} else {
|
2014-10-11 02:44:34 +08:00
|
|
|
Record.push_back(D->InitStorage.getInt() + 1);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(static_cast<Expr *>(D->InitStorage.getPointer()));
|
2012-06-10 11:12:00 +08:00
|
|
|
}
|
2010-07-05 05:44:35 +08:00
|
|
|
if (!D->getDeclName())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
|
2011-06-04 07:11:16 +08:00
|
|
|
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() == D->getLexicalDeclContext() &&
|
|
|
|
!D->hasAttrs() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->isImplicit() &&
|
|
|
|
!D->isUsed(false) &&
|
|
|
|
!D->isInvalidDecl() &&
|
|
|
|
!D->isReferenced() &&
|
2011-11-24 05:11:23 +08:00
|
|
|
!D->isTopLevelDeclInObjCContainer() &&
|
2011-09-09 10:06:17 +08:00
|
|
|
!D->isModulePrivate() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->getBitWidth() &&
|
2011-06-12 01:19:42 +08:00
|
|
|
!D->hasInClassInitializer() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->hasExtInfo() &&
|
|
|
|
!ObjCIvarDecl::classofKind(D->getKind()) &&
|
|
|
|
!ObjCAtDefsFieldDecl::classofKind(D->getKind()) &&
|
|
|
|
D->getDeclName())
|
|
|
|
AbbrevToUse = Writer.getDeclFieldAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_FIELD;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2013-04-16 15:28:30 +08:00
|
|
|
void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) {
|
|
|
|
VisitDeclaratorDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddIdentifierRef(D->getGetterId());
|
|
|
|
Record.AddIdentifierRef(D->getSetterId());
|
2013-04-16 15:28:30 +08:00
|
|
|
Code = serialization::DECL_MS_PROPERTY;
|
|
|
|
}
|
|
|
|
|
2010-11-21 14:08:52 +08:00
|
|
|
void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
|
|
|
|
VisitValueDecl(D);
|
|
|
|
Record.push_back(D->getChainingSize());
|
|
|
|
|
2014-03-08 02:36:15 +08:00
|
|
|
for (const auto *P : D->chain())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(P);
|
2010-11-21 14:08:52 +08:00
|
|
|
Code = serialization::DECL_INDIRECTFIELD;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
|
2010-09-09 03:31:22 +08:00
|
|
|
VisitRedeclarable(D);
|
2011-10-27 01:53:41 +08:00
|
|
|
VisitDeclaratorDecl(D);
|
2013-04-04 03:27:57 +08:00
|
|
|
Record.push_back(D->getStorageClass());
|
2013-05-04 16:27:07 +08:00
|
|
|
Record.push_back(D->getTSCSpec());
|
Represent C++ direct initializers as ParenListExprs before semantic analysis
instead of having a special-purpose function.
- ActOnCXXDirectInitializer, which was mostly duplication of
AddInitializerToDecl (leading e.g. to PR10620, which Eli fixed a few days
ago), is dropped completely.
- MultiInitializer, which was an ugly hack I added, is dropped again.
- We now have the infrastructure in place to distinguish between
int x = {1};
int x({1});
int x{1};
-- VarDecl now has getInitStyle(), which indicates which of the above was used.
-- CXXConstructExpr now has a flag to indicate that it represents list-
initialization, although this is not yet used.
- InstantiateInitializer was renamed to SubstInitializer and simplified.
- ActOnParenOrParenListExpr has been replaced by ActOnParenListExpr, which
always produces a ParenListExpr. Placed that so far failed to convert that
back to a ParenExpr containing comma operators have been fixed. I'm pretty
sure I could have made a crashing test case before this.
The end result is a (I hope) considerably cleaner design of initializers.
More importantly, the fact that I can now distinguish between the various
initialization kinds means that I can get the tricky generalized initializer
test cases Johannes Schaub supplied to work. (This is not yet done.)
This commit passed self-host, with the resulting compiler passing the tests. I
hope it doesn't break more complicated code. It's a pretty big change, but one
that I feel is necessary.
llvm-svn: 150318
2012-02-12 07:51:47 +08:00
|
|
|
Record.push_back(D->getInitStyle());
|
2015-05-19 08:57:16 +08:00
|
|
|
if (!isa<ParmVarDecl>(D)) {
|
|
|
|
Record.push_back(D->isExceptionVariable());
|
|
|
|
Record.push_back(D->isNRVOVariable());
|
|
|
|
Record.push_back(D->isCXXForRangeDecl());
|
|
|
|
Record.push_back(D->isARCPseudoStrong());
|
2016-06-25 08:15:56 +08:00
|
|
|
Record.push_back(D->isInline());
|
|
|
|
Record.push_back(D->isInlineSpecified());
|
2015-05-19 08:57:16 +08:00
|
|
|
Record.push_back(D->isConstexpr());
|
|
|
|
Record.push_back(D->isInitCapture());
|
|
|
|
Record.push_back(D->isPreviousDeclInSameBlockScope());
|
|
|
|
}
|
2013-05-13 08:12:11 +08:00
|
|
|
Record.push_back(D->getLinkageInternal());
|
2012-09-21 07:43:29 +08:00
|
|
|
|
2011-12-19 14:19:21 +08:00
|
|
|
if (D->getInit()) {
|
|
|
|
Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2));
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getInit());
|
2011-12-19 14:19:21 +08:00
|
|
|
} else {
|
|
|
|
Record.push_back(0);
|
|
|
|
}
|
2013-08-14 11:09:19 +08:00
|
|
|
|
|
|
|
enum {
|
|
|
|
VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
|
|
|
|
};
|
|
|
|
if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) {
|
|
|
|
Record.push_back(VarTemplate);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(TemplD);
|
2013-08-14 11:09:19 +08:00
|
|
|
} else if (MemberSpecializationInfo *SpecInfo
|
|
|
|
= D->getMemberSpecializationInfo()) {
|
|
|
|
Record.push_back(StaticDataMemberSpecialization);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(SpecInfo->getInstantiatedFrom());
|
2010-07-05 05:44:00 +08:00
|
|
|
Record.push_back(SpecInfo->getTemplateSpecializationKind());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(SpecInfo->getPointOfInstantiation());
|
2013-08-14 11:09:19 +08:00
|
|
|
} else {
|
|
|
|
Record.push_back(VarNotTemplate);
|
2010-07-05 05:44:00 +08:00
|
|
|
}
|
|
|
|
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() == D->getLexicalDeclContext() &&
|
|
|
|
!D->hasAttrs() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->isImplicit() &&
|
|
|
|
!D->isUsed(false) &&
|
|
|
|
!D->isInvalidDecl() &&
|
|
|
|
!D->isReferenced() &&
|
2011-11-24 05:11:23 +08:00
|
|
|
!D->isTopLevelDeclInObjCContainer() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
D->getAccess() == AS_none &&
|
2011-09-09 10:06:17 +08:00
|
|
|
!D->isModulePrivate() &&
|
2014-08-28 09:33:39 +08:00
|
|
|
!needsAnonymousDeclarationNumber(D) &&
|
2011-06-04 07:11:16 +08:00
|
|
|
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
|
|
|
|
!D->hasExtInfo() &&
|
2013-10-17 23:37:26 +08:00
|
|
|
D->getFirstDecl() == D->getMostRecentDecl() &&
|
Represent C++ direct initializers as ParenListExprs before semantic analysis
instead of having a special-purpose function.
- ActOnCXXDirectInitializer, which was mostly duplication of
AddInitializerToDecl (leading e.g. to PR10620, which Eli fixed a few days
ago), is dropped completely.
- MultiInitializer, which was an ugly hack I added, is dropped again.
- We now have the infrastructure in place to distinguish between
int x = {1};
int x({1});
int x{1};
-- VarDecl now has getInitStyle(), which indicates which of the above was used.
-- CXXConstructExpr now has a flag to indicate that it represents list-
initialization, although this is not yet used.
- InstantiateInitializer was renamed to SubstInitializer and simplified.
- ActOnParenOrParenListExpr has been replaced by ActOnParenListExpr, which
always produces a ParenListExpr. Placed that so far failed to convert that
back to a ParenExpr containing comma operators have been fixed. I'm pretty
sure I could have made a crashing test case before this.
The end result is a (I hope) considerably cleaner design of initializers.
More importantly, the fact that I can now distinguish between the various
initialization kinds means that I can get the tricky generalized initializer
test cases Johannes Schaub supplied to work. (This is not yet done.)
This commit passed self-host, with the resulting compiler passing the tests. I
hope it doesn't break more complicated code. It's a pretty big change, but one
that I feel is necessary.
llvm-svn: 150318
2012-02-12 07:51:47 +08:00
|
|
|
D->getInitStyle() == VarDecl::CInit &&
|
2014-05-22 13:54:18 +08:00
|
|
|
D->getInit() == nullptr &&
|
2011-06-17 14:42:21 +08:00
|
|
|
!isa<ParmVarDecl>(D) &&
|
2013-08-13 10:02:26 +08:00
|
|
|
!isa<VarTemplateSpecializationDecl>(D) &&
|
2016-06-25 08:15:56 +08:00
|
|
|
!D->isInline() &&
|
2012-09-21 07:43:29 +08:00
|
|
|
!D->isConstexpr() &&
|
2013-09-28 12:02:39 +08:00
|
|
|
!D->isInitCapture() &&
|
2013-08-14 02:18:50 +08:00
|
|
|
!D->isPreviousDeclInSameBlockScope() &&
|
2013-08-14 11:09:19 +08:00
|
|
|
!D->getMemberSpecializationInfo())
|
2011-06-04 07:11:16 +08:00
|
|
|
AbbrevToUse = Writer.getDeclVarAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_VAR;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitVarDecl(D);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_IMPLICIT_PARAM;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitVarDecl(D);
|
2011-05-02 08:30:12 +08:00
|
|
|
Record.push_back(D->isObjCMethodParameter());
|
2011-05-02 06:35:37 +08:00
|
|
|
Record.push_back(D->getFunctionScopeDepth());
|
|
|
|
Record.push_back(D->getFunctionScopeIndex());
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
|
2011-03-09 12:22:44 +08:00
|
|
|
Record.push_back(D->isKNRPromoted());
|
2010-03-13 02:31:32 +08:00
|
|
|
Record.push_back(D->hasInheritedDefaultArg());
|
2010-07-05 05:44:07 +08:00
|
|
|
Record.push_back(D->hasUninstantiatedDefaultArg());
|
|
|
|
if (D->hasUninstantiatedDefaultArg())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getUninstantiatedDefaultArg());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_PARM_VAR;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-06-17 14:42:21 +08:00
|
|
|
assert(!D->isARCPseudoStrong()); // can be true of ImplicitParamDecl
|
|
|
|
|
2009-04-27 15:35:58 +08:00
|
|
|
// If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here
|
|
|
|
// we dynamically check for the properties that we optimize for, but don't
|
|
|
|
// know are true of all PARM_VAR_DECLs.
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() == D->getLexicalDeclContext() &&
|
|
|
|
!D->hasAttrs() &&
|
2011-06-04 07:11:16 +08:00
|
|
|
!D->hasExtInfo() &&
|
2009-04-27 15:35:58 +08:00
|
|
|
!D->isImplicit() &&
|
2010-06-18 07:14:26 +08:00
|
|
|
!D->isUsed(false) &&
|
2012-03-10 05:09:04 +08:00
|
|
|
!D->isInvalidDecl() &&
|
2012-01-14 07:41:25 +08:00
|
|
|
!D->isReferenced() &&
|
2009-04-27 15:35:58 +08:00
|
|
|
D->getAccess() == AS_none &&
|
2011-09-09 10:06:17 +08:00
|
|
|
!D->isModulePrivate() &&
|
2009-04-27 15:35:58 +08:00
|
|
|
D->getStorageClass() == 0 &&
|
Represent C++ direct initializers as ParenListExprs before semantic analysis
instead of having a special-purpose function.
- ActOnCXXDirectInitializer, which was mostly duplication of
AddInitializerToDecl (leading e.g. to PR10620, which Eli fixed a few days
ago), is dropped completely.
- MultiInitializer, which was an ugly hack I added, is dropped again.
- We now have the infrastructure in place to distinguish between
int x = {1};
int x({1});
int x{1};
-- VarDecl now has getInitStyle(), which indicates which of the above was used.
-- CXXConstructExpr now has a flag to indicate that it represents list-
initialization, although this is not yet used.
- InstantiateInitializer was renamed to SubstInitializer and simplified.
- ActOnParenOrParenListExpr has been replaced by ActOnParenListExpr, which
always produces a ParenListExpr. Placed that so far failed to convert that
back to a ParenExpr containing comma operators have been fixed. I'm pretty
sure I could have made a crashing test case before this.
The end result is a (I hope) considerably cleaner design of initializers.
More importantly, the fact that I can now distinguish between the various
initialization kinds means that I can get the tricky generalized initializer
test cases Johannes Schaub supplied to work. (This is not yet done.)
This commit passed self-host, with the resulting compiler passing the tests. I
hope it doesn't break more complicated code. It's a pretty big change, but one
that I feel is necessary.
llvm-svn: 150318
2012-02-12 07:51:47 +08:00
|
|
|
D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
|
2011-05-02 08:30:12 +08:00
|
|
|
D->getFunctionScopeDepth() == 0 &&
|
2010-03-13 02:31:32 +08:00
|
|
|
D->getObjCDeclQualifier() == 0 &&
|
2011-03-09 12:22:44 +08:00
|
|
|
!D->isKNRPromoted() &&
|
2010-05-09 14:40:08 +08:00
|
|
|
!D->hasInheritedDefaultArg() &&
|
2014-05-22 13:54:18 +08:00
|
|
|
D->getInit() == nullptr &&
|
2010-07-05 05:44:07 +08:00
|
|
|
!D->hasUninstantiatedDefaultArg()) // No default expr.
|
2011-06-04 07:11:16 +08:00
|
|
|
AbbrevToUse = Writer.getDeclParmVarAbbrev();
|
2009-04-27 15:35:58 +08:00
|
|
|
|
|
|
|
// Check things we know are true of *every* PARM_VAR_DECL, which is more than
|
|
|
|
// just us assuming it.
|
2013-05-04 16:27:07 +08:00
|
|
|
assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS");
|
2009-04-27 15:35:58 +08:00
|
|
|
assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
|
2010-05-04 02:51:14 +08:00
|
|
|
assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
|
2014-05-22 13:54:18 +08:00
|
|
|
assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl");
|
2010-07-05 05:44:00 +08:00
|
|
|
assert(!D->isStaticDataMember() &&
|
|
|
|
"PARM_VAR_DECL can't be static data member");
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitDecl(D);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getAsmString());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_FILE_SCOPE_ASM;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2013-02-23 01:15:32 +08:00
|
|
|
void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
|
|
|
|
VisitDecl(D);
|
|
|
|
Code = serialization::DECL_EMPTY;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
|
2009-04-27 14:16:06 +08:00
|
|
|
VisitDecl(D);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getBody());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getSignatureAsWritten());
|
2009-04-27 14:16:06 +08:00
|
|
|
Record.push_back(D->param_size());
|
2016-06-24 13:33:44 +08:00
|
|
|
for (ParmVarDecl *P : D->parameters())
|
|
|
|
Record.AddDeclRef(P);
|
2012-04-14 01:33:29 +08:00
|
|
|
Record.push_back(D->isVariadic());
|
|
|
|
Record.push_back(D->blockMissingReturnType());
|
|
|
|
Record.push_back(D->isConversionFromLambda());
|
2011-02-02 21:00:07 +08:00
|
|
|
Record.push_back(D->capturesCXXThis());
|
2011-02-07 18:33:21 +08:00
|
|
|
Record.push_back(D->getNumCaptures());
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &capture : D->captures()) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(capture.getVariable());
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
unsigned flags = 0;
|
|
|
|
if (capture.isByRef()) flags |= 1;
|
|
|
|
if (capture.isNested()) flags |= 2;
|
|
|
|
if (capture.hasCopyExpr()) flags |= 4;
|
|
|
|
Record.push_back(flags);
|
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
if (capture.hasCopyExpr()) Record.AddStmt(capture.getCopyExpr());
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
2011-02-02 21:00:07 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_BLOCK;
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2013-05-04 03:20:19 +08:00
|
|
|
void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) {
|
|
|
|
Record.push_back(CD->getNumParams());
|
|
|
|
VisitDecl(CD);
|
2014-05-06 18:08:46 +08:00
|
|
|
Record.push_back(CD->getContextParamPosition());
|
|
|
|
Record.push_back(CD->isNothrow() ? 1 : 0);
|
2013-05-04 03:20:19 +08:00
|
|
|
// Body is stored by VisitCapturedStmt.
|
2014-05-06 18:08:46 +08:00
|
|
|
for (unsigned I = 0; I < CD->getNumParams(); ++I)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(CD->getParam(I));
|
2013-05-04 03:20:19 +08:00
|
|
|
Code = serialization::DECL_CAPTURED;
|
2013-04-17 03:37:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitDecl(D);
|
|
|
|
Record.push_back(D->getLanguage());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getExternLoc());
|
|
|
|
Record.AddSourceLocation(D->getRBraceLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_LINKAGE_SPEC;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2011-02-17 15:39:24 +08:00
|
|
|
void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
|
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocStart());
|
2011-02-17 15:39:24 +08:00
|
|
|
Code = serialization::DECL_LABEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
|
2012-01-07 17:11:48 +08:00
|
|
|
VisitRedeclarable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2010-10-06 04:41:58 +08:00
|
|
|
Record.push_back(D->isInline());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocStart());
|
|
|
|
Record.AddSourceLocation(D->getRBraceLoc());
|
2010-05-08 05:43:38 +08:00
|
|
|
|
|
|
|
if (D->isOriginalNamespace())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getAnonymousNamespace());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_NAMESPACE;
|
2010-08-06 05:22:19 +08:00
|
|
|
|
2012-01-07 17:11:48 +08:00
|
|
|
if (Writer.hasChain() && D->isAnonymousNamespace() &&
|
2012-01-15 00:38:05 +08:00
|
|
|
D == D->getMostRecentDecl()) {
|
2011-04-25 00:28:21 +08:00
|
|
|
// This is a most recent reopening of the anonymous namespace. If its parent
|
|
|
|
// is in a previous PCH (or is the TU), mark that parent for update, because
|
|
|
|
// the original namespace always points to the latest re-opening of its
|
|
|
|
// anonymous namespace.
|
|
|
|
Decl *Parent = cast<Decl>(
|
|
|
|
D->getParent()->getRedeclContext()->getPrimaryContext());
|
2011-09-10 07:01:35 +08:00
|
|
|
if (Parent->isFromASTFile() || isa<TranslationUnitDecl>(Parent)) {
|
2014-03-21 05:02:00 +08:00
|
|
|
Writer.DeclUpdates[Parent].push_back(
|
2014-03-21 23:22:56 +08:00
|
|
|
ASTWriter::DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, D));
|
2011-04-25 00:28:13 +08:00
|
|
|
}
|
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
|
2014-09-04 07:11:22 +08:00
|
|
|
VisitRedeclarable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getNamespaceLoc());
|
|
|
|
Record.AddSourceLocation(D->getTargetNameLoc());
|
|
|
|
Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
|
|
|
|
Record.AddDeclRef(D->getNamespace());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_NAMESPACE_ALIAS;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getUsingLoc());
|
|
|
|
Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
|
|
|
|
Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
|
|
|
|
Record.AddDeclRef(D->FirstUsingShadow.getPointer());
|
2013-07-22 18:54:09 +08:00
|
|
|
Record.push_back(D->hasTypename());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(Context.getInstantiatedFromUsingDecl(D));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_USING;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
|
2013-10-23 10:17:46 +08:00
|
|
|
VisitRedeclarable(D);
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getTargetDecl());
|
|
|
|
Record.AddDeclRef(D->UsingOrNextShadow);
|
|
|
|
Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_USING_SHADOW;
|
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 ASTDeclWriter::VisitConstructorUsingShadowDecl(
|
|
|
|
ConstructorUsingShadowDecl *D) {
|
|
|
|
VisitUsingShadowDecl(D);
|
|
|
|
Record.AddDeclRef(D->NominatedBaseClassShadowDecl);
|
|
|
|
Record.AddDeclRef(D->ConstructedBaseClassShadowDecl);
|
|
|
|
Record.push_back(D->IsVirtual);
|
|
|
|
Code = serialization::DECL_CONSTRUCTOR_USING_SHADOW;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getUsingLoc());
|
|
|
|
Record.AddSourceLocation(D->getNamespaceKeyLocation());
|
|
|
|
Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
|
|
|
|
Record.AddDeclRef(D->getNominatedNamespace());
|
|
|
|
Record.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_USING_DIRECTIVE;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitValueDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getUsingLoc());
|
|
|
|
Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
|
|
|
|
Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_UNRESOLVED_USING_VALUE;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
|
2010-05-08 05:43:38 +08:00
|
|
|
UnresolvedUsingTypenameDecl *D) {
|
|
|
|
VisitTypeDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getTypenameLoc());
|
|
|
|
Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitRecordDecl(D);
|
2010-07-02 19:55:32 +08:00
|
|
|
|
2010-06-20 03:28:53 +08:00
|
|
|
enum {
|
|
|
|
CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
|
|
|
|
};
|
|
|
|
if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
|
|
|
|
Record.push_back(CXXRecTemplate);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(TemplD);
|
2010-06-20 03:28:53 +08:00
|
|
|
} else if (MemberSpecializationInfo *MSInfo
|
|
|
|
= D->getMemberSpecializationInfo()) {
|
|
|
|
Record.push_back(CXXRecMemberSpecialization);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(MSInfo->getInstantiatedFrom());
|
2010-06-20 03:28:53 +08:00
|
|
|
Record.push_back(MSInfo->getTemplateSpecializationKind());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
|
2010-06-20 03:28:53 +08:00
|
|
|
} else {
|
|
|
|
Record.push_back(CXXRecNotTemplate);
|
|
|
|
}
|
|
|
|
|
2014-04-19 11:48:30 +08:00
|
|
|
Record.push_back(D->isThisDeclarationADefinition());
|
|
|
|
if (D->isThisDeclarationADefinition())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddCXXDefinitionData(D);
|
2014-04-19 11:48:30 +08:00
|
|
|
|
2013-01-26 06:31:03 +08:00
|
|
|
// Store (what we currently believe to be) the key function to avoid
|
|
|
|
// deserializing every method so we can compute it.
|
2011-10-07 14:10:15 +08:00
|
|
|
if (D->IsCompleteDefinition)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(Context.getCurrentKeyFunction(D));
|
2010-10-15 04:14:38 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_CXX_RECORD;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitFunctionDecl(D);
|
2012-10-12 13:31:40 +08:00
|
|
|
if (D->isCanonicalDecl()) {
|
|
|
|
Record.push_back(D->size_overridden_methods());
|
|
|
|
for (CXXMethodDecl::method_iterator
|
|
|
|
I = D->begin_overridden_methods(), E = D->end_overridden_methods();
|
|
|
|
I != E; ++I)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(*I);
|
2012-10-12 13:31:40 +08:00
|
|
|
} else {
|
|
|
|
// We only need to record overridden methods once for the canonical decl.
|
|
|
|
Record.push_back(0);
|
|
|
|
}
|
2014-07-26 14:37:51 +08:00
|
|
|
|
2015-12-12 06:41:00 +08:00
|
|
|
if (D->getDeclContext() == D->getLexicalDeclContext() &&
|
|
|
|
D->getFirstDecl() == D->getMostRecentDecl() &&
|
2014-07-26 14:37:51 +08:00
|
|
|
!D->isInvalidDecl() &&
|
|
|
|
!D->hasAttrs() &&
|
|
|
|
!D->isTopLevelDeclInObjCContainer() &&
|
|
|
|
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
|
|
|
|
!D->hasExtInfo() &&
|
|
|
|
!D->hasInheritedPrototype() &&
|
|
|
|
D->hasWrittenPrototype())
|
|
|
|
AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_CXX_METHOD;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::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
|
|
|
if (auto Inherited = D->getInheritedConstructor()) {
|
|
|
|
Record.AddDeclRef(Inherited.getShadowDecl());
|
|
|
|
Record.AddDeclRef(Inherited.getConstructor());
|
|
|
|
Code = serialization::DECL_CXX_INHERITED_CONSTRUCTOR;
|
|
|
|
} else {
|
|
|
|
Code = serialization::DECL_CXX_CONSTRUCTOR;
|
|
|
|
}
|
|
|
|
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
2010-07-02 23:58:43 +08:00
|
|
|
|
|
|
|
Record.push_back(D->IsExplicitSpecified);
|
|
|
|
|
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
|
|
|
Code = D->isInheritingConstructor()
|
|
|
|
? serialization::DECL_CXX_INHERITED_CONSTRUCTOR
|
|
|
|
: serialization::DECL_CXX_CONSTRUCTOR;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
2010-07-02 23:58:43 +08:00
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getOperatorDelete());
|
2010-07-02 23:58:43 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_CXX_DESTRUCTOR;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
2010-07-02 23:58:43 +08:00
|
|
|
Record.push_back(D->IsExplicitSpecified);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_CXX_CONVERSION;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2011-12-03 07:23:56 +08:00
|
|
|
void ASTDeclWriter::VisitImportDecl(ImportDecl *D) {
|
|
|
|
VisitDecl(D);
|
2012-10-03 09:58:45 +08:00
|
|
|
Record.push_back(Writer.getSubmoduleID(D->getImportedModule()));
|
2011-12-03 07:23:56 +08:00
|
|
|
ArrayRef<SourceLocation> IdentifierLocs = D->getIdentifierLocs();
|
|
|
|
Record.push_back(!IdentifierLocs.empty());
|
|
|
|
if (IdentifierLocs.empty()) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocEnd());
|
2011-12-03 07:23:56 +08:00
|
|
|
Record.push_back(1);
|
|
|
|
} else {
|
|
|
|
for (unsigned I = 0, N = IdentifierLocs.size(); I != N; ++I)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(IdentifierLocs[I]);
|
2011-12-03 07:23:56 +08:00
|
|
|
Record.push_back(IdentifierLocs.size());
|
|
|
|
}
|
|
|
|
// Note: the number of source locations must always be the last element in
|
|
|
|
// the record.
|
|
|
|
Code = serialization::DECL_IMPORT;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
|
2010-06-05 13:09:32 +08:00
|
|
|
VisitDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getColonLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_ACCESS_SPEC;
|
2010-06-05 13:09:32 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
|
2013-01-31 17:54:08 +08:00
|
|
|
// Record the number of friend type template parameter lists here
|
|
|
|
// so as to simplify memory allocation during deserialization.
|
|
|
|
Record.push_back(D->NumTPLists);
|
2010-07-05 18:38:01 +08:00
|
|
|
VisitDecl(D);
|
2013-01-31 17:54:08 +08:00
|
|
|
bool hasFriendDecl = D->Friend.is<NamedDecl*>();
|
|
|
|
Record.push_back(hasFriendDecl);
|
|
|
|
if (hasFriendDecl)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getFriendDecl());
|
2010-06-30 06:47:00 +08:00
|
|
|
else
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getFriendType());
|
2013-01-31 17:54:08 +08:00
|
|
|
for (unsigned i = 0; i < D->NumTPLists; ++i)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i));
|
|
|
|
Record.AddDeclRef(D->getNextFriend());
|
2010-10-16 14:59:13 +08:00
|
|
|
Record.push_back(D->UnsupportedFriend);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->FriendLoc);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_FRIEND;
|
2010-06-30 06:47:00 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
|
2010-07-23 00:04:10 +08:00
|
|
|
VisitDecl(D);
|
|
|
|
Record.push_back(D->getNumTemplateParameters());
|
|
|
|
for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateParameterList(D->getTemplateParameterList(i));
|
2014-05-22 13:54:18 +08:00
|
|
|
Record.push_back(D->getFriendDecl() != nullptr);
|
2010-07-23 00:04:10 +08:00
|
|
|
if (D->getFriendDecl())
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getFriendDecl());
|
2010-07-23 00:04:10 +08:00
|
|
|
else
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getFriendType());
|
|
|
|
Record.AddSourceLocation(D->getFriendLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_FRIEND_TEMPLATE;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
|
2010-06-20 03:28:53 +08:00
|
|
|
VisitNamedDecl(D);
|
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getTemplatedDecl());
|
|
|
|
Record.AddTemplateParameterList(D->getTemplateParameters());
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
|
2012-01-14 23:13:49 +08:00
|
|
|
VisitRedeclarable(D);
|
|
|
|
|
2010-09-09 03:31:22 +08:00
|
|
|
// Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
|
|
|
|
// getCommonPtr() can be used while this is still initializing.
|
2013-10-17 23:37:26 +08:00
|
|
|
if (D->isFirstDecl()) {
|
2011-12-20 02:19:24 +08:00
|
|
|
// This declaration owns the 'common' pointer, so serialize that data now.
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getInstantiatedFromMemberTemplate());
|
2010-07-30 00:11:51 +08:00
|
|
|
if (D->getInstantiatedFromMemberTemplate())
|
|
|
|
Record.push_back(D->isMemberSpecialization());
|
2011-12-20 02:19:24 +08:00
|
|
|
}
|
|
|
|
|
2010-09-09 03:31:22 +08:00
|
|
|
VisitTemplateDecl(D);
|
|
|
|
Record.push_back(D->getIdentifierNamespace());
|
2010-07-30 00:11:51 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
2010-07-30 00:11:51 +08:00
|
|
|
VisitRedeclarableTemplateDecl(D);
|
|
|
|
|
2015-02-28 07:05:10 +08:00
|
|
|
if (D->isFirstDecl())
|
|
|
|
AddTemplateSpecializations(D);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_CLASS_TEMPLATE;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
|
2010-05-08 05:43:38 +08:00
|
|
|
ClassTemplateSpecializationDecl *D) {
|
2015-08-22 09:47:18 +08:00
|
|
|
RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
|
|
|
|
|
2010-06-23 21:48:30 +08:00
|
|
|
VisitCXXRecordDecl(D);
|
|
|
|
|
|
|
|
llvm::PointerUnion<ClassTemplateDecl *,
|
|
|
|
ClassTemplatePartialSpecializationDecl *> InstFrom
|
|
|
|
= D->getSpecializedTemplateOrPartial();
|
2011-08-18 05:35:28 +08:00
|
|
|
if (Decl *InstFromD = InstFrom.dyn_cast<ClassTemplateDecl *>()) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(InstFromD);
|
2010-06-23 21:48:30 +08:00
|
|
|
} else {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>());
|
|
|
|
Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
|
2010-06-23 21:48:30 +08:00
|
|
|
}
|
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateArgumentList(&D->getTemplateArgs());
|
|
|
|
Record.AddSourceLocation(D->getPointOfInstantiation());
|
2010-06-23 21:48:30 +08:00
|
|
|
Record.push_back(D->getSpecializationKind());
|
2012-10-01 15:34:47 +08:00
|
|
|
Record.push_back(D->isCanonicalDecl());
|
2010-06-23 21:48:30 +08:00
|
|
|
|
2010-07-20 21:59:40 +08:00
|
|
|
if (D->isCanonicalDecl()) {
|
|
|
|
// When reading, we'll add it to the folding set of the following template.
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
|
2010-07-10 05:11:43 +08:00
|
|
|
}
|
|
|
|
|
2013-09-10 00:55:27 +08:00
|
|
|
// Explicit info.
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getTypeAsWritten());
|
2013-09-10 00:55:27 +08:00
|
|
|
if (D->getTypeAsWritten()) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getExternLoc());
|
|
|
|
Record.AddSourceLocation(D->getTemplateKeywordLoc());
|
2013-09-10 00:55:27 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
|
2010-05-08 05:43:38 +08:00
|
|
|
ClassTemplatePartialSpecializationDecl *D) {
|
2010-06-23 21:48:30 +08:00
|
|
|
VisitClassTemplateSpecializationDecl(D);
|
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateParameterList(D->getTemplateParameters());
|
|
|
|
Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
|
2010-06-23 21:48:30 +08:00
|
|
|
|
|
|
|
// These are read/set from/to the first declaration.
|
2014-05-22 13:54:18 +08:00
|
|
|
if (D->getPreviousDecl() == nullptr) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getInstantiatedFromMember());
|
2010-06-23 21:48:30 +08:00
|
|
|
Record.push_back(D->isMemberSpecialization());
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2013-08-06 09:03:05 +08:00
|
|
|
void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) {
|
|
|
|
VisitRedeclarableTemplateDecl(D);
|
|
|
|
|
2015-02-28 07:05:10 +08:00
|
|
|
if (D->isFirstDecl())
|
|
|
|
AddTemplateSpecializations(D);
|
2013-08-06 09:03:05 +08:00
|
|
|
Code = serialization::DECL_VAR_TEMPLATE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
|
|
|
|
VarTemplateSpecializationDecl *D) {
|
2015-08-22 09:47:18 +08:00
|
|
|
RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
|
|
|
|
|
2013-08-06 09:03:05 +08:00
|
|
|
VisitVarDecl(D);
|
|
|
|
|
|
|
|
llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
|
|
|
|
InstFrom = D->getSpecializedTemplateOrPartial();
|
|
|
|
if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(InstFromD);
|
2013-08-06 09:03:05 +08:00
|
|
|
} else {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>());
|
|
|
|
Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
|
2013-08-06 09:03:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Explicit info.
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getTypeAsWritten());
|
2013-08-06 09:03:05 +08:00
|
|
|
if (D->getTypeAsWritten()) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getExternLoc());
|
|
|
|
Record.AddSourceLocation(D->getTemplateKeywordLoc());
|
2013-08-06 09:03:05 +08:00
|
|
|
}
|
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateArgumentList(&D->getTemplateArgs());
|
|
|
|
Record.AddSourceLocation(D->getPointOfInstantiation());
|
2013-08-06 09:03:05 +08:00
|
|
|
Record.push_back(D->getSpecializationKind());
|
|
|
|
Record.push_back(D->isCanonicalDecl());
|
|
|
|
|
|
|
|
if (D->isCanonicalDecl()) {
|
|
|
|
// When reading, we'll add it to the folding set of the following template.
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
|
2013-08-06 09:03:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Code = serialization::DECL_VAR_TEMPLATE_SPECIALIZATION;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
|
|
|
|
VarTemplatePartialSpecializationDecl *D) {
|
|
|
|
VisitVarTemplateSpecializationDecl(D);
|
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateParameterList(D->getTemplateParameters());
|
|
|
|
Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
|
2013-08-06 09:03:05 +08:00
|
|
|
|
|
|
|
// These are read/set from/to the first declaration.
|
2014-05-22 13:54:18 +08:00
|
|
|
if (D->getPreviousDecl() == nullptr) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getInstantiatedFromMember());
|
2013-08-06 09:03:05 +08:00
|
|
|
Record.push_back(D->isMemberSpecialization());
|
|
|
|
}
|
|
|
|
|
|
|
|
Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION;
|
|
|
|
}
|
|
|
|
|
2011-08-28 04:50:59 +08:00
|
|
|
void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
|
|
|
|
ClassScopeFunctionSpecializationDecl *D) {
|
2011-08-17 09:06:54 +08:00
|
|
|
VisitDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getSpecialization());
|
2011-08-17 09:06:54 +08:00
|
|
|
Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
2010-07-30 00:11:51 +08:00
|
|
|
VisitRedeclarableTemplateDecl(D);
|
2010-06-22 17:55:07 +08:00
|
|
|
|
2015-02-28 07:05:10 +08:00
|
|
|
if (D->isFirstDecl())
|
|
|
|
AddTemplateSpecializations(D);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_FUNCTION_TEMPLATE;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
|
2010-06-20 03:28:53 +08:00
|
|
|
VisitTypeDecl(D);
|
|
|
|
|
|
|
|
Record.push_back(D->wasDeclaredWithTypename());
|
2015-06-10 09:47:58 +08:00
|
|
|
|
|
|
|
bool OwnsDefaultArg = D->hasDefaultArgument() &&
|
|
|
|
!D->defaultArgumentWasInherited();
|
|
|
|
Record.push_back(OwnsDefaultArg);
|
|
|
|
if (OwnsDefaultArg)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
|
2010-06-20 03:28:53 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_TEMPLATE_TYPE_PARM;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
|
2011-01-20 04:10:05 +08:00
|
|
|
// For an expanded parameter pack, record the number of expansion types here
|
2012-09-07 10:06:42 +08:00
|
|
|
// so that it's easier for deserialization to allocate the right amount of
|
|
|
|
// memory.
|
2011-01-20 04:10:05 +08:00
|
|
|
if (D->isExpandedParameterPack())
|
|
|
|
Record.push_back(D->getNumExpansionTypes());
|
|
|
|
|
2011-02-09 09:13:10 +08:00
|
|
|
VisitDeclaratorDecl(D);
|
2010-06-26 00:25:09 +08:00
|
|
|
// TemplateParmPosition.
|
|
|
|
Record.push_back(D->getDepth());
|
|
|
|
Record.push_back(D->getPosition());
|
2011-01-20 04:10:05 +08:00
|
|
|
|
|
|
|
if (D->isExpandedParameterPack()) {
|
|
|
|
for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTypeRef(D->getExpansionType(I));
|
|
|
|
Record.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I));
|
2011-01-20 04:10:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK;
|
|
|
|
} else {
|
|
|
|
// Rest of NonTypeTemplateParmDecl.
|
|
|
|
Record.push_back(D->isParameterPack());
|
2015-06-10 09:47:58 +08:00
|
|
|
bool OwnsDefaultArg = D->hasDefaultArgument() &&
|
|
|
|
!D->defaultArgumentWasInherited();
|
|
|
|
Record.push_back(OwnsDefaultArg);
|
|
|
|
if (OwnsDefaultArg)
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getDefaultArgument());
|
2011-01-20 04:10:05 +08:00
|
|
|
Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
|
2010-06-26 00:25:09 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
|
2012-09-07 10:06:42 +08:00
|
|
|
// For an expanded parameter pack, record the number of expansion types here
|
|
|
|
// so that it's easier for deserialization to allocate the right amount of
|
|
|
|
// memory.
|
|
|
|
if (D->isExpandedParameterPack())
|
|
|
|
Record.push_back(D->getNumExpansionTemplateParameters());
|
|
|
|
|
2010-07-09 01:12:57 +08:00
|
|
|
VisitTemplateDecl(D);
|
|
|
|
// TemplateParmPosition.
|
|
|
|
Record.push_back(D->getDepth());
|
|
|
|
Record.push_back(D->getPosition());
|
2012-09-07 10:06:42 +08:00
|
|
|
|
|
|
|
if (D->isExpandedParameterPack()) {
|
|
|
|
for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
|
|
|
|
I != N; ++I)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateParameterList(D->getExpansionTemplateParameters(I));
|
2012-09-07 10:06:42 +08:00
|
|
|
Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK;
|
|
|
|
} else {
|
|
|
|
// Rest of TemplateTemplateParmDecl.
|
|
|
|
Record.push_back(D->isParameterPack());
|
2015-06-10 09:47:58 +08:00
|
|
|
bool OwnsDefaultArg = D->hasDefaultArgument() &&
|
|
|
|
!D->defaultArgumentWasInherited();
|
|
|
|
Record.push_back(OwnsDefaultArg);
|
|
|
|
if (OwnsDefaultArg)
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddTemplateArgumentLoc(D->getDefaultArgument());
|
2012-09-07 10:06:42 +08:00
|
|
|
Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
|
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2011-05-06 05:57:07 +08:00
|
|
|
void ASTDeclWriter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
|
|
|
|
VisitRedeclarableTemplateDecl(D);
|
|
|
|
Code = serialization::DECL_TYPE_ALIAS_TEMPLATE;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
|
2010-07-23 01:28:12 +08:00
|
|
|
VisitDecl(D);
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getAssertExpr());
|
2012-07-12 06:37:56 +08:00
|
|
|
Record.push_back(D->isFailed());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getMessage());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getRParenLoc());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::DECL_STATIC_ASSERT;
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2009-04-27 14:16:06 +08:00
|
|
|
/// \brief Emit the DeclContext part of a declaration context decl.
|
2016-04-13 10:12:03 +08:00
|
|
|
void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
|
|
|
|
Record.AddOffset(Writer.WriteDeclContextLexicalBlock(Context, DC));
|
|
|
|
Record.AddOffset(Writer.WriteDeclContextVisibleBlock(Context, DC));
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
|
|
|
|
2015-08-22 09:47:18 +08:00
|
|
|
const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
|
2015-09-11 10:22:03 +08:00
|
|
|
assert(IsLocalDecl(D) && "expected a local declaration");
|
2015-08-22 09:47:18 +08:00
|
|
|
|
|
|
|
const Decl *Canon = D->getCanonicalDecl();
|
2015-09-11 10:22:03 +08:00
|
|
|
if (IsLocalDecl(Canon))
|
2015-08-22 09:47:18 +08:00
|
|
|
return Canon;
|
|
|
|
|
|
|
|
const Decl *&CacheEntry = FirstLocalDeclCache[Canon];
|
|
|
|
if (CacheEntry)
|
|
|
|
return CacheEntry;
|
|
|
|
|
|
|
|
for (const Decl *Redecl = D; Redecl; Redecl = Redecl->getPreviousDecl())
|
2015-09-11 10:22:03 +08:00
|
|
|
if (IsLocalDecl(Redecl))
|
2015-08-22 09:47:18 +08:00
|
|
|
D = Redecl;
|
|
|
|
return CacheEntry = D;
|
2015-07-13 07:43:21 +08:00
|
|
|
}
|
|
|
|
|
2010-08-04 01:30:10 +08:00
|
|
|
template <typename T>
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
|
2013-10-17 23:37:26 +08:00
|
|
|
T *First = D->getFirstDecl();
|
2015-02-06 10:42:59 +08:00
|
|
|
T *MostRecent = First->getMostRecentDecl();
|
2015-08-22 09:47:18 +08:00
|
|
|
T *DAsT = static_cast<T *>(D);
|
2015-02-06 10:42:59 +08:00
|
|
|
if (MostRecent != First) {
|
2015-08-22 09:47:18 +08:00
|
|
|
assert(isRedeclarableDeclKind(DAsT->getKind()) &&
|
2013-01-22 00:16:40 +08:00
|
|
|
"Not considered redeclarable?");
|
2015-02-06 10:42:59 +08:00
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(First);
|
2015-03-06 07:24:12 +08:00
|
|
|
|
2015-08-22 09:47:18 +08:00
|
|
|
// Write out a list of local redeclarations of this declaration if it's the
|
|
|
|
// first local declaration in the chain.
|
|
|
|
const Decl *FirstLocal = Writer.getFirstLocalDecl(DAsT);
|
|
|
|
if (DAsT == FirstLocal) {
|
|
|
|
// Emit a list of all imported first declarations so that we can be sure
|
|
|
|
// that all redeclarations visible to this module are before D in the
|
|
|
|
// redecl chain.
|
|
|
|
unsigned I = Record.size();
|
|
|
|
Record.push_back(0);
|
|
|
|
if (Writer.Chain)
|
|
|
|
AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false);
|
|
|
|
// This is the number of imported first declarations + 1.
|
|
|
|
Record[I] = Record.size() - I;
|
2015-08-23 04:13:39 +08:00
|
|
|
|
|
|
|
// Collect the set of local redeclarations of this declaration, from
|
|
|
|
// newest to oldest.
|
2016-04-02 06:52:03 +08:00
|
|
|
ASTWriter::RecordData LocalRedecls;
|
|
|
|
ASTRecordWriter LocalRedeclWriter(Record, LocalRedecls);
|
2015-08-23 04:13:39 +08:00
|
|
|
for (const Decl *Prev = FirstLocal->getMostRecentDecl();
|
|
|
|
Prev != FirstLocal; Prev = Prev->getPreviousDecl())
|
|
|
|
if (!Prev->isFromASTFile())
|
2016-04-02 06:52:03 +08:00
|
|
|
LocalRedeclWriter.AddDeclRef(Prev);
|
2015-08-23 04:13:39 +08:00
|
|
|
|
|
|
|
// If we have any redecls, write them now as a separate record preceding
|
|
|
|
// the declaration itself.
|
|
|
|
if (LocalRedecls.empty())
|
|
|
|
Record.push_back(0);
|
2016-04-13 10:12:03 +08:00
|
|
|
else
|
|
|
|
Record.AddOffset(LocalRedeclWriter.Emit(LOCAL_REDECLARATIONS));
|
2015-08-22 09:47:18 +08:00
|
|
|
} else {
|
|
|
|
Record.push_back(0);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(FirstLocal);
|
2015-03-06 07:24:12 +08:00
|
|
|
}
|
2012-01-16 00:58:34 +08:00
|
|
|
|
|
|
|
// Make sure that we serialize both the previous and the most-recent
|
|
|
|
// declarations, which (transitively) ensures that all declarations in the
|
|
|
|
// chain get serialized.
|
2015-02-06 10:42:59 +08:00
|
|
|
//
|
|
|
|
// FIXME: This is not correct; when we reach an imported declaration we
|
|
|
|
// won't emit its previous declaration.
|
2015-07-13 07:43:21 +08:00
|
|
|
(void)Writer.GetDeclRef(D->getPreviousDecl());
|
2015-02-06 10:42:59 +08:00
|
|
|
(void)Writer.GetDeclRef(MostRecent);
|
2012-01-16 00:58:34 +08:00
|
|
|
} else {
|
|
|
|
// We use the sentinel value 0 to indicate an only declaration.
|
|
|
|
Record.push_back(0);
|
2011-12-20 02:19:24 +08:00
|
|
|
}
|
2010-08-04 01:30:10 +08:00
|
|
|
}
|
2009-04-27 14:16:06 +08:00
|
|
|
|
2013-03-22 14:34:35 +08:00
|
|
|
void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
|
|
|
|
Record.push_back(D->varlist_size());
|
|
|
|
VisitDecl(D);
|
2014-03-14 23:55:35 +08:00
|
|
|
for (auto *I : D->varlists())
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(I);
|
2013-03-22 14:34:35 +08:00
|
|
|
Code = serialization::DECL_OMP_THREADPRIVATE;
|
|
|
|
}
|
|
|
|
|
2016-03-03 13:21:39 +08:00
|
|
|
void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
|
2016-03-04 17:22:22 +08:00
|
|
|
VisitValueDecl(D);
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddSourceLocation(D->getLocStart());
|
2016-04-07 01:06:00 +08:00
|
|
|
Record.AddStmt(D->getCombiner());
|
|
|
|
Record.AddStmt(D->getInitializer());
|
2016-04-02 06:52:03 +08:00
|
|
|
Record.AddDeclRef(D->getPrevDeclInScope());
|
2016-03-03 13:21:39 +08:00
|
|
|
Code = serialization::DECL_OMP_DECLARE_REDUCTION;
|
|
|
|
}
|
|
|
|
|
2016-02-11 13:35:55 +08:00
|
|
|
void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
|
2016-02-08 17:29:13 +08:00
|
|
|
VisitVarDecl(D);
|
2016-02-11 13:35:55 +08:00
|
|
|
Code = serialization::DECL_OMP_CAPTUREDEXPR;
|
2016-02-08 17:29:13 +08:00
|
|
|
}
|
|
|
|
|
2009-04-27 14:16:06 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2010-08-19 07:56:21 +08:00
|
|
|
// ASTWriter Implementation
|
2009-04-27 14:16:06 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-07-26 14:37:51 +08:00
|
|
|
void ASTWriter::WriteDeclAbbrevs() {
|
2009-04-27 15:35:58 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2011-06-03 10:27:19 +08:00
|
|
|
BitCodeAbbrev *Abv;
|
|
|
|
|
2011-06-04 07:11:16 +08:00
|
|
|
// Abbreviation for DECL_FIELD
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
|
2011-06-03 10:27:19 +08:00
|
|
|
// Decl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
|
2015-12-12 06:41:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
|
2012-03-10 05:09:04 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
|
2011-11-24 04:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // AccessSpecifier
|
2011-09-09 10:06:17 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
|
2011-12-01 10:07:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
|
2011-06-04 07:11:16 +08:00
|
|
|
// NamedDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
|
2015-02-07 11:11:11 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
|
2011-06-04 07:11:16 +08:00
|
|
|
// ValueDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
|
|
|
// DeclaratorDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
|
|
|
|
// FieldDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); //getBitWidth
|
|
|
|
// Type Source Info
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
|
|
|
|
DeclFieldAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
|
|
|
// Abbreviation for DECL_OBJC_IVAR
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR));
|
|
|
|
// Decl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
|
2015-12-12 06:41:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
|
2012-03-10 05:09:04 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
|
2011-11-24 04:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // AccessSpecifier
|
2011-09-09 10:06:17 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
|
2011-12-01 10:07:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
|
2011-06-03 10:27:19 +08:00
|
|
|
// NamedDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
|
2015-02-07 11:11:11 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
|
2011-06-03 10:27:19 +08:00
|
|
|
// ValueDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
2011-06-04 07:11:16 +08:00
|
|
|
// DeclaratorDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
|
|
|
|
// FieldDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); //getBitWidth
|
|
|
|
// ObjC Ivar
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
|
|
|
|
// Type Source Info
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
|
|
|
|
DeclObjCIvarAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
|
|
|
// Abbreviation for DECL_ENUM
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
|
2011-10-27 01:53:41 +08:00
|
|
|
// Redeclarable
|
2011-12-19 23:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
|
2011-06-04 07:11:16 +08:00
|
|
|
// Decl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
|
2015-12-12 06:41:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
|
2012-03-10 05:09:04 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
|
2011-11-24 04:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
|
2011-09-09 10:06:17 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
|
2011-12-01 10:07:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
|
2011-06-04 07:11:16 +08:00
|
|
|
// NamedDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
|
2015-02-07 11:11:11 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
|
2011-06-04 07:11:16 +08:00
|
|
|
// TypeDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
|
|
|
|
// TagDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
|
2011-10-07 14:10:15 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
|
2011-10-01 06:11:31 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
|
2013-07-14 09:07:41 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
|
2016-07-16 02:11:33 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
|
2014-08-30 08:04:23 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ExtInfoKind
|
2011-06-04 07:11:16 +08:00
|
|
|
// EnumDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // AddTypeRef
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IntegerType
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getPromotionType
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getNumPositiveBits
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getNumNegativeBits
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScoped
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScopedUsingClassTag
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isFixed
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedMembEnum
|
|
|
|
// DC
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
|
|
|
|
DeclEnumAbbrev = Stream.EmitAbbrev(Abv);
|
2011-06-03 10:27:19 +08:00
|
|
|
|
|
|
|
// Abbreviation for DECL_RECORD
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
|
2011-10-27 01:53:41 +08:00
|
|
|
// Redeclarable
|
2011-12-19 23:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
|
2011-06-03 10:27:19 +08:00
|
|
|
// Decl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
|
2015-12-12 06:41:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
|
2012-03-10 05:09:04 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
|
2011-11-24 04:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
|
2011-09-09 10:06:17 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
|
2011-12-01 10:07:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
|
2011-06-03 10:27:19 +08:00
|
|
|
// NamedDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
|
2015-02-07 11:11:11 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
|
2011-06-03 10:27:19 +08:00
|
|
|
// TypeDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
|
|
|
|
// TagDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
|
2011-10-07 14:10:15 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
|
2011-10-01 06:11:31 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
|
2013-07-14 09:07:41 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
|
2016-07-16 02:11:33 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
|
2014-08-30 08:04:23 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ExtInfoKind
|
2011-06-03 10:27:19 +08:00
|
|
|
// RecordDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FlexibleArrayMember
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasObjectMember
|
2013-01-26 07:57:05 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasVolatileMember
|
2011-06-03 10:27:19 +08:00
|
|
|
// DC
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
|
|
|
|
DeclRecordAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
|
|
|
// Abbreviation for DECL_PARM_VAR
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
|
2011-10-27 01:53:41 +08:00
|
|
|
// Redeclarable
|
2011-12-19 23:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
|
2009-04-27 15:35:58 +08:00
|
|
|
// Decl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
|
2015-12-12 06:41:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
|
2012-03-10 05:09:04 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
|
2009-04-27 15:35:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
|
2009-06-20 07:52:42 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
|
2011-04-20 03:51:10 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
|
2011-11-24 04:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
|
2009-04-27 15:35:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
|
2011-09-09 10:06:17 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
|
2011-12-01 10:07:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
|
2009-04-27 15:35:58 +08:00
|
|
|
// NamedDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
|
2015-02-07 11:11:11 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
|
2009-04-27 15:35:58 +08:00
|
|
|
// ValueDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
2009-08-19 09:28:35 +08:00
|
|
|
// DeclaratorDecl
|
2011-03-08 16:55:46 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
|
2010-10-16 02:21:24 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
|
2009-04-27 15:35:58 +08:00
|
|
|
// VarDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // StorageClass
|
2013-05-04 16:27:07 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // getTSCSpec
|
2009-04-27 15:35:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer
|
2013-02-12 13:48:23 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // Linkage
|
2009-04-27 15:35:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasInit
|
2010-07-05 05:44:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo
|
2009-04-27 15:35:58 +08:00
|
|
|
// ParmVarDecl
|
2011-05-02 08:30:12 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsObjCMethodParameter
|
2011-05-02 06:35:37 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ScopeDepth
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex
|
2009-04-27 15:35:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ObjCDeclQualifier
|
2011-03-09 12:22:44 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // KNRPromoted
|
2010-03-13 02:31:32 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedDefaultArg
|
2010-07-05 05:44:07 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasUninstantiatedDefaultArg
|
2011-06-04 07:11:16 +08:00
|
|
|
// Type Source Info
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
|
|
|
|
DeclParmVarAbbrev = Stream.EmitAbbrev(Abv);
|
2010-07-27 08:17:23 +08:00
|
|
|
|
2011-06-07 00:22:39 +08:00
|
|
|
// Abbreviation for DECL_TYPEDEF
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
|
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
|
|
|
// Redeclarable
|
2011-12-19 23:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
|
2011-06-04 07:11:16 +08:00
|
|
|
// Decl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
|
2015-12-12 06:41:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
|
2012-03-10 05:09:04 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
|
2014-07-26 14:37:51 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isUsed
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isReferenced
|
2011-11-24 04:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
|
2014-07-26 14:37:51 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // C++ AccessSpecifier
|
2011-09-09 10:06:17 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
|
2011-12-01 10:07:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
|
2011-06-04 07:11:16 +08:00
|
|
|
// NamedDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
|
2015-02-07 11:11:11 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
|
2011-06-04 07:11:16 +08:00
|
|
|
// TypeDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
|
|
|
|
// TypedefDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
|
|
|
|
DeclTypedefAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
2011-06-07 00:22:39 +08:00
|
|
|
// Abbreviation for DECL_VAR
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
|
2011-10-27 01:53:41 +08:00
|
|
|
// Redeclarable
|
2011-12-19 23:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
|
2011-06-04 07:11:16 +08:00
|
|
|
// Decl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
|
2015-12-12 06:41:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
|
2012-03-10 05:09:04 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
|
2011-11-24 04:27:36 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
|
2011-09-09 10:06:17 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
|
2011-12-01 10:07:58 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
|
2011-06-04 07:11:16 +08:00
|
|
|
// NamedDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
|
2015-02-07 11:11:11 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
|
2011-06-04 07:11:16 +08:00
|
|
|
// ValueDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
|
|
|
// DeclaratorDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
|
|
|
|
// VarDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClass
|
2013-05-04 16:27:07 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // getTSCSpec
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // CXXDirectInitializer
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
|
2011-06-17 14:42:21 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
|
2016-06-25 08:15:56 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInline
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInlineSpecified
|
2012-09-21 07:43:29 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isConstexpr
|
2013-09-28 12:02:39 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isInitCapture
|
2013-08-14 02:18:50 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // isPrevDeclInSameScope
|
2013-05-26 01:16:20 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
|
2011-06-04 07:11:16 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasInit
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasMemberSpecInfo
|
|
|
|
// Type Source Info
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
|
|
|
|
DeclVarAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
2014-07-26 14:37:51 +08:00
|
|
|
// Abbreviation for DECL_CXX_METHOD
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
|
|
|
|
// RedeclarableDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
|
|
|
|
// Decl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
|
2015-12-12 06:41:00 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
|
2014-07-26 14:37:51 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // Invalid
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Used
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Referenced
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // InObjCContainer
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Access
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModulePrivate
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
|
|
|
|
// NamedDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier
|
2015-02-07 11:11:11 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
|
2014-07-26 14:37:51 +08:00
|
|
|
// ValueDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
|
|
|
// DeclaratorDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo
|
|
|
|
// FunctionDecl
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedProto
|
|
|
|
Abv->Add(BitCodeAbbrevOp(1)); // HasWrittenProto
|
2015-02-07 07:20:21 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Deleted
|
2014-07-26 14:37:51 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Trivial
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constexpr
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind
|
|
|
|
// This Array slurps the rest of the record. Fortunately we want to encode
|
|
|
|
// (nearly) all the remaining (variable number of) fields in the same way.
|
|
|
|
//
|
|
|
|
// This is the function template information if any, then
|
|
|
|
// NumParams and Params[] from FunctionDecl, and
|
|
|
|
// NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
|
|
|
|
//
|
|
|
|
// Add an AbbrevOp for 'size then elements' and use it here.
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
|
|
|
DeclCXXMethodAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
2011-06-07 00:22:39 +08:00
|
|
|
// Abbreviation for EXPR_DECL_REF
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
|
|
|
|
//Stmt
|
|
|
|
//Expr
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
2011-07-01 09:22:09 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
|
|
|
|
//DeclRefExpr
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
|
2011-10-05 15:56:41 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
|
2015-01-12 18:17:46 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
|
|
|
|
1)); // RefersToEnclosingVariableOrCapture
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
|
|
|
|
DeclRefExprAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
|
|
|
// Abbreviation for EXPR_INTEGER_LITERAL
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
|
|
|
|
//Stmt
|
|
|
|
//Expr
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
2011-07-01 09:22:09 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
|
|
|
|
//Integer Literal
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
|
|
|
|
Abv->Add(BitCodeAbbrevOp(32)); // Bit Width
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
|
|
|
|
IntegerLiteralAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
|
|
|
// Abbreviation for EXPR_CHARACTER_LITERAL
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
|
|
|
|
//Stmt
|
|
|
|
//Expr
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
2011-07-01 09:22:09 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
|
2011-06-04 05:46:44 +08:00
|
|
|
//Character Literal
|
2011-06-03 10:27:19 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
|
2016-01-08 04:59:26 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind
|
2011-06-03 10:27:19 +08:00
|
|
|
CharacterLiteralAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
2014-07-27 12:19:32 +08:00
|
|
|
// Abbreviation for EXPR_IMPLICIT_CAST
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
|
|
|
|
// Stmt
|
|
|
|
// Expr
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
|
|
|
|
// CastExpr
|
|
|
|
Abv->Add(BitCodeAbbrevOp(0)); // PathSize
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
|
|
|
|
// ImplicitCastExpr
|
|
|
|
ExprImplicitCastAbbrev = Stream.EmitAbbrev(Abv);
|
|
|
|
|
2010-07-27 08:17:23 +08:00
|
|
|
Abv = new BitCodeAbbrev();
|
2010-08-19 07:57:32 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
|
2010-07-27 08:17:23 +08:00
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
|
|
|
DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv);
|
2010-08-21 00:04:35 +08:00
|
|
|
|
|
|
|
Abv = new BitCodeAbbrev();
|
|
|
|
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
|
|
|
|
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
|
|
|
DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv);
|
2009-04-27 15:35:58 +08:00
|
|
|
}
|
|
|
|
|
2009-09-17 11:06:51 +08:00
|
|
|
/// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
|
|
|
|
/// consumers of the AST.
|
|
|
|
///
|
2010-08-19 07:56:27 +08:00
|
|
|
/// Such decls will always be deserialized from the AST file, so we would like
|
2009-09-17 11:06:51 +08:00
|
|
|
/// this to be as restrictive as possible. Currently the predicate is driven by
|
|
|
|
/// code generation requirements, if other clients have a different notion of
|
|
|
|
/// what is "required" then we may have to consider an alternate scheme where
|
|
|
|
/// clients can iterate over the top-level decls and get information on them,
|
|
|
|
/// without necessary deserializing them. We could explicitly require such
|
|
|
|
/// clients to use a separate API call to "realize" the decl. This should be
|
|
|
|
/// relatively painless since they would presumably only do it for top-level
|
|
|
|
/// decls.
|
2015-08-19 10:30:28 +08:00
|
|
|
static bool isRequiredDecl(const Decl *D, ASTContext &Context,
|
|
|
|
bool WritingModule) {
|
2011-09-14 05:35:00 +08:00
|
|
|
// An ObjCMethodDecl is never considered as "required" because its
|
|
|
|
// implementation container always is.
|
|
|
|
|
2016-04-06 19:38:59 +08:00
|
|
|
// File scoped assembly or obj-c or OMP declare target implementation must be
|
|
|
|
// seen.
|
|
|
|
if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D) ||
|
|
|
|
D->hasAttr<OMPDeclareTargetDeclAttr>())
|
2015-08-19 10:30:28 +08:00
|
|
|
return true;
|
|
|
|
|
2016-07-21 03:10:16 +08:00
|
|
|
if (WritingModule && (isa<VarDecl>(D) || isa<ImportDecl>(D))) {
|
|
|
|
// These declarations are part of the module initializer, and are emitted
|
|
|
|
// if and when the module is imported, rather than being emitted eagerly.
|
|
|
|
return false;
|
|
|
|
}
|
2009-09-17 11:06:51 +08:00
|
|
|
|
2010-07-30 04:08:05 +08:00
|
|
|
return Context.DeclMustBeEmitted(D);
|
2009-09-17 11:06:51 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:21 +08:00
|
|
|
void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
|
2012-03-23 00:08:04 +08:00
|
|
|
// Determine the ID for this declaration.
|
|
|
|
serialization::DeclID ID;
|
2015-11-03 09:20:54 +08:00
|
|
|
assert(!D->isFromASTFile() && "should not be emitting imported decl");
|
|
|
|
serialization::DeclID &IDR = DeclIDs[D];
|
|
|
|
if (IDR == 0)
|
|
|
|
IDR = NextDeclID++;
|
2012-03-23 00:08:04 +08:00
|
|
|
|
2015-11-03 09:20:54 +08:00
|
|
|
ID = IDR;
|
2012-03-23 00:08:04 +08:00
|
|
|
|
2016-03-27 13:52:25 +08:00
|
|
|
assert(ID >= FirstDeclID && "invalid decl ID");
|
2012-01-06 06:33:30 +08:00
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
RecordData Record;
|
|
|
|
ASTDeclWriter W(*this, Context, Record);
|
|
|
|
|
2015-08-23 04:13:39 +08:00
|
|
|
// Build a record for this declaration
|
|
|
|
W.Visit(D);
|
|
|
|
|
2016-04-02 06:52:03 +08:00
|
|
|
// Emit this declaration to the bitstream.
|
|
|
|
uint64_t Offset = W.Emit(D);
|
2015-08-23 04:13:39 +08:00
|
|
|
|
2016-03-27 13:52:25 +08:00
|
|
|
// Record the offset for this declaration
|
|
|
|
SourceLocation Loc = D->getLocation();
|
2016-04-02 06:52:03 +08:00
|
|
|
unsigned Index = ID - FirstDeclID;
|
2016-03-27 13:52:25 +08:00
|
|
|
if (DeclOffsets.size() == Index)
|
2016-04-02 06:52:03 +08:00
|
|
|
DeclOffsets.push_back(DeclOffset(Loc, Offset));
|
2016-03-27 13:52:25 +08:00
|
|
|
else if (DeclOffsets.size() < Index) {
|
2016-04-02 06:52:03 +08:00
|
|
|
// FIXME: Can/should this happen?
|
2016-03-27 13:52:25 +08:00
|
|
|
DeclOffsets.resize(Index+1);
|
|
|
|
DeclOffsets[Index].setLocation(Loc);
|
2016-04-02 06:52:03 +08:00
|
|
|
DeclOffsets[Index].BitOffset = Offset;
|
|
|
|
} else {
|
|
|
|
llvm_unreachable("declarations should be emitted in ID order");
|
2009-10-17 08:13:19 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-03-27 13:52:25 +08:00
|
|
|
SourceManager &SM = Context.getSourceManager();
|
|
|
|
if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
|
|
|
|
associateDeclWithFile(D, ID);
|
|
|
|
|
2014-01-31 09:06:56 +08:00
|
|
|
// Note declarations that should be deserialized eagerly so that we can add
|
|
|
|
// them to a record in the AST file later.
|
2015-08-19 10:30:28 +08:00
|
|
|
if (isRequiredDecl(D, Context, WritingModule))
|
2014-01-31 09:06:56 +08:00
|
|
|
EagerlyDeserializedDecls.push_back(ID);
|
2009-04-27 14:16:06 +08:00
|
|
|
}
|
2014-03-23 07:33:22 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
|
|
|
|
// Switch case IDs are per function body.
|
|
|
|
Writer->ClearSwitchCaseIDs();
|
2014-03-23 07:33:22 +08:00
|
|
|
|
2016-04-07 01:06:00 +08:00
|
|
|
assert(FD->doesThisDeclarationHaveABody());
|
|
|
|
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
|
|
|
|
Record->push_back(CD->getNumCtorInitializers());
|
|
|
|
if (CD->getNumCtorInitializers())
|
2016-04-14 05:57:08 +08:00
|
|
|
AddCXXCtorInitializers(
|
2016-04-07 01:06:00 +08:00
|
|
|
llvm::makeArrayRef(CD->init_begin(), CD->init_end()));
|
|
|
|
}
|
|
|
|
AddStmt(FD->getBody());
|
2014-03-23 07:33:22 +08:00
|
|
|
}
|