public:
/// \brief Type code that corresponds to the record generated.
TypeCode Code;
+ /// \brief Abbreviation to use for the record, if any.
+ unsigned AbbrevToUse;
ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
: Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { }
// FIXME: need to stabilize encoding of calling convention...
Record.push_back(C.getCC());
Record.push_back(C.getProducesResult());
+
+ if (C.getHasRegParm() || C.getRegParm() || C.getProducesResult())
+ AbbrevToUse = 0;
}
void ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
VisitFunctionType(T);
- Record.push_back(T->getNumParams());
- for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
- Writer.AddTypeRef(T->getParamType(I), Record);
+
Record.push_back(T->isVariadic());
Record.push_back(T->hasTrailingReturn());
Record.push_back(T->getTypeQuals());
Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
addExceptionSpec(Writer, T, Record);
+
+ Record.push_back(T->getNumParams());
+ for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
+ Writer.AddTypeRef(T->getParamType(I), Record);
+
+ if (T->isVariadic() || T->hasTrailingReturn() || T->getTypeQuals() ||
+ T->getRefQualifier() || T->getExceptionSpecType() != EST_None)
+ AbbrevToUse = 0;
+
Code = TYPE_FUNCTION_PROTO;
}
Writer.AddSourceLocation(TL.getRParenLoc(), Record);
}
+void ASTWriter::WriteTypeAbbrevs() {
+ using namespace llvm;
+
+ BitCodeAbbrev *Abv;
+
+ // Abbreviation for TYPE_EXT_QUAL
+ Abv = new BitCodeAbbrev();
+ Abv->Add(BitCodeAbbrevOp(serialization::TYPE_EXT_QUAL));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3)); // Quals
+ TypeExtQualAbbrev = Stream.EmitAbbrev(Abv);
+
+ // Abbreviation for TYPE_FUNCTION_PROTO
+ Abv = new BitCodeAbbrev();
+ Abv->Add(BitCodeAbbrevOp(serialization::TYPE_FUNCTION_PROTO));
+ // FunctionType
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ReturnType
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // NoReturn
+ Abv->Add(BitCodeAbbrevOp(0)); // HasRegParm
+ Abv->Add(BitCodeAbbrevOp(0)); // RegParm
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // CC
+ Abv->Add(BitCodeAbbrevOp(0)); // ProducesResult
+ // FunctionProtoType
+ Abv->Add(BitCodeAbbrevOp(0)); // IsVariadic
+ Abv->Add(BitCodeAbbrevOp(0)); // HasTrailingReturn
+ Abv->Add(BitCodeAbbrevOp(0)); // TypeQuals
+ Abv->Add(BitCodeAbbrevOp(0)); // RefQualifier
+ Abv->Add(BitCodeAbbrevOp(EST_None)); // ExceptionSpec
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumParams
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Params
+ TypeFunctionProtoAbbrev = Stream.EmitAbbrev(Abv);
+}
+
//===----------------------------------------------------------------------===//
// ASTWriter Implementation
//===----------------------------------------------------------------------===//
#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
RECORD(STMT_STOP);
RECORD(STMT_NULL_PTR);
+ RECORD(STMT_REF_PTR);
RECORD(STMT_NULL);
RECORD(STMT_COMPOUND);
RECORD(STMT_CASE);
RECORD(STMT_OBJC_AT_SYNCHRONIZED);
RECORD(STMT_OBJC_AT_THROW);
RECORD(EXPR_OBJC_BOOL_LITERAL);
+ RECORD(STMT_CXX_CATCH);
+ RECORD(STMT_CXX_TRY);
+ RECORD(STMT_CXX_FOR_RANGE);
RECORD(EXPR_CXX_OPERATOR_CALL);
RECORD(EXPR_CXX_CONSTRUCT);
RECORD(EXPR_CXX_STATIC_CAST);
RECORD(EXPR_CXX_NULL_PTR_LITERAL);
RECORD(EXPR_CXX_TYPEID_EXPR);
RECORD(EXPR_CXX_TYPEID_TYPE);
- RECORD(EXPR_CXX_UUIDOF_EXPR);
- RECORD(EXPR_CXX_UUIDOF_TYPE);
RECORD(EXPR_CXX_THIS);
RECORD(EXPR_CXX_THROW);
RECORD(EXPR_CXX_DEFAULT_ARG);
+ RECORD(EXPR_CXX_DEFAULT_INIT);
RECORD(EXPR_CXX_BIND_TEMPORARY);
RECORD(EXPR_CXX_SCALAR_VALUE_INIT);
RECORD(EXPR_CXX_NEW);
RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT);
RECORD(EXPR_CXX_UNRESOLVED_MEMBER);
RECORD(EXPR_CXX_UNRESOLVED_LOOKUP);
+ RECORD(EXPR_CXX_EXPRESSION_TRAIT);
RECORD(EXPR_CXX_NOEXCEPT);
RECORD(EXPR_OPAQUE_VALUE);
+ RECORD(EXPR_BINARY_CONDITIONAL_OPERATOR);
+ RECORD(EXPR_TYPE_TRAIT);
+ RECORD(EXPR_ARRAY_TYPE_TRAIT);
RECORD(EXPR_PACK_EXPANSION);
RECORD(EXPR_SIZEOF_PACK);
+ RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM);
RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
+ RECORD(EXPR_FUNCTION_PARM_PACK);
+ RECORD(EXPR_MATERIALIZE_TEMPORARY);
RECORD(EXPR_CUDA_KERNEL_CALL);
+ RECORD(EXPR_CXX_UUIDOF_EXPR);
+ RECORD(EXPR_CXX_UUIDOF_TYPE);
+ RECORD(EXPR_LAMBDA);
#undef RECORD
}
RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
RECORD(TYPE_ATOMIC);
RECORD(DECL_TYPEDEF);
+ RECORD(DECL_TYPEALIAS);
RECORD(DECL_ENUM);
RECORD(DECL_RECORD);
RECORD(DECL_ENUM_CONSTANT);
}
// Enter the submodule description block.
- Stream.EnterSubblock(SUBMODULE_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
+ Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/4);
// Write the abbreviations needed for the submodules block.
using namespace llvm;
// Emit the type's representation.
ASTTypeWriter W(*this, Record);
+ W.AbbrevToUse = 0;
if (T.hasLocalNonFastQualifiers()) {
Qualifiers Qs = T.getLocalQualifiers();
AddTypeRef(T.getLocalUnqualifiedType(), Record);
Record.push_back(Qs.getAsOpaqueValue());
W.Code = TYPE_EXT_QUAL;
+ W.AbbrevToUse = TypeExtQualAbbrev;
} else {
switch (T->getTypeClass()) {
// For all of the concrete, non-dependent types, call the
}
// Emit the serialized record.
- Stream.EmitRecord(W.Code, Record);
+ Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
// Flush any expressions that were written as part of this type.
FlushStmts();
Record.push_back(BucketOffset);
Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
LookupTable.str());
-
- Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);
++NumVisibleDeclContexts;
return Offset;
}
}
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
- : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr),
- WritingModule(nullptr), WritingAST(false), DoneWritingDeclsAndTypes(false),
- ASTHasCompilerErrors(false),
- FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
- FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
- FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
- FirstMacroID(NUM_PREDEF_MACRO_IDS), NextMacroID(FirstMacroID),
- FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS),
- NextSubmoduleID(FirstSubmoduleID),
- FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
- CollectedStmts(&StmtsToEmit),
- NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
- NumVisibleDeclContexts(0),
- NextCXXBaseSpecifiersID(1),
- DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0),
- DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0),
- DeclRefExprAbbrev(0), CharacterLiteralAbbrev(0),
- DeclRecordAbbrev(0), IntegerLiteralAbbrev(0),
- DeclTypedefAbbrev(0),
- DeclVarAbbrev(0), DeclFieldAbbrev(0),
- DeclEnumAbbrev(0), DeclObjCIvarAbbrev(0)
-{
-}
+ : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr),
+ WritingModule(nullptr), WritingAST(false),
+ DoneWritingDeclsAndTypes(false), ASTHasCompilerErrors(false),
+ FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
+ FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
+ FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
+ FirstMacroID(NUM_PREDEF_MACRO_IDS), NextMacroID(FirstMacroID),
+ FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS),
+ NextSubmoduleID(FirstSubmoduleID),
+ FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
+ CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0),
+ NumLexicalDeclContexts(0), NumVisibleDeclContexts(0),
+ NextCXXBaseSpecifiersID(1), TypeExtQualAbbrev(0),
+ TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0),
+ DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0),
+ UpdateVisibleAbbrev(0), DeclRefExprAbbrev(0), CharacterLiteralAbbrev(0),
+ DeclRecordAbbrev(0), IntegerLiteralAbbrev(0), DeclTypedefAbbrev(0),
+ DeclVarAbbrev(0), DeclFieldAbbrev(0), DeclEnumAbbrev(0),
+ DeclObjCIvarAbbrev(0), DeclCXXMethodAbbrev(0) {}
ASTWriter::~ASTWriter() {
llvm::DeleteContainerSeconds(FileDeclIDs);
// Keep writing types, declarations, and declaration update records
// until we've emitted all of them.
- Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
- WriteDeclsBlockAbbrevs();
+ Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5);
+ WriteTypeAbbrevs();
+ WriteDeclAbbrevs();
for (DeclsToRewriteTy::iterator I = DeclsToRewrite.begin(),
E = DeclsToRewrite.end();
I != E; ++I)
VisitTypedefNameDecl(D);
if (!D->hasAttrs() &&
!D->isImplicit() &&
- !D->isUsed(false) &&
D->getFirstDecl() == D->getMostRecentDecl() &&
!D->isInvalidDecl() &&
- !D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
- D->getAccess() == AS_none &&
!D->isModulePrivate() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier)
AbbrevToUse = Writer.getDeclTypedefAbbrev();
void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
VisitRedeclarable(D);
VisitDeclaratorDecl(D);
-
Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
Record.push_back(D->getIdentifierNamespace());
// We only need to record overridden methods once for the canonical decl.
Record.push_back(0);
}
+
+ if (D->getFirstDecl() == D->getMostRecentDecl() &&
+ !D->isInvalidDecl() &&
+ !D->hasAttrs() &&
+ !D->isTopLevelDeclInObjCContainer() &&
+ D->getDeclName().getNameKind() == DeclarationName::Identifier &&
+ !D->hasExtInfo() &&
+ !D->hasInheritedPrototype() &&
+ D->hasWrittenPrototype())
+ AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
+
Code = serialization::DECL_CXX_METHOD;
}
// ASTWriter Implementation
//===----------------------------------------------------------------------===//
-void ASTWriter::WriteDeclsBlockAbbrevs() {
+void ASTWriter::WriteDeclAbbrevs() {
using namespace llvm;
BitCodeAbbrev *Abv;
Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
- Abv->Add(BitCodeAbbrevOp(0)); // isUsed
- Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isUsed
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isReferenced
Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
- Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // C++ AccessSpecifier
Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
// NamedDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
DeclVarAbbrev = Stream.EmitAbbrev(Abv);
+ // Abbreviation for DECL_CXX_METHOD
+ Abv = new BitCodeAbbrev();
+ Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
+ // RedeclarableDecl
+ Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
+ // Decl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
+ Abv->Add(BitCodeAbbrevOp(0)); // Invalid
+ Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Used
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Referenced
+ Abv->Add(BitCodeAbbrevOp(0)); // InObjCContainer
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Access
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModulePrivate
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
+ // NamedDecl
+ Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier
+ // ValueDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // DeclaratorDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart
+ Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo
+ // FunctionDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
+ Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedProto
+ Abv->Add(BitCodeAbbrevOp(1)); // HasWrittenProto
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // DeletedAsWritten
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Trivial
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constexpr
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind
+ // This Array slurps the rest of the record. Fortunately we want to encode
+ // (nearly) all the remaining (variable number of) fields in the same way.
+ //
+ // This is the function template information if any, then
+ // NumParams and Params[] from FunctionDecl, and
+ // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
+ //
+ // Add an AbbrevOp for 'size then elements' and use it here.
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ DeclCXXMethodAbbrev = Stream.EmitAbbrev(Abv);
+
// Abbreviation for EXPR_DECL_REF
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));