add PCH support for a bunch of C++ Decls, patch by

Andrew Sutton!

llvm-svn: 103301
This commit is contained in:
Chris Lattner 2010-05-07 21:43:38 +00:00
parent 2c4d69d7ad
commit ca025db769
14 changed files with 869 additions and 52 deletions

View File

@ -267,18 +267,25 @@ public:
// \brief Returns true if this is an anonymous namespace declaration.
//
// For example:
/// \code
// namespace {
// ...
// };
// \endcode
// q.v. C++ [namespace.unnamed]
bool isAnonymousNamespace() const {
return !getIdentifier();
}
/// \brief Return the next extended namespace declaration or null if this
/// is none.
NamespaceDecl *getNextNamespace() { return NextNamespace; }
const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
/// \brief Set the next extended namespace declaration.
void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
/// \brief Get the original (first) namespace declaration.
NamespaceDecl *getOriginalNamespace() const {
if (OrigOrAnonNamespace.getInt())
return const_cast<NamespaceDecl *>(this);
@ -286,6 +293,14 @@ public:
return OrigOrAnonNamespace.getPointer();
}
/// \brief Return true if this declaration is an original (first) declaration
/// of the namespace. This is false for non-original (subsequent) namespace
/// declarations and anonymous namespaces.
bool isOriginalNamespace() const {
return getOriginalNamespace() == this;
}
/// \brief Set the original (first) namespace declaration.
void setOriginalNamespace(NamespaceDecl *ND) {
if (ND != this) {
OrigOrAnonNamespace.setPointer(ND);

View File

@ -76,6 +76,11 @@ public:
#include "clang/AST/DeclNodes.def"
};
/// \brief A placeholder type used to construct an empty shell of a
/// decl-derived type that will be filled in later (e.g., by some
/// deserialization method).
struct EmptyShell { };
/// IdentifierNamespace - The different namespaces in which
/// declarations may appear. According to C99 6.2.3, there are
/// four namespaces, labels, tags, members and ordinary

View File

@ -1244,6 +1244,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
virtual void Destroy(ASTContext& C);
public:
static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
@ -1386,6 +1387,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
}
public:
static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, bool isInline,
@ -1441,6 +1443,7 @@ class CXXConversionDecl : public CXXMethodDecl {
IsExplicitSpecified(isExplicitSpecified) { }
public:
static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
@ -1481,8 +1484,10 @@ public:
/// ASTs and cannot be changed without altering that abi. To help
/// ensure a stable abi for this, we choose the DW_LANG_ encodings
/// from the dwarf standard.
enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002,
lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 };
enum LanguageIDs {
lang_c = /* DW_LANG_C */ 0x0002,
lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
};
private:
/// Language - The language for this linkage specification.
LanguageIDs Language;
@ -1500,12 +1505,20 @@ public:
SourceLocation L, LanguageIDs Lang,
bool Braces);
/// \brief Return the language specified by this linkage specification.
LanguageIDs getLanguage() const { return Language; }
/// hasBraces - Determines whether this linkage specification had
/// braces in its syntactic form.
/// \brief Set the language specified by this linkage specification.
void setLanguage(LanguageIDs L) { Language = L; }
/// \brief Determines whether this linkage specification had braces in
/// its syntactic form.
bool hasBraces() const { return HadBraces; }
/// \brief Set whether this linkage specification has braces in its
/// syntactic form.
void setHasBraces(bool B) { HadBraces = B; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LinkageSpecDecl *D) { return true; }
static bool classofKind(Kind K) { return K == LinkageSpec; }
@ -1571,13 +1584,21 @@ class UsingDirectiveDecl : public NamedDecl {
public:
/// \brief Retrieve the source range of the nested-name-specifier
/// that qualifiers the namespace name.
/// that qualifies the namespace name.
SourceRange getQualifierRange() const { return QualifierRange; }
/// \brief Set the source range of the nested-name-specifier that
/// qualifies the namespace name.
void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
/// \brief Set the nested-name-specifier that qualifes the name of the
/// namespace.
void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
const NamedDecl *getNominatedNamespaceAsWritten() const {
return NominatedNamespace;
@ -1590,17 +1611,32 @@ public:
return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
}
/// getCommonAncestor - returns common ancestor context of using-directive,
/// and nominated by it namespace.
/// setNominatedNamespace - Set the namespace nominataed by the
/// using-directive.
void setNominatedNamespace(NamedDecl* NS);
/// \brief Returns the common ancestor context of this using-directive and
/// its nominated namespace.
DeclContext *getCommonAncestor() { return CommonAncestor; }
const DeclContext *getCommonAncestor() const { return CommonAncestor; }
/// \brief Set the common ancestor context of this using-directive and its
/// nominated namespace.
void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; }
// FIXME: Could omit 'Key' in name.
/// getNamespaceKeyLocation - Returns location of namespace keyword.
SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
/// setNamespaceKeyLocation - Set the the location of the namespacekeyword.
void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; }
/// getIdentLocation - Returns location of identifier.
SourceLocation getIdentLocation() const { return IdentLoc; }
/// setIdentLocation - set the location of the identifier.
void setIdentLocation(SourceLocation L) { IdentLoc = L; }
static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
SourceLocation NamespaceLoc,
@ -1634,7 +1670,7 @@ class NamespaceAliasDecl : public NamedDecl {
/// name, if any.
NestedNameSpecifier *Qualifier;
/// IdentLoc - Location of namespace identifier.
/// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
SourceLocation IdentLoc;
/// Namespace - The Decl that this alias points to. Can either be a
@ -1655,10 +1691,19 @@ public:
/// that qualifiers the namespace name.
SourceRange getQualifierRange() const { return QualifierRange; }
/// \brief Set the source range of the nested-name-specifier that qualifies
/// the namespace name.
void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
/// \brief Set the nested-name-specifier that qualifies the name of the
/// namespace.
void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
/// \brief Retrieve the namespace declaration aliased by this directive.
NamespaceDecl *getNamespace() {
if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
return AD->getNamespace();
@ -1674,16 +1719,31 @@ public:
/// "namespace foo = ns::bar;".
SourceLocation getAliasLoc() const { return AliasLoc; }
/// Set the location o;f the alias name, e.e., 'foo' in
/// "namespace foo = ns::bar;".
void setAliasLoc(SourceLocation L) { AliasLoc = L; }
/// Returns the location of the 'namespace' keyword.
SourceLocation getNamespaceLoc() const { return getLocation(); }
/// Returns the location of the identifier in the named namespace.
SourceLocation getTargetNameLoc() const { return IdentLoc; }
/// Set the location of the identifier in the named namespace.
void setTargetNameLoc(SourceLocation L) { IdentLoc = L; }
/// \brief Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
/// \brief Set the namespace or namespace alias pointed to by this
/// alias decl.
void setAliasedNamespace(NamedDecl *ND) {
assert((isa<NamespaceAliasDecl>(ND) || isa<NamespaceDecl>(ND)) &&
"expecting namespace or namespace alias decl");
Namespace = ND;
}
static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, SourceLocation AliasLoc,
IdentifierInfo *Alias,
@ -1730,16 +1790,20 @@ public:
return new (C) UsingShadowDecl(DC, Loc, Using, Target);
}
/// Gets the underlying declaration which has been brought into the
/// \brief Gets the underlying declaration which has been brought into the
/// local scope.
NamedDecl *getTargetDecl() const {
return Underlying;
}
NamedDecl *getTargetDecl() const { return Underlying; }
/// Gets the using declaration to which this declaration is tied.
UsingDecl *getUsingDecl() const {
return Using;
}
/// \brief Sets the underlying declaration which has been brought into the
/// local scope.
void setTargetDecl(NamedDecl* ND) { Underlying = ND; }
/// \brief Gets the using declaration to which this declaration is tied.
UsingDecl *getUsingDecl() const { return Using; }
/// \brief Sets the using declaration that introduces this target
/// declaration.
void setUsingDecl(UsingDecl* UD) { Using = UD; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingShadowDecl *D) { return true; }
@ -1776,21 +1840,39 @@ class UsingDecl : public NamedDecl {
}
public:
// FIXME: Should be const?
/// \brief Returns the source range that covers the nested-name-specifier
/// preceding the namespace name.
SourceRange getNestedNameRange() { return NestedNameRange; }
/// \brief Returns the source location of the "using" location itself.
/// \brief Set the source range of the nested-name-specifier.
void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
// FIXME; Should be const?
// FIXME: Naming is inconsistent with other get*Loc functions.
/// \brief Returns the source location of the "using" keyword.
SourceLocation getUsingLocation() { return UsingLocation; }
/// \brief Get target nested name declaration.
/// \brief Set the source location of the 'using' keyword.
void setUsingLocation(SourceLocation L) { UsingLocation = L; }
/// \brief Get the target nested name declaration.
NestedNameSpecifier* getTargetNestedNameDecl() {
return TargetNestedName;
}
/// isTypeName - Return true if using decl has 'typename'.
/// \brief Set the target nested name declaration.
void setTargetNestedNameDecl(NestedNameSpecifier *NNS) {
TargetNestedName = NNS;
}
/// \brief Return true if the using declaration has 'typename'.
bool isTypeName() const { return IsTypeName; }
/// \brief Sets whether the using declaration has 'typename'.
void setTypeName(bool TN) { IsTypeName = TN; }
typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
shadow_iterator shadow_begin() const { return Shadows.begin(); }
shadow_iterator shadow_end() const { return Shadows.end(); }
@ -1808,6 +1890,12 @@ public:
}
}
/// \brief Return the number of shadowed declarations associated with this
/// using declaration.
unsigned getNumShadowDecls() const {
return Shadows.size();
}
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
@ -1850,14 +1938,26 @@ public:
/// preceding the namespace name.
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
/// \brief Set the source range coverting the nested-name-specifier preceding
/// the namespace name.
void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameSpecifier() {
return TargetNestedNameSpecifier;
}
/// \brief Set the nested name declaration.
void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
TargetNestedNameSpecifier = NNS;
}
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
/// \brief Set the source location of the 'using' keyword.
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
static UnresolvedUsingValueDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
@ -1904,17 +2004,32 @@ public:
/// preceding the namespace name.
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
/// \brief Set the source range coverting the nested-name-specifier preceding
/// the namespace name.
void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameSpecifier() {
return TargetNestedNameSpecifier;
}
/// \brief Set the nested name declaration.
void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
TargetNestedNameSpecifier = NNS;
}
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
/// \brief Set the source location of the 'using' keyword.
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
/// \brief Returns the source location of the 'typename' keyword.
SourceLocation getTypenameLoc() const { return TypenameLocation; }
/// \brief Set the source location of the 'typename' keyword.
void setTypenameLoc(SourceLocation L) { TypenameLocation = L; }
static UnresolvedUsingTypenameDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceLocation TypenameLoc,

