diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 9b120a4e55b5..e65d4484da12 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -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(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); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index a9b948eee546..c15aeef14ba6 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -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 diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 20ee5ab1e01f..538da747766b 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -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(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(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(ND) || isa(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::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, diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index 1640afb4122a..08efcc296f2b 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -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. diff --git a/clang/include/clang/Frontend/PCHReader.h b/clang/include/clang/Frontend/PCHReader.h index c2352301caa0..cac3398b965c 100644 --- a/clang/include/clang/Frontend/PCHReader.h +++ b/clang/include/clang/Frontend/PCHReader.h @@ -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); diff --git a/clang/include/clang/Frontend/PCHWriter.h b/clang/include/clang/Frontend/PCHWriter.h index e006de524ca3..24025c9feb42 100644 --- a/clang/include/clang/Frontend/PCHWriter.h +++ b/clang/include/clang/Frontend/PCHWriter.h @@ -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); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index d15cfefed048..a279eda38a37 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -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(NominatedNamespace); } +void UsingDirectiveDecl::setNominatedNamespace(NamedDecl* ND) { + assert((isa(ND) || isa(ND)) && + "expected a NamespaceDecl or NamespaceAliasDecl"); + NominatedNamespace = ND; +} + NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, SourceLocation AliasLoc, diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index ae57ce581def..8bc3b18bab48 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -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(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++]; diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp index 7e126600b82f..c4f9622db8db 100644 --- a/clang/lib/Frontend/PCHReaderDecl.cpp +++ b/clang/lib/Frontend/PCHReaderDecl.cpp @@ -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 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(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(Reader.GetDecl(Record[Idx++]))); - D->setOriginalNamespace( - cast_or_null(Reader.GetDecl(Record[Idx++]))); - D->setAnonymousNamespace( - cast_or_null(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 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(Reader.GetDecl(Record[Idx++]))); + + // Only read one reference--the original or anonymous namespace. + bool IsOriginal = Record[Idx++]; + if (IsOriginal) + D->setAnonymousNamespace( + cast_or_null(Reader.GetDecl(Record[Idx++]))); + else + D->setOriginalNamespace( + cast_or_null(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(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(Reader.GetDecl(Record[Idx++]))); + } + D->setTypeName(Record[Idx++]); +} + +void PCHDeclReader::VisitUsingShadow(UsingShadowDecl *D) { + VisitNamedDecl(D); + D->setTargetDecl(cast(Reader.GetDecl(Record[Idx++]))); + D->setUsingDecl(cast(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(Reader.GetDecl(Record[Idx++]))); + D->setCommonAncestor(cast_or_null( + 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 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"); diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index e56dd3132224..225772b30d3d 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -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 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; + } + } +} diff --git a/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp index 358509343826..a898c705e2e3 100644 --- a/clang/lib/Frontend/PCHWriterDecl.cpp +++ b/clang/lib/Frontend/PCHWriterDecl.cpp @@ -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(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 diff --git a/clang/test/PCH/Inputs/namespaces.h b/clang/test/PCH/Inputs/namespaces.h index 1bab7463fbbb..553aadd1f9ed 100644 --- a/clang/test/PCH/Inputs/namespaces.h +++ b/clang/test/PCH/Inputs/namespaces.h @@ -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(); } diff --git a/clang/test/PCH/namespaces.cpp b/clang/test/PCH/namespaces.cpp index eef9e06e5462..532d627fadcf 100644 --- a/clang/test/PCH/namespaces.cpp +++ b/clang/test/PCH/namespaces.cpp @@ -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; diff --git a/clang/test/SemaCXX/namespace-alias.cpp b/clang/test/SemaCXX/namespace-alias.cpp index 1c3da3c656a6..52cae2e92f5a 100644 --- a/clang/test/SemaCXX/namespace-alias.cpp +++ b/clang/test/SemaCXX/namespace-alias.cpp @@ -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 { }