diff options
Diffstat (limited to 'include/clang/AST')
45 files changed, 1833 insertions, 1238 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 69a3866..37b0740 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -19,12 +19,14 @@ namespace clang { class CXXRecordDecl; class DeclGroupRef; class HandleTagDeclDefinition; + class PPMutationListener; class ASTMutationListener; class ASTDeserializationListener; // layering violation because void* is ugly class SemaConsumer; // layering violation required for safe SemaConsumer class TagDecl; class VarDecl; class FunctionDecl; + class ImportDecl; /// ASTConsumer - This is an abstract interface that should be implemented by /// clients that read ASTs. This abstraction layer allows the client to be @@ -79,6 +81,11 @@ public: /// The default implementation ignored them. virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D); + /// \brief Handle an ImportDecl that was implicitly created due to an + /// inclusion directive. + /// The default implementation passes it to HandleTopLevelDecl. + virtual void HandleImplicitImportDecl(ImportDecl *D); + /// CompleteTentativeDefinition - Callback invoked at the end of a translation /// unit to notify the consumer that the given tentative definition should be /// completed. @@ -105,6 +112,11 @@ public: /// it was actually used. virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {} + /// \brief If the consumer is interested in preprocessor entities getting + /// modified after their initial creation, it should return a pointer to + /// a PPMutationListener here. + virtual PPMutationListener *GetPPMutationListener() { return 0; } + /// \brief If the consumer is interested in entities getting modified after /// their initial creation, it should return a pointer to /// an ASTMutationListener here. @@ -118,9 +130,6 @@ public: /// PrintStats - If desired, print any statistics. virtual void PrintStats() {} - - // Support isa/cast/dyn_cast - static bool classof(const ASTConsumer *) { return true; } }; } // end namespace clang. diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index cad3ad2..f0934b7 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -6,9 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the ASTContext interface. -// +/// +/// \file +/// \brief Defines the clang::ASTContext interface. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_ASTCONTEXT_H @@ -28,6 +29,7 @@ #include "clang/AST/Type.h" #include "clang/AST/CanonicalType.h" #include "clang/AST/RawCommentList.h" +#include "clang/AST/CommentCommandTraits.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -84,8 +86,8 @@ namespace clang { class FullComment; } -/// ASTContext - This class holds long-lived AST nodes (such as types and -/// decls) that can be referred to throughout the semantic analysis of a file. +/// \brief Holds long-lived AST nodes (such as types and decls) that can be +/// referred to throughout the semantic analysis of a file. class ASTContext : public RefCountedBase<ASTContext> { ASTContext &this_() { return *this; } @@ -144,19 +146,20 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable NestedNameSpecifier *GlobalNestedNameSpecifier; friend class NestedNameSpecifier; - /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts. - /// This is lazily created. This is intentionally not serialized. + /// \brief A cache mapping from RecordDecls to ASTRecordLayouts. + /// + /// This is lazily created. This is intentionally not serialized. mutable llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts; mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*> ObjCLayouts; - /// TypeInfoMap - A cache from types to size and alignment information. + /// \brief A cache from types to size and alignment information. typedef llvm::DenseMap<const Type*, std::pair<uint64_t, unsigned> > TypeInfoMap; mutable TypeInfoMap MemoizedTypeInfo; - /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions. + /// \brief A cache mapping from CXXRecordDecls to key functions. llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions; /// \brief Mapping from ObjCContainers to their ObjCImplementations. @@ -170,7 +173,7 @@ class ASTContext : public RefCountedBase<ASTContext> { llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits; /// \brief Mapping from class scope functions specialization to their - /// template patterns. + /// template patterns. llvm::DenseMap<const FunctionDecl*, FunctionDecl*> ClassScopeSpecializationPattern; @@ -206,17 +209,20 @@ class ASTContext : public RefCountedBase<ASTContext> { /// __builtin_va_list type. mutable TypedefDecl *BuiltinVaListDecl; - /// \brief The typedef for the predefined 'id' type. + /// \brief The typedef for the predefined \c id type. mutable TypedefDecl *ObjCIdDecl; - /// \brief The typedef for the predefined 'SEL' type. + /// \brief The typedef for the predefined \c SEL type. mutable TypedefDecl *ObjCSelDecl; - /// \brief The typedef for the predefined 'Class' type. + /// \brief The typedef for the predefined \c Class type. mutable TypedefDecl *ObjCClassDecl; - /// \brief The typedef for the predefined 'Protocol' class in Objective-C. + /// \brief The typedef for the predefined \c Protocol class in Objective-C. mutable ObjCInterfaceDecl *ObjCProtocolClassDecl; + + /// \brief The typedef for the predefined 'BOOL' type. + mutable TypedefDecl *BOOLDecl; // Typedefs which may be provided defining the structure of Objective-C // pseudo-builtins @@ -296,9 +302,10 @@ class ASTContext : public RefCountedBase<ASTContext> { InstantiatedFromStaticDataMember; /// \brief Keeps track of the declaration from which a UsingDecl was - /// created during instantiation. The source declaration is always - /// a UsingDecl, an UnresolvedUsingValueDecl, or an - /// UnresolvedUsingTypenameDecl. + /// created during instantiation. + /// + /// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl, + /// or an UnresolvedUsingTypenameDecl. /// /// For example: /// \code @@ -337,9 +344,8 @@ class ASTContext : public RefCountedBase<ASTContext> { /// mangling context. llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts; - /// \brief Mapping that stores parameterIndex values for ParmVarDecls - /// when that value exceeds the bitfield size of - /// ParmVarDeclBits.ParameterIndex. + /// \brief Mapping that stores parameterIndex values for ParmVarDecls when + /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex. typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable; ParameterIndexTable ParamIndices; @@ -348,10 +354,10 @@ class ASTContext : public RefCountedBase<ASTContext> { TranslationUnitDecl *TUDecl; - /// SourceMgr - The associated SourceManager object. + /// \brief The associated SourceManager object.a SourceManager &SourceMgr; - /// LangOpts - The language options used to create the AST associated with + /// \brief The language options used to create the AST associated with /// this ASTContext object. LangOptions &LangOpts; @@ -387,9 +393,11 @@ public: OwningPtr<ExternalASTSource> ExternalSource; ASTMutationListener *Listener; - clang::PrintingPolicy getPrintingPolicy() const { return PrintingPolicy; } + const clang::PrintingPolicy &getPrintingPolicy() const { + return PrintingPolicy; + } - void setPrintingPolicy(clang::PrintingPolicy Policy) { + void setPrintingPolicy(const clang::PrintingPolicy &Policy) { PrintingPolicy = Policy; } @@ -508,6 +516,8 @@ public: } void addComment(const RawComment &RC) { + assert(LangOpts.RetainCommentsFromSystemHeaders || + !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin())); Comments.addComment(RC, BumpAlloc); } @@ -522,7 +532,22 @@ public: /// Return parsed documentation comment attached to a given declaration. /// Returns NULL if no comment is attached. - comments::FullComment *getCommentForDecl(const Decl *D) const; + /// + /// \param PP the Preprocessor used with this TU. Could be NULL if + /// preprocessor is not available. + comments::FullComment *getCommentForDecl(const Decl *D, + const Preprocessor *PP) const; + + comments::FullComment *cloneFullComment(comments::FullComment *FC, + const Decl *D) const; + +private: + mutable comments::CommandTraits CommentCommandTraits; + +public: + comments::CommandTraits &getCommentCommandTraits() const { + return CommentCommandTraits; + } /// \brief Retrieve the attributes for the given declaration. AttrVec& getDeclAttrs(const Decl *D); @@ -547,7 +572,7 @@ public: TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation = SourceLocation()); - /// \brief If the given using decl is an instantiation of a + /// \brief If the given using decl \p Inst is an instantiation of a /// (possibly unresolved) using decl from a template instantiation, /// return it. NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst); @@ -564,28 +589,28 @@ public: void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl); - /// ZeroBitfieldFollowsNonBitfield - return 'true" if 'FD' is a zero-length - /// bitfield which follows the non-bitfield 'LastFD'. + /// \brief Return \c true if \p FD is a zero-length bitfield which follows + /// the non-bitfield \p LastFD. bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; - /// ZeroBitfieldFollowsBitfield - return 'true" if 'FD' is a zero-length - /// bitfield which follows the bitfield 'LastFD'. + /// \brief Return \c true if \p FD is a zero-length bitfield which follows + /// the bitfield \p LastFD. bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; - /// BitfieldFollowsBitfield - return 'true" if 'FD' is a - /// bitfield which follows the bitfield 'LastFD'. + /// \brief Return \c true if \p FD is a bitfield which follows the bitfield + /// \p LastFD. bool BitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; - /// NonBitfieldFollowsBitfield - return 'true" if 'FD' is not a - /// bitfield which follows the bitfield 'LastFD'. + /// \brief Return \c true if \p FD is not a bitfield which follows the + /// bitfield \p LastFD. bool NonBitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; - /// BitfieldFollowsNonBitfield - return 'true" if 'FD' is a - /// bitfield which follows the none bitfield 'LastFD'. + /// \brief Return \c true if \p FD is a bitfield which follows the + /// non-bitfield \p LastFD. bool BitfieldFollowsNonBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; @@ -603,6 +628,17 @@ public: /// Overridden method. void addOverriddenMethod(const CXXMethodDecl *Method, const CXXMethodDecl *Overridden); + + /// \brief Return C++ or ObjC overridden methods for the given \p Method. + /// + /// An ObjC method is considered to override any method in the class's + /// base classes, its protocols, or its categories' protocols, that has + /// the same selector and is of the same kind (class or instance). + /// A method in an implementation is not considered as overriding the same + /// method in the interface or its categories. + void getOverriddenMethods( + const NamedDecl *Method, + SmallVectorImpl<const NamedDecl *> &Overridden) const; /// \brief Notify the AST context that a new import declaration has been /// parsed or implicitly created within this translation unit. @@ -673,6 +709,7 @@ public: CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType VoidPtrTy, NullPtrTy; CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; @@ -731,77 +768,85 @@ public: //===--------------------------------------------------------------------===// private: - /// getExtQualType - Return a type with extended qualifiers. + /// \brief Return a type with extended qualifiers. QualType getExtQualType(const Type *Base, Qualifiers Quals) const; QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const; public: - /// getAddSpaceQualType - Return the uniqued reference to the type for an - /// address space qualified type with the specified type and address space. + /// \brief Return the uniqued reference to the type for an address space + /// qualified type with the specified type and address space. + /// /// The resulting type has a union of the qualifiers from T and the address /// space. If T already has an address space specifier, it is silently /// replaced. QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const; - /// getObjCGCQualType - Returns the uniqued reference to the type for an - /// objc gc qualified type. The retulting type has a union of the qualifiers - /// from T and the gc attribute. + /// \brief Return the uniqued reference to the type for an Objective-C + /// gc-qualified type. + /// + /// The retulting type has a union of the qualifiers from T and the gc + /// attribute. QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const; - /// getRestrictType - Returns the uniqued reference to the type for a - /// 'restrict' qualified type. The resulting type has a union of the - /// qualifiers from T and 'restrict'. + /// \brief Return the uniqued reference to the type for a \c restrict + /// qualified type. + /// + /// The resulting type has a union of the qualifiers from \p T and + /// \c restrict. QualType getRestrictType(QualType T) const { return T.withFastQualifiers(Qualifiers::Restrict); } - /// getVolatileType - Returns the uniqued reference to the type for a - /// 'volatile' qualified type. The resulting type has a union of the - /// qualifiers from T and 'volatile'. + /// \brief Return the uniqued reference to the type for a \c volatile + /// qualified type. + /// + /// The resulting type has a union of the qualifiers from \p T and + /// \c volatile. QualType getVolatileType(QualType T) const { return T.withFastQualifiers(Qualifiers::Volatile); } - /// getConstType - Returns the uniqued reference to the type for a - /// 'const' qualified type. The resulting type has a union of the - /// qualifiers from T and 'const'. + /// \brief Return the uniqued reference to the type for a \c const + /// qualified type. /// - /// It can be reasonably expected that this will always be - /// equivalent to calling T.withConst(). + /// The resulting type has a union of the qualifiers from \p T and \c const. + /// + /// It can be reasonably expected that this will always be equivalent to + /// calling T.withConst(). QualType getConstType(QualType T) const { return T.withConst(); } - /// adjustFunctionType - Change the ExtInfo on a function type. + /// \brief Change the ExtInfo on a function type. const FunctionType *adjustFunctionType(const FunctionType *Fn, FunctionType::ExtInfo EInfo); - /// getComplexType - Return the uniqued reference to the type for a complex + /// \brief Return the uniqued reference to the type for a complex /// number with the specified element type. QualType getComplexType(QualType T) const; CanQualType getComplexType(CanQualType T) const { return CanQualType::CreateUnsafe(getComplexType((QualType) T)); } - /// getPointerType - Return the uniqued reference to the type for a pointer to + /// \brief Return the uniqued reference to the type for a pointer to /// the specified type. QualType getPointerType(QualType T) const; CanQualType getPointerType(CanQualType T) const { return CanQualType::CreateUnsafe(getPointerType((QualType) T)); } - /// getAtomicType - Return the uniqued reference to the atomic type for - /// the specified type. + /// \brief Return the uniqued reference to the atomic type for the specified + /// type. QualType getAtomicType(QualType T) const; - /// getBlockPointerType - Return the uniqued reference to the type for a block - /// of the specified type. + /// \brief Return the uniqued reference to the type for a block of the + /// specified type. QualType getBlockPointerType(QualType T) const; - /// This gets the struct used to keep track of the descriptor for pointer to + /// Gets the struct used to keep track of the descriptor for pointer to /// blocks. QualType getBlockDescriptorType() const; - /// This gets the struct used to keep track of the extended descriptor for + /// Gets the struct used to keep track of the extended descriptor for /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; @@ -812,78 +857,82 @@ public: return cudaConfigureCallDecl; } - /// This builds the struct used for __block variables. + /// Builds the struct used for __block variables. QualType BuildByRefType(StringRef DeclName, QualType Ty) const; /// Returns true iff we need copy/dispose helpers for the given type. bool BlockRequiresCopying(QualType Ty) const; - /// getLValueReferenceType - Return the uniqued reference to the type for an - /// lvalue reference to the specified type. + /// \brief Return the uniqued reference to the type for an lvalue reference + /// to the specified type. QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true) const; - /// getRValueReferenceType - Return the uniqued reference to the type for an - /// rvalue reference to the specified type. + /// \brief Return the uniqued reference to the type for an rvalue reference + /// to the specified type. QualType getRValueReferenceType(QualType T) const; - /// getMemberPointerType - Return the uniqued reference to the type for a - /// member pointer to the specified type in the specified class. The class - /// is a Type because it could be a dependent name. + /// \brief Return the uniqued reference to the type for a member pointer to + /// the specified type in the specified class. + /// + /// The class \p Cls is a \c Type because it could be a dependent name. QualType getMemberPointerType(QualType T, const Type *Cls) const; - /// getVariableArrayType - Returns a non-unique reference to the type for a - /// variable array of the specified element type. + /// \brief Return a non-unique reference to the type for a variable array of + /// the specified element type. QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const; - /// getDependentSizedArrayType - Returns a non-unique reference to - /// the type for a dependently-sized array of the specified element - /// type. FIXME: We will need these to be uniqued, or at least - /// comparable, at some point. + /// \brief Return a non-unique reference to the type for a dependently-sized + /// array of the specified element type. + /// + /// FIXME: We will need these to be uniqued, or at least comparable, at some + /// point. QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const; - /// getIncompleteArrayType - Returns a unique reference to the type for a - /// incomplete array of the specified element type. + /// \brief Return a unique reference to the type for an incomplete array of + /// the specified element type. QualType getIncompleteArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; - /// getConstantArrayType - Return the unique reference to the type for a - /// constant array of the specified element type. + /// \brief Return the unique reference to the type for a constant array of + /// the specified element type. QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; - /// getVariableArrayDecayedType - Returns a vla type where known sizes - /// are replaced with [*]. + /// \brief Returns a vla type where known sizes are replaced with [*]. QualType getVariableArrayDecayedType(QualType Ty) const; - /// getVectorType - Return the unique reference to a vector type of - /// the specified element type and size. VectorType must be a built-in type. + /// \brief Return the unique reference to a vector type of the specified + /// element type and size. + /// + /// \pre \p VectorType must be a built-in type. QualType getVectorType(QualType VectorType, unsigned NumElts, VectorType::VectorKind VecKind) const; - /// getExtVectorType - Return the unique reference to an extended vector type - /// of the specified element type and size. VectorType must be a built-in - /// type. + /// \brief Return the unique reference to an extended vector type + /// of the specified element type and size. + /// + /// \pre \p VectorType must be a built-in type. QualType getExtVectorType(QualType VectorType, unsigned NumElts) const; - /// getDependentSizedExtVectorType - Returns a non-unique reference to - /// the type for a dependently-sized vector of the specified element - /// type. FIXME: We will need these to be uniqued, or at least - /// comparable, at some point. + /// \pre Return a non-unique reference to the type for a dependently-sized + /// vector of the specified element type. + /// + /// FIXME: We will need these to be uniqued, or at least comparable, at some + /// point. QualType getDependentSizedExtVectorType(QualType VectorType, Expr *SizeExpr, SourceLocation AttrLoc) const; - /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. - /// + /// \brief Return a K&R style C function type like 'int()'. QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const; @@ -891,14 +940,13 @@ public: return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo()); } - /// getFunctionType - Return a normal function type with a typed - /// argument list. + /// \brief Return a normal function type with a typed argument list. QualType getFunctionType(QualType ResultTy, const QualType *Args, unsigned NumArgs, const FunctionProtoType::ExtProtoInfo &EPI) const; - /// getTypeDeclType - Return the unique reference to the type for - /// the specified type declaration. + /// \brief Return the unique reference to the type for the specified type + /// declaration. QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl = 0) const { assert(Decl && "Passed null for Decl param"); @@ -913,8 +961,8 @@ public: return getTypeDeclTypeSlow(Decl); } - /// getTypedefType - Return the unique reference to the type for the - /// specified typedef-name decl. + /// \brief Return the unique reference to the type for the specified + /// typedef-name decl. QualType getTypedefType(const TypedefNameDecl *Decl, QualType Canon = QualType()) const; @@ -986,69 +1034,75 @@ public: ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) const; - /// getObjCObjectPointerType - Return a ObjCObjectPointerType type - /// for the given ObjCObjectType. + /// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType. QualType getObjCObjectPointerType(QualType OIT) const; - /// getTypeOfType - GCC extension. + /// \brief GCC extension. QualType getTypeOfExprType(Expr *e) const; QualType getTypeOfType(QualType t) const; - /// getDecltypeType - C++0x decltype. + /// \brief C++11 decltype. QualType getDecltypeType(Expr *e, QualType UnderlyingType) const; - /// getUnaryTransformType - unary type transforms + /// \brief Unary type transforms QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType, UnaryTransformType::UTTKind UKind) const; - /// getAutoType - C++0x deduced auto type. + /// \brief C++11 deduced auto type. QualType getAutoType(QualType DeducedType) const; - /// getAutoDeductType - C++0x deduction pattern for 'auto' type. + /// \brief C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; - /// getAutoRRefDeductType - C++0x deduction pattern for 'auto &&' type. + /// \brief C++11 deduction pattern for 'auto &&' type. QualType getAutoRRefDeductType() const; - /// getTagDeclType - Return the unique reference to the type for the - /// specified TagDecl (struct/union/class/enum) decl. + /// \brief Return the unique reference to the type for the specified TagDecl + /// (struct/union/class/enum) decl. QualType getTagDeclType(const TagDecl *Decl) const; - /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined - /// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4). + /// \brief Return the unique type for "size_t" (C99 7.17), defined in + /// <stddef.h>. + /// + /// The sizeof operator requires this (C99 6.5.3.4p4). CanQualType getSizeType() const; - /// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5), - /// defined in <stdint.h>. + /// \brief Return the unique type for "intmax_t" (C99 7.18.1.5), defined in + /// <stdint.h>. CanQualType getIntMaxType() const; - /// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5), - /// defined in <stdint.h>. + /// \brief Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in + /// <stdint.h>. CanQualType getUIntMaxType() const; - /// getWCharType - In C++, this returns the unique wchar_t type. In C99, this + /// \brief In C++, this returns the unique wchar_t type. In C99, this /// returns a type compatible with the type defined in <stddef.h> as defined /// by the target. QualType getWCharType() const { return WCharTy; } - /// getSignedWCharType - Return the type of "signed wchar_t". + /// \brief Return the type of "signed wchar_t". + /// /// Used when in C++, as a GCC extension. QualType getSignedWCharType() const; - /// getUnsignedWCharType - Return the type of "unsigned wchar_t". + /// \brief Return the type of "unsigned wchar_t". + /// /// Used when in C++, as a GCC extension. QualType getUnsignedWCharType() const; - /// getWIntType - In C99, this returns a type compatible with the type + /// \brief In C99, this returns a type compatible with the type /// defined in <stddef.h> as defined by the target. QualType getWIntType() const { return WIntTy; } - /// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17) - /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). + /// \brief Return the unique type for "ptrdiff_t" (C99 7.17) defined in + /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). QualType getPointerDiffType() const; - // getCFConstantStringType - Return the C structure type used to represent - // constant CFStrings. + /// \brief Return the unique type for "pid_t" defined in + /// <sys/types.h>. We need this to compute the correct type for vfork(). + QualType getProcessIDType() const; + + /// \brief Return the C structure type used to represent constant CFStrings. QualType getCFConstantStringType() const; /// Get the structure type used to representation CFStrings, or NULL @@ -1074,21 +1128,21 @@ public: ObjCNSStringType = T; } - /// \brief Retrieve the type that 'id' has been defined to, which may be - /// different from the built-in 'id' if 'id' has been typedef'd. + /// \brief Retrieve the type that \c id has been defined to, which may be + /// different from the built-in \c id if \c id has been typedef'd. QualType getObjCIdRedefinitionType() const { if (ObjCIdRedefinitionType.isNull()) return getObjCIdType(); return ObjCIdRedefinitionType; } - /// \brief Set the user-written type that redefines 'id'. + /// \brief Set the user-written type that redefines \c id. void setObjCIdRedefinitionType(QualType RedefType) { ObjCIdRedefinitionType = RedefType; } - /// \brief Retrieve the type that 'Class' has been defined to, which may be - /// different from the built-in 'Class' if 'Class' has been typedef'd. + /// \brief Retrieve the type that \c Class has been defined to, which may be + /// different from the built-in \c Class if \c Class has been typedef'd. QualType getObjCClassRedefinitionType() const { if (ObjCClassRedefinitionType.isNull()) return getObjCClassType(); @@ -1175,27 +1229,29 @@ public: return getLangOpts().CPlusPlus ? BoolTy : IntTy; } - /// getObjCEncodingForType - Emit the ObjC type encoding for the - /// given type into \arg S. If \arg NameFields is specified then - /// record field names are also encoded. - void getObjCEncodingForType(QualType t, std::string &S, + /// \brief Emit the Objective-CC type encoding for the given type \p T into + /// \p S. + /// + /// If \p Field is specified then record field names are also encoded. + void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=0) const; void getLegacyIntegralTypeEncoding(QualType &t) const; - // Put the string version of type qualifiers into S. + /// \brief Put the string version of the type qualifiers \p QT into \p S. void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, std::string &S) const; - /// getObjCEncodingForFunctionDecl - Returns the encoded type for this - /// function. This is in the same format as Objective-C method encodings. + /// \brief Emit the encoded type for the function \p Decl into \p S. + /// + /// This is in the same format as Objective-C method encodings. /// /// \returns true if an error occurred (e.g., because one of the parameter /// types is incomplete), false otherwise. bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S); - /// getObjCEncodingForMethodDecl - Return the encoded type for this method - /// declaration. + /// \brief Emit the encoded type for the method declaration \p Decl into + /// \p S. /// /// \returns true if an error occurred (e.g., because one of the parameter /// types is incomplete), false otherwise. @@ -1203,8 +1259,7 @@ public: bool Extended = false) const; - /// getObjCEncodingForBlock - Return the encoded type for this block - /// declaration. + /// \brief Return the encoded type for this block declaration. std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const; /// getObjCEncodingForPropertyDecl - Return the encoded type for @@ -1218,16 +1273,18 @@ public: bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, ObjCProtocolDecl *rProto) const; - /// getObjCEncodingTypeSize returns size of type for objective-c encoding - /// purpose in characters. - CharUnits getObjCEncodingTypeSize(QualType t) const; + /// \brief Return the size of type \p T for Objective-C encoding purpose, + /// in characters. + CharUnits getObjCEncodingTypeSize(QualType T) const; - /// \brief Retrieve the typedef corresponding to the predefined 'id' type + /// \brief Retrieve the typedef corresponding to the predefined \c id type /// in Objective-C. TypedefDecl *getObjCIdDecl() const; - /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by - /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct. + /// \brief Represents the Objective-CC \c id type. + /// + /// This is set up lazily, by Sema. \c id is always a (typedef for a) + /// pointer type, a pointer to a struct. QualType getObjCIdType() const { return getTypeDeclType(getObjCIdDecl()); } @@ -1246,48 +1303,64 @@ public: /// Objective-C 'Class' type. TypedefDecl *getObjCClassDecl() const; - /// This setter/getter repreents the ObjC 'Class' type. It is setup lazily, by - /// Sema. 'Class' is always a (typedef for a) pointer type, a pointer to a - /// struct. + /// \brief Represents the Objective-C \c Class type. + /// + /// This is set up lazily, by Sema. \c Class is always a (typedef for a) + /// pointer type, a pointer to a struct. QualType getObjCClassType() const { return getTypeDeclType(getObjCClassDecl()); } /// \brief Retrieve the Objective-C class declaration corresponding to - /// the predefined 'Protocol' class. + /// the predefined \c Protocol class. ObjCInterfaceDecl *getObjCProtocolDecl() const; + + /// \brief Retrieve declaration of 'BOOL' typedef + TypedefDecl *getBOOLDecl() const { + return BOOLDecl; + } + + /// \brief Save declaration of 'BOOL' typedef + void setBOOLDecl(TypedefDecl *TD) { + BOOLDecl = TD; + } + + /// \brief type of 'BOOL' type. + QualType getBOOLType() const { + return getTypeDeclType(getBOOLDecl()); + } - /// \brief Retrieve the type of the Objective-C "Protocol" class. + /// \brief Retrieve the type of the Objective-C \c Protocol class. QualType getObjCProtoType() const { return getObjCInterfaceType(getObjCProtocolDecl()); } /// \brief Retrieve the C type declaration corresponding to the predefined - /// __builtin_va_list type. + /// \c __builtin_va_list type. TypedefDecl *getBuiltinVaListDecl() const; - /// \brief Retrieve the type of the __builtin_va_list type. + /// \brief Retrieve the type of the \c __builtin_va_list type. QualType getBuiltinVaListType() const { return getTypeDeclType(getBuiltinVaListDecl()); } /// \brief Retrieve the C type declaration corresponding to the predefined - /// __va_list_tag type used to help define the __builtin_va_list type for - /// some targets. + /// \c __va_list_tag type used to help define the \c __builtin_va_list type + /// for some targets. QualType getVaListTagType() const; - /// getCVRQualifiedType - Returns a type with additional const, - /// volatile, or restrict qualifiers. + /// \brief Return a type with additional \c const, \c volatile, or + /// \c restrict qualifiers. QualType getCVRQualifiedType(QualType T, unsigned CVR) const { return getQualifiedType(T, Qualifiers::fromCVRMask(CVR)); } - /// getQualifiedType - Un-split a SplitQualType. + /// \brief Un-split a SplitQualType. QualType getQualifiedType(SplitQualType split) const { return getQualifiedType(split.Ty, split.Quals); } - /// getQualifiedType - Returns a type with additional qualifiers. + /// \brief Return a type with additional qualifiers. QualType getQualifiedType(QualType T, Qualifiers Qs) const { if (!Qs.hasNonFastQualifiers()) return T.withFastQualifiers(Qs.getFastQualifiers()); @@ -1296,15 +1369,16 @@ public: return getExtQualType(Ptr, Qc); } - /// getQualifiedType - Returns a type with additional qualifiers. + /// \brief Return a type with additional qualifiers. QualType getQualifiedType(const Type *T, Qualifiers Qs) const { if (!Qs.hasNonFastQualifiers()) return QualType(T, Qs.getFastQualifiers()); return getExtQualType(T, Qs); } - /// getLifetimeQualifiedType - Returns a type with the given - /// lifetime qualifier. + /// \brief Return a type with the given lifetime qualifier. + /// + /// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None. QualType getLifetimeQualifiedType(QualType type, Qualifiers::ObjCLifetime lifetime) { assert(type.getObjCLifetime() == Qualifiers::OCL_None); @@ -1341,8 +1415,9 @@ public: GE_Missing_ucontext ///< Missing a type from <ucontext.h> }; - /// GetBuiltinType - Return the type for the specified builtin. If - /// IntegerConstantArgs is non-null, it is filled in with a bitmask of + /// \brief Return the type for the specified builtin. + /// + /// If \p IntegerConstantArgs is non-null, it is filled in with a bitmask of /// arguments to the builtin that are required to be integer constant /// expressions. QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, @@ -1357,19 +1432,19 @@ private: //===--------------------------------------------------------------------===// public: - /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's - /// garbage collection attribute. - /// + /// \brief Return one of the GCNone, Weak or Strong Objective-C garbage + /// collection attributes. Qualifiers::GC getObjCGCAttrKind(QualType Ty) const; - /// areCompatibleVectorTypes - Return true if the given vector types - /// are of the same unqualified type or if they are equivalent to the same - /// GCC vector type, ignoring whether they are target-specific (AltiVec or - /// Neon) types. + /// \brief Return true if the given vector types are of the same unqualified + /// type or if they are equivalent to the same GCC vector type. + /// + /// \note This ignores whether they are target-specific (AltiVec or Neon) + /// types. bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec); - /// isObjCNSObjectType - Return true if this is an NSObject object with - /// its NSObject attribute set. + /// \brief Return true if this is an \c NSObject object with its \c NSObject + /// attribute set. static bool isObjCNSObjectType(QualType Ty) { return Ty->isObjCNSObjectType(); } @@ -1378,19 +1453,17 @@ public: // Type Sizing and Analysis //===--------------------------------------------------------------------===// - /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified - /// scalar floating point type. + /// \brief Return the APFloat 'semantics' for the specified scalar floating + /// point type. const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const; - /// getTypeInfo - Get the size and alignment of the specified complete type in - /// bits. + /// \brief Get the size and alignment of the specified complete type in bits. std::pair<uint64_t, unsigned> getTypeInfo(const Type *T) const; std::pair<uint64_t, unsigned> getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); } - /// getTypeSize - Return the size of the specified type, in bits. This method - /// does not work on incomplete types. + /// \brief Return the size of the specified (complete) type \p T, in bits. uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).first; } @@ -1398,24 +1471,24 @@ public: return getTypeInfo(T).first; } - /// getCharWidth - Return the size of the character type, in bits + /// \brief Return the size of the character type, in bits. uint64_t getCharWidth() const { return getTypeSize(CharTy); } - /// toCharUnitsFromBits - Convert a size in bits to a size in characters. + /// \brief Convert a size in bits to a size in characters. CharUnits toCharUnitsFromBits(int64_t BitSize) const; - /// toBits - Convert a size in characters to a size in bits. + /// \brief Convert a size in characters to a size in bits. int64_t toBits(CharUnits CharSize) const; - /// getTypeSizeInChars - Return the size of the specified type, in characters. - /// This method does not work on incomplete types. + /// \brief Return the size of the specified (complete) type \p T, in + /// characters. CharUnits getTypeSizeInChars(QualType T) const; CharUnits getTypeSizeInChars(const Type *T) const; - /// getTypeAlign - Return the ABI-specified alignment of a type, in bits. - /// This method does not work on incomplete types. + /// \brief Return the ABI-specified alignment of a (complete) type \p T, in + /// bits. unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).second; } @@ -1423,49 +1496,59 @@ public: return getTypeInfo(T).second; } - /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in - /// characters. This method does not work on incomplete types. + /// \brief Return the ABI-specified alignment of a (complete) type \p T, in + /// characters. CharUnits getTypeAlignInChars(QualType T) const; CharUnits getTypeAlignInChars(const Type *T) const; + + // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the + // type is a record, its data size is returned. + std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const; std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const; std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const; - /// getPreferredTypeAlign - Return the "preferred" alignment of the specified - /// type for the current target in bits. This can be different than the ABI - /// alignment in cases where it is beneficial for performance to overalign - /// a data type. + /// \brief Return the "preferred" alignment of the specified type \p T for + /// the current target, in bits. + /// + /// This can be different than the ABI alignment in cases where it is + /// beneficial for performance to overalign a data type. unsigned getPreferredTypeAlign(const Type *T) const; - /// getDeclAlign - Return a conservative estimate of the alignment of - /// the specified decl. Note that bitfields do not have a valid alignment, so - /// this method will assert on them. - /// If @p RefAsPointee, references are treated like their underlying type + /// \brief Return a conservative estimate of the alignment of the specified + /// decl \p D. + /// + /// \pre \p D must not be a bitfield type, as bitfields do not have a valid + /// alignment. + /// + /// If \p RefAsPointee, references are treated like their underlying type /// (for alignof), else they're treated like pointers (for CodeGen). CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false) const; - /// getASTRecordLayout - Get or compute information about the layout of the - /// specified record (struct/union/class), which indicates its size and field + /// \brief Get or compute information about the layout of the specified + /// record (struct/union/class) \p D, which indicates its size and field /// position information. const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const; - /// getASTObjCInterfaceLayout - Get or compute information about the - /// layout of the specified Objective-C interface. + /// \brief Get or compute information about the layout of the specified + /// Objective-C interface. const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const; void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS, bool Simple = false) const; - /// getASTObjCImplementationLayout - Get or compute information about - /// the layout of the specified Objective-C implementation. This may - /// differ from the interface if synthesized ivars are present. + /// \brief Get or compute information about the layout of the specified + /// Objective-C implementation. + /// + /// This may differ from the interface if synthesized ivars are present. const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const; - /// getKeyFunction - Get the key function for the given record decl, or NULL - /// if there isn't one. The key function is, according to the Itanium C++ ABI - /// section 5.2.3: + /// \brief Get the key function for the given record decl, or NULL if there + /// isn't one. + /// + /// The key function is, according to the Itanium C++ ABI section 5.2.3: /// /// ...the first non-pure virtual function that is not inline at the point /// of class definition. @@ -1489,12 +1572,14 @@ public: // Type Operators //===--------------------------------------------------------------------===// - /// getCanonicalType - Return the canonical (structural) type corresponding to - /// the specified potentially non-canonical type. The non-canonical version - /// of a type may have many "decorated" versions of types. Decorators can - /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed - /// to be free of any of these, allowing two canonical types to be compared - /// for exact equality with a simple pointer comparison. + /// \brief Return the canonical (structural) type corresponding to the + /// specified potentially non-canonical type \p T. + /// + /// The non-canonical version of a type may have many "decorated" versions of + /// types. Decorators can include typedefs, 'typeof' operators, etc. The + /// returned type is guaranteed to be free of any of these, allowing two + /// canonical types to be compared for exact equality with a simple pointer + /// comparison. CanQualType getCanonicalType(QualType T) const { return CanQualType::CreateUnsafe(T.getCanonicalType()); } @@ -1503,21 +1588,23 @@ public: return T->getCanonicalTypeInternal().getTypePtr(); } - /// getCanonicalParamType - Return the canonical parameter type - /// corresponding to the specific potentially non-canonical one. + /// \brief Return the canonical parameter type corresponding to the specific + /// potentially non-canonical one. + /// /// Qualifiers are stripped off, functions are turned into function /// pointers, and arrays decay one level into pointers. CanQualType getCanonicalParamType(QualType T) const; - /// \brief Determine whether the given types are equivalent. + /// \brief Determine whether the given types \p T1 and \p T2 are equivalent. bool hasSameType(QualType T1, QualType T2) const { return getCanonicalType(T1) == getCanonicalType(T2); } - /// \brief Returns this type as a completely-unqualified array type, - /// capturing the qualifiers in Quals. This will remove the minimal amount of - /// sugaring from the types, similar to the behavior of - /// QualType::getUnqualifiedType(). + /// \brief Return this type as a completely-unqualified array type, + /// capturing the qualifiers in \p Quals. + /// + /// This will remove the minimal amount of sugaring from the types, similar + /// to the behavior of QualType::getUnqualifiedType(). /// /// \param T is the qualified type, which may be an ArrayType /// @@ -1628,15 +1715,16 @@ public: return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T)); } - /// getBaseElementType - Returns the innermost element type of an array type. + /// \brief Return the innermost element type of an array type. + /// /// For example, will return "int" for int[m][n] QualType getBaseElementType(const ArrayType *VAT) const; - /// getBaseElementType - Returns the innermost element type of a type - /// (which needn't actually be an array type). + /// \brief Return the innermost element type of a type (which needn't + /// actually be an array type). QualType getBaseElementType(QualType QT) const; - /// getConstantArrayElementCount - Returns number of constant array elements. + /// \brief Return number of constant array elements. uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const; /// \brief Perform adjustment on the parameter type of a function. @@ -1651,21 +1739,22 @@ public: /// cv-qualifiers. QualType getSignatureParameterType(QualType T) const; - /// getArrayDecayedType - Return the properly qualified result of decaying the - /// specified array type to a pointer. This operation is non-trivial when - /// handling typedefs etc. The canonical type of "T" must be an array type, - /// this returns a pointer to a properly qualified element of the array. + /// \brief Return the properly qualified result of decaying the specified + /// array type to a pointer. + /// + /// This operation is non-trivial when handling typedefs etc. The canonical + /// type of \p T must be an array type, this returns a pointer to a properly + /// qualified element of the array. /// /// See C99 6.7.5.3p7 and C99 6.3.2.1p3. QualType getArrayDecayedType(QualType T) const; - /// getPromotedIntegerType - Returns the type that Promotable will - /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable - /// integer type. + /// \brief Return the type that \p PromotableType will promote to: C99 + /// 6.3.1.1p2, assuming that \p PromotableType is a promotable integer type. QualType getPromotedIntegerType(QualType PromotableType) const; - /// \brief Recurses in pointer/array types until it finds an objc retainable - /// type and returns its ownership. + /// \brief Recurses in pointer/array types until it finds an Objective-C + /// retainable type and returns its ownership. Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const; /// \brief Whether this is a promotable bitfield reference according @@ -1675,21 +1764,24 @@ public: /// promotion occurs. QualType isPromotableBitField(Expr *E) const; - /// getIntegerTypeOrder - Returns the highest ranked integer type: - /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If - /// LHS < RHS, return -1. + /// \brief Return the highest ranked integer type, see C99 6.3.1.8p1. + /// + /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If + /// \p LHS < \p RHS, return -1. int getIntegerTypeOrder(QualType LHS, QualType RHS) const; - /// getFloatingTypeOrder - Compare the rank of the two specified floating - /// point types, ignoring the domain of the type (i.e. 'double' == - /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If - /// LHS < RHS, return -1. + /// \brief Compare the rank of the two specified floating point types, + /// ignoring the domain of the type (i.e. 'double' == '_Complex double'). + /// + /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If + /// \p LHS < \p RHS, return -1. int getFloatingTypeOrder(QualType LHS, QualType RHS) const; - /// getFloatingTypeOfSizeWithinDomain - Returns a real floating - /// point or a complex type (based on typeDomain/typeSize). - /// 'typeDomain' is a real floating point or complex type. - /// 'typeSize' is a real floating point or complex type. + /// \brief Return a real floating point or a complex type (based on + /// \p typeDomain/\p typeSize). + /// + /// \param typeDomain a real floating point or complex type. + /// \param typeSize a real floating point or complex type. QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize, QualType typeDomain) const; @@ -1787,7 +1879,7 @@ public: // Per C99 6.2.5p6, for every signed integer type, there is a corresponding // unsigned integer type. This method takes a signed type, and returns the // corresponding unsigned integer type. - QualType getCorrespondingUnsignedType(QualType T); + QualType getCorrespondingUnsignedType(QualType T) const; //===--------------------------------------------------------------------===// // Type Iterators. @@ -1805,8 +1897,8 @@ public: // Integer Values //===--------------------------------------------------------------------===// - /// MakeIntValue - Make an APSInt of the appropriate width and - /// signedness for the given \arg Value and integer \arg Type. + /// \brief Make an APSInt of the appropriate width and signedness for the + /// given \p Value and integer \p Type. llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const { llvm::APSInt Res(getIntWidth(Type), !Type->isSignedIntegerOrEnumerationType()); @@ -1816,12 +1908,14 @@ public: bool isSentinelNullExpr(const Expr *E); - /// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists. + /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if + /// none exists. ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D); - /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists. + /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if + /// none exists. ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); - /// \brief returns true if there is at least one \@implementation in TU. + /// \brief Return true if there is at least one \@implementation in the TU. bool AnyObjCImplementation() { return !ObjCImpls.empty(); } @@ -1834,7 +1928,7 @@ public: ObjCCategoryImplDecl *ImplD); /// \brief Get the duplicate declaration of a ObjCMethod in the same - /// interface, or null if non exists. + /// interface, or null if none exists. const ObjCMethodDecl *getObjCMethodRedeclaration( const ObjCMethodDecl *MD) const { return ObjCMethodRedecls.lookup(MD); @@ -1846,16 +1940,16 @@ public: ObjCMethodRedecls[MD] = Redecl; } - /// \brief Returns the objc interface that \arg ND belongs to if it is a - /// objc method/property/ivar etc. that is part of an interface, + /// \brief Returns the Objective-C interface that \p ND belongs to if it is + /// an Objective-C method/property/ivar etc. that is part of an interface, /// otherwise returns null. ObjCInterfaceDecl *getObjContainingInterface(NamedDecl *ND) const; /// \brief Set the copy inialization expression of a block var decl. void setBlockVarCopyInits(VarDecl*VD, Expr* Init); - /// \brief Get the copy initialization expression of VarDecl,or NULL if - /// none exists. - Expr *getBlockVarCopyInits(const VarDecl*VD); + /// \brief Get the copy initialization expression of the VarDecl \p VD, or + /// NULL if none exists. + Expr *getBlockVarCopyInits(const VarDecl* VD); /// \brief Allocate an uninitialized TypeSourceInfo. /// @@ -1882,9 +1976,9 @@ public: /// \brief Add a deallocation callback that will be invoked when the /// ASTContext is destroyed. /// - /// \brief Callback A callback function that will be invoked on destruction. + /// \param Callback A callback function that will be invoked on destruction. /// - /// \brief Data Pointer data that will be provided to the callback function + /// \param Data Pointer data that will be provided to the callback function /// when it is called. void AddDeallocation(void (*Callback)(void*), void *Data); @@ -1957,8 +2051,8 @@ public: static unsigned NumImplicitDestructorsDeclared; private: - ASTContext(const ASTContext&); // DO NOT IMPLEMENT - void operator=(const ASTContext&); // DO NOT IMPLEMENT + ASTContext(const ASTContext &) LLVM_DELETED_FUNCTION; + void operator=(const ASTContext &) LLVM_DELETED_FUNCTION; public: /// \brief Initialize built-in types. @@ -1974,7 +2068,7 @@ public: private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); - // Return the ObjC type encoding for a given type. + // Return the Objective-C type encoding for a given type. void getObjCEncodingForTypeImpl(QualType t, std::string &S, bool ExpandPointedToStructures, bool ExpandStructures, @@ -2017,13 +2111,13 @@ private: void ReleaseDeclContextMaps(); }; -/// @brief Utility function for constructing a nullary selector. +/// \brief Utility function for constructing a nullary selector. static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(0, &II); } -/// @brief Utility function for constructing an unary selector. +/// \brief Utility function for constructing an unary selector. static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(1, &II); diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index cb038a0..56d1526 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -13,6 +13,8 @@ #ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H #define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H +#include "clang/Basic/SourceLocation.h" + namespace clang { class Decl; class DeclContext; diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index b17bd48..12a9855 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -107,9 +107,6 @@ public: // Pretty print this attribute. virtual void printPretty(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const = 0; - - // Implement isa/cast/dyncast/etc. - static bool classof(const Attr *) { return true; } }; class InheritableAttr : public Attr { @@ -125,7 +122,6 @@ public: static bool classof(const Attr *A) { return A->getKind() <= attr::LAST_INHERITABLE; } - static bool classof(const InheritableAttr *) { return true; } }; class InheritableParamAttr : public InheritableAttr { @@ -139,7 +135,6 @@ public: static bool classof(const Attr *A) { return A->getKind() <= attr::LAST_INHERITABLE_PARAM; } - static bool classof(const InheritableParamAttr *) { return true; } }; #include "clang/AST/Attrs.inc" diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index 34e6fc5..ba322fb 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -206,6 +206,8 @@ PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy) // unknown type, most notably explicit casts. PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy) +PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy) + // The type of a cast which, in ARC, would normally require a // __bridge, but which might be okay depending on the immediate // context. diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt index d7458aa..4c4c0fb 100644 --- a/include/clang/AST/CMakeLists.txt +++ b/include/clang/AST/CMakeLists.txt @@ -20,3 +20,15 @@ clang_tablegen(CommentNodes.inc -gen-clang-comment-nodes SOURCE ../Basic/CommentNodes.td TARGET ClangCommentNodes) +clang_tablegen(CommentHTMLTags.inc -gen-clang-comment-html-tags + SOURCE CommentHTMLTags.td + TARGET ClangCommentHTMLTags) + +clang_tablegen(CommentHTMLTagsProperties.inc -gen-clang-comment-html-tags-properties + SOURCE CommentHTMLTags.td + TARGET ClangCommentHTMLTagsProperties) + +clang_tablegen(CommentCommandInfo.inc -gen-clang-comment-command-info + SOURCE CommentCommands.td + TARGET ClangCommentCommandInfo) + diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index ee6eba7..87bdbe0 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -19,7 +19,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include <list> @@ -271,15 +271,14 @@ struct UniqueVirtualMethod { /// pair is the virtual method that overrides it (including the /// subobject in which that virtual function occurs). class OverridingMethods { - llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> > - Overrides; + typedef SmallVector<UniqueVirtualMethod, 4> ValuesT; + typedef llvm::MapVector<unsigned, ValuesT> MapType; + MapType Overrides; public: // Iterate over the set of subobjects that have overriding methods. - typedef llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> > - ::iterator iterator; - typedef llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> > - ::const_iterator const_iterator; + typedef MapType::iterator iterator; + typedef MapType::const_iterator const_iterator; iterator begin() { return Overrides.begin(); } const_iterator begin() const { return Overrides.begin(); } iterator end() { return Overrides.end(); } @@ -357,8 +356,8 @@ public: /// 0 represents the virtua base class subobject of that type, while /// subobject numbers greater than 0 refer to non-virtual base class /// subobjects of that type. -class CXXFinalOverriderMap - : public llvm::DenseMap<const CXXMethodDecl *, OverridingMethods> { }; +class CXXFinalOverriderMap + : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { }; /// \brief A set of all the primary bases for a class. class CXXIndirectPrimaryBaseSet diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 6cce888..ea307bf 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -276,6 +276,7 @@ public: LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType) diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 5be3582..12e74b3 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -164,8 +164,8 @@ namespace clang { QuantityType getQuantity() const { return Quantity; } /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is - /// greater than or equal to this quantity and is a multiple of \arg - /// Align. Align must be non-zero. + /// greater than or equal to this quantity and is a multiple of \p Align. + /// Align must be non-zero. CharUnits RoundUpToAlignment(const CharUnits &Align) { return CharUnits(llvm::RoundUpToAlignment(Quantity, Align.Quantity)); diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h index 01aaac3..316a180 100644 --- a/include/clang/AST/Comment.h +++ b/include/clang/AST/Comment.h @@ -16,6 +16,8 @@ #include "clang/Basic/SourceLocation.h" #include "clang/AST/Type.h" +#include "clang/AST/CommentCommandTraits.h" +#include "clang/AST/DeclObjC.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -25,7 +27,7 @@ class ParmVarDecl; class TemplateParameterList; namespace comments { - +class FullComment; /// Any part of the comment. /// Abstract class. class Comment { @@ -74,8 +76,9 @@ protected: unsigned : NumInlineContentCommentBits; unsigned RenderKind : 2; + unsigned CommandID : 8; }; - enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 1 }; + enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 }; class HTMLStartTagCommentBitfields { friend class HTMLStartTagComment; @@ -101,10 +104,19 @@ protected: }; enum { NumParagraphCommentBits = NumCommentBits + 2 }; + class BlockCommandCommentBitfields { + friend class BlockCommandComment; + + unsigned : NumCommentBits; + + unsigned CommandID : 8; + }; + enum { NumBlockCommandCommentBits = NumCommentBits + 8 }; + class ParamCommandCommentBitfields { friend class ParamCommandComment; - unsigned : NumCommentBits; + unsigned : NumBlockCommandCommentBits; /// Parameter passing direction, see ParamCommandComment::PassDirection. unsigned Direction : 2; @@ -112,7 +124,7 @@ protected: /// True if direction was specified explicitly in the comment. unsigned IsDirectionExplicit : 1; }; - enum { NumParamCommandCommentBits = 11 }; + enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 }; union { CommentBitfields CommentBits; @@ -121,6 +133,7 @@ protected: InlineCommandCommentBitfields InlineCommandCommentBits; HTMLStartTagCommentBitfields HTMLStartTagCommentBits; ParagraphCommentBitfields ParagraphCommentBits; + BlockCommandCommentBitfields BlockCommandCommentBits; ParamCommandCommentBitfields ParamCommandCommentBits; }; @@ -158,10 +171,9 @@ public: const char *getCommentKindName() const; LLVM_ATTRIBUTE_USED void dump() const; - LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const; - void dump(llvm::raw_ostream &OS, SourceManager *SM) const; - - static bool classof(const Comment *) { return true; } + LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const; + void dump(llvm::raw_ostream &OS, const CommandTraits *Traits, + const SourceManager *SM) const; SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -204,8 +216,6 @@ public: C->getCommentKind() <= LastInlineContentCommentConstant; } - static bool classof(const InlineContentComment *) { return true; } - void addTrailingNewline() { InlineContentCommentBits.HasTrailingNewline = 1; } @@ -232,8 +242,6 @@ public: return C->getCommentKind() == TextCommentKind; } - static bool classof(const TextComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -273,35 +281,35 @@ public: }; protected: - /// Command name. - StringRef Name; - /// Command arguments. llvm::ArrayRef<Argument> Args; public: InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name, + unsigned CommandID, RenderKind RK, llvm::ArrayRef<Argument> Args) : InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd), - Name(Name), Args(Args) { + Args(Args) { InlineCommandCommentBits.RenderKind = RK; + InlineCommandCommentBits.CommandID = CommandID; } static bool classof(const Comment *C) { return C->getCommentKind() == InlineCommandCommentKind; } - static bool classof(const InlineCommandComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } - StringRef getCommandName() const { - return Name; + unsigned getCommandID() const { + return InlineCommandCommentBits.CommandID; + } + + StringRef getCommandName(const CommandTraits &Traits) const { + return Traits.getCommandInfo(getCommandID())->Name; } SourceRange getCommandNameRange() const { @@ -352,8 +360,6 @@ public: C->getCommentKind() <= LastHTMLTagCommentConstant; } - static bool classof(const HTMLTagComment *) { return true; } - StringRef getTagName() const LLVM_READONLY { return TagName; } SourceRange getTagNameSourceRange() const LLVM_READONLY { @@ -419,8 +425,6 @@ public: return C->getCommentKind() == HTMLStartTagCommentKind; } - static bool classof(const HTMLStartTagComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -476,8 +480,6 @@ public: return C->getCommentKind() == HTMLEndTagCommentKind; } - static bool classof(const HTMLEndTagComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -498,8 +500,6 @@ public: return C->getCommentKind() >= FirstBlockContentCommentConstant && C->getCommentKind() <= LastBlockContentCommentConstant; } - - static bool classof(const BlockContentComment *) { return true; } }; /// A single paragraph that contains inline content. @@ -529,8 +529,6 @@ public: return C->getCommentKind() == ParagraphCommentKind; } - static bool classof(const ParagraphComment *) { return true; } - child_iterator child_begin() const { return reinterpret_cast<child_iterator>(Content.begin()); } @@ -566,9 +564,6 @@ public: }; protected: - /// Command name. - StringRef Name; - /// Word-like arguments. llvm::ArrayRef<Argument> Args; @@ -578,21 +573,21 @@ protected: BlockCommandComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : + unsigned CommandID) : BlockContentComment(K, LocBegin, LocEnd), - Name(Name), Paragraph(NULL) { - setLocation(getCommandNameRange().getBegin()); + setLocation(getCommandNameBeginLoc()); + BlockCommandCommentBits.CommandID = CommandID; } public: BlockCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : + unsigned CommandID) : BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd), - Name(Name), Paragraph(NULL) { - setLocation(getCommandNameRange().getBegin()); + setLocation(getCommandNameBeginLoc()); + BlockCommandCommentBits.CommandID = CommandID; } static bool classof(const Comment *C) { @@ -600,8 +595,6 @@ public: C->getCommentKind() <= LastBlockCommandCommentConstant; } - static bool classof(const BlockCommandComment *) { return true; } - child_iterator child_begin() const { return reinterpret_cast<child_iterator>(&Paragraph); } @@ -610,12 +603,21 @@ public: return reinterpret_cast<child_iterator>(&Paragraph + 1); } - StringRef getCommandName() const { - return Name; + unsigned getCommandID() const { + return BlockCommandCommentBits.CommandID; } - SourceRange getCommandNameRange() const { - return SourceRange(getLocStart().getLocWithOffset(1), + StringRef getCommandName(const CommandTraits &Traits) const { + return Traits.getCommandInfo(getCommandID())->Name; + } + + SourceLocation getCommandNameBeginLoc() const { + return getLocStart().getLocWithOffset(1); + } + + SourceRange getCommandNameRange(const CommandTraits &Traits) const { + StringRef Name = getCommandName(Traits); + return SourceRange(getCommandNameBeginLoc(), getLocStart().getLocWithOffset(1 + Name.size())); } @@ -667,8 +669,9 @@ public: ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : - BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, Name), + unsigned CommandID) : + BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, + CommandID), ParamIndex(InvalidParamIndex) { ParamCommandCommentBits.Direction = In; ParamCommandCommentBits.IsDirectionExplicit = false; @@ -678,8 +681,6 @@ public: return C->getCommentKind() == ParamCommandCommentKind; } - static bool classof(const ParamCommandComment *) { return true; } - enum PassDirection { In, Out, @@ -705,7 +706,9 @@ public: return getNumArgs() > 0; } - StringRef getParamName() const { + StringRef getParamName(const FullComment *FC) const; + + StringRef getParamNameAsWritten() const { return Args[0].Text; } @@ -748,21 +751,21 @@ private: public: TParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : - BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, Name) + unsigned CommandID) : + BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID) { } static bool classof(const Comment *C) { return C->getCommentKind() == TParamCommandCommentKind; } - static bool classof(const TParamCommandComment *) { return true; } - bool hasParamName() const { return getNumArgs() > 0; } - StringRef getParamName() const { + StringRef getParamName(const FullComment *FC) const; + + StringRef getParamNameAsWritten() const { return Args[0].Text; } @@ -807,8 +810,6 @@ public: return C->getCommentKind() == VerbatimBlockLineCommentKind; } - static bool classof(const VerbatimBlockLineComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -830,17 +831,15 @@ protected: public: VerbatimBlockComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : + unsigned CommandID) : BlockCommandComment(VerbatimBlockCommentKind, - LocBegin, LocEnd, Name) + LocBegin, LocEnd, CommandID) { } static bool classof(const Comment *C) { return C->getCommentKind() == VerbatimBlockCommentKind; } - static bool classof(const VerbatimBlockComment *) { return true; } - child_iterator child_begin() const { return reinterpret_cast<child_iterator>(Lines.begin()); } @@ -882,12 +881,12 @@ protected: public: VerbatimLineComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name, + unsigned CommandID, SourceLocation TextBegin, StringRef Text) : BlockCommandComment(VerbatimLineCommentKind, LocBegin, LocEnd, - Name), + CommandID), Text(Text), TextBegin(TextBegin) { } @@ -896,8 +895,6 @@ public: return C->getCommentKind() == VerbatimLineCommentKind; } - static bool classof(const VerbatimLineComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -913,23 +910,34 @@ public: /// Information about the declaration, useful to clients of FullComment. struct DeclInfo { - /// Declaration the comment is attached to. Should not be NULL. - const Decl *ThisDecl; - - /// Parameters that can be referenced by \\param if \c ThisDecl is something + /// Declaration the comment is actually attached to (in the source). + /// Should not be NULL. + const Decl *CommentDecl; + + /// CurrentDecl is the declaration with which the FullComment is associated. + /// + /// It can be different from \c CommentDecl. It happens when we we decide + /// that the comment originally attached to \c CommentDecl is fine for + /// \c CurrentDecl too (for example, for a redeclaration or an overrider of + /// \c CommentDecl). + /// + /// The information in the DeclInfo corresponds to CurrentDecl. + const Decl *CurrentDecl; + + /// Parameters that can be referenced by \\param if \c CommentDecl is something /// that we consider a "function". ArrayRef<const ParmVarDecl *> ParamVars; - /// Function result type if \c ThisDecl is something that we consider + /// Function result type if \c CommentDecl is something that we consider /// a "function". QualType ResultType; - /// Template parameters that can be referenced by \\tparam if \c ThisDecl is + /// Template parameters that can be referenced by \\tparam if \c CommentDecl is /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is /// true). const TemplateParameterList *TemplateParameters; - /// A simplified description of \c ThisDecl kind that should be good enough + /// A simplified description of \c CommentDecl kind that should be good enough /// for documentation rendering purposes. enum DeclKind { /// Everything else not explicitly mentioned below. @@ -942,7 +950,9 @@ struct DeclInfo { /// \li member function, /// \li member function template, /// \li member function template specialization, - /// \li ObjC method. + /// \li ObjC method, + /// \li a typedef for a function pointer, member function pointer, + /// ObjC block. FunctionKind, /// Something that we consider a "class": @@ -968,7 +978,7 @@ struct DeclInfo { EnumKind }; - /// What kind of template specialization \c ThisDecl is. + /// What kind of template specialization \c CommentDecl is. enum TemplateDeclKind { NotTemplate, Template, @@ -976,24 +986,24 @@ struct DeclInfo { TemplatePartialSpecialization }; - /// If false, only \c ThisDecl is valid. + /// If false, only \c CommentDecl is valid. unsigned IsFilled : 1; - /// Simplified kind of \c ThisDecl, see\c DeclKind enum. + /// Simplified kind of \c CommentDecl, see \c DeclKind enum. unsigned Kind : 3; - /// Is \c ThisDecl a template declaration. + /// Is \c CommentDecl a template declaration. unsigned TemplateKind : 2; - /// Is \c ThisDecl an ObjCMethodDecl. + /// Is \c CommentDecl an ObjCMethodDecl. unsigned IsObjCMethod : 1; - /// Is \c ThisDecl a non-static member function of C++ class or + /// Is \c CommentDecl a non-static member function of C++ class or /// instance method of ObjC class. /// Can be true only if \c IsFunctionDecl is true. unsigned IsInstanceMethod : 1; - /// Is \c ThisDecl a static member function of C++ class or + /// Is \c CommentDecl a static member function of C++ class or /// class method of ObjC class. /// Can be true only if \c IsFunctionDecl is true. unsigned IsClassMethod : 1; @@ -1012,7 +1022,6 @@ struct DeclInfo { /// A full comment attached to a declaration, contains block content. class FullComment : public Comment { llvm::ArrayRef<BlockContentComment *> Blocks; - DeclInfo *ThisDeclInfo; public: @@ -1031,27 +1040,31 @@ public: return C->getCommentKind() == FullCommentKind; } - static bool classof(const FullComment *) { return true; } - child_iterator child_begin() const { return reinterpret_cast<child_iterator>(Blocks.begin()); } child_iterator child_end() const { - return reinterpret_cast<child_iterator>(Blocks.end()); + return reinterpret_cast<child_iterator>(Blocks.end()); } const Decl *getDecl() const LLVM_READONLY { - return ThisDeclInfo->ThisDecl; + return ThisDeclInfo->CommentDecl; } - + const DeclInfo *getDeclInfo() const LLVM_READONLY { if (!ThisDeclInfo->IsFilled) ThisDeclInfo->fill(); return ThisDeclInfo; } + + DeclInfo *getThisDeclInfo() const LLVM_READONLY { + return ThisDeclInfo; + } + + llvm::ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; } + }; - } // end namespace comments } // end namespace clang diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h index 003c337..5d50886 100644 --- a/include/clang/AST/CommentBriefParser.h +++ b/include/clang/AST/CommentBriefParser.h @@ -44,8 +44,7 @@ class BriefParser { public: BriefParser(Lexer &L, const CommandTraits &Traits); - /// Return \\brief paragraph, if it exists; otherwise return the first - /// paragraph. + /// Return the best "brief description" we can find. std::string Parse(); }; diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h index 5f0269a..6d44c70 100644 --- a/include/clang/AST/CommentCommandTraits.h +++ b/include/clang/AST/CommentCommandTraits.h @@ -19,136 +19,132 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/ErrorHandling.h" namespace clang { namespace comments { -/// This class provides informaiton about commands that can be used -/// in comments. -class CommandTraits { -public: - CommandTraits() { } +/// \brief Information about a single command. +/// +/// When reordering, adding or removing members please update the corresponding +/// TableGen backend. +struct CommandInfo { + unsigned getID() const { + return ID; + } + + const char *Name; + + /// Name of the command that ends the verbatim block. + const char *EndCommandName; + + unsigned ID : 8; + + /// Number of word-like arguments for a given block command, except for + /// \\param and \\tparam commands -- these have special argument parsers. + unsigned NumArgs : 4; - /// \brief Check if a given command is a verbatim-like block command. + /// True if this command is a inline command (of any kind). + unsigned IsInlineCommand : 1; + + /// True if this command is a block command (of any kind). + unsigned IsBlockCommand : 1; + + /// True if this command is introducing a brief documentation + /// paragraph (\\brief or an alias). + unsigned IsBriefCommand : 1; + + /// True if this command is \\returns or an alias. + unsigned IsReturnsCommand : 1; + + /// True if this command is introducing documentation for a function + /// parameter (\\param or an alias). + unsigned IsParamCommand : 1; + + /// True if this command is introducing documentation for + /// a template parameter (\\tparam or an alias). + unsigned IsTParamCommand : 1; + + /// True if this command is \\deprecated or an alias. + unsigned IsDeprecatedCommand : 1; + + /// True if we don't want to warn about this command being passed an empty + /// paragraph. Meaningful only for block commands. + unsigned IsEmptyParagraphAllowed : 1; + + /// \brief True if this command is a verbatim-like block command. /// /// A verbatim-like block command eats every character (except line starting /// decorations) until matching end command is seen or comment end is hit. - /// - /// \param StartName name of the command that starts the verbatim block. - /// \param [out] EndName name of the command that ends the verbatim block. - /// - /// \returns true if a given command is a verbatim block command. - bool isVerbatimBlockCommand(StringRef StartName, StringRef &EndName) const; + unsigned IsVerbatimBlockCommand : 1; - /// \brief Register a new verbatim block command. - void addVerbatimBlockCommand(StringRef StartName, StringRef EndName); + /// \brief True if this command is an end command for a verbatim-like block. + unsigned IsVerbatimBlockEndCommand : 1; - /// \brief Check if a given command is a verbatim line command. + /// \brief True if this command is a verbatim line command. /// /// A verbatim-like line command eats everything until a newline is seen or /// comment end is hit. - bool isVerbatimLineCommand(StringRef Name) const; + unsigned IsVerbatimLineCommand : 1; - /// \brief Check if a given command is a command that contains a declaration - /// for the entity being documented. + /// \brief True if this command contains a declaration for the entity being + /// documented. /// /// For example: /// \code /// \fn void f(int a); /// \endcode - bool isDeclarationCommand(StringRef Name) const; + unsigned IsDeclarationCommand : 1; - /// \brief Register a new verbatim line command. - void addVerbatimLineCommand(StringRef Name); + /// \brief True if this command is unknown. This \c CommandInfo object was + /// created during parsing. + unsigned IsUnknownCommand : 1; +}; - /// \brief Check if a given command is a block command (of any kind). - bool isBlockCommand(StringRef Name) const; +/// This class provides information about commands that can be used +/// in comments. +class CommandTraits { +public: + CommandTraits(llvm::BumpPtrAllocator &Allocator); - /// \brief Check if a given command is introducing documentation for - /// a function parameter (\\param or an alias). - bool isParamCommand(StringRef Name) const; + /// \returns a CommandInfo object for a given command name or + /// NULL if no CommandInfo object exists for this command. + const CommandInfo *getCommandInfoOrNULL(StringRef Name) const; - /// \brief Check if a given command is introducing documentation for - /// a template parameter (\\tparam or an alias). - bool isTParamCommand(StringRef Name) const; + const CommandInfo *getCommandInfo(StringRef Name) const { + if (const CommandInfo *Info = getCommandInfoOrNULL(Name)) + return Info; + llvm_unreachable("the command should be known"); + } - /// \brief Check if a given command is introducing a brief documentation - /// paragraph (\\brief or an alias). - bool isBriefCommand(StringRef Name) const; + const CommandInfo *getCommandInfo(unsigned CommandID) const; - /// \brief Check if a given command is \\brief or an alias. - bool isReturnsCommand(StringRef Name) const; + const CommandInfo *registerUnknownCommand(StringRef CommandName); - /// \returns the number of word-like arguments for a given block command, - /// except for \\param and \\tparam commands -- these have special argument - /// parsers. - unsigned getBlockCommandNumArgs(StringRef Name) const; + /// \returns a CommandInfo object for a given command name or + /// NULL if \c Name is not a builtin command. + static const CommandInfo *getBuiltinCommandInfo(StringRef Name); - /// \brief Check if a given command is a inline command (of any kind). - bool isInlineCommand(StringRef Name) const; + /// \returns a CommandInfo object for a given command ID or + /// NULL if \c CommandID is not a builtin command. + static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID); private: - struct VerbatimBlockCommand { - StringRef StartName; - StringRef EndName; - }; - - typedef SmallVector<VerbatimBlockCommand, 4> VerbatimBlockCommandVector; + CommandTraits(const CommandTraits &) LLVM_DELETED_FUNCTION; + void operator=(const CommandTraits &) LLVM_DELETED_FUNCTION; - /// Registered additional verbatim-like block commands. - VerbatimBlockCommandVector VerbatimBlockCommands; + const CommandInfo *getRegisteredCommandInfo(StringRef Name) const; + const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const; - struct VerbatimLineCommand { - StringRef Name; - }; + unsigned NextID; - typedef SmallVector<VerbatimLineCommand, 4> VerbatimLineCommandVector; + /// Allocator for CommandInfo objects. + llvm::BumpPtrAllocator &Allocator; - /// Registered verbatim-like line commands. - VerbatimLineCommandVector VerbatimLineCommands; + SmallVector<CommandInfo *, 4> RegisteredCommands; }; -inline bool CommandTraits::isBlockCommand(StringRef Name) const { - return isBriefCommand(Name) || isReturnsCommand(Name) || - isParamCommand(Name) || isTParamCommand(Name) || - llvm::StringSwitch<bool>(Name) - .Case("author", true) - .Case("authors", true) - .Case("pre", true) - .Case("post", true) - .Default(false); -} - -inline bool CommandTraits::isParamCommand(StringRef Name) const { - return Name == "param"; -} - -inline bool CommandTraits::isTParamCommand(StringRef Name) const { - return Name == "tparam" || // Doxygen - Name == "templatefield"; // HeaderDoc -} - -inline bool CommandTraits::isBriefCommand(StringRef Name) const { - return Name == "brief" || Name == "short"; -} - -inline bool CommandTraits::isReturnsCommand(StringRef Name) const { - return Name == "returns" || Name == "return" || Name == "result"; -} - -inline unsigned CommandTraits::getBlockCommandNumArgs(StringRef Name) const { - return 0; -} - -inline bool CommandTraits::isInlineCommand(StringRef Name) const { - return llvm::StringSwitch<bool>(Name) - .Case("b", true) - .Cases("c", "p", true) - .Cases("a", "e", "em", true) - .Default(false); -} - } // end namespace comments } // end namespace clang diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td new file mode 100644 index 0000000..3d8bad8 --- /dev/null +++ b/include/clang/AST/CommentCommands.td @@ -0,0 +1,156 @@ +class Command<string name> { + string Name = name; + string EndCommandName = ""; + + int NumArgs = 0; + + bit IsInlineCommand = 0; + + bit IsBlockCommand = 0; + bit IsBriefCommand = 0; + bit IsReturnsCommand = 0; + bit IsParamCommand = 0; + bit IsTParamCommand = 0; + bit IsDeprecatedCommand = 0; + + bit IsEmptyParagraphAllowed = 0; + + bit IsVerbatimBlockCommand = 0; + bit IsVerbatimBlockEndCommand = 0; + bit IsVerbatimLineCommand = 0; + bit IsDeclarationCommand = 0; +} + +class InlineCommand<string name> : Command<name> { + let IsInlineCommand = 1; +} + +class BlockCommand<string name> : Command<name> { + let IsBlockCommand = 1; +} + +class VerbatimBlockCommand<string name> : Command<name> { + let EndCommandName = name; + let IsVerbatimBlockCommand = 1; +} + +multiclass VerbatimBlockCommand<string name, string endCommandName> { + def Begin : Command<name> { + let EndCommandName = endCommandName; + let IsVerbatimBlockCommand = 1; + } + + def End : Command<endCommandName> { + let IsVerbatimBlockEndCommand = 1; + } +} + +class VerbatimLineCommand<string name> : Command<name> { + let IsVerbatimLineCommand = 1; +} + +class DeclarationVerbatimLineCommand<string name> : + VerbatimLineCommand<name> { + let IsDeclarationCommand = 1; +} + +def B : InlineCommand<"b">; +def C : InlineCommand<"c">; +def P : InlineCommand<"p">; +def A : InlineCommand<"a">; +def E : InlineCommand<"e">; +def Em : InlineCommand<"em">; + +def Brief : BlockCommand<"brief"> { let IsBriefCommand = 1; } +def Short : BlockCommand<"short"> { let IsBriefCommand = 1; } + +def Returns : BlockCommand<"returns"> { let IsReturnsCommand = 1; } +def Return : BlockCommand<"return"> { let IsReturnsCommand = 1; } +def Result : BlockCommand<"result"> { let IsReturnsCommand = 1; } + +def Param : BlockCommand<"param"> { let IsParamCommand = 1; } + +// Doxygen +def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; } + +// HeaderDoc +def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; } + +def Deprecated : BlockCommand<"deprecated"> { + let IsEmptyParagraphAllowed = 1; + let IsDeprecatedCommand = 1; +} + +def Author : BlockCommand<"author">; +def Authors : BlockCommand<"authors">; +def Bug : BlockCommand<"bug">; +def Copyright : BlockCommand<"copyright">; +def Date : BlockCommand<"date">; +def Details : BlockCommand<"details">; +def Invariant : BlockCommand<"invariant">; +def Note : BlockCommand<"note">; +def Post : BlockCommand<"post">; +def Pre : BlockCommand<"pre">; +def Remark : BlockCommand<"remark">; +def Remarks : BlockCommand<"remarks">; +def Sa : BlockCommand<"sa">; +def See : BlockCommand<"see">; +def Since : BlockCommand<"since">; +def Todo : BlockCommand<"todo">; +def Version : BlockCommand<"version">; +def Warning : BlockCommand<"warning">; + +defm Code : VerbatimBlockCommand<"code", "endcode">; +defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">; +defm Htmlonly : VerbatimBlockCommand<"htmlonly", "endhtmlonly">; +defm Latexonly : VerbatimBlockCommand<"latexonly", "endlatexonly">; +defm Xmlonly : VerbatimBlockCommand<"xmlonly", "endxmlonly">; +defm Manonly : VerbatimBlockCommand<"manonly", "endmanonly">; +defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">; + +defm Dot : VerbatimBlockCommand<"dot", "enddot">; +defm Msc : VerbatimBlockCommand<"msc", "endmsc">; + +// These commands have special support in lexer. +def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula +defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula +defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment + +def Defgroup : VerbatimLineCommand<"defgroup">; +def Ingroup : VerbatimLineCommand<"ingroup">; +def Addtogroup : VerbatimLineCommand<"addtogroup">; +def Weakgroup : VerbatimLineCommand<"weakgroup">; +def Name : VerbatimLineCommand<"name">; + +def Section : VerbatimLineCommand<"section">; +def Subsection : VerbatimLineCommand<"subsection">; +def Subsubsection : VerbatimLineCommand<"subsubsection">; +def Paragraph : VerbatimLineCommand<"paragraph">; + +def Mainpage : VerbatimLineCommand<"mainpage">; +def Subpage : VerbatimLineCommand<"subpage">; +def Ref : VerbatimLineCommand<"ref">; + +// Doxygen commands. +def Fn : DeclarationVerbatimLineCommand<"fn">; +def Namespace : DeclarationVerbatimLineCommand<"namespace">; +def Overload : DeclarationVerbatimLineCommand<"overload">; +def Property : DeclarationVerbatimLineCommand<"property">; +def Typedef : DeclarationVerbatimLineCommand<"typedef">; +def Var : DeclarationVerbatimLineCommand<"var">; + +// HeaderDoc commands. +def Class : DeclarationVerbatimLineCommand<"class">; +def Interface : DeclarationVerbatimLineCommand<"interface">; +def Protocol : DeclarationVerbatimLineCommand<"protocol">; +def Category : DeclarationVerbatimLineCommand<"category">; +def Template : DeclarationVerbatimLineCommand<"template">; +def Function : DeclarationVerbatimLineCommand<"function">; +def Method : DeclarationVerbatimLineCommand<"method">; +def Callback : DeclarationVerbatimLineCommand<"callback">; +def Const : DeclarationVerbatimLineCommand<"const">; +def Constant : DeclarationVerbatimLineCommand<"constant">; +def Struct : DeclarationVerbatimLineCommand<"struct">; +def Union : DeclarationVerbatimLineCommand<"union">; +def Enum : DeclarationVerbatimLineCommand<"enum">; + diff --git a/include/clang/AST/CommentHTMLTags.td b/include/clang/AST/CommentHTMLTags.td new file mode 100644 index 0000000..f98e32d --- /dev/null +++ b/include/clang/AST/CommentHTMLTags.td @@ -0,0 +1,54 @@ +class Tag<string spelling> { + string Spelling = spelling; + bit EndTagOptional = 0; + bit EndTagForbidden = 0; +} + +def Em : Tag<"em">; +def Strong : Tag<"strong">; +def Tt : Tag<"tt">; +def I : Tag<"i">; +def B : Tag<"b">; +def Big : Tag<"big">; +def Small : Tag<"small">; +def Strike : Tag<"strike">; +def S : Tag<"s">; +def U : Tag<"u">; +def Font : Tag<"font">; +def A : Tag<"a">; +def Hr : Tag<"hr"> { let EndTagForbidden = 1; } +def Div : Tag<"div">; +def Span : Tag<"span">; +def H1 : Tag<"h1">; +def H2 : Tag<"h2">; +def H3 : Tag<"h3">; +def H4 : Tag<"h4">; +def H5 : Tag<"h5">; +def H6 : Tag<"h6">; +def Code : Tag<"code">; +def Blockquote : Tag<"blockquote">; +def Sub : Tag<"sub">; +def Sup : Tag<"sup">; +def Img : Tag<"img"> { let EndTagForbidden = 1; } +def P : Tag<"p"> { let EndTagOptional = 1; } +def Br : Tag<"br"> { let EndTagForbidden = 1; } +def Pre : Tag<"pre">; +def Ins : Tag<"ins">; +def Del : Tag<"del">; +def Ul : Tag<"ul">; +def Ol : Tag<"ol">; +def Li : Tag<"li"> { let EndTagOptional = 1; } +def Dl : Tag<"dl">; +def Dt : Tag<"dt"> { let EndTagOptional = 1; } +def Dd : Tag<"dd"> { let EndTagOptional = 1; } +def Table : Tag<"table">; +def Caption : Tag<"caption">; +def Thead : Tag<"thead"> { let EndTagOptional = 1; } +def Tfoot : Tag<"tfoot"> { let EndTagOptional = 1; } +def Tbody : Tag<"tbody"> { let EndTagOptional = 1; } +def Colgroup : Tag<"colgroup"> { let EndTagOptional = 1; } +def Col : Tag<"col"> { let EndTagForbidden = 1; } +def Tr : Tag<"tr"> { let EndTagOptional = 1; } +def Th : Tag<"th"> { let EndTagOptional = 1; } +def Td : Tag<"td"> { let EndTagOptional = 1; } + diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h index 7a24b11..f263697 100644 --- a/include/clang/AST/CommentLexer.h +++ b/include/clang/AST/CommentLexer.h @@ -26,6 +26,7 @@ namespace comments { class Lexer; class TextTokenRetokenizer; +struct CommandInfo; class CommandTraits; namespace tok { @@ -33,7 +34,8 @@ enum TokenKind { eof, newline, text, - command, + unknown_command, // Command that does not have an ID. + command, // Command with an ID. verbatim_block_begin, verbatim_block_line, verbatim_block_end, @@ -49,11 +51,6 @@ enum TokenKind { }; } // end namespace tok -class CommentOptions { -public: - bool Markdown; -}; - /// \brief Comment token. class Token { friend class Lexer; @@ -70,8 +67,14 @@ class Token { unsigned Length; /// Contains text value associated with a token. - const char *TextPtr1; - unsigned TextLen1; + const char *TextPtr; + + /// Integer value associated with a token. + /// + /// If the token is a konwn command, contains command ID and TextPtr is + /// unused (command spelling can be found with CommandTraits). Otherwise, + /// contains the length of the string that starts at TextPtr. + unsigned IntVal; public: SourceLocation getLocation() const LLVM_READONLY { return Loc; } @@ -94,113 +97,120 @@ public: StringRef getText() const LLVM_READONLY { assert(is(tok::text)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setText(StringRef Text) { assert(is(tok::text)); - TextPtr1 = Text.data(); - TextLen1 = Text.size(); + TextPtr = Text.data(); + IntVal = Text.size(); + } + + StringRef getUnknownCommandName() const LLVM_READONLY { + assert(is(tok::unknown_command)); + return StringRef(TextPtr, IntVal); + } + + void setUnknownCommandName(StringRef Name) { + assert(is(tok::unknown_command)); + TextPtr = Name.data(); + IntVal = Name.size(); } - StringRef getCommandName() const LLVM_READONLY { + unsigned getCommandID() const LLVM_READONLY { assert(is(tok::command)); - return StringRef(TextPtr1, TextLen1); + return IntVal; } - void setCommandName(StringRef Name) { + void setCommandID(unsigned ID) { assert(is(tok::command)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + IntVal = ID; } - StringRef getVerbatimBlockName() const LLVM_READONLY { + unsigned getVerbatimBlockID() const LLVM_READONLY { assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end)); - return StringRef(TextPtr1, TextLen1); + return IntVal; } - void setVerbatimBlockName(StringRef Name) { + void setVerbatimBlockID(unsigned ID) { assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + IntVal = ID; } StringRef getVerbatimBlockText() const LLVM_READONLY { assert(is(tok::verbatim_block_line)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setVerbatimBlockText(StringRef Text) { assert(is(tok::verbatim_block_line)); - TextPtr1 = Text.data(); - TextLen1 = Text.size(); + TextPtr = Text.data(); + IntVal = Text.size(); } - /// Returns the name of verbatim line command. - StringRef getVerbatimLineName() const LLVM_READONLY { + unsigned getVerbatimLineID() const LLVM_READONLY { assert(is(tok::verbatim_line_name)); - return StringRef(TextPtr1, TextLen1); + return IntVal; } - void setVerbatimLineName(StringRef Name) { + void setVerbatimLineID(unsigned ID) { assert(is(tok::verbatim_line_name)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + IntVal = ID; } StringRef getVerbatimLineText() const LLVM_READONLY { assert(is(tok::verbatim_line_text)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setVerbatimLineText(StringRef Text) { assert(is(tok::verbatim_line_text)); - TextPtr1 = Text.data(); - TextLen1 = Text.size(); + TextPtr = Text.data(); + IntVal = Text.size(); } StringRef getHTMLTagStartName() const LLVM_READONLY { assert(is(tok::html_start_tag)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setHTMLTagStartName(StringRef Name) { assert(is(tok::html_start_tag)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + TextPtr = Name.data(); + IntVal = Name.size(); } StringRef getHTMLIdent() const LLVM_READONLY { assert(is(tok::html_ident)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setHTMLIdent(StringRef Name) { assert(is(tok::html_ident)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + TextPtr = Name.data(); + IntVal = Name.size(); } StringRef getHTMLQuotedString() const LLVM_READONLY { assert(is(tok::html_quoted_string)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setHTMLQuotedString(StringRef Str) { assert(is(tok::html_quoted_string)); - TextPtr1 = Str.data(); - TextLen1 = Str.size(); + TextPtr = Str.data(); + IntVal = Str.size(); } StringRef getHTMLTagEndName() const LLVM_READONLY { assert(is(tok::html_end_tag)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setHTMLTagEndName(StringRef Name) { assert(is(tok::html_end_tag)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + TextPtr = Name.data(); + IntVal = Name.size(); } void dump(const Lexer &L, const SourceManager &SM) const; @@ -209,8 +219,8 @@ public: /// \brief Comment lexer. class Lexer { private: - Lexer(const Lexer&); // DO NOT IMPLEMENT - void operator=(const Lexer&); // DO NOT IMPLEMENT + Lexer(const Lexer &) LLVM_DELETED_FUNCTION; + void operator=(const Lexer &) LLVM_DELETED_FUNCTION; /// Allocator for strings that are semantic values of tokens and have to be /// computed (for example, resolved decimal character references). @@ -221,7 +231,6 @@ private: const char *const BufferStart; const char *const BufferEnd; SourceLocation FileLoc; - CommentOptions CommOpts; const char *BufferPtr; @@ -286,8 +295,8 @@ private: Result.setKind(Kind); Result.setLength(TokLen); #ifndef NDEBUG - Result.TextPtr1 = "<UNSET>"; - Result.TextLen1 = 7; + Result.TextPtr = "<UNSET>"; + Result.IntVal = 7; #endif BufferPtr = TokEnd; } @@ -314,13 +323,14 @@ private: void setupAndLexVerbatimBlock(Token &T, const char *TextBegin, - char Marker, StringRef EndName); + char Marker, const CommandInfo *Info); void lexVerbatimBlockFirstLine(Token &T); void lexVerbatimBlockBody(Token &T); - void setupAndLexVerbatimLine(Token &T, const char *TextBegin); + void setupAndLexVerbatimLine(Token &T, const char *TextBegin, + const CommandInfo *Info); void lexVerbatimLineText(Token &T); @@ -336,7 +346,7 @@ private: public: Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits, - SourceLocation FileLoc, const CommentOptions &CommOpts, + SourceLocation FileLoc, const char *BufferStart, const char *BufferEnd); void lex(Token &T); diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h index 0390799..19e1d57 100644 --- a/include/clang/AST/CommentParser.h +++ b/include/clang/AST/CommentParser.h @@ -28,8 +28,8 @@ class CommandTraits; /// Doxygen comment parser. class Parser { - Parser(const Parser&); // DO NOT IMPLEMENT - void operator=(const Parser&); // DO NOT IMPLEMENT + Parser(const Parser &) LLVM_DELETED_FUNCTION; + void operator=(const Parser &) LLVM_DELETED_FUNCTION; friend class TextTokenRetokenizer; diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index e1756ca..0340b3c 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -25,13 +25,14 @@ namespace clang { class Decl; class SourceMgr; +class Preprocessor; namespace comments { class CommandTraits; class Sema { - Sema(const Sema&); // DO NOT IMPLEMENT - void operator=(const Sema&); // DO NOT IMPLEMENT + Sema(const Sema &) LLVM_DELETED_FUNCTION; + void operator=(const Sema &) LLVM_DELETED_FUNCTION; /// Allocator for AST nodes. llvm::BumpPtrAllocator &Allocator; @@ -41,18 +42,13 @@ class Sema { DiagnosticsEngine &Diags; - const CommandTraits &Traits; + CommandTraits &Traits; + + const Preprocessor *PP; /// Information about the declaration this comment is attached to. DeclInfo *ThisDeclInfo; - /// Comment AST nodes that correspond to \c ParamVars for which we have - /// found a \\param command or NULL if no documentation was found so far. - /// - /// Has correct size and contains valid values if \c DeclInfo->IsFilled is - /// true. - llvm::SmallVector<ParamCommandComment *, 8> ParamVarDocs; - /// Comment AST nodes that correspond to parameter names in /// \c TemplateParameters. /// @@ -75,7 +71,8 @@ class Sema { public: Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, - DiagnosticsEngine &Diags, const CommandTraits &Traits); + DiagnosticsEngine &Diags, CommandTraits &Traits, + const Preprocessor *PP); void setDecl(const Decl *D); @@ -96,7 +93,7 @@ public: BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + unsigned CommandID); void actOnBlockCommandArgs(BlockCommandComment *Command, ArrayRef<BlockCommandComment::Argument> Args); @@ -106,7 +103,7 @@ public: ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + unsigned CommandID); void actOnParamCommandDirectionArg(ParamCommandComment *Command, SourceLocation ArgLocBegin, @@ -123,7 +120,7 @@ public: TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + unsigned CommandID); void actOnTParamCommandParamNameArg(TParamCommandComment *Command, SourceLocation ArgLocBegin, @@ -135,25 +132,29 @@ public: InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin, SourceLocation CommandLocEnd, - StringRef CommandName); + unsigned CommandID); InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin, SourceLocation CommandLocEnd, - StringRef CommandName, + unsigned CommandID, SourceLocation ArgLocBegin, SourceLocation ArgLocEnd, StringRef Arg); InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + StringRef CommandName); + + InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin, + SourceLocation LocEnd, + unsigned CommandID); TextComment *actOnText(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Text); VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc, - StringRef Name); + unsigned CommandID); VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc, StringRef Text); @@ -164,7 +165,7 @@ public: ArrayRef<VerbatimBlockLineComment *> Lines); VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin, - StringRef Name, + unsigned CommandID, SourceLocation TextBegin, StringRef Text); @@ -190,6 +191,12 @@ public: /// used only once per comment, e.g., \\brief and \\returns. void checkBlockCommandDuplicate(const BlockCommandComment *Command); + void checkDeprecatedCommand(const BlockCommandComment *Comment); + + /// Resolve parameter names to parameter indexes in function declaration. + /// Emit diagnostics about unknown parametrs. + void resolveParamCommandIndexes(const FullComment *FC); + bool isFunctionDecl(); bool isTemplateOrSpecialization(); @@ -218,9 +225,6 @@ public: InlineCommandComment::RenderKind getInlineCommandRenderKind(StringRef Name) const; - - bool isHTMLEndTagOptional(StringRef Name); - bool isHTMLEndTagForbidden(StringRef Name); }; } // end namespace comments diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index e9f25b3..087a585 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -88,7 +88,6 @@ public: static TranslationUnitDecl *Create(ASTContext &C); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TranslationUnitDecl *D) { return true; } static bool classofKind(Kind K) { return K == TranslationUnit; } static DeclContext *castToDeclContext(const TranslationUnitDecl *D) { return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D)); @@ -214,16 +213,19 @@ public: bool isCXXInstanceMember() const; class LinkageInfo { - Linkage linkage_; - Visibility visibility_; - bool explicit_; + uint8_t linkage_ : 2; + uint8_t visibility_ : 2; + uint8_t explicit_ : 1; void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } public: LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), explicit_(false) {} LinkageInfo(Linkage L, Visibility V, bool E) - : linkage_(L), visibility_(V), explicit_(E) {} + : linkage_(L), visibility_(V), explicit_(E) { + assert(linkage() == L && visibility() == V && visibilityExplicit() == E && + "Enum truncated!"); + } static LinkageInfo external() { return LinkageInfo(); @@ -238,8 +240,8 @@ public: return LinkageInfo(NoLinkage, DefaultVisibility, false); } - Linkage linkage() const { return linkage_; } - Visibility visibility() const { return visibility_; } + Linkage linkage() const { return (Linkage)linkage_; } + Visibility visibility() const { return (Visibility)visibility_; } bool visibilityExplicit() const { return explicit_; } void setLinkage(Linkage L) { linkage_ = L; } @@ -337,7 +339,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NamedDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; } }; @@ -383,7 +384,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const LabelDecl *D) { return true; } static bool classofKind(Kind K) { return K == Label; } }; @@ -509,7 +509,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NamespaceDecl *D) { return true; } static bool classofKind(Kind K) { return K == Namespace; } static DeclContext *castToDeclContext(const NamespaceDecl *D) { return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D)); @@ -545,7 +544,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ValueDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; } }; @@ -578,8 +576,8 @@ struct QualifierInfo { private: // Copy constructor and copy assignment are disabled. - QualifierInfo(const QualifierInfo&); - QualifierInfo& operator=(const QualifierInfo&); + QualifierInfo(const QualifierInfo&) LLVM_DELETED_FUNCTION; + QualifierInfo& operator=(const QualifierInfo&) LLVM_DELETED_FUNCTION; }; /// \brief Represents a ValueDecl that came out of a declarator. @@ -666,7 +664,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const DeclaratorDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstDeclarator && K <= lastDeclarator; } @@ -712,7 +709,7 @@ public: typedef clang::StorageClass StorageClass; /// getStorageClassSpecifierString - Return the string used to - /// specify the storage class \arg SC. + /// specify the storage class \p SC. /// /// It is illegal to call this function with SC == None. static const char *getStorageClassSpecifierString(StorageClass SC); @@ -1208,7 +1205,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const VarDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; } }; @@ -1229,7 +1225,6 @@ public: } // Implement isa/cast/dyncast/etc. - static bool classof(const ImplicitParamDecl *D) { return true; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ImplicitParam; } }; @@ -1399,7 +1394,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ParmVarDecl *D) { return true; } static bool classofKind(Kind K) { return K == ParmVar; } private: @@ -2070,7 +2064,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FunctionDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstFunction && K <= lastFunction; } @@ -2204,7 +2197,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FieldDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstField && K <= lastField; } friend class ASTDeclReader; @@ -2243,7 +2235,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const EnumConstantDecl *D) { return true; } static bool classofKind(Kind K) { return K == EnumConstant; } friend class StmtIteratorBase; @@ -2287,7 +2278,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const IndirectFieldDecl *D) { return true; } static bool classofKind(Kind K) { return K == IndirectField; } friend class ASTDeclReader; }; @@ -2334,7 +2324,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypeDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstType && K <= lastType; } }; @@ -2390,7 +2379,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypedefNameDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstTypedefName && K <= lastTypedefName; } @@ -2413,7 +2401,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypedefDecl *D) { return true; } static bool classofKind(Kind K) { return K == Typedef; } }; @@ -2434,7 +2421,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypeAliasDecl *D) { return true; } static bool classofKind(Kind K) { return K == TypeAlias; } }; @@ -2448,7 +2434,7 @@ public: private: // FIXME: This can be packed into the bitfields in Decl. /// TagDeclKind - The TagKind enum. - unsigned TagDeclKind : 2; + unsigned TagDeclKind : 3; /// IsCompleteDefinition - True if this is a definition ("struct foo /// {};"), false if it is a declaration ("struct foo;"). It is not @@ -2625,6 +2611,7 @@ public: void setTagKind(TagKind TK) { TagDeclKind = TK; } bool isStruct() const { return getTagKind() == TTK_Struct; } + bool isInterface() const { return getTagKind() == TTK_Interface; } bool isClass() const { return getTagKind() == TTK_Class; } bool isUnion() const { return getTagKind() == TTK_Union; } bool isEnum() const { return getTagKind() == TTK_Enum; } @@ -2665,7 +2652,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TagDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; } static DeclContext *castToDeclContext(const TagDecl *D) { @@ -2895,7 +2881,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const EnumDecl *D) { return true; } static bool classofKind(Kind K) { return K == Enum; } friend class ASTDeclReader; @@ -3026,11 +3011,15 @@ public: virtual void completeDefinition(); static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const RecordDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstRecord && K <= lastRecord; } + /// isMsStrust - Get whether or not this is an ms_struct which can + /// be turned on with an attribute, pragma, or -mms-bitfields + /// commandline option. + bool isMsStruct(const ASTContext &C) const; + private: /// \brief Deserialize just the fields. void LoadFieldsFromExternalStorage() const; @@ -3062,7 +3051,6 @@ public: void setAsmString(StringLiteral *Asm) { AsmString = Asm; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FileScopeAsmDecl *D) { return true; } static bool classofKind(Kind K) { return K == FileScopeAsm; } }; @@ -3208,7 +3196,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const BlockDecl *D) { return true; } static bool classofKind(Kind K) { return K == Block; } static DeclContext *castToDeclContext(const BlockDecl *D) { return static_cast<DeclContext *>(const_cast<BlockDecl*>(D)); @@ -3282,7 +3269,6 @@ public: virtual SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ImportDecl *D) { return true; } static bool classofKind(Kind K) { return K == Import; } }; diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 0f59609..50e2027 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -430,16 +430,10 @@ public: void dropAttr() { if (!HasAttrs) return; - AttrVec &Attrs = getAttrs(); - for (unsigned i = 0, e = Attrs.size(); i != e; /* in loop */) { - if (isa<T>(Attrs[i])) { - Attrs.erase(Attrs.begin() + i); - --e; - } - else - ++i; - } - if (Attrs.empty()) + AttrVec &Vec = getAttrs(); + Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa<T, Attr*>), Vec.end()); + + if (Vec.empty()) HasAttrs = false; } @@ -844,8 +838,6 @@ public: IdentifierNamespace |= IDNS_NonMemberOperator; } - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *) { return true; } static bool classofKind(Kind K) { return true; } static DeclContext *castToDeclContext(const Decl *); static Decl *castFromDeclContext(const DeclContext *); @@ -1479,6 +1471,13 @@ public: inline ddiag_iterator ddiag_end() const; // Low-level accessors + + /// \brief Mark the lookup table as needing to be built. This should be + /// used only if setHasExternalLexicalStorage() has been called. + void setMustBuildLookupTable() { + assert(ExternalLexicalStorage && "Requires external lexical storage"); + LookupPtr.setInt(true); + } /// \brief Retrieve the internal representation of the lookup structure. /// This may omit some names if we are lazily building the structure. @@ -1516,10 +1515,6 @@ public: static bool classof(const Decl *D); static bool classof(const DeclContext *D) { return true; } -#define DECL(NAME, BASE) -#define DECL_CONTEXT(NAME) \ - static bool classof(const NAME##Decl *D) { return true; } -#include "clang/AST/DeclNodes.inc" LLVM_ATTRIBUTE_USED void dumpDeclContext() const; diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 2d95f03..9cb56e2 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -145,7 +145,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const AccessSpecDecl *D) { return true; } static bool classofKind(Kind K) { return K == AccessSpec; } }; @@ -563,9 +562,10 @@ class CXXRecordDecl : public RecordDecl { struct LambdaDefinitionData : public DefinitionData { typedef LambdaExpr::Capture Capture; - LambdaDefinitionData(CXXRecordDecl *D, bool Dependent) + LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent) : DefinitionData(D), Dependent(Dependent), NumCaptures(0), - NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0) + NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0), + MethodTyInfo(Info) { IsLambda = true; } @@ -598,7 +598,10 @@ class CXXRecordDecl : public RecordDecl { /// \brief The list of captures, both explicit and implicit, for this /// lambda. - Capture *Captures; + Capture *Captures; + + /// \brief The type of the call method. + TypeSourceInfo *MethodTyInfo; }; struct DefinitionData &data() { @@ -705,7 +708,8 @@ public: IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0, bool DelayTypeCreation = false); static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC, - SourceLocation Loc, bool DependentLambda); + TypeSourceInfo *Info, SourceLocation Loc, + bool DependentLambda); static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); bool isDynamicClass() const { @@ -1303,7 +1307,7 @@ public: /// \brief Function type used by forallBases() as a callback. /// - /// \param Base the definition of the base class + /// \param BaseDefinition the definition of the base class /// /// \returns true if this base matched the search criteria typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition, @@ -1500,15 +1504,15 @@ public: bool isDependentLambda() const { return isLambda() && getLambdaData().Dependent; } - + + TypeSourceInfo *getLambdaTypeInfo() const { + return getLambdaData().MethodTyInfo; + } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstCXXRecord && K <= lastCXXRecord; } - static bool classof(const CXXRecordDecl *D) { return true; } - static bool classof(const ClassTemplateSpecializationDecl *D) { - return true; - } friend class ASTDeclReader; friend class ASTDeclWriter; @@ -1549,14 +1553,16 @@ public: bool isStatic() const { return getStorageClass() == SC_Static; } bool isInstance() const { return !isStatic(); } - bool isConst() { return getType()->castAs<FunctionType>()->isConst(); } - bool isVolatile() { return getType()->castAs<FunctionType>()->isVolatile(); } + bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); } + bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); } bool isVirtual() const { CXXMethodDecl *CD = cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl()); - if (CD->isVirtualAsWritten()) + // Methods declared in interfaces are automatically (pure) virtual. + if (CD->isVirtualAsWritten() || + (CD->getParent()->isInterface() && CD->isUserProvided())) return true; return (CD->begin_overridden_methods() != CD->end_overridden_methods()); @@ -1661,7 +1667,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const CXXMethodDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstCXXMethod && K <= lastCXXMethod; } @@ -2141,7 +2146,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const CXXConstructorDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXConstructor; } friend class ASTDeclReader; @@ -2213,7 +2217,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const CXXDestructorDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXDestructor; } friend class ASTDeclReader; @@ -2280,7 +2283,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const CXXConversionDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXConversion; } friend class ASTDeclReader; @@ -2350,7 +2352,6 @@ public: } 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; } static DeclContext *castToDeclContext(const LinkageSpecDecl *D) { return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D)); @@ -2454,7 +2455,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UsingDirectiveDecl *D) { return true; } static bool classofKind(Kind K) { return K == UsingDirective; } // Friend for getUsingDirectiveName. @@ -2548,7 +2548,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NamespaceAliasDecl *D) { return true; } static bool classofKind(Kind K) { return K == NamespaceAlias; } }; @@ -2619,7 +2618,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UsingShadowDecl *D) { return true; } static bool classofKind(Kind K) { return K == Decl::UsingShadow; } friend class ASTDeclReader; @@ -2751,7 +2749,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UsingDecl *D) { return true; } static bool classofKind(Kind K) { return K == Using; } friend class ASTDeclReader; @@ -2825,7 +2822,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UnresolvedUsingValueDecl *D) { return true; } static bool classofKind(Kind K) { return K == UnresolvedUsingValue; } friend class ASTDeclReader; @@ -2891,7 +2887,6 @@ public: CreateDeserialized(ASTContext &C, unsigned ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; } static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; } }; @@ -2931,7 +2926,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(StaticAssertDecl *D) { return true; } static bool classofKind(Kind K) { return K == StaticAssert; } friend class ASTDeclReader; diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 9a64f08..37e4586 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_AST_DECLFRIEND_H #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" #include "llvm/Support/Compiler.h" namespace clang { @@ -104,9 +105,15 @@ public: /// Retrieves the source range for the friend declaration. SourceRange getSourceRange() const LLVM_READONLY { - /* FIXME: consider the case of templates wrt start of range. */ - if (NamedDecl *ND = getFriendDecl()) + if (NamedDecl *ND = getFriendDecl()) { + if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND)) + return FTD->getSourceRange(); + if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) { + if (DD->getOuterLocStart() != DD->getInnerLocStart()) + return DD->getSourceRange(); + } return SourceRange(getFriendLoc(), ND->getLocEnd()); + } else if (TypeSourceInfo *TInfo = getFriendType()) return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc()); else @@ -123,7 +130,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FriendDecl *D) { return true; } static bool classofKind(Kind K) { return K == Decl::Friend; } friend class ASTDeclReader; diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 6c39f2c..8b27dd8 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -33,8 +33,8 @@ class ObjCPropertyImplDecl; class CXXCtorInitializer; class ObjCListBase { - void operator=(const ObjCListBase &); // DO NOT IMPLEMENT - ObjCListBase(const ObjCListBase&); // DO NOT IMPLEMENT + ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION; + void operator=(const ObjCListBase &) LLVM_DELETED_FUNCTION; protected: /// List is an array of pointers to objects that are not owned by this object. void **List; @@ -123,8 +123,8 @@ private: unsigned IsInstance : 1; unsigned IsVariadic : 1; - // Synthesized declaration method for a property setter/getter - unsigned IsSynthesized : 1; + /// True if this method is the getter or setter for an explicit property. + unsigned IsPropertyAccessor : 1; // Method has a definition. unsigned IsDefined : 1; @@ -174,8 +174,7 @@ private: SourceLocation DeclEndLoc; // the location of the ';' or '{'. // The following are only used for method definitions, null otherwise. - // FIXME: space savings opportunity, consider a sub-class. - Stmt *Body; + LazyDeclStmtPtr Body; /// SelfDecl - Decl for the implicit self parameter. This is lazily /// constructed by createImplicitParams. @@ -227,7 +226,7 @@ private: DeclContext *contextDecl, bool isInstance = true, bool isVariadic = false, - bool isSynthesized = false, + bool isPropertyAccessor = false, bool isImplicitlyDeclared = false, bool isDefined = false, ImplementationControl impControl = None, @@ -235,14 +234,14 @@ private: : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), IsInstance(isInstance), IsVariadic(isVariadic), - IsSynthesized(isSynthesized), + IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), RelatedResultType(HasRelatedResultType), SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), MethodDeclType(T), ResultTInfo(ResultTInfo), ParamsAndSelLocs(0), NumParams(0), - DeclEndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) { + DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) { setImplicit(isImplicitlyDeclared); } @@ -261,7 +260,7 @@ public: DeclContext *contextDecl, bool isInstance = true, bool isVariadic = false, - bool isSynthesized = false, + bool isPropertyAccessor = false, bool isImplicitlyDeclared = false, bool isDefined = false, ImplementationControl impControl = None, @@ -363,7 +362,7 @@ public: } /// \brief Sets the method's parameters and selector source locations. - /// If the method is implicit (not coming from source) \arg SelLocs is + /// If the method is implicit (not coming from source) \p SelLocs is /// ignored. void setMethodParams(ASTContext &C, ArrayRef<ParmVarDecl*> Params, @@ -403,8 +402,8 @@ public: bool isClassMethod() const { return !IsInstance; } - bool isSynthesized() const { return IsSynthesized; } - void setSynthesized(bool isSynth) { IsSynthesized = isSynth; } + bool isPropertyAccessor() const { return IsPropertyAccessor; } + void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; } bool isDefined() const { return IsDefined; } void setDefined(bool isDefined) { IsDefined = isDefined; } @@ -418,7 +417,25 @@ public: /// method in the interface or its categories. bool isOverriding() const { return IsOverriding; } void setOverriding(bool isOverriding) { IsOverriding = isOverriding; } - + + /// \brief Return overridden methods for the given \p Method. + /// + /// An ObjC method is considered to override any method in the class's + /// base classes (and base's categories), its protocols, or its categories' + /// protocols, that has + /// the same selector and is of the same kind (class or instance). + /// A method in an implementation is not considered as overriding the same + /// method in the interface or its categories. + void getOverriddenMethods( + SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const; + + /// \brief Returns the property associated with this method's selector. + /// + /// Note that even if this particular method is not marked as a property + /// accessor, it is still possible for it to match a property declared in a + /// superclass. Pass \c false if you only want to check the current class. + const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const; + // Related to protocols declared in \@protocol void setDeclImplementation(ImplementationControl ic) { DeclImplementation = ic; @@ -427,10 +444,15 @@ public: return ImplementationControl(DeclImplementation); } - virtual Stmt *getBody() const { - return (Stmt*) Body; - } - CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; } + /// \brief Determine whether this method has a body. + virtual bool hasBody() const { return Body; } + + /// \brief Retrieve the body of this method, if it has one. + virtual Stmt *getBody() const; + + void setLazyBody(uint64_t Offset) { Body = Offset; } + + CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); } void setBody(Stmt *B) { Body = B; } /// \brief Returns whether this specific method is a definition. @@ -438,7 +460,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCMethodDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCMethod; } static DeclContext *castToDeclContext(const ObjCMethodDecl *D) { return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D)); @@ -520,6 +541,13 @@ public: ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; + typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap; + + /// This routine collects list of properties to be implemented in the class. + /// This includes, class's and its conforming protocols' properties. + /// Note, the superclass's properties are not included in the list. + virtual void collectPropertiesToImplement(PropertyMap &PM) const {} + SourceLocation getAtStartLoc() const { return AtStart; } void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } @@ -537,7 +565,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCContainerDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstObjCContainer && K <= lastObjCContainer; @@ -880,6 +907,8 @@ public: ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; + virtual void collectPropertiesToImplement(PropertyMap &PM) const; + /// isSuperClassOf - Return true if this class is the specified class or is a /// super class of the specified interface class. bool isSuperClassOf(const ObjCInterfaceDecl *I) const { @@ -992,7 +1021,6 @@ public: void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCInterfaceDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCInterface; } friend class ASTReader; @@ -1065,7 +1093,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCIvarDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCIvar; } private: /// NextIvar - Next Ivar in the list of ivars declared in class; class's @@ -1098,7 +1125,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCAtDefsFieldDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCAtDefsField; } }; @@ -1277,8 +1303,9 @@ public: return getFirstDeclaration(); } + virtual void collectPropertiesToImplement(PropertyMap &PM) const; + static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCProtocolDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCProtocol; } friend class ASTReader; @@ -1402,7 +1429,6 @@ public: SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCCategoryDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCCategory; } friend class ASTDeclReader; @@ -1455,7 +1481,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCImplDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstObjCImpl && K <= lastObjCImpl; } @@ -1532,7 +1557,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCCategoryImplDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} friend class ASTDeclReader; @@ -1568,8 +1592,12 @@ class ObjCImplementationDecl : public ObjCImplDecl { CXXCtorInitializer **IvarInitializers; unsigned NumIvarInitializers; - /// true if class has a .cxx_[construct,destruct] method. - bool HasCXXStructors : 1; + /// Do the ivars of this class require initialization other than + /// zero-initialization? + bool HasNonZeroConstructors : 1; + + /// Do the ivars of this class require non-trivial destruction? + bool HasDestructors : 1; ObjCImplementationDecl(DeclContext *DC, ObjCInterfaceDecl *classInterface, @@ -1581,7 +1609,7 @@ class ObjCImplementationDecl : public ObjCImplDecl { SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc), IvarInitializers(0), NumIvarInitializers(0), - HasCXXStructors(false) {} + HasNonZeroConstructors(false), HasDestructors(false) {} public: static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *classInterface, @@ -1625,8 +1653,15 @@ public: CXXCtorInitializer ** initializers, unsigned numInitializers); - bool hasCXXStructors() const { return HasCXXStructors; } - void setHasCXXStructors(bool val) { HasCXXStructors = val; } + /// Do any of the ivars of this class (not counting its base classes) + /// require construction other than zero-initialization? + bool hasNonZeroConstructors() const { return HasNonZeroConstructors; } + void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; } + + /// Do any of the ivars of this class (not counting its base classes) + /// require non-trivial destruction? + bool hasDestructors() const { return HasDestructors; } + void setHasDestructors(bool val) { HasDestructors = val; } /// getIdentifier - Get the identifier that names the class /// interface associated with this implementation. @@ -1676,7 +1711,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCImplementationDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCImplementation; } friend class ASTDeclReader; @@ -1708,7 +1742,6 @@ public: void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCCompatibleAliasDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; } }; @@ -1882,13 +1915,15 @@ public: virtual SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AtLoc, getLocation()); } + + /// Get the default name of the synthesized ivar. + IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const; /// Lookup a property by name in the specified DeclContext. static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, IdentifierInfo *propertyID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCPropertyDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCProperty; } }; @@ -1999,7 +2034,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCPropertyImplDecl *D) { return true; } static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; } friend class ASTDeclReader; diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 7affc7e..8620116 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -50,7 +50,11 @@ class TemplateParameterList { /// The number of template parameters in this template /// parameter list. - unsigned NumParams; + unsigned NumParams : 31; + + /// Whether this template parameter list contains an unexpanded parameter + /// pack. + unsigned ContainsUnexpandedParameterPack : 1; protected: TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, @@ -104,6 +108,12 @@ public: /// the second template parameter list will have depth 1, etc. unsigned getDepth() const; + /// \brief Determine whether this template parameter list contains an + /// unexpanded parameter pack. + bool containsUnexpandedParameterPack() const { + return ContainsUnexpandedParameterPack; + } + SourceLocation getTemplateLoc() const { return TemplateLoc; } SourceLocation getLAngleLoc() const { return LAngleLoc; } SourceLocation getRAngleLoc() const { return RAngleLoc; } @@ -139,8 +149,8 @@ class TemplateArgumentList { /// argument list. unsigned NumArguments; - TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL - void operator=(const TemplateArgumentList &Other); // DO NOT IMPL + TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; + void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, bool Owned) @@ -233,12 +243,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateDecl *D) { return true; } - static bool classof(const RedeclarableTemplateDecl *D) { return true; } - static bool classof(const FunctionTemplateDecl *D) { return true; } - static bool classof(const ClassTemplateDecl *D) { return true; } - static bool classof(const TemplateTemplateParmDecl *D) { return true; } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstTemplate && K <= lastTemplate; } @@ -678,10 +682,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const RedeclarableTemplateDecl *D) { return true; } - static bool classof(const FunctionTemplateDecl *D) { return true; } - static bool classof(const ClassTemplateDecl *D) { return true; } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate; } @@ -827,7 +827,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FunctionTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == FunctionTemplate; } friend class ASTDeclReader; @@ -969,7 +968,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateTypeParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == TemplateTypeParm; } }; @@ -1090,8 +1088,17 @@ public: /// \endcode bool isParameterPack() const { return ParameterPack; } + /// \brief Whether this parameter pack is a pack expansion. + /// + /// A non-type template parameter pack is a pack expansion if its type + /// contains an unexpanded parameter pack. In this case, we will have + /// built a PackExpansionType wrapping the type. + bool isPackExpansion() const { + return ParameterPack && getType()->getAs<PackExpansionType>(); + } + /// \brief Whether this parameter is a non-type template parameter pack - /// that has different types at different positions. + /// that has a known list of different types at different positions. /// /// A parameter pack is an expanded parameter pack when the original /// parameter pack's type was itself a pack expansion, and that expansion @@ -1141,7 +1148,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NonTypeTemplateParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == NonTypeTemplateParm; } }; @@ -1165,23 +1171,47 @@ class TemplateTemplateParmDecl : public TemplateDecl, /// \brief Whether this parameter is a parameter pack. bool ParameterPack; + /// \brief Whether this template template parameter is an "expanded" + /// parameter pack, meaning that it is a pack expansion and we + /// already know the set of template parameters that expansion expands to. + bool ExpandedParameterPack; + + /// \brief The number of parameters in an expanded parameter pack. + unsigned NumExpandedParams; + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params) : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), TemplateParmPosition(D, P), DefaultArgument(), - DefaultArgumentWasInherited(false), ParameterPack(ParameterPack) + DefaultArgumentWasInherited(false), ParameterPack(ParameterPack), + ExpandedParameterPack(false), NumExpandedParams(0) { } + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, + unsigned D, unsigned P, + IdentifierInfo *Id, TemplateParameterList *Params, + unsigned NumExpansions, + TemplateParameterList * const *Expansions); + public: static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params); + static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, + SourceLocation L, unsigned D, + unsigned P, + IdentifierInfo *Id, + TemplateParameterList *Params, + llvm::ArrayRef<TemplateParameterList*> Expansions); - static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, + static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, + unsigned ID, + unsigned NumExpansions); using TemplateParmPosition::getDepth; using TemplateParmPosition::getPosition; @@ -1195,6 +1225,49 @@ public: /// \endcode bool isParameterPack() const { return ParameterPack; } + /// \brief Whether this parameter pack is a pack expansion. + /// + /// A template template parameter pack is a pack expansion if its template + /// parameter list contains an unexpanded parameter pack. + bool isPackExpansion() const { + return ParameterPack && + getTemplateParameters()->containsUnexpandedParameterPack(); + } + + /// \brief Whether this parameter is a template template parameter pack that + /// has a known list of different template parameter lists at different + /// positions. + /// + /// A parameter pack is an expanded parameter pack when the original parameter + /// pack's template parameter list was itself a pack expansion, and that + /// expansion has already been expanded. For exampe, given: + /// + /// \code + /// template<typename...Types> struct Outer { + /// template<template<Types> class...Templates> struct Inner; + /// }; + /// \endcode + /// + /// The parameter pack \c Templates is a pack expansion, which expands the + /// pack \c Types. When \c Types is supplied with template arguments by + /// instantiating \c Outer, the instantiation of \c Templates is an expanded + /// parameter pack. + bool isExpandedParameterPack() const { return ExpandedParameterPack; } + + /// \brief Retrieves the number of expansion template parameters in + /// an expanded parameter pack. + unsigned getNumExpansionTemplateParameters() const { + assert(ExpandedParameterPack && "Not an expansion parameter pack"); + return NumExpandedParams; + } + + /// \brief Retrieve a particular expansion type within an expanded parameter + /// pack. + TemplateParameterList *getExpansionTemplateParameters(unsigned I) const { + assert(I < NumExpandedParams && "Out-of-range expansion type index"); + return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I]; + } + /// \brief Determine whether this template parameter has a default /// argument. bool hasDefaultArgument() const { @@ -1238,7 +1311,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateTemplateParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == TemplateTemplateParm; } friend class ASTDeclReader; @@ -1505,14 +1577,6 @@ public: K <= lastClassTemplateSpecialization; } - static bool classof(const ClassTemplateSpecializationDecl *) { - return true; - } - - static bool classof(const ClassTemplatePartialSpecializationDecl *) { - return true; - } - friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -1681,10 +1745,6 @@ public: return K == ClassTemplatePartialSpecialization; } - static bool classof(const ClassTemplatePartialSpecializationDecl *) { - return true; - } - friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -1886,7 +1946,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ClassTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == ClassTemplate; } friend class ASTDeclReader; @@ -1984,7 +2043,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::FriendTemplate; } - static bool classof(const FriendTemplateDecl *D) { return true; } friend class ASTDeclReader; }; @@ -2059,7 +2117,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == TypeAliasTemplate; } friend class ASTDeclReader; @@ -2123,9 +2180,6 @@ public: static bool classofKind(Kind K) { return K == Decl::ClassScopeFunctionSpecialization; } - static bool classof(const ClassScopeFunctionSpecializationDecl *D) { - return true; - } friend class ASTDeclReader; friend class ASTDeclWriter; diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 6146525..d991c73 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -334,8 +334,8 @@ class DeclarationNameTable { CXXOperatorIdName *CXXOperatorNames; // Operator names void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName* - DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE - DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE + DeclarationNameTable(const DeclarationNameTable&) LLVM_DELETED_FUNCTION; + void operator=(const DeclarationNameTable&) LLVM_DELETED_FUNCTION; public: DeclarationNameTable(const ASTContext &C); diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 89c003c..dc83654 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -34,6 +34,7 @@ namespace clang { class ASTContext; class APValue; + class CastExpr; class Decl; class IdentifierInfo; class ParmVarDecl; @@ -42,6 +43,7 @@ namespace clang { class BlockDecl; class CXXBaseSpecifier; class CXXOperatorCallExpr; + class MaterializeTemporaryExpr; class CXXMemberCallExpr; class ObjCPropertyRefExpr; class OpaqueValueExpr; @@ -49,6 +51,48 @@ namespace clang { /// \brief A simple array of base specifiers. typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; +/// \brief An adjustment to be made to the temporary created when emitting a +/// reference binding, which accesses a particular subobject of that temporary. +struct SubobjectAdjustment { + enum { + DerivedToBaseAdjustment, + FieldAdjustment, + MemberPointerAdjustment + } Kind; + + union { + struct { + const CastExpr *BasePath; + const CXXRecordDecl *DerivedClass; + } DerivedToBase; + + FieldDecl *Field; + + struct { + const MemberPointerType *MPT; + Expr *RHS; + } Ptr; + }; + + SubobjectAdjustment(const CastExpr *BasePath, + const CXXRecordDecl *DerivedClass) + : Kind(DerivedToBaseAdjustment) { + DerivedToBase.BasePath = BasePath; + DerivedToBase.DerivedClass = DerivedClass; + } + + SubobjectAdjustment(FieldDecl *Field) + : Kind(FieldAdjustment) { + this->Field = Field; + } + + SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS) + : Kind(MemberPointerAdjustment) { + this->Ptr.MPT = MPT; + this->Ptr.RHS = RHS; + } +}; + /// Expr - This represents one expression. Note that Expr's are subclasses of /// Stmt. This allows an expression to be transparently used any place a Stmt /// is required. @@ -220,15 +264,6 @@ public: /// Reasons why an expression might not be an l-value. LValueClassification ClassifyLValue(ASTContext &Ctx) const; - /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, - /// does not have an incomplete type, does not have a const-qualified type, - /// and if it is a structure or union, does not have any member (including, - /// recursively, any member or element of all contained aggregates or unions) - /// with a const-qualified type. - /// - /// \param Loc [in,out] - A source location which *may* be filled - /// in with the location of the expression making this a - /// non-modifiable lvalue, if specified. enum isModifiableLvalueResult { MLV_Valid, MLV_NotObjectType, @@ -247,6 +282,15 @@ public: MLV_ClassTemporary, MLV_ArrayTemporary }; + /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, + /// does not have an incomplete type, does not have a const-qualified type, + /// and if it is a structure or union, does not have any member (including, + /// recursively, any member or element of all contained aggregates or unions) + /// with a const-qualified type. + /// + /// \param Loc [in,out] - A source location which *may* be filled + /// in with the location of the expression making this a + /// non-modifiable lvalue, if specified. isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = 0) const; @@ -392,6 +436,9 @@ public: /// property, find the underlying property reference expression. const ObjCPropertyRefExpr *getObjCProperty() const; + /// \brief Check if this expression is the ObjC 'self' implicit parameter. + bool isObjCSelfExpr() const; + /// \brief Returns whether this expression refers to a vector element. bool refersToVectorElement() const; @@ -692,11 +739,22 @@ public: /// behavior if the object isn't dynamically of the derived type. const CXXRecordDecl *getBestDynamicClassType() const; + /// Walk outwards from an expression we want to bind a reference to and + /// find the expression whose lifetime needs to be extended. Record + /// the adjustments needed along the path. + const Expr * + skipRValueSubobjectAdjustments( + SmallVectorImpl<SubobjectAdjustment> &Adjustments) const; + + /// Skip irrelevant expressions to find what should be materialize for + /// binding with a reference. + const Expr * + findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const; + static bool classof(const Stmt *T) { return T->getStmtClass() >= firstExprConstant && T->getStmtClass() <= lastExprConstant; } - static bool classof(const Expr *) { return true; } }; @@ -762,7 +820,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == OpaqueValueExprClass; } - static bool classof(const OpaqueValueExpr *) { return true; } }; /// \brief A reference to a declared variable, function, enum, etc. @@ -1059,7 +1116,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DeclRefExprClass; } - static bool classof(const DeclRefExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1109,7 +1165,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == PredefinedExprClass; } - static bool classof(const PredefinedExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1132,8 +1187,8 @@ class APNumericStorage { bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; } - APNumericStorage(const APNumericStorage&); // do not implement - APNumericStorage& operator=(const APNumericStorage&); // do not implement + APNumericStorage(const APNumericStorage &) LLVM_DELETED_FUNCTION; + void operator=(const APNumericStorage &) LLVM_DELETED_FUNCTION; protected: APNumericStorage() : VAL(0), BitWidth(0) { } @@ -1196,7 +1251,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == IntegerLiteralClass; } - static bool classof(const IntegerLiteral *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1243,7 +1297,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CharacterLiteralClass; } - static bool classof(const CharacterLiteral *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1286,7 +1339,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == FloatingLiteralClass; } - static bool classof(const FloatingLiteral *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1317,7 +1369,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ImaginaryLiteralClass; } - static bool classof(const ImaginaryLiteral *) { return true; } // Iterators child_range children() { return child_range(&Val, &Val+1); } @@ -1479,7 +1530,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == StringLiteralClass; } - static bool classof(const StringLiteral *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1520,7 +1570,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ParenExprClass; } - static bool classof(const ParenExpr *) { return true; } // Iterators child_range children() { return child_range(&Val, &Val+1); } @@ -1610,7 +1659,7 @@ public: /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// corresponds to, e.g. "sizeof" or "[pre]++" - static const char *getOpcodeStr(Opcode Op); + static StringRef getOpcodeStr(Opcode Op); /// \brief Retrieve the unary opcode that corresponds to the given /// overloaded operator. @@ -1631,7 +1680,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryOperatorClass; } - static bool classof(const UnaryOperator *) { return true; } // Iterators child_range children() { return child_range(&Val, &Val+1); } @@ -1757,8 +1805,7 @@ private: OffsetOfExpr(ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, - OffsetOfNode* compsPtr, unsigned numComps, - Expr** exprsPtr, unsigned numExprs, + ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs, SourceLocation RParenLoc); explicit OffsetOfExpr(unsigned numComps, unsigned numExprs) @@ -1769,9 +1816,8 @@ public: static OffsetOfExpr *Create(ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, - OffsetOfNode* compsPtr, unsigned numComps, - Expr** exprsPtr, unsigned numExprs, - SourceLocation RParenLoc); + ArrayRef<OffsetOfNode> comps, + ArrayRef<Expr*> exprs, SourceLocation RParenLoc); static OffsetOfExpr *CreateEmpty(ASTContext &C, unsigned NumComps, unsigned NumExprs); @@ -1832,8 +1878,6 @@ public: return T->getStmtClass() == OffsetOfExprClass; } - static bool classof(const OffsetOfExpr *) { return true; } - // Iterators child_range children() { Stmt **begin = @@ -1937,7 +1981,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryExprOrTypeTraitExprClass; } - static bool classof(const UnaryExprOrTypeTraitExpr *) { return true; } // Iterators child_range children(); @@ -2017,7 +2060,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ArraySubscriptExprClass; } - static bool classof(const ArraySubscriptExpr *) { return true; } // Iterators child_range children() { @@ -2041,7 +2083,7 @@ class CallExpr : public Expr { protected: // These versions of the constructor are for derived classes. CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, - Expr **args, unsigned numargs, QualType t, ExprValueKind VK, + ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation rparenloc); CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty); @@ -2061,7 +2103,7 @@ protected: unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; } public: - CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t, + CallExpr(ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation rparenloc); /// \brief Build an empty call expression. @@ -2153,7 +2195,6 @@ public: return T->getStmtClass() >= firstCallExprConstant && T->getStmtClass() <= lastCallExprConstant; } - static bool classof(const CallExpr *) { return true; } // Iterators child_range children() { @@ -2440,7 +2481,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MemberExprClass; } - static bool classof(const MemberExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base+1); } @@ -2506,7 +2546,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CompoundLiteralExprClass; } - static bool classof(const CompoundLiteralExpr *) { return true; } // Iterators child_range children() { return child_range(&Init, &Init+1); } @@ -2597,7 +2636,6 @@ public: return T->getStmtClass() >= firstCastExprConstant && T->getStmtClass() <= lastCastExprConstant; } - static bool classof(const CastExpr *) { return true; } // Iterators child_range children() { return child_range(&Op, &Op+1); } @@ -2661,7 +2699,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitCastExprClass; } - static bool classof(const ImplicitCastExpr *) { return true; } }; inline Expr *Expr::IgnoreImpCasts() { @@ -2716,7 +2753,6 @@ public: return T->getStmtClass() >= firstExplicitCastExprConstant && T->getStmtClass() <= lastExplicitCastExprConstant; } - static bool classof(const ExplicitCastExpr *) { return true; } }; /// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style @@ -2757,7 +2793,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CStyleCastExprClass; } - static bool classof(const CStyleCastExpr *) { return true; } }; /// \brief A builtin binary operation expression such as "x + y" or "x <= y". @@ -2784,6 +2819,12 @@ public: private: unsigned Opc : 6; + + // Records the FP_CONTRACT pragma status at the point that this binary + // operator was parsed. This bit is only meaningful for operations on + // floating point types. For all other types it should default to + // false. + unsigned FPContractable : 1; SourceLocation OpLoc; enum { LHS, RHS, END_EXPR }; @@ -2792,7 +2833,7 @@ public: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc) + SourceLocation opLoc, bool fpContractable) : Expr(BinaryOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), @@ -2800,7 +2841,7 @@ public: rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), - Opc(opc), OpLoc(opLoc) { + Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; assert(!isCompoundAssignmentOp() && @@ -2829,9 +2870,9 @@ public: /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// corresponds to, e.g. "<<=". - static const char *getOpcodeStr(Opcode Op); + static StringRef getOpcodeStr(Opcode Op); - const char *getOpcodeStr() const { return getOpcodeStr(getOpcode()); } + StringRef getOpcodeStr() const { return getOpcodeStr(getOpcode()); } /// \brief Retrieve the binary opcode that corresponds to the given /// overloaded operator. @@ -2894,17 +2935,24 @@ public: return S->getStmtClass() >= firstBinaryOperatorConstant && S->getStmtClass() <= lastBinaryOperatorConstant; } - static bool classof(const BinaryOperator *) { return true; } // Iterators child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + // Set the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + void setFPContractable(bool FPC) { FPContractable = FPC; } + + // Get the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + bool isFPContractable() const { return FPContractable; } + protected: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc, bool dead) + SourceLocation opLoc, bool fpContractable, bool dead2) : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), @@ -2912,7 +2960,7 @@ protected: rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), - Opc(opc), OpLoc(opLoc) { + Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; } @@ -2934,8 +2982,9 @@ public: CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType, ExprValueKind VK, ExprObjectKind OK, QualType CompLHSType, QualType CompResultType, - SourceLocation OpLoc) - : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, true), + SourceLocation OpLoc, bool fpContractable) + : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable, + true), ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) { assert(isCompoundAssignmentOp() && @@ -2955,7 +3004,6 @@ public: QualType getComputationResultType() const { return ComputationResultType; } void setComputationResultType(QualType T) { ComputationResultType = T; } - static bool classof(const CompoundAssignOperator *) { return true; } static bool classof(const Stmt *S) { return S->getStmtClass() == CompoundAssignOperatorClass; } @@ -3001,7 +3049,6 @@ public: return T->getStmtClass() == ConditionalOperatorClass || T->getStmtClass() == BinaryConditionalOperatorClass; } - static bool classof(const AbstractConditionalOperator *) { return true; } }; /// ConditionalOperator - The ?: ternary operator. The GNU "missing @@ -3060,7 +3107,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ConditionalOperatorClass; } - static bool classof(const ConditionalOperator *) { return true; } // Iterators child_range children() { @@ -3142,7 +3188,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == BinaryConditionalOperatorClass; } - static bool classof(const BinaryConditionalOperator *) { return true; } // Iterators child_range children() { @@ -3198,7 +3243,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == AddrLabelExprClass; } - static bool classof(const AddrLabelExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -3242,7 +3286,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == StmtExprClass; } - static bool classof(const StmtExpr *) { return true; } // Iterators child_range children() { return child_range(&SubStmt, &SubStmt+1); } @@ -3266,9 +3309,8 @@ class ShuffleVectorExpr : public Expr { unsigned NumExprs; public: - ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, - QualType Type, SourceLocation BLoc, - SourceLocation RP); + ShuffleVectorExpr(ASTContext &C, ArrayRef<Expr*> args, QualType Type, + SourceLocation BLoc, SourceLocation RP); /// \brief Build an empty vector-shuffle expression. explicit ShuffleVectorExpr(EmptyShell Empty) @@ -3286,7 +3328,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ShuffleVectorExprClass; } - static bool classof(const ShuffleVectorExpr *) { return true; } /// getNumSubExprs - Return the size of the SubExprs array. This includes the /// constant expression, the actual arguments passed in, and the function @@ -3308,7 +3349,7 @@ public: void setExprs(ASTContext &C, Expr ** Exprs, unsigned NumExprs); - unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) { + unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) const { assert((N < NumExprs - 2) && "Shuffle idx out of range!"); return getExpr(N+2)->EvaluateKnownConstInt(Ctx).getZExtValue(); } @@ -3381,7 +3422,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ChooseExprClass; } - static bool classof(const ChooseExpr *) { return true; } // Iterators child_range children() { @@ -3418,7 +3458,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == GNUNullExprClass; } - static bool classof(const GNUNullExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -3464,7 +3503,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == VAArgExprClass; } - static bool classof(const VAArgExpr *) { return true; } // Iterators child_range children() { return child_range(&Val, &Val+1); } @@ -3501,21 +3539,32 @@ public: /// initializer lists may still have fewer initializers than there are /// elements to initialize within the object. /// +/// After semantic analysis has completed, given an initializer list, +/// method isSemanticForm() returns true if and only if this is the +/// semantic form of the initializer list (note: the same AST node +/// may at the same time be the syntactic form). /// Given the semantic form of the initializer list, one can retrieve -/// the original syntactic form of that initializer list (if it -/// exists) using getSyntacticForm(). Since many initializer lists -/// have the same syntactic and semantic forms, getSyntacticForm() may -/// return NULL, indicating that the current initializer list also -/// serves as its syntactic form. +/// the syntactic form of that initializer list (when different) +/// using method getSyntacticForm(); the method returns null if applied +/// to a initializer list which is already in syntactic form. +/// Similarly, given the syntactic form (i.e., an initializer list such +/// that isSemanticForm() returns false), one can retrieve the semantic +/// form using method getSemanticForm(). +/// Since many initializer lists have the same syntactic and semantic forms, +/// getSyntacticForm() may return NULL, indicating that the current +/// semantic initializer list also serves as its syntactic form. class InitListExpr : public Expr { // FIXME: Eliminate this vector in favor of ASTContext allocation typedef ASTVector<Stmt *> InitExprsTy; InitExprsTy InitExprs; SourceLocation LBraceLoc, RBraceLoc; - /// Contains the initializer list that describes the syntactic form - /// written in the source code. - InitListExpr *SyntacticForm; + /// The alternative form of the initializer list (if it exists). + /// The int part of the pair stores whether this initalizer list is + /// in semantic form. If not null, the pointer points to: + /// - the syntactic form, if this is in semantic form; + /// - the semantic form, if this is in syntactic form. + llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm; /// \brief Either: /// If this initializer list initializes an array with more elements than @@ -3528,8 +3577,7 @@ class InitListExpr : public Expr { public: InitListExpr(ASTContext &C, SourceLocation lbraceloc, - Expr **initexprs, unsigned numinits, - SourceLocation rbraceloc); + ArrayRef<Expr*> initExprs, SourceLocation rbraceloc); /// \brief Build an empty initializer list. explicit InitListExpr(ASTContext &C, EmptyShell Empty) @@ -3621,12 +3669,20 @@ public: SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; } - /// @brief Retrieve the initializer list that describes the - /// syntactic form of the initializer. - /// - /// - InitListExpr *getSyntacticForm() const { return SyntacticForm; } - void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; } + bool isSemanticForm() const { return AltForm.getInt(); } + InitListExpr *getSemanticForm() const { + return isSemanticForm() ? 0 : AltForm.getPointer(); + } + InitListExpr *getSyntacticForm() const { + return isSemanticForm() ? AltForm.getPointer() : 0; + } + + void setSyntacticForm(InitListExpr *Init) { + AltForm.setPointer(Init); + AltForm.setInt(true); + Init->AltForm.setPointer(this); + Init->AltForm.setInt(false); + } bool hadArrayRangeDesignator() const { return InitListExprBits.HadArrayRangeDesignator != 0; @@ -3647,7 +3703,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == InitListExprClass; } - static bool classof(const InitListExpr *) { return true; } // Iterators child_range children() { @@ -3723,8 +3778,7 @@ private: DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumDesignators, const Designator *Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, - Expr **IndexExprs, unsigned NumIndexExprs, - Expr *Init); + ArrayRef<Expr*> IndexExprs, Expr *Init); explicit DesignatedInitExpr(unsigned NumSubExprs) : Expr(DesignatedInitExprClass, EmptyShell()), @@ -3885,7 +3939,7 @@ public: static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators, unsigned NumDesignators, - Expr **IndexExprs, unsigned NumIndexExprs, + ArrayRef<Expr*> IndexExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init); @@ -3985,7 +4039,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DesignatedInitExprClass; } - static bool classof(const DesignatedInitExpr *) { return true; } // Iterators child_range children() { @@ -4015,7 +4068,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitValueInitExprClass; } - static bool classof(const ImplicitValueInitExpr *) { return true; } SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); @@ -4032,8 +4084,8 @@ class ParenListExpr : public Expr { SourceLocation LParenLoc, RParenLoc; public: - ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, - unsigned numexprs, SourceLocation rparenloc); + ParenListExpr(ASTContext& C, SourceLocation lparenloc, ArrayRef<Expr*> exprs, + SourceLocation rparenloc); /// \brief Build an empty paren list. explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } @@ -4061,7 +4113,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ParenListExprClass; } - static bool classof(const ParenListExpr *) { return true; } // Iterators child_range children() { @@ -4109,18 +4160,18 @@ class GenericSelectionExpr : public Expr { public: GenericSelectionExpr(ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, - TypeSourceInfo **AssocTypes, Expr **AssocExprs, - unsigned NumAssocs, SourceLocation DefaultLoc, - SourceLocation RParenLoc, + ArrayRef<TypeSourceInfo*> AssocTypes, + ArrayRef<Expr*> AssocExprs, + SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex); /// This constructor is used in the result-dependent case. GenericSelectionExpr(ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, - TypeSourceInfo **AssocTypes, Expr **AssocExprs, - unsigned NumAssocs, SourceLocation DefaultLoc, - SourceLocation RParenLoc, + ArrayRef<TypeSourceInfo*> AssocTypes, + ArrayRef<Expr*> AssocExprs, + SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack); explicit GenericSelectionExpr(EmptyShell Empty) @@ -4176,7 +4227,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == GenericSelectionExprClass; } - static bool classof(const GenericSelectionExpr *) { return true; } child_range children() { return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs); @@ -4247,7 +4297,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ExtVectorElementExprClass; } - static bool classof(const ExtVectorElementExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base+1); } @@ -4289,7 +4338,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == BlockExprClass; } - static bool classof(const BlockExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -4336,7 +4384,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == AsTypeExprClass; } - static bool classof(const AsTypeExpr *) { return true; } // Iterators child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } @@ -4473,7 +4520,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == PseudoObjectExprClass; } - static bool classof(const PseudoObjectExpr *) { return true; } }; /// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, @@ -4501,7 +4547,7 @@ private: friend class ASTStmtReader; public: - AtomicExpr(SourceLocation BLoc, Expr **args, unsigned nexpr, QualType t, + AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t, AtomicOp op, SourceLocation RP); /// \brief Determine the number of arguments the specified atomic builtin @@ -4563,7 +4609,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == AtomicExprClass; } - static bool classof(const AtomicExpr *) { return true; } // Iterators child_range children() { diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index ecfa9e2..9c759db 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -53,14 +53,19 @@ class CXXOperatorCallExpr : public CallExpr { OverloadedOperatorKind Operator; SourceRange Range; + // Record the FP_CONTRACT state that applies to this operator call. Only + // meaningful for floating point types. For other types this value can be + // set to false. + unsigned FPContractable : 1; + SourceRange getSourceRangeImpl() const LLVM_READONLY; public: CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn, - Expr **args, unsigned numargs, QualType t, - ExprValueKind VK, SourceLocation operatorloc) - : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, numargs, t, VK, + ArrayRef<Expr*> args, QualType t, ExprValueKind VK, + SourceLocation operatorloc, bool fpContractable) + : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK, operatorloc), - Operator(Op) { + Operator(Op), FPContractable(fpContractable) { Range = getSourceRangeImpl(); } explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) : @@ -83,7 +88,14 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXOperatorCallExprClass; } - static bool classof(const CXXOperatorCallExpr *) { return true; } + + // Set the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + void setFPContractable(bool FPC) { FPContractable = FPC; } + + // Get the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + bool isFPContractable() const { return FPContractable; } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -99,9 +111,9 @@ public: /// the object argument). class CXXMemberCallExpr : public CallExpr { public: - CXXMemberCallExpr(ASTContext &C, Expr *fn, Expr **args, unsigned numargs, + CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, numargs, t, VK, RP) {} + : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {} CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CXXMemberCallExprClass, Empty) { } @@ -124,7 +136,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXMemberCallExprClass; } - static bool classof(const CXXMemberCallExpr *) { return true; } }; /// CUDAKernelCallExpr - Represents a call to a CUDA kernel function. @@ -134,10 +145,9 @@ private: public: CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config, - Expr **args, unsigned numargs, QualType t, - ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, numargs, t, VK, - RP) { + ArrayRef<Expr*> args, QualType t, ExprValueKind VK, + SourceLocation RP) + : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) { setConfig(Config); } @@ -153,7 +163,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CUDAKernelCallExprClass; } - static bool classof(const CUDAKernelCallExpr *) { return true; } }; /// CXXNamedCastExpr - Abstract class common to all of the C++ "named" @@ -205,7 +214,6 @@ public: return false; } } - static bool classof(const CXXNamedCastExpr *) { return true; } }; /// CXXStaticCastExpr - A C++ @c static_cast expression @@ -235,7 +243,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXStaticCastExprClass; } - static bool classof(const CXXStaticCastExpr *) { return true; } }; /// CXXDynamicCastExpr - A C++ @c dynamic_cast expression @@ -269,7 +276,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDynamicCastExprClass; } - static bool classof(const CXXDynamicCastExpr *) { return true; } }; /// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++ @@ -301,7 +307,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXReinterpretCastExprClass; } - static bool classof(const CXXReinterpretCastExpr *) { return true; } }; /// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]), @@ -329,7 +334,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstCastExprClass; } - static bool classof(const CXXConstCastExpr *) { return true; } }; /// UserDefinedLiteral - A call to a literal operator (C++11 [over.literal]) @@ -346,11 +350,11 @@ class UserDefinedLiteral : public CallExpr { SourceLocation UDSuffixLoc; public: - UserDefinedLiteral(ASTContext &C, Expr *Fn, Expr **Args, unsigned NumArgs, + UserDefinedLiteral(ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args, QualType T, ExprValueKind VK, SourceLocation LitEndLoc, SourceLocation SuffixLoc) - : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, NumArgs, T, VK, - LitEndLoc), UDSuffixLoc(SuffixLoc) {} + : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc), + UDSuffixLoc(SuffixLoc) {} explicit UserDefinedLiteral(ASTContext &C, EmptyShell Empty) : CallExpr(C, UserDefinedLiteralClass, Empty) {} @@ -398,7 +402,6 @@ public: static bool classof(const Stmt *S) { return S->getStmtClass() == UserDefinedLiteralClass; } - static bool classof(const UserDefinedLiteral *) { return true; } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -429,7 +432,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXBoolLiteralExprClass; } - static bool classof(const CXXBoolLiteralExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -455,7 +457,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXNullPtrLiteralExprClass; } - static bool classof(const CXXNullPtrLiteralExpr *) { return true; } child_range children() { return child_range(); } }; @@ -536,7 +537,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTypeidExprClass; } - static bool classof(const CXXTypeidExpr *) { return true; } // Iterators child_range children() { @@ -611,7 +611,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXUuidofExprClass; } - static bool classof(const CXXUuidofExpr *) { return true; } + + /// Grabs __declspec(uuid()) off a type, or returns 0 if there is none. + static UuidAttr *GetUuidAttrOfType(QualType QT); // Iterators child_range children() { @@ -659,7 +661,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXThisExprClass; } - static bool classof(const CXXThisExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -710,7 +711,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXThrowExprClass; } - static bool classof(const CXXThrowExpr *) { return true; } // Iterators child_range children() { @@ -798,7 +798,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDefaultArgExprClass; } - static bool classof(const CXXDefaultArgExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -875,7 +874,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXBindTemporaryExprClass; } - static bool classof(const CXXBindTemporaryExpr *) { return true; } // Iterators child_range children() { return child_range(&SubExpr, &SubExpr + 1); } @@ -908,7 +906,7 @@ protected: CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, CXXConstructorDecl *d, bool elidable, - Expr **args, unsigned numargs, + ArrayRef<Expr *> Args, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization, @@ -934,7 +932,7 @@ public: static CXXConstructExpr *Create(ASTContext &C, QualType T, SourceLocation Loc, CXXConstructorDecl *D, bool Elidable, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization, @@ -1011,7 +1009,6 @@ public: return T->getStmtClass() == CXXConstructExprClass || T->getStmtClass() == CXXTemporaryObjectExprClass; } - static bool classof(const CXXConstructExpr *) { return true; } // Iterators child_range children() { @@ -1066,7 +1063,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXFunctionalCastExprClass; } - static bool classof(const CXXFunctionalCastExpr *) { return true; } }; /// @brief Represents a C++ functional cast expression that builds a @@ -1090,7 +1086,7 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr { public: CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons, TypeSourceInfo *Type, - Expr **Args,unsigned NumArgs, + ArrayRef<Expr *> Args, SourceRange parenRange, bool HadMultipleCandidates, bool ZeroInitialization = false); @@ -1104,7 +1100,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTemporaryObjectExprClass; } - static bool classof(const CXXTemporaryObjectExpr *) { return true; } friend class ASTStmtReader; }; @@ -1281,8 +1276,11 @@ private: /// \brief Retrieve the complete set of array-index variables. VarDecl **getArrayIndexVars() const { + unsigned ArrayIndexSize = + llvm::RoundUpToAlignment(sizeof(unsigned) * (NumCaptures + 1), + llvm::alignOf<VarDecl*>()); return reinterpret_cast<VarDecl **>( - getArrayIndexStarts() + NumCaptures + 1); + reinterpret_cast<char*>(getArrayIndexStarts()) + ArrayIndexSize); } public: @@ -1394,7 +1392,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == LambdaExprClass; } - static bool classof(const LambdaExpr *) { return true; } SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(IntroducerRange.getBegin(), ClosingBrace); @@ -1442,7 +1439,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXScalarValueInitExprClass; } - static bool classof(const CXXScalarValueInitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1467,8 +1463,8 @@ class CXXNewExpr : public Expr { /// the source range covering the parenthesized type-id. SourceRange TypeIdParens; - /// \brief Location of the first token. - SourceLocation StartLoc; + /// \brief Range of the entire new expression. + SourceRange Range; /// \brief Source-range of a paren-delimited initializer. SourceRange DirectInitRange; @@ -1498,11 +1494,11 @@ public: CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize, - Expr **placementArgs, unsigned numPlaceArgs, + ArrayRef<Expr*> placementArgs, SourceRange typeIdParens, Expr *arraySize, InitializationStyle initializationStyle, Expr *initializer, QualType ty, TypeSourceInfo *AllocatedTypeInfo, - SourceLocation startLoc, SourceRange directInitRange); + SourceRange Range, SourceRange directInitRange); explicit CXXNewExpr(EmptyShell Shell) : Expr(CXXNewExprClass, Shell), SubExprs(0) { } @@ -1580,7 +1576,7 @@ public: } /// \brief Returns the CXXConstructExpr from this new-expression, or NULL. - const CXXConstructExpr* getConstructExpr() { + const CXXConstructExpr* getConstructExpr() const { return dyn_cast_or_null<CXXConstructExpr>(getInitializer()); } @@ -1617,19 +1613,18 @@ public: return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); } - SourceLocation getStartLoc() const { return StartLoc; } - SourceLocation getEndLoc() const; + SourceLocation getStartLoc() const { return Range.getBegin(); } + SourceLocation getEndLoc() const { return Range.getEnd(); } SourceRange getDirectInitRange() const { return DirectInitRange; } SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getStartLoc(), getEndLoc()); + return Range; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXNewExprClass; } - static bool classof(const CXXNewExpr *) { return true; } // Iterators child_range children() { @@ -1700,7 +1695,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDeleteExprClass; } - static bool classof(const CXXDeleteExpr *) { return true; } // Iterators child_range children() { return child_range(&Argument, &Argument+1); } @@ -1889,7 +1883,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXPseudoDestructorExprClass; } - static bool classof(const CXXPseudoDestructorExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base + 1); } @@ -1945,7 +1938,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryTypeTraitExprClass; } - static bool classof(const UnaryTypeTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2017,7 +2009,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == BinaryTypeTraitExprClass; } - static bool classof(const BinaryTypeTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2111,7 +2102,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == TypeTraitExprClass; } - static bool classof(const TypeTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2186,7 +2176,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ArrayTypeTraitExprClass; } - static bool classof(const ArrayTypeTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2245,7 +2234,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ExpressionTraitExprClass; } - static bool classof(const ExpressionTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2432,7 +2420,6 @@ public: return T->getStmtClass() == UnresolvedLookupExprClass || T->getStmtClass() == UnresolvedMemberExprClass; } - static bool classof(const OverloadExpr *) { return true; } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -2454,10 +2441,6 @@ class UnresolvedLookupExpr : public OverloadExpr { /// call. bool RequiresADL; - /// True if namespace ::std should be considered an associated namespace - /// for the purposes of argument-dependent lookup. See C++0x [stmt.ranged]p1. - bool StdIsAssociatedNamespace; - /// True if these lookup results are overloaded. This is pretty /// trivially rederivable if we urgently need to kill this field. bool Overloaded; @@ -2476,19 +2459,16 @@ class UnresolvedLookupExpr : public OverloadExpr { const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, - UnresolvedSetIterator Begin, UnresolvedSetIterator End, - bool StdIsAssociatedNamespace) + UnresolvedSetIterator Begin, UnresolvedSetIterator End) : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, false, false, false), RequiresADL(RequiresADL), - StdIsAssociatedNamespace(StdIsAssociatedNamespace), Overloaded(Overloaded), NamingClass(NamingClass) {} UnresolvedLookupExpr(EmptyShell Empty) : OverloadExpr(UnresolvedLookupExprClass, Empty), - RequiresADL(false), StdIsAssociatedNamespace(false), Overloaded(false), - NamingClass(0) + RequiresADL(false), Overloaded(false), NamingClass(0) {} friend class ASTStmtReader; @@ -2500,14 +2480,10 @@ public: const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, - UnresolvedSetIterator End, - bool StdIsAssociatedNamespace = false) { - assert((ADL || !StdIsAssociatedNamespace) && - "std considered associated namespace when not performing ADL"); + UnresolvedSetIterator End) { return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, SourceLocation(), NameInfo, - ADL, Overloaded, 0, Begin, End, - StdIsAssociatedNamespace); + ADL, Overloaded, 0, Begin, End); } static UnresolvedLookupExpr *Create(ASTContext &C, @@ -2528,10 +2504,6 @@ public: /// argument-dependent lookup. bool requiresADL() const { return RequiresADL; } - /// True if namespace \::std should be artificially added to the set of - /// associated namespaces for argument-dependent lookup purposes. - bool isStdAssociatedNamespace() const { return StdIsAssociatedNamespace; } - /// True if this lookup is overloaded. bool isOverloaded() const { return Overloaded; } @@ -2554,7 +2526,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnresolvedLookupExprClass; } - static bool classof(const UnresolvedLookupExpr *) { return true; } }; /// \brief A qualified reference to a name whose declaration cannot @@ -2705,7 +2676,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DependentScopeDeclRefExprClass; } - static bool classof(const DependentScopeDeclRefExpr *) { return true; } child_range children() { return child_range(); } @@ -2778,7 +2748,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ExprWithCleanupsClass; } - static bool classof(const ExprWithCleanups *) { return true; } // Iterators child_range children() { return child_range(&SubExpr, &SubExpr + 1); } @@ -2820,8 +2789,7 @@ class CXXUnresolvedConstructExpr : public Expr { CXXUnresolvedConstructExpr(TypeSourceInfo *Type, SourceLocation LParenLoc, - Expr **Args, - unsigned NumArgs, + ArrayRef<Expr*> Args, SourceLocation RParenLoc); CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs) @@ -2833,8 +2801,7 @@ public: static CXXUnresolvedConstructExpr *Create(ASTContext &C, TypeSourceInfo *Type, SourceLocation LParenLoc, - Expr **Args, - unsigned NumArgs, + ArrayRef<Expr*> Args, SourceLocation RParenLoc); static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C, @@ -2893,7 +2860,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXUnresolvedConstructExprClass; } - static bool classof(const CXXUnresolvedConstructExpr *) { return true; } // Iterators child_range children() { @@ -3142,7 +3108,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDependentScopeMemberExprClass; } - static bool classof(const CXXDependentScopeMemberExpr *) { return true; } // Iterators child_range children() { @@ -3276,7 +3241,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnresolvedMemberExprClass; } - static bool classof(const UnresolvedMemberExpr *) { return true; } // Iterators child_range children() { @@ -3320,7 +3284,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXNoexceptExprClass; } - static bool classof(const CXXNoexceptExpr *) { return true; } // Iterators child_range children() { return child_range(&Operand, &Operand + 1); } @@ -3397,7 +3360,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == PackExpansionExprClass; } - static bool classof(const PackExpansionExpr *) { return true; } // Iterators child_range children() { @@ -3503,7 +3465,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SizeOfPackExprClass; } - static bool classof(const SizeOfPackExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -3548,9 +3509,6 @@ public: static bool classof(const Stmt *s) { return s->getStmtClass() == SubstNonTypeTemplateParmExprClass; } - static bool classof(const SubstNonTypeTemplateParmExpr *) { - return true; - } // Iterators child_range children() { return child_range(&Replacement, &Replacement+1); } @@ -3561,7 +3519,7 @@ public: /// /// When a pack expansion in the source code contains multiple parameter packs /// and those parameter packs correspond to different levels of template -/// parameter lists, this node node is used to represent a non-type template +/// parameter lists, this node is used to represent a non-type template /// parameter pack from an outer level, which has already had its argument pack /// substituted but that still lives within a pack expansion that itself /// could not be instantiated. When actually performing a substitution into @@ -3608,14 +3566,77 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass; } - static bool classof(const SubstNonTypeTemplateParmPackExpr *) { - return true; - } // Iterators child_range children() { return child_range(); } }; +/// \brief Represents a reference to a function parameter pack that has been +/// substituted but not yet expanded. +/// +/// When a pack expansion contains multiple parameter packs at different levels, +/// this node is used to represent a function parameter pack at an outer level +/// which we have already substituted to refer to expanded parameters, but where +/// the containing pack expansion cannot yet be expanded. +/// +/// \code +/// template<typename...Ts> struct S { +/// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...)); +/// }; +/// template struct S<int, int>; +/// \endcode +class FunctionParmPackExpr : public Expr { + /// \brief The function parameter pack which was referenced. + ParmVarDecl *ParamPack; + + /// \brief The location of the function parameter pack reference. + SourceLocation NameLoc; + + /// \brief The number of expansions of this pack. + unsigned NumParameters; + + FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack, + SourceLocation NameLoc, unsigned NumParams, + Decl * const *Params); + + friend class ASTReader; + friend class ASTStmtReader; + +public: + static FunctionParmPackExpr *Create(ASTContext &Context, QualType T, + ParmVarDecl *ParamPack, + SourceLocation NameLoc, + llvm::ArrayRef<Decl*> Params); + static FunctionParmPackExpr *CreateEmpty(ASTContext &Context, + unsigned NumParams); + + /// \brief Get the parameter pack which this expression refers to. + ParmVarDecl *getParameterPack() const { return ParamPack; } + + /// \brief Get the location of the parameter pack. + SourceLocation getParameterPackLocation() const { return NameLoc; } + + /// \brief Iterators over the parameters which the parameter pack expanded + /// into. + typedef ParmVarDecl * const *iterator; + iterator begin() const { return reinterpret_cast<iterator>(this+1); } + iterator end() const { return begin() + NumParameters; } + + /// \brief Get the number of parameters in this parameter pack. + unsigned getNumExpansions() const { return NumParameters; } + + /// \brief Get an expansion of the parameter pack by index. + ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; } + + SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == FunctionParmPackExprClass; + } + + child_range children() { return child_range(); } +}; + /// \brief Represents a prvalue temporary that written into memory so that /// a reference can bind to it. /// @@ -3670,9 +3691,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MaterializeTemporaryExprClass; } - static bool classof(const MaterializeTemporaryExpr *) { - return true; - } // Iterators child_range children() { return child_range(&Temporary, &Temporary + 1); } diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 93a5ada..27f5da0 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -51,7 +51,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCStringLiteralClass; } - static bool classof(const ObjCStringLiteral *) { return true; } // Iterators child_range children() { return child_range(&String, &String+1); } @@ -81,7 +80,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCBoolLiteralExprClass; } - static bool classof(const ObjCBoolLiteralExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -121,7 +119,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCBoxedExprClass; } - static bool classof(const ObjCBoxedExpr *) { return true; } // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } @@ -156,7 +153,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCArrayLiteralClass; } - static bool classof(const ObjCArrayLiteral *) { return true; } /// \brief Retrieve elements of array of literals. Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); } @@ -319,7 +315,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCDictionaryLiteralClass; } - static bool classof(const ObjCDictionaryLiteral *) { return true; } // Iterators child_range children() { @@ -372,7 +367,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCEncodeExprClass; } - static bool classof(const ObjCEncodeExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -409,7 +403,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSelectorExprClass; } - static bool classof(const ObjCSelectorExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -447,7 +440,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCProtocolExprClass; } - static bool classof(const ObjCProtocolExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -501,7 +493,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIvarRefExprClass; } - static bool classof(const ObjCIvarRefExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base+1); } @@ -715,7 +706,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCPropertyRefExprClass; } - static bool classof(const ObjCPropertyRefExpr *) { return true; } // Iterators child_range children() { @@ -813,7 +803,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSubscriptRefExprClass; } - static bool classof(const ObjCSubscriptRefExpr *) { return true; } Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); } void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; } @@ -1156,10 +1145,8 @@ public: return getReceiverKind() == Class || getReceiverKind() == SuperClass; } - /// \brief Returns the receiver of an instance message. - /// - /// \brief Returns the object expression for an instance message, or - /// NULL for a message that is not an instance message. + /// \brief Returns the object expression (receiver) for an instance message, + /// or null for a message that is not an instance message. Expr *getInstanceReceiver() { if (getReceiverKind() == Instance) return static_cast<Expr *>(getReceiverPointer()); @@ -1208,6 +1195,17 @@ public: return SourceLocation(); } + /// \brief Retrieve the receiver type to which this message is being directed. + /// + /// This routine cross-cuts all of the different kinds of message + /// sends to determine what the underlying (statically known) type + /// of the receiver will be; use \c getReceiverKind() to determine + /// whether the message is a class or an instance method, whether it + /// is a send to super or not, etc. + /// + /// \returns The type of the receiver. + QualType getReceiverType() const; + /// \brief Retrieve the Objective-C interface to which this message /// is being directed, if known. /// @@ -1344,7 +1342,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCMessageExprClass; } - static bool classof(const ObjCMessageExpr *) { return true; } // Iterators child_range children(); @@ -1409,7 +1406,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIsaExprClass; } - static bool classof(const ObjCIsaExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base+1); } @@ -1483,7 +1479,6 @@ public: static bool classof(const Stmt *s) { return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass; } - static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; } }; /// \brief An Objective-C "bridged" cast expression, which casts between @@ -1532,8 +1527,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCBridgedCastExprClass; } - static bool classof(const ObjCBridgedCastExpr *) { return true; } - }; } // end namespace clang diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 7aedfe2..db2bddb 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -162,7 +162,7 @@ public: } /// \brief Get the decls that are contained in a file in the Offset/Length - /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of + /// range. \p Length can be 0 to indicate a point at \p Offset instead of /// a range. virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length, SmallVectorImpl<Decl *> &Decls) {} diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile index f6dd4ce..7fb33f2 100644 --- a/include/clang/AST/Makefile +++ b/include/clang/AST/Makefile @@ -1,6 +1,8 @@ CLANG_LEVEL := ../../.. TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc CommentNodes.inc +BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc \ + CommentNodes.inc CommentHTMLTags.inc \ + CommentHTMLTagsProperties.inc CommentCommandInfo.inc TABLEGEN_INC_FILES_COMMON = 1 @@ -33,3 +35,18 @@ $(ObjDir)/CommentNodes.inc.tmp : $(TD_SRC_DIR)/CommentNodes.td $(CLANG_TBLGEN) \ $(Echo) "Building Clang comment node tables with tblgen" $(Verb) $(ClangTableGen) -gen-clang-comment-nodes -o $(call SYSPATH, $@) $< +$(ObjDir)/CommentHTMLTags.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(CLANG_TBLGEN) \ + $(ObjDir)/.dir + $(Echo) "Building Clang comment HTML tag matchers with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags -o $(call SYSPATH, $@) $< + +$(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td \ + $(CLANG_TBLGEN) $(ObjDir)/.dir + $(Echo) "Building Clang comment HTML tag properties with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $< + +$(ObjDir)/CommentCommandInfo.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \ + $(CLANG_TBLGEN) $(ObjDir)/.dir + $(Echo) "Building Clang comment command info with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-comment-command-info -o $(call SYSPATH, $@) $< + diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h index 51ae1da..f9fd1f9 100644 --- a/include/clang/AST/NSAPI.h +++ b/include/clang/AST/NSAPI.h @@ -83,7 +83,7 @@ public: /// \brief The Objective-C NSArray selectors. Selector getNSArraySelector(NSArrayMethodKind MK) const; - /// \brief Return NSArrayMethodKind if \arg Sel is such a selector. + /// \brief Return NSArrayMethodKind if \p Sel is such a selector. llvm::Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel); /// \brief Enumerates the NSDictionary methods used to generate literals. @@ -104,7 +104,7 @@ public: /// \brief The Objective-C NSDictionary selectors. Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const; - /// \brief Return NSDictionaryMethodKind if \arg Sel is such a selector. + /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector. llvm::Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel); @@ -169,7 +169,7 @@ public: Sel == getNSNumberLiteralSelector(MK, true); } - /// \brief Return NSNumberLiteralMethodKind if \arg Sel is such a selector. + /// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector. llvm::Optional<NSNumberLiteralMethodKind> getNSNumberLiteralMethodKind(Selector Sel) const; diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index a5aec1f..bf9e1cb 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -97,8 +97,7 @@ private: Specifier(Other.Specifier) { } - NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not - // implement + void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION; /// \brief Either find or insert the given nested name specifier /// mockup in the given context. diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index 6359414..18169fd 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -288,7 +288,11 @@ enum CastKind { /// /// This particular cast kind is used for the conversion from a C++11 /// lambda expression to a block pointer. - CK_CopyAndAutoreleaseBlockObject + CK_CopyAndAutoreleaseBlockObject, + + // Convert a builtin function to a function pointer; only allowed in the + // callee of a call expression. + CK_BuiltinFnToFnPtr }; static const CastKind CK_Invalid = static_cast<CastKind>(-1); diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index f2c015f..7babc1b 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -39,6 +39,7 @@ struct PrintingPolicy { SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), SuppressStrongLifetime(false), Bool(LO.Bool), + TerseOutput(false), SuppressAttributes(false), DumpSourceManager(0) { } /// \brief What language we're printing. @@ -134,6 +135,17 @@ struct PrintingPolicy { /// doesn't actually have 'bool' (because, e.g., it is defined as a macro). unsigned Bool : 1; + /// \brief Provide a 'terse' output. + /// + /// For example, in this mode we don't print function bodies, class members, + /// declarations inside namespaces etc. Effectively, this should print + /// only the requested declaration. + unsigned TerseOutput : 1; + + /// \brief When true, do not print attributes attached to the declaration. + /// + unsigned SuppressAttributes : 1; + /// \brief If we are "dumping" rather than "pretty-printing", this points to /// a SourceManager which will be used to dump SourceLocations. Dumping /// involves printing the internal details of the AST and pretty-printing diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h index 630626b..3a8b218 100644 --- a/include/clang/AST/RawCommentList.h +++ b/include/clang/AST/RawCommentList.h @@ -18,6 +18,7 @@ namespace clang { class ASTContext; class ASTReader; class Decl; +class Preprocessor; namespace comments { class FullComment; @@ -114,7 +115,8 @@ public: } /// Parse the comment, assuming it is attached to decl \c D. - comments::FullComment *parse(const ASTContext &Context, const Decl *D) const; + comments::FullComment *parse(const ASTContext &Context, + const Preprocessor *PP, const Decl *D) const; private: SourceRange Range; @@ -188,7 +190,7 @@ public: private: SourceManager &SourceMgr; std::vector<RawComment *> Comments; - RawComment LastComment; + SourceLocation PrevCommentEndLoc; bool OnlyWhitespaceSeen; void addCommentsToFront(const std::vector<RawComment *> &C) { diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index 3a870d0..3655646 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -136,8 +136,8 @@ private: void Destroy(ASTContext &Ctx); - ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT - void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT + ASTRecordLayout(const ASTRecordLayout &) LLVM_DELETED_FUNCTION; + void operator=(const ASTRecordLayout &) LLVM_DELETED_FUNCTION; public: /// getAlignment - Get the record alignment in characters. diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 2e56a48..f96e067 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -721,6 +721,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument( case TemplateArgument::Null: case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: return true; case TemplateArgument::Type: @@ -753,6 +754,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc( case TemplateArgument::Null: case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: return true; case TemplateArgument::Type: { @@ -799,7 +801,7 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer( if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); - if (Init->isWritten()) + if (Init->isWritten() || getDerived().shouldVisitImplicitCode()) TRY_TO(TraverseStmt(Init->getInit())); return true; } @@ -1827,7 +1829,7 @@ bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \ return true; \ } -DEF_TRAVERSE_STMT(AsmStmt, { +DEF_TRAVERSE_STMT(GCCAsmStmt, { TRY_TO(TraverseStmt(S->getAsmString())); for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) { TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I))); @@ -1836,7 +1838,7 @@ DEF_TRAVERSE_STMT(AsmStmt, { TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I))); } for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) { - TRY_TO(TraverseStmt(S->getClobber(I))); + TRY_TO(TraverseStmt(S->getClobberStringLiteral(I))); } // children() iterates over inputExpr and outputExpr. }) @@ -2141,7 +2143,9 @@ DEF_TRAVERSE_STMT(BlockExpr, { return true; // no child statements to loop through. }) DEF_TRAVERSE_STMT(ChooseExpr, { }) -DEF_TRAVERSE_STMT(CompoundLiteralExpr, { }) +DEF_TRAVERSE_STMT(CompoundLiteralExpr, { + TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); +}) DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { }) DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { }) DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { }) @@ -2219,6 +2223,7 @@ DEF_TRAVERSE_STMT(PackExpansionExpr, { }) DEF_TRAVERSE_STMT(SizeOfPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { }) +DEF_TRAVERSE_STMT(FunctionParmPackExpr, { }) DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { }) DEF_TRAVERSE_STMT(AtomicExpr, { }) diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h index cd43a5c..6d903f8 100644 --- a/include/clang/AST/SelectorLocationsKind.h +++ b/include/clang/AST/SelectorLocationsKind.h @@ -42,7 +42,7 @@ enum SelectorLocationsKind { SelLoc_StandardWithSpace = 2 }; -/// \brief Returns true if all \arg SelLocs are in a "standard" location. +/// \brief Returns true if all \p SelLocs are in a "standard" location. SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef<SourceLocation> SelLocs, ArrayRef<Expr *> Args, @@ -60,7 +60,7 @@ SourceLocation getStandardSelectorLoc(unsigned Index, ArrayRef<Expr *> Args, SourceLocation EndLoc); -/// \brief Returns true if all \arg SelLocs are in a "standard" location. +/// \brief Returns true if all \p SelLocs are in a "standard" location. SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef<SourceLocation> SelLocs, ArrayRef<ParmVarDecl *> Args, diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 35fb693..a9bbb48 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -392,9 +392,6 @@ public: const_cast<const Stmt*>(this)->stripLabelLikeStatements()); } - // Implement isa<T> support. - static bool classof(const Stmt *) { return true; } - /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) /// contain implicit control-flow in the order their subexpressions /// are evaluated. This predicate returns true if this statement has @@ -424,12 +421,12 @@ public: /// \brief Produce a unique representation of the given statement. /// - /// \brief ID once the profiling operation is complete, will contain + /// \param ID once the profiling operation is complete, will contain /// the unique representation of the given statement. /// - /// \brief Context the AST context in which the statement resides + /// \param Context the AST context in which the statement resides /// - /// \brief Canonical whether the profile should be based on the canonical + /// \param Canonical whether the profile should be based on the canonical /// representation of this statement (e.g., where non-type template /// parameters are identified by index/level rather than their /// declaration pointers) or the exact representation of the statement as @@ -480,7 +477,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DeclStmtClass; } - static bool classof(const DeclStmt *) { return true; } // Iterators over subexpressions. child_range children() { @@ -535,7 +531,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == NullStmtClass; } - static bool classof(const NullStmt *) { return true; } child_range children() { return child_range(); } @@ -615,7 +610,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CompoundStmtClass; } - static bool classof(const CompoundStmt *) { return true; } // Iterators child_range children() { @@ -654,7 +648,6 @@ public: return T->getStmtClass() == CaseStmtClass || T->getStmtClass() == DefaultStmtClass; } - static bool classof(const SwitchCase *) { return true; } }; class CaseStmt : public SwitchCase { @@ -714,7 +707,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CaseStmtClass; } - static bool classof(const CaseStmt *) { return true; } // Iterators child_range children() { @@ -749,7 +741,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DefaultStmtClass; } - static bool classof(const DefaultStmt *) { return true; } // Iterators child_range children() { return child_range(&SubStmt, &SubStmt+1); } @@ -788,7 +779,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == LabelStmtClass; } - static bool classof(const LabelStmt *) { return true; } }; @@ -837,7 +827,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == AttributedStmtClass; } - static bool classof(const AttributedStmt *) { return true; } }; @@ -906,7 +895,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == IfStmtClass; } - static bool classof(const IfStmt *) { return true; } }; /// SwitchStmt - This represents a 'switch' stmt. @@ -1000,7 +988,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SwitchStmtClass; } - static bool classof(const SwitchStmt *) { return true; } }; @@ -1050,7 +1037,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == WhileStmtClass; } - static bool classof(const WhileStmt *) { return true; } // Iterators child_range children() { @@ -1099,7 +1085,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DoStmtClass; } - static bool classof(const DoStmt *) { return true; } // Iterators child_range children() { @@ -1171,7 +1156,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ForStmtClass; } - static bool classof(const ForStmt *) { return true; } // Iterators child_range children() { @@ -1206,7 +1190,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == GotoStmtClass; } - static bool classof(const GotoStmt *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1251,7 +1234,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == IndirectGotoStmtClass; } - static bool classof(const IndirectGotoStmt *) { return true; } // Iterators child_range children() { return child_range(&Target, &Target+1); } @@ -1278,7 +1260,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ContinueStmtClass; } - static bool classof(const ContinueStmt *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1302,7 +1283,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == BreakStmtClass; } - static bool classof(const BreakStmt *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1354,7 +1334,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ReturnStmtClass; } - static bool classof(const ReturnStmt *) { return true; } // Iterators child_range children() { @@ -1363,48 +1342,184 @@ public: } }; -/// AsmStmt - This represents a GNU inline-assembly statement extension. +/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt. /// class AsmStmt : public Stmt { - SourceLocation AsmLoc, RParenLoc; - StringLiteral *AsmStr; - +protected: + SourceLocation AsmLoc; + /// \brief True if the assembly statement does not have any input or output + /// operands. bool IsSimple; + + /// \brief If true, treat this inline assembly as having side effects. + /// This assembly statement should not be optimized, deleted or moved. bool IsVolatile; - bool MSAsm; unsigned NumOutputs; unsigned NumInputs; unsigned NumClobbers; - // FIXME: If we wanted to, we could allocate all of these in one big array. IdentifierInfo **Names; - StringLiteral **Constraints; Stmt **Exprs; - StringLiteral **Clobbers; -public: - AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, - bool msasm, unsigned numoutputs, unsigned numinputs, - IdentifierInfo **names, StringLiteral **constraints, - Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, - StringLiteral **clobbers, SourceLocation rparenloc); + AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile, + unsigned numoutputs, unsigned numinputs, unsigned numclobbers) : + Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile), + NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { } +public: /// \brief Build an empty inline-assembly statement. - explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty), - Names(0), Constraints(0), Exprs(0), Clobbers(0) { } + explicit AsmStmt(StmtClass SC, EmptyShell Empty) : + Stmt(SC, Empty), Names(0), Exprs(0) { } SourceLocation getAsmLoc() const { return AsmLoc; } void setAsmLoc(SourceLocation L) { AsmLoc = L; } - SourceLocation getRParenLoc() const { return RParenLoc; } - void setRParenLoc(SourceLocation L) { RParenLoc = L; } - bool isVolatile() const { return IsVolatile; } - void setVolatile(bool V) { IsVolatile = V; } bool isSimple() const { return IsSimple; } void setSimple(bool V) { IsSimple = V; } - bool isMSAsm() const { return MSAsm; } - void setMSAsm(bool V) { MSAsm = V; } + + bool isVolatile() const { return IsVolatile; } + void setVolatile(bool V) { IsVolatile = V; } + + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); } + + //===--- Asm String Analysis ---===// + + /// Assemble final IR asm string. + std::string generateAsmString(ASTContext &C) const; + + //===--- Output operands ---===// + + unsigned getNumOutputs() const { return NumOutputs; } + + IdentifierInfo *getOutputIdentifier(unsigned i) const { + return Names[i]; + } + + StringRef getOutputName(unsigned i) const { + if (IdentifierInfo *II = getOutputIdentifier(i)) + return II->getName(); + + return StringRef(); + } + + /// getOutputConstraint - Return the constraint string for the specified + /// output operand. All output constraints are known to be non-empty (either + /// '=' or '+'). + StringRef getOutputConstraint(unsigned i) const; + + /// isOutputPlusConstraint - Return true if the specified output constraint + /// is a "+" constraint (which is both an input and an output) or false if it + /// is an "=" constraint (just an output). + bool isOutputPlusConstraint(unsigned i) const { + return getOutputConstraint(i)[0] == '+'; + } + + const Expr *getOutputExpr(unsigned i) const; + + /// getNumPlusOperands - Return the number of output operands that have a "+" + /// constraint. + unsigned getNumPlusOperands() const; + + //===--- Input operands ---===// + + unsigned getNumInputs() const { return NumInputs; } + + IdentifierInfo *getInputIdentifier(unsigned i) const { + return Names[i + NumOutputs]; + } + + StringRef getInputName(unsigned i) const { + if (IdentifierInfo *II = getInputIdentifier(i)) + return II->getName(); + + return StringRef(); + } + + /// getInputConstraint - Return the specified input constraint. Unlike output + /// constraints, these can be empty. + StringRef getInputConstraint(unsigned i) const; + + const Expr *getInputExpr(unsigned i) const; + + //===--- Other ---===// + + unsigned getNumClobbers() const { return NumClobbers; } + StringRef getClobber(unsigned i) const; + + static bool classof(const Stmt *T) { + return T->getStmtClass() == GCCAsmStmtClass || + T->getStmtClass() == MSAsmStmtClass; + } + + // Input expr iterators. + + typedef ExprIterator inputs_iterator; + typedef ConstExprIterator const_inputs_iterator; + + inputs_iterator begin_inputs() { + return &Exprs[0] + NumOutputs; + } + + inputs_iterator end_inputs() { + return &Exprs[0] + NumOutputs + NumInputs; + } + + const_inputs_iterator begin_inputs() const { + return &Exprs[0] + NumOutputs; + } + + const_inputs_iterator end_inputs() const { + return &Exprs[0] + NumOutputs + NumInputs; + } + + // Output expr iterators. + + typedef ExprIterator outputs_iterator; + typedef ConstExprIterator const_outputs_iterator; + + outputs_iterator begin_outputs() { + return &Exprs[0]; + } + outputs_iterator end_outputs() { + return &Exprs[0] + NumOutputs; + } + + const_outputs_iterator begin_outputs() const { + return &Exprs[0]; + } + const_outputs_iterator end_outputs() const { + return &Exprs[0] + NumOutputs; + } + + child_range children() { + return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); + } +}; + +/// This represents a GCC inline-assembly statement extension. +/// +class GCCAsmStmt : public AsmStmt { + SourceLocation RParenLoc; + StringLiteral *AsmStr; + + // FIXME: If we wanted to, we could allocate all of these in one big array. + StringLiteral **Constraints; + StringLiteral **Clobbers; + +public: + GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, + bool isvolatile, unsigned numoutputs, unsigned numinputs, + IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, + StringLiteral *asmstr, unsigned numclobbers, + StringLiteral **clobbers, SourceLocation rparenloc); + + /// \brief Build an empty inline-assembly statement. + explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty), + Constraints(0), Clobbers(0) { } + + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } //===--- Asm String Analysis ---===// @@ -1461,25 +1576,11 @@ public: unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces, ASTContext &C, unsigned &DiagOffs) const; + /// Assemble final IR asm string. + std::string generateAsmString(ASTContext &C) const; //===--- Output operands ---===// - unsigned getNumOutputs() const { return NumOutputs; } - - IdentifierInfo *getOutputIdentifier(unsigned i) const { - return Names[i]; - } - - StringRef getOutputName(unsigned i) const { - if (IdentifierInfo *II = getOutputIdentifier(i)) - return II->getName(); - - return StringRef(); - } - - /// getOutputConstraint - Return the constraint string for the specified - /// output operand. All output constraints are known to be non-empty (either - /// '=' or '+'). StringRef getOutputConstraint(unsigned i) const; const StringLiteral *getOutputConstraintLiteral(unsigned i) const { @@ -1492,37 +1593,11 @@ public: Expr *getOutputExpr(unsigned i); const Expr *getOutputExpr(unsigned i) const { - return const_cast<AsmStmt*>(this)->getOutputExpr(i); + return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i); } - /// isOutputPlusConstraint - Return true if the specified output constraint - /// is a "+" constraint (which is both an input and an output) or false if it - /// is an "=" constraint (just an output). - bool isOutputPlusConstraint(unsigned i) const { - return getOutputConstraint(i)[0] == '+'; - } - - /// getNumPlusOperands - Return the number of output operands that have a "+" - /// constraint. - unsigned getNumPlusOperands() const; - //===--- Input operands ---===// - unsigned getNumInputs() const { return NumInputs; } - - IdentifierInfo *getInputIdentifier(unsigned i) const { - return Names[i + NumOutputs]; - } - - StringRef getInputName(unsigned i) const { - if (IdentifierInfo *II = getInputIdentifier(i)) - return II->getName(); - - return StringRef(); - } - - /// getInputConstraint - Return the specified input constraint. Unlike output - /// constraints, these can be empty. StringRef getInputConstraint(unsigned i) const; const StringLiteral *getInputConstraintLiteral(unsigned i) const { @@ -1536,7 +1611,7 @@ public: void setInputExpr(unsigned i, Expr *E); const Expr *getInputExpr(unsigned i) const { - return const_cast<AsmStmt*>(this)->getInputExpr(i); + return const_cast<GCCAsmStmt*>(this)->getInputExpr(i); } void setOutputsAndInputsAndClobbers(ASTContext &C, @@ -1555,90 +1630,45 @@ public: /// This returns -1 if the operand name is invalid. int getNamedOperand(StringRef SymbolicName) const; - unsigned getNumClobbers() const { return NumClobbers; } - StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } - const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } + StringRef getClobber(unsigned i) const; + StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; } + const StringLiteral *getClobberStringLiteral(unsigned i) const { + return Clobbers[i]; + } SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AsmLoc, RParenLoc); } - static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} - static bool classof(const AsmStmt *) { return true; } - - // Input expr iterators. - - typedef ExprIterator inputs_iterator; - typedef ConstExprIterator const_inputs_iterator; - - inputs_iterator begin_inputs() { - return &Exprs[0] + NumOutputs; - } - - inputs_iterator end_inputs() { - return &Exprs[0] + NumOutputs + NumInputs; - } - - const_inputs_iterator begin_inputs() const { - return &Exprs[0] + NumOutputs; - } - - const_inputs_iterator end_inputs() const { - return &Exprs[0] + NumOutputs + NumInputs; - } - - // Output expr iterators. - - typedef ExprIterator outputs_iterator; - typedef ConstExprIterator const_outputs_iterator; - - outputs_iterator begin_outputs() { - return &Exprs[0]; - } - outputs_iterator end_outputs() { - return &Exprs[0] + NumOutputs; - } - - const_outputs_iterator begin_outputs() const { - return &Exprs[0]; - } - const_outputs_iterator end_outputs() const { - return &Exprs[0] + NumOutputs; - } - - child_range children() { - return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); + static bool classof(const Stmt *T) { + return T->getStmtClass() == GCCAsmStmtClass; } }; -/// MSAsmStmt - This represents a MS inline-assembly statement extension. +/// This represents a Microsoft inline-assembly statement extension. /// -class MSAsmStmt : public Stmt { +class MSAsmStmt : public AsmStmt { SourceLocation AsmLoc, LBraceLoc, EndLoc; std::string AsmStr; - bool IsSimple; - bool IsVolatile; - unsigned NumAsmToks; - unsigned NumInputs; - unsigned NumOutputs; - unsigned NumClobbers; Token *AsmToks; - IdentifierInfo **Names; - Stmt **Exprs; + StringRef *Constraints; StringRef *Clobbers; public: MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, bool issimple, bool isvolatile, ArrayRef<Token> asmtoks, - ArrayRef<IdentifierInfo*> inputs, ArrayRef<IdentifierInfo*> outputs, - StringRef asmstr, ArrayRef<StringRef> clobbers, - SourceLocation endloc); + unsigned numoutputs, unsigned numinputs, + ArrayRef<IdentifierInfo*> names, ArrayRef<StringRef> constraints, + ArrayRef<Expr*> exprs, StringRef asmstr, + ArrayRef<StringRef> clobbers, SourceLocation endloc); + + /// \brief Build an empty MS-style inline-assembly statement. + explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty), + NumAsmToks(0), AsmToks(0), Constraints(0), Clobbers(0) { } - SourceLocation getAsmLoc() const { return AsmLoc; } - void setAsmLoc(SourceLocation L) { AsmLoc = L; } SourceLocation getLBraceLoc() const { return LBraceLoc; } void setLBraceLoc(SourceLocation L) { LBraceLoc = L; } SourceLocation getEndLoc() const { return EndLoc; } @@ -1649,20 +1679,42 @@ public: unsigned getNumAsmToks() { return NumAsmToks; } Token *getAsmToks() { return AsmToks; } - bool isVolatile() const { return IsVolatile; } - void setVolatile(bool V) { IsVolatile = V; } - bool isSimple() const { return IsSimple; } - void setSimple(bool V) { IsSimple = V; } - //===--- Asm String Analysis ---===// const std::string *getAsmString() const { return &AsmStr; } std::string *getAsmString() { return &AsmStr; } void setAsmString(StringRef &E) { AsmStr = E.str(); } + /// Assemble final IR asm string. + std::string generateAsmString(ASTContext &C) const; + + //===--- Output operands ---===// + + StringRef getOutputConstraint(unsigned i) const { + return Constraints[i]; + } + + Expr *getOutputExpr(unsigned i); + + const Expr *getOutputExpr(unsigned i) const { + return const_cast<MSAsmStmt*>(this)->getOutputExpr(i); + } + + //===--- Input operands ---===// + + StringRef getInputConstraint(unsigned i) const { + return Constraints[i + NumOutputs]; + } + + Expr *getInputExpr(unsigned i); + void setInputExpr(unsigned i, Expr *E); + + const Expr *getInputExpr(unsigned i) const { + return const_cast<MSAsmStmt*>(this)->getInputExpr(i); + } + //===--- Other ---===// - unsigned getNumClobbers() const { return NumClobbers; } StringRef getClobber(unsigned i) const { return Clobbers[i]; } SourceRange getSourceRange() const LLVM_READONLY { @@ -1671,7 +1723,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MSAsmStmtClass; } - static bool classof(const MSAsmStmt *) { return true; } child_range children() { return child_range(&Exprs[0], &Exprs[0]); @@ -1720,8 +1771,6 @@ public: return T->getStmtClass() == SEHExceptStmtClass; } - static bool classof(SEHExceptStmt *) { return true; } - }; class SEHFinallyStmt : public Stmt { @@ -1757,8 +1806,6 @@ public: return T->getStmtClass() == SEHFinallyStmtClass; } - static bool classof(SEHFinallyStmt *) { return true; } - }; class SEHTryStmt : public Stmt { @@ -1810,8 +1857,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SEHTryStmtClass; } - - static bool classof(SEHTryStmt *) { return true; } }; } // end namespace clang diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index a948722..f4e4dcd 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -50,7 +50,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXCatchStmtClass; } - static bool classof(const CXXCatchStmt *) { return true; } child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); } @@ -111,7 +110,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTryStmtClass; } - static bool classof(const CXXTryStmt *) { return true; } child_range children() { return child_range(getStmts(), getStmts() + getNumHandlers() + 1); @@ -196,7 +194,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXForRangeStmtClass; } - static bool classof(const CXXForRangeStmt *) { return true; } // Iterators child_range children() { @@ -286,8 +283,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MSDependentExistsStmtClass; } - - static bool classof(MSDependentExistsStmt *) { return true; } }; } // end namespace clang diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index e7e1232..d7a73a7 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -61,7 +61,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCForCollectionStmtClass; } - static bool classof(const ObjCForCollectionStmt *) { return true; } // Iterators child_range children() { @@ -112,7 +111,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtCatchStmtClass; } - static bool classof(const ObjCAtCatchStmt *) { return true; } child_range children() { return child_range(&Body, &Body + 1); } }; @@ -143,7 +141,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtFinallyStmtClass; } - static bool classof(const ObjCAtFinallyStmt *) { return true; } child_range children() { return child_range(&AtFinallyStmt, &AtFinallyStmt+1); @@ -244,7 +241,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtTryStmtClass; } - static bool classof(const ObjCAtTryStmt *) { return true; } child_range children() { return child_range(getStmts(), @@ -303,7 +299,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtSynchronizedStmtClass; } - static bool classof(const ObjCAtSynchronizedStmt *) { return true; } child_range children() { return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR); @@ -339,7 +334,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtThrowStmtClass; } - static bool classof(const ObjCAtThrowStmt *) { return true; } child_range children() { return child_range(&Throw, &Throw+1); } }; @@ -371,7 +365,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAutoreleasePoolStmtClass; } - static bool classof(const ObjCAutoreleasePoolStmt *) { return true; } child_range children() { return child_range(&SubStmt, &SubStmt + 1); } }; diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 5047028..1c0abde 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -28,11 +28,11 @@ namespace llvm { namespace clang { -class Decl; class DiagnosticBuilder; class Expr; struct PrintingPolicy; class TypeSourceInfo; +class ValueDecl; /// \brief Represents a template argument within a class template /// specialization. @@ -43,12 +43,14 @@ public: /// \brief Represents an empty template argument, e.g., one that has not /// been deduced. Null = 0, - /// The template argument is a type. Its value is stored in the - /// TypeOrValue field. + /// The template argument is a type. Type, - /// The template argument is a declaration that was provided for a pointer - /// or reference non-type template parameter. + /// The template argument is a declaration that was provided for a pointer, + /// reference, or pointer to member non-type template parameter. Declaration, + /// The template argument is a null pointer or null pointer to member that + /// was provided for a non-type template parameter. + NullPtr, /// The template argument is an integral value stored in an llvm::APSInt /// that was provided for an integral non-type template parameter. Integral, @@ -73,6 +75,10 @@ private: union { uintptr_t TypeOrValue; struct { + ValueDecl *D; + bool ForRefParam; + } DeclArg; + struct { // We store a decomposed APSInt with the data allocated by ASTContext if // BitWidth > 64. The memory may be shared between multiple // TemplateArgument instances. @@ -101,15 +107,18 @@ public: TemplateArgument() : Kind(Null), TypeOrValue(0) { } /// \brief Construct a template type argument. - TemplateArgument(QualType T) : Kind(Type) { + TemplateArgument(QualType T, bool isNullPtr = false) + : Kind(isNullPtr ? NullPtr : Type) { TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); } /// \brief Construct a template argument that refers to a /// declaration, which is either an external declaration or a /// template declaration. - TemplateArgument(Decl *D) : Kind(Declaration) { - TypeOrValue = reinterpret_cast<uintptr_t>(D); + TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) { + assert(D && "Expected decl"); + DeclArg.D = D; + DeclArg.ForRefParam = ForRefParam; } /// \brief Construct an integral constant template argument. The memory to @@ -177,6 +186,10 @@ public: this->Args.NumArgs = NumArgs; } + static TemplateArgument getEmptyPack() { + return TemplateArgument((TemplateArgument*)0, 0); + } + /// \brief Create a new template argument pack by copying the given set of /// template arguments. static TemplateArgument CreatePackCopy(ASTContext &Context, @@ -205,34 +218,43 @@ public: /// \brief Determine whether this template argument is a pack expansion. bool isPackExpansion() const; - /// \brief Retrieve the template argument as a type. + /// \brief Retrieve the type for a type template argument. QualType getAsType() const { - if (Kind != Type) - return QualType(); - + assert(Kind == Type && "Unexpected kind"); return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); } - /// \brief Retrieve the template argument as a declaration. - Decl *getAsDecl() const { - if (Kind != Declaration) - return 0; - return reinterpret_cast<Decl *>(TypeOrValue); + /// \brief Retrieve the declaration for a declaration non-type + /// template argument. + ValueDecl *getAsDecl() const { + assert(Kind == Declaration && "Unexpected kind"); + return DeclArg.D; + } + + /// \brief Retrieve whether a declaration is binding to a + /// reference parameter in a declaration non-type template argument. + bool isDeclForReferenceParam() const { + assert(Kind == Declaration && "Unexpected kind"); + return DeclArg.ForRefParam; } - /// \brief Retrieve the template argument as a template name. + /// \brief Retrieve the type for null non-type template argument. + QualType getNullPtrType() const { + assert(Kind == NullPtr && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); + } + + /// \brief Retrieve the template name for a template name argument. TemplateName getAsTemplate() const { - if (Kind != Template) - return TemplateName(); - + assert(Kind == Template && "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } /// \brief Retrieve the template argument as a template name; if the argument /// is a pack expansion, return the pattern as a template name. TemplateName getAsTemplateOrTemplatePattern() const { - if (Kind != Template && Kind != TemplateExpansion) - return TemplateName(); + assert((Kind == Template || Kind == TemplateExpansion) && + "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } @@ -244,6 +266,7 @@ public: /// \brief Retrieve the template argument as an integral value. // FIXME: Provide a way to read the integral data without copying the value. llvm::APSInt getAsIntegral() const { + assert(Kind == Integral && "Unexpected kind"); using namespace llvm; if (Integer.BitWidth <= 64) return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); @@ -255,23 +278,18 @@ public: /// \brief Retrieve the type of the integral value. QualType getIntegralType() const { - if (Kind != Integral) - return QualType(); - + assert(Kind == Integral && "Unexpected kind"); return QualType::getFromOpaquePtr(Integer.Type); } void setIntegralType(QualType T) { - assert(Kind == Integral && - "Cannot set the integral type of a non-integral template argument"); + assert(Kind == Integral && "Unexpected kind"); Integer.Type = T.getAsOpaquePtr(); } /// \brief Retrieve the template argument as an expression. Expr *getAsExpr() const { - if (Kind != Expression) - return 0; - + assert(Kind == Expression && "Unexpected kind"); return reinterpret_cast<Expr *>(TypeOrValue); } @@ -436,7 +454,17 @@ public: assert(Argument.getKind() == TemplateArgument::Declaration); return LocInfo.getAsExpr(); } - + + Expr *getSourceNullPtrExpression() const { + assert(Argument.getKind() == TemplateArgument::NullPtr); + return LocInfo.getAsExpr(); + } + + Expr *getSourceIntegralExpression() const { + assert(Argument.getKind() == TemplateArgument::Integral); + return LocInfo.getAsExpr(); + } + NestedNameSpecifierLoc getTemplateQualifierLoc() const { assert(Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion); diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 6564b66..6900a7d 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -20,6 +20,7 @@ #include "clang/Basic/Linkage.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/Visibility.h" +#include "clang/Basic/Specifiers.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "llvm/Support/type_traits.h" @@ -160,6 +161,44 @@ public: Qualifiers() : Mask(0) {} + /// \brief Returns the common set of qualifiers while removing them from + /// the given sets. + static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { + // If both are only CVR-qualified, bit operations are sufficient. + if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { + Qualifiers Q; + Q.Mask = L.Mask & R.Mask; + L.Mask &= ~Q.Mask; + R.Mask &= ~Q.Mask; + return Q; + } + + Qualifiers Q; + unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); + Q.addCVRQualifiers(CommonCRV); + L.removeCVRQualifiers(CommonCRV); + R.removeCVRQualifiers(CommonCRV); + + if (L.getObjCGCAttr() == R.getObjCGCAttr()) { + Q.setObjCGCAttr(L.getObjCGCAttr()); + L.removeObjCGCAttr(); + R.removeObjCGCAttr(); + } + + if (L.getObjCLifetime() == R.getObjCLifetime()) { + Q.setObjCLifetime(L.getObjCLifetime()); + L.removeObjCLifetime(); + R.removeObjCLifetime(); + } + + if (L.getAddressSpace() == R.getAddressSpace()) { + Q.setAddressSpace(L.getAddressSpace()); + L.removeAddressSpace(); + R.removeAddressSpace(); + } + return Q; + } + static Qualifiers fromFastMask(unsigned Mask) { Qualifiers Qs; Qs.addFastQualifiers(Mask); @@ -333,6 +372,23 @@ public: } } + /// \brief Remove the qualifiers from the given set from this set. + void removeQualifiers(Qualifiers Q) { + // If the other set doesn't have any non-boolean qualifiers, just + // bit-and the inverse in. + if (!(Q.Mask & ~CVRMask)) + Mask &= ~Q.Mask; + else { + Mask &= ~(Q.Mask & CVRMask); + if (getObjCGCAttr() == Q.getObjCGCAttr()) + removeObjCGCAttr(); + if (getObjCLifetime() == Q.getObjCLifetime()) + removeObjCLifetime(); + if (getAddressSpace() == Q.getAddressSpace()) + removeAddressSpace(); + } + } + /// \brief Add the qualifiers from the given set to this set, given that /// they don't conflict. void addConsistentQualifiers(Qualifiers qs) { @@ -400,7 +456,7 @@ public: } Qualifiers &operator-=(Qualifiers R) { - Mask = Mask & ~(R.Mask); + removeQualifiers(R); return *this; } @@ -435,18 +491,6 @@ private: static const uint32_t AddressSpaceShift = 8; }; -/// CallingConv - Specifies the calling convention that a function uses. -enum CallingConv { - CC_Default, - CC_C, // __attribute__((cdecl)) - CC_X86StdCall, // __attribute__((stdcall)) - CC_X86FastCall, // __attribute__((fastcall)) - CC_X86ThisCall, // __attribute__((thiscall)) - CC_X86Pascal, // __attribute__((pascal)) - CC_AAPCS, // __attribute__((pcs("aapcs"))) - CC_AAPCS_VFP // __attribute__((pcs("aapcs-vfp"))) -}; - /// A std::pair-like structure for storing a qualified type split /// into its local qualifiers and its locally-unqualified type. struct SplitQualType { @@ -1126,8 +1170,8 @@ public: }; private: - Type(const Type&); // DO NOT IMPLEMENT. - void operator=(const Type&); // DO NOT IMPLEMENT. + Type(const Type &) LLVM_DELETED_FUNCTION; + void operator=(const Type &) LLVM_DELETED_FUNCTION; /// Bitfields required by the Type class. class TypeBitfields { @@ -1225,7 +1269,7 @@ protected: /// Extra information which affects how the function is called, like /// regparm and the calling convention. - unsigned ExtInfo : 8; + unsigned ExtInfo : 9; /// TypeQuals - Used only by FunctionProtoType, put here to pack with the /// other bitfields. @@ -1512,6 +1556,7 @@ public: bool isRecordType() const; bool isClassType() const; bool isStructureType() const; + bool isInterfaceType() const; bool isStructureOrClassType() const; bool isUnionType() const; bool isComplexIntegerType() const; // GCC _Complex integer type. @@ -1630,13 +1675,19 @@ public: const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; - const CXXRecordDecl *getCXXRecordDeclForPointerType() const; /// \brief Retrieves the CXXRecordDecl that this type refers to, either /// because the type is a RecordType or because it is the injected-class-name /// type of a class template or class template partial specialization. CXXRecordDecl *getAsCXXRecordDecl() const; + /// If this is a pointer or reference to a RecordType, return the + /// CXXRecordDecl that that type refers to. + /// + /// If this is not a pointer or reference, or the type being pointed to does + /// not refer to a CXXRecordDecl, returns NULL. + const CXXRecordDecl *getPointeeCXXRecordDecl() const; + /// \brief Get the AutoType whose type will be deduced for a variable with /// an initializer of this type. This looks through declarators like pointer /// types, but not through decltype or typedefs. @@ -1738,8 +1789,6 @@ public: CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h LLVM_ATTRIBUTE_USED void dump() const; - static bool classof(const Type *) { return true; } - friend class ASTReader; friend class ASTWriter; }; @@ -1748,6 +1797,11 @@ public: /// until it reaches a TypedefType or a non-sugared type. template <> const TypedefType *Type::getAs() const; +/// \brief This will check for a TemplateSpecializationType by removing any +/// existing sugar until it reaches a TemplateSpecializationType or a +/// non-sugared type. +template <> const TemplateSpecializationType *Type::getAs() const; + // We can do canonical leaf types faster, because we don't have to // worry about preserving child type decoration. #define TYPE(Class, Base) @@ -1834,7 +1888,6 @@ public: } static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } - static bool classof(const BuiltinType *) { return true; } }; /// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex @@ -1865,7 +1918,6 @@ public: } static bool classof(const Type *T) { return T->getTypeClass() == Complex; } - static bool classof(const ComplexType *) { return true; } }; /// ParenType - Sugar for parentheses used when specifying types. @@ -1897,7 +1949,6 @@ public: } static bool classof(const Type *T) { return T->getTypeClass() == Paren; } - static bool classof(const ParenType *) { return true; } }; /// PointerType - C99 6.7.5.1 - Pointer Declarators. @@ -1929,7 +1980,6 @@ public: } static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } - static bool classof(const PointerType *) { return true; } }; /// BlockPointerType - pointer to a block type. @@ -1965,7 +2015,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == BlockPointer; } - static bool classof(const BlockPointerType *) { return true; } }; /// ReferenceType - Base for LValueReferenceType and RValueReferenceType @@ -2013,7 +2062,6 @@ public: return T->getTypeClass() == LValueReference || T->getTypeClass() == RValueReference; } - static bool classof(const ReferenceType *) { return true; } }; /// LValueReferenceType - C++ [dcl.ref] - Lvalue reference @@ -2031,7 +2079,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == LValueReference; } - static bool classof(const LValueReferenceType *) { return true; } }; /// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference @@ -2048,7 +2095,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == RValueReference; } - static bool classof(const RValueReferenceType *) { return true; } }; /// MemberPointerType - C++ 8.3.3 - Pointers to members @@ -2103,7 +2149,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == MemberPointer; } - static bool classof(const MemberPointerType *) { return true; } }; /// ArrayType - C99 6.7.5.2 - Array Declarators. @@ -2159,7 +2204,6 @@ public: T->getTypeClass() == IncompleteArray || T->getTypeClass() == DependentSizedArray; } - static bool classof(const ArrayType *) { return true; } }; /// ConstantArrayType - This class represents the canonical version of @@ -2211,7 +2255,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == ConstantArray; } - static bool classof(const ConstantArrayType *) { return true; } }; /// IncompleteArrayType - This class represents C arrays with an unspecified @@ -2231,7 +2274,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == IncompleteArray; } - static bool classof(const IncompleteArrayType *) { return true; } friend class StmtIteratorBase; @@ -2294,7 +2336,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == VariableArray; } - static bool classof(const VariableArrayType *) { return true; } friend class StmtIteratorBase; @@ -2351,7 +2392,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == DependentSizedArray; } - static bool classof(const DependentSizedArrayType *) { return true; } friend class StmtIteratorBase; @@ -2397,7 +2437,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == DependentSizedExtVector; } - static bool classof(const DependentSizedExtVectorType *) { return true; } void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Context, getElementType(), getSizeExpr()); @@ -2463,7 +2502,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; } - static bool classof(const VectorType *) { return true; } }; /// ExtVectorType - Extended vector type. This type is created using @@ -2529,7 +2567,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == ExtVector; } - static bool classof(const ExtVectorType *) { return true; } }; /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base @@ -2561,19 +2598,19 @@ class FunctionType : public Type { // * AST read and write // * Codegen class ExtInfo { - // Feel free to rearrange or add bits, but if you go over 8, + // Feel free to rearrange or add bits, but if you go over 9, // you'll need to adjust both the Bits field below and // Type::FunctionTypeBitfields. // | CC |noreturn|produces|regparm| - // |0 .. 2| 3 | 4 | 5 .. 7| + // |0 .. 3| 4 | 5 | 6 .. 8| // // regparm is either 0 (no regparm attribute) or the regparm value+1. - enum { CallConvMask = 0x7 }; - enum { NoReturnMask = 0x8 }; - enum { ProducesResultMask = 0x10 }; + enum { CallConvMask = 0xF }; + enum { NoReturnMask = 0x10 }; + enum { ProducesResultMask = 0x20 }; enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask), - RegParmOffset = 5 }; // Assumed to be the last field + RegParmOffset = 6 }; // Assumed to be the last field uint16_t Bits; @@ -2692,7 +2729,6 @@ public: return T->getTypeClass() == FunctionNoProto || T->getTypeClass() == FunctionProto; } - static bool classof(const FunctionType *) { return true; } }; /// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has @@ -2724,7 +2760,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == FunctionNoProto; } - static bool classof(const FunctionNoProtoType *) { return true; } }; /// FunctionProtoType - Represents a prototype with argument type info, e.g. @@ -2972,14 +3007,13 @@ public: // FIXME: Remove the string version. void printExceptionSpecification(std::string &S, - PrintingPolicy Policy) const; + const PrintingPolicy &Policy) const; void printExceptionSpecification(raw_ostream &OS, - PrintingPolicy Policy) const; + const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == FunctionProto; } - static bool classof(const FunctionProtoType *) { return true; } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, @@ -3010,7 +3044,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == UnresolvedUsing; } - static bool classof(const UnresolvedUsingType *) { return true; } void Profile(llvm::FoldingSetNodeID &ID) { return Profile(ID, Decl); @@ -3042,7 +3075,6 @@ public: QualType desugar() const; static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } - static bool classof(const TypedefType *) { return true; } }; /// TypeOfExprType (GCC extension). @@ -3062,7 +3094,6 @@ public: bool isSugared() const; static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } - static bool classof(const TypeOfExprType *) { return true; } }; /// \brief Internal representation of canonical, dependent @@ -3109,7 +3140,6 @@ public: bool isSugared() const { return true; } static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } - static bool classof(const TypeOfType *) { return true; } }; /// DecltypeType (C++0x) @@ -3131,7 +3161,6 @@ public: bool isSugared() const; static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } - static bool classof(const DecltypeType *) { return true; } }; /// \brief Internal representation of canonical, dependent @@ -3184,7 +3213,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == UnaryTransform; } - static bool classof(const UnaryTransformType *) { return true; } }; class TagType : public Type { @@ -3207,7 +3235,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast; } - static bool classof(const TagType *) { return true; } }; /// RecordType - This is a helper class that allows the use of isa/cast/dyncast @@ -3234,7 +3261,6 @@ public: QualType desugar() const { return QualType(this, 0); } static bool classof(const Type *T) { return T->getTypeClass() == Record; } - static bool classof(const RecordType *) { return true; } }; /// EnumType - This is a helper class that allows the use of isa/cast/dyncast @@ -3253,7 +3279,6 @@ public: QualType desugar() const { return QualType(this, 0); } static bool classof(const Type *T) { return T->getTypeClass() == Enum; } - static bool classof(const EnumType *) { return true; } }; /// AttributedType - An attributed type is a type to which a type @@ -3297,7 +3322,8 @@ public: attr_fastcall, attr_stdcall, attr_thiscall, - attr_pascal + attr_pascal, + attr_pnaclcall }; private: @@ -3341,7 +3367,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Attributed; } - static bool classof(const AttributedType *T) { return true; } }; class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { @@ -3415,7 +3440,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == TemplateTypeParm; } - static bool classof(const TemplateTypeParmType *T) { return true; } }; /// \brief Represents the result of substituting a type for a template @@ -3466,7 +3490,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == SubstTemplateTypeParm; } - static bool classof(const SubstTemplateTypeParmType *T) { return true; } }; /// \brief Represents the result of substituting a set of types for a template @@ -3519,7 +3542,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == SubstTemplateTypeParmPack; } - static bool classof(const SubstTemplateTypeParmPackType *T) { return true; } }; /// \brief Represents a C++0x auto type. @@ -3562,7 +3584,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Auto; } - static bool classof(const AutoType *T) { return true; } }; /// \brief Represents a type template specialization; the template @@ -3726,7 +3747,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == TemplateSpecialization; } - static bool classof(const TemplateSpecializationType *T) { return true; } }; /// \brief The injected class name of a C++ class template or class @@ -3789,13 +3809,14 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == InjectedClassName; } - static bool classof(const InjectedClassNameType *T) { return true; } }; /// \brief The kind of a tag type. enum TagTypeKind { /// \brief The "struct" keyword. TTK_Struct, + /// \brief The "__interface" keyword. + TTK_Interface, /// \brief The "union" keyword. TTK_Union, /// \brief The "class" keyword. @@ -3809,6 +3830,8 @@ enum TagTypeKind { enum ElaboratedTypeKeyword { /// \brief The "struct" keyword introduces the elaborated-type-specifier. ETK_Struct, + /// \brief The "__interface" keyword introduces the elaborated-type-specifier. + ETK_Interface, /// \brief The "union" keyword introduces the elaborated-type-specifier. ETK_Union, /// \brief The "class" keyword introduces the elaborated-type-specifier. @@ -3932,7 +3955,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; } - static bool classof(const ElaboratedType *T) { return true; } }; /// \brief Represents a qualified type name for which the type name is @@ -3996,7 +4018,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == DependentName; } - static bool classof(const DependentNameType *T) { return true; } }; /// DependentTemplateSpecializationType - Represents a template @@ -4067,9 +4088,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == DependentTemplateSpecialization; } - static bool classof(const DependentTemplateSpecializationType *T) { - return true; - } }; /// \brief Represents a pack expansion of types. @@ -4150,9 +4168,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == PackExpansion; } - static bool classof(const PackExpansionType *T) { - return true; - } }; /// ObjCObjectType - Represents a class type in Objective C. @@ -4263,7 +4278,6 @@ public: return T->getTypeClass() == ObjCObject || T->getTypeClass() == ObjCInterface; } - static bool classof(const ObjCObjectType *) { return true; } }; /// ObjCObjectTypeImpl - A class providing a concrete implementation @@ -4327,7 +4341,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == ObjCInterface; } - static bool classof(const ObjCInterfaceType *) { return true; } // Nonsense to "hide" certain members of ObjCObjectType within this // class. People asking for protocols on an ObjCInterfaceType are @@ -4477,7 +4490,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == ObjCObjectPointer; } - static bool classof(const ObjCObjectPointerType *) { return true; } }; class AtomicType : public Type, public llvm::FoldingSetNode { @@ -4508,7 +4520,6 @@ class AtomicType : public Type, public llvm::FoldingSetNode { static bool classof(const Type *T) { return T->getTypeClass() == Atomic; } - static bool classof(const AtomicType *) { return true; } }; /// A qualifier set is used to build a set of qualifiers. diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 11a878d..8a04bd8 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -159,8 +159,6 @@ public: return !(LHS == RHS); } - static bool classof(const TypeLoc *TL) { return true; } - private: static void initializeImpl(ASTContext &Context, TypeLoc TL, SourceLocation Loc); @@ -192,7 +190,6 @@ public: static bool classof(const TypeLoc *TL) { return !TL->getType().hasLocalQualifiers(); } - static bool classof(const UnqualTypeLoc *TL) { return true; } }; /// \brief Wrapper of type source information for a type with @@ -237,7 +234,6 @@ public: static bool classof(const TypeLoc *TL) { return TL->getType().hasLocalQualifiers(); } - static bool classof(const QualifiedTypeLoc *TL) { return true; } }; inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { @@ -250,11 +246,11 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { /// to a particular Type subclass. It is accepted for a single /// TypeLoc class to correspond to multiple Type classes. /// -/// \param Base a class from which to derive -/// \param Derived the class deriving from this one -/// \param TypeClass the concrete Type subclass associated with this +/// \tparam Base a class from which to derive +/// \tparam Derived the class deriving from this one +/// \tparam TypeClass the concrete Type subclass associated with this /// location type -/// \param LocalData the structure type of local location data for +/// \tparam LocalData the structure type of local location data for /// this type /// /// sizeof(LocalData) needs to be a multiple of sizeof(void*) or @@ -303,9 +299,6 @@ public: static bool classof(const UnqualTypeLoc *TL) { return Derived::classofType(TL->getTypePtr()); } - static bool classof(const Derived *TL) { - return true; - } TypeLoc getNextTypeLoc() const { return getNextTypeLoc(asDerived()->getInnerType()); @@ -380,9 +373,6 @@ public: static bool classof(const UnqualTypeLoc *TL) { return Derived::classofType(TL->getTypePtr()); } - static bool classof(const Derived *TL) { - return true; - } const TypeClass *getTypePtr() const { return cast<TypeClass>(Base::getTypePtr()); @@ -417,7 +407,6 @@ public: } static bool classof(const TypeLoc *TL); - static bool classof(const TypeSpecTypeLoc *TL) { return true; } }; @@ -866,6 +855,7 @@ public: void initializeLocal(ASTContext &Context, SourceLocation Loc) { setNameLoc(Loc); + setNameEndLoc(Loc); } }; @@ -1060,6 +1050,8 @@ public: struct FunctionLocInfo { SourceLocation LocalRangeBegin; + SourceLocation LParenLoc; + SourceLocation RParenLoc; SourceLocation LocalRangeEnd; }; @@ -1083,6 +1075,24 @@ public: getLocalData()->LocalRangeEnd = L; } + SourceLocation getLParenLoc() const { + return this->getLocalData()->LParenLoc; + } + void setLParenLoc(SourceLocation Loc) { + this->getLocalData()->LParenLoc = Loc; + } + + SourceLocation getRParenLoc() const { + return this->getLocalData()->RParenLoc; + } + void setRParenLoc(SourceLocation Loc) { + this->getLocalData()->RParenLoc = Loc; + } + + SourceRange getParensRange() const { + return SourceRange(getLParenLoc(), getRParenLoc()); + } + ArrayRef<ParmVarDecl *> getParams() const { return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs()); } @@ -1110,6 +1120,8 @@ public: void initializeLocal(ASTContext &Context, SourceLocation Loc) { setLocalRangeBegin(Loc); + setLParenLoc(Loc); + setRParenLoc(Loc); setLocalRangeEnd(Loc); for (unsigned i = 0, e = getNumArgs(); i != e; ++i) setArg(i, NULL); diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index 0918dc4..9f11ee5 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -94,7 +94,7 @@ class UnresolvedSetImpl { private: template <unsigned N> friend class UnresolvedSet; UnresolvedSetImpl() {} - UnresolvedSetImpl(const UnresolvedSetImpl &) {} + UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION; public: // We don't currently support assignment through this iterator, so we might diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h index 392dad9..a6aa40b 100644 --- a/include/clang/AST/VTableBuilder.h +++ b/include/clang/AST/VTableBuilder.h @@ -147,9 +147,10 @@ private: assert((ComponentKind == CK_VCallOffset || ComponentKind == CK_VBaseOffset || ComponentKind == CK_OffsetToTop) && "Invalid component kind!"); - assert(Offset.getQuantity() <= ((1LL << 56) - 1) && "Offset is too big!"); + assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!"); + assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!"); - Value = ((Offset.getQuantity() << 3) | ComponentKind); + Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind; } VTableComponent(Kind ComponentKind, uintptr_t Ptr) { |