View File

@ -534,8 +534,46 @@ namespace clang {
/// IDs. This data is used when performing qualified name lookup
/// into a DeclContext via DeclContext::lookup.
DECL_CONTEXT_VISIBLE,
/// \brief A NamespaceDecl record.
DECL_NAMESPACE
/// \brief A NamespaceDecl rcord.
DECL_NAMESPACE,
/// \brief A NamespaceAliasDecl record.
DECL_NAMESPACE_ALIAS,
/// \brief A UsingDecl record.
DECL_USING,
/// \brief A UsingShadowDecl record.
DECL_USING_SHADOW,
/// \brief A UsingDirecitveDecl record.
DECL_USING_DIRECTIVE,
/// \brief An UnresolvedUsingValueDecl record.
DECL_UNRESOLVED_USING_VALUE,
/// \brief An UnresolvedUsingTypenameDecl record.
DECL_UNRESOLVED_USING_TYPENAME,
/// \brief A LinkageSpecDecl record.
DECL_LINKAGE_SPEC,
/// \brief A CXXRecordDecl record.
DECL_CXX_RECORD,
/// \brief A CXXMethodDecl record.
DECL_CXX_METHOD,
/// \brief A CXXConstructorDecl record.
DECL_CXX_CONSTRUCTOR,
/// \brief A CXXDestructorDecl record.
DECL_CXX_DESTRUCTOR,
/// \brief A CXXConversionDecl record.
DECL_CXX_CONVERSION,
// FIXME: Implement serialization for these decl types. This just
// allocates the order in which
DECL_FRIEND,
DECL_FRIEND_TEMPLATE,
DECL_TEMPLATE,
DECL_CLASS_TEMPLATE,
DECL_CLASS_TEMPLATE_SPECIALIZATION,
DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
DECL_FUNCTION_TEMPLATE,
DECL_TEMPLATE_TYPE_PARM,
DECL_NON_TYPE_TEMPLATE_PARM,
DECL_TEMPLATE_TEMPLATE_PARM,
DECL_STATIC_ASSERT
};
/// \brief Record codes for each kind of statement or expression.

