2010-08-19 07:57:11 +08:00
|
|
|
//===--- ASTReaderDecl.cpp - Decl Deserialization ---------------*- C++ -*-===//
|
2009-04-27 13:27:42 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2010-08-19 07:56:43 +08:00
|
|
|
// This file implements the ASTReader::ReadDeclRecord method, which is the
|
2009-04-27 13:27:42 +08:00
|
|
|
// entrypoint for loading a decl.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-10-25 01:26:36 +08:00
|
|
|
#include "ASTCommon.h"
|
2010-08-19 07:57:17 +08:00
|
|
|
#include "clang/Serialization/ASTReader.h"
|
2011-09-01 08:58:55 +08:00
|
|
|
#include "clang/Sema/SemaDiagnostic.h"
|
2009-04-27 13:27:42 +08:00
|
|
|
#include "clang/AST/ASTConsumer.h"
|
|
|
|
#include "clang/AST/ASTContext.h"
|
|
|
|
#include "clang/AST/DeclVisitor.h"
|
|
|
|
#include "clang/AST/DeclGroup.h"
|
2010-05-08 05:43:38 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2009-04-27 13:27:42 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
using namespace clang;
|
2010-08-19 07:57:32 +08:00
|
|
|
using namespace clang::serialization;
|
2009-04-27 13:27:42 +08:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Declaration deserialization
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-30 06:47:00 +08:00
|
|
|
namespace clang {
|
2010-08-19 07:56:48 +08:00
|
|
|
class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {
|
2010-08-19 07:56:43 +08:00
|
|
|
ASTReader &Reader;
|
2011-07-23 00:00:58 +08:00
|
|
|
Module &F;
|
2010-07-23 06:43:28 +08:00
|
|
|
llvm::BitstreamCursor &Cursor;
|
2010-08-19 07:57:32 +08:00
|
|
|
const DeclID ThisDeclID;
|
2010-10-25 01:26:27 +08:00
|
|
|
typedef ASTReader::RecordData RecordData;
|
|
|
|
const RecordData &Record;
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned &Idx;
|
2010-08-19 07:57:32 +08:00
|
|
|
TypeID TypeIDForTypeDecl;
|
2011-03-05 09:35:54 +08:00
|
|
|
|
|
|
|
DeclID DeclContextIDForTemplateParmDecl;
|
|
|
|
DeclID LexicalDeclContextIDForTemplateParmDecl;
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2010-07-23 06:43:28 +08:00
|
|
|
uint64_t GetCurrentCursorOffset();
|
2011-07-22 06:35:25 +08:00
|
|
|
|
2010-10-25 01:26:27 +08:00
|
|
|
SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) {
|
2010-10-05 23:59:54 +08:00
|
|
|
return Reader.ReadSourceLocation(F, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
2010-10-25 01:26:27 +08:00
|
|
|
SourceRange ReadSourceRange(const RecordData &R, unsigned &I) {
|
2010-10-05 23:59:54 +08:00
|
|
|
return Reader.ReadSourceRange(F, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
2010-10-25 01:26:27 +08:00
|
|
|
TypeSourceInfo *GetTypeSourceInfo(const RecordData &R, unsigned &I) {
|
2010-10-05 23:59:54 +08:00
|
|
|
return Reader.GetTypeSourceInfo(F, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
|
|
|
serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
|
|
|
|
return Reader.ReadDeclID(F, R, I);
|
|
|
|
}
|
|
|
|
|
|
|
|
Decl *ReadDecl(const RecordData &R, unsigned &I) {
|
|
|
|
return Reader.ReadDecl(F, R, I);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
T *ReadDeclAs(const RecordData &R, unsigned &I) {
|
|
|
|
return Reader.ReadDeclAs<T>(F, R, I);
|
|
|
|
}
|
|
|
|
|
2010-10-16 02:21:24 +08:00
|
|
|
void ReadQualifierInfo(QualifierInfo &Info,
|
2010-10-25 01:26:27 +08:00
|
|
|
const RecordData &R, unsigned &I) {
|
2010-10-16 02:21:24 +08:00
|
|
|
Reader.ReadQualifierInfo(F, Info, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
2010-10-16 02:21:24 +08:00
|
|
|
void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name,
|
2010-10-25 01:26:27 +08:00
|
|
|
const RecordData &R, unsigned &I) {
|
2010-10-16 02:21:24 +08:00
|
|
|
Reader.ReadDeclarationNameLoc(F, DNLoc, Name, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
2010-10-16 02:21:24 +08:00
|
|
|
void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo,
|
2010-10-25 01:26:27 +08:00
|
|
|
const RecordData &R, unsigned &I) {
|
2010-10-16 02:21:24 +08:00
|
|
|
Reader.ReadDeclarationNameInfo(F, NameInfo, R, I);
|
|
|
|
}
|
2010-07-23 06:43:28 +08:00
|
|
|
|
2010-10-25 01:26:40 +08:00
|
|
|
void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data,
|
|
|
|
const RecordData &R, unsigned &I);
|
|
|
|
|
|
|
|
void InitializeCXXDefinitionData(CXXRecordDecl *D,
|
|
|
|
CXXRecordDecl *DefinitionDecl,
|
|
|
|
const RecordData &Record, unsigned &Idx);
|
2009-04-27 13:27:42 +08:00
|
|
|
public:
|
2011-07-23 00:00:58 +08:00
|
|
|
ASTDeclReader(ASTReader &Reader, Module &F,
|
2010-10-05 23:59:54 +08:00
|
|
|
llvm::BitstreamCursor &Cursor, DeclID thisDeclID,
|
2010-10-25 01:26:27 +08:00
|
|
|
const RecordData &Record, unsigned &Idx)
|
2010-10-05 23:59:54 +08:00
|
|
|
: Reader(Reader), F(F), Cursor(Cursor), ThisDeclID(thisDeclID),
|
|
|
|
Record(Record), Idx(Idx), TypeIDForTypeDecl(0) { }
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2011-02-12 15:50:47 +08:00
|
|
|
static void attachPreviousDecl(Decl *D, Decl *previous);
|
|
|
|
|
2010-07-02 19:55:01 +08:00
|
|
|
void Visit(Decl *D);
|
|
|
|
|
2011-07-23 00:00:58 +08:00
|
|
|
void UpdateDecl(Decl *D, Module &Module,
|
2011-04-29 16:19:30 +08:00
|
|
|
const RecordData &Record);
|
2010-10-25 01:26:36 +08:00
|
|
|
|
2011-09-01 08:58:55 +08:00
|
|
|
static void setNextObjCCategory(ObjCCategoryDecl *Cat,
|
|
|
|
ObjCCategoryDecl *Next) {
|
|
|
|
Cat->NextClassCategory = Next;
|
|
|
|
}
|
|
|
|
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitDecl(Decl *D);
|
|
|
|
void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
|
|
|
|
void VisitNamedDecl(NamedDecl *ND);
|
2011-02-17 15:39:24 +08:00
|
|
|
void VisitLabelDecl(LabelDecl *LD);
|
2010-02-22 02:22:14 +08:00
|
|
|
void VisitNamespaceDecl(NamespaceDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
|
|
|
|
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitTypeDecl(TypeDecl *TD);
|
|
|
|
void VisitTypedefDecl(TypedefDecl *TD);
|
2011-04-15 22:24:37 +08:00
|
|
|
void VisitTypeAliasDecl(TypeAliasDecl *TD);
|
2010-06-30 16:49:30 +08:00
|
|
|
void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitTagDecl(TagDecl *TD);
|
|
|
|
void VisitEnumDecl(EnumDecl *ED);
|
|
|
|
void VisitRecordDecl(RecordDecl *RD);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitCXXRecordDecl(CXXRecordDecl *D);
|
|
|
|
void VisitClassTemplateSpecializationDecl(
|
|
|
|
ClassTemplateSpecializationDecl *D);
|
|
|
|
void VisitClassTemplatePartialSpecializationDecl(
|
|
|
|
ClassTemplatePartialSpecializationDecl *D);
|
2011-08-31 21:59:56 +08:00
|
|
|
void VisitClassScopeFunctionSpecializationDecl(
|
|
|
|
ClassScopeFunctionSpecializationDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitValueDecl(ValueDecl *VD);
|
|
|
|
void VisitEnumConstantDecl(EnumConstantDecl *ECD);
|
2010-06-30 16:49:30 +08:00
|
|
|
void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
|
2009-08-19 09:28:35 +08:00
|
|
|
void VisitDeclaratorDecl(DeclaratorDecl *DD);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitFunctionDecl(FunctionDecl *FD);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitCXXMethodDecl(CXXMethodDecl *D);
|
|
|
|
void VisitCXXConstructorDecl(CXXConstructorDecl *D);
|
|
|
|
void VisitCXXDestructorDecl(CXXDestructorDecl *D);
|
|
|
|
void VisitCXXConversionDecl(CXXConversionDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitFieldDecl(FieldDecl *FD);
|
2010-11-21 14:08:52 +08:00
|
|
|
void VisitIndirectFieldDecl(IndirectFieldDecl *FD);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitVarDecl(VarDecl *VD);
|
|
|
|
void VisitImplicitParamDecl(ImplicitParamDecl *PD);
|
|
|
|
void VisitParmVarDecl(ParmVarDecl *PD);
|
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);
|
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);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
|
2010-06-05 13:09:32 +08:00
|
|
|
void VisitAccessSpecDecl(AccessSpecDecl *D);
|
2010-06-30 06:47:00 +08:00
|
|
|
void VisitFriendDecl(FriendDecl *D);
|
2010-05-08 05:43:38 +08:00
|
|
|
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
|
|
|
|
void VisitStaticAssertDecl(StaticAssertDecl *D);
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitBlockDecl(BlockDecl *BD);
|
2010-05-08 05:43:38 +08:00
|
|
|
|
2009-04-27 13:27:42 +08:00
|
|
|
std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
|
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: Reorder according to DeclNodes.td?
|
2009-04-27 13:27:42 +08:00
|
|
|
void VisitObjCMethodDecl(ObjCMethodDecl *D);
|
|
|
|
void VisitObjCContainerDecl(ObjCContainerDecl *D);
|
|
|
|
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
|
|
|
|
void VisitObjCIvarDecl(ObjCIvarDecl *D);
|
|
|
|
void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
|
|
|
|
void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
|
|
|
|
void VisitObjCClassDecl(ObjCClassDecl *D);
|
|
|
|
void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *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);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
uint64_t ASTDeclReader::GetCurrentCursorOffset() {
|
Introduce a global bit-offset continuous range map into the ASTReader,
so that we have one, simple way to map from global bit offsets to
local bit offsets. Eliminates a number of loops over the chain, and
generalizes for more interesting bit remappings.
Also, as an amusing oddity, we were computing global bit offsets
*backwards* for preprocessed entities (e.g., the directly included PCH
file in the chain would start at offset zero, rather than the original
PCH that occurs first in translation unit). Even more amusingly, it
made precompiled preambles work, because we were forgetting to adjust
the local bit offset to a global bit offset when storing preprocessed
entity offsets in the ASTUnit. Two wrongs made a right, and now
they're both right.
llvm-svn: 135750
2011-07-22 14:10:01 +08:00
|
|
|
return F.DeclsCursor.GetCurrentBitNo() + F.GlobalBitOffset;
|
2010-07-23 06:43:28 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::Visit(Decl *D) {
|
|
|
|
DeclVisitor<ASTDeclReader, void>::Visit(D);
|
2010-07-02 19:55:01 +08:00
|
|
|
|
2011-06-04 07:11:16 +08:00
|
|
|
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
|
|
|
|
if (DD->DeclInfo) {
|
|
|
|
DeclaratorDecl::ExtInfo *Info =
|
|
|
|
DD->DeclInfo.get<DeclaratorDecl::ExtInfo *>();
|
|
|
|
Info->TInfo =
|
|
|
|
GetTypeSourceInfo(Record, Idx);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
DD->DeclInfo = GetTypeSourceInfo(Record, Idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-02 23:58:43 +08:00
|
|
|
if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
|
2010-08-11 20:19:30 +08:00
|
|
|
// if we have a fully initialized TypeDecl, we can safely read its type now.
|
2010-12-11 01:03:06 +08:00
|
|
|
TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull());
|
2010-07-02 23:58:43 +08:00
|
|
|
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
|
|
|
// FunctionDecl's body was written last after all other Stmts/Exprs.
|
|
|
|
if (Record[Idx++])
|
2010-07-23 06:43:28 +08:00
|
|
|
FD->setLazyBody(GetCurrentCursorOffset());
|
2011-03-05 09:35:54 +08:00
|
|
|
} else if (D->isTemplateParameter()) {
|
|
|
|
// If we have a fully initialized template parameter, we can now
|
|
|
|
// set its DeclContext.
|
|
|
|
D->setDeclContext(
|
|
|
|
cast_or_null<DeclContext>(
|
|
|
|
Reader.GetDecl(DeclContextIDForTemplateParmDecl)));
|
|
|
|
D->setLexicalDeclContext(
|
|
|
|
cast_or_null<DeclContext>(
|
|
|
|
Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl)));
|
2010-07-02 23:58:43 +08:00
|
|
|
}
|
2010-07-02 19:55:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitDecl(Decl *D) {
|
2011-03-05 09:35:54 +08:00
|
|
|
if (D->isTemplateParameter()) {
|
|
|
|
// We don't want to deserialize the DeclContext of a template
|
|
|
|
// parameter immediately, because the template parameter might be
|
|
|
|
// used in the formulation of its DeclContext. Use the translation
|
|
|
|
// unit DeclContext as a placeholder.
|
2011-07-22 06:35:25 +08:00
|
|
|
DeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
|
|
|
|
LexicalDeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
|
2011-09-10 05:34:22 +08:00
|
|
|
D->setDeclContext(Reader.getContext().getTranslationUnitDecl());
|
2011-03-05 09:35:54 +08:00
|
|
|
} else {
|
2011-07-22 06:35:25 +08:00
|
|
|
D->setDeclContext(ReadDeclAs<DeclContext>(Record, Idx));
|
|
|
|
D->setLexicalDeclContext(ReadDeclAs<DeclContext>(Record, Idx));
|
2011-03-05 09:35:54 +08:00
|
|
|
}
|
2010-10-05 23:59:54 +08:00
|
|
|
D->setLocation(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
D->setInvalidDecl(Record[Idx++]);
|
2010-10-19 03:20:11 +08:00
|
|
|
if (Record[Idx++]) { // hasAttrs
|
2010-08-19 07:23:40 +08:00
|
|
|
AttrVec Attrs;
|
2010-10-19 03:20:11 +08:00
|
|
|
Reader.ReadAttributes(F, Attrs, Record, Idx);
|
2010-08-19 07:23:40 +08:00
|
|
|
D->setAttrs(Attrs);
|
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
D->setImplicit(Record[Idx++]);
|
2009-06-20 07:52:42 +08:00
|
|
|
D->setUsed(Record[Idx++]);
|
2011-04-20 03:51:10 +08:00
|
|
|
D->setReferenced(Record[Idx++]);
|
2009-04-27 13:27:42 +08:00
|
|
|
D->setAccess((AccessSpecifier)Record[Idx++]);
|
2011-09-10 08:09:20 +08:00
|
|
|
D->FromASTFile = true;
|
2011-09-09 10:06:17 +08:00
|
|
|
D->ModulePrivate = Record[Idx++];
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
|
2011-08-12 08:15:20 +08:00
|
|
|
llvm_unreachable("Translation units are not serialized");
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(ND);
|
2011-07-22 08:38:23 +08:00
|
|
|
ND->setDeclName(Reader.ReadDeclarationName(F, Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(TD);
|
2011-03-06 23:48:19 +08:00
|
|
|
TD->setLocStart(ReadSourceLocation(Record, Idx));
|
2010-07-02 19:55:01 +08:00
|
|
|
// Delay type reading until after we have fully initialized the decl.
|
2011-07-22 08:38:23 +08:00
|
|
|
TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
|
2010-07-02 19:55:01 +08:00
|
|
|
VisitTypeDecl(TD);
|
2010-10-05 23:59:54 +08:00
|
|
|
TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 22:24:37 +08:00
|
|
|
void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) {
|
|
|
|
VisitTypeDecl(TD);
|
|
|
|
TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitTypeDecl(TD);
|
2010-08-04 01:30:10 +08:00
|
|
|
VisitRedeclarable(TD);
|
2010-09-09 03:31:22 +08:00
|
|
|
TD->IdentifierNamespace = Record[Idx++];
|
2009-04-27 13:27:42 +08:00
|
|
|
TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
|
|
|
|
TD->setDefinition(Record[Idx++]);
|
2010-02-13 01:40:34 +08:00
|
|
|
TD->setEmbeddedInDeclarator(Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
TD->setRBraceLoc(ReadSourceLocation(Record, Idx));
|
2010-10-16 02:21:24 +08:00
|
|
|
if (Record[Idx++]) { // hasExtInfo
|
2011-09-10 05:34:22 +08:00
|
|
|
TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo();
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadQualifierInfo(*Info, Record, Idx);
|
2011-04-15 22:24:37 +08:00
|
|
|
TD->TypedefNameDeclOrQualifier = Info;
|
2010-10-16 02:21:24 +08:00
|
|
|
} else
|
2011-07-22 06:35:25 +08:00
|
|
|
TD->setTypedefNameForAnonDecl(ReadDeclAs<TypedefNameDecl>(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitTagDecl(ED);
|
2010-10-09 07:50:27 +08:00
|
|
|
if (TypeSourceInfo *TI = Reader.GetTypeSourceInfo(F, Record, Idx))
|
|
|
|
ED->setIntegerTypeSourceInfo(TI);
|
|
|
|
else
|
2011-07-22 08:38:23 +08:00
|
|
|
ED->setIntegerType(Reader.readType(F, Record, Idx));
|
|
|
|
ED->setPromotionType(Reader.readType(F, Record, Idx));
|
2010-05-06 16:49:23 +08:00
|
|
|
ED->setNumPositiveBits(Record[Idx++]);
|
|
|
|
ED->setNumNegativeBits(Record[Idx++]);
|
2010-10-09 07:50:27 +08:00
|
|
|
ED->IsScoped = Record[Idx++];
|
2010-12-04 02:54:17 +08:00
|
|
|
ED->IsScopedUsingClassTag = Record[Idx++];
|
2010-10-09 07:50:27 +08:00
|
|
|
ED->IsFixed = Record[Idx++];
|
2011-07-22 06:35:25 +08:00
|
|
|
ED->setInstantiationOfMemberEnum(ReadDeclAs<EnumDecl>(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitTagDecl(RD);
|
|
|
|
RD->setHasFlexibleArrayMember(Record[Idx++]);
|
|
|
|
RD->setAnonymousStructOrUnion(Record[Idx++]);
|
2009-07-09 00:37:44 +08:00
|
|
|
RD->setHasObjectMember(Record[Idx++]);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(VD);
|
2011-07-22 08:38:23 +08:00
|
|
|
VD->setType(Reader.readType(F, Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitValueDecl(ECD);
|
|
|
|
if (Record[Idx++])
|
2010-10-05 23:59:54 +08:00
|
|
|
ECD->setInitExpr(Reader.ReadExpr(F));
|
2009-04-27 13:27:42 +08:00
|
|
|
ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
|
2009-08-19 09:28:35 +08:00
|
|
|
VisitValueDecl(DD);
|
2011-03-08 16:55:46 +08:00
|
|
|
DD->setInnerLocStart(ReadSourceLocation(Record, Idx));
|
2010-10-16 02:21:24 +08:00
|
|
|
if (Record[Idx++]) { // hasExtInfo
|
|
|
|
DeclaratorDecl::ExtInfo *Info
|
2011-09-10 05:34:22 +08:00
|
|
|
= new (Reader.getContext()) DeclaratorDecl::ExtInfo();
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadQualifierInfo(*Info, Record, Idx);
|
|
|
|
DD->DeclInfo = Info;
|
2011-06-04 07:11:16 +08:00
|
|
|
}
|
2009-08-19 09:28:35 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
|
2009-08-19 09:28:35 +08:00
|
|
|
VisitDeclaratorDecl(FD);
|
2010-09-09 03:31:22 +08:00
|
|
|
VisitRedeclarable(FD);
|
2010-05-08 05:43:38 +08:00
|
|
|
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName(), Record, Idx);
|
2010-07-05 18:38:01 +08:00
|
|
|
FD->IdentifierNamespace = Record[Idx++];
|
2010-06-22 17:55:07 +08:00
|
|
|
switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
|
2011-09-23 13:06:16 +08:00
|
|
|
default: llvm_unreachable("Unhandled TemplatedKind!");
|
2010-06-22 17:55:07 +08:00
|
|
|
case FunctionDecl::TK_NonTemplate:
|
|
|
|
break;
|
|
|
|
case FunctionDecl::TK_FunctionTemplate:
|
2011-07-22 06:35:25 +08:00
|
|
|
FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>(Record,
|
|
|
|
Idx));
|
2010-06-22 17:55:07 +08:00
|
|
|
break;
|
|
|
|
case FunctionDecl::TK_MemberSpecialization: {
|
2011-07-22 06:35:25 +08:00
|
|
|
FunctionDecl *InstFD = ReadDeclAs<FunctionDecl>(Record, Idx);
|
2010-06-22 17:55:07 +08:00
|
|
|
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation(Record, Idx);
|
2011-09-10 05:34:22 +08:00
|
|
|
FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
|
2010-06-22 17:55:07 +08:00
|
|
|
FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case FunctionDecl::TK_FunctionTemplateSpecialization: {
|
2011-07-22 06:35:25 +08:00
|
|
|
FunctionTemplateDecl *Template = ReadDeclAs<FunctionTemplateDecl>(Record,
|
|
|
|
Idx);
|
2010-06-22 17:55:07 +08:00
|
|
|
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
|
|
|
|
|
|
|
|
// Template arguments.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2010-10-05 23:59:54 +08:00
|
|
|
Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
|
2010-06-22 17:55:07 +08:00
|
|
|
|
|
|
|
// Template args as written.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
|
2010-06-22 17:55:07 +08:00
|
|
|
SourceLocation LAngleLoc, RAngleLoc;
|
2011-09-23 04:07:09 +08:00
|
|
|
bool HasTemplateArgumentsAsWritten = Record[Idx++];
|
|
|
|
if (HasTemplateArgumentsAsWritten) {
|
2010-07-02 19:55:40 +08:00
|
|
|
unsigned NumTemplateArgLocs = Record[Idx++];
|
|
|
|
TemplArgLocs.reserve(NumTemplateArgLocs);
|
|
|
|
for (unsigned i=0; i != NumTemplateArgLocs; ++i)
|
2010-07-23 06:43:28 +08:00
|
|
|
TemplArgLocs.push_back(
|
2010-10-05 23:59:54 +08:00
|
|
|
Reader.ReadTemplateArgumentLoc(F, Record, Idx));
|
2010-07-02 19:55:40 +08:00
|
|
|
|
2010-10-05 23:59:54 +08:00
|
|
|
LAngleLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
RAngleLoc = ReadSourceLocation(Record, Idx);
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
2010-07-05 18:37:55 +08:00
|
|
|
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation(Record, Idx);
|
2010-06-22 17:55:07 +08:00
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
ASTContext &C = Reader.getContext();
|
2010-09-09 19:28:23 +08:00
|
|
|
TemplateArgumentList *TemplArgList
|
2010-11-08 07:05:16 +08:00
|
|
|
= TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size());
|
2011-09-23 04:07:09 +08:00
|
|
|
TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
|
2010-09-09 19:28:23 +08:00
|
|
|
for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i)
|
2011-09-23 04:07:09 +08:00
|
|
|
TemplArgsInfo.addArgument(TemplArgLocs[i]);
|
2010-09-09 19:28:23 +08:00
|
|
|
FunctionTemplateSpecializationInfo *FTInfo
|
|
|
|
= FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK,
|
|
|
|
TemplArgList,
|
2011-09-23 04:07:09 +08:00
|
|
|
HasTemplateArgumentsAsWritten ? &TemplArgsInfo : 0,
|
|
|
|
POI);
|
2010-09-09 19:28:23 +08:00
|
|
|
FD->TemplateOrSpecialization = FTInfo;
|
2010-09-09 03:31:22 +08:00
|
|
|
|
2010-09-09 19:28:23 +08:00
|
|
|
if (FD->isCanonicalDecl()) { // if canonical add to template's set.
|
2010-09-13 19:45:48 +08:00
|
|
|
// The template that contains the specializations set. It's not safe to
|
|
|
|
// use getCanonicalDecl on Template since it may still be initializing.
|
|
|
|
FunctionTemplateDecl *CanonTemplate
|
2011-07-22 06:35:25 +08:00
|
|
|
= ReadDeclAs<FunctionTemplateDecl>(Record, Idx);
|
2010-09-09 19:28:23 +08:00
|
|
|
// Get the InsertPos by FindNodeOrInsertPos() instead of calling
|
|
|
|
// InsertNode(FTInfo) directly to avoid the getASTContext() call in
|
|
|
|
// FunctionTemplateSpecializationInfo's Profile().
|
|
|
|
// We avoid getASTContext because a decl in the parent hierarchy may
|
|
|
|
// be initializing.
|
2010-09-09 03:31:22 +08:00
|
|
|
llvm::FoldingSetNodeID ID;
|
|
|
|
FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(),
|
|
|
|
TemplArgs.size(), C);
|
|
|
|
void *InsertPos = 0;
|
2010-09-13 19:45:48 +08:00
|
|
|
CanonTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
|
2010-09-09 19:28:23 +08:00
|
|
|
assert(InsertPos && "Another specialization already inserted!");
|
2010-09-13 19:45:48 +08:00
|
|
|
CanonTemplate->getSpecializations().InsertNode(FTInfo, InsertPos);
|
2010-09-09 03:31:22 +08:00
|
|
|
}
|
2010-06-28 17:31:34 +08:00
|
|
|
break;
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
|
|
|
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
|
|
|
|
// Templates.
|
|
|
|
UnresolvedSet<8> TemplDecls;
|
|
|
|
unsigned NumTemplates = Record[Idx++];
|
|
|
|
while (NumTemplates--)
|
2011-07-22 06:35:25 +08:00
|
|
|
TemplDecls.addDecl(ReadDeclAs<NamedDecl>(Record, Idx));
|
2010-06-22 17:55:07 +08:00
|
|
|
|
|
|
|
// Templates args.
|
|
|
|
TemplateArgumentListInfo TemplArgs;
|
|
|
|
unsigned NumArgs = Record[Idx++];
|
|
|
|
while (NumArgs--)
|
2010-10-05 23:59:54 +08:00
|
|
|
TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(F, Record, Idx));
|
|
|
|
TemplArgs.setLAngleLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
TemplArgs.setRAngleLoc(ReadSourceLocation(Record, Idx));
|
2010-06-22 17:55:07 +08:00
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
FD->setDependentTemplateSpecialization(Reader.getContext(),
|
2010-06-22 17:55:07 +08:00
|
|
|
TemplDecls, TemplArgs);
|
2010-06-28 17:31:34 +08:00
|
|
|
break;
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
|
|
|
}
|
2010-07-02 19:55:40 +08:00
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
// FunctionDecl's body is handled last at ASTDeclReader::Visit,
|
2010-07-02 23:58:43 +08:00
|
|
|
// after everything else is read.
|
|
|
|
|
2010-12-07 02:36:25 +08:00
|
|
|
FD->SClass = (StorageClass)Record[Idx++];
|
2011-01-04 01:57:40 +08:00
|
|
|
FD->SClassAsWritten = (StorageClass)Record[Idx++];
|
2010-12-10 00:59:22 +08:00
|
|
|
FD->IsInline = Record[Idx++];
|
|
|
|
FD->IsInlineSpecified = Record[Idx++];
|
2011-01-04 01:57:40 +08:00
|
|
|
FD->IsVirtualAsWritten = Record[Idx++];
|
|
|
|
FD->IsPure = Record[Idx++];
|
|
|
|
FD->HasInheritedPrototype = Record[Idx++];
|
|
|
|
FD->HasWrittenPrototype = Record[Idx++];
|
|
|
|
FD->IsDeleted = Record[Idx++];
|
|
|
|
FD->IsTrivial = Record[Idx++];
|
2011-05-13 06:46:29 +08:00
|
|
|
FD->IsDefaulted = Record[Idx++];
|
|
|
|
FD->IsExplicitlyDefaulted = Record[Idx++];
|
2011-01-04 01:57:40 +08:00
|
|
|
FD->HasImplicitReturnZero = Record[Idx++];
|
2011-08-16 05:04:07 +08:00
|
|
|
FD->IsConstexpr = Record[Idx++];
|
2011-01-04 01:57:40 +08:00
|
|
|
FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
|
2010-07-02 19:55:40 +08:00
|
|
|
|
2010-05-08 05:43:38 +08:00
|
|
|
// Read in the parameters.
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned NumParams = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ParmVarDecl *, 16> Params;
|
2009-04-27 13:27:42 +08:00
|
|
|
Params.reserve(NumParams);
|
|
|
|
for (unsigned I = 0; I != NumParams; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
|
2011-09-22 02:16:56 +08:00
|
|
|
FD->setParams(Reader.getContext(), Params);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(MD);
|
|
|
|
if (Record[Idx++]) {
|
|
|
|
// In practice, this won't be executed (since method definitions
|
|
|
|
// don't occur in header files).
|
2010-10-05 23:59:54 +08:00
|
|
|
MD->setBody(Reader.ReadStmt(F));
|
2011-07-22 06:35:25 +08:00
|
|
|
MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
|
|
|
|
MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
MD->setInstanceMethod(Record[Idx++]);
|
|
|
|
MD->setVariadic(Record[Idx++]);
|
|
|
|
MD->setSynthesized(Record[Idx++]);
|
2010-07-23 02:24:20 +08:00
|
|
|
MD->setDefined(Record[Idx++]);
|
2009-04-27 13:27:42 +08:00
|
|
|
MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
|
|
|
|
MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
|
2011-06-11 09:09:30 +08:00
|
|
|
MD->SetRelatedResultType(Record[Idx++]);
|
2010-04-09 05:29:11 +08:00
|
|
|
MD->setNumSelectorArgs(unsigned(Record[Idx++]));
|
2011-07-22 08:38:23 +08:00
|
|
|
MD->setResultType(Reader.readType(F, Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
MD->setResultTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
|
|
|
|
MD->setEndLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned NumParams = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ParmVarDecl *, 16> Params;
|
2009-04-27 13:27:42 +08:00
|
|
|
Params.reserve(NumParams);
|
|
|
|
for (unsigned I = 0; I != NumParams; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
|
2011-09-10 05:34:22 +08:00
|
|
|
MD->setMethodParams(Reader.getContext(), Params.data(), NumParams,
|
2010-04-09 23:40:42 +08:00
|
|
|
NumParams);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(CD);
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceLocation A = ReadSourceLocation(Record, Idx);
|
|
|
|
SourceLocation B = ReadSourceLocation(Record, Idx);
|
2010-01-07 09:20:12 +08:00
|
|
|
CD->setAtEndRange(SourceRange(A, B));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCContainerDecl(ID);
|
2011-07-22 08:38:23 +08:00
|
|
|
ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
|
2011-07-22 06:35:25 +08:00
|
|
|
ID->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
|
2010-09-01 09:21:15 +08:00
|
|
|
|
|
|
|
// Read the directly referenced protocols and their SourceLocations.
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned NumProtocols = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ObjCProtocolDecl *, 16> Protocols;
|
2009-04-27 13:27:42 +08:00
|
|
|
Protocols.reserve(NumProtocols);
|
|
|
|
for (unsigned I = 0; I != NumProtocols; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<SourceLocation, 16> ProtoLocs;
|
2010-01-16 23:02:53 +08:00
|
|
|
ProtoLocs.reserve(NumProtocols);
|
|
|
|
for (unsigned I = 0; I != NumProtocols; ++I)
|
2010-10-05 23:59:54 +08:00
|
|
|
ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
|
2010-01-16 23:02:53 +08:00
|
|
|
ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(),
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext());
|
2010-09-01 09:21:15 +08:00
|
|
|
|
|
|
|
// Read the transitive closure of protocols referenced by this class.
|
|
|
|
NumProtocols = Record[Idx++];
|
|
|
|
Protocols.clear();
|
|
|
|
Protocols.reserve(NumProtocols);
|
|
|
|
for (unsigned I = 0; I != NumProtocols; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
|
2010-09-01 09:21:15 +08:00
|
|
|
ID->AllReferencedProtocols.set(Protocols.data(), NumProtocols,
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext());
|
2010-09-01 09:21:15 +08:00
|
|
|
|
|
|
|
// Read the ivars.
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned NumIvars = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ObjCIvarDecl *, 16> IVars;
|
2009-04-27 13:27:42 +08:00
|
|
|
IVars.reserve(NumIvars);
|
|
|
|
for (unsigned I = 0; I != NumIvars; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
IVars.push_back(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
|
|
|
|
ID->setCategoryList(ReadDeclAs<ObjCCategoryDecl>(Record, Idx));
|
|
|
|
|
2010-08-21 05:21:08 +08:00
|
|
|
// We will rebuild this list lazily.
|
|
|
|
ID->setIvarList(0);
|
2010-08-11 20:19:30 +08:00
|
|
|
ID->setForwardDecl(Record[Idx++]);
|
|
|
|
ID->setImplicitInterfaceDecl(Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
ID->setClassLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
ID->setSuperClassLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
ID->setLocEnd(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitFieldDecl(IVD);
|
|
|
|
IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
|
2010-08-21 05:21:08 +08:00
|
|
|
// This field will be built lazily.
|
|
|
|
IVD->setNextIvar(0);
|
2010-07-18 02:35:47 +08:00
|
|
|
bool synth = Record[Idx++];
|
|
|
|
IVD->setSynthesize(synth);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCContainerDecl(PD);
|
|
|
|
PD->setForwardDecl(Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
PD->setLocEnd(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned NumProtoRefs = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
|
2009-04-27 13:27:42 +08:00
|
|
|
ProtoRefs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<SourceLocation, 16> ProtoLocs;
|
2010-01-16 23:02:53 +08:00
|
|
|
ProtoLocs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2010-10-05 23:59:54 +08:00
|
|
|
ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
|
2010-01-16 23:02:53 +08:00
|
|
|
PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitFieldDecl(FD);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(CD);
|
2011-08-28 04:50:59 +08:00
|
|
|
ObjCInterfaceDecl *ClassRef = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
|
|
|
|
SourceLocation SLoc = ReadSourceLocation(Record, Idx);
|
2011-09-10 05:34:22 +08:00
|
|
|
CD->setClass(Reader.getContext(), ClassRef, SLoc);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(FPD);
|
|
|
|
unsigned NumProtoRefs = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
|
2009-04-27 13:27:42 +08:00
|
|
|
ProtoRefs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<SourceLocation, 16> ProtoLocs;
|
2010-01-16 23:02:53 +08:00
|
|
|
ProtoLocs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2010-10-05 23:59:54 +08:00
|
|
|
ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
|
2010-01-16 23:02:53 +08:00
|
|
|
FPD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext());
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCContainerDecl(CD);
|
2011-08-31 03:43:26 +08:00
|
|
|
CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned NumProtoRefs = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
|
2009-04-27 13:27:42 +08:00
|
|
|
ProtoRefs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<SourceLocation, 16> ProtoLocs;
|
2010-01-16 23:02:53 +08:00
|
|
|
ProtoLocs.reserve(NumProtoRefs);
|
|
|
|
for (unsigned I = 0; I != NumProtoRefs; ++I)
|
2010-10-05 23:59:54 +08:00
|
|
|
ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
|
2010-01-16 23:02:53 +08:00
|
|
|
CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext());
|
2011-08-31 03:43:26 +08:00
|
|
|
CD->NextClassCategory = ReadDeclAs<ObjCCategoryDecl>(Record, Idx);
|
2010-08-24 02:51:39 +08:00
|
|
|
CD->setHasSynthBitfield(Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
CD->setAtLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
CD->setCategoryNameLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(CAD);
|
2011-07-22 06:35:25 +08:00
|
|
|
CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitNamedDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->setAtLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
D->setType(GetTypeSourceInfo(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
// FIXME: stable encoding
|
|
|
|
D->setPropertyAttributes(
|
|
|
|
(ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
|
2010-06-23 07:20:40 +08:00
|
|
|
D->setPropertyAttributesAsWritten(
|
|
|
|
(ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
|
2009-04-27 13:27:42 +08:00
|
|
|
// FIXME: stable encoding
|
|
|
|
D->setPropertyImplementation(
|
|
|
|
(ObjCPropertyDecl::PropertyControl)Record[Idx++]);
|
2011-07-22 08:38:23 +08:00
|
|
|
D->setGetterName(Reader.ReadDeclarationName(F,Record, Idx).getObjCSelector());
|
|
|
|
D->setSetterName(Reader.ReadDeclarationName(F,Record, Idx).getObjCSelector());
|
2011-07-22 06:35:25 +08:00
|
|
|
D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
|
|
|
|
D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
|
|
|
|
D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
|
2009-07-28 03:04:32 +08:00
|
|
|
VisitObjCContainerDecl(D);
|
2011-07-22 06:35:25 +08:00
|
|
|
D->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCImplDecl(D);
|
2011-07-29 04:55:49 +08:00
|
|
|
D->setIdentifier(Reader.GetIdentifierInfo(F, Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitObjCImplDecl(D);
|
2011-07-22 06:35:25 +08:00
|
|
|
D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
|
2010-08-09 18:54:20 +08:00
|
|
|
llvm::tie(D->IvarInitializers, D->NumIvarInitializers)
|
2011-01-09 04:30:50 +08:00
|
|
|
= Reader.ReadCXXCtorInitializers(F, Record, Idx);
|
2010-08-24 02:51:39 +08:00
|
|
|
D->setHasSynthBitfield(Record[Idx++]);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->setAtLoc(ReadSourceLocation(Record, Idx));
|
2011-07-22 06:35:25 +08:00
|
|
|
D->setPropertyDecl(ReadDeclAs<ObjCPropertyDecl>(Record, Idx));
|
|
|
|
D->PropertyIvarDecl = ReadDeclAs<ObjCIvarDecl>(Record, Idx);
|
2010-11-17 09:03:52 +08:00
|
|
|
D->IvarLoc = ReadSourceLocation(Record, Idx);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->setGetterCXXConstructor(Reader.ReadExpr(F));
|
|
|
|
D->setSetterCXXAssignment(Reader.ReadExpr(F));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
|
2009-08-19 09:28:35 +08:00
|
|
|
VisitDeclaratorDecl(FD);
|
2009-04-27 13:27:42 +08:00
|
|
|
FD->setMutable(Record[Idx++]);
|
2011-06-12 01:19:42 +08:00
|
|
|
int BitWidthOrInitializer = Record[Idx++];
|
|
|
|
if (BitWidthOrInitializer == 1)
|
2010-10-05 23:59:54 +08:00
|
|
|
FD->setBitWidth(Reader.ReadExpr(F));
|
2011-06-12 01:19:42 +08:00
|
|
|
else if (BitWidthOrInitializer == 2)
|
|
|
|
FD->setInClassInitializer(Reader.ReadExpr(F));
|
2010-07-05 05:44:35 +08:00
|
|
|
if (!FD->getDeclName()) {
|
2011-07-22 06:35:25 +08:00
|
|
|
if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>(Record, Idx))
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
|
2010-07-05 05:44:35 +08:00
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-11-21 14:08:52 +08:00
|
|
|
void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
|
|
|
|
VisitValueDecl(FD);
|
|
|
|
|
|
|
|
FD->ChainingSize = Record[Idx++];
|
|
|
|
assert(FD->ChainingSize >= 2 && "Anonymous chaining must be >= 2");
|
2011-09-10 05:34:22 +08:00
|
|
|
FD->Chaining = new (Reader.getContext())NamedDecl*[FD->ChainingSize];
|
2010-11-21 14:08:52 +08:00
|
|
|
|
|
|
|
for (unsigned I = 0; I != FD->ChainingSize; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
FD->Chaining[I] = ReadDeclAs<NamedDecl>(Record, Idx);
|
2010-11-21 14:08:52 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
|
2009-08-19 09:28:35 +08:00
|
|
|
VisitDeclaratorDecl(VD);
|
2010-09-09 03:31:22 +08:00
|
|
|
VisitRedeclarable(VD);
|
2011-05-01 10:13:58 +08:00
|
|
|
VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];
|
|
|
|
VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++];
|
|
|
|
VD->VarDeclBits.ThreadSpecified = Record[Idx++];
|
|
|
|
VD->VarDeclBits.HasCXXDirectInit = Record[Idx++];
|
|
|
|
VD->VarDeclBits.ExceptionVar = Record[Idx++];
|
|
|
|
VD->VarDeclBits.NRVOVariable = Record[Idx++];
|
|
|
|
VD->VarDeclBits.CXXForRangeDecl = Record[Idx++];
|
2011-06-17 14:42:21 +08:00
|
|
|
VD->VarDeclBits.ARCPseudoStrong = Record[Idx++];
|
2009-04-27 13:27:42 +08:00
|
|
|
if (Record[Idx++])
|
2010-10-05 23:59:54 +08:00
|
|
|
VD->setInit(Reader.ReadExpr(F));
|
2010-07-05 05:44:00 +08:00
|
|
|
|
|
|
|
if (Record[Idx++]) { // HasMemberSpecializationInfo.
|
2011-07-22 06:35:25 +08:00
|
|
|
VarDecl *Tmpl = ReadDeclAs<VarDecl>(Record, Idx);
|
2010-07-05 05:44:00 +08:00
|
|
|
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation(Record, Idx);
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
|
2010-07-05 05:44:00 +08:00
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitVarDecl(PD);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitVarDecl(PD);
|
2011-05-02 08:30:12 +08:00
|
|
|
unsigned isObjCMethodParam = Record[Idx++];
|
|
|
|
unsigned scopeDepth = Record[Idx++];
|
|
|
|
unsigned scopeIndex = Record[Idx++];
|
|
|
|
unsigned declQualifier = Record[Idx++];
|
|
|
|
if (isObjCMethodParam) {
|
|
|
|
assert(scopeDepth == 0);
|
|
|
|
PD->setObjCMethodScopeInfo(scopeIndex);
|
|
|
|
PD->ParmVarDeclBits.ScopeDepthOrObjCQuals = declQualifier;
|
|
|
|
} else {
|
|
|
|
PD->setScopeInfo(scopeDepth, scopeIndex);
|
|
|
|
}
|
2011-05-01 10:13:58 +08:00
|
|
|
PD->ParmVarDeclBits.IsKNRPromoted = Record[Idx++];
|
|
|
|
PD->ParmVarDeclBits.HasInheritedDefaultArg = Record[Idx++];
|
2010-07-05 05:44:07 +08:00
|
|
|
if (Record[Idx++]) // hasUninstantiatedDefaultArg.
|
2010-10-05 23:59:54 +08:00
|
|
|
PD->setUninstantiatedDefaultArg(Reader.ReadExpr(F));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(AD);
|
2010-10-05 23:59:54 +08:00
|
|
|
AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr(F)));
|
2011-03-03 22:20:18 +08:00
|
|
|
AD->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
|
2009-04-27 13:27:42 +08:00
|
|
|
VisitDecl(BD);
|
2010-10-05 23:59:54 +08:00
|
|
|
BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt(F)));
|
|
|
|
BD->setSignatureAsWritten(GetTypeSourceInfo(Record, Idx));
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned NumParams = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<ParmVarDecl *, 16> Params;
|
2009-04-27 13:27:42 +08:00
|
|
|
Params.reserve(NumParams);
|
|
|
|
for (unsigned I = 0; I != NumParams; ++I)
|
2011-07-22 06:35:25 +08:00
|
|
|
Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
|
2011-09-22 02:16:56 +08:00
|
|
|
BD->setParams(Params);
|
2011-02-02 21:00:07 +08:00
|
|
|
|
|
|
|
bool capturesCXXThis = Record[Idx++];
|
2011-02-07 18:33:21 +08:00
|
|
|
unsigned numCaptures = Record[Idx++];
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<BlockDecl::Capture, 16> captures;
|
2011-02-07 18:33:21 +08:00
|
|
|
captures.reserve(numCaptures);
|
|
|
|
for (unsigned i = 0; i != numCaptures; ++i) {
|
2011-07-22 06:35:25 +08:00
|
|
|
VarDecl *decl = ReadDeclAs<VarDecl>(Record, Idx);
|
2011-02-07 18:33:21 +08:00
|
|
|
unsigned flags = Record[Idx++];
|
|
|
|
bool byRef = (flags & 1);
|
|
|
|
bool nested = (flags & 2);
|
|
|
|
Expr *copyExpr = ((flags & 4) ? Reader.ReadExpr(F) : 0);
|
|
|
|
|
|
|
|
captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr));
|
|
|
|
}
|
2011-09-10 05:34:22 +08:00
|
|
|
BD->setCaptures(Reader.getContext(), captures.begin(),
|
2011-02-07 18:33:21 +08:00
|
|
|
captures.end(), capturesCXXThis);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitDecl(D);
|
|
|
|
D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]);
|
2011-03-09 00:41:52 +08:00
|
|
|
D->setExternLoc(ReadSourceLocation(Record, Idx));
|
2011-03-03 22:52:38 +08:00
|
|
|
D->setRBraceLoc(ReadSourceLocation(Record, Idx));
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2011-02-17 15:39:24 +08:00
|
|
|
void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
|
|
|
|
VisitNamedDecl(D);
|
2011-03-06 02:21:20 +08:00
|
|
|
D->setLocStart(ReadSourceLocation(Record, Idx));
|
2011-02-17 15:39:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2010-10-06 04:41:58 +08:00
|
|
|
D->IsInline = Record[Idx++];
|
2011-03-08 20:38:20 +08:00
|
|
|
D->LocStart = ReadSourceLocation(Record, Idx);
|
|
|
|
D->RBraceLoc = ReadSourceLocation(Record, Idx);
|
2010-10-28 03:49:05 +08:00
|
|
|
D->NextNamespace = Record[Idx++];
|
2010-05-08 05:43:38 +08:00
|
|
|
|
|
|
|
bool IsOriginal = Record[Idx++];
|
2011-07-22 06:35:25 +08:00
|
|
|
// FIXME: Modules will likely have trouble with pointing directly at
|
|
|
|
// the original namespace.
|
2010-07-03 15:57:53 +08:00
|
|
|
D->OrigOrAnonNamespace.setInt(IsOriginal);
|
2011-07-22 06:35:25 +08:00
|
|
|
D->OrigOrAnonNamespace.setPointer(ReadDeclAs<NamespaceDecl>(Record, Idx));
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->NamespaceLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
D->IdentLoc = ReadSourceLocation(Record, Idx);
|
2011-02-26 01:08:07 +08:00
|
|
|
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2011-07-22 06:35:25 +08:00
|
|
|
D->Namespace = ReadDeclAs<NamedDecl>(Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->setUsingLocation(ReadSourceLocation(Record, Idx));
|
2011-02-25 08:36:19 +08:00
|
|
|
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
|
2011-07-22 06:35:25 +08:00
|
|
|
D->FirstUsingShadow = ReadDeclAs<UsingShadowDecl>(Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
D->setTypeName(Record[Idx++]);
|
2011-07-22 06:35:25 +08:00
|
|
|
if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>(Record, Idx))
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2011-07-22 06:35:25 +08:00
|
|
|
D->setTargetDecl(ReadDeclAs<NamedDecl>(Record, Idx));
|
|
|
|
D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(Record, Idx);
|
|
|
|
UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>(Record, Idx);
|
2010-07-05 05:44:35 +08:00
|
|
|
if (Pattern)
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitNamedDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->UsingLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
D->NamespaceLoc = ReadSourceLocation(Record, Idx);
|
2011-02-26 00:33:46 +08:00
|
|
|
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2011-07-22 06:35:25 +08:00
|
|
|
D->NominatedNamespace = ReadDeclAs<NamedDecl>(Record, Idx);
|
|
|
|
D->CommonAncestor = ReadDeclAs<DeclContext>(Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitValueDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->setUsingLoc(ReadSourceLocation(Record, Idx));
|
2011-02-25 08:36:19 +08:00
|
|
|
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
|
2010-05-08 05:43:38 +08:00
|
|
|
UnresolvedUsingTypenameDecl *D) {
|
|
|
|
VisitTypeDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->TypenameLocation = ReadSourceLocation(Record, Idx);
|
2011-02-25 08:36:19 +08:00
|
|
|
D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-10-25 01:26:27 +08:00
|
|
|
void ASTDeclReader::ReadCXXDefinitionData(
|
2010-10-25 01:26:40 +08:00
|
|
|
struct CXXRecordDecl::DefinitionData &Data,
|
|
|
|
const RecordData &Record, unsigned &Idx) {
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.UserDeclaredConstructor = Record[Idx++];
|
|
|
|
Data.UserDeclaredCopyConstructor = Record[Idx++];
|
2011-09-07 00:38:46 +08:00
|
|
|
Data.UserDeclaredMoveConstructor = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.UserDeclaredCopyAssignment = Record[Idx++];
|
2011-09-07 00:38:46 +08:00
|
|
|
Data.UserDeclaredMoveAssignment = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.UserDeclaredDestructor = Record[Idx++];
|
|
|
|
Data.Aggregate = Record[Idx++];
|
|
|
|
Data.PlainOldData = Record[Idx++];
|
|
|
|
Data.Empty = Record[Idx++];
|
|
|
|
Data.Polymorphic = Record[Idx++];
|
|
|
|
Data.Abstract = Record[Idx++];
|
2011-04-30 18:07:30 +08:00
|
|
|
Data.IsStandardLayout = Record[Idx++];
|
Completely re-implement the core logic behind the __is_standard_layout
type trait. The previous implementation suffered from several problems:
1) It implemented all of the logic in RecordType by walking over every
base and field in a CXXRecordDecl and validating the constraints of
the standard. This made for very straightforward code, but is
extremely inefficient. It also is conceptually wrong, the logic tied
to the C++ definition of standard-layout classes should be in
CXXRecordDecl, not RecordType.
2) To address the performance problems with #1, a cache bit was added to
CXXRecordDecl, and at the completion of every C++ class, the
RecordType was queried to determine if it was a standard layout
class, and that state was cached. Two things went very very wrong
with this. First, the caching version of the query *was never
called*. Even within the recursive steps of the walk over all fields
and bases the caching variant was not called, making each query
a full *recursive* walk. Second, despite the cache not being used, it
was computed for every class declared, even when the trait was never
used in the program. This probably significantly regressed compile
time performance for edge-case files.
3) An ASTContext was required merely to query the type trait because
querying it performed the actual computations.
4) The caching bit wasn't managed correctly (uninitialized).
The new implementation follows the system for all the other traits on
C++ classes by encoding all the state needed in the definition data and
building up the trait incrementally as each base and member are added to
the definition of the class.
The idiosyncracies of the specification of standard-layout classes
requires more state than I would like; currently 5 bits. I could
eliminate one of the bits easily at the expense of both clarity and
resilience of the code. I might be able to eliminate one of the other
bits by computing its state in terms of other state bits in the
definition. I've already done that in one place where there was a fairly
simple way to achieve it.
It's possible some of the bits could be moved out of the definition data
and into some other structure which isn't serialized if the serialized
bloat is a problem. That would preclude serialization of a partial class
declaration, but that's likely already precluded.
Comments on any of these issues welcome.
llvm-svn: 130601
2011-04-30 17:17:45 +08:00
|
|
|
Data.HasNoNonEmptyBases = Record[Idx++];
|
|
|
|
Data.HasPrivateFields = Record[Idx++];
|
|
|
|
Data.HasProtectedFields = Record[Idx++];
|
|
|
|
Data.HasPublicFields = Record[Idx++];
|
2011-05-13 09:05:07 +08:00
|
|
|
Data.HasMutableFields = Record[Idx++];
|
2011-05-10 02:22:59 +08:00
|
|
|
Data.HasTrivialDefaultConstructor = Record[Idx++];
|
2011-08-11 02:11:37 +08:00
|
|
|
Data.HasConstexprNonCopyMoveConstructor = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.HasTrivialCopyConstructor = Record[Idx++];
|
2011-04-24 07:10:33 +08:00
|
|
|
Data.HasTrivialMoveConstructor = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.HasTrivialCopyAssignment = Record[Idx++];
|
2011-04-24 07:10:33 +08:00
|
|
|
Data.HasTrivialMoveAssignment = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.HasTrivialDestructor = Record[Idx++];
|
2011-04-24 10:49:34 +08:00
|
|
|
Data.HasNonLiteralTypeFieldsOrBases = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.ComputedVisibleConversions = Record[Idx++];
|
2011-05-12 06:34:38 +08:00
|
|
|
Data.UserProvidedDefaultConstructor = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.DeclaredDefaultConstructor = Record[Idx++];
|
|
|
|
Data.DeclaredCopyConstructor = Record[Idx++];
|
2011-09-07 00:38:46 +08:00
|
|
|
Data.DeclaredMoveConstructor = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.DeclaredCopyAssignment = Record[Idx++];
|
2011-09-07 00:38:46 +08:00
|
|
|
Data.DeclaredMoveAssignment = Record[Idx++];
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.DeclaredDestructor = Record[Idx++];
|
2011-08-31 21:59:56 +08:00
|
|
|
Data.FailedImplicitMoveConstructor = Record[Idx++];
|
|
|
|
Data.FailedImplicitMoveAssignment = Record[Idx++];
|
2011-01-23 02:11:02 +08:00
|
|
|
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.NumBases = Record[Idx++];
|
2010-10-30 06:39:52 +08:00
|
|
|
if (Data.NumBases)
|
2011-08-04 08:01:48 +08:00
|
|
|
Data.Bases = Reader.readCXXBaseSpecifiers(F, Record, Idx);
|
2010-10-25 01:26:27 +08:00
|
|
|
Data.NumVBases = Record[Idx++];
|
2010-10-30 06:39:52 +08:00
|
|
|
if (Data.NumVBases)
|
2011-08-04 08:01:48 +08:00
|
|
|
Data.VBases = Reader.readCXXBaseSpecifiers(F, Record, Idx);
|
2010-10-30 06:39:52 +08:00
|
|
|
|
2011-07-22 06:35:25 +08:00
|
|
|
Reader.ReadUnresolvedSet(F, Data.Conversions, Record, Idx);
|
|
|
|
Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx);
|
2010-10-25 01:26:27 +08:00
|
|
|
assert(Data.Definition && "Data.Definition should be already set!");
|
2011-07-22 06:35:25 +08:00
|
|
|
Data.FirstFriend = ReadDeclAs<FriendDecl>(Record, Idx);
|
2010-10-25 01:26:27 +08:00
|
|
|
}
|
|
|
|
|
2010-10-25 01:26:40 +08:00
|
|
|
void ASTDeclReader::InitializeCXXDefinitionData(CXXRecordDecl *D,
|
|
|
|
CXXRecordDecl *DefinitionDecl,
|
|
|
|
const RecordData &Record,
|
|
|
|
unsigned &Idx) {
|
2011-09-10 05:34:22 +08:00
|
|
|
ASTContext &C = Reader.getContext();
|
2010-10-20 08:11:15 +08:00
|
|
|
|
2010-10-25 01:26:31 +08:00
|
|
|
if (D == DefinitionDecl) {
|
|
|
|
D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
|
2010-10-25 01:26:40 +08:00
|
|
|
ReadCXXDefinitionData(*D->DefinitionData, Record, Idx);
|
2010-10-25 01:26:31 +08:00
|
|
|
// We read the definition info. Check if there are pending forward
|
|
|
|
// references that need to point to this DefinitionData pointer.
|
|
|
|
ASTReader::PendingForwardRefsMap::iterator
|
|
|
|
FindI = Reader.PendingForwardRefs.find(D);
|
|
|
|
if (FindI != Reader.PendingForwardRefs.end()) {
|
|
|
|
ASTReader::ForwardRefs &Refs = FindI->second;
|
|
|
|
for (ASTReader::ForwardRefs::iterator
|
|
|
|
I = Refs.begin(), E = Refs.end(); I != E; ++I)
|
|
|
|
(*I)->DefinitionData = D->DefinitionData;
|
|
|
|
#ifndef NDEBUG
|
|
|
|
// We later check whether PendingForwardRefs is empty to make sure all
|
|
|
|
// pending references were linked.
|
|
|
|
Reader.PendingForwardRefs.erase(D);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
} else if (DefinitionDecl) {
|
|
|
|
if (DefinitionDecl->DefinitionData) {
|
|
|
|
D->DefinitionData = DefinitionDecl->DefinitionData;
|
|
|
|
} else {
|
|
|
|
// The definition is still initializing.
|
|
|
|
Reader.PendingForwardRefs[DefinitionDecl].push_back(D);
|
|
|
|
}
|
2010-07-02 19:55:32 +08:00
|
|
|
}
|
2010-10-25 01:26:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
|
|
|
VisitRecordDecl(D);
|
|
|
|
|
2011-07-22 06:35:25 +08:00
|
|
|
CXXRecordDecl *DefinitionDecl = ReadDeclAs<CXXRecordDecl>(Record, Idx);
|
2010-10-25 01:26:40 +08:00
|
|
|
InitializeCXXDefinitionData(D, DefinitionDecl, Record, Idx);
|
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
ASTContext &C = Reader.getContext();
|
2010-07-02 19:55:32 +08:00
|
|
|
|
2010-06-20 03:29:09 +08:00
|
|
|
enum CXXRecKind {
|
|
|
|
CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
|
|
|
|
};
|
|
|
|
switch ((CXXRecKind)Record[Idx++]) {
|
|
|
|
default:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Out of sync with ASTDeclWriter::VisitCXXRecordDecl?");
|
2010-06-20 03:29:09 +08:00
|
|
|
case CXXRecNotTemplate:
|
|
|
|
break;
|
|
|
|
case CXXRecTemplate:
|
2011-07-22 06:35:25 +08:00
|
|
|
D->TemplateOrInstantiation = ReadDeclAs<ClassTemplateDecl>(Record, Idx);
|
2010-06-20 03:29:09 +08:00
|
|
|
break;
|
|
|
|
case CXXRecMemberSpecialization: {
|
2011-07-22 06:35:25 +08:00
|
|
|
CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(Record, Idx);
|
2010-06-20 03:29:09 +08:00
|
|
|
TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceLocation POI = ReadSourceLocation(Record, Idx);
|
2010-09-13 19:45:25 +08:00
|
|
|
MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK);
|
|
|
|
MSI->setPointOfInstantiation(POI);
|
|
|
|
D->TemplateOrInstantiation = MSI;
|
2010-06-20 03:29:09 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-10-15 04:14:38 +08:00
|
|
|
|
|
|
|
// Load the key function to avoid deserializing every method so we can
|
|
|
|
// compute it.
|
|
|
|
if (D->IsDefinition) {
|
2011-07-22 06:35:25 +08:00
|
|
|
if (CXXMethodDecl *Key = ReadDeclAs<CXXMethodDecl>(Record, Idx))
|
2010-10-15 04:14:38 +08:00
|
|
|
C.KeyFunctions[D] = Key;
|
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitFunctionDecl(D);
|
2010-07-05 05:44:35 +08:00
|
|
|
unsigned NumOverridenMethods = Record[Idx++];
|
|
|
|
while (NumOverridenMethods--) {
|
|
|
|
// Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
|
|
|
|
// MD may be initializing.
|
2011-07-22 06:35:25 +08:00
|
|
|
if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx))
|
2011-09-10 05:34:22 +08:00
|
|
|
Reader.getContext().addOverriddenMethod(D, MD);
|
2010-07-05 05:44:35 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
2010-07-02 23:58:43 +08:00
|
|
|
|
|
|
|
D->IsExplicitSpecified = Record[Idx++];
|
|
|
|
D->ImplicitlyDefined = Record[Idx++];
|
2011-01-09 04:30:50 +08:00
|
|
|
llvm::tie(D->CtorInitializers, D->NumCtorInitializers)
|
|
|
|
= Reader.ReadCXXCtorInitializers(F, Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
2010-07-02 23:58:43 +08:00
|
|
|
|
|
|
|
D->ImplicitlyDefined = Record[Idx++];
|
2011-07-22 06:35:25 +08:00
|
|
|
D->OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
|
2010-05-08 05:43:38 +08:00
|
|
|
VisitCXXMethodDecl(D);
|
2010-07-02 23:58:43 +08:00
|
|
|
D->IsExplicitSpecified = Record[Idx++];
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
|
2010-06-05 13:09:32 +08:00
|
|
|
VisitDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->setColonLoc(ReadSourceLocation(Record, Idx));
|
2010-06-05 13:09:32 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
|
2010-07-05 18:38:01 +08:00
|
|
|
VisitDecl(D);
|
2010-06-30 06:47:00 +08:00
|
|
|
if (Record[Idx++])
|
2010-10-05 23:59:54 +08:00
|
|
|
D->Friend = GetTypeSourceInfo(Record, Idx);
|
2010-06-30 06:47:00 +08:00
|
|
|
else
|
2011-07-22 06:35:25 +08:00
|
|
|
D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
|
2010-10-28 04:23:41 +08:00
|
|
|
D->NextFriend = Record[Idx++];
|
2010-10-16 14:59:13 +08:00
|
|
|
D->UnsupportedFriend = (Record[Idx++] != 0);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->FriendLoc = ReadSourceLocation(Record, Idx);
|
2010-06-30 06:47:00 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
|
2010-07-23 00:04:10 +08:00
|
|
|
VisitDecl(D);
|
|
|
|
unsigned NumParams = Record[Idx++];
|
|
|
|
D->NumParams = NumParams;
|
|
|
|
D->Params = new TemplateParameterList*[NumParams];
|
|
|
|
for (unsigned i = 0; i != NumParams; ++i)
|
2010-10-05 23:59:54 +08:00
|
|
|
D->Params[i] = Reader.ReadTemplateParameterList(F, Record, Idx);
|
2010-07-23 00:04:10 +08:00
|
|
|
if (Record[Idx++]) // HasFriendDecl
|
2011-07-22 06:35:25 +08:00
|
|
|
D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
|
2010-07-23 00:04:10 +08:00
|
|
|
else
|
2010-10-05 23:59:54 +08:00
|
|
|
D->Friend = GetTypeSourceInfo(Record, Idx);
|
|
|
|
D->FriendLoc = ReadSourceLocation(Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
|
2010-06-20 03:29:09 +08:00
|
|
|
VisitNamedDecl(D);
|
|
|
|
|
2011-07-22 06:35:25 +08:00
|
|
|
NamedDecl *TemplatedDecl = ReadDeclAs<NamedDecl>(Record, Idx);
|
2010-06-23 21:48:30 +08:00
|
|
|
TemplateParameterList* TemplateParams
|
2010-10-05 23:59:54 +08:00
|
|
|
= Reader.ReadTemplateParameterList(F, Record, Idx);
|
2010-06-20 03:29:09 +08:00
|
|
|
D->init(TemplatedDecl, TemplateParams);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
|
2010-09-09 03:31:22 +08:00
|
|
|
// Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr()
|
|
|
|
// can be used while this is still initializing.
|
2010-06-20 03:29:09 +08:00
|
|
|
|
2010-09-09 03:31:22 +08:00
|
|
|
assert(D->CommonOrPrev.isNull() && "getCommonPtr was called earlier on this");
|
2011-07-22 06:35:25 +08:00
|
|
|
DeclID PreviousDeclID = ReadDeclID(Record, Idx);
|
|
|
|
DeclID FirstDeclID = PreviousDeclID ? ReadDeclID(Record, Idx) : 0;
|
2011-02-12 15:50:47 +08:00
|
|
|
// We delay loading of the redeclaration chain to avoid deeply nested calls.
|
|
|
|
// We temporarily set the first (canonical) declaration as the previous one
|
|
|
|
// which is the one that matters and mark the real previous DeclID to be
|
|
|
|
// loaded & attached later on.
|
|
|
|
RedeclarableTemplateDecl *FirstDecl =
|
|
|
|
cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(FirstDeclID));
|
|
|
|
assert((FirstDecl == 0 || FirstDecl->getKind() == D->getKind()) &&
|
|
|
|
"FirstDecl kind mismatch");
|
|
|
|
if (FirstDecl) {
|
|
|
|
D->CommonOrPrev = FirstDecl;
|
|
|
|
// Mark the real previous DeclID to be loaded & attached later on.
|
|
|
|
if (PreviousDeclID != FirstDeclID)
|
|
|
|
Reader.PendingPreviousDecls.push_back(std::make_pair(D, PreviousDeclID));
|
|
|
|
} else {
|
2011-09-10 05:34:22 +08:00
|
|
|
D->CommonOrPrev = D->newCommon(Reader.getContext());
|
2010-07-30 00:11:51 +08:00
|
|
|
if (RedeclarableTemplateDecl *RTD
|
2011-07-22 06:35:25 +08:00
|
|
|
= ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx)) {
|
2010-07-30 00:11:51 +08:00
|
|
|
assert(RTD->getKind() == D->getKind() &&
|
|
|
|
"InstantiatedFromMemberTemplate kind mismatch");
|
|
|
|
D->setInstantiatedFromMemberTemplateImpl(RTD);
|
|
|
|
if (Record[Idx++])
|
|
|
|
D->setMemberSpecialization();
|
|
|
|
}
|
2010-07-30 00:12:01 +08:00
|
|
|
|
2011-07-22 06:35:25 +08:00
|
|
|
RedeclarableTemplateDecl *LatestDecl
|
|
|
|
= ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx);
|
2010-08-04 01:30:10 +08:00
|
|
|
|
|
|
|
// This decl is a first one and the latest declaration that it points to is
|
2010-08-19 07:57:06 +08:00
|
|
|
// in the same AST file. However, if this actually needs to point to a
|
|
|
|
// redeclaration in another AST file, we need to update it by checking
|
2010-08-04 01:30:10 +08:00
|
|
|
// the FirstLatestDeclIDs map which tracks this kind of decls.
|
|
|
|
assert(Reader.GetDecl(ThisDeclID) == D && "Invalid ThisDeclID ?");
|
2010-08-19 07:56:43 +08:00
|
|
|
ASTReader::FirstLatestDeclIDMap::iterator I
|
2010-08-04 01:30:10 +08:00
|
|
|
= Reader.FirstLatestDeclIDs.find(ThisDeclID);
|
|
|
|
if (I != Reader.FirstLatestDeclIDs.end()) {
|
2011-08-25 23:28:26 +08:00
|
|
|
if (Decl *NewLatest = Reader.GetDecl(I->second))
|
|
|
|
LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest);
|
2010-08-04 01:30:10 +08:00
|
|
|
}
|
|
|
|
|
2010-07-30 00:12:01 +08:00
|
|
|
assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch");
|
|
|
|
D->getCommonPtr()->Latest = LatestDecl;
|
2010-07-30 00:11:51 +08:00
|
|
|
}
|
2010-09-09 03:31:22 +08:00
|
|
|
|
|
|
|
VisitTemplateDecl(D);
|
|
|
|
D->IdentifierNamespace = Record[Idx++];
|
2010-07-30 00:11:51 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
2010-07-30 00:11:51 +08:00
|
|
|
VisitRedeclarableTemplateDecl(D);
|
|
|
|
|
|
|
|
if (D->getPreviousDeclaration() == 0) {
|
2010-10-28 06:21:36 +08:00
|
|
|
// This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
|
|
|
|
// the specializations.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<serialization::DeclID, 2> SpecIDs;
|
2010-10-28 06:21:36 +08:00
|
|
|
SpecIDs.push_back(0);
|
|
|
|
|
|
|
|
// Specializations.
|
|
|
|
unsigned Size = Record[Idx++];
|
|
|
|
SpecIDs[0] += Size;
|
2011-07-22 06:35:25 +08:00
|
|
|
for (unsigned I = 0; I != Size; ++I)
|
|
|
|
SpecIDs.push_back(ReadDeclID(Record, Idx));
|
2010-10-28 06:21:36 +08:00
|
|
|
|
|
|
|
// Partial specializations.
|
|
|
|
Size = Record[Idx++];
|
|
|
|
SpecIDs[0] += Size;
|
2011-07-22 06:35:25 +08:00
|
|
|
for (unsigned I = 0; I != Size; ++I)
|
|
|
|
SpecIDs.push_back(ReadDeclID(Record, Idx));
|
2010-10-28 06:21:36 +08:00
|
|
|
|
|
|
|
if (SpecIDs[0]) {
|
|
|
|
typedef serialization::DeclID DeclID;
|
|
|
|
|
|
|
|
ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr();
|
|
|
|
CommonPtr->LazySpecializations
|
2011-09-10 05:34:22 +08:00
|
|
|
= new (Reader.getContext()) DeclID [SpecIDs.size()];
|
2010-10-28 06:21:36 +08:00
|
|
|
memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
|
|
|
|
SpecIDs.size() * sizeof(DeclID));
|
|
|
|
}
|
|
|
|
|
2010-06-20 03:29:09 +08:00
|
|
|
// InjectedClassNameType is computed.
|
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitClassTemplateSpecializationDecl(
|
2010-05-08 05:43:38 +08:00
|
|
|
ClassTemplateSpecializationDecl *D) {
|
2010-06-23 21:48:30 +08:00
|
|
|
VisitCXXRecordDecl(D);
|
2010-09-13 19:45:32 +08:00
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
ASTContext &C = Reader.getContext();
|
2011-07-22 06:35:25 +08:00
|
|
|
if (Decl *InstD = ReadDecl(Record, Idx)) {
|
2010-06-23 21:48:30 +08:00
|
|
|
if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
|
2010-09-13 19:45:32 +08:00
|
|
|
D->SpecializedTemplate = CTD;
|
2010-06-23 21:48:30 +08:00
|
|
|
} else {
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2010-10-05 23:59:54 +08:00
|
|
|
Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
|
2010-09-13 19:45:32 +08:00
|
|
|
TemplateArgumentList *ArgList
|
2010-11-08 07:05:16 +08:00
|
|
|
= TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
|
|
|
|
TemplArgs.size());
|
2010-09-13 19:45:32 +08:00
|
|
|
ClassTemplateSpecializationDecl::SpecializedPartialSpecialization *PS
|
|
|
|
= new (C) ClassTemplateSpecializationDecl::
|
|
|
|
SpecializedPartialSpecialization();
|
|
|
|
PS->PartialSpecialization
|
|
|
|
= cast<ClassTemplatePartialSpecializationDecl>(InstD);
|
|
|
|
PS->TemplateArgs = ArgList;
|
|
|
|
D->SpecializedTemplate = PS;
|
2010-06-23 21:48:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Explicit info.
|
2010-10-05 23:59:54 +08:00
|
|
|
if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) {
|
2010-09-13 19:45:32 +08:00
|
|
|
ClassTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo
|
|
|
|
= new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo;
|
|
|
|
ExplicitInfo->TypeAsWritten = TyInfo;
|
2010-10-05 23:59:54 +08:00
|
|
|
ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx);
|
2010-09-13 19:45:32 +08:00
|
|
|
D->ExplicitInfo = ExplicitInfo;
|
2010-06-23 21:48:30 +08:00
|
|
|
}
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 8> TemplArgs;
|
2010-10-05 23:59:54 +08:00
|
|
|
Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
|
2010-11-08 07:05:16 +08:00
|
|
|
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
|
|
|
|
TemplArgs.size());
|
2010-10-05 23:59:54 +08:00
|
|
|
D->PointOfInstantiation = ReadSourceLocation(Record, Idx);
|
2010-09-13 19:45:32 +08:00
|
|
|
D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++];
|
2010-10-28 06:21:36 +08:00
|
|
|
|
2010-07-20 21:59:40 +08:00
|
|
|
if (D->isCanonicalDecl()) { // It's kept in the folding set.
|
2011-07-22 06:35:25 +08:00
|
|
|
ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>(Record,Idx);
|
2010-07-10 05:11:43 +08:00
|
|
|
if (ClassTemplatePartialSpecializationDecl *Partial
|
2010-10-28 06:21:36 +08:00
|
|
|
= dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
|
|
|
|
CanonPattern->getCommonPtr()->PartialSpecializations.InsertNode(Partial);
|
2010-07-10 05:11:43 +08:00
|
|
|
} else {
|
2010-10-28 06:21:36 +08:00
|
|
|
CanonPattern->getCommonPtr()->Specializations.InsertNode(D);
|
2010-07-10 05:11:43 +08:00
|
|
|
}
|
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
|
2010-05-08 05:43:38 +08:00
|
|
|
ClassTemplatePartialSpecializationDecl *D) {
|
2010-06-23 21:48:30 +08:00
|
|
|
VisitClassTemplateSpecializationDecl(D);
|
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
ASTContext &C = Reader.getContext();
|
2010-10-05 23:59:54 +08:00
|
|
|
D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx);
|
2010-09-13 19:45:41 +08:00
|
|
|
|
2010-06-23 21:48:30 +08:00
|
|
|
unsigned NumArgs = Record[Idx++];
|
2010-09-13 19:45:41 +08:00
|
|
|
if (NumArgs) {
|
|
|
|
D->NumArgsAsWritten = NumArgs;
|
|
|
|
D->ArgsAsWritten = new (C) TemplateArgumentLoc[NumArgs];
|
|
|
|
for (unsigned i=0; i != NumArgs; ++i)
|
2010-10-05 23:59:54 +08:00
|
|
|
D->ArgsAsWritten[i] = Reader.ReadTemplateArgumentLoc(F, Record, Idx);
|
2010-09-13 19:45:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
D->SequenceNumber = Record[Idx++];
|
2010-06-23 21:48:30 +08:00
|
|
|
|
|
|
|
// These are read/set from/to the first declaration.
|
|
|
|
if (D->getPreviousDeclaration() == 0) {
|
2010-09-13 19:45:41 +08:00
|
|
|
D->InstantiatedFromMember.setPointer(
|
2011-07-22 06:35:25 +08:00
|
|
|
ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx));
|
2010-09-13 19:45:41 +08:00
|
|
|
D->InstantiatedFromMember.setInt(Record[Idx++]);
|
2010-06-23 21:48:30 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2011-08-31 21:59:56 +08:00
|
|
|
void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
|
|
|
|
ClassScopeFunctionSpecializationDecl *D) {
|
2011-08-17 09:06:54 +08:00
|
|
|
VisitDecl(D);
|
|
|
|
D->Specialization = ReadDeclAs<CXXMethodDecl>(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
2010-07-30 00:11:51 +08:00
|
|
|
VisitRedeclarableTemplateDecl(D);
|
2010-06-22 17:55:07 +08:00
|
|
|
|
2010-07-30 00:11:51 +08:00
|
|
|
if (D->getPreviousDeclaration() == 0) {
|
2010-06-22 17:55:07 +08:00
|
|
|
// This FunctionTemplateDecl owns a CommonPtr; read it.
|
|
|
|
|
2010-07-06 23:37:09 +08:00
|
|
|
// Read the function specialization declarations.
|
|
|
|
// FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled
|
2010-09-13 19:45:48 +08:00
|
|
|
// when reading the specialized FunctionDecl.
|
2010-07-06 23:37:09 +08:00
|
|
|
unsigned NumSpecs = Record[Idx++];
|
|
|
|
while (NumSpecs--)
|
2011-07-22 06:35:25 +08:00
|
|
|
(void)ReadDecl(Record, Idx);
|
2010-06-22 17:55:07 +08:00
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
|
2010-06-20 03:29:09 +08:00
|
|
|
VisitTypeDecl(D);
|
|
|
|
|
|
|
|
D->setDeclaredWithTypename(Record[Idx++]);
|
|
|
|
|
|
|
|
bool Inherited = Record[Idx++];
|
2010-10-05 23:59:54 +08:00
|
|
|
TypeSourceInfo *DefArg = GetTypeSourceInfo(Record, Idx);
|
2010-06-20 03:29:09 +08:00
|
|
|
D->setDefaultArgument(DefArg, Inherited);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
|
2011-02-09 09:13:10 +08:00
|
|
|
VisitDeclaratorDecl(D);
|
2010-06-26 00:25:09 +08:00
|
|
|
// TemplateParmPosition.
|
|
|
|
D->setDepth(Record[Idx++]);
|
|
|
|
D->setPosition(Record[Idx++]);
|
2011-01-20 04:10:05 +08:00
|
|
|
if (D->isExpandedParameterPack()) {
|
|
|
|
void **Data = reinterpret_cast<void **>(D + 1);
|
|
|
|
for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
|
2011-07-22 08:38:23 +08:00
|
|
|
Data[2*I] = Reader.readType(F, Record, Idx).getAsOpaquePtr();
|
2011-01-20 04:10:05 +08:00
|
|
|
Data[2*I + 1] = GetTypeSourceInfo(Record, Idx);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Rest of NonTypeTemplateParmDecl.
|
|
|
|
D->ParameterPack = Record[Idx++];
|
|
|
|
if (Record[Idx++]) {
|
|
|
|
Expr *DefArg = Reader.ReadExpr(F);
|
|
|
|
bool Inherited = Record[Idx++];
|
|
|
|
D->setDefaultArgument(DefArg, Inherited);
|
|
|
|
}
|
|
|
|
}
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
|
2010-07-09 01:12:57 +08:00
|
|
|
VisitTemplateDecl(D);
|
|
|
|
// TemplateParmPosition.
|
|
|
|
D->setDepth(Record[Idx++]);
|
|
|
|
D->setPosition(Record[Idx++]);
|
|
|
|
// Rest of TemplateTemplateParmDecl.
|
2010-10-05 23:59:54 +08:00
|
|
|
TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(F, Record, Idx);
|
2010-07-09 01:12:57 +08:00
|
|
|
bool IsInherited = Record[Idx++];
|
|
|
|
D->setDefaultArgument(Arg, IsInherited);
|
2011-01-05 23:48:55 +08:00
|
|
|
D->ParameterPack = Record[Idx++];
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2011-05-06 05:57:07 +08:00
|
|
|
void ASTDeclReader::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
|
|
|
|
VisitRedeclarableTemplateDecl(D);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
|
2010-07-23 01:28:12 +08:00
|
|
|
VisitDecl(D);
|
2010-10-05 23:59:54 +08:00
|
|
|
D->AssertExpr = Reader.ReadExpr(F);
|
|
|
|
D->Message = cast<StringLiteral>(Reader.ReadExpr(F));
|
2011-03-09 00:41:52 +08:00
|
|
|
D->RParenLoc = ReadSourceLocation(Record, Idx);
|
2010-05-08 05:43:38 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
std::pair<uint64_t, uint64_t>
|
2010-08-19 07:56:48 +08:00
|
|
|
ASTDeclReader::VisitDeclContext(DeclContext *DC) {
|
2009-04-27 13:27:42 +08:00
|
|
|
uint64_t LexicalOffset = Record[Idx++];
|
|
|
|
uint64_t VisibleOffset = Record[Idx++];
|
|
|
|
return std::make_pair(LexicalOffset, VisibleOffset);
|
|
|
|
}
|
|
|
|
|
2010-08-04 01:30:10 +08:00
|
|
|
template <typename T>
|
2010-08-19 07:56:48 +08:00
|
|
|
void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
|
2010-08-04 01:30:10 +08:00
|
|
|
enum RedeclKind { NoRedeclaration = 0, PointsToPrevious, PointsToLatest };
|
|
|
|
RedeclKind Kind = (RedeclKind)Record[Idx++];
|
|
|
|
switch (Kind) {
|
|
|
|
default:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Out of sync with ASTDeclWriter::VisitRedeclarable or"
|
|
|
|
" messed up reading");
|
2010-08-04 01:30:10 +08:00
|
|
|
case NoRedeclaration:
|
|
|
|
break;
|
2011-02-12 15:50:47 +08:00
|
|
|
case PointsToPrevious: {
|
2011-07-22 06:35:25 +08:00
|
|
|
DeclID PreviousDeclID = ReadDeclID(Record, Idx);
|
|
|
|
DeclID FirstDeclID = ReadDeclID(Record, Idx);
|
2011-02-12 15:50:47 +08:00
|
|
|
// We delay loading of the redeclaration chain to avoid deeply nested calls.
|
|
|
|
// We temporarily set the first (canonical) declaration as the previous one
|
|
|
|
// which is the one that matters and mark the real previous DeclID to be
|
|
|
|
// loaded & attached later on.
|
2010-08-04 01:30:10 +08:00
|
|
|
D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(
|
2011-02-12 15:50:47 +08:00
|
|
|
cast_or_null<T>(Reader.GetDecl(FirstDeclID)));
|
|
|
|
if (PreviousDeclID != FirstDeclID)
|
|
|
|
Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D),
|
|
|
|
PreviousDeclID));
|
2010-08-04 01:30:10 +08:00
|
|
|
break;
|
2011-02-12 15:50:47 +08:00
|
|
|
}
|
2010-08-04 01:30:10 +08:00
|
|
|
case PointsToLatest:
|
|
|
|
D->RedeclLink = typename Redeclarable<T>::LatestDeclLink(
|
2011-07-22 06:35:25 +08:00
|
|
|
ReadDeclAs<T>(Record, Idx));
|
2010-08-04 01:30:10 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(!(Kind == PointsToPrevious &&
|
|
|
|
Reader.FirstLatestDeclIDs.find(ThisDeclID) !=
|
|
|
|
Reader.FirstLatestDeclIDs.end()) &&
|
|
|
|
"This decl is not first, it should not be in the map");
|
|
|
|
if (Kind == PointsToPrevious)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// This decl is a first one and the latest declaration that it points to is in
|
2010-08-19 07:57:06 +08:00
|
|
|
// the same AST file. However, if this actually needs to point to a
|
|
|
|
// redeclaration in another AST file, we need to update it by checking the
|
2010-08-04 01:30:10 +08:00
|
|
|
// FirstLatestDeclIDs map which tracks this kind of decls.
|
|
|
|
assert(Reader.GetDecl(ThisDeclID) == static_cast<T*>(D) &&
|
|
|
|
"Invalid ThisDeclID ?");
|
2010-08-19 07:56:43 +08:00
|
|
|
ASTReader::FirstLatestDeclIDMap::iterator I
|
2010-08-04 01:30:10 +08:00
|
|
|
= Reader.FirstLatestDeclIDs.find(ThisDeclID);
|
|
|
|
if (I != Reader.FirstLatestDeclIDs.end()) {
|
|
|
|
Decl *NewLatest = Reader.GetDecl(I->second);
|
|
|
|
D->RedeclLink
|
|
|
|
= typename Redeclarable<T>::LatestDeclLink(cast_or_null<T>(NewLatest));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-27 13:27:42 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-04-27 14:01:06 +08:00
|
|
|
// Attribute Reading
|
2009-04-27 13:27:42 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-04-27 14:01:06 +08:00
|
|
|
/// \brief Reads attributes from the current stream position.
|
2011-07-23 00:00:58 +08:00
|
|
|
void ASTReader::ReadAttributes(Module &F, AttrVec &Attrs,
|
2010-10-19 03:20:11 +08:00
|
|
|
const RecordData &Record, unsigned &Idx) {
|
|
|
|
for (unsigned i = 0, e = Record[Idx++]; i != e; ++i) {
|
2009-04-27 14:01:06 +08:00
|
|
|
Attr *New = 0;
|
2010-06-17 07:43:53 +08:00
|
|
|
attr::Kind Kind = (attr::Kind)Record[Idx++];
|
2011-09-14 00:05:58 +08:00
|
|
|
SourceRange Range = ReadSourceRange(F, Record, Idx);
|
2009-04-27 14:01:06 +08:00
|
|
|
|
2010-08-19 07:23:40 +08:00
|
|
|
#include "clang/Serialization/AttrPCHRead.inc"
|
2009-04-27 14:01:06 +08:00
|
|
|
|
|
|
|
assert(New && "Unable to decode attribute?");
|
2010-08-19 07:23:40 +08:00
|
|
|
Attrs.push_back(New);
|
2009-04-27 14:01:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2010-08-19 07:56:43 +08:00
|
|
|
// ASTReader Implementation
|
2009-04-27 14:01:06 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-04-27 13:27:42 +08:00
|
|
|
|
|
|
|
/// \brief Note that we have loaded the declaration with the given
|
|
|
|
/// Index.
|
2009-09-09 23:08:12 +08:00
|
|
|
///
|
2009-04-27 13:27:42 +08:00
|
|
|
/// This routine notes that this declaration has already been loaded,
|
|
|
|
/// so that future GetDecl calls will return this declaration rather
|
|
|
|
/// than trying to load a new declaration.
|
2010-08-19 07:56:43 +08:00
|
|
|
inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) {
|
2009-04-27 13:27:42 +08:00
|
|
|
assert(!DeclsLoaded[Index] && "Decl loaded twice?");
|
|
|
|
DeclsLoaded[Index] = D;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// \brief Determine whether the consumer will be interested in seeing
|
|
|
|
/// this declaration (via HandleTopLevelDecl).
|
|
|
|
///
|
|
|
|
/// This routine should return true for anything that might affect
|
|
|
|
/// code generation, e.g., inline function definitions, Objective-C
|
|
|
|
/// declarations with metadata, etc.
|
|
|
|
static bool isConsumerInterestedIn(Decl *D) {
|
2011-09-14 05:35:00 +08:00
|
|
|
// An ObjCMethodDecl is never considered as "interesting" because its
|
|
|
|
// implementation container always is.
|
|
|
|
|
2011-09-10 08:22:34 +08:00
|
|
|
if (isa<FileScopeAsmDecl>(D) ||
|
|
|
|
isa<ObjCProtocolDecl>(D) ||
|
|
|
|
isa<ObjCImplDecl>(D))
|
2009-09-17 11:06:44 +08:00
|
|
|
return true;
|
2009-04-27 13:27:42 +08:00
|
|
|
if (VarDecl *Var = dyn_cast<VarDecl>(D))
|
2010-08-05 17:47:59 +08:00
|
|
|
return Var->isFileVarDecl() &&
|
|
|
|
Var->isThisDeclarationADefinition() == VarDecl::Definition;
|
2009-04-27 13:27:42 +08:00
|
|
|
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
|
2011-05-07 04:44:56 +08:00
|
|
|
return Func->doesThisDeclarationHaveABody();
|
2011-09-10 08:22:34 +08:00
|
|
|
|
|
|
|
return false;
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2011-07-20 08:27:43 +08:00
|
|
|
/// \brief Get the correct cursor and offset for loading a declaration.
|
2010-08-19 07:56:43 +08:00
|
|
|
ASTReader::RecordLocation
|
2011-08-03 23:48:04 +08:00
|
|
|
ASTReader::DeclCursorForID(DeclID ID) {
|
2010-08-13 08:28:03 +08:00
|
|
|
// See if there's an override.
|
|
|
|
DeclReplacementMap::iterator It = ReplacedDecls.find(ID);
|
|
|
|
if (It != ReplacedDecls.end())
|
2010-10-05 23:59:54 +08:00
|
|
|
return RecordLocation(It->second.first, It->second.second);
|
2010-08-13 08:28:03 +08:00
|
|
|
|
2011-07-20 08:27:43 +08:00
|
|
|
GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID);
|
|
|
|
assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
|
2011-07-29 08:56:45 +08:00
|
|
|
Module *M = I->second;
|
2011-08-04 07:28:44 +08:00
|
|
|
return RecordLocation(M,
|
|
|
|
M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS]);
|
2010-07-21 06:46:15 +08:00
|
|
|
}
|
|
|
|
|
Introduce a global bit-offset continuous range map into the ASTReader,
so that we have one, simple way to map from global bit offsets to
local bit offsets. Eliminates a number of loops over the chain, and
generalizes for more interesting bit remappings.
Also, as an amusing oddity, we were computing global bit offsets
*backwards* for preprocessed entities (e.g., the directly included PCH
file in the chain would start at offset zero, rather than the original
PCH that occurs first in translation unit). Even more amusingly, it
made precompiled preambles work, because we were forgetting to adjust
the local bit offset to a global bit offset when storing preprocessed
entity offsets in the ASTUnit. Two wrongs made a right, and now
they're both right.
llvm-svn: 135750
2011-07-22 14:10:01 +08:00
|
|
|
ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) {
|
2011-07-23 00:00:58 +08:00
|
|
|
ContinuousRangeMap<uint64_t, Module*, 4>::iterator I
|
Introduce a global bit-offset continuous range map into the ASTReader,
so that we have one, simple way to map from global bit offsets to
local bit offsets. Eliminates a number of loops over the chain, and
generalizes for more interesting bit remappings.
Also, as an amusing oddity, we were computing global bit offsets
*backwards* for preprocessed entities (e.g., the directly included PCH
file in the chain would start at offset zero, rather than the original
PCH that occurs first in translation unit). Even more amusingly, it
made precompiled preambles work, because we were forgetting to adjust
the local bit offset to a global bit offset when storing preprocessed
entity offsets in the ASTUnit. Two wrongs made a right, and now
they're both right.
llvm-svn: 135750
2011-07-22 14:10:01 +08:00
|
|
|
= GlobalBitOffsetsMap.find(GlobalOffset);
|
|
|
|
|
|
|
|
assert(I != GlobalBitOffsetsMap.end() && "Corrupted global bit offsets map");
|
|
|
|
return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset);
|
|
|
|
}
|
|
|
|
|
2011-08-04 08:01:48 +08:00
|
|
|
uint64_t ASTReader::getGlobalBitOffset(Module &M, uint32_t LocalOffset) {
|
|
|
|
return LocalOffset + M.GlobalBitOffset;
|
|
|
|
}
|
|
|
|
|
2011-02-12 15:50:47 +08:00
|
|
|
void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
|
|
|
|
assert(D && previous);
|
|
|
|
if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
|
|
|
|
TD->RedeclLink.setPointer(cast<TagDecl>(previous));
|
|
|
|
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
|
|
|
FD->RedeclLink.setPointer(cast<FunctionDecl>(previous));
|
|
|
|
} else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
|
|
|
VD->RedeclLink.setPointer(cast<VarDecl>(previous));
|
|
|
|
} else {
|
|
|
|
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
|
|
|
|
TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTReader::loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID) {
|
|
|
|
Decl *previous = GetDecl(ID);
|
|
|
|
ASTDeclReader::attachPreviousDecl(D, previous);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
/// \brief Read the declaration at the given offset from the AST file.
|
2011-08-03 23:48:04 +08:00
|
|
|
Decl *ASTReader::ReadDeclRecord(DeclID ID) {
|
2011-08-12 08:15:20 +08:00
|
|
|
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
|
2011-08-03 23:48:04 +08:00
|
|
|
RecordLocation Loc = DeclCursorForID(ID);
|
2010-10-05 23:59:54 +08:00
|
|
|
llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
|
2009-04-27 13:27:42 +08:00
|
|
|
// Keep track of where we are in the stream, then jump back there
|
|
|
|
// after reading this declaration.
|
2009-04-27 13:58:23 +08:00
|
|
|
SavedStreamPosition SavedPosition(DeclsCursor);
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2010-06-29 06:28:35 +08:00
|
|
|
ReadingKindTracker ReadingKind(Read_Decl, *this);
|
|
|
|
|
2009-07-07 02:54:52 +08:00
|
|
|
// Note that we are loading a declaration record.
|
2010-07-30 18:03:16 +08:00
|
|
|
Deserializing ADecl(this);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-10-05 23:59:54 +08:00
|
|
|
DeclsCursor.JumpToBit(Loc.Offset);
|
2009-04-27 13:27:42 +08:00
|
|
|
RecordData Record;
|
2009-04-27 13:58:23 +08:00
|
|
|
unsigned Code = DeclsCursor.ReadCode();
|
2009-04-27 13:27:42 +08:00
|
|
|
unsigned Idx = 0;
|
2010-10-05 23:59:54 +08:00
|
|
|
ASTDeclReader Reader(*this, *Loc.F, DeclsCursor, ID, Record, Idx);
|
2009-04-27 13:27:42 +08:00
|
|
|
|
2009-04-27 13:58:23 +08:00
|
|
|
Decl *D = 0;
|
2010-08-19 07:57:32 +08:00
|
|
|
switch ((DeclCode)DeclsCursor.ReadRecord(Code, Record)) {
|
|
|
|
case DECL_CONTEXT_LEXICAL:
|
|
|
|
case DECL_CONTEXT_VISIBLE:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord");
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_TYPEDEF:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = TypedefDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
|
2011-03-06 23:48:19 +08:00
|
|
|
0, 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2011-04-15 22:24:37 +08:00
|
|
|
case DECL_TYPEALIAS:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = TypeAliasDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
|
2011-04-15 22:24:37 +08:00
|
|
|
0, 0);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_ENUM:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = EnumDecl::Create(Context, Decl::EmptyShell());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_RECORD:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = RecordDecl::Create(Context, Decl::EmptyShell());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_ENUM_CONSTANT:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = EnumConstantDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
|
2009-04-27 13:27:42 +08:00
|
|
|
0, llvm::APSInt());
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FUNCTION:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = FunctionDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
|
2011-03-08 16:55:46 +08:00
|
|
|
DeclarationName(), QualType(), 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_LINKAGE_SPEC:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = LinkageSpecDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
|
2010-05-08 05:43:38 +08:00
|
|
|
(LinkageSpecDecl::LanguageIDs)0,
|
2011-03-04 00:52:29 +08:00
|
|
|
SourceLocation());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2011-02-17 15:39:24 +08:00
|
|
|
case DECL_LABEL:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = LabelDecl::Create(Context, 0, SourceLocation(), 0);
|
2011-02-17 15:39:24 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_NAMESPACE:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = NamespaceDecl::Create(Context, 0, SourceLocation(),
|
2011-03-08 20:38:20 +08:00
|
|
|
SourceLocation(), 0);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_NAMESPACE_ALIAS:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = NamespaceAliasDecl::Create(Context, 0, SourceLocation(),
|
2011-02-26 01:08:07 +08:00
|
|
|
SourceLocation(), 0,
|
|
|
|
NestedNameSpecifierLoc(),
|
2010-05-08 05:43:38 +08:00
|
|
|
SourceLocation(), 0);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_USING:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = UsingDecl::Create(Context, 0, SourceLocation(),
|
2011-02-25 08:36:19 +08:00
|
|
|
NestedNameSpecifierLoc(), DeclarationNameInfo(),
|
|
|
|
false);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_USING_SHADOW:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = UsingShadowDecl::Create(Context, 0, SourceLocation(), 0, 0);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_USING_DIRECTIVE:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = UsingDirectiveDecl::Create(Context, 0, SourceLocation(),
|
2011-02-26 00:33:46 +08:00
|
|
|
SourceLocation(), NestedNameSpecifierLoc(),
|
2010-05-08 05:43:38 +08:00
|
|
|
SourceLocation(), 0, 0);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_UNRESOLVED_USING_VALUE:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = UnresolvedUsingValueDecl::Create(Context, 0, SourceLocation(),
|
2011-02-25 08:36:19 +08:00
|
|
|
NestedNameSpecifierLoc(),
|
2010-08-12 19:46:03 +08:00
|
|
|
DeclarationNameInfo());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_UNRESOLVED_USING_TYPENAME:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = UnresolvedUsingTypenameDecl::Create(Context, 0, SourceLocation(),
|
2011-02-25 08:36:19 +08:00
|
|
|
SourceLocation(),
|
|
|
|
NestedNameSpecifierLoc(),
|
|
|
|
SourceLocation(),
|
2010-05-08 05:43:38 +08:00
|
|
|
DeclarationName());
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_RECORD:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = CXXRecordDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_METHOD:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = CXXMethodDecl::Create(Context, 0, SourceLocation(),
|
2011-03-09 01:10:18 +08:00
|
|
|
DeclarationNameInfo(), QualType(), 0,
|
2011-08-16 05:04:07 +08:00
|
|
|
false, SC_None, false, false, SourceLocation());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_CONSTRUCTOR:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = CXXConstructorDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_DESTRUCTOR:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = CXXDestructorDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CXX_CONVERSION:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = CXXConversionDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_ACCESS_SPEC:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = AccessSpecDecl::Create(Context, Decl::EmptyShell());
|
2010-06-05 13:09:32 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FRIEND:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = FriendDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FRIEND_TEMPLATE:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = FriendTemplateDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CLASS_TEMPLATE:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ClassTemplateDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CLASS_TEMPLATE_SPECIALIZATION:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ClassTemplateSpecializationDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ClassTemplatePartialSpecializationDecl::Create(Context,
|
2011-03-05 01:52:15 +08:00
|
|
|
Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2011-08-14 11:52:19 +08:00
|
|
|
case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ClassScopeFunctionSpecializationDecl::Create(Context,
|
2011-08-14 11:52:19 +08:00
|
|
|
Decl::EmptyShell());
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FUNCTION_TEMPLATE:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = FunctionTemplateDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_TEMPLATE_TYPE_PARM:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = TemplateTypeParmDecl::Create(Context, Decl::EmptyShell());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_NON_TYPE_TEMPLATE_PARM:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = NonTypeTemplateParmDecl::Create(Context, 0, SourceLocation(),
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation(), 0, 0, 0, QualType(),
|
|
|
|
false, 0);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2011-01-20 04:10:05 +08:00
|
|
|
case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = NonTypeTemplateParmDecl::Create(Context, 0, SourceLocation(),
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation(), 0, 0, 0, QualType(),
|
|
|
|
0, 0, Record[Idx++], 0);
|
2011-01-20 04:10:05 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_TEMPLATE_TEMPLATE_PARM:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = TemplateTemplateParmDecl::Create(Context, 0, SourceLocation(), 0, 0,
|
2011-01-05 23:48:55 +08:00
|
|
|
false, 0, 0);
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
2011-05-06 05:57:07 +08:00
|
|
|
case DECL_TYPE_ALIAS_TEMPLATE:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = TypeAliasTemplateDecl::Create(Context, Decl::EmptyShell());
|
2011-05-06 05:57:07 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_STATIC_ASSERT:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = StaticAssertDecl::Create(Context, 0, SourceLocation(), 0, 0,
|
2011-03-09 00:41:52 +08:00
|
|
|
SourceLocation());
|
2010-05-08 05:43:38 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_METHOD:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(),
|
2010-03-08 22:59:44 +08:00
|
|
|
Selector(), QualType(), 0, 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_INTERFACE:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_IVAR:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), SourceLocation(),
|
2011-03-08 16:55:46 +08:00
|
|
|
0, QualType(), 0, ObjCIvarDecl::None);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_PROTOCOL:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCProtocolDecl::Create(Context, 0, SourceLocation(), 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_AT_DEFS_FIELD:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCAtDefsFieldDecl::Create(Context, 0, SourceLocation(),
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation(), 0, QualType(), 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_CLASS:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCClassDecl::Create(Context, 0, SourceLocation());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_FORWARD_PROTOCOL:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCForwardProtocolDecl::Create(Context, 0, SourceLocation());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_CATEGORY:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCCategoryDecl::Create(Context, Decl::EmptyShell());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_CATEGORY_IMPL:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCCategoryImplDecl::Create(Context, 0, SourceLocation(), 0, 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_IMPLEMENTATION:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCImplementationDecl::Create(Context, 0, SourceLocation(), 0, 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_COMPATIBLE_ALIAS:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCCompatibleAliasDecl::Create(Context, 0, SourceLocation(), 0, 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_PROPERTY:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCPropertyDecl::Create(Context, 0, SourceLocation(), 0, SourceLocation(),
|
2010-06-05 04:50:08 +08:00
|
|
|
0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_OBJC_PROPERTY_IMPL:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ObjCPropertyImplDecl::Create(Context, 0, SourceLocation(),
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation(), 0,
|
2010-11-17 09:03:52 +08:00
|
|
|
ObjCPropertyImplDecl::Dynamic, 0,
|
|
|
|
SourceLocation());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FIELD:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = FieldDecl::Create(Context, 0, SourceLocation(), SourceLocation(), 0,
|
2011-06-12 01:19:42 +08:00
|
|
|
QualType(), 0, 0, false, false);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-11-21 14:08:52 +08:00
|
|
|
case DECL_INDIRECTFIELD:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = IndirectFieldDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
|
2010-11-21 14:08:52 +08:00
|
|
|
0, 0);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_VAR:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = VarDecl::Create(Context, 0, SourceLocation(), SourceLocation(), 0,
|
2011-03-08 16:55:46 +08:00
|
|
|
QualType(), 0, SC_None, SC_None);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_IMPLICIT_PARAM:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ImplicitParamDecl::Create(Context, 0, SourceLocation(), 0, QualType());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_PARM_VAR:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = ParmVarDecl::Create(Context, 0, SourceLocation(), SourceLocation(), 0,
|
2011-03-08 16:55:46 +08:00
|
|
|
QualType(), 0, SC_None, SC_None, 0);
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_FILE_SCOPE_ASM:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = FileScopeAsmDecl::Create(Context, 0, 0, SourceLocation(),
|
2011-03-03 22:20:18 +08:00
|
|
|
SourceLocation());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case DECL_BLOCK:
|
2011-09-10 05:34:22 +08:00
|
|
|
D = BlockDecl::Create(Context, 0, SourceLocation());
|
2009-04-27 13:27:42 +08:00
|
|
|
break;
|
2010-10-30 06:39:52 +08:00
|
|
|
case DECL_CXX_BASE_SPECIFIERS:
|
|
|
|
Error("attempt to read a C++ base-specifier record as a declaration");
|
|
|
|
return 0;
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:48 +08:00
|
|
|
assert(D && "Unknown declaration reading AST file");
|
2009-04-27 14:01:06 +08:00
|
|
|
LoadedDecl(Index, D);
|
|
|
|
Reader.Visit(D);
|
2009-04-27 13:27:42 +08:00
|
|
|
|
|
|
|
// If this declaration is also a declaration context, get the
|
|
|
|
// offsets for its tables of lexical and visible declarations.
|
|
|
|
if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
|
|
|
|
std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
|
|
|
|
if (Offsets.first || Offsets.second) {
|
2011-08-25 03:03:07 +08:00
|
|
|
if (Offsets.first != 0)
|
|
|
|
DC->setHasExternalLexicalStorage(true);
|
|
|
|
if (Offsets.second != 0)
|
|
|
|
DC->setHasExternalVisibleStorage(true);
|
|
|
|
if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets,
|
|
|
|
Loc.F->DeclContextInfos[DC]))
|
2010-07-27 08:17:23 +08:00
|
|
|
return 0;
|
2011-04-25 00:27:54 +08:00
|
|
|
}
|
2010-08-24 08:50:04 +08:00
|
|
|
|
2011-04-25 00:27:54 +08:00
|
|
|
// Now add the pending visible updates for this decl context, if it has any.
|
|
|
|
DeclContextVisibleUpdatesPending::iterator I =
|
|
|
|
PendingVisibleUpdates.find(ID);
|
|
|
|
if (I != PendingVisibleUpdates.end()) {
|
|
|
|
// There are updates. This means the context has external visible
|
|
|
|
// storage, even if the original stored version didn't.
|
|
|
|
DC->setHasExternalVisibleStorage(true);
|
|
|
|
DeclContextVisibleUpdates &U = I->second;
|
|
|
|
for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end();
|
|
|
|
UI != UE; ++UI) {
|
2011-08-25 03:03:07 +08:00
|
|
|
UI->second->DeclContextInfos[DC].NameLookupTableData = UI->first;
|
2010-08-24 08:50:04 +08:00
|
|
|
}
|
2011-04-25 00:27:54 +08:00
|
|
|
PendingVisibleUpdates.erase(I);
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(Idx == Record.size());
|
|
|
|
|
2011-08-12 08:15:20 +08:00
|
|
|
// Load any relevant update records.
|
|
|
|
loadDeclUpdateRecords(ID, D);
|
|
|
|
|
2011-09-01 08:58:55 +08:00
|
|
|
if (ObjCChainedCategoriesInterfaces.count(ID))
|
|
|
|
loadObjCChainedCategories(ID, cast<ObjCInterfaceDecl>(D));
|
|
|
|
|
2011-08-12 08:15:20 +08:00
|
|
|
// If we have deserialized a declaration that has a definition the
|
|
|
|
// AST consumer might need to know about, queue it.
|
|
|
|
// We don't pass it to the consumer immediately because we may be in recursive
|
|
|
|
// loading, and some declarations may still be initializing.
|
2011-09-14 05:35:00 +08:00
|
|
|
if (isConsumerInterestedIn(D))
|
2011-09-10 08:22:34 +08:00
|
|
|
InterestingDecls.push_back(D);
|
|
|
|
|
2011-08-12 08:15:20 +08:00
|
|
|
return D;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
|
2010-10-25 01:26:36 +08:00
|
|
|
// The declaration may have been modified by files later in the chain.
|
|
|
|
// If this is the case, read the record containing the updates from each file
|
|
|
|
// and pass it to ASTDeclReader to make the modifications.
|
|
|
|
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
|
|
|
|
if (UpdI != DeclUpdateOffsets.end()) {
|
|
|
|
FileOffsetsTy &UpdateOffsets = UpdI->second;
|
|
|
|
for (FileOffsetsTy::iterator
|
2011-08-12 08:15:20 +08:00
|
|
|
I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) {
|
2011-07-23 00:00:58 +08:00
|
|
|
Module *F = I->first;
|
2010-10-25 01:26:36 +08:00
|
|
|
uint64_t Offset = I->second;
|
|
|
|
llvm::BitstreamCursor &Cursor = F->DeclsCursor;
|
|
|
|
SavedStreamPosition SavedPosition(Cursor);
|
|
|
|
Cursor.JumpToBit(Offset);
|
|
|
|
RecordData Record;
|
|
|
|
unsigned Code = Cursor.ReadCode();
|
|
|
|
unsigned RecCode = Cursor.ReadRecord(Code, Record);
|
|
|
|
(void)RecCode;
|
|
|
|
assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
|
2011-08-12 08:15:20 +08:00
|
|
|
|
|
|
|
unsigned Idx = 0;
|
|
|
|
ASTDeclReader Reader(*this, *F, Cursor, ID, Record, Idx);
|
2011-04-29 16:19:30 +08:00
|
|
|
Reader.UpdateDecl(D, *F, Record);
|
2010-10-25 01:26:36 +08:00
|
|
|
}
|
|
|
|
}
|
2009-04-27 13:27:42 +08:00
|
|
|
}
|
2010-10-25 01:26:36 +08:00
|
|
|
|
2011-09-01 08:58:55 +08:00
|
|
|
namespace {
|
|
|
|
/// \brief Given an ObjC interface, goes through the modules and links to the
|
|
|
|
/// interface all the categories for it.
|
|
|
|
class ObjCChainedCategoriesVisitor {
|
|
|
|
ASTReader &Reader;
|
|
|
|
serialization::GlobalDeclID InterfaceID;
|
|
|
|
ObjCInterfaceDecl *Interface;
|
|
|
|
ObjCCategoryDecl *GlobHeadCat, *GlobTailCat;
|
|
|
|
llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap;
|
|
|
|
|
|
|
|
public:
|
|
|
|
ObjCChainedCategoriesVisitor(ASTReader &Reader,
|
|
|
|
serialization::GlobalDeclID InterfaceID,
|
|
|
|
ObjCInterfaceDecl *Interface)
|
|
|
|
: Reader(Reader), InterfaceID(InterfaceID), Interface(Interface),
|
|
|
|
GlobHeadCat(0), GlobTailCat(0) { }
|
|
|
|
|
|
|
|
static bool visit(Module &M, void *UserData) {
|
|
|
|
return static_cast<ObjCChainedCategoriesVisitor *>(UserData)->visit(M);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool visit(Module &M) {
|
|
|
|
if (Reader.isDeclIDFromModule(InterfaceID, M))
|
|
|
|
return true; // We reached the module where the interface originated
|
|
|
|
// from. Stop traversing the imported modules.
|
|
|
|
|
|
|
|
Module::ChainedObjCCategoriesMap::iterator
|
|
|
|
I = M.ChainedObjCCategories.find(InterfaceID);
|
|
|
|
if (I == M.ChainedObjCCategories.end())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
ObjCCategoryDecl *
|
|
|
|
HeadCat = Reader.GetLocalDeclAs<ObjCCategoryDecl>(M, I->second.first);
|
|
|
|
ObjCCategoryDecl *
|
|
|
|
TailCat = Reader.GetLocalDeclAs<ObjCCategoryDecl>(M, I->second.second);
|
|
|
|
|
|
|
|
addCategories(HeadCat, TailCat);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void addCategories(ObjCCategoryDecl *HeadCat,
|
|
|
|
ObjCCategoryDecl *TailCat = 0) {
|
|
|
|
if (!HeadCat) {
|
|
|
|
assert(!TailCat);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!TailCat) {
|
|
|
|
TailCat = HeadCat;
|
|
|
|
while (TailCat->getNextClassCategory())
|
|
|
|
TailCat = TailCat->getNextClassCategory();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!GlobHeadCat) {
|
|
|
|
GlobHeadCat = HeadCat;
|
|
|
|
GlobTailCat = TailCat;
|
|
|
|
} else {
|
|
|
|
ASTDeclReader::setNextObjCCategory(GlobTailCat, HeadCat);
|
|
|
|
GlobTailCat = TailCat;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::DenseSet<DeclarationName> Checked;
|
|
|
|
for (ObjCCategoryDecl *Cat = HeadCat,
|
|
|
|
*CatEnd = TailCat->getNextClassCategory();
|
|
|
|
Cat != CatEnd; Cat = Cat->getNextClassCategory()) {
|
|
|
|
if (Checked.count(Cat->getDeclName()))
|
|
|
|
continue;
|
|
|
|
Checked.insert(Cat->getDeclName());
|
|
|
|
checkForDuplicate(Cat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Warns for duplicate categories that come from different modules.
|
|
|
|
void checkForDuplicate(ObjCCategoryDecl *Cat) {
|
|
|
|
DeclarationName Name = Cat->getDeclName();
|
|
|
|
// Find the top category with the same name. We do not want to warn for
|
|
|
|
// duplicates along the established chain because there were already
|
|
|
|
// warnings for them when the module was created. We only want to warn for
|
|
|
|
// duplicates between non-dependent modules:
|
|
|
|
//
|
2011-09-01 11:07:11 +08:00
|
|
|
// MT //
|
|
|
|
// / \ //
|
|
|
|
// ML MR //
|
2011-09-01 08:58:55 +08:00
|
|
|
//
|
|
|
|
// We want to warn for duplicates between ML and MR,not between ML and MT.
|
|
|
|
//
|
|
|
|
// FIXME: We should not warn for duplicates in diamond:
|
|
|
|
//
|
2011-09-01 11:07:11 +08:00
|
|
|
// MT //
|
|
|
|
// / \ //
|
|
|
|
// ML MR //
|
|
|
|
// \ / //
|
|
|
|
// MB //
|
2011-09-01 08:58:55 +08:00
|
|
|
//
|
|
|
|
// If there are duplicates in ML/MR, there will be warning when creating
|
|
|
|
// MB *and* when importing MB. We should not warn when importing.
|
|
|
|
for (ObjCCategoryDecl *Next = Cat->getNextClassCategory(); Next;
|
|
|
|
Next = Next->getNextClassCategory()) {
|
|
|
|
if (Next->getDeclName() == Name)
|
|
|
|
Cat = Next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCCategoryDecl *&PrevCat = NameCategoryMap[Name];
|
|
|
|
if (!PrevCat)
|
|
|
|
PrevCat = Cat;
|
|
|
|
|
|
|
|
if (PrevCat != Cat) {
|
|
|
|
Reader.Diag(Cat->getLocation(), diag::warn_dup_category_def)
|
|
|
|
<< Interface->getDeclName() << Name;
|
|
|
|
Reader.Diag(PrevCat->getLocation(), diag::note_previous_definition);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCCategoryDecl *getHeadCategory() const { return GlobHeadCat; }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTReader::loadObjCChainedCategories(serialization::GlobalDeclID ID,
|
|
|
|
ObjCInterfaceDecl *D) {
|
|
|
|
ObjCChainedCategoriesVisitor Visitor(*this, ID, D);
|
|
|
|
ModuleMgr.visit(ObjCChainedCategoriesVisitor::visit, &Visitor);
|
|
|
|
// Also add the categories that the interface already links to.
|
|
|
|
Visitor.addCategories(D->getCategoryList());
|
|
|
|
D->setCategoryList(Visitor.getHeadCategory());
|
|
|
|
}
|
2011-08-12 08:15:20 +08:00
|
|
|
|
2011-07-23 00:00:58 +08:00
|
|
|
void ASTDeclReader::UpdateDecl(Decl *D, Module &Module,
|
2011-04-29 16:19:30 +08:00
|
|
|
const RecordData &Record) {
|
2010-10-25 01:26:50 +08:00
|
|
|
unsigned Idx = 0;
|
|
|
|
while (Idx < Record.size()) {
|
|
|
|
switch ((DeclUpdateKind)Record[Idx++]) {
|
|
|
|
case UPD_CXX_SET_DEFINITIONDATA: {
|
|
|
|
CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
|
2011-08-03 23:48:04 +08:00
|
|
|
CXXRecordDecl *DefinitionDecl
|
|
|
|
= Reader.ReadDeclAs<CXXRecordDecl>(Module, Record, Idx);
|
2010-10-25 01:26:50 +08:00
|
|
|
assert(!RD->DefinitionData && "DefinitionData is already set!");
|
|
|
|
InitializeCXXDefinitionData(RD, DefinitionDecl, Record, Idx);
|
|
|
|
break;
|
|
|
|
}
|
2010-10-25 01:26:54 +08:00
|
|
|
|
|
|
|
case UPD_CXX_ADDED_IMPLICIT_MEMBER:
|
2011-08-03 23:48:04 +08:00
|
|
|
cast<CXXRecordDecl>(D)->addedMember(Reader.ReadDecl(Module, Record, Idx));
|
2010-10-25 01:26:54 +08:00
|
|
|
break;
|
2010-10-28 15:38:42 +08:00
|
|
|
|
|
|
|
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
|
|
|
|
// It will be added to the template's specializations set when loaded.
|
2011-08-03 23:48:04 +08:00
|
|
|
(void)Reader.ReadDecl(Module, Record, Idx);
|
2011-04-25 00:28:13 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
|
2011-08-03 23:48:04 +08:00
|
|
|
NamespaceDecl *Anon
|
|
|
|
= Reader.ReadDeclAs<NamespaceDecl>(Module, Record, Idx);
|
2011-04-25 00:28:21 +08:00
|
|
|
// Guard against these being loaded out of original order. Don't use
|
|
|
|
// getNextNamespace(), since it tries to access the context and can't in
|
|
|
|
// the middle of deserialization.
|
|
|
|
if (!Anon->NextNamespace) {
|
|
|
|
if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D))
|
|
|
|
TU->setAnonymousNamespace(Anon);
|
|
|
|
else
|
|
|
|
cast<NamespaceDecl>(D)->OrigOrAnonNamespace.setPointer(Anon);
|
|
|
|
}
|
2011-04-25 00:28:13 +08:00
|
|
|
break;
|
|
|
|
}
|
2011-04-29 16:19:30 +08:00
|
|
|
|
|
|
|
case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
|
|
|
|
cast<VarDecl>(D)->getMemberSpecializationInfo()->setPointOfInstantiation(
|
|
|
|
Reader.ReadSourceLocation(Module, Record, Idx));
|
|
|
|
break;
|
2010-10-25 01:26:50 +08:00
|
|
|
}
|
|
|
|
}
|
2010-10-25 01:26:36 +08:00
|
|
|
}
|