diff options
author | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | c72c57c9e9b69944e3e009cd5e209634839581d3 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /include/clang/AST | |
parent | 5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff) | |
download | FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz |
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'include/clang/AST')
63 files changed, 3287 insertions, 1647 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index 1b6e90c..ec8faa4 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -15,8 +15,8 @@ #define LLVM_CLANG_AST_APVALUE_H #include "clang/Basic/LLVM.h" -#include "llvm/ADT/APSInt.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h index 164c5fb..6db351d 100644 --- a/include/clang/AST/AST.h +++ b/include/clang/AST/AST.h @@ -22,7 +22,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" -#include "clang/AST/Type.h" #include "clang/AST/StmtVisitor.h" +#include "clang/AST/Type.h" #endif diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 37b0740..ae77943 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -17,9 +17,9 @@ namespace clang { class ASTContext; class CXXRecordDecl; + class Decl; class DeclGroupRef; class HandleTagDeclDefinition; - class PPMutationListener; class ASTMutationListener; class ASTDeserializationListener; // layering violation because void* is ugly class SemaConsumer; // layering violation required for safe SemaConsumer @@ -112,11 +112,6 @@ 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. @@ -130,6 +125,14 @@ public: /// PrintStats - If desired, print any statistics. virtual void PrintStats() {} + + /// \brief This callback is called for each function if the Parser was + /// initialized with \c SkipFunctionBodies set to \c true. + /// + /// \return \c true if the function's body should be skipped. The function + /// body may be parsed anyway if it is needed (for instance, if it contains + /// the code completion point or is constexpr). + virtual bool shouldSkipFunctionBody(Decl *D) { return true; } }; } // end namespace clang. diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index f0934b7..d4878a9 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -15,21 +15,23 @@ #ifndef LLVM_CLANG_AST_ASTCONTEXT_H #define LLVM_CLANG_AST_ASTCONTEXT_H -#include "clang/Basic/AddressSpaces.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/OperatorKinds.h" -#include "clang/Basic/PartialDiagnostic.h" -#include "clang/Basic/VersionTuple.h" +#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/CanonicalType.h" +#include "clang/AST/CommentCommandTraits.h" #include "clang/AST/Decl.h" #include "clang/AST/LambdaMangleContext.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" +#include "clang/AST/RawCommentList.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" -#include "clang/AST/CanonicalType.h" -#include "clang/AST/RawCommentList.h" -#include "clang/AST/CommentCommandTraits.h" +#include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/VersionTuple.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -57,28 +59,12 @@ namespace clang { class TargetInfo; class CXXABI; // Decls - class DeclContext; - class CXXConversionDecl; - class CXXMethodDecl; - class CXXRecordDecl; - class Decl; - class FieldDecl; class MangleContext; class ObjCIvarDecl; - class ObjCIvarRefExpr; class ObjCPropertyDecl; - class ParmVarDecl; - class RecordDecl; - class StoredDeclsMap; - class TagDecl; - class TemplateTemplateParmDecl; - class TemplateTypeParmDecl; - class TranslationUnitDecl; - class TypeDecl; - class TypedefNameDecl; + class UnresolvedSetIterator; class UsingDecl; class UsingShadowDecl; - class UnresolvedSetIterator; namespace Builtin { class Context; } @@ -91,7 +77,7 @@ namespace clang { class ASTContext : public RefCountedBase<ASTContext> { ASTContext &this_() { return *this; } - mutable std::vector<Type*> Types; + mutable SmallVector<Type *, 0> Types; mutable llvm::FoldingSet<ExtQuals> ExtQualNodes; mutable llvm::FoldingSet<ComplexType> ComplexTypes; mutable llvm::FoldingSet<PointerType> PointerTypes; @@ -233,6 +219,8 @@ class ASTContext : public RefCountedBase<ASTContext> { QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTypeDecl; + mutable QualType ObjCSuperType; + QualType ObjCNSStringType; /// \brief The typedef declaration for the Objective-C "instancetype" type. @@ -343,7 +331,10 @@ class ASTContext : public RefCountedBase<ASTContext> { /// \brief Mapping from each declaration context to its corresponding lambda /// mangling context. llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts; - + + llvm::DenseMap<const DeclContext *, unsigned> UnnamedMangleContexts; + llvm::DenseMap<const TagDecl *, unsigned> UnnamedMangleNumbers; + /// \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; @@ -393,6 +384,58 @@ public: OwningPtr<ExternalASTSource> ExternalSource; ASTMutationListener *Listener; + /// \brief Contains parents of a node. + typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 1> ParentVector; + + /// \brief Maps from a node to its parents. + typedef llvm::DenseMap<const void *, ParentVector> ParentMap; + + /// \brief Returns the parents of the given node. + /// + /// Note that this will lazily compute the parents of all nodes + /// and store them for later retrieval. Thus, the first call is O(n) + /// in the number of AST nodes. + /// + /// Caveats and FIXMEs: + /// Calculating the parent map over all AST nodes will need to load the + /// full AST. This can be undesirable in the case where the full AST is + /// expensive to create (for example, when using precompiled header + /// preambles). Thus, there are good opportunities for optimization here. + /// One idea is to walk the given node downwards, looking for references + /// to declaration contexts - once a declaration context is found, compute + /// the parent map for the declaration context; if that can satisfy the + /// request, loading the whole AST can be avoided. Note that this is made + /// more complex by statements in templates having multiple parents - those + /// problems can be solved by building closure over the templated parts of + /// the AST, which also avoids touching large parts of the AST. + /// Additionally, we will want to add an interface to already give a hint + /// where to search for the parents, for example when looking at a statement + /// inside a certain function. + /// + /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc, + /// NestedNameSpecifier or NestedNameSpecifierLoc. + template <typename NodeT> + ParentVector getParents(const NodeT &Node) { + return getParents(ast_type_traits::DynTypedNode::create(Node)); + } + + ParentVector getParents(const ast_type_traits::DynTypedNode &Node) { + assert(Node.getMemoizationData() && + "Invariant broken: only nodes that support memoization may be " + "used in the parent map."); + if (!AllParents) { + // We always need to run over the whole translation unit, as + // hasAncestor can escape any subtree. + AllParents.reset( + ParentMapASTVisitor::buildMap(*getTranslationUnitDecl())); + } + ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData()); + if (I == AllParents->end()) { + return ParentVector(); + } + return I->second; + } + const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; } @@ -713,6 +756,10 @@ public: CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; + CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy; + CanQualType OCLImage2dTy, OCLImage2dArrayTy; + CanQualType OCLImage3dTy; + CanQualType OCLSamplerTy, OCLEventTy; // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. mutable QualType AutoDeductTy; // Deduction against 'auto'. @@ -755,7 +802,7 @@ public: ASTMutationListener *getASTMutationListener() const { return Listener; } void PrintStats() const; - const std::vector<Type*>& getTypes() const { return Types; } + const SmallVectorImpl<Type *>& getTypes() const { return Types; } /// \brief Retrieve the declaration for the 128-bit signed integer type. TypedefDecl *getInt128Decl() const; @@ -857,12 +904,17 @@ public: return cudaConfigureCallDecl; } - /// 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; - + bool BlockRequiresCopying(QualType Ty, const VarDecl *D); + + + /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set + /// to false in this case. If HasByrefExtendedLayout returns true, byref variable + /// has extended lifetime. + bool getByrefLifetime(QualType Ty, + Qualifiers::ObjCLifetime &Lifetime, + bool &HasByrefExtendedLayout) const; + /// \brief Return the uniqued reference to the type for an lvalue reference /// to the specified type. QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true) @@ -941,8 +993,7 @@ public: } /// \brief Return a normal function type with a typed argument list. - QualType getFunctionType(QualType ResultTy, - const QualType *Args, unsigned NumArgs, + QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args, const FunctionProtoType::ExtProtoInfo &EPI) const; /// \brief Return the unique reference to the type for the specified type @@ -1025,7 +1076,7 @@ public: const TemplateArgument *Args) const; QualType getPackExpansionType(QualType Pattern, - llvm::Optional<unsigned> NumExpansions); + Optional<unsigned> NumExpansions); QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl = 0) const; @@ -1094,6 +1145,14 @@ public: /// defined in <stddef.h> as defined by the target. QualType getWIntType() const { return WIntTy; } + /// \brief Return a type compatible with "intptr_t" (C99 7.18.1.4), + /// as defined by the target. + QualType getIntPtrType() const; + + /// \brief Return a type compatible with "uintptr_t" (C99 7.18.1.4), + /// as defined by the target. + QualType getUIntPtrType() const; + /// \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; @@ -1104,7 +1163,11 @@ public: /// \brief Return the C structure type used to represent constant CFStrings. QualType getCFConstantStringType() const; - + + /// \brief Returns the C struct type for objc_super + QualType getObjCSuperType() const; + void setObjCSuperType(QualType ST) { ObjCSuperType = ST; } + /// Get the structure type used to representation CFStrings, or NULL /// if it hasn't yet been built. QualType getRawCFConstantStringType() const { @@ -1545,14 +1608,27 @@ public: const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const; - /// \brief Get the key function for the given record decl, or NULL if there - /// isn't one. + /// \brief Get our current best idea for the key function of 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. /// - /// ...the first non-pure virtual function that is not inline at the point - /// of class definition. - const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD); + /// Other ABIs use the same idea. However, the ARM C++ ABI ignores + /// virtual functions that are defined 'inline', which means that + /// the result of this computation can change. + const CXXMethodDecl *getCurrentKeyFunction(const CXXRecordDecl *RD); + + /// \brief Observe that the given method cannot be a key function. + /// Checks the key-function cache for the method's class and clears it + /// if matches the given declaration. + /// + /// This is used in ABIs where out-of-line definitions marked + /// inline are not considered to be key functions. + /// + /// \param method should be the declaration from the class definition + void setNonKeyFunction(const CXXMethodDecl *method); /// Get the offset of a FieldDecl or IndirectFieldDecl, in bits. uint64_t getFieldOffset(const ValueDecl *FD) const; @@ -1885,8 +1961,8 @@ public: // Type Iterators. //===--------------------------------------------------------------------===// - typedef std::vector<Type*>::iterator type_iterator; - typedef std::vector<Type*>::const_iterator const_type_iterator; + typedef SmallVectorImpl<Type *>::iterator type_iterator; + typedef SmallVectorImpl<Type *>::const_iterator const_type_iterator; type_iterator types_begin() { return Types.begin(); } type_iterator types_end() { return Types.end(); } @@ -1943,7 +2019,7 @@ public: /// \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; + const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const; /// \brief Set the copy inialization expression of a block var decl. void setBlockVarCopyInits(VarDecl*VD, Expr* Init); @@ -1993,6 +2069,9 @@ public: /// it is not used. bool DeclMustBeEmitted(const Decl *D); + void addUnnamedTag(const TagDecl *Tag); + int getUnnamedTagManglingNumber(const TagDecl *Tag) const; + /// \brief Retrieve the lambda mangling number for a lambda expression. unsigned getLambdaManglingNumber(CXXMethodDecl *CallOperator); @@ -2077,7 +2156,8 @@ private: bool EncodingProperty = false, bool StructField = false, bool EncodeBlockParameters = false, - bool EncodeClassNames = false) const; + bool EncodeClassNames = false, + bool EncodePointerToObjCTypedef = false) const; // Adds the encoding of the structure's members. void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S, @@ -2109,8 +2189,81 @@ private: friend class DeclContext; friend class DeclarationNameTable; void ReleaseDeclContextMaps(); + + /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their + /// parents as defined by the \c RecursiveASTVisitor. + /// + /// Note that the relationship described here is purely in terms of AST + /// traversal - there are other relationships (for example declaration context) + /// in the AST that are better modeled by special matchers. + /// + /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes. + class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> { + public: + /// \brief Builds and returns the translation unit's parent map. + /// + /// The caller takes ownership of the returned \c ParentMap. + static ParentMap *buildMap(TranslationUnitDecl &TU) { + ParentMapASTVisitor Visitor(new ParentMap); + Visitor.TraverseDecl(&TU); + return Visitor.Parents; + } + + private: + typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase; + + ParentMapASTVisitor(ParentMap *Parents) : Parents(Parents) { + } + + bool shouldVisitTemplateInstantiations() const { + return true; + } + bool shouldVisitImplicitCode() const { + return true; + } + // Disables data recursion. We intercept Traverse* methods in the RAV, which + // are not triggered during data recursion. + bool shouldUseDataRecursionFor(clang::Stmt *S) const { + return false; + } + + template <typename T> + bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) { + if (Node == NULL) + return true; + if (ParentStack.size() > 0) + // FIXME: Currently we add the same parent multiple times, for example + // when we visit all subexpressions of template instantiations; this is + // suboptimal, bug benign: the only way to visit those is with + // hasAncestor / hasParent, and those do not create new matches. + // The plan is to enable DynTypedNode to be storable in a map or hash + // map. The main problem there is to implement hash functions / + // comparison operators for all types that DynTypedNode supports that + // do not have pointer identity. + (*Parents)[Node].push_back(ParentStack.back()); + ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node)); + bool Result = (this ->* traverse) (Node); + ParentStack.pop_back(); + return Result; + } + + bool TraverseDecl(Decl *DeclNode) { + return TraverseNode(DeclNode, &VisitorBase::TraverseDecl); + } + + bool TraverseStmt(Stmt *StmtNode) { + return TraverseNode(StmtNode, &VisitorBase::TraverseStmt); + } + + ParentMap *Parents; + llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; + + friend class RecursiveASTVisitor<ParentMapASTVisitor>; + }; + + llvm::OwningPtr<ParentMap> AllParents; }; - + /// \brief Utility function for constructing a nullary selector. static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); @@ -2132,8 +2285,8 @@ static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) { /// This placement form of operator new uses the ASTContext's allocator for /// obtaining memory. /// -/// IMPORTANT: These are also declared in clang/AST/Attr.h! Any changes here -/// need to also be made there. +/// IMPORTANT: These are also declared in clang/AST/AttrIterator.h! Any changes +/// here need to also be made there. /// /// We intentionally avoid using a nothrow specification here so that the calls /// to this operator will not perform a null check on the result -- the diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index 46a9881..1672ab2 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -48,6 +48,9 @@ namespace clang { /// \brief Whether to perform a minimal import. bool Minimal; + + /// \brief Whether the last diagnostic came from the "from" context. + bool LastDiagFromFrom; /// \brief Mapping from the already-imported types in the "from" context /// to the corresponding types in the "to" context. diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index 56d1526..6b70285 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -16,18 +16,19 @@ #include "clang/Basic/SourceLocation.h" namespace clang { - class Decl; - class DeclContext; - class TagDecl; class CXXRecordDecl; class ClassTemplateDecl; class ClassTemplateSpecializationDecl; + class Decl; + class DeclContext; class FunctionDecl; class FunctionTemplateDecl; class ObjCCategoryDecl; - class ObjCInterfaceDecl; class ObjCContainerDecl; + class ObjCInterfaceDecl; class ObjCPropertyDecl; + class TagDecl; + class VarDecl; /// \brief An abstract interface that should be implemented by listeners /// that want to be notified when an AST entity gets modified after its diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h new file mode 100644 index 0000000..4688b12 --- /dev/null +++ b/include/clang/AST/ASTTypeTraits.h @@ -0,0 +1,211 @@ +//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Provides a dynamically typed node container that can be used to store +// an AST base node at runtime in the same storage in a type safe way. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H +#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H + +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/TypeLoc.h" +#include "llvm/Support/AlignOf.h" + +namespace clang { +namespace ast_type_traits { + +/// \brief A dynamically typed AST node container. +/// +/// Stores an AST node in a type safe way. This allows writing code that +/// works with different kinds of AST nodes, despite the fact that they don't +/// have a common base class. +/// +/// Use \c create(Node) to create a \c DynTypedNode from an AST node, +/// and \c get<T>() to retrieve the node as type T if the types match. +/// +/// See \c NodeTypeTag for which node base types are currently supported; +/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of +/// the supported base types. +class DynTypedNode { +public: + /// \brief Creates a \c DynTypedNode from \c Node. + template <typename T> + static DynTypedNode create(const T &Node) { + return BaseConverter<T>::create(Node); + } + + /// \brief Retrieve the stored node as type \c T. + /// + /// Returns NULL if the stored node does not have a type that is + /// convertible to \c T. + /// + /// For types that have identity via their pointer in the AST + /// (like \c Stmt and \c Decl) the returned pointer points to the + /// referenced AST node. + /// For other types (like \c QualType) the value is stored directly + /// in the \c DynTypedNode, and the returned pointer points at + /// the storage inside DynTypedNode. For those nodes, do not + /// use the pointer outside the scope of the DynTypedNode. + template <typename T> + const T *get() const { + return BaseConverter<T>::get(Tag, Storage.buffer); + } + + /// \brief Returns a pointer that identifies the stored AST node. + /// + /// Note that this is not supported by all AST nodes. For AST nodes + /// that don't have a pointer-defined identity inside the AST, this + /// method returns NULL. + const void *getMemoizationData() const; + +private: + /// \brief Takes care of converting from and to \c T. + template <typename T, typename EnablerT = void> struct BaseConverter; + + /// \brief Supported base node types. + enum NodeTypeTag { + NT_Decl, + NT_Stmt, + NT_NestedNameSpecifier, + NT_NestedNameSpecifierLoc, + NT_QualType, + NT_Type, + NT_TypeLoc + } Tag; + + /// \brief Stores the data of the node. + /// + /// Note that we can store \c Decls and \c Stmts by pointer as they are + /// guaranteed to be unique pointers pointing to dedicated storage in the + /// AST. \c QualTypes on the other hand do not have storage or unique + /// pointers and thus need to be stored by value. + llvm::AlignedCharArrayUnion<Decl *, Stmt *, NestedNameSpecifier, + NestedNameSpecifierLoc, QualType, Type, + TypeLoc> Storage; +}; + +// FIXME: Pull out abstraction for the following. +template<typename T> struct DynTypedNode::BaseConverter<T, + typename llvm::enable_if<llvm::is_base_of<Decl, T> >::type> { + static const T *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_Decl) + return dyn_cast<T>(*reinterpret_cast<Decl*const*>(Storage)); + return NULL; + } + static DynTypedNode create(const Decl &Node) { + DynTypedNode Result; + Result.Tag = NT_Decl; + new (Result.Storage.buffer) const Decl*(&Node); + return Result; + } +}; +template<typename T> struct DynTypedNode::BaseConverter<T, + typename llvm::enable_if<llvm::is_base_of<Stmt, T> >::type> { + static const T *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_Stmt) + return dyn_cast<T>(*reinterpret_cast<Stmt*const*>(Storage)); + return NULL; + } + static DynTypedNode create(const Stmt &Node) { + DynTypedNode Result; + Result.Tag = NT_Stmt; + new (Result.Storage.buffer) const Stmt*(&Node); + return Result; + } +}; +template<typename T> struct DynTypedNode::BaseConverter<T, + typename llvm::enable_if<llvm::is_base_of<Type, T> >::type> { + static const T *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_Type) + return dyn_cast<T>(*reinterpret_cast<Type*const*>(Storage)); + return NULL; + } + static DynTypedNode create(const Type &Node) { + DynTypedNode Result; + Result.Tag = NT_Type; + new (Result.Storage.buffer) const Type*(&Node); + return Result; + } +}; +template<> struct DynTypedNode::BaseConverter<NestedNameSpecifier, void> { + static const NestedNameSpecifier *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_NestedNameSpecifier) + return *reinterpret_cast<NestedNameSpecifier*const*>(Storage); + return NULL; + } + static DynTypedNode create(const NestedNameSpecifier &Node) { + DynTypedNode Result; + Result.Tag = NT_NestedNameSpecifier; + new (Result.Storage.buffer) const NestedNameSpecifier*(&Node); + return Result; + } +}; +template<> struct DynTypedNode::BaseConverter<NestedNameSpecifierLoc, void> { + static const NestedNameSpecifierLoc *get(NodeTypeTag Tag, + const char Storage[]) { + if (Tag == NT_NestedNameSpecifierLoc) + return reinterpret_cast<const NestedNameSpecifierLoc*>(Storage); + return NULL; + } + static DynTypedNode create(const NestedNameSpecifierLoc &Node) { + DynTypedNode Result; + Result.Tag = NT_NestedNameSpecifierLoc; + new (Result.Storage.buffer) NestedNameSpecifierLoc(Node); + return Result; + } +}; +template<> struct DynTypedNode::BaseConverter<QualType, void> { + static const QualType *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_QualType) + return reinterpret_cast<const QualType*>(Storage); + return NULL; + } + static DynTypedNode create(const QualType &Node) { + DynTypedNode Result; + Result.Tag = NT_QualType; + new (Result.Storage.buffer) QualType(Node); + return Result; + } +}; +template<> struct DynTypedNode::BaseConverter<TypeLoc, void> { + static const TypeLoc *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_TypeLoc) + return reinterpret_cast<const TypeLoc*>(Storage); + return NULL; + } + static DynTypedNode create(const TypeLoc &Node) { + DynTypedNode Result; + Result.Tag = NT_TypeLoc; + new (Result.Storage.buffer) TypeLoc(Node); + return Result; + } +}; +// The only operation we allow on unsupported types is \c get. +// This allows to conveniently use \c DynTypedNode when having an arbitrary +// AST node that is not supported, but prevents misuse - a user cannot create +// a DynTypedNode from arbitrary types. +template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter { + static const T *get(NodeTypeTag Tag, const char Storage[]) { return NULL; } +}; + +inline const void *DynTypedNode::getMemoizationData() const { + switch (Tag) { + case NT_Decl: return BaseConverter<Decl>::get(Tag, Storage.buffer); + case NT_Stmt: return BaseConverter<Stmt>::get(Tag, Storage.buffer); + default: return NULL; + }; +} + +} // end namespace ast_type_traits +} // end namespace clang + +#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h new file mode 100644 index 0000000..c709895 --- /dev/null +++ b/include/clang/AST/ASTUnresolvedSet.h @@ -0,0 +1,86 @@ +//===-- ASTUnresolvedSet.h - Unresolved sets of declarations ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides an UnresolvedSet-like class, whose contents are +// allocated using the allocator associated with an ASTContext. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H +#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H + +#include "clang/AST/ASTVector.h" +#include "clang/AST/UnresolvedSet.h" + +namespace clang { + +/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator. +class ASTUnresolvedSet { + typedef ASTVector<DeclAccessPair> DeclsTy; + DeclsTy Decls; + + ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION; + void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION; + +public: + ASTUnresolvedSet() {} + ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {} + + typedef UnresolvedSetIterator iterator; + typedef UnresolvedSetIterator const_iterator; + + iterator begin() { return iterator(Decls.begin()); } + iterator end() { return iterator(Decls.end()); } + + const_iterator begin() const { return const_iterator(Decls.begin()); } + const_iterator end() const { return const_iterator(Decls.end()); } + + void addDecl(ASTContext &C, NamedDecl *D) { + addDecl(C, D, AS_none); + } + + void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) { + Decls.push_back(DeclAccessPair::make(D, AS), C); + } + + /// Replaces the given declaration with the new one, once. + /// + /// \return true if the set changed + bool replace(const NamedDecl* Old, NamedDecl *New) { + for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) + if (I->getDecl() == Old) + return (I->setDecl(New), true); + return false; + } + + void erase(unsigned I) { + Decls[I] = Decls.back(); + Decls.pop_back(); + } + + void clear() { Decls.clear(); } + + bool empty() const { return Decls.empty(); } + unsigned size() const { return Decls.size(); } + + void reserve(ASTContext &C, unsigned N) { + Decls.reserve(C, N); + } + + void append(ASTContext &C, iterator I, iterator E) { + Decls.append(C, I.ir, E.ir); + } + + DeclAccessPair &operator[](unsigned I) { return Decls[I]; } + const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; } +}; + +} // namespace clang + +#endif diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h index 4ff5ea3..669e50d 100644 --- a/include/clang/AST/ASTVector.h +++ b/include/clang/AST/ASTVector.h @@ -18,12 +18,13 @@ #ifndef LLVM_CLANG_AST_VECTOR #define LLVM_CLANG_AST_VECTOR -#include "llvm/Support/type_traits.h" -#include "llvm/Support/Allocator.h" +#include "clang/AST/AttrIterator.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/type_traits.h" #include <algorithm> -#include <memory> #include <cstring> +#include <memory> #ifdef _MSC_VER namespace std { @@ -50,6 +51,7 @@ namespace std { #endif namespace clang { + class ASTContext; template<typename T> class ASTVector { @@ -59,7 +61,9 @@ class ASTVector { public: // Default ctor - Initialize to empty. - explicit ASTVector(ASTContext &C, unsigned N = 0) + ASTVector() : Begin(NULL), End(NULL), Capacity(NULL) { } + + ASTVector(ASTContext &C, unsigned N) : Begin(NULL), End(NULL), Capacity(NULL) { reserve(C, N); } diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 12a9855..27dcef2 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -14,9 +14,10 @@ #ifndef LLVM_CLANG_AST_ATTR_H #define LLVM_CLANG_AST_ATTR_H -#include "clang/Basic/LLVM.h" -#include "clang/Basic/AttrKinds.h" +#include "clang/AST/AttrIterator.h" #include "clang/AST/Type.h" +#include "clang/Basic/AttrKinds.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/VersionTuple.h" #include "llvm/ADT/SmallVector.h" @@ -26,7 +27,6 @@ #include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstring> -#include <algorithm> namespace clang { class ASTContext; @@ -36,23 +36,6 @@ namespace clang { class QualType; class FunctionDecl; class TypeSourceInfo; -} - -// Defined in ASTContext.h -void *operator new(size_t Bytes, const clang::ASTContext &C, - size_t Alignment = 16); -// FIXME: Being forced to not have a default argument here due to redeclaration -// rules on default arguments sucks -void *operator new[](size_t Bytes, const clang::ASTContext &C, - size_t Alignment); - -// It is good practice to pair new/delete operators. Also, MSVC gives many -// warnings if a matching delete overload is not declared, even though the -// throw() spec guarantees it will not be implicitly called. -void operator delete(void *Ptr, const clang::ASTContext &C, size_t); -void operator delete[](void *Ptr, const clang::ASTContext &C, size_t); - -namespace clang { /// Attr - This represents one attribute. class Attr { @@ -61,10 +44,16 @@ private: unsigned AttrKind : 16; protected: + /// An index into the spelling list of an + /// attribute defined in Attr.td file. + unsigned SpellingListIndex : 4; + bool Inherited : 1; + bool IsPackExpansion : 1; + virtual ~Attr(); - + void* operator new(size_t bytes) throw() { llvm_unreachable("Attrs cannot be allocated with regular 'new'."); } @@ -84,14 +73,17 @@ public: } protected: - Attr(attr::Kind AK, SourceRange R) - : Range(R), AttrKind(AK), Inherited(false) {} + Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0) + : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex), + Inherited(false), IsPackExpansion(false) {} public: attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); } + + unsigned getSpellingListIndex() const { return SpellingListIndex; } SourceLocation getLocation() const { return Range.getBegin(); } SourceRange getRange() const { return Range; } @@ -99,21 +91,24 @@ public: bool isInherited() const { return Inherited; } + void setPackExpansion(bool PE) { IsPackExpansion = PE; } + bool isPackExpansion() const { return IsPackExpansion; } + // Clone this attribute. - virtual Attr* clone(ASTContext &C) const = 0; + virtual Attr *clone(ASTContext &C) const = 0; virtual bool isLateParsed() const { return false; } // Pretty print this attribute. - virtual void printPretty(llvm::raw_ostream &OS, + virtual void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const = 0; }; class InheritableAttr : public Attr { virtual void anchor(); protected: - InheritableAttr(attr::Kind AK, SourceRange R) - : Attr(AK, R) {} + InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0) + : Attr(AK, R, SpellingListIndex) {} public: void setInherited(bool I) { Inherited = I; } @@ -127,125 +122,35 @@ public: class InheritableParamAttr : public InheritableAttr { virtual void anchor(); protected: - InheritableParamAttr(attr::Kind AK, SourceRange R) - : InheritableAttr(AK, R) {} + InheritableParamAttr(attr::Kind AK, SourceRange R, + unsigned SpellingListIndex = 0) + : InheritableAttr(AK, R, SpellingListIndex) {} public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { + // Relies on relative order of enum emission with respect to MS inheritance + // attrs. return A->getKind() <= attr::LAST_INHERITABLE_PARAM; } }; -#include "clang/AST/Attrs.inc" - -/// AttrVec - A vector of Attr, which is how they are stored on the AST. -typedef SmallVector<Attr*, 2> AttrVec; -typedef SmallVector<const Attr*, 2> ConstAttrVec; - -/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only -/// providing attributes that are of a specifc type. -template <typename SpecificAttr, typename Container = AttrVec> -class specific_attr_iterator { - typedef typename Container::const_iterator Iterator; - - /// Current - The current, underlying iterator. - /// In order to ensure we don't dereference an invalid iterator unless - /// specifically requested, we don't necessarily advance this all the - /// way. Instead, we advance it when an operation is requested; if the - /// operation is acting on what should be a past-the-end iterator, - /// then we offer no guarantees, but this way we do not dererence a - /// past-the-end iterator when we move to a past-the-end position. - mutable Iterator Current; - - void AdvanceToNext() const { - while (!isa<SpecificAttr>(*Current)) - ++Current; - } - - void AdvanceToNext(Iterator I) const { - while (Current != I && !isa<SpecificAttr>(*Current)) - ++Current; - } +class MSInheritanceAttr : public InheritableAttr { + virtual void anchor(); +protected: + MSInheritanceAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0) + : InheritableAttr(AK, R, SpellingListIndex) {} public: - typedef SpecificAttr* value_type; - typedef SpecificAttr* reference; - typedef SpecificAttr* pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; - - specific_attr_iterator() : Current() { } - explicit specific_attr_iterator(Iterator i) : Current(i) { } - - reference operator*() const { - AdvanceToNext(); - return cast<SpecificAttr>(*Current); - } - pointer operator->() const { - AdvanceToNext(); - return cast<SpecificAttr>(*Current); - } - - specific_attr_iterator& operator++() { - ++Current; - return *this; - } - specific_attr_iterator operator++(int) { - specific_attr_iterator Tmp(*this); - ++(*this); - return Tmp; - } - - friend bool operator==(specific_attr_iterator Left, - specific_attr_iterator Right) { - if (Left.Current < Right.Current) - Left.AdvanceToNext(Right.Current); - else - Right.AdvanceToNext(Left.Current); - return Left.Current == Right.Current; - } - friend bool operator!=(specific_attr_iterator Left, - specific_attr_iterator Right) { - return !(Left == Right); + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + // Relies on relative order of enum emission with respect to param attrs. + return (A->getKind() <= attr::LAST_MS_INHERITABLE && + A->getKind() > attr::LAST_INHERITABLE_PARAM); } }; -template <typename SpecificAttr, typename Container> -inline specific_attr_iterator<SpecificAttr, Container> - specific_attr_begin(const Container& container) { - return specific_attr_iterator<SpecificAttr, Container>(container.begin()); -} -template <typename SpecificAttr, typename Container> -inline specific_attr_iterator<SpecificAttr, Container> - specific_attr_end(const Container& container) { - return specific_attr_iterator<SpecificAttr, Container>(container.end()); -} - -template <typename SpecificAttr, typename Container> -inline bool hasSpecificAttr(const Container& container) { - return specific_attr_begin<SpecificAttr>(container) != - specific_attr_end<SpecificAttr>(container); -} -template <typename SpecificAttr, typename Container> -inline SpecificAttr *getSpecificAttr(const Container& container) { - specific_attr_iterator<SpecificAttr, Container> i = - specific_attr_begin<SpecificAttr>(container); - if (i != specific_attr_end<SpecificAttr>(container)) - return *i; - else - return 0; -} - -/// getMaxAlignment - Returns the highest alignment value found among -/// AlignedAttrs in an AttrVec, or 0 if there are none. -inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) { - unsigned Align = 0; - specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end()); - for(; i != e; ++i) - Align = std::max(Align, i->getAlignment(Ctx)); - return Align; -} +#include "clang/AST/Attrs.inc" } // end namespace clang diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h new file mode 100644 index 0000000..8bd8fbe --- /dev/null +++ b/include/clang/AST/AttrIterator.h @@ -0,0 +1,142 @@ +//===--- AttrIterator.h - Classes for attribute iteration -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the Attr vector and specific_attr_iterator interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ATTRITERATOR_H +#define LLVM_CLANG_AST_ATTRITERATOR_H + +#include "clang/Basic/LLVM.h" +#include <iterator> + +namespace clang { + class ASTContext; + class Attr; +} + +// Defined in ASTContext.h +void *operator new(size_t Bytes, const clang::ASTContext &C, + size_t Alignment = 16); +// FIXME: Being forced to not have a default argument here due to redeclaration +// rules on default arguments sucks +void *operator new[](size_t Bytes, const clang::ASTContext &C, + size_t Alignment); + +// It is good practice to pair new/delete operators. Also, MSVC gives many +// warnings if a matching delete overload is not declared, even though the +// throw() spec guarantees it will not be implicitly called. +void operator delete(void *Ptr, const clang::ASTContext &C, size_t); +void operator delete[](void *Ptr, const clang::ASTContext &C, size_t); + +namespace clang { + +/// AttrVec - A vector of Attr, which is how they are stored on the AST. +typedef SmallVector<Attr*, 2> AttrVec; +typedef SmallVector<const Attr*, 2> ConstAttrVec; + +/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only +/// providing attributes that are of a specifc type. +template <typename SpecificAttr, typename Container = AttrVec> +class specific_attr_iterator { + typedef typename Container::const_iterator Iterator; + + /// Current - The current, underlying iterator. + /// In order to ensure we don't dereference an invalid iterator unless + /// specifically requested, we don't necessarily advance this all the + /// way. Instead, we advance it when an operation is requested; if the + /// operation is acting on what should be a past-the-end iterator, + /// then we offer no guarantees, but this way we do not dererence a + /// past-the-end iterator when we move to a past-the-end position. + mutable Iterator Current; + + void AdvanceToNext() const { + while (!isa<SpecificAttr>(*Current)) + ++Current; + } + + void AdvanceToNext(Iterator I) const { + while (Current != I && !isa<SpecificAttr>(*Current)) + ++Current; + } + +public: + typedef SpecificAttr* value_type; + typedef SpecificAttr* reference; + typedef SpecificAttr* pointer; + typedef std::forward_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + specific_attr_iterator() : Current() { } + explicit specific_attr_iterator(Iterator i) : Current(i) { } + + reference operator*() const { + AdvanceToNext(); + return cast<SpecificAttr>(*Current); + } + pointer operator->() const { + AdvanceToNext(); + return cast<SpecificAttr>(*Current); + } + + specific_attr_iterator& operator++() { + ++Current; + return *this; + } + specific_attr_iterator operator++(int) { + specific_attr_iterator Tmp(*this); + ++(*this); + return Tmp; + } + + friend bool operator==(specific_attr_iterator Left, + specific_attr_iterator Right) { + assert((Left.Current == 0) == (Right.Current == 0)); + if (Left.Current < Right.Current) + Left.AdvanceToNext(Right.Current); + else + Right.AdvanceToNext(Left.Current); + return Left.Current == Right.Current; + } + friend bool operator!=(specific_attr_iterator Left, + specific_attr_iterator Right) { + return !(Left == Right); + } +}; + +template <typename SpecificAttr, typename Container> +inline specific_attr_iterator<SpecificAttr, Container> + specific_attr_begin(const Container& container) { + return specific_attr_iterator<SpecificAttr, Container>(container.begin()); +} +template <typename SpecificAttr, typename Container> +inline specific_attr_iterator<SpecificAttr, Container> + specific_attr_end(const Container& container) { + return specific_attr_iterator<SpecificAttr, Container>(container.end()); +} + +template <typename SpecificAttr, typename Container> +inline bool hasSpecificAttr(const Container& container) { + return specific_attr_begin<SpecificAttr>(container) != + specific_attr_end<SpecificAttr>(container); +} +template <typename SpecificAttr, typename Container> +inline SpecificAttr *getSpecificAttr(const Container& container) { + specific_attr_iterator<SpecificAttr, Container> i = + specific_attr_begin<SpecificAttr>(container); + if (i != specific_attr_end<SpecificAttr>(container)) + return *i; + else + return 0; +} + +} // end namespace clang + +#endif diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index ba322fb..488cace 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -154,6 +154,20 @@ BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy) // type is a typedef of a PointerType to this. BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy) +// OpenCL image types. +BUILTIN_TYPE(OCLImage1d, OCLImage1dTy) +BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy) +BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy) +BUILTIN_TYPE(OCLImage2d, OCLImage2dTy) +BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy) +BUILTIN_TYPE(OCLImage3d, OCLImage3dTy) + +// OpenCL sampler_t. +BUILTIN_TYPE(OCLSampler, OCLSamplerTy) + +// OpenCL event_t. +BUILTIN_TYPE(OCLEvent, OCLEventTy) + // This represents the type of an expression whose type is // totally unknown, e.g. 'T::foo'. It is permitted for this to // appear in situations where the structure of the type is diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt index 4c4c0fb..ba54fa2 100644 --- a/include/clang/AST/CMakeLists.txt +++ b/include/clang/AST/CMakeLists.txt @@ -8,6 +8,11 @@ clang_tablegen(AttrImpl.inc -gen-clang-attr-impl SOURCE ../Basic/Attr.td TARGET ClangAttrImpl) +clang_tablegen(AttrDump.inc -gen-clang-attr-dump + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + SOURCE ../Basic/Attr.td + TARGET ClangAttrDump) + clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes SOURCE ../Basic/StmtNodes.td TARGET ClangStmtNodes) @@ -28,7 +33,15 @@ clang_tablegen(CommentHTMLTagsProperties.inc -gen-clang-comment-html-tags-proper SOURCE CommentHTMLTags.td TARGET ClangCommentHTMLTagsProperties) +clang_tablegen(CommentHTMLNamedCharacterReferences.inc -gen-clang-comment-html-named-character-references + SOURCE CommentHTMLNamedCharacterReferences.td + TARGET ClangCommentHTMLNamedCharacterReferences) + clang_tablegen(CommentCommandInfo.inc -gen-clang-comment-command-info SOURCE CommentCommands.td TARGET ClangCommentCommandInfo) +clang_tablegen(CommentCommandList.inc -gen-clang-comment-command-list + SOURCE CommentCommands.td + TARGET ClangCommentCommandList) + diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 87bdbe0..2983e04 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -14,17 +14,17 @@ #ifndef LLVM_CLANG_AST_CXXINHERITANCE_H #define LLVM_CLANG_AST_CXXINHERITANCE_H -#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" +#include <cassert> #include <list> #include <map> -#include <cassert> namespace clang { diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index ea307bf..9460757 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -351,15 +351,12 @@ namespace llvm { /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc. /// to return smart pointer (proxies?). template<typename T> -struct simplify_type<const ::clang::CanQual<T> > { +struct simplify_type< ::clang::CanQual<T> > { typedef const T *SimpleType; - static SimpleType getSimplifiedValue(const ::clang::CanQual<T> &Val) { + static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) { return Val.getTypePtr(); } }; -template<typename T> -struct simplify_type< ::clang::CanQual<T> > -: public simplify_type<const ::clang::CanQual<T> > {}; // Teach SmallPtrSet that CanQual<T> is "basically a pointer". template<typename T> @@ -514,55 +511,13 @@ struct CanProxyAdaptor<MemberPointerType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass) }; -template<> -struct CanProxyAdaptor<ArrayType> : public CanProxyBase<ArrayType> { - LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, - getSizeModifier) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) -}; - -template<> -struct CanProxyAdaptor<ConstantArrayType> - : public CanProxyBase<ConstantArrayType> { - LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, - getSizeModifier) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize) -}; - -template<> -struct CanProxyAdaptor<IncompleteArrayType> - : public CanProxyBase<IncompleteArrayType> { - LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, - getSizeModifier) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) -}; - -template<> -struct CanProxyAdaptor<VariableArrayType> - : public CanProxyBase<VariableArrayType> { - LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier, - getSizeModifier) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc) -}; - -template<> -struct CanProxyAdaptor<DependentSizedArrayType> - : public CanProxyBase<DependentSizedArrayType> { - LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc) -}; +// CanProxyAdaptors for arrays are intentionally unimplemented because +// they are not safe. +template<> struct CanProxyAdaptor<ArrayType>; +template<> struct CanProxyAdaptor<ConstantArrayType>; +template<> struct CanProxyAdaptor<IncompleteArrayType>; +template<> struct CanProxyAdaptor<VariableArrayType>; +template<> struct CanProxyAdaptor<DependentSizedArrayType>; template<> struct CanProxyAdaptor<DependentSizedExtVectorType> @@ -746,6 +701,9 @@ CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) { template<typename T> template<typename U> CanProxy<U> CanQual<T>::getAs() const { + ArrayType_cannot_be_used_with_getAs<U> at; + (void)at; + if (Stored.isNull()) return CanProxy<U>(); @@ -758,6 +716,9 @@ CanProxy<U> CanQual<T>::getAs() const { template<typename T> template<typename U> CanProxy<U> CanQual<T>::castAs() const { + ArrayType_cannot_be_used_with_getAs<U> at; + (void)at; + assert(!Stored.isNull() && isa<U>(Stored.getTypePtr())); return CanQual<U>::CreateUnsafe(Stored); } diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 12e74b3..082c672 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -171,6 +171,17 @@ namespace clang { Align.Quantity)); } + /// Given that this is a non-zero alignment value, what is the + /// alignment at the given offset? + CharUnits alignmentAtOffset(CharUnits offset) { + // alignment: 0010000 + // offset: 1011100 + // lowBits: 0001011 + // result: 0000100 + QuantityType lowBits = (Quantity-1) & (offset.Quantity-1); + return CharUnits((lowBits + 1) & ~lowBits); + } + }; // class CharUnit } // namespace clang diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h index 316a180..c02a82f 100644 --- a/include/clang/AST/Comment.h +++ b/include/clang/AST/Comment.h @@ -14,10 +14,10 @@ #ifndef LLVM_CLANG_AST_COMMENT_H #define LLVM_CLANG_AST_COMMENT_H -#include "clang/Basic/SourceLocation.h" -#include "clang/AST/Type.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -28,6 +28,26 @@ class TemplateParameterList; namespace comments { class FullComment; + +/// Describes the syntax that was used in a documentation command. +/// +/// Exact values of this enumeration are important because they used to select +/// parts of diagnostic messages. Audit diagnostics before changing or adding +/// a new value. +enum CommandMarkerKind { + /// Command started with a backslash character: + /// \code + /// \foo + /// \endcode + CMK_Backslash = 0, + + /// Command started with an 'at' character: + /// \code + /// @foo + /// \endcode + CMK_At = 1 +}; + /// Any part of the comment. /// Abstract class. class Comment { @@ -110,8 +130,12 @@ protected: unsigned : NumCommentBits; unsigned CommandID : 8; + + /// Describes the syntax that was used in a documentation command. + /// Contains values from CommandMarkerKind enum. + unsigned CommandMarker : 1; }; - enum { NumBlockCommandCommentBits = NumCommentBits + 8 }; + enum { NumBlockCommandCommentBits = NumCommentBits + 9 }; class ParamCommandCommentBitfields { friend class ParamCommandComment; @@ -171,8 +195,9 @@ public: const char *getCommentKindName() const; LLVM_ATTRIBUTE_USED void dump() const; + LLVM_ATTRIBUTE_USED void dumpColor() const; LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const; - void dump(llvm::raw_ostream &OS, const CommandTraits *Traits, + void dump(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM) const; SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -282,14 +307,14 @@ public: protected: /// Command arguments. - llvm::ArrayRef<Argument> Args; + ArrayRef<Argument> Args; public: InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, RenderKind RK, - llvm::ArrayRef<Argument> Args) : + ArrayRef<Argument> Args) : InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd), Args(Args) { InlineCommandCommentBits.RenderKind = RK; @@ -504,10 +529,10 @@ public: /// A single paragraph that contains inline content. class ParagraphComment : public BlockContentComment { - llvm::ArrayRef<InlineContentComment *> Content; + ArrayRef<InlineContentComment *> Content; public: - ParagraphComment(llvm::ArrayRef<InlineContentComment *> Content) : + ParagraphComment(ArrayRef<InlineContentComment *> Content) : BlockContentComment(ParagraphCommentKind, SourceLocation(), SourceLocation()), @@ -565,7 +590,7 @@ public: protected: /// Word-like arguments. - llvm::ArrayRef<Argument> Args; + ArrayRef<Argument> Args; /// Paragraph argument. ParagraphComment *Paragraph; @@ -573,21 +598,25 @@ protected: BlockCommandComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd, - unsigned CommandID) : + unsigned CommandID, + CommandMarkerKind CommandMarker) : BlockContentComment(K, LocBegin, LocEnd), Paragraph(NULL) { setLocation(getCommandNameBeginLoc()); BlockCommandCommentBits.CommandID = CommandID; + BlockCommandCommentBits.CommandMarker = CommandMarker; } public: BlockCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - unsigned CommandID) : + unsigned CommandID, + CommandMarkerKind CommandMarker) : BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd), Paragraph(NULL) { setLocation(getCommandNameBeginLoc()); BlockCommandCommentBits.CommandID = CommandID; + BlockCommandCommentBits.CommandMarker = CommandMarker; } static bool classof(const Comment *C) { @@ -633,7 +662,7 @@ public: return Args[Idx].Range; } - void setArgs(llvm::ArrayRef<Argument> A) { + void setArgs(ArrayRef<Argument> A) { Args = A; if (Args.size() > 0) { SourceLocation NewLocEnd = Args.back().Range.getEnd(); @@ -656,6 +685,11 @@ public: if (NewLocEnd.isValid()) setSourceRange(SourceRange(getLocStart(), NewLocEnd)); } + + CommandMarkerKind getCommandMarker() const LLVM_READONLY { + return static_cast<CommandMarkerKind>( + BlockCommandCommentBits.CommandMarker); + } }; /// Doxygen \\param command. @@ -669,9 +703,10 @@ public: ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - unsigned CommandID) : + unsigned CommandID, + CommandMarkerKind CommandMarker) : BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, - CommandID), + CommandID, CommandMarker), ParamIndex(InvalidParamIndex) { ParamCommandCommentBits.Direction = In; ParamCommandCommentBits.IsDirectionExplicit = false; @@ -746,13 +781,15 @@ private: /// For C: Position = { 0 } /// For TT: Position = { 1 } /// For T: Position = { 1, 0 } - llvm::ArrayRef<unsigned> Position; + ArrayRef<unsigned> Position; public: TParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - unsigned CommandID) : - BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID) + unsigned CommandID, + CommandMarkerKind CommandMarker) : + BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID, + CommandMarker) { } static bool classof(const Comment *C) { @@ -826,14 +863,15 @@ class VerbatimBlockComment : public BlockCommandComment { protected: StringRef CloseName; SourceLocation CloseNameLocBegin; - llvm::ArrayRef<VerbatimBlockLineComment *> Lines; + ArrayRef<VerbatimBlockLineComment *> Lines; public: VerbatimBlockComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID) : BlockCommandComment(VerbatimBlockCommentKind, - LocBegin, LocEnd, CommandID) + LocBegin, LocEnd, CommandID, + CMK_At) // FIXME: improve source fidelity. { } static bool classof(const Comment *C) { @@ -853,7 +891,7 @@ public: CloseNameLocBegin = LocBegin; } - void setLines(llvm::ArrayRef<VerbatimBlockLineComment *> L) { + void setLines(ArrayRef<VerbatimBlockLineComment *> L) { Lines = L; } @@ -886,7 +924,8 @@ public: StringRef Text) : BlockCommandComment(VerbatimLineCommentKind, LocBegin, LocEnd, - CommandID), + CommandID, + CMK_At), // FIXME: improve source fidelity. Text(Text), TextBegin(TextBegin) { } @@ -1021,11 +1060,11 @@ struct DeclInfo { /// A full comment attached to a declaration, contains block content. class FullComment : public Comment { - llvm::ArrayRef<BlockContentComment *> Blocks; + ArrayRef<BlockContentComment *> Blocks; DeclInfo *ThisDeclInfo; public: - FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) : + FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) : Comment(FullCommentKind, SourceLocation(), SourceLocation()), Blocks(Blocks), ThisDeclInfo(D) { if (Blocks.empty()) @@ -1062,7 +1101,7 @@ public: return ThisDeclInfo; } - llvm::ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; } + ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; } }; } // end namespace comments diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h index 6d44c70..d1f5209 100644 --- a/include/clang/AST/CommentCommandTraits.h +++ b/include/clang/AST/CommentCommandTraits.h @@ -16,9 +16,10 @@ #ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H #define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H +#include "clang/Basic/CommentOptions.h" #include "clang/Basic/LLVM.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/ErrorHandling.h" @@ -69,6 +70,9 @@ struct CommandInfo { /// True if this command is \\deprecated or an alias. unsigned IsDeprecatedCommand : 1; + /// \brief True if this is a \\headerfile-like command. + unsigned IsHeaderfileCommand : 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; @@ -96,7 +100,17 @@ struct CommandInfo { /// \fn void f(int a); /// \endcode unsigned IsDeclarationCommand : 1; - + + /// \brief True if verbatim-like line command is a function declaration. + unsigned IsFunctionDeclarationCommand : 1; + + /// \brief True if block command is further describing a container API; such + /// as \@coclass, \@classdesign, etc. + unsigned IsRecordLikeDetailCommand : 1; + + /// \brief True if block command is a container API; such as \@interface. + unsigned IsRecordLikeDeclarationCommand : 1; + /// \brief True if this command is unknown. This \c CommandInfo object was /// created during parsing. unsigned IsUnknownCommand : 1; @@ -106,7 +120,17 @@ struct CommandInfo { /// in comments. class CommandTraits { public: - CommandTraits(llvm::BumpPtrAllocator &Allocator); + enum KnownCommandIDs { +#define COMMENT_COMMAND(NAME) KCI_##NAME, +#include "clang/AST/CommentCommandList.inc" +#undef COMMENT_COMMAND + KCI_Last + }; + + CommandTraits(llvm::BumpPtrAllocator &Allocator, + const CommentOptions &CommentOptions); + + void registerCommentOptions(const CommentOptions &CommentOptions); /// \returns a CommandInfo object for a given command name or /// NULL if no CommandInfo object exists for this command. @@ -122,6 +146,8 @@ public: const CommandInfo *registerUnknownCommand(StringRef CommandName); + const CommandInfo *registerBlockCommand(StringRef CommandName); + /// \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); @@ -137,6 +163,8 @@ private: const CommandInfo *getRegisteredCommandInfo(StringRef Name) const; const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const; + CommandInfo *createCommandInfoWithName(StringRef CommandName); + unsigned NextID; /// Allocator for CommandInfo objects. diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td index 3d8bad8..9587ace 100644 --- a/include/clang/AST/CommentCommands.td +++ b/include/clang/AST/CommentCommands.td @@ -1,3 +1,7 @@ +//===----------------------------------------------------------------------===// +// Define command classes. +//===----------------------------------------------------------------------===// + class Command<string name> { string Name = name; string EndCommandName = ""; @@ -12,6 +16,7 @@ class Command<string name> { bit IsParamCommand = 0; bit IsTParamCommand = 0; bit IsDeprecatedCommand = 0; + bit IsHeaderfileCommand = 0; bit IsEmptyParagraphAllowed = 0; @@ -19,6 +24,9 @@ class Command<string name> { bit IsVerbatimBlockEndCommand = 0; bit IsVerbatimLineCommand = 0; bit IsDeclarationCommand = 0; + bit IsFunctionDeclarationCommand = 0; + bit IsRecordLikeDetailCommand = 0; + bit IsRecordLikeDeclarationCommand = 0; } class InlineCommand<string name> : Command<name> { @@ -29,6 +37,10 @@ class BlockCommand<string name> : Command<name> { let IsBlockCommand = 1; } +class RecordLikeDetailCommand<string name> : BlockCommand<name> { + let IsRecordLikeDetailCommand = 1; +} + class VerbatimBlockCommand<string name> : Command<name> { let EndCommandName = name; let IsVerbatimBlockCommand = 1; @@ -54,6 +66,22 @@ class DeclarationVerbatimLineCommand<string name> : let IsDeclarationCommand = 1; } +class FunctionDeclarationVerbatimLineCommand<string name> : + VerbatimLineCommand<name> { + let IsDeclarationCommand = 1; + let IsFunctionDeclarationCommand = 1; +} + +class RecordLikeDeclarationVerbatimLineCommand<string name> : + VerbatimLineCommand<name> { + let IsDeclarationCommand = 1; + let IsRecordLikeDeclarationCommand = 1; +} + +//===----------------------------------------------------------------------===// +// InlineCommand +//===----------------------------------------------------------------------===// + def B : InlineCommand<"b">; def C : InlineCommand<"c">; def P : InlineCommand<"p">; @@ -61,19 +89,26 @@ def A : InlineCommand<"a">; def E : InlineCommand<"e">; def Em : InlineCommand<"em">; +//===----------------------------------------------------------------------===// +// BlockCommand +//===----------------------------------------------------------------------===// + def Brief : BlockCommand<"brief"> { let IsBriefCommand = 1; } def Short : BlockCommand<"short"> { let IsBriefCommand = 1; } +// Opposite of \brief, it is the default in our implementation. +def Details : BlockCommand<"details">; + 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 +// Doxygen command for template parameter documentation. def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; } -// HeaderDoc +// HeaderDoc command for template parameter documentation. def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; } def Deprecated : BlockCommand<"deprecated"> { @@ -81,12 +116,17 @@ def Deprecated : BlockCommand<"deprecated"> { let IsDeprecatedCommand = 1; } +def Headerfile : BlockCommand<"headerfile"> { let IsHeaderfileCommand = 1; } + +// We don't do any additional semantic analysis for the following +// BlockCommands. It might be a good idea to do something extra for them, but +// for now we model them as plain BlockCommands. +def Attention : BlockCommand<"attention">; 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">; @@ -99,6 +139,22 @@ def Since : BlockCommand<"since">; def Todo : BlockCommand<"todo">; def Version : BlockCommand<"version">; def Warning : BlockCommand<"warning">; +// HeaderDoc commands +def ClassDesign : RecordLikeDetailCommand<"classdesign">; +def CoClass : RecordLikeDetailCommand<"coclass">; +def Dependency : RecordLikeDetailCommand<"dependency">; +def Helper : RecordLikeDetailCommand<"helper">; +def HelperClass : RecordLikeDetailCommand<"helperclass">; +def Helps : RecordLikeDetailCommand<"helps">; +def InstanceSize : RecordLikeDetailCommand<"instancesize">; +def Ownership : RecordLikeDetailCommand<"ownership">; +def Performance : RecordLikeDetailCommand<"performance">; +def Security : RecordLikeDetailCommand<"security">; +def SuperClass : RecordLikeDetailCommand<"superclass">; + +//===----------------------------------------------------------------------===// +// VerbatimBlockCommand +//===----------------------------------------------------------------------===// defm Code : VerbatimBlockCommand<"code", "endcode">; defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">; @@ -111,11 +167,16 @@ defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">; defm Dot : VerbatimBlockCommand<"dot", "enddot">; defm Msc : VerbatimBlockCommand<"msc", "endmsc">; -// These commands have special support in lexer. +// These three commands have special support in CommentLexer to recognize their +// names. def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment +//===----------------------------------------------------------------------===// +// VerbatimLineCommand +//===----------------------------------------------------------------------===// + def Defgroup : VerbatimLineCommand<"defgroup">; def Ingroup : VerbatimLineCommand<"ingroup">; def Addtogroup : VerbatimLineCommand<"addtogroup">; @@ -131,6 +192,10 @@ def Mainpage : VerbatimLineCommand<"mainpage">; def Subpage : VerbatimLineCommand<"subpage">; def Ref : VerbatimLineCommand<"ref">; +//===----------------------------------------------------------------------===// +// DeclarationVerbatimLineCommand +//===----------------------------------------------------------------------===// + // Doxygen commands. def Fn : DeclarationVerbatimLineCommand<"fn">; def Namespace : DeclarationVerbatimLineCommand<"namespace">; @@ -140,17 +205,18 @@ def Typedef : DeclarationVerbatimLineCommand<"typedef">; def Var : DeclarationVerbatimLineCommand<"var">; // HeaderDoc commands. -def Class : DeclarationVerbatimLineCommand<"class">; -def Interface : DeclarationVerbatimLineCommand<"interface">; -def Protocol : DeclarationVerbatimLineCommand<"protocol">; +def Class : RecordLikeDeclarationVerbatimLineCommand<"class">; +def Interface : RecordLikeDeclarationVerbatimLineCommand<"interface">; +def Protocol : RecordLikeDeclarationVerbatimLineCommand<"protocol">; +def Struct : RecordLikeDeclarationVerbatimLineCommand<"struct">; +def Union : RecordLikeDeclarationVerbatimLineCommand<"union">; def Category : DeclarationVerbatimLineCommand<"category">; def Template : DeclarationVerbatimLineCommand<"template">; -def Function : DeclarationVerbatimLineCommand<"function">; -def Method : DeclarationVerbatimLineCommand<"method">; -def Callback : DeclarationVerbatimLineCommand<"callback">; +def Function : FunctionDeclarationVerbatimLineCommand<"function">; +def FunctionGroup : FunctionDeclarationVerbatimLineCommand<"functiongroup">; +def Method : FunctionDeclarationVerbatimLineCommand<"method">; +def MethodGroup : FunctionDeclarationVerbatimLineCommand<"methodgroup">; +def Callback : FunctionDeclarationVerbatimLineCommand<"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/CommentHTMLNamedCharacterReferences.td b/include/clang/AST/CommentHTMLNamedCharacterReferences.td new file mode 100644 index 0000000..4493108 --- /dev/null +++ b/include/clang/AST/CommentHTMLNamedCharacterReferences.td @@ -0,0 +1,177 @@ +// HTML Named Character Reference +class NCR<string spelling, int codePoint> { + string Spelling = spelling; + int CodePoint = codePoint; +} + +// The list below includes named character references supported by Doxygen: +// http://www.stack.nl/~dimitri/doxygen/manual/htmlcmds.html +// +// It does not include all HTML 5 named character references. +// +// Corresponding code point values can be found here: +// http://www.w3.org/TR/2011/WD-html5-20110113/named-character-references.html + +def : NCR<"copy", 0x000A9>; +def : NCR<"COPY", 0x000A9>; +def : NCR<"trade", 0x02122>; +def : NCR<"TRADE", 0x02122>; +def : NCR<"reg", 0x000AE>; +def : NCR<"REG", 0x000AE>; +def : NCR<"lt", 0x0003C>; +def : NCR<"Lt", 0x0003C>; +def : NCR<"LT", 0x0003C>; +def : NCR<"gt", 0x0003E>; +def : NCR<"Gt", 0x0003E>; +def : NCR<"GT", 0x0003E>; +def : NCR<"amp", 0x00026>; +def : NCR<"AMP", 0x00026>; +def : NCR<"apos", 0x00027>; +def : NCR<"quot", 0x00022>; +def : NCR<"QUOT", 0x00022>; +def : NCR<"lsquo", 0x02018>; +def : NCR<"rsquo", 0x02019>; +def : NCR<"ldquo", 0x0201C>; +def : NCR<"rdquo", 0x0201D>; +def : NCR<"ndash", 0x02013>; +def : NCR<"mdash", 0x02014>; + +def : NCR<"Auml", 0x000C4>; +def : NCR<"Euml", 0x000CB>; +def : NCR<"Iuml", 0x000CF>; +def : NCR<"Ouml", 0x000D6>; +def : NCR<"Uuml", 0x000DC>; +def : NCR<"Yuml", 0x00178>; +def : NCR<"auml", 0x000E4>; +def : NCR<"euml", 0x000EB>; +def : NCR<"iuml", 0x000EF>; +def : NCR<"ouml", 0x000F6>; +def : NCR<"uuml", 0x000FC>; +def : NCR<"yuml", 0x000FF>; + +def : NCR<"Aacute", 0x000C1>; +def : NCR<"Eacute", 0x000C9>; +def : NCR<"Iacute", 0x000CD>; +def : NCR<"Oacute", 0x000D3>; +def : NCR<"Uacute", 0x000DA>; +def : NCR<"Yacute", 0x000DD>; +def : NCR<"aacute", 0x000E1>; +def : NCR<"eacute", 0x000E9>; +def : NCR<"iacute", 0x000ED>; +def : NCR<"oacute", 0x000F3>; +def : NCR<"uacute", 0x000FA>; +def : NCR<"yacute", 0x000FD>; + +def : NCR<"Agrave", 0x000C0>; +def : NCR<"Egrave", 0x000C8>; +def : NCR<"Igrave", 0x000CC>; +def : NCR<"Ograve", 0x000D2>; +def : NCR<"Ugrave", 0x000D9>; +// def : NCR<"Ygrave", 0x01EF2>; // Defined neither in Doxygen, nor in HTML5. +def : NCR<"agrave", 0x000E0>; +def : NCR<"egrave", 0x000E8>; +def : NCR<"igrave", 0x000EC>; +def : NCR<"ograve", 0x000F2>; +def : NCR<"ugrave", 0x000F9>; +def : NCR<"ygrave", 0x01EF3>; // Defined in Doxygen, not defined in HTML5. + +def : NCR<"Acirc", 0x000C2>; +def : NCR<"Ecirc", 0x000CA>; +def : NCR<"Icirc", 0x000CE>; +def : NCR<"Ocirc", 0x000D4>; +def : NCR<"Ucirc", 0x000DB>; +def : NCR<"Ycirc", 0x00176>; // Not defined in Doxygen, defined in HTML5. +def : NCR<"acirc", 0x000E2>; +def : NCR<"ecirc", 0x000EA>; +def : NCR<"icirc", 0x000EE>; +def : NCR<"ocirc", 0x000F4>; +def : NCR<"ucirc", 0x000FB>; +def : NCR<"ycirc", 0x00177>; + +def : NCR<"Atilde", 0x000C3>; +def : NCR<"Ntilde", 0x000D1>; +def : NCR<"Otilde", 0x000D5>; +def : NCR<"atilde", 0x000E3>; +def : NCR<"ntilde", 0x000F1>; +def : NCR<"otilde", 0x000F5>; + +def : NCR<"szlig", 0x000DF>; + +def : NCR<"ccedil", 0x000E7>; +def : NCR<"Ccedil", 0x000C7>; + +def : NCR<"aring", 0x000E5>; +def : NCR<"Aring", 0x000C5>; + +def : NCR<"nbsp", 0x000A0>; + +def : NCR<"Gamma", 0x00393>; +def : NCR<"Delta", 0x00394>; +def : NCR<"Theta", 0x00398>; +def : NCR<"Lambda", 0x0039B>; +def : NCR<"Xi", 0x0039E>; +def : NCR<"Pi", 0x003A0>; +def : NCR<"Sigma", 0x003A3>; +def : NCR<"Upsilon", 0x003A5>; +def : NCR<"Phi", 0x003A6>; +def : NCR<"Psi", 0x003A8>; +def : NCR<"Omega", 0x003A9>; + +def : NCR<"alpha", 0x003B1>; +def : NCR<"beta", 0x003B2>; +def : NCR<"gamma", 0x003B3>; +def : NCR<"delta", 0x003B4>; +def : NCR<"epsilon", 0x003B5>; +def : NCR<"zeta", 0x003B6>; +def : NCR<"eta", 0x003B7>; +def : NCR<"theta", 0x003B8>; +def : NCR<"iota", 0x003B9>; +def : NCR<"kappa", 0x003BA>; +def : NCR<"lambda", 0x003BB>; +def : NCR<"mu", 0x003BC>; +def : NCR<"nu", 0x003BD>; +def : NCR<"xi", 0x003BE>; +def : NCR<"pi", 0x003C0>; +def : NCR<"rho", 0x003C1>; +def : NCR<"sigma", 0x003C3>; +def : NCR<"tau", 0x003C4>; +def : NCR<"upsilon", 0x003C5>; +def : NCR<"phi", 0x003C6>; +def : NCR<"chi", 0x003C7>; +def : NCR<"psi", 0x003C8>; +def : NCR<"omega", 0x003C9>; +def : NCR<"sigmaf", 0x003C2>; + +def : NCR<"sect", 0x000A7>; +def : NCR<"deg", 0x000B0>; +def : NCR<"prime", 0x02032>; +def : NCR<"Prime", 0x02033>; +def : NCR<"infin", 0x0221E>; +def : NCR<"empty", 0x02205>; +def : NCR<"plusmn", 0x000B1>; +def : NCR<"times", 0x000D7>; +def : NCR<"minus", 0x02212>; +def : NCR<"sdot", 0x022C5>; +def : NCR<"part", 0x02202>; +def : NCR<"nabla", 0x02207>; +def : NCR<"radic", 0x0221A>; +def : NCR<"perp", 0x022A5>; +def : NCR<"sum", 0x02211>; +def : NCR<"int", 0x0222B>; +def : NCR<"prod", 0x0220F>; +def : NCR<"sim", 0x0223C>; +def : NCR<"asymp", 0x02248>; +def : NCR<"ne", 0x02260>; +def : NCR<"equiv", 0x02261>; +def : NCR<"prop", 0x0221D>; +def : NCR<"le", 0x02264>; +def : NCR<"ge", 0x02265>; +def : NCR<"larr", 0x02190>; +def : NCR<"rarr", 0x02192>; +def : NCR<"isin", 0x02208>; +def : NCR<"notin", 0x02209>; +def : NCR<"lceil", 0x02308>; +def : NCR<"rceil", 0x02309>; +def : NCR<"lfloor", 0x0230A>; +def : NCR<"rfloor", 0x0230B>; + diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h index f263697..4179f45 100644 --- a/include/clang/AST/CommentLexer.h +++ b/include/clang/AST/CommentLexer.h @@ -15,9 +15,9 @@ #define LLVM_CLANG_AST_COMMENT_LEXER_H #include "clang/Basic/SourceManager.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/raw_ostream.h" @@ -34,8 +34,9 @@ enum TokenKind { eof, newline, text, - unknown_command, // Command that does not have an ID. - command, // Command with an ID. + unknown_command, // Command that does not have an ID. + backslash_command, // Command with an ID, that used backslash marker. + at_command, // Command with an ID, that used 'at' marker. verbatim_block_begin, verbatim_block_line, verbatim_block_end, @@ -75,7 +76,7 @@ class Token { /// 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; } void setLocation(SourceLocation SL) { Loc = SL; } @@ -118,12 +119,12 @@ public: } unsigned getCommandID() const LLVM_READONLY { - assert(is(tok::command)); + assert(is(tok::backslash_command) || is(tok::at_command)); return IntVal; } void setCommandID(unsigned ID) { - assert(is(tok::command)); + assert(is(tok::backslash_command) || is(tok::at_command)); IntVal = ID; } diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h index 19e1d57..d6a1072 100644 --- a/include/clang/AST/CommentParser.h +++ b/include/clang/AST/CommentParser.h @@ -14,10 +14,10 @@ #ifndef LLVM_CLANG_AST_COMMENT_PARSER_H #define LLVM_CLANG_AST_COMMENT_PARSER_H -#include "clang/Basic/Diagnostic.h" -#include "clang/AST/CommentLexer.h" #include "clang/AST/Comment.h" +#include "clang/AST/CommentLexer.h" #include "clang/AST/CommentSema.h" +#include "clang/Basic/Diagnostic.h" #include "llvm/Support/Allocator.h" namespace clang { @@ -86,6 +86,11 @@ class Parser { Tok = Toks[0]; } + bool isTokBlockCommand() { + return (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) && + Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand; + } + public: Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, DiagnosticsEngine &Diags, diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index 0340b3c..15e454d 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -14,12 +14,12 @@ #ifndef LLVM_CLANG_AST_COMMENT_SEMA_H #define LLVM_CLANG_AST_COMMENT_SEMA_H +#include "clang/AST/Comment.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" -#include "clang/AST/Comment.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" namespace clang { @@ -60,6 +60,9 @@ class Sema { /// AST node for the \\returns command and its aliases. const BlockCommandComment *ReturnsCommand; + + /// AST node for the \\headerfile command. + const BlockCommandComment *HeaderfileCommand; DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { return Diags.Report(Loc, DiagID); @@ -93,7 +96,8 @@ public: BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - unsigned CommandID); + unsigned CommandID, + CommandMarkerKind CommandMarker); void actOnBlockCommandArgs(BlockCommandComment *Command, ArrayRef<BlockCommandComment::Argument> Args); @@ -103,7 +107,8 @@ public: ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - unsigned CommandID); + unsigned CommandID, + CommandMarkerKind CommandMarker); void actOnParamCommandDirectionArg(ParamCommandComment *Command, SourceLocation ArgLocBegin, @@ -120,7 +125,8 @@ public: TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - unsigned CommandID); + unsigned CommandID, + CommandMarkerKind CommandMarker); void actOnTParamCommandParamNameArg(TParamCommandComment *Command, SourceLocation ArgLocBegin, @@ -192,13 +198,28 @@ public: void checkBlockCommandDuplicate(const BlockCommandComment *Command); void checkDeprecatedCommand(const BlockCommandComment *Comment); + + void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment); + + void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment); + + void checkContainerDecl(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 isAnyFunctionDecl(); + bool isFunctionPointerVarDecl(); + bool isObjCMethodDecl(); + bool isObjCPropertyDecl(); bool isTemplateOrSpecialization(); + bool isRecordLikeDecl(); + bool isClassOrStructDecl(); + bool isUnionDecl(); + bool isObjCInterfaceDecl(); + bool isObjCProtocolDecl(); ArrayRef<const ParmVarDecl *> getParamVars(); diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h index 47867a6..21641bf 100644 --- a/include/clang/AST/CommentVisitor.h +++ b/include/clang/AST/CommentVisitor.h @@ -7,6 +7,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_COMMENTVISITOR_H +#define LLVM_CLANG_AST_COMMENTVISITOR_H + #include "clang/AST/Comment.h" #include "llvm/Support/ErrorHandling.h" @@ -64,3 +67,4 @@ class ConstCommentVisitor : } // end namespace comments } // end namespace clang +#endif diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 087a585..7927279 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -16,33 +16,34 @@ #include "clang/AST/APValue.h" #include "clang/AST/DeclBase.h" -#include "clang/AST/Redeclarable.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/Redeclarable.h" +#include "clang/AST/Type.h" #include "clang/Basic/Linkage.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" namespace clang { +struct ASTTemplateArgumentListInfo; class CXXTemporary; +class CompoundStmt; +class DependentFunctionTemplateSpecializationInfo; class Expr; class FunctionTemplateDecl; +class FunctionTemplateSpecializationInfo; +class LabelStmt; +class MemberSpecializationInfo; +class Module; +class NestedNameSpecifier; class Stmt; -class CompoundStmt; class StringLiteral; -class NestedNameSpecifier; -class TemplateParameterList; class TemplateArgumentList; -struct ASTTemplateArgumentListInfo; -class MemberSpecializationInfo; -class FunctionTemplateSpecializationInfo; -class DependentFunctionTemplateSpecializationInfo; +class TemplateParameterList; class TypeLoc; class UnresolvedSetImpl; -class LabelStmt; -class Module; - + /// \brief A container of type source information. /// /// A client can read the relevant info using TypeLoc wrappers, e.g: @@ -108,6 +109,7 @@ class NamedDecl : public Decl { private: NamedDecl *getUnderlyingDeclImpl(); + void verifyLinkage() const; protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) @@ -149,32 +151,29 @@ public: /// \brief Set the name of this declaration. void setDeclName(DeclarationName N) { Name = N; } - /// getQualifiedNameAsString - Returns human-readable qualified name for + /// printQualifiedName - Returns human-readable qualified name for /// declaration, like A::B::i, for i being member of namespace A::B. /// If declaration is not member of context which can be named (record, - /// namespace), it will return same result as getNameAsString(). + /// namespace), it will return same result as printName(). /// Creating this name is expensive, so it should be called only when /// performance doesn't matter. + void printQualifiedName(raw_ostream &OS) const; + void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const; + + // FIXME: Remove string versions. std::string getQualifiedNameAsString() const; std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const; /// getNameForDiagnostic - Appends a human-readable name for this - /// declaration into the given string. + /// declaration into the given stream. /// /// This is the method invoked by Sema when displaying a NamedDecl /// in a diagnostic. It does not necessarily produce the same - /// result as getNameAsString(); for example, class template + /// result as printName(); for example, class template /// specializations are printed with their template arguments. - /// - /// TODO: use an API that doesn't require so many temporary strings - virtual void getNameForDiagnostic(std::string &S, + virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, - bool Qualified) const { - if (Qualified) - S += getQualifiedNameAsString(Policy); - else - S += getNameAsString(); - } + bool Qualified) const; /// declarationReplaces - Determine whether this declaration, if /// known to be well-formed within its context, will replace the @@ -212,117 +211,40 @@ public: /// a C++ class. bool isCXXInstanceMember() const; - class LinkageInfo { - 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) { - assert(linkage() == L && visibility() == V && visibilityExplicit() == E && - "Enum truncated!"); - } - - static LinkageInfo external() { - return LinkageInfo(); - } - static LinkageInfo internal() { - return LinkageInfo(InternalLinkage, DefaultVisibility, false); - } - static LinkageInfo uniqueExternal() { - return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false); - } - static LinkageInfo none() { - return LinkageInfo(NoLinkage, DefaultVisibility, false); - } - - Linkage linkage() const { return (Linkage)linkage_; } - Visibility visibility() const { return (Visibility)visibility_; } - bool visibilityExplicit() const { return explicit_; } - - void setLinkage(Linkage L) { linkage_ = L; } - void mergeLinkage(Linkage L) { - setLinkage(minLinkage(linkage(), L)); - } - void mergeLinkage(LinkageInfo Other) { - mergeLinkage(Other.linkage()); - } - - // Merge the visibility V giving preference to explicit ones. - // This is used, for example, when merging the visibility of a class - // down to one of its members. If the member has no explicit visibility, - // the class visibility wins. - void mergeVisibility(Visibility V, bool E = false) { - // Never increase the visibility - if (visibility() < V) - return; - - // If we have an explicit visibility, keep it - if (visibilityExplicit()) - return; - - setVisibility(V, E); - } - // Merge the visibility V, keeping the most restrictive one. - // This is used for cases like merging the visibility of a template - // argument to an instantiation. If we already have a hidden class, - // no argument should give it default visibility. - void mergeVisibilityWithMin(Visibility V, bool E = false) { - // Never increase the visibility - if (visibility() < V) - return; - - // FIXME: this - // If this visibility is explicit, keep it. - if (visibilityExplicit() && !E) - return; - - // should be replaced with this - // Don't lose the explicit bit for nothing - // if (visibility() == V && visibilityExplicit()) - // return; - - setVisibility(V, E); - } - void mergeVisibility(LinkageInfo Other) { - mergeVisibility(Other.visibility(), Other.visibilityExplicit()); - } - void mergeVisibilityWithMin(LinkageInfo Other) { - mergeVisibilityWithMin(Other.visibility(), Other.visibilityExplicit()); - } - - void merge(LinkageInfo Other) { - mergeLinkage(Other); - mergeVisibility(Other); - } - void mergeWithMin(LinkageInfo Other) { - mergeLinkage(Other); - mergeVisibilityWithMin(Other); - } - }; - /// \brief Determine what kind of linkage this entity has. Linkage getLinkage() const; + /// \brief True if this decl has external linkage. + bool hasExternalLinkage() const { + return getLinkage() == ExternalLinkage; + } + + /// \brief True if this decl has external linkage. Don't cache the linkage, + /// because we are not finished setting up the redecl chain for the decl. + bool hasExternalLinkageUncached() const; + /// \brief Determines the visibility of this entity. Visibility getVisibility() const { - return getLinkageAndVisibility().visibility(); + return getLinkageAndVisibility().getVisibility(); } /// \brief Determines the linkage and visibility of this entity. LinkageInfo getLinkageAndVisibility() const; + /// Kinds of explicit visibility. + enum ExplicitVisibilityKind { + VisibilityForType, + VisibilityForValue + }; + /// \brief If visibility was explicitly specified for this /// declaration, return that visibility. - llvm::Optional<Visibility> getExplicitVisibility() const; + Optional<Visibility> + getExplicitVisibility(ExplicitVisibilityKind kind) const; - /// \brief Clear the linkage cache in response to a change - /// to the declaration. - void ClearLinkageCache(); + /// \brief True if the computed linkage is valid. Used for consistency + /// checking. Should always return true. + bool isLinkageValid() const; /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for /// the underlying named decl. @@ -538,9 +460,7 @@ public: /// \brief Determine whether this symbol is weakly-imported, /// or declared with the weak or weak-ref attr. - bool isWeak() const { - return hasAttr<WeakAttr>() || hasAttr<WeakRefAttr>() || isWeakImported(); - } + bool isWeak() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -744,7 +664,6 @@ private: friend class ASTDeclReader; unsigned SClass : 3; - unsigned SClassAsWritten : 3; unsigned ThreadSpecified : 1; unsigned InitStyle : 2; @@ -811,14 +730,12 @@ protected: VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, StorageClass SC, - StorageClass SCAsWritten) + QualType T, TypeSourceInfo *TInfo, StorageClass SC) : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() { assert(sizeof(VarDeclBitfields) <= sizeof(unsigned)); assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned)); AllBits = 0; VarDeclBits.SClass = SC; - VarDeclBits.SClassAsWritten = SCAsWritten; // Everything else is implicitly initialized to false. } @@ -841,23 +758,18 @@ public: static VarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten); + StorageClass S); static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID); virtual SourceRange getSourceRange() const LLVM_READONLY; + /// \brief Returns the storage class as written in the source. For the + /// computed linkage of symbol, see getLinkage. StorageClass getStorageClass() const { return (StorageClass) VarDeclBits.SClass; } - StorageClass getStorageClassAsWritten() const { - return (StorageClass) VarDeclBits.SClassAsWritten; - } void setStorageClass(StorageClass SC); - void setStorageClassAsWritten(StorageClass SC) { - assert(isLegalForVariable(SC)); - VarDeclBits.SClassAsWritten = SC; - } void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; } bool isThreadSpecified() const { @@ -882,8 +794,8 @@ public: return getStorageClass() == SC_Static && !isFileVarDecl(); } - /// hasExternStorage - Returns true if a variable has extern or - /// __private_extern__ storage. + /// \brief Returns true if a variable has extern or __private_extern__ + /// storage. bool hasExternalStorage() const { return getStorageClass() == SC_Extern || getStorageClass() == SC_PrivateExtern; @@ -894,6 +806,9 @@ public: /// as static variables declared within a function. bool hasGlobalStorage() const { return !hasLocalStorage(); } + /// Compute the language linkage. + LanguageLinkage getLanguageLinkage() const; + /// \brief Determines whether this variable is a variable with /// external, C linkage. bool isExternC() const; @@ -1087,8 +1002,7 @@ public: /// not a constant expression. Returns a pointer to the value if evaluation /// succeeded, 0 otherwise. APValue *evaluateValue() const; - APValue *evaluateValue( - llvm::SmallVectorImpl<PartialDiagnosticAt> &Notes) const; + APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const; /// \brief Return the already-evaluated value of this variable's /// initializer, or NULL if the value is not yet known. Returns pointer @@ -1220,7 +1134,7 @@ public: ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType Type) : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type, - /*tinfo*/ 0, SC_None, SC_None) { + /*tinfo*/ 0, SC_None) { setImplicit(); } @@ -1239,8 +1153,8 @@ protected: ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten, Expr *DefArg) - : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S, SCAsWritten) { + StorageClass S, Expr *DefArg) + : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) { assert(ParmVarDeclBits.HasInheritedDefaultArg == false); assert(ParmVarDeclBits.IsKNRPromoted == false); assert(ParmVarDeclBits.IsObjCMethodParam == false); @@ -1252,8 +1166,7 @@ public: SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten, - Expr *DefArg); + StorageClass S, Expr *DefArg); static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1451,14 +1364,13 @@ private: /// DeclsInPrototypeScope - Array of pointers to NamedDecls for /// decls defined in the function prototype that are not parameters. E.g. /// 'enum Y' in 'void f(enum Y {AA} x) {}'. - llvm::ArrayRef<NamedDecl*> DeclsInPrototypeScope; + ArrayRef<NamedDecl *> DeclsInPrototypeScope; LazyDeclStmtPtr Body; // FIXME: This can be packed into the bitfields in Decl. // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum unsigned SClass : 2; - unsigned SClassAsWritten : 2; bool IsInline : 1; bool IsInlineSpecified : 1; bool IsVirtualAsWritten : 1; @@ -1473,6 +1385,10 @@ private: bool IsLateTemplateParsed : 1; bool IsConstexpr : 1; + /// \brief Indicates if the function was a definition but its body was + /// skipped. + unsigned HasSkippedBody : 1; + /// \brief End part of this FunctionDecl's source range. /// /// We could compute the full range in getSourceRange(). However, when we're @@ -1538,25 +1454,26 @@ private: void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD, TemplateSpecializationKind TSK); - void setParams(ASTContext &C, llvm::ArrayRef<ParmVarDecl *> NewParamInfo); + void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo); protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified, + StorageClass S, bool isInlineSpecified, bool isConstexprSpecified) : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, StartLoc), DeclContext(DK), ParamInfo(0), Body(), - SClass(S), SClassAsWritten(SCAsWritten), + SClass(S), IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), IsDefaulted(false), IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), - IsConstexpr(isConstexprSpecified), EndRangeLoc(NameInfo.getEndLoc()), + IsConstexpr(isConstexprSpecified), HasSkippedBody(false), + EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), DNLoc(NameInfo.getInfo()) {} @@ -1580,14 +1497,13 @@ public: SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, - StorageClass SC = SC_None, - StorageClass SCAsWritten = SC_None, + StorageClass SC, bool isInlineSpecified = false, bool hasWrittenPrototype = true, bool isConstexprSpecified = false) { DeclarationNameInfo NameInfo(N, NLoc); return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, - SC, SCAsWritten, + SC, isInlineSpecified, hasWrittenPrototype, isConstexprSpecified); } @@ -1596,10 +1512,9 @@ public: SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass SC = SC_None, - StorageClass SCAsWritten = SC_None, - bool isInlineSpecified = false, - bool hasWrittenPrototype = true, + StorageClass SC, + bool isInlineSpecified, + bool hasWrittenPrototype, bool isConstexprSpecified = false); static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1608,7 +1523,7 @@ public: return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } - virtual void getNameForDiagnostic(std::string &S, + virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const; @@ -1732,7 +1647,7 @@ public: /// Whether this is a (C++11) constexpr function or constexpr constructor. bool isConstexpr() const { return IsConstexpr; } - void setConstexpr(bool IC); + void setConstexpr(bool IC) { IsConstexpr = IC; } /// \brief Whether this function has been deleted. /// @@ -1776,6 +1691,9 @@ public: /// This function must be an allocation or deallocation function. bool isReservedGlobalPlacementOperator() const; + /// Compute the language linkage. + LanguageLinkage getLanguageLinkage() const; + /// \brief Determines whether this function is a function with /// external, C linkage. bool isExternC() const; @@ -1783,6 +1701,14 @@ public: /// \brief Determines whether this is a global function. bool isGlobal() const; + /// \brief Determines whether this function is known to be 'noreturn', through + /// an attribute on its declaration or its type. + bool isNoReturn() const; + + /// \brief True if the function was a definition but its body was skipped. + bool hasSkippedBody() const { return HasSkippedBody; } + void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + void setPreviousDeclaration(FunctionDecl * PrevDecl); virtual const FunctionDecl *getCanonicalDecl() const; @@ -1814,14 +1740,14 @@ public: assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } - void setParams(llvm::ArrayRef<ParmVarDecl *> NewParamInfo) { + void setParams(ArrayRef<ParmVarDecl *> NewParamInfo) { setParams(getASTContext(), NewParamInfo); } - const llvm::ArrayRef<NamedDecl*> &getDeclsInPrototypeScope() const { + const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const { return DeclsInPrototypeScope; } - void setDeclsInPrototypeScope(llvm::ArrayRef<NamedDecl *> NewDecls); + void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls); /// getMinRequiredArguments - Returns the minimum number of arguments /// needed to call this function. This may be fewer than the number of @@ -1838,12 +1764,9 @@ public: return getType()->getAs<FunctionType>()->getCallResultType(getASTContext()); } + /// \brief Returns the storage class as written in the source. For the + /// computed linkage of symbol, see getLinkage. StorageClass getStorageClass() const { return StorageClass(SClass); } - void setStorageClass(StorageClass SC); - - StorageClass getStorageClassAsWritten() const { - return StorageClass(SClassAsWritten); - } /// \brief Determine whether the "inline" keyword was specified for this /// function. @@ -1863,7 +1786,7 @@ public: /// \brief Determine whether this function should be inlined, because it is /// either marked "inline" or "constexpr" or is a member function of a class /// that was defined in the class body. - bool isInlined() const; + bool isInlined() const { return IsInline; } bool isInlineDefinitionExternallyVisible() const; @@ -1908,7 +1831,9 @@ public: /// \brief If this function is an instantiation of a member function of a /// class template specialization, retrieves the member specialization /// information. - MemberSpecializationInfo *getMemberSpecializationInfo() const; + MemberSpecializationInfo *getMemberSpecializationInfo() const { + return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); + } /// \brief Specify that this record is an instantiation of the /// member function FD. @@ -2472,6 +2397,12 @@ protected: /// possible in C++11 or Microsoft extensions mode. bool IsFixed : 1; + /// \brief Indicates whether it is possible for declarations of this kind + /// to have an out-of-date definition. + /// + /// This option is only enabled when modules are enabled. + bool MayHaveOutOfDateDef : 1; + private: SourceLocation RBraceLoc; @@ -2616,6 +2547,25 @@ public: bool isUnion() const { return getTagKind() == TTK_Union; } bool isEnum() const { return getTagKind() == TTK_Enum; } + /// Is this tag type named, either directly or via being defined in + /// a typedef of this type? + /// + /// C++11 [basic.link]p8: + /// A type is said to have linkage if and only if: + /// - it is a class or enumeration type that is named (or has a + /// name for linkage purposes) and the name has linkage; ... + /// C++11 [dcl.typedef]p9: + /// If the typedef declaration defines an unnamed class (or enum), + /// the first typedef-name declared by the declaration to be that + /// class type (or enum type) is used to denote the class type (or + /// enum type) for linkage purposes only. + /// + /// C does not have an analogous rule, but the same concept is + /// nonetheless useful in some places. + bool hasNameForLinkage() const { + return (getDeclName() || getTypedefNameForAnonDecl()); + } + TypedefNameDecl *getTypedefNameForAnonDecl() const { return hasExtInfo() ? 0 : TypedefNameDeclOrQualifier.get<TypedefNameDecl*>(); @@ -2906,6 +2856,10 @@ class RecordDecl : public TagDecl { /// HasObjectMember - This is true if this struct has at least one member /// containing an Objective-C object pointer type. bool HasObjectMember : 1; + + /// HasVolatileMember - This is true if struct has at least one member of + /// 'volatile' type. + bool HasVolatileMember : 1; /// \brief Whether the field declarations of this record have been loaded /// from external storage. To avoid unnecessary deserialization of @@ -2962,6 +2916,9 @@ public: bool hasObjectMember() const { return HasObjectMember; } void setHasObjectMember (bool val) { HasObjectMember = val; } + bool hasVolatileMember() const { return HasVolatileMember; } + void setHasVolatileMember (bool val) { HasVolatileMember = val; } + /// \brief Determines whether this declaration represents the /// injected class name. /// @@ -3161,7 +3118,7 @@ public: assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } - void setParams(llvm::ArrayRef<ParmVarDecl *> NewParamInfo); + void setParams(ArrayRef<ParmVarDecl *> NewParamInfo); /// hasCaptures - True if this block (or its nested blocks) captures /// anything of local storage from its enclosing scopes. @@ -3210,7 +3167,7 @@ public: /// /// An import declaration imports the named module (or submodule). For example: /// \code -/// @__experimental_modules_import std.vector; +/// @import std.vector; /// \endcode /// /// Import declarations can also be implicitly generated from @@ -3271,7 +3228,21 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Import; } }; - + +/// \brief Represents an empty-declaration. +class EmptyDecl : public Decl { + virtual void anchor(); + EmptyDecl(DeclContext *DC, SourceLocation L) + : Decl(Empty, DC, L) { } + +public: + static EmptyDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L); + static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Empty; } +}; /// Insertion operator for diagnostics. This allows sending NamedDecl's /// into a diagnostic with <<. @@ -3299,10 +3270,10 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) { // Point to previous. Make sure that this is actually the most recent // redeclaration, or we can build invalid chains. If the most recent // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. - RedeclLink = PreviousDeclLink( - llvm::cast<decl_type>(PrevDecl->getMostRecentDecl())); First = PrevDecl->getFirstDeclaration(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); + decl_type *MostRecent = First->RedeclLink.getNext(); + RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent)); } else { // Make this first. First = static_cast<decl_type*>(this); @@ -3310,8 +3281,8 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) { // First one will point to this one as latest. First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this)); - if (NamedDecl *ND = dyn_cast<NamedDecl>(static_cast<decl_type*>(this))) - ND->ClearLinkageCache(); + assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) || + cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid()); } // Inline function definitions. diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h index 7ecd8f8..5731308 100644 --- a/include/clang/AST/DeclAccessPair.h +++ b/include/clang/AST/DeclAccessPair.h @@ -19,6 +19,7 @@ #define LLVM_CLANG_AST_DECLACCESSPAIR_H #include "clang/Basic/Specifiers.h" +#include "llvm/Support/DataTypes.h" namespace clang { diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 50e2027..852bb9a 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -14,38 +14,40 @@ #ifndef LLVM_CLANG_AST_DECLBASE_H #define LLVM_CLANG_AST_DECLBASE_H -#include "clang/AST/Attr.h" +#include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" -#include "clang/AST/Type.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" namespace clang { -class DeclContext; -class TranslationUnitDecl; -class NamespaceDecl; -class UsingDirectiveDecl; -class NamedDecl; -class FunctionDecl; +class ASTMutationListener; +class BlockDecl; class CXXRecordDecl; +class CompoundStmt; +class DeclContext; +class DeclarationName; +class DependentDiagnostic; class EnumDecl; -class ObjCMethodDecl; -class ObjCContainerDecl; -class ObjCInterfaceDecl; +class FunctionDecl; +class LinkageSpecDecl; +class Module; +class NamedDecl; +class NamespaceDecl; class ObjCCategoryDecl; -class ObjCProtocolDecl; -class ObjCImplementationDecl; class ObjCCategoryImplDecl; +class ObjCContainerDecl; class ObjCImplDecl; -class LinkageSpecDecl; -class BlockDecl; -class DeclarationName; -class CompoundStmt; +class ObjCImplementationDecl; +class ObjCInterfaceDecl; +class ObjCMethodDecl; +class ObjCProtocolDecl; +struct PrintingPolicy; +class Stmt; class StoredDeclsMap; -class DependentDiagnostic; -class ASTMutationListener; +class TranslationUnitDecl; +class UsingDirectiveDecl; } namespace llvm { @@ -133,7 +135,7 @@ public: /// or member ends up here. IDNS_Ordinary = 0x0020, - /// Objective C @protocol. + /// Objective C \@protocol. IDNS_ObjCProtocol = 0x0040, /// This declaration is a friend function. A friend function @@ -335,7 +337,10 @@ protected: static void *AllocateDeserializedDecl(const ASTContext &Context, unsigned ID, unsigned Size); - + + /// \brief Update a potentially out-of-date declaration. + void updateOutOfDate(IdentifierInfo &II) const; + public: /// \brief Source range that this declaration covers. @@ -455,9 +460,7 @@ public: /// getMaxAlignment - return the maximum alignment specified by attributes /// on this decl, 0 if there are none. - unsigned getMaxAlignment() const { - return hasAttrs() ? getMaxAttrAlignment(getAttrs(), getASTContext()) : 0; - } + unsigned getMaxAlignment() const; /// setInvalidDecl - Indicates the Decl had a semantic error. This /// allows for graceful error recovery. @@ -593,7 +596,18 @@ public: return 0; } - + +private: + Module *getOwningModuleSlow() const; + +public: + Module *getOwningModule() const { + if (!isFromASTFile()) + return 0; + + return getOwningModuleSlow(); + } + unsigned getIdentifierNamespace() const { return IdentifierNamespace; } @@ -851,6 +865,8 @@ public: unsigned Indentation = 0); // Debuggers don't usually respect default arguments. LLVM_ATTRIBUTE_USED void dump() const; + // Same as dump(), but forces color printing. + LLVM_ATTRIBUTE_USED void dumpColor() const; void dump(raw_ostream &Out) const; // Debuggers don't usually respect default arguments. LLVM_ATTRIBUTE_USED void dumpXML() const; @@ -891,29 +907,9 @@ public: virtual void print(raw_ostream &OS) const; }; -class DeclContextLookupResult - : public std::pair<NamedDecl**,NamedDecl**> { -public: - DeclContextLookupResult(NamedDecl **I, NamedDecl **E) - : std::pair<NamedDecl**,NamedDecl**>(I, E) {} - DeclContextLookupResult() - : std::pair<NamedDecl**,NamedDecl**>() {} +typedef llvm::MutableArrayRef<NamedDecl*> DeclContextLookupResult; - using std::pair<NamedDecl**,NamedDecl**>::operator=; -}; - -class DeclContextLookupConstResult - : public std::pair<NamedDecl*const*, NamedDecl*const*> { -public: - DeclContextLookupConstResult(std::pair<NamedDecl**,NamedDecl**> R) - : std::pair<NamedDecl*const*, NamedDecl*const*>(R) {} - DeclContextLookupConstResult(NamedDecl * const *I, NamedDecl * const *E) - : std::pair<NamedDecl*const*, NamedDecl*const*>(I, E) {} - DeclContextLookupConstResult() - : std::pair<NamedDecl*const*, NamedDecl*const*>() {} - - using std::pair<NamedDecl*const*,NamedDecl*const*>::operator=; -}; +typedef ArrayRef<NamedDecl *> DeclContextLookupConstResult; /// DeclContext - This is used only as base class of specific decl types that /// can act as declaration contexts. These decls are (only the top classes @@ -935,19 +931,26 @@ class DeclContext { /// \brief Whether this declaration context also has some external /// storage that contains additional declarations that are lexically /// part of this context. - mutable unsigned ExternalLexicalStorage : 1; + mutable bool ExternalLexicalStorage : 1; /// \brief Whether this declaration context also has some external /// storage that contains additional declarations that are visible /// in this context. - mutable unsigned ExternalVisibleStorage : 1; + mutable bool ExternalVisibleStorage : 1; + + /// \brief Whether this declaration context has had external visible + /// storage added since the last lookup. In this case, \c LookupPtr's + /// invariant may not hold and needs to be fixed before we perform + /// another lookup. + mutable bool NeedToReconcileExternalVisibleStorage : 1; /// \brief Pointer to the data structure used to lookup declarations /// within this context (or a DependentStoredDeclsMap if this is a /// dependent context), and a bool indicating whether we have lazily /// omitted any declarations from the map. We maintain the invariant - /// that, if the map contains an entry for a DeclarationName, then it - /// contains all relevant entries for that name. + /// that, if the map contains an entry for a DeclarationName (and we + /// haven't lazily omitted anything), then it contains all relevant + /// entries for that name. mutable llvm::PointerIntPair<StoredDeclsMap*, 1, bool> LookupPtr; protected: @@ -970,10 +973,11 @@ protected: static std::pair<Decl *, Decl *> BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded); - DeclContext(Decl::Kind K) - : DeclKind(K), ExternalLexicalStorage(false), - ExternalVisibleStorage(false), LookupPtr(0, false), FirstDecl(0), - LastDecl(0) { } + DeclContext(Decl::Kind K) + : DeclKind(K), ExternalLexicalStorage(false), + ExternalVisibleStorage(false), + NeedToReconcileExternalVisibleStorage(false), LookupPtr(0, false), + FirstDecl(0), LastDecl(0) {} public: ~DeclContext(); @@ -1086,6 +1090,10 @@ public: /// a C++ extern "C" linkage spec. bool isExternCContext() const; + /// \brief Determines whether this context is, or is nested within, + /// a C++ extern "C++" linkage spec. + bool isExternCXXContext() const; + /// \brief Determine whether this declaration context is equivalent /// to the declaration context DC. bool Equals(const DeclContext *DC) const { @@ -1160,7 +1168,7 @@ public: /// contexts that are semanticaly connected to this declaration context, /// in source order, including this context (which may be the only result, /// for non-namespace contexts). - void collectAllContexts(llvm::SmallVectorImpl<DeclContext *> &Contexts); + void collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts); /// decl_iterator - Iterates through the declarations stored /// within this context. @@ -1423,7 +1431,7 @@ public: /// usual relationship between a DeclContext and the external source. /// See the ASTImporter for the (few, but important) use cases. void localUncachedLookup(DeclarationName Name, - llvm::SmallVectorImpl<NamedDecl *> &Results); + SmallVectorImpl<NamedDecl *> &Results); /// @brief Makes a declaration visible within this context. /// @@ -1473,9 +1481,9 @@ public: // Low-level accessors /// \brief Mark the lookup table as needing to be built. This should be - /// used only if setHasExternalLexicalStorage() has been called. + /// used only if setHasExternalLexicalStorage() has been called on any + /// decl context for which this is the primary context. void setMustBuildLookupTable() { - assert(ExternalLexicalStorage && "Requires external lexical storage"); LookupPtr.setInt(true); } @@ -1504,6 +1512,8 @@ public: /// declarations visible in this context. void setHasExternalVisibleStorage(bool ES = true) { ExternalVisibleStorage = ES; + if (ES && LookupPtr.getPointer()) + NeedToReconcileExternalVisibleStorage = true; } /// \brief Determine whether the given declaration is stored in the list of @@ -1519,6 +1529,7 @@ public: LLVM_ATTRIBUTE_USED void dumpDeclContext() const; private: + void reconcileExternalVisibleStorage(); void LoadLexicalDeclsFromExternalStorage() const; /// @brief Makes a declaration visible within this context, but diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 9cb56e2..05ff49c 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -15,11 +15,11 @@ #ifndef LLVM_CLANG_AST_DECLCXX_H #define LLVM_CLANG_AST_DECLCXX_H +#include "clang/AST/ASTUnresolvedSet.h" +#include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" -#include "clang/AST/Decl.h" #include "clang/AST/TypeLoc.h" -#include "clang/AST/UnresolvedSet.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" @@ -69,17 +69,6 @@ public: } // end namespace clang namespace llvm { - /// Implement simplify_type for AnyFunctionDecl, so that we can dyn_cast from - /// AnyFunctionDecl to any function or function template declaration. - template<> struct simplify_type<const ::clang::AnyFunctionDecl> { - typedef ::clang::NamedDecl* SimpleType; - static SimpleType getSimplifiedValue(const ::clang::AnyFunctionDecl &Val) { - return Val; - } - }; - template<> struct simplify_type< ::clang::AnyFunctionDecl> - : public simplify_type<const ::clang::AnyFunctionDecl> {}; - // Provide PointerLikeTypeTraits for non-cvr pointers. template<> class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> { @@ -272,32 +261,25 @@ class CXXRecordDecl : public RecordDecl { friend void TagDecl::startDefinition(); + /// Values used in DefinitionData fields to represent special members. + enum SpecialMemberFlags { + SMF_DefaultConstructor = 0x1, + SMF_CopyConstructor = 0x2, + SMF_MoveConstructor = 0x4, + SMF_CopyAssignment = 0x8, + SMF_MoveAssignment = 0x10, + SMF_Destructor = 0x20, + SMF_All = 0x3f + }; + struct DefinitionData { DefinitionData(CXXRecordDecl *D); - /// UserDeclaredConstructor - True when this class has a - /// user-declared constructor. + /// \brief True if this class has any user-declared constructors. bool UserDeclaredConstructor : 1; - /// UserDeclaredCopyConstructor - True when this class has a - /// user-declared copy constructor. - bool UserDeclaredCopyConstructor : 1; - - /// UserDeclareMoveConstructor - True when this class has a - /// user-declared move constructor. - bool UserDeclaredMoveConstructor : 1; - - /// UserDeclaredCopyAssignment - True when this class has a - /// user-declared copy assignment operator. - bool UserDeclaredCopyAssignment : 1; - - /// UserDeclareMoveAssignment - True when this class has a - /// user-declared move assignment. - bool UserDeclaredMoveAssignment : 1; - - /// UserDeclaredDestructor - True when this class has a - /// user-declared destructor. - bool UserDeclaredDestructor : 1; + /// The user-declared special members which this class has. + unsigned UserDeclaredSpecialMembers : 6; /// Aggregate - True when this class is an aggregate. bool Aggregate : 1; @@ -360,21 +342,46 @@ class CXXRecordDecl : public RecordDecl { /// \brief True if any field has an in-class initializer. bool HasInClassInitializer : 1; - /// HasTrivialDefaultConstructor - True when, if this class has a default - /// constructor, this default constructor is trivial. + /// \brief True if any field is of reference type, and does not have an + /// in-class initializer. In this case, value-initialization of this class + /// is illegal in C++98 even if the class has a trivial default constructor. + bool HasUninitializedReferenceMember : 1; + + /// \brief These flags are \c true if a defaulted corresponding special + /// member can't be fully analyzed without performing overload resolution. + /// @{ + bool NeedOverloadResolutionForMoveConstructor : 1; + bool NeedOverloadResolutionForMoveAssignment : 1; + bool NeedOverloadResolutionForDestructor : 1; + /// @} + + /// \brief These flags are \c true if an implicit defaulted corresponding + /// special member would be defined as deleted. + /// @{ + bool DefaultedMoveConstructorIsDeleted : 1; + bool DefaultedMoveAssignmentIsDeleted : 1; + bool DefaultedDestructorIsDeleted : 1; + /// @} + + /// \brief The trivial special members which this class has, per + /// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25, + /// C++11 [class.dtor]p5, or would have if the member were not suppressed. + /// + /// This excludes any user-declared but not user-provided special members + /// which have been declared but not yet defined. + unsigned HasTrivialSpecialMembers : 6; + + /// \brief The declared special members of this class which are known to be + /// non-trivial. /// - /// C++0x [class.ctor]p5 - /// A default constructor is trivial if it is not user-provided and if - /// -- its class has no virtual functions and no virtual base classes, - /// and - /// -- no non-static data member of its class has a - /// brace-or-equal-initializer, and - /// -- all the direct base classes of its class have trivial - /// default constructors, and - /// -- for all the nonstatic data members of its class that are of class - /// type (or array thereof), each such class has a trivial - /// default constructor. - bool HasTrivialDefaultConstructor : 1; + /// This excludes any user-declared but not user-provided special members + /// which have been declared but not yet defined, and any implicit special + /// members which have not yet been declared. + unsigned DeclaredNonTrivialSpecialMembers : 6; + + /// HasIrrelevantDestructor - True when this class has a destructor with no + /// semantic effect. + bool HasIrrelevantDestructor : 1; /// HasConstexprNonCopyMoveConstructor - True when this class has at least /// one user-declared constexpr constructor which is neither the copy nor @@ -389,80 +396,6 @@ class CXXRecordDecl : public RecordDecl { /// default constructor (either user-declared or implicitly declared). bool HasConstexprDefaultConstructor : 1; - /// HasTrivialCopyConstructor - True when this class has a trivial copy - /// constructor. - /// - /// C++0x [class.copy]p13: - /// A copy/move constructor for class X is trivial if it is neither - /// user-provided and if - /// -- class X has no virtual functions and no virtual base classes, and - /// -- the constructor selected to copy/move each direct base class - /// subobject is trivial, and - /// -- for each non-static data member of X that is of class type (or an - /// array thereof), the constructor selected to copy/move that member - /// is trivial; - /// otherwise the copy/move constructor is non-trivial. - bool HasTrivialCopyConstructor : 1; - - /// HasTrivialMoveConstructor - True when this class has a trivial move - /// constructor. - /// - /// C++0x [class.copy]p13: - /// A copy/move constructor for class X is trivial if it is neither - /// user-provided and if - /// -- class X has no virtual functions and no virtual base classes, and - /// -- the constructor selected to copy/move each direct base class - /// subobject is trivial, and - /// -- for each non-static data member of X that is of class type (or an - /// array thereof), the constructor selected to copy/move that member - /// is trivial; - /// otherwise the copy/move constructor is non-trivial. - bool HasTrivialMoveConstructor : 1; - - /// HasTrivialCopyAssignment - True when this class has a trivial copy - /// assignment operator. - /// - /// C++0x [class.copy]p27: - /// A copy/move assignment operator for class X is trivial if it is - /// neither user-provided nor deleted and if - /// -- class X has no virtual functions and no virtual base classes, and - /// -- the assignment operator selected to copy/move each direct base - /// class subobject is trivial, and - /// -- for each non-static data member of X that is of class type (or an - /// array thereof), the assignment operator selected to copy/move - /// that member is trivial; - /// otherwise the copy/move assignment operator is non-trivial. - bool HasTrivialCopyAssignment : 1; - - /// HasTrivialMoveAssignment - True when this class has a trivial move - /// assignment operator. - /// - /// C++0x [class.copy]p27: - /// A copy/move assignment operator for class X is trivial if it is - /// neither user-provided nor deleted and if - /// -- class X has no virtual functions and no virtual base classes, and - /// -- the assignment operator selected to copy/move each direct base - /// class subobject is trivial, and - /// -- for each non-static data member of X that is of class type (or an - /// array thereof), the assignment operator selected to copy/move - /// that member is trivial; - /// otherwise the copy/move assignment operator is non-trivial. - bool HasTrivialMoveAssignment : 1; - - /// HasTrivialDestructor - True when this class has a trivial destructor. - /// - /// C++ [class.dtor]p3. A destructor is trivial if it is an - /// implicitly-declared destructor and if: - /// * all of the direct base classes of its class have trivial destructors - /// and - /// * for all of the non-static data members of its class that are of class - /// type (or array thereof), each such class has a trivial destructor. - bool HasTrivialDestructor : 1; - - /// HasIrrelevantDestructor - True when this class has a destructor with no - /// semantic effect. - bool HasIrrelevantDestructor : 1; - /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least /// one non-static data member or base class of non-literal or volatile /// type. @@ -472,27 +405,29 @@ class CXXRecordDecl : public RecordDecl { /// already computed and are available. bool ComputedVisibleConversions : 1; - /// \brief Whether we have a C++0x user-provided default constructor (not + /// \brief Whether we have a C++11 user-provided default constructor (not /// explicitly deleted or defaulted). bool UserProvidedDefaultConstructor : 1; - /// \brief Whether we have already declared the default constructor. - bool DeclaredDefaultConstructor : 1; + /// \brief The special members which have been declared for this class, + /// either by the user or implicitly. + unsigned DeclaredSpecialMembers : 6; - /// \brief Whether we have already declared the copy constructor. - bool DeclaredCopyConstructor : 1; + /// \brief Whether an implicit copy constructor would have a const-qualified + /// parameter. + bool ImplicitCopyConstructorHasConstParam : 1; - /// \brief Whether we have already declared the move constructor. - bool DeclaredMoveConstructor : 1; + /// \brief Whether an implicit copy assignment operator would have a + /// const-qualified parameter. + bool ImplicitCopyAssignmentHasConstParam : 1; - /// \brief Whether we have already declared the copy-assignment operator. - bool DeclaredCopyAssignment : 1; + /// \brief Whether any declared copy constructor has a const-qualified + /// parameter. + bool HasDeclaredCopyConstructorWithConstParam : 1; - /// \brief Whether we have already declared the move-assignment operator. - bool DeclaredMoveAssignment : 1; - - /// \brief Whether we have already declared a destructor within the class. - bool DeclaredDestructor : 1; + /// \brief Whether any declared copy assignment operator has either a + /// const-qualified reference parameter or a non-reference parameter. + bool HasDeclaredCopyAssignmentWithConstParam : 1; /// \brief Whether an implicit move constructor was attempted to be declared /// but would have been deleted. @@ -522,14 +457,14 @@ class CXXRecordDecl : public RecordDecl { /// of this C++ class (but not its inherited conversion /// functions). Each of the entries in this overload set is a /// CXXConversionDecl. - UnresolvedSet<4> Conversions; + ASTUnresolvedSet Conversions; /// VisibleConversions - Overload set containing the conversion /// functions of this C++ class and all those inherited conversion /// functions that are visible in this class. Each of the entries /// in this overload set is a CXXConversionDecl or a /// FunctionTemplateDecl. - UnresolvedSet<4> VisibleConversions; + ASTUnresolvedSet VisibleConversions; /// Definition - The declaration which defines this record. CXXRecordDecl *Definition; @@ -636,6 +571,10 @@ class CXXRecordDecl : public RecordDecl { friend class DeclContext; friend class LambdaExpr; + /// \brief Called from setBases and addedMember to notify the class that a + /// direct or virtual base class or a member of class type has been added. + void addedClassSubobject(CXXRecordDecl *Base); + /// \brief Notify the class that member has been added. /// /// This routine helps maintain information about the class based on which @@ -646,9 +585,6 @@ class CXXRecordDecl : public RecordDecl { void markedVirtualFunctionPure(); friend void FunctionDecl::setPure(bool); - void markedConstructorConstexpr(CXXConstructorDecl *CD); - friend void FunctionDecl::setConstexpr(bool); - friend class ASTNodeImporter; protected: @@ -765,7 +701,8 @@ public: return reverse_base_class_const_iterator(vbases_begin()); } - /// \brief Determine whether this class has any dependent base classes. + /// \brief Determine whether this class has any dependent base classes which + /// are not the current instantiation. bool hasAnyDependentBases() const; /// Iterator access to method members. The method iterator visits @@ -805,47 +742,38 @@ public: return data().FirstFriend != 0; } + /// \brief \c true if we know for sure that this class has a single, + /// accessible, unambiguous move constructor that is not deleted. + bool hasSimpleMoveConstructor() const { + return !hasUserDeclaredMoveConstructor() && hasMoveConstructor(); + } + /// \brief \c true if we know for sure that this class has a single, + /// accessible, unambiguous move assignment operator that is not deleted. + bool hasSimpleMoveAssignment() const { + return !hasUserDeclaredMoveAssignment() && hasMoveAssignment(); + } + /// \brief \c true if we know for sure that this class has an accessible + /// destructor that is not deleted. + bool hasSimpleDestructor() const { + return !hasUserDeclaredDestructor() && + !data().DefaultedDestructorIsDeleted; + } + + /// \brief Determine whether this class has any default constructors. + bool hasDefaultConstructor() const { + return (data().DeclaredSpecialMembers & SMF_DefaultConstructor) || + needsImplicitDefaultConstructor(); + } + /// \brief Determine if we need to declare a default constructor for /// this class. /// /// This value is used for lazy creation of default constructors. bool needsImplicitDefaultConstructor() const { return !data().UserDeclaredConstructor && - !data().DeclaredDefaultConstructor; - } - - /// hasDeclaredDefaultConstructor - Whether this class's default constructor - /// has been declared (either explicitly or implicitly). - bool hasDeclaredDefaultConstructor() const { - return data().DeclaredDefaultConstructor; + !(data().DeclaredSpecialMembers & SMF_DefaultConstructor); } - /// hasConstCopyConstructor - Determines whether this class has a - /// copy constructor that accepts a const-qualified argument. - bool hasConstCopyConstructor() const; - - /// getCopyConstructor - Returns the copy constructor for this class - CXXConstructorDecl *getCopyConstructor(unsigned TypeQuals) const; - - /// getMoveConstructor - Returns the move constructor for this class - CXXConstructorDecl *getMoveConstructor() const; - - /// \brief Retrieve the copy-assignment operator for this class, if available. - /// - /// This routine attempts to find the copy-assignment operator for this - /// class, using a simplistic form of overload resolution. - /// - /// \param ArgIsConst Whether the argument to the copy-assignment operator - /// is const-qualified. - /// - /// \returns The copy-assignment operator that can be invoked, or NULL if - /// a unique copy-assignment operator could not be found. - CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const; - - /// getMoveAssignmentOperator - Returns the move assignment operator for this - /// class - CXXMethodDecl *getMoveAssignmentOperator() const; - /// hasUserDeclaredConstructor - Whether this class has any /// user-declared constructors. When true, a default constructor /// will not be implicitly declared. @@ -863,35 +791,53 @@ public: /// user-declared copy constructor. When false, a copy constructor /// will be implicitly declared. bool hasUserDeclaredCopyConstructor() const { - return data().UserDeclaredCopyConstructor; + return data().UserDeclaredSpecialMembers & SMF_CopyConstructor; } - /// \brief Determine whether this class has had its copy constructor - /// declared, either via the user or via an implicit declaration. - /// - /// This value is used for lazy creation of copy constructors. - bool hasDeclaredCopyConstructor() const { - return data().DeclaredCopyConstructor; + /// \brief Determine whether this class needs an implicit copy + /// constructor to be lazily declared. + bool needsImplicitCopyConstructor() const { + return !(data().DeclaredSpecialMembers & SMF_CopyConstructor); + } + + /// \brief Determine whether we need to eagerly declare a defaulted copy + /// constructor for this class. + bool needsOverloadResolutionForCopyConstructor() const { + return data().HasMutableFields; + } + + /// \brief Determine whether an implicit copy constructor for this type + /// would have a parameter with a const-qualified reference type. + bool implicitCopyConstructorHasConstParam() const { + return data().ImplicitCopyConstructorHasConstParam; + } + + /// \brief Determine whether this class has a copy constructor with + /// a parameter type which is a reference to a const-qualified type. + bool hasCopyConstructorWithConstParam() const { + return data().HasDeclaredCopyConstructorWithConstParam || + (needsImplicitCopyConstructor() && + implicitCopyConstructorHasConstParam()); } /// hasUserDeclaredMoveOperation - Whether this class has a user- /// declared move constructor or assignment operator. When false, a /// move constructor and assignment operator may be implicitly declared. bool hasUserDeclaredMoveOperation() const { - return data().UserDeclaredMoveConstructor || - data().UserDeclaredMoveAssignment; + return data().UserDeclaredSpecialMembers & + (SMF_MoveConstructor | SMF_MoveAssignment); } /// \brief Determine whether this class has had a move constructor /// declared by the user. bool hasUserDeclaredMoveConstructor() const { - return data().UserDeclaredMoveConstructor; + return data().UserDeclaredSpecialMembers & SMF_MoveConstructor; } - /// \brief Determine whether this class has had a move constructor - /// declared. - bool hasDeclaredMoveConstructor() const { - return data().DeclaredMoveConstructor; + /// \brief Determine whether this class has a move constructor. + bool hasMoveConstructor() const { + return (data().DeclaredSpecialMembers & SMF_MoveConstructor) || + needsImplicitMoveConstructor(); } /// \brief Determine whether implicit move constructor generation for this @@ -908,44 +854,66 @@ public: /// \brief Determine whether this class should get an implicit move /// constructor or if any existing special member function inhibits this. - /// - /// Covers all bullets of C++0x [class.copy]p9 except the last, that the - /// constructor wouldn't be deleted, which is only looked up from a cached - /// result. bool needsImplicitMoveConstructor() const { return !hasFailedImplicitMoveConstructor() && - !hasDeclaredMoveConstructor() && + !(data().DeclaredSpecialMembers & SMF_MoveConstructor) && !hasUserDeclaredCopyConstructor() && !hasUserDeclaredCopyAssignment() && !hasUserDeclaredMoveAssignment() && - !hasUserDeclaredDestructor(); + !hasUserDeclaredDestructor() && + !data().DefaultedMoveConstructorIsDeleted; + } + + /// \brief Determine whether we need to eagerly declare a defaulted move + /// constructor for this class. + bool needsOverloadResolutionForMoveConstructor() const { + return data().NeedOverloadResolutionForMoveConstructor; } /// hasUserDeclaredCopyAssignment - Whether this class has a /// user-declared copy assignment operator. When false, a copy /// assigment operator will be implicitly declared. bool hasUserDeclaredCopyAssignment() const { - return data().UserDeclaredCopyAssignment; + return data().UserDeclaredSpecialMembers & SMF_CopyAssignment; } - /// \brief Determine whether this class has had its copy assignment operator - /// declared, either via the user or via an implicit declaration. - /// - /// This value is used for lazy creation of copy assignment operators. - bool hasDeclaredCopyAssignment() const { - return data().DeclaredCopyAssignment; + /// \brief Determine whether this class needs an implicit copy + /// assignment operator to be lazily declared. + bool needsImplicitCopyAssignment() const { + return !(data().DeclaredSpecialMembers & SMF_CopyAssignment); + } + + /// \brief Determine whether we need to eagerly declare a defaulted copy + /// assignment operator for this class. + bool needsOverloadResolutionForCopyAssignment() const { + return data().HasMutableFields; + } + + /// \brief Determine whether an implicit copy assignment operator for this + /// type would have a parameter with a const-qualified reference type. + bool implicitCopyAssignmentHasConstParam() const { + return data().ImplicitCopyAssignmentHasConstParam; + } + + /// \brief Determine whether this class has a copy assignment operator with + /// a parameter type which is a reference to a const-qualified type or is not + /// a reference.. + bool hasCopyAssignmentWithConstParam() const { + return data().HasDeclaredCopyAssignmentWithConstParam || + (needsImplicitCopyAssignment() && + implicitCopyAssignmentHasConstParam()); } /// \brief Determine whether this class has had a move assignment /// declared by the user. bool hasUserDeclaredMoveAssignment() const { - return data().UserDeclaredMoveAssignment; + return data().UserDeclaredSpecialMembers & SMF_MoveAssignment; } - /// hasDeclaredMoveAssignment - Whether this class has a - /// declared move assignment operator. - bool hasDeclaredMoveAssignment() const { - return data().DeclaredMoveAssignment; + /// \brief Determine whether this class has a move assignment operator. + bool hasMoveAssignment() const { + return (data().DeclaredSpecialMembers & SMF_MoveAssignment) || + needsImplicitMoveAssignment(); } /// \brief Determine whether implicit move assignment generation for this @@ -963,34 +931,44 @@ public: /// \brief Determine whether this class should get an implicit move /// assignment operator or if any existing special member function inhibits /// this. - /// - /// Covers all bullets of C++0x [class.copy]p20 except the last, that the - /// constructor wouldn't be deleted. bool needsImplicitMoveAssignment() const { return !hasFailedImplicitMoveAssignment() && - !hasDeclaredMoveAssignment() && + !(data().DeclaredSpecialMembers & SMF_MoveAssignment) && !hasUserDeclaredCopyConstructor() && !hasUserDeclaredCopyAssignment() && !hasUserDeclaredMoveConstructor() && - !hasUserDeclaredDestructor(); + !hasUserDeclaredDestructor() && + !data().DefaultedMoveAssignmentIsDeleted; + } + + /// \brief Determine whether we need to eagerly declare a move assignment + /// operator for this class. + bool needsOverloadResolutionForMoveAssignment() const { + return data().NeedOverloadResolutionForMoveAssignment; } /// hasUserDeclaredDestructor - Whether this class has a /// user-declared destructor. When false, a destructor will be /// implicitly declared. bool hasUserDeclaredDestructor() const { - return data().UserDeclaredDestructor; + return data().UserDeclaredSpecialMembers & SMF_Destructor; } - /// \brief Determine whether this class has had its destructor declared, - /// either via the user or via an implicit declaration. - /// - /// This value is used for lazy creation of destructors. - bool hasDeclaredDestructor() const { return data().DeclaredDestructor; } + /// \brief Determine whether this class needs an implicit destructor to + /// be lazily declared. + bool needsImplicitDestructor() const { + return !(data().DeclaredSpecialMembers & SMF_Destructor); + } + + /// \brief Determine whether we need to eagerly declare a destructor for this + /// class. + bool needsOverloadResolutionForDestructor() const { + return data().NeedOverloadResolutionForDestructor; + } /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { return hasDefinition() && data().IsLambda; } - + /// \brief For a closure type, retrieve the mapping from captured /// variables and this to the non-static data members that store the /// values or references of the captures. @@ -1011,21 +989,12 @@ public: return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL; } - /// getConversions - Retrieve the overload set containing all of the - /// conversion functions in this class. - UnresolvedSetImpl *getConversionFunctions() { - return &data().Conversions; - } - const UnresolvedSetImpl *getConversionFunctions() const { - return &data().Conversions; - } - - typedef UnresolvedSetImpl::iterator conversion_iterator; + typedef UnresolvedSetIterator conversion_iterator; conversion_iterator conversion_begin() const { - return getConversionFunctions()->begin(); + return data().Conversions.begin(); } conversion_iterator conversion_end() const { - return getConversionFunctions()->end(); + return data().Conversions.end(); } /// Removes a conversion function from this class. The conversion @@ -1035,7 +1004,8 @@ public: /// getVisibleConversionFunctions - get all conversion functions visible /// in current class; including conversion function templates. - const UnresolvedSetImpl *getVisibleConversionFunctions(); + std::pair<conversion_iterator, conversion_iterator> + getVisibleConversionFunctions(); /// isAggregate - Whether this class is an aggregate (C++ /// [dcl.init.aggr]), which is a class with no user-declared @@ -1047,10 +1017,26 @@ public: /// for non-static data members. bool hasInClassInitializer() const { return data().HasInClassInitializer; } + /// \brief Whether this class or any of its subobjects has any members of + /// reference type which would make value-initialization ill-formed, per + /// C++03 [dcl.init]p5: + /// -- if T is a non-union class type without a user-declared constructor, + /// then every non-static data member and base-class component of T is + /// value-initialized + /// [...] + /// A program that calls for [...] value-initialization of an entity of + /// reference type is ill-formed. + bool hasUninitializedReferenceMember() const { + return !isUnion() && !hasUserDeclaredConstructor() && + data().HasUninitializedReferenceMember; + } + /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class /// that is an aggregate that has no non-static non-POD data members, no /// reference data members, no user-defined copy assignment operator and no /// user-defined destructor. + /// + /// Note that this is the C++ TR1 definition of POD. bool isPOD() const { return data().PlainOldData; } /// \brief True if this class is C-like, without C++-specific features, e.g. @@ -1079,64 +1065,110 @@ public: /// mutable field. bool hasMutableFields() const { return data().HasMutableFields; } - /// hasTrivialDefaultConstructor - Whether this class has a trivial default - /// constructor (C++11 [class.ctor]p5). + /// \brief Determine whether this class has a trivial default constructor + /// (C++11 [class.ctor]p5). bool hasTrivialDefaultConstructor() const { - return data().HasTrivialDefaultConstructor && - (!data().UserDeclaredConstructor || - data().DeclaredDefaultConstructor); + return hasDefaultConstructor() && + (data().HasTrivialSpecialMembers & SMF_DefaultConstructor); + } + + /// \brief Determine whether this class has a non-trivial default constructor + /// (C++11 [class.ctor]p5). + bool hasNonTrivialDefaultConstructor() const { + return (data().DeclaredNonTrivialSpecialMembers & SMF_DefaultConstructor) || + (needsImplicitDefaultConstructor() && + !(data().HasTrivialSpecialMembers & SMF_DefaultConstructor)); } - /// hasConstexprNonCopyMoveConstructor - Whether this class has at least one - /// constexpr constructor other than the copy or move constructors. + /// \brief Determine whether this class has at least one constexpr constructor + /// other than the copy or move constructors. bool hasConstexprNonCopyMoveConstructor() const { return data().HasConstexprNonCopyMoveConstructor || - (!hasUserDeclaredConstructor() && + (needsImplicitDefaultConstructor() && defaultedDefaultConstructorIsConstexpr()); } - /// defaultedDefaultConstructorIsConstexpr - Whether a defaulted default - /// constructor for this class would be constexpr. + /// \brief Determine whether a defaulted default constructor for this class + /// would be constexpr. bool defaultedDefaultConstructorIsConstexpr() const { return data().DefaultedDefaultConstructorIsConstexpr && (!isUnion() || hasInClassInitializer()); } - /// hasConstexprDefaultConstructor - Whether this class has a constexpr - /// default constructor. + /// \brief Determine whether this class has a constexpr default constructor. bool hasConstexprDefaultConstructor() const { return data().HasConstexprDefaultConstructor || - (!data().UserDeclaredConstructor && + (needsImplicitDefaultConstructor() && defaultedDefaultConstructorIsConstexpr()); } - // hasTrivialCopyConstructor - Whether this class has a trivial copy - // constructor (C++ [class.copy]p6, C++0x [class.copy]p13) + /// \brief Determine whether this class has a trivial copy constructor + /// (C++ [class.copy]p6, C++11 [class.copy]p12) bool hasTrivialCopyConstructor() const { - return data().HasTrivialCopyConstructor; + return data().HasTrivialSpecialMembers & SMF_CopyConstructor; + } + + /// \brief Determine whether this class has a non-trivial copy constructor + /// (C++ [class.copy]p6, C++11 [class.copy]p12) + bool hasNonTrivialCopyConstructor() const { + return data().DeclaredNonTrivialSpecialMembers & SMF_CopyConstructor || + !hasTrivialCopyConstructor(); } - // hasTrivialMoveConstructor - Whether this class has a trivial move - // constructor (C++0x [class.copy]p13) + /// \brief Determine whether this class has a trivial move constructor + /// (C++11 [class.copy]p12) bool hasTrivialMoveConstructor() const { - return data().HasTrivialMoveConstructor; + return hasMoveConstructor() && + (data().HasTrivialSpecialMembers & SMF_MoveConstructor); } - // hasTrivialCopyAssignment - Whether this class has a trivial copy - // assignment operator (C++ [class.copy]p11, C++0x [class.copy]p27) + /// \brief Determine whether this class has a non-trivial move constructor + /// (C++11 [class.copy]p12) + bool hasNonTrivialMoveConstructor() const { + return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveConstructor) || + (needsImplicitMoveConstructor() && + !(data().HasTrivialSpecialMembers & SMF_MoveConstructor)); + } + + /// \brief Determine whether this class has a trivial copy assignment operator + /// (C++ [class.copy]p11, C++11 [class.copy]p25) bool hasTrivialCopyAssignment() const { - return data().HasTrivialCopyAssignment; + return data().HasTrivialSpecialMembers & SMF_CopyAssignment; + } + + /// \brief Determine whether this class has a non-trivial copy assignment + /// operator (C++ [class.copy]p11, C++11 [class.copy]p25) + bool hasNonTrivialCopyAssignment() const { + return data().DeclaredNonTrivialSpecialMembers & SMF_CopyAssignment || + !hasTrivialCopyAssignment(); } - // hasTrivialMoveAssignment - Whether this class has a trivial move - // assignment operator (C++0x [class.copy]p27) + /// \brief Determine whether this class has a trivial move assignment operator + /// (C++11 [class.copy]p25) bool hasTrivialMoveAssignment() const { - return data().HasTrivialMoveAssignment; + return hasMoveAssignment() && + (data().HasTrivialSpecialMembers & SMF_MoveAssignment); + } + + /// \brief Determine whether this class has a non-trivial move assignment + /// operator (C++11 [class.copy]p25) + bool hasNonTrivialMoveAssignment() const { + return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveAssignment) || + (needsImplicitMoveAssignment() && + !(data().HasTrivialSpecialMembers & SMF_MoveAssignment)); } - // hasTrivialDestructor - Whether this class has a trivial destructor - // (C++ [class.dtor]p3) - bool hasTrivialDestructor() const { return data().HasTrivialDestructor; } + /// \brief Determine whether this class has a trivial destructor + /// (C++ [class.dtor]p3) + bool hasTrivialDestructor() const { + return data().HasTrivialSpecialMembers & SMF_Destructor; + } + + /// \brief Determine whether this class has a non-trivial destructor + /// (C++ [class.dtor]p3) + bool hasNonTrivialDestructor() const { + return !(data().HasTrivialSpecialMembers & SMF_Destructor); + } // hasIrrelevantDestructor - Whether this class has a destructor which has no // semantic effect. Any such destructor will be trivial, public, defaulted @@ -1210,7 +1242,9 @@ public: /// \brief If this class is an instantiation of a member class of a /// class template specialization, retrieves the member specialization /// information. - MemberSpecializationInfo *getMemberSpecializationInfo() const; + MemberSpecializationInfo *getMemberSpecializationInfo() const { + return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>(); + } /// \brief Specify that this record is an instantiation of the /// member class RD. @@ -1256,6 +1290,10 @@ public: return dyn_cast<FunctionDecl>(getDeclContext()); } + /// \brief Determine whether this dependent class is a current instantiation, + /// when viewed from within the given context. + bool isCurrentInstantiation(const DeclContext *CurContext) const; + /// \brief Determine whether this class is derived from the class \p Base. /// /// This routine only determines whether this class is derived from \p Base, @@ -1437,6 +1475,10 @@ public: return (PathAccess > DeclAccess ? PathAccess : DeclAccess); } + /// \brief Indicates that the declaration of a defaulted or deleted special + /// member function is now complete. + void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD); + /// \brief Indicates that the definition of this class is now complete. virtual void completeDefinition(); @@ -1490,6 +1532,9 @@ public: getLambdaData().ContextDecl = ContextDecl; } + /// \brief Returns the inheritance model used for this record. + MSInheritanceModel getMSInheritanceModel() const; + /// \brief Determine whether this lambda expression was known to be dependent /// at the time it was created, even if its context does not appear to be /// dependent. @@ -1528,11 +1573,10 @@ protected: CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isStatic, StorageClass SCAsWritten, bool isInline, + StorageClass SC, bool isInline, bool isConstexpr, SourceLocation EndLocation) : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo, - (isStatic ? SC_Static : SC_None), - SCAsWritten, isInline, isConstexpr) { + SC, isInline, isConstexpr) { if (EndLocation.isValid()) setRangeEnd(EndLocation); } @@ -1542,15 +1586,14 @@ public: SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isStatic, - StorageClass SCAsWritten, + StorageClass SC, bool isInline, bool isConstexpr, SourceLocation EndLocation); static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - bool isStatic() const { return getStorageClass() == SC_Static; } + + bool isStatic() const; bool isInstance() const { return !isStatic(); } bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); } @@ -1958,7 +2001,7 @@ class CXXConstructorDecl : public CXXMethodDecl { QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, bool isConstexpr) - : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false, + : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, SourceLocation()), IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false), CtorInitializers(0), NumCtorInitializers(0) { @@ -2077,7 +2120,7 @@ public: /// constructor (C++ [class.copy]p2, which can be used to copy the /// class. @p TypeQuals will be set to the qualifiers on the /// argument type. For example, @p TypeQuals would be set to @c - /// QualType::Const for the following copy constructor: + /// Qualifiers::Const for the following copy constructor: /// /// @code /// class X { @@ -2177,7 +2220,7 @@ class CXXDestructorDecl : public CXXMethodDecl { const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false, + : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, /*isConstexpr=*/false, SourceLocation()), ImplicitlyDefined(false), OperatorDelete(0) { setImplicit(isImplicitlyDeclared); @@ -2244,7 +2287,7 @@ class CXXConversionDecl : public CXXMethodDecl { QualType T, TypeSourceInfo *TInfo, bool isInline, bool isExplicitSpecified, bool isConstexpr, SourceLocation EndLocation) - : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false, + : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, EndLocation), IsExplicitSpecified(isExplicitSpecified) { } diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h index 39f04c6..84f3698 100644 --- a/include/clang/AST/DeclContextInternals.h +++ b/include/clang/AST/DeclContextInternals.h @@ -15,10 +15,10 @@ #define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H #include "clang/AST/Decl.h" -#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclCXX.h" -#include "llvm/ADT/PointerUnion.h" +#include "clang/AST/DeclarationName.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" #include <algorithm> @@ -97,6 +97,22 @@ public: == Vec.end() && "list still contains decl"); } + /// \brief Remove any declarations which were imported from an external + /// AST source. + void removeExternalDecls() { + if (isNull()) { + // Nothing to do. + } else if (NamedDecl *Singleton = getAsDecl()) { + if (Singleton->isFromASTFile()) + *this = StoredDeclsList(); + } else { + DeclsTy &Vec = *getAsVector(); + Vec.erase(std::remove_if(Vec.begin(), Vec.end(), + std::mem_fun(&Decl::isFromASTFile)), + Vec.end()); + } + } + /// getLookupResult - Return an array of all the decls that this list /// represents. DeclContext::lookup_result getLookupResult() { @@ -117,7 +133,7 @@ public: DeclsTy &Vector = *getAsVector(); // Otherwise, we have a range result. - return DeclContext::lookup_result(&Vector[0], &Vector[0]+Vector.size()); + return DeclContext::lookup_result(Vector.begin(), Vector.end()); } /// HandleRedeclaration - If this is a redeclaration of an existing decl, @@ -186,7 +202,7 @@ public: // All other declarations go at the end of the list, but before any // tag declarations. But we can be clever about tag declarations // because there can only ever be one in a scope. - } else if (Vec.back()->hasTagIdentifierNamespace()) { + } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) { NamedDecl *TagD = Vec.back(); Vec.back() = D; Vec.push_back(TagD); diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 37e4586..253c23c 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -54,22 +54,40 @@ private: /// True if this 'friend' declaration is unsupported. Eventually we /// will support every possible friend declaration, but for now we /// silently ignore some and set this flag to authorize all access. - bool UnsupportedFriend; + bool UnsupportedFriend : 1; + + // The number of "outer" template parameter lists in non-templatic + // (currently unsupported) friend type declarations, such as + // template <class T> friend class A<T>::B; + unsigned NumTPLists : 31; + + // The tail-allocated friend type template parameter lists (if any). + TemplateParameterList* const *getTPLists() const { + return reinterpret_cast<TemplateParameterList* const *>(this + 1); + } + TemplateParameterList **getTPLists() { + return reinterpret_cast<TemplateParameterList**>(this + 1); + } friend class CXXRecordDecl::friend_iterator; friend class CXXRecordDecl; FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, - SourceLocation FriendL) + SourceLocation FriendL, + ArrayRef<TemplateParameterList*> FriendTypeTPLists) : Decl(Decl::Friend, DC, L), Friend(Friend), NextFriend(), FriendLoc(FriendL), - UnsupportedFriend(false) { + UnsupportedFriend(false), + NumTPLists(FriendTypeTPLists.size()) { + for (unsigned i = 0; i < NumTPLists; ++i) + getTPLists()[i] = FriendTypeTPLists[i]; } - explicit FriendDecl(EmptyShell Empty) - : Decl(Decl::Friend, Empty), NextFriend() { } + FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists) + : Decl(Decl::Friend, Empty), NextFriend(), + NumTPLists(NumFriendTypeTPLists) { } FriendDecl *getNextFriend() { if (!NextFriend.isOffset()) @@ -81,8 +99,11 @@ private: public: static FriendDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, - SourceLocation FriendL); - static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID); + SourceLocation FriendL, + ArrayRef<TemplateParameterList*> FriendTypeTPLists + = ArrayRef<TemplateParameterList*>()); + static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned FriendTypeNumTPLists); /// If this friend declaration names an (untemplated but possibly /// dependent) type, return the type; otherwise return null. This @@ -91,6 +112,13 @@ public: TypeSourceInfo *getFriendType() const { return Friend.dyn_cast<TypeSourceInfo*>(); } + unsigned getFriendTypeNumTemplateParameterLists() const { + return NumTPLists; + } + TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const { + assert(N < NumTPLists); + return getTPLists()[N]; + } /// If this friend declaration doesn't name a type, return the inner /// declaration. @@ -114,8 +142,12 @@ public: } return SourceRange(getFriendLoc(), ND->getLocEnd()); } - else if (TypeSourceInfo *TInfo = getFriendType()) - return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc()); + else if (TypeSourceInfo *TInfo = getFriendType()) { + SourceLocation StartL = (NumTPLists == 0) + ? getFriendLoc() + : getTPLists()[0]->getTemplateLoc(); + return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc()); + } else return SourceRange(getFriendLoc(), getLocation()); } diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h index 867b465..4477c25 100644 --- a/include/clang/AST/DeclLookups.h +++ b/include/clang/AST/DeclLookups.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_DECLLOOKUPS_H #define LLVM_CLANG_AST_DECLLOOKUPS_H +#include "clang/AST/ASTContext.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclContextInternals.h" #include "clang/AST/DeclarationName.h" diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 8b27dd8..c294922 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -159,6 +159,9 @@ private: /// method in the interface or its categories. unsigned IsOverriding : 1; + /// \brief Indicates if the method was a definition but its body was skipped. + unsigned HasSkippedBody : 1; + // Result type of this method. QualType MethodDeclType; @@ -238,7 +241,7 @@ private: IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), RelatedResultType(HasRelatedResultType), - SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), + SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0), MethodDeclType(T), ResultTInfo(ResultTInfo), ParamsAndSelLocs(0), NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) { @@ -429,6 +432,10 @@ public: void getOverriddenMethods( SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const; + /// \brief True if the method was a definition but its body was skipped. + bool hasSkippedBody() const { return HasSkippedBody; } + void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + /// \brief Returns the property associated with this method's selector. /// /// Note that even if this particular method is not marked as a property @@ -530,23 +537,29 @@ public: } // Get the local instance/class method declared in this interface. - ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const; - ObjCMethodDecl *getInstanceMethod(Selector Sel) const { - return getMethod(Sel, true/*isInstance*/); + ObjCMethodDecl *getMethod(Selector Sel, bool isInstance, + bool AllowHidden = false) const; + ObjCMethodDecl *getInstanceMethod(Selector Sel, + bool AllowHidden = false) const { + return getMethod(Sel, true/*isInstance*/, AllowHidden); } - ObjCMethodDecl *getClassMethod(Selector Sel) const { - return getMethod(Sel, false/*isInstance*/); + ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const { + return getMethod(Sel, false/*isInstance*/, AllowHidden); } + bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const; ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap; - + + typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder; + /// 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 {} + virtual void collectPropertiesToImplement(PropertyMap &PM, + PropertyDeclOrder &PO) const {} SourceLocation getAtStartLoc() const { return AtStart; } void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } @@ -641,6 +654,10 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// completed by the external AST source when required. mutable bool ExternallyCompleted : 1; + /// \brief Indicates that the ivar cache does not yet include ivars + /// declared in the implementation. + mutable bool IvarListMissingImplementation : 1; + /// \brief The location of the superclass, if any. SourceLocation SuperClassLoc; @@ -650,7 +667,8 @@ class ObjCInterfaceDecl : public ObjCContainerDecl SourceLocation EndLoc; DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), - ExternallyCompleted() { } + ExternallyCompleted(), + IvarListMissingImplementation(true) { } }; ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, @@ -661,11 +679,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// \brief Contains a pointer to the data associated with this class, /// which will be NULL if this class has not yet been defined. - DefinitionData *Data; + /// + /// The bit indicates when we don't need to check for out-of-date + /// declarations. It will be set unless modules are enabled. + llvm::PointerIntPair<DefinitionData *, 1, bool> Data; DefinitionData &data() const { - assert(Data != 0 && "Declaration has no definition!"); - return *Data; + assert(Data.getPointer() && "Declaration has no definition!"); + return *Data.getPointer(); } /// \brief Allocate the definition data for this class. @@ -673,7 +694,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base; virtual ObjCInterfaceDecl *getNextRedeclaration() { - return RedeclLink.getNext(); + return RedeclLink.getNext(); } virtual ObjCInterfaceDecl *getPreviousDeclImpl() { return getPreviousDecl(); @@ -846,24 +867,38 @@ public: /// \brief Determine whether this particular declaration of this class is /// actually also a definition. bool isThisDeclarationADefinition() const { - return Data && Data->Definition == this; + return getDefinition() == this; } /// \brief Determine whether this class has been defined. - bool hasDefinition() const { return Data; } + bool hasDefinition() const { + // If the name of this class is out-of-date, bring it up-to-date, which + // might bring in a definition. + // Note: a null value indicates that we don't have a definition and that + // modules are enabled. + if (!Data.getOpaqueValue()) { + if (IdentifierInfo *II = getIdentifier()) { + if (II->isOutOfDate()) { + updateOutOfDate(*II); + } + } + } + + return Data.getPointer(); + } /// \brief Retrieve the definition of this class, or NULL if this class /// has been forward-declared (with \@class) but not yet defined (with /// \@interface). ObjCInterfaceDecl *getDefinition() { - return hasDefinition()? Data->Definition : 0; + return hasDefinition()? Data.getPointer()->Definition : 0; } /// \brief Retrieve the definition of this class, or NULL if this class /// has been forward-declared (with \@class) but not yet defined (with /// \@interface). const ObjCInterfaceDecl *getDefinition() const { - return hasDefinition()? Data->Definition : 0; + return hasDefinition()? Data.getPointer()->Definition : 0; } /// \brief Starts the definition of this Objective-C class, taking it from @@ -887,7 +922,166 @@ public: : superCls; } - ObjCCategoryDecl* getCategoryList() const { + /// \brief Iterator that walks over the list of categories, filtering out + /// those that do not meet specific criteria. + /// + /// This class template is used for the various permutations of category + /// and extension iterators. + template<bool (*Filter)(ObjCCategoryDecl *)> + class filtered_category_iterator { + ObjCCategoryDecl *Current; + + void findAcceptableCategory(); + + public: + typedef ObjCCategoryDecl * value_type; + typedef value_type reference; + typedef value_type pointer; + typedef std::ptrdiff_t difference_type; + typedef std::input_iterator_tag iterator_category; + + filtered_category_iterator() : Current(0) { } + explicit filtered_category_iterator(ObjCCategoryDecl *Current) + : Current(Current) + { + findAcceptableCategory(); + } + + reference operator*() const { return Current; } + pointer operator->() const { return Current; } + + filtered_category_iterator &operator++(); + + filtered_category_iterator operator++(int) { + filtered_category_iterator Tmp = *this; + ++(*this); + return Tmp; + } + + friend bool operator==(filtered_category_iterator X, + filtered_category_iterator Y) { + return X.Current == Y.Current; + } + + friend bool operator!=(filtered_category_iterator X, + filtered_category_iterator Y) { + return X.Current != Y.Current; + } + }; + +private: + /// \brief Test whether the given category is visible. + /// + /// Used in the \c visible_categories_iterator. + static bool isVisibleCategory(ObjCCategoryDecl *Cat); + +public: + /// \brief Iterator that walks over the list of categories and extensions + /// that are visible, i.e., not hidden in a non-imported submodule. + typedef filtered_category_iterator<isVisibleCategory> + visible_categories_iterator; + + /// \brief Retrieve an iterator to the beginning of the visible-categories + /// list. + visible_categories_iterator visible_categories_begin() const { + return visible_categories_iterator(getCategoryListRaw()); + } + + /// \brief Retrieve an iterator to the end of the visible-categories list. + visible_categories_iterator visible_categories_end() const { + return visible_categories_iterator(); + } + + /// \brief Determine whether the visible-categories list is empty. + bool visible_categories_empty() const { + return visible_categories_begin() == visible_categories_end(); + } + +private: + /// \brief Test whether the given category... is a category. + /// + /// Used in the \c known_categories_iterator. + static bool isKnownCategory(ObjCCategoryDecl *) { return true; } + +public: + /// \brief Iterator that walks over all of the known categories and + /// extensions, including those that are hidden. + typedef filtered_category_iterator<isKnownCategory> known_categories_iterator; + + /// \brief Retrieve an iterator to the beginning of the known-categories + /// list. + known_categories_iterator known_categories_begin() const { + return known_categories_iterator(getCategoryListRaw()); + } + + /// \brief Retrieve an iterator to the end of the known-categories list. + known_categories_iterator known_categories_end() const { + return known_categories_iterator(); + } + + /// \brief Determine whether the known-categories list is empty. + bool known_categories_empty() const { + return known_categories_begin() == known_categories_end(); + } + +private: + /// \brief Test whether the given category is a visible extension. + /// + /// Used in the \c visible_extensions_iterator. + static bool isVisibleExtension(ObjCCategoryDecl *Cat); + +public: + /// \brief Iterator that walks over all of the visible extensions, skipping + /// any that are known but hidden. + typedef filtered_category_iterator<isVisibleExtension> + visible_extensions_iterator; + + /// \brief Retrieve an iterator to the beginning of the visible-extensions + /// list. + visible_extensions_iterator visible_extensions_begin() const { + return visible_extensions_iterator(getCategoryListRaw()); + } + + /// \brief Retrieve an iterator to the end of the visible-extensions list. + visible_extensions_iterator visible_extensions_end() const { + return visible_extensions_iterator(); + } + + /// \brief Determine whether the visible-extensions list is empty. + bool visible_extensions_empty() const { + return visible_extensions_begin() == visible_extensions_end(); + } + +private: + /// \brief Test whether the given category is an extension. + /// + /// Used in the \c known_extensions_iterator. + static bool isKnownExtension(ObjCCategoryDecl *Cat); + +public: + /// \brief Iterator that walks over all of the known extensions. + typedef filtered_category_iterator<isKnownExtension> + known_extensions_iterator; + + /// \brief Retrieve an iterator to the beginning of the known-extensions + /// list. + known_extensions_iterator known_extensions_begin() const { + return known_extensions_iterator(getCategoryListRaw()); + } + + /// \brief Retrieve an iterator to the end of the known-extensions list. + known_extensions_iterator known_extensions_end() const { + return known_extensions_iterator(); + } + + /// \brief Determine whether the known-extensions list is empty. + bool known_extensions_empty() const { + return known_extensions_begin() == known_extensions_end(); + } + + /// \brief Retrieve the raw pointer to the start of the category/extension + /// list. + ObjCCategoryDecl* getCategoryListRaw() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return 0; @@ -898,16 +1092,17 @@ public: return data().CategoryList; } - void setCategoryList(ObjCCategoryDecl *category) { + /// \brief Set the raw pointer to the start of the category/extension + /// list. + void setCategoryListRaw(ObjCCategoryDecl *category) { data().CategoryList = category; } - ObjCCategoryDecl* getFirstClassExtension() const; - ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; - virtual void collectPropertiesToImplement(PropertyMap &PM) const; + virtual void collectPropertiesToImplement(PropertyMap &PM, + PropertyDeclOrder &PO) const; /// isSuperClassOf - Return true if this class is the specified class or is a /// super class of the specified interface class. @@ -924,28 +1119,12 @@ public: /// isArcWeakrefUnavailable - Checks for a class or one of its super classes /// to be incompatible with __weak references. Returns true if it is. - bool isArcWeakrefUnavailable() const { - const ObjCInterfaceDecl *Class = this; - while (Class) { - if (Class->hasAttr<ArcWeakrefUnavailableAttr>()) - return true; - Class = Class->getSuperClass(); - } - return false; - } + bool isArcWeakrefUnavailable() const; /// isObjCRequiresPropertyDefs - Checks that a class or one of its super /// classes must not be auto-synthesized. Returns class decl. if it must not /// be; 0, otherwise. - const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const { - const ObjCInterfaceDecl *Class = this; - while (Class) { - if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>()) - return Class; - Class = Class->getSuperClass(); - } - return 0; - } + const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const; ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared); @@ -992,7 +1171,7 @@ public: /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation /// declaration without an \@interface declaration. bool isImplicitInterfaceDecl() const { - return hasDefinition() ? Data->Definition->isImplicit() : isImplicit(); + return hasDefinition() ? data().Definition->isImplicit() : isImplicit(); } /// ClassImplementsProtocol - Checks that 'lProto' protocol @@ -1169,12 +1348,17 @@ class ObjCProtocolDecl : public ObjCContainerDecl, /// \brief Referenced protocols ObjCProtocolList ReferencedProtocols; }; - - DefinitionData *Data; + + /// \brief Contains a pointer to the data associated with this class, + /// which will be NULL if this class has not yet been defined. + /// + /// The bit indicates when we don't need to check for out-of-date + /// declarations. It will be set unless modules are enabled. + llvm::PointerIntPair<DefinitionData *, 1, bool> Data; DefinitionData &data() const { - assert(Data && "Objective-C protocol has no definition!"); - return *Data; + assert(Data.getPointer() && "Objective-C protocol has no definition!"); + return *Data.getPointer(); } ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, @@ -1193,7 +1377,7 @@ class ObjCProtocolDecl : public ObjCContainerDecl, virtual ObjCProtocolDecl *getMostRecentDeclImpl() { return getMostRecentDecl(); } - + public: static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, @@ -1244,7 +1428,7 @@ public: /// implements. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, const SourceLocation *Locs, ASTContext &C) { - assert(Data && "Protocol is not defined"); + assert(hasDefinition() && "Protocol is not defined"); data().ReferencedProtocols.set(List, Num, Locs, C); } @@ -1261,16 +1445,30 @@ public: } /// \brief Determine whether this protocol has a definition. - bool hasDefinition() const { return Data != 0; } + bool hasDefinition() const { + // If the name of this protocol is out-of-date, bring it up-to-date, which + // might bring in a definition. + // Note: a null value indicates that we don't have a definition and that + // modules are enabled. + if (!Data.getOpaqueValue()) { + if (IdentifierInfo *II = getIdentifier()) { + if (II->isOutOfDate()) { + updateOutOfDate(*II); + } + } + } + + return Data.getPointer(); + } /// \brief Retrieve the definition of this protocol, if any. ObjCProtocolDecl *getDefinition() { - return Data? Data->Definition : 0; + return hasDefinition()? Data.getPointer()->Definition : 0; } /// \brief Retrieve the definition of this protocol, if any. const ObjCProtocolDecl *getDefinition() const { - return Data? Data->Definition : 0; + return hasDefinition()? Data.getPointer()->Definition : 0; } /// \brief Determine whether this particular declaration is also the @@ -1303,7 +1501,8 @@ public: return getFirstDeclaration(); } - virtual void collectPropertiesToImplement(PropertyMap &PM) const; + virtual void collectPropertiesToImplement(PropertyMap &PM, + PropertyDeclOrder &PO) const; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCProtocol; } @@ -1360,6 +1559,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl { CategoryNameLoc(CategoryNameLoc), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { } + public: static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, @@ -1403,8 +1603,13 @@ public: ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } + /// \brief Retrieve the pointer to the next stored category (or extension), + /// which may be hidden. + ObjCCategoryDecl *getNextClassCategoryRaw() const { + return NextClassCategory; + } + bool IsClassExtension() const { return getIdentifier() == 0; } - const ObjCCategoryDecl *getNextClassExtension() const; typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; ivar_iterator ivar_begin() const { @@ -1847,7 +2052,7 @@ public: PropertyAttributesAsWritten = PRVal; } - void makeitReadWriteAttribute(void) { + void makeitReadWriteAttribute() { PropertyAttributes &= ~OBJC_PR_readonly; PropertyAttributes |= OBJC_PR_readwrite; } @@ -2039,5 +2244,33 @@ public: friend class ASTDeclReader; }; +template<bool (*Filter)(ObjCCategoryDecl *)> +void +ObjCInterfaceDecl::filtered_category_iterator<Filter>:: +findAcceptableCategory() { + while (Current && !Filter(Current)) + Current = Current->getNextClassCategoryRaw(); +} + +template<bool (*Filter)(ObjCCategoryDecl *)> +inline ObjCInterfaceDecl::filtered_category_iterator<Filter> & +ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() { + Current = Current->getNextClassCategoryRaw(); + findAcceptableCategory(); + return *this; +} + +inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) { + return !Cat->isHidden(); +} + +inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) { + return Cat->IsClassExtension() && !Cat->isHidden(); +} + +inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) { + return Cat->IsClassExtension(); +} + } // end namespace clang #endif diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h new file mode 100644 index 0000000..ca92040 --- /dev/null +++ b/include/clang/AST/DeclOpenMP.h @@ -0,0 +1,83 @@ +//===--- OpenMP.h - Classes for representing OpenMP directives ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file defines OpenMP nodes. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_OPENMP_H +#define LLVM_CLANG_AST_OPENMP_H + +#include "clang/AST/DeclBase.h" +#include "llvm/ADT/ArrayRef.h" + +namespace clang { + +class DeclRefExpr; + +/// \brief This represents '#pragma omp threadprivate ...' directive. +/// For example, in the following, both 'a' and 'A::b' are threadprivate: +/// +/// \code +/// int a; +/// #pragma omp threadprivate(a) +/// struct A { +/// static int b; +/// #pragma omp threadprivate(b) +/// }; +/// \endcode +/// +class OMPThreadPrivateDecl : public Decl { + friend class ASTDeclReader; + unsigned NumVars; + + virtual void anchor(); + + OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) : + Decl(DK, DC, L), NumVars(0) { } + + ArrayRef<const DeclRefExpr *> getVars() const { + return ArrayRef<const DeclRefExpr *>( + reinterpret_cast<const DeclRefExpr * const *>(this + 1), + NumVars); + } + + llvm::MutableArrayRef<DeclRefExpr *> getVars() { + return llvm::MutableArrayRef<DeclRefExpr *>( + reinterpret_cast<DeclRefExpr **>(this + 1), + NumVars); + } + + void setVars(ArrayRef<DeclRefExpr *> VL); + +public: + static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + ArrayRef<DeclRefExpr *> VL); + static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, + unsigned ID, unsigned N); + + typedef llvm::MutableArrayRef<DeclRefExpr *>::iterator varlist_iterator; + typedef ArrayRef<const DeclRefExpr *>::iterator varlist_const_iterator; + + unsigned varlist_size() const { return NumVars; } + bool varlist_empty() const { return NumVars == 0; } + varlist_iterator varlist_begin() { return getVars().begin(); } + varlist_iterator varlist_end() { return getVars().end(); } + varlist_const_iterator varlist_begin() const { return getVars().begin(); } + varlist_const_iterator varlist_end() const { return getVars().end(); } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPThreadPrivate; } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 8620116..425a617 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -84,6 +84,13 @@ public: unsigned size() const { return NumParams; } + llvm::ArrayRef<NamedDecl*> asArray() { + return llvm::ArrayRef<NamedDecl*>(begin(), size()); + } + llvm::ArrayRef<const NamedDecl*> asArray() const { + return llvm::ArrayRef<const NamedDecl*>(begin(), size()); + } + NamedDecl* getParam(unsigned Idx) { assert(Idx < size() && "Template parameter index out-of-range"); return begin()[Idx]; @@ -193,6 +200,11 @@ public: /// \brief Retrieve the template argument at a given index. const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); } + /// \brief Produce this as an array ref. + llvm::ArrayRef<TemplateArgument> asArray() const { + return llvm::ArrayRef<TemplateArgument>(data(), size()); + } + /// \brief Retrieve the number of template arguments in this /// template argument list. unsigned size() const { return NumArguments; } @@ -324,6 +336,23 @@ public: return getTemplateSpecializationKind() == TSK_ExplicitSpecialization; } + /// \brief True if this declaration is an explicit specialization, + /// explicit instantiation declaration, or explicit instantiation + /// definition. + bool isExplicitInstantiationOrSpecialization() const { + switch (getTemplateSpecializationKind()) { + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return true; + + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + return false; + } + llvm_unreachable("bad template specialization kind"); + } + /// \brief Set the template specialization kind. void setTemplateSpecializationKind(TemplateSpecializationKind TSK) { assert(TSK != TSK_Undeclared && @@ -390,6 +419,10 @@ public: return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1); } + bool isExplicitSpecialization() const { + return getTemplateSpecializationKind() == TSK_ExplicitSpecialization; + } + /// \brief Set the template specialization kind. void setTemplateSpecializationKind(TemplateSpecializationKind TSK) { assert(TSK != TSK_Undeclared && @@ -425,18 +458,19 @@ public: /// }; /// \endcode class DependentFunctionTemplateSpecializationInfo { + struct CA { + /// The number of potential template candidates. + unsigned NumTemplates; + + /// The number of template arguments. + unsigned NumArgs; + }; + union { // Force sizeof to be a multiple of sizeof(void*) so that the // trailing data is aligned. void *Aligner; - - struct { - /// The number of potential template candidates. - unsigned NumTemplates; - - /// The number of template arguments. - unsigned NumArgs; - } d; + struct CA d; }; /// The locations of the left and right angle brackets. @@ -552,7 +586,7 @@ protected: }; template <typename EntryType> - SpecIterator<EntryType> + static SpecIterator<EntryType> makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) { return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin()); } @@ -576,14 +610,14 @@ protected: /// \brief Pointer to the common data shared by all declarations of this /// template. - CommonBase *Common; + mutable CommonBase *Common; /// \brief Retrieves the "common" pointer shared by all (re-)declarations of /// the same template. Calling this routine may implicitly allocate memory /// for the common pointer. - CommonBase *getCommonPtr(); + CommonBase *getCommonPtr() const; - virtual CommonBase *newCommon(ASTContext &C) = 0; + virtual CommonBase *newCommon(ASTContext &C) const = 0; // Construct a template decl with name, parameters, and templated element. RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -618,7 +652,7 @@ public: /// template<> template<typename T> /// struct X<int>::Inner { /* ... */ }; /// \endcode - bool isMemberSpecialization() { + bool isMemberSpecialization() const { return getCommonPtr()->InstantiatedFromMember.getInt(); } @@ -665,7 +699,7 @@ public: /// template<typename U> /// void X<T>::f(T, U); /// \endcode - RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() { + RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const { return getCommonPtr()->InstantiatedFromMember.getPointer(); } @@ -729,9 +763,9 @@ protected: TemplateParameterList *Params, NamedDecl *Decl) : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { } - CommonBase *newCommon(ASTContext &C); + CommonBase *newCommon(ASTContext &C) const; - Common *getCommonPtr() { + Common *getCommonPtr() const { return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); } @@ -740,7 +774,7 @@ protected: /// \brief Retrieve the set of function template specializations of this /// function template. llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & - getSpecializations() { + getSpecializations() const { return getCommonPtr()->Specializations; } @@ -798,11 +832,11 @@ public: typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator; - spec_iterator spec_begin() { + spec_iterator spec_begin() const { return makeSpecIterator(getSpecializations(), false); } - spec_iterator spec_end() { + spec_iterator spec_end() const { return makeSpecIterator(getSpecializations(), true); } @@ -1205,7 +1239,7 @@ public: unsigned P, IdentifierInfo *Id, TemplateParameterList *Params, - llvm::ArrayRef<TemplateParameterList*> Expansions); + ArrayRef<TemplateParameterList *> Expansions); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1399,7 +1433,7 @@ public: static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID); - virtual void getNameForDiagnostic(std::string &S, + virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const; @@ -1433,6 +1467,23 @@ public: return getSpecializationKind() == TSK_ExplicitSpecialization; } + /// \brief True if this declaration is an explicit specialization, + /// explicit instantiation declaration, or explicit instantiation + /// definition. + bool isExplicitInstantiationOrSpecialization() const { + switch (getTemplateSpecializationKind()) { + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return true; + + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + return false; + } + llvm_unreachable("bad template specialization kind"); + } + void setSpecializationKind(TemplateSpecializationKind TSK) { SpecializationKind = TSK; } @@ -1464,8 +1515,7 @@ public: = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) return PartialSpec->PartialSpecialization; - return const_cast<ClassTemplateDecl*>( - SpecializedTemplate.get<ClassTemplateDecl*>()); + return SpecializedTemplate.get<ClassTemplateDecl*>(); } /// \brief Retrieve the class template or class template partial @@ -1477,8 +1527,7 @@ public: = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) return PartialSpec->PartialSpecialization; - return const_cast<ClassTemplateDecl*>( - SpecializedTemplate.get<ClassTemplateDecl*>()); + return SpecializedTemplate.get<ClassTemplateDecl*>(); } /// \brief Retrieve the set of template arguments that should be used @@ -1780,10 +1829,11 @@ protected: }; /// \brief Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations(); + void LoadLazySpecializations() const; /// \brief Retrieve the set of specializations of this class template. - llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &getSpecializations(); + llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & + getSpecializations() const; /// \brief Retrieve the set of partial specializations of this class /// template. @@ -1798,9 +1848,9 @@ protected: : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(), DeclarationName(), 0, 0) { } - CommonBase *newCommon(ASTContext &C); + CommonBase *newCommon(ASTContext &C) const; - Common *getCommonPtr() { + Common *getCommonPtr() const { return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); } @@ -1925,11 +1975,11 @@ public: typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator; - spec_iterator spec_begin() { + spec_iterator spec_begin() const { return makeSpecIterator(getSpecializations(), false); } - spec_iterator spec_end() { + spec_iterator spec_end() const { return makeSpecIterator(getSpecializations(), true); } @@ -2063,7 +2113,7 @@ protected: TemplateParameterList *Params, NamedDecl *Decl) : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { } - CommonBase *newCommon(ASTContext &C); + CommonBase *newCommon(ASTContext &C) const; Common *getCommonPtr() { return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h index 62654b8..4eaae35 100644 --- a/include/clang/AST/DeclVisitor.h +++ b/include/clang/AST/DeclVisitor.h @@ -14,21 +14,28 @@ #define LLVM_CLANG_AST_DECLVISITOR_H #include "clang/AST/Decl.h" -#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" namespace clang { +namespace declvisitor { -#define DISPATCH(NAME, CLASS) \ - return static_cast<ImplClass*>(this)-> Visit##NAME(static_cast<CLASS*>(D)) +template <typename T> struct make_ptr { typedef T *type; }; +template <typename T> struct make_const_ptr { typedef const T *type; }; /// \brief A simple visitor class that helps create declaration visitors. -template<typename ImplClass, typename RetTy=void> -class DeclVisitor { +template<template <typename> class Ptr, typename ImplClass, typename RetTy=void> +class Base { public: - RetTy Visit(Decl *D) { + +#define PTR(CLASS) typename Ptr<CLASS>::type +#define DISPATCH(NAME, CLASS) \ + return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D)) + + RetTy Visit(PTR(Decl) D) { switch (D->getKind()) { #define DECL(DERIVED, BASE) \ case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl); @@ -41,13 +48,31 @@ public: // If the implementation chooses not to implement a certain visit // method, fall back to the parent. #define DECL(DERIVED, BASE) \ - RetTy Visit##DERIVED##Decl(DERIVED##Decl *D) { DISPATCH(BASE, BASE); } + RetTy Visit##DERIVED##Decl(PTR(DERIVED##Decl) D) { DISPATCH(BASE, BASE); } #include "clang/AST/DeclNodes.inc" - RetTy VisitDecl(Decl *D) { return RetTy(); } -}; + RetTy VisitDecl(PTR(Decl) D) { return RetTy(); } +#undef PTR #undef DISPATCH +}; + +} // end namespace declvisitor + +/// \brief A simple visitor class that helps create declaration visitors. +/// +/// This class does not preserve constness of Decl pointers (see also +/// ConstDeclVisitor). +template<typename ImplClass, typename RetTy=void> +class DeclVisitor + : public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {}; + +/// \brief A simple visitor class that helps create declaration visitors. +/// +/// This class preserves constness of Decl pointers (see also DeclVisitor). +template<typename ImplClass, typename RetTy=void> +class ConstDeclVisitor + : public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {}; } // end namespace clang diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index d991c73..f28882b 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -14,8 +14,6 @@ #define LLVM_CLANG_AST_DECLARATIONNAME_H #include "clang/Basic/IdentifierTable.h" -#include "clang/AST/Type.h" -#include "clang/AST/CanonicalType.h" #include "clang/Basic/PartialDiagnostic.h" #include "llvm/Support/Compiler.h" @@ -24,14 +22,20 @@ namespace llvm { } namespace clang { - class CXXSpecialName; - class CXXOperatorIdName; + class ASTContext; class CXXLiteralOperatorIdName; + class CXXOperatorIdName; + class CXXSpecialName; class DeclarationNameExtra; class IdentifierInfo; class MultiKeywordSelector; - class UsingDirectiveDecl; + class QualType; + class Type; class TypeSourceInfo; + class UsingDirectiveDecl; + + template <typename> class CanQual; + typedef CanQual<Type> CanQualType; /// DeclarationName - The name of a declaration. In the common case, /// this just stores an IdentifierInfo pointer to a normal @@ -349,23 +353,15 @@ public: /// getCXXConstructorName - Returns the name of a C++ constructor /// for the given Type. - DeclarationName getCXXConstructorName(CanQualType Ty) { - return getCXXSpecialName(DeclarationName::CXXConstructorName, - Ty.getUnqualifiedType()); - } + DeclarationName getCXXConstructorName(CanQualType Ty); /// getCXXDestructorName - Returns the name of a C++ destructor /// for the given Type. - DeclarationName getCXXDestructorName(CanQualType Ty) { - return getCXXSpecialName(DeclarationName::CXXDestructorName, - Ty.getUnqualifiedType()); - } + DeclarationName getCXXDestructorName(CanQualType Ty); /// getCXXConversionFunctionName - Returns the name of a C++ /// conversion function for the given Type. - DeclarationName getCXXConversionFunctionName(CanQualType Ty) { - return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty); - } + DeclarationName getCXXConversionFunctionName(CanQualType Ty); /// getCXXSpecialName - Returns a declaration name for special kind /// of C++ name, e.g., for a constructor, destructor, or conversion @@ -386,32 +382,35 @@ public: /// for a declaration name. Needs a DeclarationName in order /// to be interpreted correctly. struct DeclarationNameLoc { + // The source location for identifier stored elsewhere. + // struct {} Identifier; + + // Type info for constructors, destructors and conversion functions. + // Locations (if any) for the tilde (destructor) or operator keyword + // (conversion) are stored elsewhere. + struct NT { + TypeSourceInfo* TInfo; + }; + + // The location (if any) of the operator keyword is stored elsewhere. + struct CXXOpName { + unsigned BeginOpNameLoc; + unsigned EndOpNameLoc; + }; + + // The location (if any) of the operator keyword is stored elsewhere. + struct CXXLitOpName { + unsigned OpNameLoc; + }; + + // struct {} CXXUsingDirective; + // struct {} ObjCZeroArgSelector; + // struct {} ObjCOneArgSelector; + // struct {} ObjCMultiArgSelector; union { - // The source location for identifier stored elsewhere. - // struct {} Identifier; - - // Type info for constructors, destructors and conversion functions. - // Locations (if any) for the tilde (destructor) or operator keyword - // (conversion) are stored elsewhere. - struct { - TypeSourceInfo* TInfo; - } NamedType; - - // The location (if any) of the operator keyword is stored elsewhere. - struct { - unsigned BeginOpNameLoc; - unsigned EndOpNameLoc; - } CXXOperatorName; - - // The location (if any) of the operator keyword is stored elsewhere. - struct { - unsigned OpNameLoc; - } CXXLiteralOperatorName; - - // struct {} CXXUsingDirective; - // struct {} ObjCZeroArgSelector; - // struct {} ObjCOneArgSelector; - // struct {} ObjCMultiArgSelector; + struct NT NamedType; + struct CXXOpName CXXOperatorName; + struct CXXLitOpName CXXLiteralOperatorName; }; DeclarationNameLoc(DeclarationName Name); @@ -525,9 +524,7 @@ public: SourceLocation getEndLoc() const; /// getSourceRange - The range of the declaration name. SourceRange getSourceRange() const LLVM_READONLY { - SourceLocation BeginLoc = getBeginLoc(); - SourceLocation EndLoc = getEndLoc(); - return SourceRange(BeginLoc, EndLoc.isValid() ? EndLoc : BeginLoc); + return SourceRange(getLocStart(), getLocEnd()); } SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h index 948dcb4..004b45d 100644 --- a/include/clang/AST/DependentDiagnostic.h +++ b/include/clang/AST/DependentDiagnostic.h @@ -18,11 +18,11 @@ #ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H #define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H -#include "clang/Basic/PartialDiagnostic.h" -#include "clang/Basic/SourceLocation.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclContextInternals.h" #include "clang/AST/Type.h" +#include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" namespace clang { @@ -108,16 +108,14 @@ private: PartialDiagnostic Diag; - union { - struct { - unsigned Loc; - unsigned Access : 2; - unsigned IsMember : 1; - NamedDecl *TargetDecl; - CXXRecordDecl *NamingClass; - void *BaseObjectType; - } AccessData; - }; + struct { + unsigned Loc; + unsigned Access : 2; + unsigned IsMember : 1; + NamedDecl *TargetDecl; + CXXRecordDecl *NamingClass; + void *BaseObjectType; + } AccessData; }; /// diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h index d5e9c8c..eb186c2 100644 --- a/include/clang/AST/EvaluatedExprVisitor.h +++ b/include/clang/AST/EvaluatedExprVisitor.h @@ -15,10 +15,10 @@ #ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H #define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H -#include "clang/AST/StmtVisitor.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/StmtVisitor.h" namespace clang { @@ -49,6 +49,9 @@ public: } void VisitChooseExpr(ChooseExpr *E) { + // Don't visit either child expression if the condition is dependent. + if (E->getCond()->isValueDependent()) + return; // Only the selected subexpression matters; the other one is not evaluated. return this->Visit(E->getChosenSubExpr(Context)); } @@ -58,17 +61,17 @@ public: // expressions. return this->Visit(E->getInit()); } - + void VisitCXXTypeidExpr(CXXTypeidExpr *E) { - // typeid(expression) is potentially evaluated when the argument is - // a glvalue of polymorphic type. (C++ 5.2.8p2-3) - if (!E->isTypeOperand() && E->Classify(Context).isGLValue()) - if (const RecordType *Record - = E->getExprOperand()->getType()->template getAs<RecordType>()) - if (cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic()) - return this->Visit(E->getExprOperand()); + if (E->isPotentiallyEvaluated()) + return this->Visit(E->getExprOperand()); } - + + void VisitCallExpr(CallExpr *CE) { + if (!CE->isUnevaluatedBuiltinCall(Context)) + return static_cast<ImplClass*>(this)->VisitExpr(CE); + } + /// \brief The basis case walks all of the children of the statement or /// expression, assuming they are all potentially evaluated. void VisitStmt(Stmt *S) { diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index dc83654..36d70d8 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -15,38 +15,38 @@ #define LLVM_CLANG_AST_EXPR_H #include "clang/AST/APValue.h" +#include "clang/AST/ASTVector.h" #include "clang/AST/Decl.h" -#include "clang/AST/Stmt.h" -#include "clang/AST/Type.h" #include "clang/AST/DeclAccessPair.h" #include "clang/AST/OperationKinds.h" -#include "clang/AST/ASTVector.h" +#include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" -#include "clang/Basic/TargetInfo.h" +#include "clang/AST/Type.h" +#include "clang/Basic/CharInfo.h" #include "clang/Basic/TypeTraits.h" -#include "llvm/ADT/APSInt.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" -#include <cctype> namespace clang { - class ASTContext; class APValue; - class CastExpr; - class Decl; - class IdentifierInfo; - class ParmVarDecl; - class NamedDecl; - class ValueDecl; + class ASTContext; class BlockDecl; class CXXBaseSpecifier; + class CXXMemberCallExpr; class CXXOperatorCallExpr; + class CastExpr; + class Decl; + class IdentifierInfo; class MaterializeTemporaryExpr; - class CXXMemberCallExpr; + class NamedDecl; class ObjCPropertyRefExpr; class OpaqueValueExpr; + class ParmVarDecl; + class TargetInfo; + class ValueDecl; /// \brief A simple array of base specifiers. typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; @@ -60,18 +60,21 @@ struct SubobjectAdjustment { MemberPointerAdjustment } Kind; - union { - struct { - const CastExpr *BasePath; - const CXXRecordDecl *DerivedClass; - } DerivedToBase; - FieldDecl *Field; + struct DTB { + const CastExpr *BasePath; + const CXXRecordDecl *DerivedClass; + }; - struct { - const MemberPointerType *MPT; - Expr *RHS; - } Ptr; + struct P { + const MemberPointerType *MPT; + Expr *RHS; + }; + + union { + struct DTB DerivedToBase; + FieldDecl *Field; + struct P Ptr; }; SubobjectAdjustment(const CastExpr *BasePath, @@ -196,7 +199,7 @@ public: } /// \brief Whether this expression contains an unexpanded parameter - /// pack (for C++0x variadic templates). + /// pack (for C++11 variadic templates). /// /// Given the following function template: /// @@ -238,7 +241,7 @@ public: /// result of an r-value expression is a value detached from any /// specific storage. /// - /// C++0x divides the concept of "r-value" into pure r-values + /// C++11 divides the concept of "r-value" into pure r-values /// ("pr-values") and so-called expiring values ("x-values"), which /// identify specific objects that can be safely cannibalized for /// their resources. This is an unfortunate abuse of terminology on @@ -294,7 +297,7 @@ public: isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = 0) const; - /// \brief The return type of classify(). Represents the C++0x expression + /// \brief The return type of classify(). Represents the C++11 expression /// taxonomy. class Classification { public: @@ -357,10 +360,10 @@ public: } }; - /// \brief Classify - Classify this expression according to the C++0x + /// \brief Classify - Classify this expression according to the C++11 /// expression taxonomy. /// - /// C++0x defines ([basic.lval]) a new taxonomy of expressions to replace the + /// C++11 defines ([basic.lval]) a new taxonomy of expressions to replace the /// old lvalue vs rvalue. This function determines the type of expression this /// is. There are three expression types: /// - lvalues are classical lvalues as in C++03. @@ -374,7 +377,7 @@ public: } /// \brief ClassifyModifiable - Classify this expression according to the - /// C++0x expression taxonomy, and see if it is valid on the left side + /// C++11 expression taxonomy, and see if it is valid on the left side /// of an assignment. /// /// This function extends classify in that it also tests whether the @@ -490,7 +493,7 @@ public: /// constexpr. Return false if the function can never produce a constant /// expression, along with diagnostics describing why not. static bool isPotentialConstantExpr(const FunctionDecl *FD, - llvm::SmallVectorImpl< + SmallVectorImpl< PartialDiagnosticAt> &Diags); /// isConstantInitializer - Returns true if this expression can be emitted to @@ -510,7 +513,7 @@ public: /// foldable. If the expression is foldable, but not a constant expression, /// the notes will describes why it isn't a constant expression. If the /// expression *is* a constant expression, no notes will be produced. - llvm::SmallVectorImpl<PartialDiagnosticAt> *Diag; + SmallVectorImpl<PartialDiagnosticAt> *Diag; EvalStatus() : HasSideEffects(false), Diag(0) {} @@ -568,7 +571,11 @@ public: /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded /// integer. This must be called on an expression that constant folds to an /// integer. - llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const; + llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, + SmallVectorImpl<PartialDiagnosticAt> *Diag=0) const; + + void EvaluateForOverflow(const ASTContext &Ctx, + SmallVectorImpl<PartialDiagnosticAt> *Diag) const; /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an /// lvalue with link time known address, with no side-effects. @@ -580,7 +587,7 @@ public: /// notes will be produced if the expression is not a constant expression. bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, - llvm::SmallVectorImpl<PartialDiagnosticAt> &Notes) const; + SmallVectorImpl<PartialDiagnosticAt> &Notes) const; /// \brief Enumeration used to describe the kind of Null pointer constant /// returned from \c isNullPointerConstant(). @@ -598,8 +605,8 @@ public: /// \brief Expression is a Null pointer constant built from a literal zero. NPCK_ZeroLiteral, - /// \brief Expression is a C++0X nullptr. - NPCK_CXX0X_nullptr, + /// \brief Expression is a C++11 nullptr. + NPCK_CXX11_nullptr, /// \brief Expression is a GNU-style __null constant. NPCK_GNUNull @@ -728,7 +735,7 @@ public: return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx); } - static bool hasAnyTypeDependentArguments(llvm::ArrayRef<Expr *> Exprs); + static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs); /// \brief For an expression of class type or pointer to class type, /// return the most derived class decl the expression is known to refer to. @@ -796,9 +803,11 @@ public: /// \brief Retrieve the location of this expression. SourceLocation getLocation() const { return Loc; } - SourceRange getSourceRange() const LLVM_READONLY { - if (SourceExpr) return SourceExpr->getSourceRange(); - return Loc; + SourceLocation getLocStart() const LLVM_READONLY { + return SourceExpr ? SourceExpr->getLocStart() : Loc; + } + SourceLocation getLocEnd() const LLVM_READONLY { + return SourceExpr ? SourceExpr->getLocEnd() : Loc; } SourceLocation getExprLoc() const LLVM_READONLY { if (SourceExpr) return SourceExpr->getExprLoc(); @@ -954,7 +963,6 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - SourceRange getSourceRange() const LLVM_READONLY; SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; @@ -1160,7 +1168,8 @@ public: static std::string ComputeName(IdentType IT, const Decl *CurrentDecl); - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } static bool classof(const Stmt *T) { return T->getStmtClass() == PredefinedExprClass; @@ -1211,8 +1220,8 @@ public: class APFloatStorage : private APNumericStorage { public: - llvm::APFloat getValue(bool IsIEEE) const { - return llvm::APFloat(getIntValue(), IsIEEE); + llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const { + return llvm::APFloat(Semantics, getIntValue()); } void setValue(ASTContext &C, const llvm::APFloat &Val) { setIntValue(C, Val.bitcastToAPInt()); @@ -1241,7 +1250,8 @@ public: /// \brief Returns a new empty integer literal. static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty); - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } /// \brief Retrieve the location of the literal. SourceLocation getLocation() const { return Loc; } @@ -1286,7 +1296,8 @@ public: return static_cast<CharacterKind>(CharacterLiteralBits.Kind); } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } unsigned getValue() const { return Value; } @@ -1317,12 +1328,31 @@ public: static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty); llvm::APFloat getValue() const { - return APFloatStorage::getValue(FloatingLiteralBits.IsIEEE); + return APFloatStorage::getValue(getSemantics()); } void setValue(ASTContext &C, const llvm::APFloat &Val) { + assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics"); APFloatStorage::setValue(C, Val); } + /// Get a raw enumeration value representing the floating-point semantics of + /// this literal (32-bit IEEE, x87, ...), suitable for serialisation. + APFloatSemantics getRawSemantics() const { + return static_cast<APFloatSemantics>(FloatingLiteralBits.Semantics); + } + + /// Set the raw enumeration value representing the floating-point semantics of + /// this literal (32-bit IEEE, x87, ...), suitable for serialisation. + void setRawSemantics(APFloatSemantics Sem) { + FloatingLiteralBits.Semantics = Sem; + } + + /// Return the APFloat semantics this literal uses. + const llvm::fltSemantics &getSemantics() const; + + /// Set the APFloat semantics this literal uses. + void setSemantics(const llvm::fltSemantics &Sem); + bool isExact() const { return FloatingLiteralBits.IsExact; } void setExact(bool E) { FloatingLiteralBits.IsExact = E; } @@ -1334,7 +1364,8 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } static bool classof(const Stmt *T) { return T->getStmtClass() == FloatingLiteralClass; @@ -1365,7 +1396,9 @@ public: Expr *getSubExpr() { return cast<Expr>(Val); } void setSubExpr(Expr *E) { Val = E; } - SourceRange getSourceRange() const LLVM_READONLY { return Val->getSourceRange(); } + SourceLocation getLocStart() const LLVM_READONLY { return Val->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Val->getLocEnd(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == ImaginaryLiteralClass; } @@ -1458,7 +1491,7 @@ public: getByteLength()); } - void outputString(raw_ostream &OS); + void outputString(raw_ostream &OS) const; uint32_t getCodeUnit(size_t i) const { assert(i < Length && "out of bounds access"); @@ -1491,7 +1524,7 @@ public: bool containsNonAsciiOrNull() const { StringRef Str = getString(); for (unsigned i = 0, e = Str.size(); i != e; ++i) - if (!isascii(Str[i]) || !Str[i]) + if (!isASCII(Str[i]) || !Str[i]) return true; return false; } @@ -1524,9 +1557,11 @@ public: tokloc_iterator tokloc_begin() const { return TokLocs; } tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(TokLocs[0], TokLocs[NumConcatenated-1]); + SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; } + SourceLocation getLocEnd() const LLVM_READONLY { + return TokLocs[NumConcatenated - 1]; } + static bool classof(const Stmt *T) { return T->getStmtClass() == StringLiteralClass; } @@ -1557,7 +1592,8 @@ public: Expr *getSubExpr() { return cast<Expr>(Val); } void setSubExpr(Expr *E) { Val = E; } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(L, R); } + SourceLocation getLocStart() const LLVM_READONLY { return L; } + SourceLocation getLocEnd() const LLVM_READONLY { return R; } /// \brief Get the location of the left parentheses '('. SourceLocation getLParen() const { return L; } @@ -1669,11 +1705,11 @@ public: /// the given unary opcode. static OverloadedOperatorKind getOverloadedOperator(Opcode Opc); - SourceRange getSourceRange() const LLVM_READONLY { - if (isPostfix()) - return SourceRange(Val->getLocStart(), Loc); - else - return SourceRange(Loc, Val->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { + return isPostfix() ? Val->getLocStart() : Loc; + } + SourceLocation getLocEnd() const LLVM_READONLY { + return isPostfix() ? Loc : Val->getLocEnd(); } SourceLocation getExprLoc() const LLVM_READONLY { return Loc; } @@ -1791,6 +1827,8 @@ public: /// contains the location of the period (if there is one) and the /// identifier. SourceRange getSourceRange() const LLVM_READONLY { return Range; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } }; private: @@ -1870,9 +1908,8 @@ public: return NumExprs; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(OperatorLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == OffsetOfExprClass; @@ -1974,9 +2011,8 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(OpLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return OpLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryExprOrTypeTraitExprClass; @@ -2048,14 +2084,17 @@ public: return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS()); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getLHS()->getLocStart(), RBracketLoc); + SourceLocation getLocStart() const LLVM_READONLY { + return getLHS()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; } SourceLocation getRBracketLoc() const { return RBracketLoc; } void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } - SourceLocation getExprLoc() const LLVM_READONLY { return getBase()->getExprLoc(); } + SourceLocation getExprLoc() const LLVM_READONLY { + return getBase()->getExprLoc(); + } static bool classof(const Stmt *T) { return T->getStmtClass() == ArraySubscriptExprClass; @@ -2171,6 +2210,15 @@ public: return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs(); } + /// This method provides fast access to all the subexpressions of + /// a CallExpr without going through the slower virtual child_iterator + /// interface. This provides efficient reverse iteration of the + /// subexpressions. This is currently used for CFG construction. + ArrayRef<Stmt*> getRawSubExprs() { + return ArrayRef<Stmt*>(SubExprs, + getNumPreArgs() + PREARGS_START + getNumArgs()); + } + /// getNumCommas - Return the number of commas that must have been present in /// this function call. unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; } @@ -2179,6 +2227,10 @@ public: /// not, return 0. unsigned isBuiltinCall() const; + /// \brief Returns \c true if this is a call to a builtin which does not + /// evaluate side-effects within its arguments. + bool isUnevaluatedBuiltinCall(ASTContext &Ctx) const; + /// getCallReturnType - Get the return type of the call expr. This is not /// always the type of the expr itself, if the return type is a reference /// type. @@ -2187,7 +2239,6 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY; SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; @@ -2455,7 +2506,6 @@ public: SourceLocation getMemberLoc() const { return MemberLoc; } void setMemberLoc(SourceLocation L) { MemberLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY; SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; @@ -2534,13 +2584,19 @@ public: TInfoAndScope.setPointer(tinfo); } - SourceRange getSourceRange() const LLVM_READONLY { + SourceLocation getLocStart() const LLVM_READONLY { // FIXME: Init should never be null. if (!Init) - return SourceRange(); + return SourceLocation(); if (LParenLoc.isInvalid()) - return Init->getSourceRange(); - return SourceRange(LParenLoc, Init->getLocEnd()); + return Init->getLocStart(); + return LParenLoc; + } + SourceLocation getLocEnd() const LLVM_READONLY { + // FIXME: Init should never be null. + if (!Init) + return SourceLocation(); + return Init->getLocEnd(); } static bool classof(const Stmt *T) { @@ -2686,9 +2742,6 @@ public: static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); - SourceRange getSourceRange() const LLVM_READONLY { - return getSubExpr()->getSourceRange(); - } SourceLocation getLocStart() const LLVM_READONLY { return getSubExpr()->getLocStart(); } @@ -2787,9 +2840,11 @@ public: SourceLocation getRParenLoc() const { return RPLoc; } void setRParenLoc(SourceLocation L) { RPLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(LPLoc, getSubExpr()->getSourceRange().getEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return LPLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return getSubExpr()->getLocEnd(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == CStyleCastExprClass; } @@ -2845,7 +2900,7 @@ public: SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; assert(!isCompoundAssignmentOp() && - "Use ArithAssignBinaryOperator for compound assignments"); + "Use CompoundAssignOperator for compound assignments"); } /// \brief Construct an empty binary operator. @@ -2864,8 +2919,11 @@ public: Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); } void setRHS(Expr *E) { SubExprs[RHS] = E; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { + return getLHS()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getRHS()->getLocEnd(); } /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it @@ -2902,6 +2960,33 @@ public: static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; } bool isComparisonOp() const { return isComparisonOp(getOpcode()); } + static Opcode negateComparisonOp(Opcode Opc) { + switch (Opc) { + default: + llvm_unreachable("Not a comparsion operator."); + case BO_LT: return BO_GE; + case BO_GT: return BO_LE; + case BO_LE: return BO_GT; + case BO_GE: return BO_LT; + case BO_EQ: return BO_NE; + case BO_NE: return BO_EQ; + } + } + + static Opcode reverseComparisonOp(Opcode Opc) { + switch (Opc) { + default: + llvm_unreachable("Not a comparsion operator."); + case BO_LT: return BO_GT; + case BO_GT: return BO_LT; + case BO_LE: return BO_GE; + case BO_GE: return BO_LE; + case BO_EQ: + case BO_NE: + return Opc; + } + } + static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; } bool isLogicalOp() const { return isLogicalOp(getOpcode()); } @@ -3101,9 +3186,13 @@ public: Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); } Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { + return getCond()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getRHS()->getLocEnd(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == ConditionalOperatorClass; } @@ -3182,9 +3271,13 @@ public: return cast<Expr>(SubExprs[RHS]); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getCommon()->getLocStart(), getFalseExpr()->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { + return getCommon()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { + return getFalseExpr()->getLocEnd(); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == BinaryConditionalOperatorClass; } @@ -3233,9 +3326,8 @@ public: SourceLocation getLabelLoc() const { return LabelLoc; } void setLabelLoc(SourceLocation L) { LabelLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AmpAmpLoc, LabelLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return AmpAmpLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; } LabelDecl *getLabel() const { return Label; } void setLabel(LabelDecl *L) { Label = L; } @@ -3274,9 +3366,8 @@ public: const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); } void setSubStmt(CompoundStmt *S) { SubStmt = S; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(LParenLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } SourceLocation getLParenLoc() const { return LParenLoc; } void setLParenLoc(SourceLocation L) { LParenLoc = L; } @@ -3322,9 +3413,9 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(BuiltinLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == ShuffleVectorExprClass; } @@ -3416,9 +3507,9 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(BuiltinLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == ChooseExprClass; } @@ -3452,9 +3543,9 @@ public: SourceLocation getTokenLocation() const { return TokenLoc; } void setTokenLocation(SourceLocation L) { TokenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(TokenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return TokenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return TokenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == GNUNullExprClass; } @@ -3497,9 +3588,9 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(BuiltinLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == VAArgExprClass; } @@ -3580,8 +3671,8 @@ public: ArrayRef<Expr*> initExprs, SourceLocation rbraceloc); /// \brief Build an empty initializer list. - explicit InitListExpr(ASTContext &C, EmptyShell Empty) - : Expr(InitListExprClass, Empty), InitExprs(C) { } + explicit InitListExpr(EmptyShell Empty) + : Expr(InitListExprClass, Empty) { } unsigned getNumInits() const { return InitExprs.size(); } @@ -3698,7 +3789,8 @@ public: InitListExprBits.InitializesStdInitializerList = ISIL; } - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == InitListExprClass; @@ -3923,17 +4015,17 @@ public: return ArrayOrRange.Index; } - SourceLocation getStartLocation() const { + SourceLocation getLocStart() const LLVM_READONLY { if (Kind == FieldDesignator) return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc(); else return getLBracketLoc(); } - SourceLocation getEndLocation() const { + SourceLocation getLocEnd() const LLVM_READONLY { return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc(); } SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getStartLocation(), getEndLocation()); + return SourceRange(getLocStart(), getLocEnd()); } }; @@ -3984,9 +4076,9 @@ public: void setDesignators(ASTContext &C, const Designator *Desigs, unsigned NumDesigs); - Expr *getArrayIndex(const Designator& D); - Expr *getArrayRangeStart(const Designator& D); - Expr *getArrayRangeEnd(const Designator& D); + Expr *getArrayIndex(const Designator &D) const; + Expr *getArrayRangeStart(const Designator &D) const; + Expr *getArrayRangeEnd(const Designator &D) const; /// @brief Retrieve the location of the '=' that precedes the /// initializer value itself, if present. @@ -4034,7 +4126,8 @@ public: SourceRange getDesignatorsSourceRange() const; - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == DesignatedInitExprClass; @@ -4069,9 +4162,8 @@ public: return T->getStmtClass() == ImplicitValueInitExprClass; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(); - } + SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); } + SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } // Iterators child_range children() { return child_range(); } @@ -4107,9 +4199,9 @@ public: SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(LParenLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == ParenListExprClass; } @@ -4221,9 +4313,9 @@ public: const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); } Expr *getResultExpr() { return getAssocExpr(getResultIndex()); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(GenericLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return GenericLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == GenericSelectionExprClass; } @@ -4286,9 +4378,10 @@ public: /// aggregate Constant of ConstantInt(s). void getEncodedElementAccess(SmallVectorImpl<unsigned> &Elts) const; - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getBase()->getLocStart(), AccessorLoc); + SourceLocation getLocStart() const LLVM_READONLY { + return getBase()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return AccessorLoc; } /// isArrow - Return true if the base expression is a pointer to vector, /// return false if the base expression is a vector. @@ -4328,9 +4421,8 @@ public: const Stmt *getBody() const; Stmt *getBody(); - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getCaretLocation(), getBody()->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return getCaretLocation(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getBody()->getLocEnd(); } /// getFunctionType - Return the underlying function type for this block. const FunctionProtoType *getFunctionType() const; @@ -4377,9 +4469,8 @@ public: /// getRParenLoc - Return the location of final right parenthesis. SourceLocation getRParenLoc() const { return RParenLoc; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(BuiltinLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == AsTypeExprClass; @@ -4508,8 +4599,12 @@ public: SourceLocation getExprLoc() const LLVM_READONLY { return getSyntacticForm()->getExprLoc(); } - SourceRange getSourceRange() const LLVM_READONLY { - return getSyntacticForm()->getSourceRange(); + + SourceLocation getLocStart() const LLVM_READONLY { + return getSyntacticForm()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getSyntacticForm()->getLocEnd(); } child_range children() { @@ -4603,9 +4698,9 @@ public: SourceLocation getBuiltinLoc() const { return BuiltinLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(BuiltinLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == AtomicExprClass; } diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 9c759db..04f6fb6 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -16,8 +16,8 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" -#include "clang/AST/UnresolvedSet.h" #include "clang/AST/TemplateBase.h" +#include "clang/AST/UnresolvedSet.h" #include "clang/Basic/ExpressionTraits.h" #include "clang/Basic/Lambda.h" #include "clang/Basic/TypeTraits.h" @@ -30,6 +30,7 @@ class CXXDestructorDecl; class CXXMethodDecl; class CXXTemporary; class TemplateArgumentListInfo; +class UuidAttr; //===--------------------------------------------------------------------===// // C++ Expressions. @@ -83,6 +84,8 @@ public: /// bracket. SourceLocation getOperatorLoc() const { return getRParenLoc(); } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const { return Range; } static bool classof(const Stmt *T) { @@ -176,14 +179,16 @@ class CXXNamedCastExpr : public ExplicitCastExpr { private: SourceLocation Loc; // the location of the casting op SourceLocation RParenLoc; // the location of the right parenthesis + SourceRange AngleBrackets; // range for '<' '>' protected: CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, CastKind kind, Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy, SourceLocation l, - SourceLocation RParenLoc) + SourceLocation RParenLoc, + SourceRange AngleBrackets) : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l), - RParenLoc(RParenLoc) {} + RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {} explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize) : ExplicitCastExpr(SC, Shell, PathSize) { } @@ -200,9 +205,10 @@ public: /// \brief Retrieve the location of the closing parenthesis. SourceLocation getRParenLoc() const { return RParenLoc; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(Loc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; } + static bool classof(const Stmt *T) { switch (T->getStmtClass()) { case CXXStaticCastExprClass: @@ -224,9 +230,10 @@ public: class CXXStaticCastExpr : public CXXNamedCastExpr { CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, - SourceLocation l, SourceLocation RParenLoc) + SourceLocation l, SourceLocation RParenLoc, + SourceRange AngleBrackets) : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize, - writtenTy, l, RParenLoc) {} + writtenTy, l, RParenLoc, AngleBrackets) {} explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize) : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { } @@ -236,7 +243,8 @@ public: ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + SourceRange AngleBrackets); static CXXStaticCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); @@ -254,9 +262,10 @@ public: class CXXDynamicCastExpr : public CXXNamedCastExpr { CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, - SourceLocation l, SourceLocation RParenLoc) + SourceLocation l, SourceLocation RParenLoc, + SourceRange AngleBrackets) : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize, - writtenTy, l, RParenLoc) {} + writtenTy, l, RParenLoc, AngleBrackets) {} explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize) : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { } @@ -266,7 +275,8 @@ public: ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + SourceRange AngleBrackets); static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context, unsigned pathSize); @@ -288,9 +298,10 @@ class CXXReinterpretCastExpr : public CXXNamedCastExpr { CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l, - SourceLocation RParenLoc) + SourceLocation RParenLoc, + SourceRange AngleBrackets) : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op, - pathSize, writtenTy, l, RParenLoc) {} + pathSize, writtenTy, l, RParenLoc, AngleBrackets) {} CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize) : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { } @@ -300,7 +311,8 @@ public: ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *WrittenTy, SourceLocation L, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + SourceRange AngleBrackets); static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context, unsigned pathSize); @@ -317,9 +329,9 @@ public: class CXXConstCastExpr : public CXXNamedCastExpr { CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, TypeSourceInfo *writtenTy, SourceLocation l, - SourceLocation RParenLoc) + SourceLocation RParenLoc, SourceRange AngleBrackets) : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, - 0, writtenTy, l, RParenLoc) {} + 0, writtenTy, l, RParenLoc, AngleBrackets) {} explicit CXXConstCastExpr(EmptyShell Empty) : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { } @@ -328,7 +340,8 @@ public: static CXXConstCastExpr *Create(ASTContext &Context, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + SourceRange AngleBrackets); static CXXConstCastExpr *CreateEmpty(ASTContext &Context); static bool classof(const Stmt *T) { @@ -386,9 +399,6 @@ public: return getArg(0)->getLocStart(); } SourceLocation getLocEnd() const { return getRParenLoc(); } - SourceRange getSourceRange() const { - return SourceRange(getLocStart(), getLocEnd()); - } /// getUDSuffixLoc - Returns the location of a ud-suffix in the expression. @@ -424,7 +434,8 @@ public: bool getValue() const { return Value; } void setValue(bool V) { Value = V; } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } @@ -449,7 +460,8 @@ public: explicit CXXNullPtrLiteralExpr(EmptyShell Empty) : Expr(CXXNullPtrLiteralExprClass, Empty) { } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } @@ -531,6 +543,8 @@ public: Operand = E; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } void setSourceRange(SourceRange R) { Range = R; } @@ -605,6 +619,8 @@ public: Operand = E; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } void setSourceRange(SourceRange R) { Range = R; } @@ -653,7 +669,8 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } bool isImplicit() const { return Implicit; } void setImplicit(bool I) { Implicit = I; } @@ -702,10 +719,11 @@ public: /// this variable. bool isThrownVariableInScope() const { return IsThrownVariableInScope; } - SourceRange getSourceRange() const LLVM_READONLY { + SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { if (getSubExpr() == 0) - return SourceRange(ThrowLoc, ThrowLoc); - return SourceRange(ThrowLoc, getSubExpr()->getSourceRange().getEnd()); + return ThrowLoc; + return getSubExpr()->getLocEnd(); } static bool classof(const Stmt *T) { @@ -789,11 +807,12 @@ public: /// used. SourceLocation getUsedLocation() const { return Loc; } - SourceRange getSourceRange() const LLVM_READONLY { - // Default argument expressions have no representation in the - // source, so they have an empty source range. - return SourceRange(); - } + // Default argument expressions have no representation in the + // source, so they have an empty source range. + SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); } + SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } + + SourceLocation getExprLoc() const LLVM_READONLY { return Loc; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDefaultArgExprClass; @@ -866,9 +885,10 @@ public: Expr *getSubExpr() { return cast<Expr>(SubExpr); } void setSubExpr(Expr *E) { SubExpr = E; } - SourceRange getSourceRange() const LLVM_READONLY { - return SubExpr->getSourceRange(); + SourceLocation getLocStart() const LLVM_READONLY { + return SubExpr->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();} // Implement isa/cast/dyncast/etc. static bool classof(const Stmt *T) { @@ -1001,7 +1021,8 @@ public: Args[Arg] = ArgExpr; } - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY; SourceRange getParenRange() const { return ParenRange; } void setParenRange(SourceRange Range) { ParenRange = Range; } @@ -1057,9 +1078,9 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(TyBeginLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXFunctionalCastExprClass; } @@ -1089,13 +1110,15 @@ public: ArrayRef<Expr *> Args, SourceRange parenRange, bool HadMultipleCandidates, - bool ZeroInitialization = false); + bool ListInitialization, + bool ZeroInitialization); explicit CXXTemporaryObjectExpr(EmptyShell Empty) : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { } TypeSourceInfo *getTypeSourceInfo() const { return Type; } - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTemporaryObjectExprClass; @@ -1111,7 +1134,7 @@ public: /// \code /// void low_pass_filter(std::vector<double> &values, double cutoff) { /// values.erase(std::remove_if(values.begin(), values.end(), -// [=](double value) { return value > cutoff; }); +/// [=](double value) { return value > cutoff; }); /// } /// \endcode /// @@ -1393,9 +1416,10 @@ public: return T->getStmtClass() == LambdaExprClass; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(IntroducerRange.getBegin(), ClosingBrace); + SourceLocation getLocStart() const LLVM_READONLY { + return IntroducerRange.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; } child_range children() { return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1); @@ -1434,7 +1458,8 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXScalarValueInitExprClass; @@ -1621,6 +1646,8 @@ public: SourceRange getSourceRange() const LLVM_READONLY { return Range; } + SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXNewExprClass; @@ -1688,9 +1715,8 @@ public: /// return an invalid type. QualType getDestroyedType() const; - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(Loc, Argument->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY {return Argument->getLocEnd();} static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDeleteExprClass; @@ -1878,7 +1904,8 @@ public: DestroyedType = PseudoDestructorTypeStorage(Info); } - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY {return Base->getLocStart();} + SourceLocation getLocEnd() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == CXXPseudoDestructorExprClass; @@ -1925,7 +1952,8 @@ public: : Expr(UnaryTypeTraitExprClass, Empty), UTT(0), Value(false), QueriedType() { } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc, RParen);} + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParen; } UnaryTypeTrait getTrait() const { return static_cast<UnaryTypeTrait>(UTT); } @@ -1990,9 +2018,8 @@ public: : Expr(BinaryTypeTraitExprClass, Empty), BTT(0), Value(false), LhsType(), RhsType() { } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(Loc, RParen); - } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParen; } BinaryTypeTrait getTrait() const { return static_cast<BinaryTypeTrait>(BTT); @@ -2097,8 +2124,9 @@ public: return getTypeSourceInfos() + getNumArgs(); } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc, RParenLoc); } - + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == TypeTraitExprClass; } @@ -2159,9 +2187,8 @@ public: virtual ~ArrayTypeTraitExpr() { } - virtual SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(Loc, RParen); - } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParen; } ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); } @@ -2221,9 +2248,8 @@ public: : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false), QueriedExpression() { } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(Loc, RParen); - } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParen; } ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); } @@ -2411,7 +2437,7 @@ public: /// /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -2512,13 +2538,15 @@ public: /// that was looked in to find these results. CXXRecordDecl *getNamingClass() const { return NamingClass; } - SourceRange getSourceRange() const LLVM_READONLY { - SourceRange Range(getNameInfo().getSourceRange()); - if (getQualifierLoc()) - Range.setBegin(getQualifierLoc().getBeginLoc()); + SourceLocation getLocStart() const LLVM_READONLY { + if (NestedNameSpecifierLoc l = getQualifierLoc()) + return l.getBeginLoc(); + return getNameInfo().getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) - Range.setEnd(getRAngleLoc()); - return Range; + return getRAngleLoc(); + return getNameInfo().getLocEnd(); } child_range children() { return child_range(); } @@ -2647,7 +2675,7 @@ public: /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -2666,11 +2694,13 @@ public: return getExplicitTemplateArgs().NumTemplateArgs; } - SourceRange getSourceRange() const LLVM_READONLY { - SourceRange Range(QualifierLoc.getBeginLoc(), getLocation()); + SourceLocation getLocStart() const LLVM_READONLY { + return QualifierLoc.getBeginLoc(); + } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) - Range.setEnd(getRAngleLoc()); - return Range; + return getRAngleLoc(); + return getLocation(); } static bool classof(const Stmt *T) { @@ -2740,9 +2770,10 @@ public: /// when modifying an existing AST to preserve its invariants. void setSubExpr(Expr *E) { SubExpr = E; } - SourceRange getSourceRange() const LLVM_READONLY { - return SubExpr->getSourceRange(); + SourceLocation getLocStart() const LLVM_READONLY { + return SubExpr->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();} // Implement isa/cast/dyncast/etc. static bool classof(const Stmt *T) { @@ -2855,7 +2886,8 @@ public: *(arg_begin() + I) = E; } - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXUnresolvedConstructExprClass; @@ -3061,7 +3093,7 @@ public: /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -3089,20 +3121,18 @@ public: return getExplicitTemplateArgs().NumTemplateArgs; } - SourceRange getSourceRange() const LLVM_READONLY { - SourceRange Range; + SourceLocation getLocStart() const LLVM_READONLY { if (!isImplicitAccess()) - Range.setBegin(Base->getSourceRange().getBegin()); - else if (getQualifier()) - Range.setBegin(getQualifierLoc().getBeginLoc()); - else - Range.setBegin(MemberNameInfo.getBeginLoc()); + return Base->getLocStart(); + if (getQualifier()) + return getQualifierLoc().getBeginLoc(); + return MemberNameInfo.getBeginLoc(); + } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) - Range.setEnd(getRAngleLoc()); - else - Range.setEnd(MemberNameInfo.getEndLoc()); - return Range; + return getRAngleLoc(); + return MemberNameInfo.getEndLoc(); } static bool classof(const Stmt *T) { @@ -3226,16 +3256,17 @@ public: // expression refers to. SourceLocation getMemberLoc() const { return getNameLoc(); } - SourceRange getSourceRange() const LLVM_READONLY { - SourceRange Range = getMemberNameInfo().getSourceRange(); + SourceLocation getLocStart() const LLVM_READONLY { if (!isImplicitAccess()) - Range.setBegin(Base->getSourceRange().getBegin()); - else if (getQualifierLoc()) - Range.setBegin(getQualifierLoc().getBeginLoc()); - + return Base->getLocStart(); + if (NestedNameSpecifierLoc l = getQualifierLoc()) + return l.getBeginLoc(); + return getMemberNameInfo().getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) - Range.setEnd(getRAngleLoc()); - return Range; + return getRAngleLoc(); + return getMemberNameInfo().getLocEnd(); } static bool classof(const Stmt *T) { @@ -3277,6 +3308,8 @@ public: Expr *getOperand() const { return static_cast<Expr*>(Operand); } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } bool getValue() const { return Value; } @@ -3323,7 +3356,7 @@ class PackExpansionExpr : public Expr { public: PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc, - llvm::Optional<unsigned> NumExpansions) + Optional<unsigned> NumExpansions) : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), Pattern->getObjectKind(), /*TypeDependent=*/true, /*ValueDependent=*/true, /*InstantiationDependent=*/true, @@ -3346,16 +3379,17 @@ public: /// \brief Determine the number of expansions that will be produced when /// this pack expansion is instantiated, if already known. - llvm::Optional<unsigned> getNumExpansions() const { + Optional<unsigned> getNumExpansions() const { if (NumExpansions) return NumExpansions - 1; - return llvm::Optional<unsigned>(); + return None; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(Pattern->getLocStart(), EllipsisLoc); + SourceLocation getLocStart() const LLVM_READONLY { + return Pattern->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == PackExpansionExprClass; @@ -3458,9 +3492,8 @@ public: return Length; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(OperatorLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == SizeOfPackExprClass; @@ -3500,7 +3533,8 @@ public: Param(param), Replacement(replacement), NameLoc(loc) {} SourceLocation getNameLoc() const { return NameLoc; } - SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; } + SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; } Expr *getReplacement() const { return cast<Expr>(Replacement); } @@ -3561,7 +3595,8 @@ public: /// template arguments. TemplateArgument getArgumentPack() const; - SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; } + SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass; @@ -3606,7 +3641,7 @@ public: static FunctionParmPackExpr *Create(ASTContext &Context, QualType T, ParmVarDecl *ParamPack, SourceLocation NameLoc, - llvm::ArrayRef<Decl*> Params); + ArrayRef<Decl *> Params); static FunctionParmPackExpr *CreateEmpty(ASTContext &Context, unsigned NumParams); @@ -3628,7 +3663,8 @@ public: /// \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; } + SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == FunctionParmPackExprClass; @@ -3684,8 +3720,11 @@ public: return getValueKind() == VK_LValue; } - SourceRange getSourceRange() const LLVM_READONLY { - return Temporary->getSourceRange(); + SourceLocation getLocStart() const LLVM_READONLY { + return Temporary->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return Temporary->getLocEnd(); } static bool classof(const Stmt *T) { diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 27f5da0..dfd4527 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -44,9 +44,8 @@ public: SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AtLoc, String->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCStringLiteralClass; @@ -72,8 +71,9 @@ public: bool getValue() const { return Value; } void setValue(bool V) { Value = V; } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } - + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } + SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } @@ -112,6 +112,8 @@ public: SourceLocation getAtLoc() const { return Range.getBegin(); } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -133,7 +135,7 @@ class ObjCArrayLiteral : public Expr { SourceRange Range; ObjCMethodDecl *ArrayWithObjectsMethod; - ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements, + ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T, ObjCMethodDecl * Method, SourceRange SR); @@ -142,12 +144,14 @@ class ObjCArrayLiteral : public Expr { public: static ObjCArrayLiteral *Create(ASTContext &C, - llvm::ArrayRef<Expr *> Elements, + ArrayRef<Expr *> Elements, QualType T, ObjCMethodDecl * Method, SourceRange SR); static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements); + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } static bool classof(const Stmt *T) { @@ -202,12 +206,18 @@ struct ObjCDictionaryElement { /// \brief The number of elements this pack expansion will expand to, if /// this is a pack expansion and is known. - llvm::Optional<unsigned> NumExpansions; + Optional<unsigned> NumExpansions; /// \brief Determines whether this dictionary element is a pack expansion. bool isPackExpansion() const { return EllipsisLoc.isValid(); } }; +} // end namespace clang + +namespace llvm { +template <> struct isPodLike<clang::ObjCDictionaryElement> : llvm::true_type {}; +} +namespace clang { /// ObjCDictionaryLiteral - AST node to represent objective-c dictionary /// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] }; class ObjCDictionaryLiteral : public Expr { @@ -296,8 +306,7 @@ public: ObjCDictionaryElement getKeyValueElement(unsigned Index) const { assert((Index < NumElements) && "Arg access out of range!"); const KeyValuePair &KV = getKeyValues()[Index]; - ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), - llvm::Optional<unsigned>() }; + ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None }; if (HasPackExpansions) { const ExpansionData &Expansion = getExpansionData()[Index]; Result.EllipsisLoc = Expansion.EllipsisLoc; @@ -310,6 +319,8 @@ public: ObjCMethodDecl *getDictWithObjectsMethod() const { return DictWithObjectsMethod; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } static bool classof(const Stmt *T) { @@ -360,9 +371,8 @@ public: EncodedType = EncType; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AtLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCEncodeExprClass; @@ -393,9 +403,8 @@ public: void setAtLoc(SourceLocation L) { AtLoc = L; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AtLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } /// getNumArgs - Return the number of actual arguments to this call. unsigned getNumArgs() const { return SelName.getNumArgs(); } @@ -408,9 +417,13 @@ public: child_range children() { return child_range(); } }; -/// ObjCProtocolExpr used for protocol expression in Objective-C. This is used -/// as: @protocol(foo), as in: -/// obj conformsToProtocol:@protocol(foo)] +/// ObjCProtocolExpr used for protocol expression in Objective-C. +/// +/// This is used as: \@protocol(foo), as in: +/// \code +/// [obj conformsToProtocol:@protocol(foo)] +/// \endcode +/// /// The return type is "Protocol*". class ObjCProtocolExpr : public Expr { ObjCProtocolDecl *TheProtocol; @@ -433,9 +446,8 @@ public: void setAtLoc(SourceLocation L) { AtLoc = L; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AtLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCProtocolExprClass; @@ -453,18 +465,23 @@ class ObjCIvarRefExpr : public Expr { ObjCIvarDecl *D; Stmt *Base; SourceLocation Loc; + /// OpLoc - This is the location of '.' or '->' + SourceLocation OpLoc; + bool IsArrow:1; // True if this is "X->F", false if this is "X.F". bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). public: ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, - SourceLocation l, Expr *base, + SourceLocation l, SourceLocation oploc, + Expr *base, bool arrow = false, bool freeIvar = false) : Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary, /*TypeDependent=*/false, base->isValueDependent(), base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), - D(d), Base(base), Loc(l), IsArrow(arrow), IsFreeIvar(freeIvar) {} + D(d), Base(base), Loc(l), OpLoc(oploc), + IsArrow(arrow), IsFreeIvar(freeIvar) {} explicit ObjCIvarRefExpr(EmptyShell Empty) : Expr(ObjCIvarRefExprClass, Empty) {} @@ -485,10 +502,13 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return isFreeIvar() ? SourceRange(Loc) - : SourceRange(getBase()->getLocStart(), Loc); + SourceLocation getLocStart() const LLVM_READONLY { + return isFreeIvar() ? Loc : getBase()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } + + SourceLocation getOpLoc() const { return OpLoc; } + void setOpLoc(SourceLocation L) { OpLoc = L; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIvarRefExprClass; @@ -697,11 +717,10 @@ public: bool isSuperReceiver() const { return Receiver.is<const Type*>(); } bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange((isObjectReceiver() ? getBase()->getLocStart() - : getReceiverLocation()), - IdLoc); + SourceLocation getLocStart() const LLVM_READONLY { + return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation(); } + SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCPropertyRefExprClass; @@ -796,10 +815,12 @@ public: SourceLocation getRBracket() const { return RBracket; } void setRBracket(SourceLocation RB) { RBracket = RB; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(SubExprs[BASE]->getLocStart(), RBracket); + + SourceLocation getLocStart() const LLVM_READONLY { + return SubExprs[BASE]->getLocStart(); } - + SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSubscriptRefExprClass; } @@ -1335,9 +1356,8 @@ public: LBracLoc = R.getBegin(); RBracLoc = R.getEnd(); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(LBracLoc, RBracLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCMessageExprClass; @@ -1372,16 +1392,20 @@ class ObjCIsaExpr : public Expr { /// IsaMemberLoc - This is the location of the 'isa'. SourceLocation IsaMemberLoc; + + /// OpLoc - This is the location of '.' or '->' + SourceLocation OpLoc; /// IsArrow - True if this is "X->F", false if this is "X.F". bool IsArrow; public: - ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) + ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc, + QualType ty) : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, /*TypeDependent=*/false, base->isValueDependent(), base->isInstantiationDependent(), /*ContainsUnexpandedParameterPack=*/false), - Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} + Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {} /// \brief Build an empty expression. explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { } @@ -1396,10 +1420,19 @@ public: /// location of 'F'. SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } + + SourceLocation getOpLoc() const { return OpLoc; } + void setOpLoc(SourceLocation L) { OpLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getBase()->getLocStart(), IsaMemberLoc); + SourceLocation getLocStart() const LLVM_READONLY { + return getBase()->getLocStart(); + } + + SourceLocation getBaseLocEnd() const LLVM_READONLY { + return getBase()->getLocEnd(); } + + SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; } SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; } @@ -1469,9 +1502,11 @@ public: child_range children() { return child_range(&Operand, &Operand+1); } // Source locations are determined by the subexpression. - SourceRange getSourceRange() const LLVM_READONLY { - return Operand->getSourceRange(); + SourceLocation getLocStart() const LLVM_READONLY { + return Operand->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();} + SourceLocation getExprLoc() const LLVM_READONLY { return getSubExpr()->getExprLoc(); } @@ -1520,8 +1555,9 @@ public: /// \brief The location of the bridge keyword. SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(LParenLoc, getSubExpr()->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return getSubExpr()->getLocEnd(); } static bool classof(const Stmt *T) { diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index db2bddb..81fcf24 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -14,8 +14,8 @@ #ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H #define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H -#include "clang/AST/DeclBase.h" #include "clang/AST/CharUnits.h" +#include "clang/AST/DeclBase.h" #include "llvm/ADT/DenseMap.h" namespace clang { @@ -24,7 +24,10 @@ class ASTConsumer; class CXXBaseSpecifier; class DeclarationName; class ExternalSemaSource; // layering violation required for downcasting +class FieldDecl; +class Module; class NamedDecl; +class RecordDecl; class Selector; class Stmt; class TagDecl; @@ -115,23 +118,28 @@ public: /// The default implementation of this method is a no-op. virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); - /// \brief Finds all declarations with the given name in the - /// given context. - /// - /// Generally the final step of this method is either to call - /// SetExternalVisibleDeclsForName or to recursively call lookup on - /// the DeclContext after calling SetExternalVisibleDecls. + /// \brief Update an out-of-date identifier. + virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { } + + /// \brief Find all declarations with the given name in the given context, + /// and add them to the context by calling SetExternalVisibleDeclsForName + /// or SetNoExternalVisibleDeclsForName. + /// \return \c true if any declarations might have been found, \c false if + /// we definitely have no declarations with tbis name. /// - /// The default implementation of this method is a no-op. - virtual DeclContextLookupResult + /// The default implementation of this method is a no-op returning \c false. + virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); /// \brief Ensures that the table of all visible declarations inside this /// context is up to date. /// - /// The default implementation of this functino is a no-op. + /// The default implementation of this function is a no-op. virtual void completeVisibleDeclsMap(const DeclContext *DC); + /// \brief Retrieve the module that corresponds to the given module ID. + virtual Module *getModule(unsigned ID) { return 0; } + /// \brief Finds all declarations lexically contained within the given /// DeclContext, after applying an optional filter predicate. /// diff --git a/include/clang/AST/LambdaMangleContext.h b/include/clang/AST/LambdaMangleContext.h index 3e2fbad..bbaee26 100644 --- a/include/clang/AST/LambdaMangleContext.h +++ b/include/clang/AST/LambdaMangleContext.h @@ -14,7 +14,9 @@ #ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H #define LLVM_CLANG_LAMBDAMANGLECONTEXT_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" namespace clang { @@ -23,7 +25,7 @@ class FunctionProtoType; /// \brief Keeps track of the mangled names of lambda expressions within a /// particular context. -class LambdaMangleContext { +class LambdaMangleContext : public RefCountedBase<LambdaMangleContext> { llvm::DenseMap<const FunctionProtoType *, unsigned> ManglingNumbers; public: diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile index 7fb33f2..ae84bcf 100644 --- a/include/clang/AST/Makefile +++ b/include/clang/AST/Makefile @@ -1,8 +1,12 @@ CLANG_LEVEL := ../../.. TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc \ +BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc \ + StmtNodes.inc DeclNodes.inc \ CommentNodes.inc CommentHTMLTags.inc \ - CommentHTMLTagsProperties.inc CommentCommandInfo.inc + CommentHTMLTagsProperties.inc \ + CommentHTMLNamedCharacterReferences.inc \ + CommentCommandInfo.inc \ + CommentCommandList.inc TABLEGEN_INC_FILES_COMMON = 1 @@ -20,6 +24,12 @@ $(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ $(Verb) $(ClangTableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \ -I $(PROJ_SRC_DIR)/../../ $< +$(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ + $(ObjDir)/.dir + $(Echo) "Building Clang attribute dumper with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \ + -I $(PROJ_SRC_DIR)/../../ $< + $(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \ $(ObjDir)/.dir $(Echo) "Building Clang statement node tables with tblgen" @@ -45,8 +55,19 @@ $(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(Echo) "Building Clang comment HTML tag properties with tblgen" $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $< +$(ObjDir)/CommentHTMLNamedCharacterReferences.inc.tmp : \ + $(PROJ_SRC_DIR)/CommentHTMLNamedCharacterReferences.td \ + $(CLANG_TBLGEN) $(ObjDir)/.dir + $(Echo) "Building Clang named character reference translation function with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-comment-html-named-character-references -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, $@) $< +$(ObjDir)/CommentCommandList.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \ + $(CLANG_TBLGEN) $(ObjDir)/.dir + $(Echo) "Building Clang list of comment commands with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-comment-command-list -o $(call SYSPATH, $@) $< + diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index a0dffb9..94faa19 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -17,8 +17,8 @@ #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" namespace clang { diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h index f9fd1f9..0b21b03 100644 --- a/include/clang/AST/NSAPI.h +++ b/include/clang/AST/NSAPI.h @@ -52,7 +52,7 @@ public: Selector getNSStringSelector(NSStringMethodKind MK) const; /// \brief Return NSStringMethodKind if \param Sel is such a selector. - llvm::Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const; + Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const; /// \brief Returns true if the expression \param E is a reference of /// "NSUTF8StringEncoding" enum constant. @@ -84,7 +84,7 @@ public: Selector getNSArraySelector(NSArrayMethodKind MK) const; /// \brief Return NSArrayMethodKind if \p Sel is such a selector. - llvm::Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel); + Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel); /// \brief Enumerates the NSDictionary methods used to generate literals. enum NSDictionaryMethodKind { @@ -96,17 +96,17 @@ public: NSDict_dictionaryWithObjectsAndKeys, NSDict_initWithDictionary, NSDict_initWithObjectsAndKeys, + NSDict_initWithObjectsForKeys, NSDict_objectForKey, NSMutableDict_setObjectForKey }; - static const unsigned NumNSDictionaryMethods = 10; + static const unsigned NumNSDictionaryMethods = 11; /// \brief The Objective-C NSDictionary selectors. Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const; /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector. - llvm::Optional<NSDictionaryMethodKind> - getNSDictionaryMethodKind(Selector Sel); + Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel); /// \brief Returns selector for "objectForKeyedSubscript:". Selector getObjectForKeyedSubscriptSelector() const { @@ -170,12 +170,12 @@ public: } /// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector. - llvm::Optional<NSNumberLiteralMethodKind> + Optional<NSNumberLiteralMethodKind> getNSNumberLiteralMethodKind(Selector Sel) const; /// \brief Determine the appropriate NSNumber factory method kind for a /// literal of the given type. - llvm::Optional<NSNumberLiteralMethodKind> + Optional<NSNumberLiteralMethodKind> getNSNumberFactoryMethodKind(QualType T) const; /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c. diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index bf9e1cb..58f3986 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -117,7 +117,7 @@ public: /// \brief Builds a nested name specifier that names a namespace. static NestedNameSpecifier *Create(const ASTContext &Context, NestedNameSpecifier *Prefix, - NamespaceDecl *NS); + const NamespaceDecl *NS); /// \brief Builds a nested name specifier that names a namespace alias. static NestedNameSpecifier *Create(const ASTContext &Context, diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index 18169fd..5e41d95 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -292,7 +292,10 @@ enum CastKind { // Convert a builtin function to a function pointer; only allowed in the // callee of a call expression. - CK_BuiltinFnToFnPtr + CK_BuiltinFnToFnPtr, + + // Convert a zero value for OpenCL event_t initialization. + CK_ZeroToOCLEvent }; static const CastKind CK_Invalid = static_cast<CastKind>(-1); diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 7babc1b..e3c09e7 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -14,14 +14,15 @@ #ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H #define LLVM_CLANG_AST_PRETTY_PRINTER_H -#include "clang/Basic/LangOptions.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" namespace clang { +class LangOptions; +class SourceManager; class Stmt; class TagDecl; -class LangOptions; class PrinterHelper { public: @@ -39,8 +40,7 @@ struct PrintingPolicy { SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), SuppressStrongLifetime(false), Bool(LO.Bool), - TerseOutput(false), SuppressAttributes(false), - DumpSourceManager(0) { } + TerseOutput(false), PolishForDeclaration(false) { } /// \brief What language we're printing. LangOptions LangOpts; @@ -142,15 +142,10 @@ struct PrintingPolicy { /// only the requested declaration. unsigned TerseOutput : 1; - /// \brief When true, do not print attributes attached to the declaration. + /// \brief When true, do certain refinement needed for producing proper + /// declaration tag; such as, 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 - /// involves printing something similar to source code. - SourceManager *DumpSourceManager; + unsigned PolishForDeclaration : 1; }; } // end namespace clang diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index f96e067..0191964 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -18,6 +18,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -464,20 +465,15 @@ template<typename Derived> bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, bool &EnqueueChildren) { -// The cast for DISPATCH_WALK is needed for older versions of g++, but causes -// problems for MSVC. So we'll skip the cast entirely for MSVC. -#if defined(_MSC_VER) - #define GCC_CAST(CLASS) -#else - #define GCC_CAST(CLASS) (bool (RecursiveASTVisitor::*)(CLASS*)) -#endif - // Dispatch to the corresponding WalkUpFrom* function only if the derived // class didn't override Traverse* (and thus the traversal is trivial). #define DISPATCH_WALK(NAME, CLASS, VAR) \ - if (&RecursiveASTVisitor::Traverse##NAME == \ - GCC_CAST(CLASS)&Derived::Traverse##NAME) \ - return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR)); \ + { \ + bool (Derived::*DerivedFn)(CLASS*) = &Derived::Traverse##NAME; \ + bool (Derived::*BaseFn)(CLASS*) = &RecursiveASTVisitor::Traverse##NAME; \ + if (DerivedFn == BaseFn) \ + return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR)); \ + } \ EnqueueChildren = false; \ return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR)); @@ -516,7 +512,6 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, } #undef DISPATCH_WALK -#undef GCC_CAST return true; } @@ -600,7 +595,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) { #define ABSTRACT_TYPELOC(CLASS, BASE) #define TYPELOC(CLASS, BASE) \ case TypeLoc::CLASS: \ - return getDerived().Traverse##CLASS##TypeLoc(*cast<CLASS##TypeLoc>(&TL)); + return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>()); #include "clang/AST/TypeLocNodes.def" } @@ -1263,6 +1258,8 @@ DEF_TRAVERSE_DECL(BlockDecl, { return true; }) +DEF_TRAVERSE_DECL(EmptyDecl, { }) + DEF_TRAVERSE_DECL(FileScopeAsmDecl, { TRY_TO(TraverseStmt(D->getAsmString())); }) @@ -1393,6 +1390,14 @@ DEF_TRAVERSE_DECL(UsingDirectiveDecl, { DEF_TRAVERSE_DECL(UsingShadowDecl, { }) +DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { + for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(), + E = D->varlist_end(); + I != E; ++I) { + TRY_TO(TraverseStmt(*I)); + } + }) + // A helper method for TemplateDecl's children. template<typename Derived> bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( @@ -1716,7 +1721,7 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { // FunctionNoProtoType or FunctionProtoType, or a typedef. This // also covers the return type and the function parameters, // including exception specifications. - if (clang::TypeSourceInfo *TSI = D->getTypeSourceInfo()) { + if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) { TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); } @@ -2106,8 +2111,7 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) { if (S->hasExplicitParameters() && S->hasExplicitResultType()) { // Visit the whole type. TRY_TO(TraverseTypeLoc(TL)); - } else if (isa<FunctionProtoTypeLoc>(TL)) { - FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL); + } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) { if (S->hasExplicitParameters()) { // Visit parameters. for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) { diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index a9bbb48..cf8fc24 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -14,16 +14,14 @@ #ifndef LLVM_CLANG_AST_STMT_H #define LLVM_CLANG_AST_STMT_H +#include "clang/AST/DeclGroup.h" +#include "clang/AST/StmtIterator.h" +#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" -#include "clang/AST/PrettyPrinter.h" -#include "clang/AST/StmtIterator.h" -#include "clang/AST/DeclGroup.h" -#include "clang/AST/Attr.h" -#include "clang/Lex/Token.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/ErrorHandling.h" #include <string> namespace llvm { @@ -32,15 +30,19 @@ namespace llvm { namespace clang { class ASTContext; - class Expr; + class Attr; class Decl; - class ParmVarDecl; - class QualType; + class Expr; class IdentifierInfo; class LabelDecl; + class ParmVarDecl; + class PrinterHelper; + struct PrintingPolicy; + class QualType; class SourceManager; class StringLiteral; class SwitchStmt; + class Token; class VarDecl; //===--------------------------------------------------------------------===// @@ -172,11 +174,20 @@ protected: unsigned Kind : 2; }; + enum APFloatSemantics { + IEEEhalf, + IEEEsingle, + IEEEdouble, + x87DoubleExtended, + IEEEquad, + PPCDoubleDouble + }; + class FloatingLiteralBitfields { friend class FloatingLiteral; unsigned : NumExprBits; - unsigned IsIEEE : 1; // Distinguishes between PPC128 and IEEE128. + unsigned Semantics : 3; // Provides semantics for APFloat construction unsigned IsExact : 1; }; @@ -302,14 +313,10 @@ public: // Only allow allocation of Stmts using the allocator in ASTContext // or by doing a placement new. void* operator new(size_t bytes, ASTContext& C, - unsigned alignment = 8) throw() { - return ::operator new(bytes, C, alignment); - } + unsigned alignment = 8) throw(); void* operator new(size_t bytes, ASTContext* C, - unsigned alignment = 8) throw() { - return ::operator new(bytes, *C, alignment); - } + unsigned alignment = 8) throw(); void* operator new(size_t bytes, void* mem) throw() { return mem; @@ -360,16 +367,14 @@ public: static void EnableStatistics(); static void PrintStats(); - /// dump - This does a local dump of the specified AST fragment. It dumps the - /// specified node and a few nodes underneath it, but not the whole subtree. - /// This is useful in a debugger. + /// \brief Dumps the specified AST fragment and all subtrees to + /// \c llvm::errs(). LLVM_ATTRIBUTE_USED void dump() const; LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const; void dump(raw_ostream &OS, SourceManager &SM) const; - /// dumpAll - This does a dump of the specified AST fragment and all subtrees. - void dumpAll() const; - void dumpAll(SourceManager &SM) const; + /// dumpColor - same as dump(), but forces color highlighting. + LLVM_ATTRIBUTE_USED void dumpColor() const; /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST /// back to its original source language syntax. @@ -470,9 +475,8 @@ public: SourceLocation getEndLoc() const { return EndLoc; } void setEndLoc(SourceLocation L) { EndLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(StartLoc, EndLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == DeclStmtClass; @@ -526,7 +530,8 @@ public: bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(SemiLoc); } + SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == NullStmtClass; @@ -544,7 +549,7 @@ class CompoundStmt : public Stmt { Stmt** Body; SourceLocation LBracLoc, RBracLoc; public: - CompoundStmt(ASTContext &C, Stmt **StmtStart, unsigned NumStmts, + CompoundStmt(ASTContext &C, ArrayRef<Stmt*> Stmts, SourceLocation LB, SourceLocation RB); // \brief Build an empty compound statment with a location. @@ -598,9 +603,8 @@ public: return const_reverse_body_iterator(body_begin()); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(LBracLoc, RBracLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; } SourceLocation getLBracLoc() const { return LBracLoc; } void setLBracLoc(SourceLocation L) { LBracLoc = L; } @@ -627,8 +631,14 @@ protected: // A pointer to the following CaseStmt or DefaultStmt class, // used by SwitchStmt. SwitchCase *NextSwitchCase; + SourceLocation KeywordLoc; + SourceLocation ColonLoc; - SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} + SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc) + : Stmt(SC), NextSwitchCase(0), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {} + + SwitchCase(StmtClass SC, EmptyShell) + : Stmt(SC), NextSwitchCase(0) {} public: const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } @@ -637,12 +647,18 @@ public: void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } + SourceLocation getKeywordLoc() const { return KeywordLoc; } + void setKeywordLoc(SourceLocation L) { KeywordLoc = L; } + SourceLocation getColonLoc() const { return ColonLoc; } + void setColonLoc(SourceLocation L) { ColonLoc = L; } + Stmt *getSubStmt(); const Stmt *getSubStmt() const { return const_cast<SwitchCase*>(this)->getSubStmt(); } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); } + SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } + SourceLocation getLocEnd() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == CaseStmtClass || @@ -654,26 +670,22 @@ class CaseStmt : public SwitchCase { enum { LHS, RHS, SUBSTMT, END_EXPR }; Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for // GNU "case 1 ... 4" extension - SourceLocation CaseLoc; SourceLocation EllipsisLoc; - SourceLocation ColonLoc; public: CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc) - : SwitchCase(CaseStmtClass) { + : SwitchCase(CaseStmtClass, caseLoc, colonLoc) { SubExprs[SUBSTMT] = 0; SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); - CaseLoc = caseLoc; EllipsisLoc = ellipsisLoc; - ColonLoc = colonLoc; } /// \brief Build an empty switch case statement. - explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { } + explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { } - SourceLocation getCaseLoc() const { return CaseLoc; } - void setCaseLoc(SourceLocation L) { CaseLoc = L; } + SourceLocation getCaseLoc() const { return KeywordLoc; } + void setCaseLoc(SourceLocation L) { KeywordLoc = L; } SourceLocation getEllipsisLoc() const { return EllipsisLoc; } void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; } SourceLocation getColonLoc() const { return ColonLoc; } @@ -695,15 +707,16 @@ public: void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } - - SourceRange getSourceRange() const LLVM_READONLY { + SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { // Handle deeply nested case statements with iteration instead of recursion. const CaseStmt *CS = this; while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt())) CS = CS2; - return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd()); + return CS->getSubStmt()->getLocEnd(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == CaseStmtClass; } @@ -716,28 +729,26 @@ public: class DefaultStmt : public SwitchCase { Stmt* SubStmt; - SourceLocation DefaultLoc; - SourceLocation ColonLoc; public: DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) : - SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL), - ColonLoc(CL) {} + SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {} /// \brief Build an empty default statement. - explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { } + explicit DefaultStmt(EmptyShell Empty) + : SwitchCase(DefaultStmtClass, Empty) { } Stmt *getSubStmt() { return SubStmt; } const Stmt *getSubStmt() const { return SubStmt; } void setSubStmt(Stmt *S) { SubStmt = S; } - SourceLocation getDefaultLoc() const { return DefaultLoc; } - void setDefaultLoc(SourceLocation L) { DefaultLoc = L; } + SourceLocation getDefaultLoc() const { return KeywordLoc; } + void setDefaultLoc(SourceLocation L) { KeywordLoc = L; } SourceLocation getColonLoc() const { return ColonLoc; } void setColonLoc(SourceLocation L) { ColonLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(DefaultLoc, SubStmt->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} + static bool classof(const Stmt *T) { return T->getStmtClass() == DefaultStmtClass; } @@ -746,6 +757,11 @@ public: child_range children() { return child_range(&SubStmt, &SubStmt+1); } }; +inline SourceLocation SwitchCase::getLocEnd() const { + if (const CaseStmt *CS = dyn_cast<CaseStmt>(this)) + return CS->getLocEnd(); + return cast<DefaultStmt>(this)->getLocEnd(); +} /// LabelStmt - Represents a label, which has a substatement. For example: /// foo: return; @@ -771,9 +787,9 @@ public: void setIdentLoc(SourceLocation L) { IdentLoc = L; } void setSubStmt(Stmt *SS) { SubStmt = SS; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(IdentLoc, SubStmt->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} + child_range children() { return child_range(&SubStmt, &SubStmt+1); } static bool classof(const Stmt *T) { @@ -819,9 +835,9 @@ public: Stmt *getSubStmt() { return SubStmt; } const Stmt *getSubStmt() const { return SubStmt; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AttrLoc, SubStmt->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} + child_range children() { return child_range(&SubStmt, &SubStmt + 1); } static bool classof(const Stmt *T) { @@ -879,11 +895,12 @@ public: SourceLocation getElseLoc() const { return ElseLoc; } void setElseLoc(SourceLocation L) { ElseLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { + SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { if (SubExprs[ELSE]) - return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); + return SubExprs[ELSE]->getLocEnd(); else - return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); + return SubExprs[THEN]->getLocEnd(); } // Iterators over subexpressions. The iterators will include iterating @@ -977,9 +994,11 @@ public: return (bool) AllEnumCasesCovered; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return SubExprs[BODY]->getLocEnd(); } + // Iterators child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); @@ -1031,9 +1050,11 @@ public: SourceLocation getWhileLoc() const { return WhileLoc; } void setWhileLoc(SourceLocation L) { WhileLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return SubExprs[BODY]->getLocEnd(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == WhileStmtClass; } @@ -1079,9 +1100,9 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(DoLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == DoStmtClass; } @@ -1150,9 +1171,11 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return SubExprs[BODY]->getLocEnd(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == ForStmtClass; } @@ -1184,9 +1207,9 @@ public: SourceLocation getLabelLoc() const { return LabelLoc; } void setLabelLoc(SourceLocation L) { LabelLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(GotoLoc, LabelLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == GotoStmtClass; } @@ -1227,9 +1250,8 @@ public: return const_cast<IndirectGotoStmt*>(this)->getConstantTarget(); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(GotoLoc, Target->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); } static bool classof(const Stmt *T) { return T->getStmtClass() == IndirectGotoStmtClass; @@ -1253,9 +1275,8 @@ public: SourceLocation getContinueLoc() const { return ContinueLoc; } void setContinueLoc(SourceLocation L) { ContinueLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(ContinueLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == ContinueStmtClass; @@ -1278,7 +1299,8 @@ public: SourceLocation getBreakLoc() const { return BreakLoc; } void setBreakLoc(SourceLocation L) { BreakLoc = L; } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(BreakLoc); } + SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == BreakStmtClass; @@ -1329,7 +1351,10 @@ public: const VarDecl *getNRVOCandidate() const { return NRVOCandidate; } void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; } - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return RetExpr ? RetExpr->getLocEnd() : RetLoc; + } static bool classof(const Stmt *T) { return T->getStmtClass() == ReturnStmtClass; @@ -1381,7 +1406,8 @@ public: bool isVolatile() const { return IsVolatile; } void setVolatile(bool V) { IsVolatile = V; } - SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); } + SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); } + SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } //===--- Asm String Analysis ---===// @@ -1636,9 +1662,8 @@ public: return Clobbers[i]; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AsmLoc, RParenLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == GCCAsmStmtClass; @@ -1648,7 +1673,7 @@ public: /// This represents a Microsoft inline-assembly statement extension. /// class MSAsmStmt : public AsmStmt { - SourceLocation AsmLoc, LBraceLoc, EndLoc; + SourceLocation LBraceLoc, EndLoc; std::string AsmStr; unsigned NumAsmToks; @@ -1717,9 +1742,9 @@ public: StringRef getClobber(unsigned i) const { return Clobbers[i]; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AsmLoc, EndLoc); - } + SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; } + static bool classof(const Stmt *T) { return T->getStmtClass() == MSAsmStmtClass; } @@ -1748,9 +1773,9 @@ public: SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block); - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getExceptLoc(), getEndLoc()); - } + + SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } SourceLocation getExceptLoc() const { return Loc; } SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); } @@ -1760,7 +1785,7 @@ public: } CompoundStmt *getBlock() const { - return llvm::cast<CompoundStmt>(Children[BLOCK]); + return cast<CompoundStmt>(Children[BLOCK]); } child_range children() { @@ -1789,14 +1814,13 @@ public: SourceLocation FinallyLoc, Stmt *Block); - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getFinallyLoc(), getEndLoc()); - } + SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } SourceLocation getFinallyLoc() const { return Loc; } SourceLocation getEndLoc() const { return Block->getLocEnd(); } - CompoundStmt *getBlock() const { return llvm::cast<CompoundStmt>(Block); } + CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); } child_range children() { return child_range(&Block,&Block+1); @@ -1831,9 +1855,8 @@ public: Stmt *TryBlock, Stmt *Handler); - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getTryLoc(), getEndLoc()); - } + SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } SourceLocation getTryLoc() const { return TryLoc; } SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); } @@ -1841,7 +1864,7 @@ public: bool getIsCXXTry() const { return IsCXXTry; } CompoundStmt* getTryBlock() const { - return llvm::cast<CompoundStmt>(Children[TRY]); + return cast<CompoundStmt>(Children[TRY]); } Stmt *getHandler() const { return Children[HANDLER]; } diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index f4e4dcd..0112bef 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -14,6 +14,9 @@ #ifndef LLVM_CLANG_AST_STMTCXX_H #define LLVM_CLANG_AST_STMTCXX_H +#include "clang/AST/DeclarationName.h" +#include "clang/AST/Expr.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Stmt.h" #include "llvm/Support/Compiler.h" @@ -38,8 +41,9 @@ public: CXXCatchStmt(EmptyShell Empty) : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {} - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(CatchLoc, HandlerBlock->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return HandlerBlock->getLocEnd(); } SourceLocation getCatchLoc() const { return CatchLoc; } @@ -62,8 +66,7 @@ class CXXTryStmt : public Stmt { SourceLocation TryLoc; unsigned NumHandlers; - CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers, - unsigned numHandlers); + CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers); CXXTryStmt(EmptyShell Empty, unsigned numHandlers) : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { } @@ -77,15 +80,13 @@ class CXXTryStmt : public Stmt { public: static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc, - Stmt *tryBlock, Stmt **handlers, - unsigned numHandlers); + Stmt *tryBlock, ArrayRef<Stmt*> handlers); static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty, unsigned numHandlers); - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getTryLoc(), getEndLoc()); - } + SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } SourceLocation getTryLoc() const { return TryLoc; } SourceLocation getEndLoc() const { @@ -93,18 +94,18 @@ public: } CompoundStmt *getTryBlock() { - return llvm::cast<CompoundStmt>(getStmts()[0]); + return cast<CompoundStmt>(getStmts()[0]); } const CompoundStmt *getTryBlock() const { - return llvm::cast<CompoundStmt>(getStmts()[0]); + return cast<CompoundStmt>(getStmts()[0]); } unsigned getNumHandlers() const { return NumHandlers; } CXXCatchStmt *getHandler(unsigned i) { - return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]); + return cast<CXXCatchStmt>(getStmts()[i + 1]); } const CXXCatchStmt *getHandler(unsigned i) const { - return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]); + return cast<CXXCatchStmt>(getStmts()[i + 1]); } static bool classof(const Stmt *T) { @@ -188,9 +189,11 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return SubExprs[BODY]->getLocEnd(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXForRangeStmtClass; } @@ -272,9 +275,8 @@ public: return reinterpret_cast<CompoundStmt *>(SubStmt); } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(KeywordLoc, SubStmt->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} child_range children() { return child_range(&SubStmt, &SubStmt+1); diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h index 25d0152..a3e9e1e 100644 --- a/include/clang/AST/StmtGraphTraits.h +++ b/include/clang/AST/StmtGraphTraits.h @@ -16,8 +16,8 @@ #define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H #include "clang/AST/Stmt.h" -#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/GraphTraits.h" namespace llvm { diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index d7a73a7..e97c1a5 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -55,9 +55,11 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return SubExprs[BODY]->getLocEnd(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCForCollectionStmtClass; } @@ -102,9 +104,8 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AtCatchLoc, Body->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); } bool hasEllipsis() const { return getCatchParamDecl() == 0; } @@ -131,8 +132,9 @@ public: Stmt *getFinallyBody() { return AtFinallyStmt; } void setFinallyBody(Stmt *S) { AtFinallyStmt = S; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return AtFinallyLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return AtFinallyStmt->getLocEnd(); } SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; } @@ -236,7 +238,8 @@ public: getStmts()[1 + NumCatchStmts] = S; } - SourceRange getSourceRange() const LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY { return AtTryLoc; } + SourceLocation getLocEnd() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtTryStmtClass; @@ -292,8 +295,9 @@ public: } void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd()); + SourceLocation getLocStart() const LLVM_READONLY { return AtSynchronizedLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return getSynchBody()->getLocEnd(); } static bool classof(const Stmt *T) { @@ -324,11 +328,9 @@ public: SourceLocation getThrowLoc() { return AtThrowLoc; } void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; } - SourceRange getSourceRange() const LLVM_READONLY { - if (Throw) - return SourceRange(AtThrowLoc, Throw->getLocEnd()); - else - return SourceRange(AtThrowLoc); + SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return Throw ? Throw->getLocEnd() : AtThrowLoc; } static bool classof(const Stmt *T) { @@ -355,9 +357,8 @@ public: Stmt *getSubStmt() { return SubStmt; } void setSubStmt(Stmt *S) { SubStmt = S; } - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(AtLoc, SubStmt->getLocEnd()); - } + SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 1c0abde..70b934f 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -15,8 +15,8 @@ #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H #define LLVM_CLANG_AST_TEMPLATEBASE_H -#include "clang/AST/Type.h" #include "clang/AST/TemplateName.h" +#include "clang/AST/Type.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" @@ -72,35 +72,39 @@ private: /// \brief The kind of template argument we're storing. unsigned Kind; + struct DA { + ValueDecl *D; + bool ForRefParam; + }; + struct I { + // We store a decomposed APSInt with the data allocated by ASTContext if + // BitWidth > 64. The memory may be shared between multiple + // TemplateArgument instances. + union { + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + const uint64_t *pVal; ///< Used to store the >64 bits integer value. + }; + unsigned BitWidth : 31; + unsigned IsUnsigned : 1; + void *Type; + }; + struct A { + const TemplateArgument *Args; + unsigned NumArgs; + }; + struct TA { + void *Name; + unsigned NumExpansions; + }; union { + struct DA DeclArg; + struct I Integer; + struct A Args; + struct TA TemplateArg; 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. - union { - uint64_t VAL; ///< Used to store the <= 64 bits integer value. - const uint64_t *pVal; ///< Used to store the >64 bits integer value. - }; - unsigned BitWidth : 31; - unsigned IsUnsigned : 1; - void *Type; - } Integer; - struct { - const TemplateArgument *Args; - unsigned NumArgs; - } Args; - struct { - void *Name; - unsigned NumExpansions; - } TemplateArg; }; - TemplateArgument(TemplateName, bool); // DO NOT USE + TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION; public: /// \brief Construct an empty, invalid template argument. @@ -158,7 +162,7 @@ public: /// /// \param NumExpansions The number of expansions that will be generated by /// instantiating - TemplateArgument(TemplateName Name, llvm::Optional<unsigned> NumExpansions) + TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) : Kind(TemplateExpansion) { TemplateArg.Name = Name.getAsVoidPointer(); @@ -261,7 +265,7 @@ public: /// \brief Retrieve the number of expansions that a template template argument /// expansion will produce, if known. - llvm::Optional<unsigned> getNumTemplateExpansions() const; + Optional<unsigned> getNumTemplateExpansions() const; /// \brief Retrieve the template argument as an integral value. // FIXME: Provide a way to read the integral data without copying the value. @@ -317,6 +321,12 @@ public: return Args.NumArgs; } + /// \brief Return the array of arguments in this template argument pack. + llvm::ArrayRef<TemplateArgument> getPackAsArray() const { + assert(Kind == Pack); + return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs); + } + /// \brief Determines whether two template arguments are superficially the /// same. bool structurallyEquals(const TemplateArgument &Other) const; @@ -335,17 +345,20 @@ public: /// Location information for a TemplateArgument. struct TemplateArgumentLocInfo { private: + + struct T { + // FIXME: We'd like to just use the qualifier in the TemplateName, + // but template arguments get canonicalized too quickly. + NestedNameSpecifier *Qualifier; + void *QualifierLocData; + unsigned TemplateNameLoc; + unsigned EllipsisLoc; + }; + union { + struct T Template; Expr *Expression; TypeSourceInfo *Declarator; - struct { - // FIXME: We'd like to just use the qualifier in the TemplateName, - // but template arguments get canonicalized too quickly. - NestedNameSpecifier *Qualifier; - void *QualifierLocData; - unsigned TemplateNameLoc; - unsigned EllipsisLoc; - } Template; }; public: @@ -490,7 +503,7 @@ public: /// \param NumExpansions Will be set to the number of expansions that will /// be generated from this pack expansion, if known a priori. TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis, - llvm::Optional<unsigned> &NumExpansions, + Optional<unsigned> &NumExpansions, ASTContext &Context) const; }; diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 7dc75b1..0b9d4c8 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -15,9 +15,9 @@ #define LLVM_CLANG_AST_TEMPLATENAME_H #include "clang/Basic/LLVM.h" +#include "clang/Basic/OperatorKinds.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerUnion.h" -#include "clang/Basic/OperatorKinds.h" namespace clang { @@ -46,16 +46,17 @@ protected: SubstTemplateTemplateParmPack }; - union { - struct { - /// \brief A Kind. - unsigned Kind : 2; - - /// \brief The number of stored templates or template arguments, - /// depending on which subclass we have. - unsigned Size : 30; - } Bits; + struct BitsTag { + /// \brief A Kind. + unsigned Kind : 2; + /// \brief The number of stored templates or template arguments, + /// depending on which subclass we have. + unsigned Size : 30; + }; + + union { + struct BitsTag Bits; void *PointerAlignment; }; @@ -308,6 +309,9 @@ public: void print(raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS = false) const; + /// \brief Debugging aid that dumps the template name. + void dump(raw_ostream &OS) const; + /// \brief Debugging aid that dumps the template name to standard /// error. void dump() const; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 6900a7d..23fa3e8 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -14,24 +14,24 @@ #ifndef LLVM_CLANG_AST_TYPE_H #define LLVM_CLANG_AST_TYPE_H +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/TemplateName.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" #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" -#include "llvm/Support/ErrorHandling.h" +#include "clang/Basic/Visibility.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/Twine.h" -#include "clang/Basic/LLVM.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/type_traits.h" namespace clang { enum { @@ -784,8 +784,8 @@ public: /// Executing \c getUnqualifiedType() on the type \c DifferenceType will /// desugar until we hit the type \c Integer, which has no qualifiers on it. /// - /// The resulting type might still be qualified if it's an array - /// type. To strip qualifiers even from within an array type, use + /// The resulting type might still be qualified if it's sugar for an array + /// type. To strip qualifiers even from within a sugared array type, use /// ASTContext::getUnqualifiedArrayType. inline QualType getUnqualifiedType() const; @@ -795,8 +795,8 @@ public: /// Like getUnqualifiedType(), but also returns the set of /// qualifiers that were built up. /// - /// The resulting type might still be qualified if it's an array - /// type. To strip qualifiers even from within an array type, use + /// The resulting type might still be qualified if it's sugar for an array + /// type. To strip qualifiers even from within a sugared array type, use /// ASTContext::getUnqualifiedArrayType. inline SplitQualType getSplitUnqualifiedType() const; @@ -979,10 +979,6 @@ public: /// type other than void. bool isCForbiddenLValueType() const; - /// \brief Determine whether this type has trivial copy/move-assignment - /// semantics. - bool hasTrivialAssignment(ASTContext &Context, bool Copying) const; - private: // These methods are implemented in a separate translation unit; // "static"-ize them to avoid creating temporary QualTypes in the @@ -1002,14 +998,12 @@ private: namespace llvm { /// Implement simplify_type for QualType, so that we can dyn_cast from QualType /// to a specific Type class. -template<> struct simplify_type<const ::clang::QualType> { +template<> struct simplify_type< ::clang::QualType> { typedef const ::clang::Type *SimpleType; - static SimpleType getSimplifiedValue(const ::clang::QualType &Val) { + static SimpleType getSimplifiedValue(::clang::QualType Val) { return Val.getTypePtr(); } }; -template<> struct simplify_type< ::clang::QualType> - : public simplify_type<const ::clang::QualType> {}; // Teach SmallPtrSet that QualType is "basically a pointer". template<> @@ -1195,13 +1189,9 @@ private: /// (for C++0x variadic templates). unsigned ContainsUnexpandedParameterPack : 1; - /// \brief Nonzero if the cache (i.e. the bitfields here starting - /// with 'Cache') is valid. If so, then this is a - /// LangOptions::VisibilityMode+1. - mutable unsigned CacheValidAndVisibility : 2; - - /// \brief True if the visibility was set explicitly in the source code. - mutable unsigned CachedExplicitVisibility : 1; + /// \brief True if the cache (i.e. the bitfields here starting with + /// 'Cache') is valid. + mutable unsigned CacheValid : 1; /// \brief Linkage of this type. mutable unsigned CachedLinkage : 2; @@ -1213,15 +1203,7 @@ private: mutable unsigned FromAST : 1; bool isCacheValid() const { - return (CacheValidAndVisibility != 0); - } - Visibility getVisibility() const { - assert(isCacheValid() && "getting linkage from invalid cache"); - return static_cast<Visibility>(CacheValidAndVisibility-1); - } - bool isVisibilityExplicit() const { - assert(isCacheValid() && "getting linkage from invalid cache"); - return CachedExplicitVisibility; + return CacheValid; } Linkage getLinkage() const { assert(isCacheValid() && "getting linkage from invalid cache"); @@ -1278,11 +1260,6 @@ protected: /// C++ 8.3.5p4: The return type, the parameter type list and the /// cv-qualifier-seq, [...], are part of the function type. unsigned TypeQuals : 3; - - /// \brief The ref-qualifier associated with a \c FunctionProtoType. - /// - /// This is a value of type \c RefQualifierKind. - unsigned RefQualifier : 2; }; class ObjCObjectTypeBitfields { @@ -1382,8 +1359,7 @@ protected: TypeBits.InstantiationDependent = Dependent || InstantiationDependent; TypeBits.VariablyModified = VariablyModified; TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; - TypeBits.CacheValidAndVisibility = 0; - TypeBits.CachedExplicitVisibility = false; + TypeBits.CacheValid = false; TypeBits.CachedLocalOrUnnamed = false; TypeBits.CachedLinkage = NoLinkage; TypeBits.FromAST = false; @@ -1584,6 +1560,20 @@ public: bool isNullPtrType() const; // C++0x nullptr_t bool isAtomicType() const; // C11 _Atomic() + bool isImage1dT() const; // OpenCL image1d_t + bool isImage1dArrayT() const; // OpenCL image1d_array_t + bool isImage1dBufferT() const; // OpenCL image1d_buffer_t + bool isImage2dT() const; // OpenCL image2d_t + bool isImage2dArrayT() const; // OpenCL image2d_array_t + bool isImage3dT() const; // OpenCL image3d_t + + bool isImageType() const; // Any OpenCL image type + + bool isSamplerT() const; // OpenCL sampler_t + bool isEventT() const; // OpenCL event_t + + bool isOpenCLSpecificType() const; // Any OpenCL specific type + /// Determines if this type, which must satisfy /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather /// than implicitly __strong. @@ -1770,16 +1760,21 @@ public: Linkage getLinkage() const; /// \brief Determine the visibility of this type. - Visibility getVisibility() const; + Visibility getVisibility() const { + return getLinkageAndVisibility().getVisibility(); + } /// \brief Return true if the visibility was explicitly set is the code. - bool isVisibilityExplicit() const; + bool isVisibilityExplicit() const { + return getLinkageAndVisibility().isVisibilityExplicit(); + } /// \brief Determine the linkage and visibility of this type. - std::pair<Linkage,Visibility> getLinkageAndVisibility() const; + LinkageInfo getLinkageAndVisibility() const; - /// \brief Note that the linkage is no longer known. - void ClearLinkageCache(); + /// \brief True if the computed linkage is valid. Used for consistency + /// checking. Should always return true. + bool isLinkageValid() const; const char *getTypeClassName() const; @@ -2097,6 +2092,14 @@ public: } }; +/// The inheritance model to use for this member pointer. +enum MSInheritanceModel { + MSIM_Single, + MSIM_Multiple, + MSIM_Virtual, + MSIM_Unspecified +}; + /// MemberPointerType - C++ 8.3.3 - Pointers to members /// class MemberPointerType : public Type, public llvm::FoldingSetNode { @@ -2132,6 +2135,10 @@ public: return !PointeeType->isFunctionProtoType(); } + /// Returns the number of pointer and integer slots used to represent this + /// member pointer in the MS C++ ABI. + std::pair<unsigned, unsigned> getMSMemberPointerSlots() const; + const Type *getClass() const { return Class; } bool isSugared() const { return false; } @@ -2686,8 +2693,7 @@ class FunctionType : public Type { protected: FunctionType(TypeClass tc, QualType res, - unsigned typeQuals, RefQualifierKind RefQualifier, - QualType Canonical, bool Dependent, + unsigned typeQuals, QualType Canonical, bool Dependent, bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack, ExtInfo Info) @@ -2696,20 +2702,18 @@ protected: ResultType(res) { FunctionTypeBits.ExtInfo = Info.Bits; FunctionTypeBits.TypeQuals = typeQuals; - FunctionTypeBits.RefQualifier = static_cast<unsigned>(RefQualifier); } unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; } - RefQualifierKind getRefQualifier() const { - return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier); - } - public: QualType getResultType() const { return ResultType; } bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } unsigned getRegParmType() const { return getExtInfo().getRegParm(); } + /// \brief Determine whether this function type includes the GNU noreturn + /// attribute. The C++11 [[noreturn]] attribute does not affect the function + /// type. bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } CallingConv getCallConv() const { return getExtInfo().getCC(); } ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } @@ -2735,7 +2739,7 @@ public: /// no information available about its arguments. class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) - : FunctionType(FunctionNoProto, Result, 0, RQ_None, Canonical, + : FunctionType(FunctionNoProto, Result, 0, Canonical, /*Dependent=*/false, /*InstantiationDependent=*/false, Result->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false, Info) {} @@ -2804,11 +2808,11 @@ private: return false; } - FunctionProtoType(QualType result, const QualType *args, unsigned numArgs, + FunctionProtoType(QualType result, ArrayRef<QualType> args, QualType canonical, const ExtProtoInfo &epi); /// NumArgs - The number of arguments this function has, not counting '...'. - unsigned NumArgs : 17; + unsigned NumArgs : 15; /// NumExceptions - The number of types in the exception spec, if any. unsigned NumExceptions : 9; @@ -2825,6 +2829,11 @@ private: /// HasTrailingReturn - Whether this function has a trailing return type. unsigned HasTrailingReturn : 1; + /// \brief The ref-qualifier associated with a \c FunctionProtoType. + /// + /// This is a value of type \c RefQualifierKind. + unsigned RefQualifier : 2; + // ArgInfo - There is an variable size array after the class in memory that // holds the argument types. @@ -2864,6 +2873,9 @@ public: assert(i < NumArgs && "Invalid argument number!"); return arg_type_begin()[i]; } + ArrayRef<QualType> getArgTypes() const { + return ArrayRef<QualType>(arg_type_begin(), arg_type_end()); + } ExtProtoInfo getExtProtoInfo() const { ExtProtoInfo EPI; @@ -2972,7 +2984,7 @@ public: /// \brief Retrieve the ref-qualifier associated with this function type. RefQualifierKind getRefQualifier() const { - return FunctionType::getRefQualifier(); + return static_cast<RefQualifierKind>(RefQualifier); } typedef const QualType *arg_type_iterator; @@ -3005,9 +3017,6 @@ public: bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } - // FIXME: Remove the string version. - void printExceptionSpecification(std::string &S, - const PrintingPolicy &Policy) const; void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const; @@ -3323,7 +3332,8 @@ public: attr_stdcall, attr_thiscall, attr_pascal, - attr_pnaclcall + attr_pnaclcall, + attr_inteloclbicc }; private: @@ -3648,21 +3658,6 @@ public: /// \brief Print a template argument list, including the '<' and '>' /// enclosing the template arguments. - // FIXME: remove the string ones. - static std::string PrintTemplateArgumentList(const TemplateArgument *Args, - unsigned NumArgs, - const PrintingPolicy &Policy, - bool SkipBrackets = false); - - static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args, - unsigned NumArgs, - const PrintingPolicy &Policy); - - static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &, - const PrintingPolicy &Policy); - - /// \brief Print a template argument list, including the '<' and '>' - /// enclosing the template arguments. static void PrintTemplateArgumentList(raw_ostream &OS, const TemplateArgument *Args, unsigned NumArgs, @@ -4125,7 +4120,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode { unsigned NumExpansions; PackExpansionType(QualType Pattern, QualType Canon, - llvm::Optional<unsigned> NumExpansions) + Optional<unsigned> NumExpansions) : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), /*InstantiationDependent=*/true, /*VariableModified=*/Pattern->isVariablyModifiedType(), @@ -4143,11 +4138,11 @@ public: /// \brief Retrieve the number of expansions that this pack expansion will /// generate, if known. - llvm::Optional<unsigned> getNumExpansions() const { + Optional<unsigned> getNumExpansions() const { if (NumExpansions) return NumExpansions - 1; - return llvm::Optional<unsigned>(); + return None; } bool isSugared() const { return false; } @@ -4158,9 +4153,9 @@ public: } static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern, - llvm::Optional<unsigned> NumExpansions) { + Optional<unsigned> NumExpansions) { ID.AddPointer(Pattern.getAsOpaquePtr()); - ID.AddBoolean(NumExpansions); + ID.AddBoolean(NumExpansions.hasValue()); if (NumExpansions) ID.AddInteger(*NumExpansions); } @@ -4887,6 +4882,49 @@ inline bool Type::isObjCSelType() const { inline bool Type::isObjCBuiltinType() const { return isObjCIdType() || isObjCClassType() || isObjCSelType(); } + +inline bool Type::isImage1dT() const { + return isSpecificBuiltinType(BuiltinType::OCLImage1d); +} + +inline bool Type::isImage1dArrayT() const { + return isSpecificBuiltinType(BuiltinType::OCLImage1dArray); +} + +inline bool Type::isImage1dBufferT() const { + return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer); +} + +inline bool Type::isImage2dT() const { + return isSpecificBuiltinType(BuiltinType::OCLImage2d); +} + +inline bool Type::isImage2dArrayT() const { + return isSpecificBuiltinType(BuiltinType::OCLImage2dArray); +} + +inline bool Type::isImage3dT() const { + return isSpecificBuiltinType(BuiltinType::OCLImage3d); +} + +inline bool Type::isSamplerT() const { + return isSpecificBuiltinType(BuiltinType::OCLSampler); +} + +inline bool Type::isEventT() const { + return isSpecificBuiltinType(BuiltinType::OCLEvent); +} + +inline bool Type::isImageType() const { + return isImage3dT() || + isImage2dT() || isImage2dArrayT() || + isImage1dT() || isImage1dArrayT() || isImage1dBufferT(); +} + +inline bool Type::isOpenCLSpecificType() const { + return isSamplerT() || isEventT() || isImageType(); +} + inline bool Type::isTemplateTypeParmType() const { return isa<TemplateTypeParmType>(CanonicalType); } diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 8a04bd8..11cad9b 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -14,9 +14,9 @@ #ifndef LLVM_CLANG_AST_TYPELOC_H #define LLVM_CLANG_AST_TYPELOC_H -#include "clang/AST/Type.h" #include "clang/AST/Decl.h" #include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" #include "clang/Basic/Specifiers.h" #include "llvm/Support/Compiler.h" @@ -44,6 +44,29 @@ protected: void *Data; public: + /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc + /// is of the desired type. + template<typename T> + T castAs() const { + assert(T::isKind(*this)); + T t; + TypeLoc& tl = t; + tl = *this; + return t; + } + + /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if + /// this TypeLoc is not of the desired type. + template<typename T> + T getAs() const { + if (!T::isKind(*this)) + return T(); + T t; + TypeLoc& tl = t; + tl = *this; + return t; + } + /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, /// except it also defines a Qualified enum that corresponds to the /// QualifiedLoc class. @@ -119,11 +142,7 @@ public: /// \brief Skips past any qualifiers, if this is qualified. UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header - TypeLoc IgnoreParens() const { - if (isa<ParenTypeLoc>(this)) - return IgnoreParensImpl(*this); - return *this; - } + TypeLoc IgnoreParens() const; /// \brief Initializes this to state that every location in this /// type is the given location. @@ -160,6 +179,10 @@ public: } private: + static bool isKind(const TypeLoc&) { + return true; + } + static void initializeImpl(ASTContext &Context, TypeLoc TL, SourceLocation Loc); static TypeLoc getNextTypeLocImpl(TypeLoc TL); @@ -187,8 +210,10 @@ public: return (TypeLocClass) getTypePtr()->getTypeClass(); } - static bool classof(const TypeLoc *TL) { - return !TL->getType().hasLocalQualifiers(); +private: + friend class TypeLoc; + static bool isKind(const TypeLoc &TL) { + return !TL.getType().hasLocalQualifiers(); } }; @@ -231,15 +256,17 @@ public: getFullDataSizeForType(getType().getLocalUnqualifiedType()); } - static bool classof(const TypeLoc *TL) { - return TL->getType().hasLocalQualifiers(); +private: + friend class TypeLoc; + static bool isKind(const TypeLoc &TL) { + return TL.getType().hasLocalQualifiers(); } }; inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { - if (isa<QualifiedTypeLoc>(this)) - return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc(); - return cast<UnqualTypeLoc>(*this); + if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>()) + return Loc.getUnqualifiedLoc(); + return castAs<UnqualTypeLoc>(); } /// A metaprogramming base class for TypeLoc classes which correspond @@ -280,24 +307,22 @@ class ConcreteTypeLoc : public Base { return static_cast<const Derived*>(this); } -public: - unsigned getLocalDataSize() const { - return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); - } - // Give a default implementation that's useful for leaf types. - unsigned getFullDataSize() const { - return asDerived()->getLocalDataSize() + getInnerTypeSize(); + friend class TypeLoc; + static bool isKind(const TypeLoc &TL) { + return Derived::classofType(TL.getTypePtr()); } static bool classofType(const Type *Ty) { return TypeClass::classof(Ty); } - static bool classof(const TypeLoc *TL) { - return Derived::classofType(TL->getTypePtr()); +public: + unsigned getLocalDataSize() const { + return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); } - static bool classof(const UnqualTypeLoc *TL) { - return Derived::classofType(TL->getTypePtr()); + // Give a default implementation that's useful for leaf types. + unsigned getFullDataSize() const { + return asDerived()->getLocalDataSize() + getInnerTypeSize(); } TypeLoc getNextTypeLoc() const { @@ -362,18 +387,19 @@ private: /// information. See the note on ConcreteTypeLoc. template <class Base, class Derived, class TypeClass> class InheritingConcreteTypeLoc : public Base { -public: + friend class TypeLoc; static bool classofType(const Type *Ty) { return TypeClass::classof(Ty); } - static bool classof(const TypeLoc *TL) { - return Derived::classofType(TL->getTypePtr()); + static bool isKind(const TypeLoc &TL) { + return Derived::classofType(TL.getTypePtr()); } - static bool classof(const UnqualTypeLoc *TL) { - return Derived::classofType(TL->getTypePtr()); + static bool isKind(const UnqualTypeLoc &TL) { + return Derived::classofType(TL.getTypePtr()); } +public: const TypeClass *getTypePtr() const { return cast<TypeClass>(Base::getTypePtr()); } @@ -406,7 +432,9 @@ public: setNameLoc(Loc); } - static bool classof(const TypeLoc *TL); +private: + friend class TypeLoc; + static bool isKind(const TypeLoc &TL); }; @@ -899,6 +927,11 @@ public: } }; +inline TypeLoc TypeLoc::IgnoreParens() const { + if (ParenTypeLoc::isKind(*this)) + return IgnoreParensImpl(*this); + return *this; +} struct PointerLikeLocInfo { SourceLocation StarLoc; diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h index 50fc439..db5775a 100644 --- a/include/clang/AST/TypeLocVisitor.h +++ b/include/clang/AST/TypeLocVisitor.h @@ -21,7 +21,7 @@ namespace clang { #define DISPATCH(CLASSNAME) \ return static_cast<ImplClass*>(this)-> \ - Visit##CLASSNAME(cast<CLASSNAME>(TyLoc)) + Visit##CLASSNAME(TyLoc.castAs<CLASSNAME>()) template<typename ImplClass, typename RetTy=void> class TypeLocVisitor { diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h index 7cf0d5e..59b59f5 100644 --- a/include/clang/AST/TypeOrdering.h +++ b/include/clang/AST/TypeOrdering.h @@ -16,8 +16,8 @@ #ifndef LLVM_CLANG_TYPE_ORDERING_H #define LLVM_CLANG_TYPE_ORDERING_H -#include "clang/AST/Type.h" #include "clang/AST/CanonicalType.h" +#include "clang/AST/Type.h" #include <functional> namespace clang { diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index 9f11ee5..d26065e 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -15,9 +15,11 @@ #ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H #define LLVM_CLANG_AST_UNRESOLVEDSET_H -#include <iterator> -#include "llvm/ADT/SmallVector.h" #include "clang/AST/DeclAccessPair.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include <iterator> namespace clang { @@ -25,12 +27,13 @@ namespace clang { /// non-const iterator. class UnresolvedSetIterator { private: - typedef SmallVectorImpl<DeclAccessPair> DeclsTy; + typedef llvm::MutableArrayRef<DeclAccessPair> DeclsTy; typedef DeclsTy::iterator IteratorTy; IteratorTy ir; friend class UnresolvedSetImpl; + friend class ASTUnresolvedSet; friend class OverloadExpr; explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : @@ -87,7 +90,7 @@ public: /// UnresolvedSet - A set of unresolved declarations. class UnresolvedSetImpl { - typedef UnresolvedSetIterator::DeclsTy DeclsTy; + typedef SmallVectorImpl<DeclAccessPair> DeclsTy; // Don't allow direct construction, and only permit subclassing by // UnresolvedSet. diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h index 6756dd1..f24bb3f 100644 --- a/include/clang/AST/VTTBuilder.h +++ b/include/clang/AST/VTTBuilder.h @@ -102,9 +102,6 @@ class VTTBuilder { bool GenerateDefinition; /// AddVTablePointer - Add a vtable pointer to the VTT currently being built. - /// - /// \param AddressPoints - If the vtable is a construction vtable, this has - /// the address points for it. void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, const CXXRecordDecl *VTableClass); @@ -117,9 +114,6 @@ class VTTBuilder { /// /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base /// or a direct or indirect base of a virtual base. - /// - /// \param AddressPoints - If the vtable is a construction vtable, this has - /// the address points for it. void LayoutSecondaryVirtualPointers(BaseSubobject Base, bool BaseIsMorallyVirtual, uint64_t VTableIndex, @@ -128,9 +122,6 @@ class VTTBuilder { /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers /// for the given base subobject. - /// - /// \param AddressPoints - If the vtable is a construction vtable, this has - /// the address points for it. void LayoutSecondaryVirtualPointers(BaseSubobject Base, uint64_t VTableIndex); diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h index a6aa40b..bcbe875 100644 --- a/include/clang/AST/VTableBuilder.h +++ b/include/clang/AST/VTableBuilder.h @@ -215,12 +215,15 @@ private: /// Address points - Address points for all vtables. AddressPointsMapTy AddressPoints; + bool IsMicrosoftABI; + public: VTableLayout(uint64_t NumVTableComponents, const VTableComponent *VTableComponents, uint64_t NumVTableThunks, const VTableThunkTy *VTableThunks, - const AddressPointsMapTy &AddressPoints); + const AddressPointsMapTy &AddressPoints, + bool IsMicrosoftABI); ~VTableLayout(); uint64_t getNumVTableComponents() const { @@ -252,7 +255,8 @@ public: "Did not find address point!"); uint64_t AddressPoint = AddressPoints.lookup(Base); - assert(AddressPoint && "Address point must not be zero!"); + assert(AddressPoint != 0 || IsMicrosoftABI); + (void)IsMicrosoftABI; return AddressPoint; } @@ -271,6 +275,8 @@ public: typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; private: + bool IsMicrosoftABI; + /// MethodVTableIndices - Contains the index (relative to the vtable address /// point) where the function pointer for a virtual function is stored. typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy; @@ -306,10 +312,21 @@ private: /// given record decl. void ComputeVTableRelatedInformation(const CXXRecordDecl *RD); + /// ErrorUnsupported - Print out an error that the v-table layout code + /// doesn't support the particular C++ feature yet. + void ErrorUnsupported(StringRef Feature, SourceLocation Location); + public: - VTableContext(ASTContext &Context) : Context(Context) {} + VTableContext(ASTContext &Context); ~VTableContext(); + bool isMicrosoftABI() const { + // FIXME: Currently, this method is only used in the VTableContext and + // VTableBuilder code which is ABI-specific. Probably we can remove it + // when we add a layer of abstraction for vtable generation. + return IsMicrosoftABI; + } + const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) { ComputeVTableRelatedInformation(RD); assert(VTableLayouts.count(RD) && "No layout for this record decl!"); |