View File

@ -52,6 +52,9 @@ class ASTContext;
class Attr;
class Decl;
class DeclContext;
class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXBaseOrMemberInitializer;
class GotoStmt;
class LabelStmt;
class MacroDefinition;
@ -694,8 +697,21 @@ public:
Selector GetSelector(const RecordData &Record, unsigned &Idx) {
return DecodeSelector(Record[Idx++]);
}
/// \brief Read a declaration name.
DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx);
NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
unsigned &Idx);
/// \brief Read a source location.
SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
return SourceLocation::getFromRawEncoding(Record[Idx++]);
}
/// \brief Read a source range.
SourceRange ReadSourceRange(const RecordData &Record, unsigned& Idx);
/// \brief Read an integral value
llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);

View File

@ -32,6 +32,9 @@ namespace llvm {
namespace clang {
class ASTContext;
class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXBaseOrMemberInitializer;
class LabelStmt;
class MacroDefinition;
class MemorizeStatCalls;
@ -251,6 +254,9 @@ public:
/// \brief Emit a source location.
void AddSourceLocation(SourceLocation Loc, RecordData &Record);
/// \brief Emit a source range.
void AddSourceRange(SourceRange Range, RecordData &Record);
/// \brief Emit an integral value.
void AddAPInt(const llvm::APInt &Value, RecordData &Record);
@ -304,6 +310,9 @@ public:
/// \brief Emit a declaration name.
void AddDeclarationName(DeclarationName Name, RecordData &Record);
/// \brief Emit a nested name specifier.
void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record);
/// \brief Add a string to the given record.
void AddString(const std::string &Str, RecordData &Record);

View File

@ -784,6 +784,12 @@ SourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
return SourceRange(getSourceLocation(), getRParenLoc());
}
CXXConstructorDecl *
CXXConstructorDecl::Create(ASTContext &C, EmptyShell Empty) {
return new (C) CXXConstructorDecl(0, SourceLocation(), DeclarationName(),
QualType(), 0, false, false, false);
}
CXXConstructorDecl *
CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@ -886,6 +892,12 @@ bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {
return true;
}
CXXDestructorDecl *
CXXDestructorDecl::Create(ASTContext &C, EmptyShell Empty) {
return new (C) CXXDestructorDecl(0, SourceLocation(), DeclarationName(),
QualType(), false, false);
}
CXXDestructorDecl *
CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@ -902,6 +914,12 @@ CXXConstructorDecl::Destroy(ASTContext& C) {
CXXMethodDecl::Destroy(C);
}
CXXConversionDecl *
CXXConversionDecl::Create(ASTContext &C, EmptyShell Empty) {
return new (C) CXXConversionDecl(0, SourceLocation(), DeclarationName(),
QualType(), 0, false, false);
}
CXXConversionDecl *
CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@ -940,6 +958,12 @@ NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
return cast_or_null<NamespaceDecl>(NominatedNamespace);
}
void UsingDirectiveDecl::setNominatedNamespace(NamedDecl* ND) {
assert((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
"expected a NamespaceDecl or NamespaceAliasDecl");
NominatedNamespace = ND;
}
NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
SourceLocation AliasLoc,

View File

@ -2901,6 +2901,51 @@ PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
return DeclarationName();
}
NestedNameSpecifier *
PCHReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
unsigned N = Record[Idx++];
NestedNameSpecifier *NNS = 0, *Prev = 0;
for (unsigned I = 0; I != N; ++I) {
NestedNameSpecifier::SpecifierKind Kind
= (NestedNameSpecifier::SpecifierKind)Record[Idx++];
switch (Kind) {
case NestedNameSpecifier::Identifier: {
IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
NNS = NestedNameSpecifier::Create(*Context, Prev, II);
break;
}
case NestedNameSpecifier::Namespace: {
NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
break;
}
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
Type *T = GetType(Record[Idx++]).getTypePtr();
bool Template = Record[Idx++];
NNS = NestedNameSpecifier::Create(*Context, Prev, Template, T);
break;
}
case NestedNameSpecifier::Global: {
NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
// No associated value, and there can't be a prefix.
break;
}
Prev = NNS;
}
}
return NNS;
}
SourceRange
PCHReader::ReadSourceRange(const RecordData &Record, unsigned &Idx) {
return SourceRange(SourceLocation::getFromRawEncoding(Record[Idx++]),
SourceLocation::getFromRawEncoding(Record[Idx++]));
}
/// \brief Read an integral value
llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
unsigned BitWidth = Record[Idx++];

