aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/APValue.h2
-rw-r--r--include/clang/AST/AST.h2
-rw-r--r--include/clang/AST/ASTConsumer.h15
-rw-r--r--include/clang/AST/ASTContext.h253
-rw-r--r--include/clang/AST/ASTImporter.h3
-rw-r--r--include/clang/AST/ASTMutationListener.h9
-rw-r--r--include/clang/AST/ASTTypeTraits.h211
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h86
-rw-r--r--include/clang/AST/ASTVector.h12
-rw-r--r--include/clang/AST/Attr.h171
-rw-r--r--include/clang/AST/AttrIterator.h142
-rw-r--r--include/clang/AST/BuiltinTypes.def14
-rw-r--r--include/clang/AST/CMakeLists.txt13
-rw-r--r--include/clang/AST/CXXInheritance.h4
-rw-r--r--include/clang/AST/CanonicalType.h69
-rw-r--r--include/clang/AST/CharUnits.h11
-rw-r--r--include/clang/AST/Comment.h87
-rw-r--r--include/clang/AST/CommentCommandTraits.h34
-rw-r--r--include/clang/AST/CommentCommands.td92
-rw-r--r--include/clang/AST/CommentHTMLNamedCharacterReferences.td177
-rw-r--r--include/clang/AST/CommentLexer.h13
-rw-r--r--include/clang/AST/CommentParser.h9
-rw-r--r--include/clang/AST/CommentSema.h31
-rw-r--r--include/clang/AST/CommentVisitor.h4
-rw-r--r--include/clang/AST/Decl.h327
-rw-r--r--include/clang/AST/DeclAccessPair.h1
-rw-r--r--include/clang/AST/DeclBase.h129
-rw-r--r--include/clang/AST/DeclCXX.h587
-rw-r--r--include/clang/AST/DeclContextInternals.h24
-rw-r--r--include/clang/AST/DeclFriend.h50
-rw-r--r--include/clang/AST/DeclLookups.h1
-rw-r--r--include/clang/AST/DeclObjC.h339
-rw-r--r--include/clang/AST/DeclOpenMP.h83
-rw-r--r--include/clang/AST/DeclTemplate.h114
-rw-r--r--include/clang/AST/DeclVisitor.h43
-rw-r--r--include/clang/AST/DeclarationName.h85
-rw-r--r--include/clang/AST/DependentDiagnostic.h22
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h23
-rw-r--r--include/clang/AST/Expr.h367
-rw-r--r--include/clang/AST/ExprCXX.h257
-rw-r--r--include/clang/AST/ExprObjC.h126
-rw-r--r--include/clang/AST/ExternalASTSource.h28
-rw-r--r--include/clang/AST/LambdaMangleContext.h4
-rw-r--r--include/clang/AST/Makefile25
-rw-r--r--include/clang/AST/Mangle.h2
-rw-r--r--include/clang/AST/NSAPI.h14
-rw-r--r--include/clang/AST/NestedNameSpecifier.h2
-rw-r--r--include/clang/AST/OperationKinds.h5
-rw-r--r--include/clang/AST/PrettyPrinter.h19
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h36
-rw-r--r--include/clang/AST/Stmt.h229
-rw-r--r--include/clang/AST/StmtCXX.h38
-rw-r--r--include/clang/AST/StmtGraphTraits.h2
-rw-r--r--include/clang/AST/StmtObjC.h37
-rw-r--r--include/clang/AST/TemplateBase.h87
-rw-r--r--include/clang/AST/TemplateName.h24
-rw-r--r--include/clang/AST/Type.h200
-rw-r--r--include/clang/AST/TypeLoc.h93
-rw-r--r--include/clang/AST/TypeLocVisitor.h2
-rw-r--r--include/clang/AST/TypeOrdering.h2
-rw-r--r--include/clang/AST/UnresolvedSet.h11
-rw-r--r--include/clang/AST/VTTBuilder.h9
-rw-r--r--include/clang/AST/VTableBuilder.h23
63 files changed, 3287 insertions, 1647 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index 1b6e90cf4a83..ec8faa4e3524 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 164c5fbbb6e2..6db351d1064b 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 37b0740cb98b..ae779436a9da 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 f0934b77961b..d4878a99a6fe 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 46a9881039c7..1672ab22a3de 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 56d15260a581..6b70285e3ad8 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 000000000000..4688b12de701
--- /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 000000000000..c709895fc0f4
--- /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 4ff5ea37b882..669e50dbeb87 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 12a9855617c0..27dcef2a1e98 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 000000000000..8bd8fbec895d
--- /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 ba322fb32655..488cacef0af3 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 4c4c0fb0a08b..ba54fa2aa92b 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 87bdbe04f3df..2983e04cda34 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 ea307bf307cb..946075739d06 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 12e74b32be8a..082c672c2191 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 316a1801bd46..c02a82f0fa55 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 6d44c706c3dc..d1f5209d1eef 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 3d8bad89c26b..9587ace87caf 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 000000000000..449310871229
--- /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 f2636973ff27..4179f45e80ee 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 19e1d57fc3f5..d6a1072786ed 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 0340b3cfd52d..15e454dcc389 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 47867a634fcc..21641bfeb89f 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 087a58587471..7927279ddd6d 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 7ecd8f8bcd78..5731308f55e6 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 50e202738dd4..852bb9ab0400 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 9cb56e2b3ccc..05ff49c64cea 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 39f04c68a3c7..84f3698d6b58 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 37e45868b57c..253c23c199af 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 867b46525753..4477c25a9135 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 8b27dd8e9e16..c29492298bfc 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 000000000000..ca92040c3286
--- /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 862011666205..425a617738b0 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 62654b8115fc..4eaae35778b9 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 d991c73612c2..f28882b3bf94 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 948dcb461a5a..004b45da0f34 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 d5e9c8c678fe..eb186c217e35 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 dc83654bd948..36d70d8b0b71 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 9c759db1f97a..04f6fb64cfd2 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 27f5da0ce707..dfd45279dd15 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 db2bddb4bfca..81fcf242b65e 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 3e2fbad2f8e6..bbaee26494a9 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 7fb33f27741a..ae84bcfd5817 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 a0dffb93088b..94faa19f1b33 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 f9fd1f906b55..0b21b0334812 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 bf9e1cbc764b..58f39862b102 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 18169fd60c83..5e41d955cfd7 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 7babc1b24a13..e3c09e7b418f 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 f96e06797855..0191964bbfe7 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 a9bbb48f0368..cf8fc249c590 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 f4e4dcdd4a5e..0112befb293f 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 25d015287b75..a3e9e1e093f6 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 d7a73a70bd54..e97c1a5a319f 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 1c0abde5b761..70b934f36c2c 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 7dc75b19257c..0b9d4c85473c 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 6900a7d40af9..23fa3e876566 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 8a04bd8d5ee0..11cad9bb9dd9 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 50fc43913f4c..db5775aa146e 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 7cf0d5e999b6..59b59f517168 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 9f11ee5fe3e2..d26065e3745b 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 6756dd1e993b..f24bb3f16b86 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 a6aa40b9d68b..bcbe8754ea4a 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!");