View File

@ -17,6 +17,8 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
using namespace clang;
@ -40,22 +42,49 @@ namespace {
void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
void VisitNamedDecl(NamedDecl *ND);
void VisitNamespaceDecl(NamespaceDecl *D);
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
void VisitTypeDecl(TypeDecl *TD);
void VisitTypedefDecl(TypedefDecl *TD);
void VisitUnresolvedUsingTypename(UnresolvedUsingTypenameDecl *D);
void VisitTagDecl(TagDecl *TD);
void VisitEnumDecl(EnumDecl *ED);
void VisitRecordDecl(RecordDecl *RD);
void VisitCXXRecordDecl(CXXRecordDecl *D);
void VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D);
void VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D);
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
void VisitValueDecl(ValueDecl *VD);
void VisitEnumConstantDecl(EnumConstantDecl *ECD);
void VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D);
void VisitDeclaratorDecl(DeclaratorDecl *DD);
void VisitFunctionDecl(FunctionDecl *FD);
void VisitCXXMethodDecl(CXXMethodDecl *D);
void VisitCXXConstructorDecl(CXXConstructorDecl *D);
void VisitCXXDestructorDecl(CXXDestructorDecl *D);
void VisitCXXConversionDecl(CXXConversionDecl *D);
void VisitFieldDecl(FieldDecl *FD);
void VisitVarDecl(VarDecl *VD);
void VisitImplicitParamDecl(ImplicitParamDecl *PD);
void VisitParmVarDecl(ParmVarDecl *PD);
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
void visitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
void VisitUsing(UsingDecl *D);
void VisitUsingShadow(UsingShadowDecl *D);
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
void VisitStaticAssertDecl(StaticAssertDecl *D);
void VisitBlockDecl(BlockDecl *BD);
std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
// FIXME: Reorder according to DeclNodes.def?
void VisitObjCMethodDecl(ObjCMethodDecl *D);
void VisitObjCContainerDecl(ObjCContainerDecl *D);
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
@ -90,6 +119,8 @@ void PCHDeclReader::VisitDecl(Decl *D) {
void PCHDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
VisitDecl(TU);
TU->setAnonymousNamespace(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
}
void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
@ -97,18 +128,6 @@ void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
}
void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
VisitNamedDecl(D);
D->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
D->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
D->setNextNamespace(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
D->setOriginalNamespace(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
D->setAnonymousNamespace(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
}
void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
VisitNamedDecl(TD);
TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
@ -193,6 +212,8 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setHasImplicitReturnZero(Record[Idx++]);
FD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
// FIXME: C++ TemplateOrInstantiation
// Read in the parameters.
unsigned NumParams = Record[Idx++];
llvm::SmallVector<ParmVarDecl *, 16> Params;
Params.reserve(NumParams);
@ -446,6 +467,155 @@ void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {
BD->setParams(Params.data(), NumParams);
}
void PCHDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
VisitDecl(D);
D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]);
D->setHasBraces(Record[Idx++]);
}
void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
VisitNamedDecl(D);
D->setLBracLoc(Reader.ReadSourceLocation(Record, Idx));
D->setRBracLoc(Reader.ReadSourceLocation(Record, Idx));
D->setNextNamespace(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
// Only read one reference--the original or anonymous namespace.
bool IsOriginal = Record[Idx++];
if (IsOriginal)
D->setAnonymousNamespace(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
else
D->setOriginalNamespace(
cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
}
void PCHDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
VisitNamedDecl(D);
D->setAliasLoc(Reader.ReadSourceLocation(Record, Idx));
D->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
D->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
D->setTargetNameLoc(Reader.ReadSourceLocation(Record, Idx));
D->setAliasedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
}
void PCHDeclReader::VisitUsing(UsingDecl *D) {
VisitNamedDecl(D);
D->setUsingLocation(Reader.ReadSourceLocation(Record, Idx));
D->setNestedNameRange(Reader.ReadSourceRange(Record, Idx));
D->setTargetNestedNameDecl(Reader.ReadNestedNameSpecifier(Record, Idx));
// FIXME: It would probably be more efficient to read these into a vector
// and then re-cosntruct the shadow decl set over that vector since it
// would avoid existence checks.
unsigned NumShadows = Record[Idx++];
for(unsigned I = 0; I != NumShadows; ++I) {
D->addShadowDecl(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])));
}
D->setTypeName(Record[Idx++]);
}
void PCHDeclReader::VisitUsingShadow(UsingShadowDecl *D) {
VisitNamedDecl(D);
D->setTargetDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
D->setUsingDecl(cast<UsingDecl>(Reader.GetDecl(Record[Idx++])));
}
void PCHDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
VisitNamedDecl(D);
D->setNamespaceKeyLocation(Reader.ReadSourceLocation(Record, Idx));
D->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
D->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
D->setIdentLocation(Reader.ReadSourceLocation(Record, Idx));
D->setNominatedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
D->setCommonAncestor(cast_or_null<DeclContext>(
Reader.GetDecl(Record[Idx++])));
}
void PCHDeclReader::VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D) {
VisitValueDecl(D);
D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));
D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx));
D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
}
void PCHDeclReader::VisitUnresolvedUsingTypename(
UnresolvedUsingTypenameDecl *D) {
VisitTypeDecl(D);
D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));
D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx));
D->setTypenameLoc(Reader.ReadSourceLocation(Record, Idx));
D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
}
void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
// assert(false && "cannot read CXXRecordDecl");
VisitRecordDecl(D);
}
void PCHDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
// assert(false && "cannot read CXXMethodDecl");
VisitFunctionDecl(D);
}
void PCHDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
// assert(false && "cannot read CXXConstructorDecl");
VisitCXXMethodDecl(D);
}
void PCHDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
// assert(false && "cannot read CXXDestructorDecl");
VisitCXXMethodDecl(D);
}
void PCHDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
// assert(false && "cannot read CXXConversionDecl");
VisitCXXMethodDecl(D);
}
void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
assert(false && "cannot read FriendTemplateDecl");
}
void PCHDeclReader::VisitTemplateDecl(TemplateDecl *D) {
assert(false && "cannot read TemplateDecl");
}
void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
assert(false && "cannot read ClassTemplateDecl");
}
void PCHDeclReader::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
assert(false && "cannot read ClassTemplateSpecializationDecl");
}
void PCHDeclReader::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
}
void PCHDeclReader::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
assert(false && "cannot read FunctionTemplateDecl");
}
void PCHDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
assert(false && "cannot read TemplateTypeParmDecl");
}
void PCHDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
assert(false && "cannot read NonTypeTemplateParmDecl");
}
void PCHDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
assert(false && "cannot read TemplateTemplateParmDecl");
}
void PCHDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
assert(false && "cannot read StaticAssertDecl");
}
std::pair<uint64_t, uint64_t>
PCHDeclReader::VisitDeclContext(DeclContext *DC) {
uint64_t LexicalOffset = Record[Idx++];
@ -706,6 +876,94 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
D = FunctionDecl::Create(*Context, 0, SourceLocation(), DeclarationName(),
QualType(), 0);
break;
case pch::DECL_LINKAGE_SPEC:
D = LinkageSpecDecl::Create(*Context, 0, SourceLocation(),
(LinkageSpecDecl::LanguageIDs)0,
false);
break;
case pch::DECL_NAMESPACE:
D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
break;
case pch::DECL_NAMESPACE_ALIAS:
D = NamespaceAliasDecl::Create(*Context, 0, SourceLocation(),
SourceLocation(), 0, SourceRange(), 0,
SourceLocation(), 0);
break;
case pch::DECL_USING:
D = UsingDecl::Create(*Context, 0, SourceLocation(), SourceRange(),
SourceLocation(), 0, DeclarationName(), false);
break;
case pch::DECL_USING_SHADOW:
D = UsingShadowDecl::Create(*Context, 0, SourceLocation(), 0, 0);
break;
case pch::DECL_USING_DIRECTIVE:
D = UsingDirectiveDecl::Create(*Context, 0, SourceLocation(),
SourceLocation(), SourceRange(), 0,
SourceLocation(), 0, 0);
break;
case pch::DECL_UNRESOLVED_USING_VALUE:
D = UnresolvedUsingValueDecl::Create(*Context, 0, SourceLocation(),
SourceRange(), 0, SourceLocation(),
DeclarationName());
break;
case pch::DECL_UNRESOLVED_USING_TYPENAME:
D = UnresolvedUsingTypenameDecl::Create(*Context, 0, SourceLocation(),
SourceLocation(), SourceRange(),
0, SourceLocation(),
DeclarationName());
break;
case pch::DECL_CXX_RECORD:
D = CXXRecordDecl::Create(*Context, TagDecl::TK_struct, 0,
SourceLocation(), 0, SourceLocation(), 0);
break;
case pch::DECL_CXX_METHOD:
D = CXXMethodDecl::Create(*Context, 0, SourceLocation(), DeclarationName(),
QualType(), 0);
break;
case pch::DECL_CXX_CONSTRUCTOR:
D = CXXConstructorDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_CXX_DESTRUCTOR:
D = CXXDestructorDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_CXX_CONVERSION:
D = CXXConversionDecl::Create(*Context, Decl::EmptyShell());
break;
case pch::DECL_FRIEND:
assert(false && "cannot read FriendDecl");
break;
case pch::DECL_FRIEND_TEMPLATE:
assert(false && "cannot read FriendTemplateDecl");
break;
case pch::DECL_TEMPLATE:
// FIXME: Should TemplateDecl be ABSTRACT_DECL???
assert(false && "TemplateDecl should be abstract!");
break;
case pch::DECL_CLASS_TEMPLATE:
assert(false && "cannot read ClassTemplateDecl");
break;
case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION:
assert(false && "cannot read ClasstemplateSpecializationDecl");
break;
case pch::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
assert(false && "cannot read ClassTemplatePartialSpecializationDecl");
break;
case pch::DECL_FUNCTION_TEMPLATE:
assert(false && "cannot read FunctionTemplateDecl");
break;
case pch::DECL_TEMPLATE_TYPE_PARM:
assert(false && "cannot read TemplateTypeParmDecl");
break;
case pch::DECL_NON_TYPE_TEMPLATE_PARM:
assert(false && "cannot read NonTypeTemplateParmDecl");
break;
case pch::DECL_TEMPLATE_TEMPLATE_PARM:
assert(false && "cannot read TemplateTemplateParmDecl");
break;
case pch::DECL_STATIC_ASSERT:
assert(false && "cannot read StaticAssertDecl");
break;
case pch::DECL_OBJC_METHOD:
D = ObjCMethodDecl::Create(*Context, SourceLocation(), SourceLocation(),
Selector(), QualType(), 0, 0);
@ -775,10 +1033,6 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
case pch::DECL_BLOCK:
D = BlockDecl::Create(*Context, 0, SourceLocation());
break;
case pch::DECL_NAMESPACE:
D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
break;
}
assert(D && "Unknown declaration reading PCH file");

View File

@ -2181,6 +2181,11 @@ void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
Record.push_back(Loc.getRawEncoding());
}
void PCHWriter::AddSourceRange(SourceRange Range, RecordData &Record) {
AddSourceLocation(Range.getBegin(), Record);
AddSourceLocation(Range.getEnd(), Record);
}
void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
Record.push_back(Value.getBitWidth());
unsigned N = Value.getNumWords();
@ -2407,3 +2412,42 @@ void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
break;
}
}
void PCHWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
RecordData &Record) {
// Nested name specifiers usually aren't too long. I think that 8 would
// typically accomodate the vast majority.
llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames;
// Push each of the NNS's onto a stack for serialization in reverse order.
while (NNS) {
NestedNames.push_back(NNS);
NNS = NNS->getPrefix();
}
Record.push_back(NestedNames.size());
while(!NestedNames.empty()) {
NNS = NestedNames.pop_back_val();
NestedNameSpecifier::SpecifierKind Kind = NNS->getKind();
Record.push_back(Kind);
switch (Kind) {
case NestedNameSpecifier::Identifier:
AddIdentifierRef(NNS->getAsIdentifier(), Record);
break;
case NestedNameSpecifier::Namespace:
AddDeclRef(NNS->getAsNamespace(), Record);
break;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
AddTypeRef(QualType(NNS->getAsType(), 0), Record);
Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
break;
case NestedNameSpecifier::Global:
// Don't need to write an associated value.
break;
}
}
}

View File

@ -13,6 +13,8 @@
#include "clang/Frontend/PCHWriter.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitstreamWriter.h"
@ -43,23 +45,51 @@ namespace {
void VisitTranslationUnitDecl(TranslationUnitDecl *D);
void VisitNamedDecl(NamedDecl *D);
void VisitNamespaceDecl(NamespaceDecl *D);
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
void VisitTypeDecl(TypeDecl *D);
void VisitTypedefDecl(TypedefDecl *D);
void VisitUnresolvedUsingTypename(UnresolvedUsingTypenameDecl *D);
void VisitTagDecl(TagDecl *D);
void VisitEnumDecl(EnumDecl *D);
void VisitRecordDecl(RecordDecl *D);
void VisitCXXRecordDecl(CXXRecordDecl *D);
void VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D);
void VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D);
void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
void VisitValueDecl(ValueDecl *D);
void VisitEnumConstantDecl(EnumConstantDecl *D);
void VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D);
void VisitDeclaratorDecl(DeclaratorDecl *D);
void VisitFunctionDecl(FunctionDecl *D);
void VisitCXXMethodDecl(CXXMethodDecl *D);
void VisitCXXConstructorDecl(CXXConstructorDecl *D);
void VisitCXXDestructorDecl(CXXDestructorDecl *D);
void VisitCXXConversionDecl(CXXConversionDecl *D);
void VisitFieldDecl(FieldDecl *D);
void VisitVarDecl(VarDecl *D);
void VisitImplicitParamDecl(ImplicitParamDecl *D);
void VisitParmVarDecl(ParmVarDecl *D);
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
void visitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
void VisitUsing(UsingDecl *D);
void VisitUsingShadow(UsingShadowDecl *D);
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
void VisitStaticAssertDecl(StaticAssertDecl *D);
void VisitBlockDecl(BlockDecl *D);
void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
uint64_t VisibleOffset);
// FIXME: Put in the same order is DeclNodes.def?
void VisitObjCMethodDecl(ObjCMethodDecl *D);
void VisitObjCContainerDecl(ObjCContainerDecl *D);
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
@ -92,6 +122,7 @@ void PCHDeclWriter::VisitDecl(Decl *D) {
void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
VisitDecl(D);
Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
Code = pch::DECL_TRANSLATION_UNIT;
}
@ -100,16 +131,6 @@ void PCHDeclWriter::VisitNamedDecl(NamedDecl *D) {
Writer.AddDeclarationName(D->getDeclName(), Record);
}
void PCHDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
VisitNamedDecl(D);
Writer.AddSourceLocation(D->getLBracLoc(), Record);
Writer.AddSourceLocation(D->getRBracLoc(), Record);
Writer.AddDeclRef(D->getNextNamespace(), Record);
Writer.AddDeclRef(D->getOriginalNamespace(), Record);
Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
Code = pch::DECL_NAMESPACE;
}
void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
VisitNamedDecl(D);
Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
@ -173,9 +194,11 @@ void PCHDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
VisitDeclaratorDecl(D);
Record.push_back(D->isThisDeclarationADefinition());
if (D->isThisDeclarationADefinition())
Writer.AddStmt(D->getBody());
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Record.push_back(D->getStorageClassAsWritten());
@ -188,8 +211,9 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->isTrivial());
Record.push_back(D->isCopyAssignment());
Record.push_back(D->hasImplicitReturnZero());
// FIXME: C++ TemplateOrInstantiation???
Writer.AddSourceLocation(D->getLocEnd(), Record);
// FIXME: C++ TemplateOrInstantiation
Record.push_back(D->param_size());
for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
P != PEnd; ++P)
@ -227,9 +251,7 @@ void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
void PCHDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
VisitNamedDecl(D);
SourceRange R = D->getAtEndRange();
Writer.AddSourceLocation(R.getBegin(), Record);
Writer.AddSourceLocation(R.getEnd(), Record);
Writer.AddSourceRange(D->getAtEndRange(), Record);
// Abstract class (no need to define a stable pch::DECL code).
}
@ -411,7 +433,6 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
Record.push_back(D->hasInheritedDefaultArg());
Code = pch::DECL_PARM_VAR;
// If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here
// we dynamically check for the properties that we optimize for, but don't
// know are true of all PARM_VAR_DECLs.
@ -454,6 +475,161 @@ void PCHDeclWriter::VisitBlockDecl(BlockDecl *D) {
Code = pch::DECL_BLOCK;
}
void PCHDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
VisitDecl(D);
// FIXME: It might be nice to serialize the brace locations for this
// declaration, which don't seem to be readily available in the AST.
Record.push_back(D->getLanguage());
Record.push_back(D->hasBraces());
Code = pch::DECL_LINKAGE_SPEC;
}
void PCHDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
VisitNamedDecl(D);
Writer.AddSourceLocation(D->getLBracLoc(), Record);
Writer.AddSourceLocation(D->getRBracLoc(), Record);
Writer.AddDeclRef(D->getNextNamespace(), Record);
// Only write one reference--original or anonymous
Record.push_back(D->isOriginalNamespace());
if (D->isOriginalNamespace())
Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
else
Writer.AddDeclRef(D->getOriginalNamespace(), Record);
Code = pch::DECL_NAMESPACE;
}
void PCHDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
VisitNamedDecl(D);
Writer.AddSourceLocation(D->getAliasLoc(), Record);
Writer.AddSourceRange(D->getQualifierRange(), Record);
Writer.AddNestedNameSpecifier(D->getQualifier(), Record);
Writer.AddSourceLocation(D->getTargetNameLoc(), Record);
Writer.AddDeclRef(D->getNamespace(), Record);
Code = pch::DECL_NAMESPACE_ALIAS;
}
void PCHDeclWriter::VisitUsing(UsingDecl *D) {
VisitNamedDecl(D);
Writer.AddSourceRange(D->getNestedNameRange(), Record);
Writer.AddSourceLocation(D->getUsingLocation(), Record);
Writer.AddNestedNameSpecifier(D->getTargetNestedNameDecl(), Record);
Record.push_back(D->getNumShadowDecls());
for (UsingDecl::shadow_iterator P = D->shadow_begin(),
PEnd = D->shadow_end(); P != PEnd; ++P)
Writer.AddDeclRef(*P, Record);
Record.push_back(D->isTypeName());
Code = pch::DECL_USING;
}
void PCHDeclWriter::VisitUsingShadow(UsingShadowDecl *D) {
VisitNamedDecl(D);
Writer.AddDeclRef(D->getTargetDecl(), Record);
Writer.AddDeclRef(D->getUsingDecl(), Record);
Code = pch::DECL_USING_SHADOW;
}
void PCHDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
VisitNamedDecl(D);
Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record);
Writer.AddSourceRange(D->getQualifierRange(), Record);
Writer.AddNestedNameSpecifier(D->getQualifier(), Record);
Writer.AddSourceLocation(D->getIdentLocation(), Record);
Writer.AddDeclRef(D->getNominatedNamespace(), Record);
Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record);
Code = pch::DECL_USING_DIRECTIVE;
}
void PCHDeclWriter::VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D) {
VisitValueDecl(D);
Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
Writer.AddSourceLocation(D->getUsingLoc(), Record);
Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
Code = pch::DECL_UNRESOLVED_USING_VALUE;
}
void PCHDeclWriter::VisitUnresolvedUsingTypename(
UnresolvedUsingTypenameDecl *D) {
VisitTypeDecl(D);
Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
Writer.AddSourceLocation(D->getUsingLoc(), Record);
Writer.AddSourceLocation(D->getTypenameLoc(), Record);
Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
Code = pch::DECL_UNRESOLVED_USING_TYPENAME;
}
void PCHDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
// assert(false && "cannot write CXXRecordDecl");
VisitRecordDecl(D);
Code = pch::DECL_CXX_RECORD;
}
void PCHDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
// assert(false && "cannot write CXXMethodDecl");
VisitFunctionDecl(D);
Code = pch::DECL_CXX_METHOD;
}
void PCHDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
// assert(false && "cannot write CXXConstructorDecl");
VisitCXXMethodDecl(D);
Code = pch::DECL_CXX_CONSTRUCTOR;
}
void PCHDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
// assert(false && "cannot write CXXDestructorDecl");
VisitCXXMethodDecl(D);
Code = pch::DECL_CXX_DESTRUCTOR;
}
void PCHDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
// assert(false && "cannot write CXXConversionDecl");
VisitCXXMethodDecl(D);
Code = pch::DECL_CXX_CONVERSION;
}
void PCHDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
assert(false && "cannot write FriendTemplateDecl");
}
void PCHDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
assert(false && "cannot write TemplateDecl");
}
void PCHDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
assert(false && "cannot write ClassTemplateDecl");
}
void PCHDeclWriter::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
assert(false && "cannot write ClassTemplateSpecializationDecl");
}
void PCHDeclWriter::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
assert(false && "cannot write ClassTemplatePartialSpecializationDecl");
}
void PCHDeclWriter::visitFunctionTemplateDecl(FunctionTemplateDecl *D) {
assert(false && "cannot write FunctionTemplateDecl");
}
void PCHDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
assert(false && "cannot write TemplateTypeParmDecl");
}
void PCHDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
assert(false && "cannot write NonTypeTemplateParmDecl");
}
void PCHDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
assert(false && "cannot write TemplateTemplateParmDecl");
}
void PCHDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
assert(false && "cannot write StaticAssertDecl");
}
/// \brief Emit the DeclContext part of a declaration context decl.
///
/// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL

View File

@ -6,8 +6,35 @@ namespace N1 {
namespace N1 {
typedef int t2;
void used_func();
struct used_cls { };
}
namespace N2 {
typedef float t1;
namespace Inner {
typedef int t3;
};
}
namespace {
void anon() { }
class C;
}
namespace N3 {
namespace {
class C;
}
}
namespace Alias1 = N2::Inner;
using namespace N2::Inner;
extern "C" {
void ext();
}

View File

@ -8,7 +8,36 @@
int int_val;
N1::t1 *ip1 = &int_val;
N1::t2 *ip2 = &int_val;
N2::Inner::t3 *ip3 = &int_val;
float float_val;
namespace N2 { }
N2::t1 *fp1 = &float_val;
Alias1::t3 *ip4 = &int_val;
t3 *ip5 = &int_val;
void(*funp1)() = anon;
namespace {
class C;
}
C* cp1;
namespace N3 {
namespace {
class C;
}
}
N3::C *cp2;
void(*funp2)() = ext;
using N1::used_func;
void (*pused)() = used_func;
// FIXME: Disabled until CXXRecord serialization is re-added.
// using N1::used_cls;
// used_cls s1;
// used_cls* ps1 = &s1;

View File

@ -84,6 +84,26 @@ namespace K {
}
}
namespace {
class C1;
}
namespace {
class C1;
}
C1 *pc1 = 0;
namespace N {
namespace {
class C2;
}
}
namespace N {
namespace {
class C2;
}
}
N::C2 *pc2 = 0;
// PR6341
namespace A = N;
namespace N { }