summaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h9
-rw-r--r--include/clang/AST/ASTContextAllocate.h38
-rw-r--r--include/clang/AST/ASTDumperUtils.h122
-rw-r--r--include/clang/AST/ASTImporter.h25
-rw-r--r--include/clang/AST/ASTImporterLookupTable.h75
-rw-r--r--include/clang/AST/ASTStructuralEquivalence.h1
-rw-r--r--include/clang/AST/ASTVector.h1
-rw-r--r--include/clang/AST/Attr.h1
-rw-r--r--include/clang/AST/AttrIterator.h19
-rw-r--r--include/clang/AST/AttrVisitor.h76
-rw-r--r--include/clang/AST/BaseSubobject.h1
-rw-r--r--include/clang/AST/CMakeLists.txt9
-rw-r--r--include/clang/AST/Decl.h39
-rw-r--r--include/clang/AST/DeclCXX.h3
-rw-r--r--include/clang/AST/DeclObjC.h8
-rw-r--r--include/clang/AST/DeclTemplate.h1
-rw-r--r--include/clang/AST/DeclarationName.h13
-rw-r--r--include/clang/AST/Expr.h297
-rw-r--r--include/clang/AST/ExprCXX.h1173
-rw-r--r--include/clang/AST/ExprObjC.h7
-rw-r--r--include/clang/AST/Mangle.h1
-rw-r--r--include/clang/AST/OpenMPClause.h91
-rw-r--r--include/clang/AST/PrettyPrinter.h5
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h54
-rw-r--r--include/clang/AST/Stmt.h221
-rw-r--r--include/clang/AST/TemplateArgumentVisitor.h99
-rw-r--r--include/clang/AST/TemplateBase.h19
-rw-r--r--include/clang/AST/TemplateName.h1
-rw-r--r--include/clang/AST/TextNodeDumper.h217
-rw-r--r--include/clang/AST/Type.h26
30 files changed, 1758 insertions, 894 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 7edf3b3fed..13870116c7 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H
+#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
@@ -2969,8 +2970,8 @@ 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/AttrIterator.h! Any changes
-/// here need to also be made there.
+/// IMPORTANT: These are also declared in clang/AST/ASTContextAllocate.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
@@ -2993,7 +2994,7 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
/// allocator supports it).
/// @return The allocated memory. Could be nullptr.
inline void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment) {
+ size_t Alignment /* = 8 */) {
return C.Allocate(Bytes, Alignment);
}
@@ -3031,7 +3032,7 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
/// allocator supports it).
/// @return The allocated memory. Could be nullptr.
inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
- size_t Alignment = 8) {
+ size_t Alignment /* = 8 */) {
return C.Allocate(Bytes, Alignment);
}
diff --git a/include/clang/AST/ASTContextAllocate.h b/include/clang/AST/ASTContextAllocate.h
new file mode 100644
index 0000000000..5b9eed208a
--- /dev/null
+++ b/include/clang/AST/ASTContextAllocate.h
@@ -0,0 +1,38 @@
+//===- ASTContextAllocate.h - ASTContext allocate functions -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares ASTContext allocation functions separate from the main
+// code in ASTContext.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
+#define LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
+
+#include <cstddef>
+
+namespace clang {
+
+class ASTContext;
+
+} // namespace clang
+
+// Defined in ASTContext.h
+void *operator new(size_t Bytes, const clang::ASTContext &C,
+ size_t Alignment = 8);
+void *operator new[](size_t Bytes, const clang::ASTContext &C,
+ size_t Alignment = 8);
+
+// 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);
+
+#endif // LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
diff --git a/include/clang/AST/ASTDumperUtils.h b/include/clang/AST/ASTDumperUtils.h
index 129c40ce3e..5e62e902b4 100644
--- a/include/clang/AST/ASTDumperUtils.h
+++ b/include/clang/AST/ASTDumperUtils.h
@@ -14,7 +14,6 @@
#ifndef LLVM_CLANG_AST_ASTDUMPERUTILS_H
#define LLVM_CLANG_AST_ASTDUMPERUTILS_H
-#include "clang/AST/ASTContext.h"
#include "llvm/Support/raw_ostream.h"
namespace clang {
@@ -23,7 +22,7 @@ namespace clang {
// Do not use bold yellow for any text. It is hard to read on white screens.
struct TerminalColor {
- raw_ostream::Colors Color;
+ llvm::raw_ostream::Colors Color;
bool Bold;
};
@@ -38,50 +37,51 @@ struct TerminalColor {
// Bold Cyan - ValueColor, DeclNameColor
// Decl kind names (VarDecl, FunctionDecl, etc)
-static const TerminalColor DeclKindNameColor = {raw_ostream::GREEN, true};
+static const TerminalColor DeclKindNameColor = {llvm::raw_ostream::GREEN, true};
// Attr names (CleanupAttr, GuardedByAttr, etc)
-static const TerminalColor AttrColor = {raw_ostream::BLUE, true};
+static const TerminalColor AttrColor = {llvm::raw_ostream::BLUE, true};
// Statement names (DeclStmt, ImplicitCastExpr, etc)
-static const TerminalColor StmtColor = {raw_ostream::MAGENTA, true};
+static const TerminalColor StmtColor = {llvm::raw_ostream::MAGENTA, true};
// Comment names (FullComment, ParagraphComment, TextComment, etc)
-static const TerminalColor CommentColor = {raw_ostream::BLUE, false};
+static const TerminalColor CommentColor = {llvm::raw_ostream::BLUE, false};
// Type names (int, float, etc, plus user defined types)
-static const TerminalColor TypeColor = {raw_ostream::GREEN, false};
+static const TerminalColor TypeColor = {llvm::raw_ostream::GREEN, false};
// Pointer address
-static const TerminalColor AddressColor = {raw_ostream::YELLOW, false};
+static const TerminalColor AddressColor = {llvm::raw_ostream::YELLOW, false};
// Source locations
-static const TerminalColor LocationColor = {raw_ostream::YELLOW, false};
+static const TerminalColor LocationColor = {llvm::raw_ostream::YELLOW, false};
// lvalue/xvalue
-static const TerminalColor ValueKindColor = {raw_ostream::CYAN, false};
+static const TerminalColor ValueKindColor = {llvm::raw_ostream::CYAN, false};
// bitfield/objcproperty/objcsubscript/vectorcomponent
-static const TerminalColor ObjectKindColor = {raw_ostream::CYAN, false};
+static const TerminalColor ObjectKindColor = {llvm::raw_ostream::CYAN, false};
// Null statements
-static const TerminalColor NullColor = {raw_ostream::BLUE, false};
+static const TerminalColor NullColor = {llvm::raw_ostream::BLUE, false};
// Undeserialized entities
-static const TerminalColor UndeserializedColor = {raw_ostream::GREEN, true};
+static const TerminalColor UndeserializedColor = {llvm::raw_ostream::GREEN,
+ true};
// CastKind from CastExpr's
-static const TerminalColor CastColor = {raw_ostream::RED, false};
+static const TerminalColor CastColor = {llvm::raw_ostream::RED, false};
// Value of the statement
-static const TerminalColor ValueColor = {raw_ostream::CYAN, true};
+static const TerminalColor ValueColor = {llvm::raw_ostream::CYAN, true};
// Decl names
-static const TerminalColor DeclNameColor = {raw_ostream::CYAN, true};
+static const TerminalColor DeclNameColor = {llvm::raw_ostream::CYAN, true};
// Indents ( `, -. | )
-static const TerminalColor IndentColor = {raw_ostream::BLUE, false};
+static const TerminalColor IndentColor = {llvm::raw_ostream::BLUE, false};
class ColorScope {
- raw_ostream &OS;
+ llvm::raw_ostream &OS;
const bool ShowColors;
public:
- ColorScope(raw_ostream &OS, bool ShowColors, TerminalColor Color)
+ ColorScope(llvm::raw_ostream &OS, bool ShowColors, TerminalColor Color)
: OS(OS), ShowColors(ShowColors) {
if (ShowColors)
OS.changeColor(Color.Color, Color.Bold);
@@ -92,90 +92,6 @@ public:
}
};
-class TextTreeStructure {
- raw_ostream &OS;
- const bool ShowColors;
-
- /// Pending[i] is an action to dump an entity at level i.
- llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending;
-
- /// Indicates whether we're at the top level.
- bool TopLevel = true;
-
- /// Indicates if we're handling the first child after entering a new depth.
- bool FirstChild = true;
-
- /// Prefix for currently-being-dumped entity.
- std::string Prefix;
-
-public:
- /// Add a child of the current node. Calls doAddChild without arguments
- template <typename Fn> void addChild(Fn doAddChild) {
- // If we're at the top level, there's nothing interesting to do; just
- // run the dumper.
- if (TopLevel) {
- TopLevel = false;
- doAddChild();
- while (!Pending.empty()) {
- Pending.back()(true);
- Pending.pop_back();
- }
- Prefix.clear();
- OS << "\n";
- TopLevel = true;
- return;
- }
-
- auto dumpWithIndent = [this, doAddChild](bool isLastChild) {
- // Print out the appropriate tree structure and work out the prefix for
- // children of this node. For instance:
- //
- // A Prefix = ""
- // |-B Prefix = "| "
- // | `-C Prefix = "| "
- // `-D Prefix = " "
- // |-E Prefix = " | "
- // `-F Prefix = " "
- // G Prefix = ""
- //
- // Note that the first level gets no prefix.
- {
- OS << '\n';
- ColorScope Color(OS, ShowColors, IndentColor);
- OS << Prefix << (isLastChild ? '`' : '|') << '-';
- this->Prefix.push_back(isLastChild ? ' ' : '|');
- this->Prefix.push_back(' ');
- }
-
- FirstChild = true;
- unsigned Depth = Pending.size();
-
- doAddChild();
-
- // If any children are left, they're the last at their nesting level.
- // Dump those ones out now.
- while (Depth < Pending.size()) {
- Pending.back()(true);
- this->Pending.pop_back();
- }
-
- // Restore the old prefix.
- this->Prefix.resize(Prefix.size() - 2);
- };
-
- if (FirstChild) {
- Pending.push_back(std::move(dumpWithIndent));
- } else {
- Pending.back()(false);
- Pending.back() = std::move(dumpWithIndent);
- }
- FirstChild = false;
- }
-
- TextTreeStructure(raw_ostream &OS, bool ShowColors)
- : OS(OS), ShowColors(ShowColors) {}
-};
-
} // namespace clang
#endif // LLVM_CLANG_AST_ASTDUMPERUTILS_H
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index cbd5c3414b..dbb9cf35dd 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -33,6 +33,7 @@
namespace clang {
class ASTContext;
+class ASTImporterLookupTable;
class CXXBaseSpecifier;
class CXXCtorInitializer;
class Decl;
@@ -80,12 +81,21 @@ class Attr;
/// Imports selected nodes from one AST context into another context,
/// merging AST nodes where appropriate.
class ASTImporter {
+ friend class ASTNodeImporter;
public:
using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
using ImportedCXXBaseSpecifierMap =
llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
private:
+
+ /// Pointer to the import specific lookup table, which may be shared
+ /// amongst several ASTImporter objects.
+ /// This is an externally managed resource (and should exist during the
+ /// lifetime of the ASTImporter object)
+ /// If not set then the original C/C++ lookup is used.
+ ASTImporterLookupTable *LookupTable = nullptr;
+
/// The contexts we're importing to and from.
ASTContext &ToContext, &FromContext;
@@ -123,9 +133,13 @@ class Attr;
/// (which we have already complained about).
NonEquivalentDeclSet NonEquivalentDecls;
+ using FoundDeclsTy = SmallVector<NamedDecl *, 2>;
+ FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
+
+ void AddToLookupTable(Decl *ToD);
+
public:
- /// Create a new AST importer.
- ///
+
/// \param ToContext The context we'll be importing into.
///
/// \param ToFileManager The file manager we'll be importing into.
@@ -137,9 +151,14 @@ class Attr;
/// \param MinimalImport If true, the importer will attempt to import
/// as little as it can, e.g., by importing declarations as forward
/// declarations that can be completed at a later point.
+ ///
+ /// \param LookupTable The importer specific lookup table which may be
+ /// shared amongst several ASTImporter objects.
+ /// If not set then the original C/C++ lookup is used.
ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
ASTContext &FromContext, FileManager &FromFileManager,
- bool MinimalImport);
+ bool MinimalImport,
+ ASTImporterLookupTable *LookupTable = nullptr);
virtual ~ASTImporter();
diff --git a/include/clang/AST/ASTImporterLookupTable.h b/include/clang/AST/ASTImporterLookupTable.h
new file mode 100644
index 0000000000..14cafe817d
--- /dev/null
+++ b/include/clang/AST/ASTImporterLookupTable.h
@@ -0,0 +1,75 @@
+//===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- 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 ASTImporterLookupTable class which implements a
+// lookup procedure for the import mechanism.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
+#define LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
+
+#include "clang/AST/DeclBase.h" // lookup_result
+#include "clang/AST/DeclarationName.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+
+class ASTContext;
+class NamedDecl;
+class DeclContext;
+
+// There are certain cases when normal C/C++ lookup (localUncachedLookup)
+// does not find AST nodes. E.g.:
+// Example 1:
+// template <class T>
+// struct X {
+// friend void foo(); // this is never found in the DC of the TU.
+// };
+// Example 2:
+// // The fwd decl to Foo is not found in the lookupPtr of the DC of the
+// // translation unit decl.
+// // Here we could find the node by doing a traverse throught the list of
+// // the Decls in the DC, but that would not scale.
+// struct A { struct Foo *p; };
+// This is a severe problem because the importer decides if it has to create a
+// new Decl or not based on the lookup results.
+// To overcome these cases we need an importer specific lookup table which
+// holds every node and we are not interested in any C/C++ specific visibility
+// considerations. Simply, we must know if there is an existing Decl in a
+// given DC. Once we found it then we can handle any visibility related tasks.
+class ASTImporterLookupTable {
+
+ // We store a list of declarations for each name.
+ // And we collect these lists for each DeclContext.
+ // We could have a flat map with (DeclContext, Name) tuple as key, but a two
+ // level map seems easier to handle.
+ using DeclList = llvm::SmallSetVector<NamedDecl *, 2>;
+ using NameMap = llvm::SmallDenseMap<DeclarationName, DeclList, 4>;
+ using DCMap = llvm::DenseMap<DeclContext *, NameMap>;
+
+ void add(DeclContext *DC, NamedDecl *ND);
+ void remove(DeclContext *DC, NamedDecl *ND);
+
+ DCMap LookupTable;
+
+public:
+ ASTImporterLookupTable(TranslationUnitDecl &TU);
+ void add(NamedDecl *ND);
+ void remove(NamedDecl *ND);
+ using LookupResult = DeclList;
+ LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
+ void dump(DeclContext *DC) const;
+ void dump() const;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h
index 2037796cd5..f8847505bc 100644
--- a/include/clang/AST/ASTStructuralEquivalence.h
+++ b/include/clang/AST/ASTStructuralEquivalence.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
#define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
+#include "clang/AST/DeclBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 80cd6b7007..51de119f08 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -18,6 +18,7 @@
#ifndef LLVM_CLANG_AST_ASTVECTOR_H
#define LLVM_CLANG_AST_ASTVECTOR_H
+#include "clang/AST/ASTContextAllocate.h"
#include "llvm/ADT/PointerIntPair.h"
#include <algorithm>
#include <cassert>
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 4ee083934c..3a319326d2 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_ATTR_H
#define LLVM_CLANG_AST_ATTR_H
+#include "clang/AST/ASTContextAllocate.h" // For Attrs.inc
#include "clang/AST/AttrIterator.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index 2087ecc0e7..43ad1c9319 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -26,25 +26,6 @@ namespace clang {
class ASTContext;
class Attr;
-} // namespace clang
-
-// Defined in ASTContext.h
-void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment = 8);
-
-// 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.
using AttrVec = SmallVector<Attr *, 4>;
diff --git a/include/clang/AST/AttrVisitor.h b/include/clang/AST/AttrVisitor.h
new file mode 100644
index 0000000000..867f9e7ad1
--- /dev/null
+++ b/include/clang/AST/AttrVisitor.h
@@ -0,0 +1,76 @@
+//===- AttrVisitor.h - Visitor for Attr subclasses --------------*- 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 AttrVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ATTRVISITOR_H
+#define LLVM_CLANG_AST_ATTRVISITOR_H
+
+#include "clang/AST/Attr.h"
+
+namespace clang {
+
+namespace attrvisitor {
+
+/// A simple visitor class that helps create attribute visitors.
+template <template <typename> class Ptr, typename ImplClass,
+ typename RetTy = void, class... ParamTys>
+class Base {
+public:
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(NAME) \
+ return static_cast<ImplClass *>(this)->Visit##NAME(static_cast<PTR(NAME)>(A))
+
+ RetTy Visit(PTR(Attr) A) {
+ switch (A->getKind()) {
+
+#define ATTR(NAME) \
+ case attr::NAME: \
+ DISPATCH(NAME##Attr);
+#include "clang/Basic/AttrList.inc"
+ }
+ llvm_unreachable("Attr that isn't part of AttrList.inc!");
+ }
+
+ // If the implementation chooses not to implement a certain visit
+ // method, fall back to the parent.
+#define ATTR(NAME) \
+ RetTy Visit##NAME##Attr(PTR(NAME##Attr) A) { DISPATCH(Attr); }
+#include "clang/Basic/AttrList.inc"
+
+ RetTy VisitAttr(PTR(Attr)) { return RetTy(); }
+
+#undef PTR
+#undef DISPATCH
+};
+
+} // namespace attrvisitor
+
+/// A simple visitor class that helps create attribute visitors.
+///
+/// This class does not preserve constness of Attr pointers (see
+/// also ConstAttrVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class AttrVisitor : public attrvisitor::Base<std::add_pointer, ImplClass, RetTy,
+ ParamTys...> {};
+
+/// A simple visitor class that helps create attribute visitors.
+///
+/// This class preserves constness of Attr pointers (see also
+/// AttrVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class ConstAttrVisitor
+ : public attrvisitor::Base<llvm::make_const_ptr, ImplClass, RetTy,
+ ParamTys...> {};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ATTRVISITOR_H
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
index 2b702c76b2..8fd4ac69eb 100644
--- a/include/clang/AST/BaseSubobject.h
+++ b/include/clang/AST/BaseSubobject.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_BASESUBOBJECT_H
#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/type_traits.h"
#include <cstdint>
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index 942d08d585..da16987141 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -8,10 +8,15 @@ clang_tablegen(AttrImpl.inc -gen-clang-attr-impl
SOURCE ../Basic/Attr.td
TARGET ClangAttrImpl)
-clang_tablegen(AttrDump.inc -gen-clang-attr-dump
+clang_tablegen(AttrTextNodeDump.inc -gen-clang-attr-text-node-dump
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
- TARGET ClangAttrDump)
+ TARGET ClangAttrTextDump)
+
+clang_tablegen(AttrNodeTraverse.inc -gen-clang-attr-node-traverse
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE ../Basic/Attr.td
+ TARGET ClangAttrTraverse)
clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 3145f35ead..de2765391f 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_DECL_H
#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
@@ -866,8 +867,12 @@ private:
unsigned SClass : 3;
unsigned TSCSpec : 2;
unsigned InitStyle : 2;
+
+ /// Whether this variable is an ARC pseudo-__strong variable; see
+ /// isARCPseudoStrong() for details.
+ unsigned ARCPseudoStrong : 1;
};
- enum { NumVarDeclBits = 7 };
+ enum { NumVarDeclBits = 8 };
protected:
enum { NumParameterIndexBits = 8 };
@@ -940,10 +945,6 @@ protected:
/// Whether this variable is the for-in loop declaration in Objective-C.
unsigned ObjCForDecl : 1;
- /// Whether this variable is an ARC pseudo-__strong
- /// variable; see isARCPseudoStrong() for details.
- unsigned ARCPseudoStrong : 1;
-
/// Whether this variable is (C++1z) inline.
unsigned IsInline : 1;
@@ -1349,17 +1350,15 @@ public:
NonParmVarDeclBits.ObjCForDecl = FRD;
}
- /// Determine whether this variable is an ARC pseudo-__strong
- /// variable. A pseudo-__strong variable has a __strong-qualified
- /// type but does not actually retain the object written into it.
- /// Generally such variables are also 'const' for safety.
- bool isARCPseudoStrong() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ARCPseudoStrong;
- }
- void setARCPseudoStrong(bool ps) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.ARCPseudoStrong = ps;
- }
+ /// Determine whether this variable is an ARC pseudo-__strong variable. A
+ /// pseudo-__strong variable has a __strong-qualified type but does not
+ /// actually retain the object written into it. Generally such variables are
+ /// also 'const' for safety. There are 3 cases where this will be set, 1) if
+ /// the variable is annotated with the objc_externally_retained attribute, 2)
+ /// if its 'self' in a non-init method, or 3) if its the variable in an for-in
+ /// loop.
+ bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
+ void setARCPseudoStrong(bool PS) { VarDeclBits.ARCPseudoStrong = PS; }
/// Whether this variable is (C++1z) inline.
bool isInline() const {
@@ -2327,14 +2326,6 @@ public:
getASTContext());
}
- /// Returns the WarnUnusedResultAttr that is either declared on this
- /// function, or its return type declaration.
- const Attr *getUnusedResultAttr() const;
-
- /// Returns true if this function or its return type has the
- /// warn_unused_result attribute.
- bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; }
-
/// Returns the storage class as written in the source. For the
/// computed linkage of symbol, see getLinkage.
StorageClass getStorageClass() const {
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 58e01bf0f0..d3357c245d 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -2180,7 +2180,7 @@ public:
/// that for the call operator of a lambda closure type, this returns the
/// desugared 'this' type (a pointer to the closure type), not the captured
/// 'this' type.
- QualType getThisType(ASTContext &C) const;
+ QualType getThisType() const;
static QualType getThisType(const FunctionProtoType *FPT,
const CXXRecordDecl *Decl);
@@ -3918,6 +3918,7 @@ class MSPropertyDecl : public DeclaratorDecl {
: DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
GetterId(Getter), SetterId(Setter) {}
+ void anchor() override;
public:
friend class ASTDeclReader;
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index bc10ba42c6..5b57411f97 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -369,6 +369,14 @@ public:
NumParams);
}
+ ParmVarDecl *getParamDecl(unsigned Idx) {
+ assert(Idx < NumParams && "Index out of bounds!");
+ return getParams()[Idx];
+ }
+ const ParmVarDecl *getParamDecl(unsigned Idx) const {
+ return const_cast<ObjCMethodDecl *>(this)->getParamDecl(Idx);
+ }
+
/// Sets the method's parameters and selector source locations.
/// If the method is implicit (not coming from source) \p SelLocs is
/// ignored.
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 9e01c4950d..f6e3d8f300 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -751,6 +751,7 @@ class RedeclarableTemplateDecl : public TemplateDecl,
return getMostRecentDecl();
}
+ void anchor() override;
protected:
template <typename EntryType> struct SpecEntryTraits {
using DeclType = EntryType;
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index d196233de1..62afae23ec 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -729,9 +729,10 @@ public:
/// getNamedTypeInfo - Returns the source type info associated to
/// the name. Assumes it is a constructor, destructor or conversion.
TypeSourceInfo *getNamedTypeInfo() const {
- assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXDestructorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+ if (Name.getNameKind() != DeclarationName::CXXConstructorName &&
+ Name.getNameKind() != DeclarationName::CXXDestructorName &&
+ Name.getNameKind() != DeclarationName::CXXConversionFunctionName)
+ return nullptr;
return LocInfo.NamedType.TInfo;
}
@@ -747,7 +748,8 @@ public:
/// getCXXOperatorNameRange - Gets the range of the operator name
/// (without the operator keyword). Assumes it is a (non-literal) operator.
SourceRange getCXXOperatorNameRange() const {
- assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+ if (Name.getNameKind() != DeclarationName::CXXOperatorName)
+ return SourceRange();
return SourceRange(
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
@@ -766,7 +768,8 @@ public:
/// operator name (not the operator keyword).
/// Assumes it is a literal operator.
SourceLocation getCXXLiteralOperatorNameLoc() const {
- assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+ if (Name.getNameKind() != DeclarationName::CXXLiteralOperatorName)
+ return SourceLocation();
return SourceLocation::
getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
}
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index d57c45eec0..3de7342882 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -945,7 +945,6 @@ public:
class OpaqueValueExpr : public Expr {
friend class ASTStmtReader;
Expr *SourceExpr;
- SourceLocation Loc;
public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
@@ -959,8 +958,9 @@ public:
T->isInstantiationDependentType() ||
(SourceExpr && SourceExpr->isInstantiationDependent()),
false),
- SourceExpr(SourceExpr), Loc(Loc) {
+ SourceExpr(SourceExpr) {
setIsUnique(false);
+ OpaqueValueExprBits.Loc = Loc;
}
/// Given an expression which invokes a copy constructor --- i.e. a
@@ -969,20 +969,19 @@ public:
static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
explicit OpaqueValueExpr(EmptyShell Empty)
- : Expr(OpaqueValueExprClass, Empty) { }
+ : Expr(OpaqueValueExprClass, Empty) {}
/// Retrieve the location of this expression.
- SourceLocation getLocation() const { return Loc; }
+ SourceLocation getLocation() const { return OpaqueValueExprBits.Loc; }
SourceLocation getBeginLoc() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getBeginLoc() : Loc;
+ return SourceExpr ? SourceExpr->getBeginLoc() : getLocation();
}
SourceLocation getEndLoc() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getEndLoc() : Loc;
+ return SourceExpr ? SourceExpr->getEndLoc() : getLocation();
}
SourceLocation getExprLoc() const LLVM_READONLY {
- if (SourceExpr) return SourceExpr->getExprLoc();
- return Loc;
+ return SourceExpr ? SourceExpr->getExprLoc() : getLocation();
}
child_range children() {
@@ -1086,20 +1085,10 @@ class DeclRefExpr final
void computeDependence(const ASTContext &Ctx);
public:
- DeclRefExpr(ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T,
+ DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
+ bool RefersToEnclosingVariableOrCapture, QualType T,
ExprValueKind VK, SourceLocation L,
- const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
- D(D), DNLoc(LocInfo) {
- DeclRefExprBits.HasQualifier = false;
- DeclRefExprBits.HasTemplateKWAndArgsInfo = false;
- DeclRefExprBits.HasFoundDecl = false;
- DeclRefExprBits.HadMultipleCandidates = false;
- DeclRefExprBits.RefersToEnclosingVariableOrCapture =
- RefersToEnclosingVariableOrCapture;
- DeclRefExprBits.Loc = L;
- computeDependence(D->getASTContext());
- }
+ const DeclarationNameLoc &LocInfo = DeclarationNameLoc());
static DeclRefExpr *
Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
@@ -2405,59 +2394,126 @@ public:
/// a subclass for overloaded operator calls that use operator syntax, e.g.,
/// "str1 + str2" to resolve to a function call.
class CallExpr : public Expr {
- enum { FN=0, PREARGS_START=1 };
- Stmt **SubExprs;
+ enum { FN = 0, PREARGS_START = 1 };
+
+ /// The number of arguments in the call expression.
unsigned NumArgs;
+
+ /// The location of the right parenthese. This has a different meaning for
+ /// the derived classes of CallExpr.
SourceLocation RParenLoc;
void updateDependenciesFromArg(Expr *Arg);
+ // CallExpr store some data in trailing objects. However since CallExpr
+ // is used a base of other expression classes we cannot use
+ // llvm::TrailingObjects. Instead we manually perform the pointer arithmetic
+ // and casts.
+ //
+ // The trailing objects are in order:
+ //
+ // * A single "Stmt *" for the callee expression.
+ //
+ // * An array of getNumPreArgs() "Stmt *" for the pre-argument expressions.
+ //
+ // * An array of getNumArgs() "Stmt *" for the argument expressions.
+ //
+ // Note that we store the offset in bytes from the this pointer to the start
+ // of the trailing objects. It would be perfectly possible to compute it
+ // based on the dynamic kind of the CallExpr. However 1.) we have plenty of
+ // space in the bit-fields of Stmt. 2.) It was benchmarked to be faster to
+ // compute this once and then load the offset from the bit-fields of Stmt,
+ // instead of re-computing the offset each time the trailing objects are
+ // accessed.
+
+ /// Return a pointer to the start of the trailing array of "Stmt *".
+ Stmt **getTrailingStmts() {
+ return reinterpret_cast<Stmt **>(reinterpret_cast<char *>(this) +
+ CallExprBits.OffsetToTrailingObjects);
+ }
+ Stmt *const *getTrailingStmts() const {
+ return const_cast<CallExpr *>(this)->getTrailingStmts();
+ }
+
+ /// Map a statement class to the appropriate offset in bytes from the
+ /// this pointer to the trailing objects.
+ static unsigned offsetToTrailingObjects(StmtClass SC);
+
public:
enum class ADLCallKind : bool { NotADL, UsesADL };
static constexpr ADLCallKind NotADL = ADLCallKind::NotADL;
static constexpr ADLCallKind UsesADL = ADLCallKind::UsesADL;
protected:
- // These versions of the constructor are for derived classes.
- CallExpr(const ASTContext &C, StmtClass SC, Expr *fn,
- ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc, unsigned MinNumArgs = 0,
- ADLCallKind UsesADL = NotADL);
- CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef<Expr *> args,
- QualType t, ExprValueKind VK, SourceLocation rparenloc,
- unsigned MinNumArgs = 0, ADLCallKind UsesADL = NotADL);
- CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
- unsigned NumArgs, EmptyShell Empty);
-
- Stmt *getPreArg(unsigned i) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
- }
- const Stmt *getPreArg(unsigned i) const {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
- }
- void setPreArg(unsigned i, Stmt *PreArg) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- SubExprs[PREARGS_START+i] = PreArg;
+ /// Build a call expression, assuming that appropriate storage has been
+ /// allocated for the trailing objects.
+ CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation RParenLoc, unsigned MinNumArgs, ADLCallKind UsesADL);
+
+ /// Build an empty call expression, for deserialization.
+ CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
+ EmptyShell Empty);
+
+ /// Return the size in bytes needed for the trailing objects.
+ /// Used by the derived classes to allocate the right amount of storage.
+ static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs) {
+ return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *);
+ }
+
+ Stmt *getPreArg(unsigned I) {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ return getTrailingStmts()[PREARGS_START + I];
+ }
+ const Stmt *getPreArg(unsigned I) const {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ return getTrailingStmts()[PREARGS_START + I];
+ }
+ void setPreArg(unsigned I, Stmt *PreArg) {
+ assert(I < getNumPreArgs() && "Prearg access out of range!");
+ getTrailingStmts()[PREARGS_START + I] = PreArg;
}
unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
public:
- /// Build a call expression. MinNumArgs specifies the minimum number of
- /// arguments. The actual number of arguments will be the greater of
- /// args.size() and MinNumArgs.
- CallExpr(const ASTContext &C, Expr *fn, ArrayRef<Expr *> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc, unsigned MinNumArgs = 0,
- ADLCallKind UsesADL = NotADL);
+ /// Create a call expression. Fn is the callee expression, Args is the
+ /// argument array, Ty is the type of the call expression (which is *not*
+ /// the return type in general), VK is the value kind of the call expression
+ /// (lvalue, rvalue, ...), and RParenLoc is the location of the right
+ /// parenthese in the call expression. MinNumArgs specifies the minimum
+ /// number of arguments. The actual number of arguments will be the greater
+ /// of Args.size() and MinNumArgs. This is used in a few places to allocate
+ /// enough storage for the default arguments. UsesADL specifies whether the
+ /// callee was found through argument-dependent lookup.
+ ///
+ /// Note that you can use CreateTemporary if you need a temporary call
+ /// expression on the stack.
+ static CallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation RParenLoc, unsigned MinNumArgs = 0,
+ ADLCallKind UsesADL = NotADL);
+
+ /// Create a temporary call expression with no arguments in the memory
+ /// pointed to by Mem. Mem must points to at least sizeof(CallExpr)
+ /// + sizeof(Stmt *) bytes of storage, aligned to alignof(CallExpr):
+ ///
+ /// \code{.cpp}
+ /// llvm::AlignedCharArray<alignof(CallExpr),
+ /// sizeof(CallExpr) + sizeof(Stmt *)> Buffer;
+ /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer.buffer, etc);
+ /// \endcode
+ static CallExpr *CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
+ ExprValueKind VK, SourceLocation RParenLoc,
+ ADLCallKind UsesADL = NotADL);
- /// Build an empty call expression.
- CallExpr(const ASTContext &C, unsigned NumArgs, EmptyShell Empty);
+ /// Create an empty call expression, for deserialization.
+ static CallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+ EmptyShell Empty);
- const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
- Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
- void setCallee(Expr *F) { SubExprs[FN] = F; }
+ Expr *getCallee() { return cast<Expr>(getTrailingStmts()[FN]); }
+ const Expr *getCallee() const { return cast<Expr>(getTrailingStmts()[FN]); }
+ void setCallee(Expr *F) { getTrailingStmts()[FN] = F; }
ADLCallKind getADLCallKind() const {
return static_cast<ADLCallKind>(CallExprBits.UsesADL);
@@ -2467,55 +2523,56 @@ public:
}
bool usesADL() const { return getADLCallKind() == UsesADL; }
- Decl *getCalleeDecl();
+ Decl *getCalleeDecl() { return getCallee()->getReferencedDeclOfCallee(); }
const Decl *getCalleeDecl() const {
- return const_cast<CallExpr*>(this)->getCalleeDecl();
+ return getCallee()->getReferencedDeclOfCallee();
}
- /// If the callee is a FunctionDecl, return it. Otherwise return 0.
- FunctionDecl *getDirectCallee();
+ /// If the callee is a FunctionDecl, return it. Otherwise return null.
+ FunctionDecl *getDirectCallee() {
+ return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
+ }
const FunctionDecl *getDirectCallee() const {
- return const_cast<CallExpr*>(this)->getDirectCallee();
+ return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
}
/// getNumArgs - Return the number of actual arguments to this call.
- ///
unsigned getNumArgs() const { return NumArgs; }
/// Retrieve the call arguments.
Expr **getArgs() {
- return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START);
+ return reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START +
+ getNumPreArgs());
}
const Expr *const *getArgs() const {
- return reinterpret_cast<Expr **>(SubExprs + getNumPreArgs() +
- PREARGS_START);
+ return reinterpret_cast<const Expr *const *>(
+ getTrailingStmts() + PREARGS_START + getNumPreArgs());
}
/// getArg - Return the specified argument.
Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
/// setArg - Set the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ getArgs()[Arg] = ArgExpr;
}
/// Reduce the number of arguments in this call expression. This is used for
/// example during error recovery to drop extra arguments. There is no way
/// to perform the opposite because: 1.) We don't track how much storage
/// we have for the argument array 2.) This would potentially require growing
- /// the argument array, something we cannot support since the arguments will
- /// be stored in a trailing array in the future.
- /// (TODO: update this comment when this is done).
+ /// the argument array, something we cannot support since the arguments are
+ /// stored in a trailing array.
void shrinkNumArgs(unsigned NewNumArgs) {
- assert((NewNumArgs <= NumArgs) &&
+ assert((NewNumArgs <= getNumArgs()) &&
"shrinkNumArgs cannot increase the number of arguments!");
NumArgs = NewNumArgs;
}
@@ -2530,29 +2587,28 @@ public:
return const_arg_range(arg_begin(), arg_end());
}
- arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
- arg_iterator arg_end() {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+ arg_iterator arg_begin() {
+ return getTrailingStmts() + PREARGS_START + getNumPreArgs();
}
+ arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
+
const_arg_iterator arg_begin() const {
- return SubExprs+PREARGS_START+getNumPreArgs();
- }
- const_arg_iterator arg_end() const {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+ return getTrailingStmts() + PREARGS_START + getNumPreArgs();
}
+ const_arg_iterator arg_end() const { return arg_begin() + 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 llvm::makeArrayRef(SubExprs,
- getNumPreArgs() + PREARGS_START + getNumArgs());
+ ArrayRef<Stmt *> getRawSubExprs() {
+ return llvm::makeArrayRef(getTrailingStmts(),
+ PREARGS_START + getNumPreArgs() + getNumArgs());
}
/// getNumCommas - Return the number of commas that must have been present in
/// this function call.
- unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
+ unsigned getNumCommas() const { return getNumArgs() ? getNumArgs() - 1 : 0; }
/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
/// of the callee. If not, return 0.
@@ -2567,6 +2623,15 @@ public:
/// type.
QualType getCallReturnType(const ASTContext &Ctx) const;
+ /// Returns the WarnUnusedResultAttr that is either declared on the called
+ /// function, or its return type declaration.
+ const Attr *getUnusedResultAttr(const ASTContext &Ctx) const;
+
+ /// Returns true if this call expression should warn on unused results.
+ bool hasUnusedResultAttr(const ASTContext &Ctx) const {
+ return getUnusedResultAttr(Ctx) != nullptr;
+ }
+
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
@@ -2578,7 +2643,7 @@ public:
bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
bool isCallToStdMove() const {
- const FunctionDecl* FD = getDirectCallee();
+ const FunctionDecl *FD = getDirectCallee();
return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
FD->getIdentifier() && FD->getIdentifier()->isStr("move");
}
@@ -2590,13 +2655,14 @@ public:
// Iterators
child_range children() {
- return child_range(&SubExprs[0],
- &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
+ return child_range(getTrailingStmts(), getTrailingStmts() + PREARGS_START +
+ getNumPreArgs() + getNumArgs());
}
const_child_range children() const {
- return const_child_range(&SubExprs[0], &SubExprs[0] + NumArgs +
- getNumPreArgs() + PREARGS_START);
+ return const_child_range(getTrailingStmts(),
+ getTrailingStmts() + PREARGS_START +
+ getNumPreArgs() + getNumArgs());
}
};
@@ -2930,28 +2996,15 @@ public:
/// representation in the source code (ExplicitCastExpr's derived
/// classes).
class CastExpr : public Expr {
-public:
- using BasePathSizeTy = unsigned int;
- static_assert(std::numeric_limits<BasePathSizeTy>::max() >= 16384,
- "[implimits] Direct and indirect base classes [16384].");
-
-private:
Stmt *Op;
bool CastConsistency() const;
- BasePathSizeTy *BasePathSize();
-
const CXXBaseSpecifier * const *path_buffer() const {
return const_cast<CastExpr*>(this)->path_buffer();
}
CXXBaseSpecifier **path_buffer();
- void setBasePathSize(BasePathSizeTy basePathSize) {
- assert(!path_empty() && basePathSize != 0);
- *(BasePathSize()) = basePathSize;
- }
-
protected:
CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
Expr *op, unsigned BasePathSize)
@@ -2972,9 +3025,9 @@ protected:
Op(op) {
CastExprBits.Kind = kind;
CastExprBits.PartOfExplicitCast = false;
- CastExprBits.BasePathIsEmpty = BasePathSize == 0;
- if (!path_empty())
- setBasePathSize(BasePathSize);
+ CastExprBits.BasePathSize = BasePathSize;
+ assert((CastExprBits.BasePathSize == BasePathSize) &&
+ "BasePathSize overflow!");
assert(CastConsistency());
}
@@ -2982,9 +3035,9 @@ protected:
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
: Expr(SC, Empty) {
CastExprBits.PartOfExplicitCast = false;
- CastExprBits.BasePathIsEmpty = BasePathSize == 0;
- if (!path_empty())
- setBasePathSize(BasePathSize);
+ CastExprBits.BasePathSize = BasePathSize;
+ assert((CastExprBits.BasePathSize == BasePathSize) &&
+ "BasePathSize overflow!");
}
public:
@@ -3011,13 +3064,9 @@ public:
NamedDecl *getConversionFunction() const;
typedef CXXBaseSpecifier **path_iterator;
- typedef const CXXBaseSpecifier * const *path_const_iterator;
- bool path_empty() const { return CastExprBits.BasePathIsEmpty; }
- unsigned path_size() const {
- if (path_empty())
- return 0U;
- return *(const_cast<CastExpr *>(this)->BasePathSize());
- }
+ typedef const CXXBaseSpecifier *const *path_const_iterator;
+ bool path_empty() const { return path_size() == 0; }
+ unsigned path_size() const { return CastExprBits.BasePathSize; }
path_iterator path_begin() { return path_buffer(); }
path_iterator path_end() { return path_buffer() + path_size(); }
path_const_iterator path_begin() const { return path_buffer(); }
@@ -3065,13 +3114,8 @@ public:
/// @endcode
class ImplicitCastExpr final
: public CastExpr,
- private llvm::TrailingObjects<ImplicitCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
+ private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> {
-private:
ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
unsigned BasePathLength, ExprValueKind VK)
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { }
@@ -3179,8 +3223,7 @@ public:
/// (Type)expr. For example: @c (int)f.
class CStyleCastExpr final
: public ExplicitCastExpr,
- private llvm::TrailingObjects<CStyleCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> {
SourceLocation LPLoc; // the location of the left paren
SourceLocation RPLoc; // the location of the right paren
@@ -3194,10 +3237,6 @@ class CStyleCastExpr final
explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind K,
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index f39bddb040..6ef837a2fc 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -75,47 +75,46 @@ class TemplateParameterList;
/// function itself will be a (possibly empty) set of functions and
/// function templates that were found by name lookup at template
/// definition time.
-class CXXOperatorCallExpr : public CallExpr {
- /// The overloaded operator.
- OverloadedOperatorKind Operator;
+class CXXOperatorCallExpr final : public CallExpr {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
SourceRange Range;
- // Only meaningful for floating point types.
- FPOptions FPFeatures;
+ // CXXOperatorCallExpr has some trailing objects belonging
+ // to CallExpr. See CallExpr for the details.
SourceRange getSourceRangeImpl() const LLVM_READONLY;
-public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
+ CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation OperatorLoc, FPOptions FPFeatures,
+ ADLCallKind UsesADL);
- CXXOperatorCallExpr(ASTContext &C, OverloadedOperatorKind Op, Expr *fn,
- ArrayRef<Expr *> args, QualType t, ExprValueKind VK,
- SourceLocation operatorloc, FPOptions FPFeatures,
- ADLCallKind UsesADL = NotADL)
- : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc,
- /*MinNumArgs=*/0, UsesADL),
- Operator(Op), FPFeatures(FPFeatures) {
- Range = getSourceRangeImpl();
- }
+ CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
- explicit CXXOperatorCallExpr(ASTContext &C, unsigned NumArgs,
- EmptyShell Empty)
- : CallExpr(C, CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs,
- Empty) {}
+public:
+ static CXXOperatorCallExpr *
+ Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation OperatorLoc, FPOptions FPFeatures,
+ ADLCallKind UsesADL = NotADL);
- /// Returns the kind of overloaded operator that this
- /// expression refers to.
- OverloadedOperatorKind getOperator() const { return Operator; }
+ static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumArgs, EmptyShell Empty);
+
+ /// Returns the kind of overloaded operator that this expression refers to.
+ OverloadedOperatorKind getOperator() const {
+ return static_cast<OverloadedOperatorKind>(
+ CXXOperatorCallExprBits.OperatorKind);
+ }
static bool isAssignmentOp(OverloadedOperatorKind Opc) {
- return Opc == OO_Equal || Opc == OO_StarEqual ||
- Opc == OO_SlashEqual || Opc == OO_PercentEqual ||
- Opc == OO_PlusEqual || Opc == OO_MinusEqual ||
- Opc == OO_LessLessEqual || Opc == OO_GreaterGreaterEqual ||
- Opc == OO_AmpEqual || Opc == OO_CaretEqual ||
- Opc == OO_PipeEqual;
+ return Opc == OO_Equal || Opc == OO_StarEqual || Opc == OO_SlashEqual ||
+ Opc == OO_PercentEqual || Opc == OO_PlusEqual ||
+ Opc == OO_MinusEqual || Opc == OO_LessLessEqual ||
+ Opc == OO_GreaterGreaterEqual || Opc == OO_AmpEqual ||
+ Opc == OO_CaretEqual || Opc == OO_PipeEqual;
}
bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
@@ -130,14 +129,15 @@ public:
SourceLocation getOperatorLoc() const { return getRParenLoc(); }
SourceLocation getExprLoc() const LLVM_READONLY {
+ OverloadedOperatorKind Operator = getOperator();
return (Operator < OO_Plus || Operator >= OO_Arrow ||
Operator == OO_PlusPlus || Operator == OO_MinusMinus)
? getBeginLoc()
: getOperatorLoc();
}
- SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
+ SourceLocation getBeginLoc() const { return Range.getBegin(); }
+ SourceLocation getEndLoc() const { return Range.getEnd(); }
SourceRange getSourceRange() const { return Range; }
static bool classof(const Stmt *T) {
@@ -146,14 +146,17 @@ public:
// Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- void setFPFeatures(FPOptions F) { FPFeatures = F; }
-
- FPOptions getFPFeatures() const { return FPFeatures; }
+ void setFPFeatures(FPOptions F) {
+ CXXOperatorCallExprBits.FPFeatures = F.getInt();
+ }
+ FPOptions getFPFeatures() const {
+ return FPOptions(CXXOperatorCallExprBits.FPFeatures);
+ }
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractableWithinStatement() const {
- return FPFeatures.allowFPContractWithinStatement();
+ return getFPFeatures().allowFPContractWithinStatement();
}
};
@@ -165,16 +168,23 @@ public:
/// both the object argument and the member function, while the
/// arguments are the arguments within the parentheses (not including
/// the object argument).
-class CXXMemberCallExpr : public CallExpr {
+class CXXMemberCallExpr final : public CallExpr {
+ // CXXMemberCallExpr has some trailing objects belonging
+ // to CallExpr. See CallExpr for the details.
+
+ CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
+ ExprValueKind VK, SourceLocation RP, unsigned MinNumArgs);
+
+ CXXMemberCallExpr(unsigned NumArgs, EmptyShell Empty);
+
public:
- CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr *> args, QualType t,
- ExprValueKind VK, SourceLocation RP,
- unsigned MinNumArgs = 0)
- : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP, MinNumArgs,
- NotADL) {}
+ static CXXMemberCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty,
+ ExprValueKind VK, SourceLocation RP,
+ unsigned MinNumArgs = 0);
- CXXMemberCallExpr(ASTContext &C, unsigned NumArgs, EmptyShell Empty)
- : CallExpr(C, CXXMemberCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+ static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
+ EmptyShell Empty);
/// Retrieves the implicit object argument for the member call.
///
@@ -206,20 +216,26 @@ public:
};
/// Represents a call to a CUDA kernel function.
-class CUDAKernelCallExpr : public CallExpr {
-private:
+class CUDAKernelCallExpr final : public CallExpr {
enum { CONFIG, END_PREARG };
+ // CUDAKernelCallExpr has some trailing objects belonging
+ // to CallExpr. See CallExpr for the details.
+
+ CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef<Expr *> Args,
+ QualType Ty, ExprValueKind VK, SourceLocation RP,
+ unsigned MinNumArgs);
+
+ CUDAKernelCallExpr(unsigned NumArgs, EmptyShell Empty);
+
public:
- CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
- ArrayRef<Expr *> args, QualType t, ExprValueKind VK,
- SourceLocation RP, unsigned MinNumArgs = 0)
- : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP,
- MinNumArgs, NotADL) {}
+ static CUDAKernelCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
+ CallExpr *Config, ArrayRef<Expr *> Args,
+ QualType Ty, ExprValueKind VK,
+ SourceLocation RP, unsigned MinNumArgs = 0);
- CUDAKernelCallExpr(ASTContext &C, unsigned NumArgs, EmptyShell Empty)
- : CallExpr(C, CUDAKernelCallExprClass, /*NumPreArgs=*/END_PREARG, NumArgs,
- Empty) {}
+ static CUDAKernelCallExpr *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumArgs, EmptyShell Empty);
const CallExpr *getConfig() const {
return cast_or_null<CallExpr>(getPreArg(CONFIG));
@@ -309,8 +325,7 @@ public:
/// \c static_cast<int>(1.0).
class CXXStaticCastExpr final
: public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXStaticCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> {
CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
@@ -321,10 +336,6 @@ class CXXStaticCastExpr final
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -350,8 +361,7 @@ public:
/// check to determine how to perform the type conversion.
class CXXDynamicCastExpr final
: public CXXNamedCastExpr,
- private llvm::TrailingObjects<
- CXXDynamicCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
@@ -362,10 +372,6 @@ class CXXDynamicCastExpr final
explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -398,7 +404,6 @@ public:
class CXXReinterpretCastExpr final
: public CXXNamedCastExpr,
private llvm::TrailingObjects<CXXReinterpretCastExpr,
- CastExpr::BasePathSizeTy,
CXXBaseSpecifier *> {
CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
Expr *op, unsigned pathSize,
@@ -411,10 +416,6 @@ class CXXReinterpretCastExpr final
CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -442,8 +443,7 @@ public:
/// value.
class CXXConstCastExpr final
: public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXConstCastExpr, CastExpr::BasePathSizeTy,
- CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> {
CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc, SourceRange AngleBrackets)
@@ -453,10 +453,6 @@ class CXXConstCastExpr final
explicit CXXConstCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -482,25 +478,30 @@ public:
///
/// Since literal operators are never found by ADL and can only be declared at
/// namespace scope, a user-defined literal is never dependent.
-class UserDefinedLiteral : public CallExpr {
+class UserDefinedLiteral final : public CallExpr {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
/// The location of a ud-suffix within the literal.
SourceLocation UDSuffixLoc;
-public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
+ // UserDefinedLiteral has some trailing objects belonging
+ // to CallExpr. See CallExpr for the details.
- UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr *> Args,
- QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
- SourceLocation SuffixLoc)
- : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc,
- /*MinNumArgs=*/0, NotADL),
- UDSuffixLoc(SuffixLoc) {}
+ UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
+ ExprValueKind VK, SourceLocation LitEndLoc,
+ SourceLocation SuffixLoc);
- explicit UserDefinedLiteral(const ASTContext &C, unsigned NumArgs,
- EmptyShell Empty)
- : CallExpr(C, UserDefinedLiteralClass, /*NumPreArgs=*/0, NumArgs, Empty) {
- }
+ UserDefinedLiteral(unsigned NumArgs, EmptyShell Empty);
+
+public:
+ static UserDefinedLiteral *Create(const ASTContext &Ctx, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty,
+ ExprValueKind VK, SourceLocation LitEndLoc,
+ SourceLocation SuffixLoc);
+
+ static UserDefinedLiteral *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumArgs, EmptyShell Empty);
/// The kind of literal operator which is invoked.
enum LiteralOperatorKind {
@@ -1259,6 +1260,8 @@ public:
/// Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
+ friend class ASTStmtReader;
+
public:
enum ConstructionKind {
CK_Complete,
@@ -1268,98 +1271,119 @@ public:
};
private:
- CXXConstructorDecl *Constructor = nullptr;
- SourceLocation Loc;
+ /// A pointer to the constructor which will be ultimately called.
+ CXXConstructorDecl *Constructor;
+
SourceRange ParenOrBraceRange;
- unsigned NumArgs : 16;
- unsigned Elidable : 1;
- unsigned HadMultipleCandidates : 1;
- unsigned ListInitialization : 1;
- unsigned StdInitListInitialization : 1;
- unsigned ZeroInitialization : 1;
- unsigned ConstructKind : 2;
- Stmt **Args = nullptr;
- void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
+ /// The number of arguments.
+ unsigned NumArgs;
+
+ // We would like to stash the arguments of the constructor call after
+ // CXXConstructExpr. However CXXConstructExpr is used as a base class of
+ // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects
+ // impossible.
+ //
+ // Instead we manually stash the trailing object after the full object
+ // containing CXXConstructExpr (that is either CXXConstructExpr or
+ // CXXTemporaryObjectExpr).
+ //
+ // The trailing objects are:
+ //
+ // * An array of getNumArgs() "Stmt *" for the arguments of the
+ // constructor call.
+
+ /// Return a pointer to the start of the trailing arguments.
+ /// Defined just after CXXTemporaryObjectExpr.
+ inline Stmt **getTrailingArgs();
+ const Stmt *const *getTrailingArgs() const {
+ return const_cast<CXXConstructExpr *>(this)->getTrailingArgs();
+ }
protected:
- CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *Ctor,
- bool Elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
+ /// Build a C++ construction expression.
+ CXXConstructExpr(StmtClass SC, QualType Ty, SourceLocation Loc,
+ CXXConstructorDecl *Ctor, bool Elidable,
+ ArrayRef<Expr *> Args, bool HadMultipleCandidates,
+ bool ListInitialization, bool StdInitListInitialization,
+ bool ZeroInitialization, ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
- /// Construct an empty C++ construction expression.
- CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), NumArgs(0), Elidable(false),
- HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0) {}
+ /// Build an empty C++ construction expression.
+ CXXConstructExpr(StmtClass SC, EmptyShell Empty, unsigned NumArgs);
+
+ /// Return the size in bytes of the trailing objects. Used by
+ /// CXXTemporaryObjectExpr to allocate the right amount of storage.
+ static unsigned sizeOfTrailingObjects(unsigned NumArgs) {
+ return NumArgs * sizeof(Stmt *);
+ }
public:
- friend class ASTStmtReader;
+ /// Create a C++ construction expression.
+ static CXXConstructExpr *
+ Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
+ CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
+ bool HadMultipleCandidates, bool ListInitialization,
+ bool StdInitListInitialization, bool ZeroInitialization,
+ ConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
- /// Construct an empty C++ construction expression.
- explicit CXXConstructExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXConstructExprClass, Empty) {}
-
- static CXXConstructExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *Ctor,
- bool Elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
+ /// Create an empty C++ construction expression.
+ static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs);
/// Get the constructor that this expression will (ultimately) call.
CXXConstructorDecl *getConstructor() const { return Constructor; }
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation Loc) { this->Loc = Loc; }
+ SourceLocation getLocation() const { return CXXConstructExprBits.Loc; }
+ void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; }
/// Whether this construction is elidable.
- bool isElidable() const { return Elidable; }
- void setElidable(bool E) { Elidable = E; }
+ bool isElidable() const { return CXXConstructExprBits.Elidable; }
+ void setElidable(bool E) { CXXConstructExprBits.Elidable = E; }
/// Whether the referred constructor was resolved from
/// an overloaded set having size greater than 1.
- bool hadMultipleCandidates() const { return HadMultipleCandidates; }
- void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
+ bool hadMultipleCandidates() const {
+ return CXXConstructExprBits.HadMultipleCandidates;
+ }
+ void setHadMultipleCandidates(bool V) {
+ CXXConstructExprBits.HadMultipleCandidates = V;
+ }
/// Whether this constructor call was written as list-initialization.
- bool isListInitialization() const { return ListInitialization; }
- void setListInitialization(bool V) { ListInitialization = V; }
+ bool isListInitialization() const {
+ return CXXConstructExprBits.ListInitialization;
+ }
+ void setListInitialization(bool V) {
+ CXXConstructExprBits.ListInitialization = V;
+ }
/// Whether this constructor call was written as list-initialization,
/// but was interpreted as forming a std::initializer_list<T> from the list
/// and passing that as a single constructor argument.
/// See C++11 [over.match.list]p1 bullet 1.
- bool isStdInitListInitialization() const { return StdInitListInitialization; }
- void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+ bool isStdInitListInitialization() const {
+ return CXXConstructExprBits.StdInitListInitialization;
+ }
+ void setStdInitListInitialization(bool V) {
+ CXXConstructExprBits.StdInitListInitialization = V;
+ }
/// Whether this construction first requires
/// zero-initialization before the initializer is called.
- bool requiresZeroInitialization() const { return ZeroInitialization; }
+ bool requiresZeroInitialization() const {
+ return CXXConstructExprBits.ZeroInitialization;
+ }
void setRequiresZeroInitialization(bool ZeroInit) {
- ZeroInitialization = ZeroInit;
+ CXXConstructExprBits.ZeroInitialization = ZeroInit;
}
/// Determine whether this constructor is actually constructing
/// a base class (rather than a complete object).
ConstructionKind getConstructionKind() const {
- return (ConstructionKind)ConstructKind;
+ return static_cast<ConstructionKind>(CXXConstructExprBits.ConstructionKind);
}
void setConstructionKind(ConstructionKind CK) {
- ConstructKind = CK;
+ CXXConstructExprBits.ConstructionKind = CK;
}
using arg_iterator = ExprIterator;
@@ -1372,31 +1396,33 @@ public:
return const_arg_range(arg_begin(), arg_end());
}
- arg_iterator arg_begin() { return Args; }
- arg_iterator arg_end() { return Args + NumArgs; }
- const_arg_iterator arg_begin() const { return Args; }
- const_arg_iterator arg_end() const { return Args + NumArgs; }
+ arg_iterator arg_begin() { return getTrailingArgs(); }
+ arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
+ const_arg_iterator arg_begin() const { return getTrailingArgs(); }
+ const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
- Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
+ Expr **getArgs() { return reinterpret_cast<Expr **>(getTrailingArgs()); }
const Expr *const *getArgs() const {
- return const_cast<CXXConstructExpr *>(this)->getArgs();
+ return reinterpret_cast<const Expr *const *>(getTrailingArgs());
}
+
+ /// Return the number of arguments to the constructor call.
unsigned getNumArgs() const { return NumArgs; }
/// Return the specified argument.
Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ return getArgs()[Arg];
}
/// Set the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- Args[Arg] = ArgExpr;
+ assert(Arg < getNumArgs() && "Arg access out of range!");
+ getArgs()[Arg] = ArgExpr;
}
SourceLocation getBeginLoc() const LLVM_READONLY;
@@ -1406,12 +1432,12 @@ public:
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXConstructExprClass ||
- T->getStmtClass() == CXXTemporaryObjectExprClass;
+ T->getStmtClass() == CXXTemporaryObjectExprClass;
}
// Iterators
child_range children() {
- return child_range(&Args[0], &Args[0]+NumArgs);
+ return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs());
}
};
@@ -1492,8 +1518,7 @@ public:
/// \endcode
class CXXFunctionalCastExpr final
: public ExplicitCastExpr,
- private llvm::TrailingObjects<
- CXXFunctionalCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> {
SourceLocation LParenLoc;
SourceLocation RParenLoc;
@@ -1508,10 +1533,6 @@ class CXXFunctionalCastExpr final
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {}
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
friend class CastExpr;
friend TrailingObjects;
@@ -1557,26 +1578,36 @@ public:
/// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
/// };
/// \endcode
-class CXXTemporaryObjectExpr : public CXXConstructExpr {
- TypeSourceInfo *Type = nullptr;
-
-public:
+class CXXTemporaryObjectExpr final : public CXXConstructExpr {
friend class ASTStmtReader;
- CXXTemporaryObjectExpr(const ASTContext &C,
- CXXConstructorDecl *Cons,
- QualType Type,
- TypeSourceInfo *TSI,
- ArrayRef<Expr *> Args,
+ // CXXTemporaryObjectExpr has some trailing objects belonging
+ // to CXXConstructExpr. See the comment inside CXXConstructExpr
+ // for more details.
+
+ TypeSourceInfo *TSI;
+
+ CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty,
+ TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
SourceRange ParenOrBraceRange,
- bool HadMultipleCandidates,
- bool ListInitialization,
+ bool HadMultipleCandidates, bool ListInitialization,
bool StdInitListInitialization,
bool ZeroInitialization);
- explicit CXXTemporaryObjectExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) {}
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+ CXXTemporaryObjectExpr(EmptyShell Empty, unsigned NumArgs);
+
+public:
+ static CXXTemporaryObjectExpr *
+ Create(const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
+ TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
+ SourceRange ParenOrBraceRange, bool HadMultipleCandidates,
+ bool ListInitialization, bool StdInitListInitialization,
+ bool ZeroInitialization);
+
+ static CXXTemporaryObjectExpr *CreateEmpty(const ASTContext &Ctx,
+ unsigned NumArgs);
+
+ TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
SourceLocation getBeginLoc() const LLVM_READONLY;
SourceLocation getEndLoc() const LLVM_READONLY;
@@ -1586,6 +1617,14 @@ public:
}
};
+Stmt **CXXConstructExpr::getTrailingArgs() {
+ if (auto *E = dyn_cast<CXXTemporaryObjectExpr>(this))
+ return reinterpret_cast<Stmt **>(E + 1);
+ assert((getStmtClass() == CXXConstructExprClass) &&
+ "Unexpected class deriving from CXXConstructExpr!");
+ return reinterpret_cast<Stmt **>(this + 1);
+}
+
/// A C++ lambda expression, which produces a function object
/// (of unspecified type) that can be invoked later.
///
@@ -1832,18 +1871,19 @@ public:
class CXXScalarValueInitExpr : public Expr {
friend class ASTStmtReader;
- SourceLocation RParenLoc;
TypeSourceInfo *TypeInfo;
public:
/// Create an explicitly-written scalar-value initialization
/// expression.
CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
- SourceLocation rParenLoc)
- : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
- false, false, Type->isInstantiationDependentType(),
+ SourceLocation RParenLoc)
+ : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, false,
+ false, Type->isInstantiationDependentType(),
Type->containsUnexpandedParameterPack()),
- RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
+ TypeInfo(TypeInfo) {
+ CXXScalarValueInitExprBits.RParenLoc = RParenLoc;
+ }
explicit CXXScalarValueInitExpr(EmptyShell Shell)
: Expr(CXXScalarValueInitExprClass, Shell) {}
@@ -1852,10 +1892,12 @@ public:
return TypeInfo;
}
- SourceLocation getRParenLoc() const { return RParenLoc; }
+ SourceLocation getRParenLoc() const {
+ return CXXScalarValueInitExprBits.RParenLoc;
+ }
SourceLocation getBeginLoc() const LLVM_READONLY;
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getEndLoc() const { return getRParenLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXScalarValueInitExprClass;
@@ -1869,54 +1911,56 @@ public:
/// Represents a new-expression for memory allocation and constructor
/// calls, e.g: "new CXXNewExpr(foo)".
-class CXXNewExpr : public Expr {
+class CXXNewExpr final
+ : public Expr,
+ private llvm::TrailingObjects<CXXNewExpr, Stmt *, SourceRange> {
friend class ASTStmtReader;
friend class ASTStmtWriter;
-
- /// Contains an optional array size expression, an optional initialization
- /// expression, and any number of optional placement arguments, in that order.
- Stmt **SubExprs = nullptr;
+ friend TrailingObjects;
/// Points to the allocation function used.
FunctionDecl *OperatorNew;
- /// Points to the deallocation function used in case of error. May be
- /// null.
+ /// Points to the deallocation function used in case of error. May be null.
FunctionDecl *OperatorDelete;
/// The allocated type-source information, as written in the source.
TypeSourceInfo *AllocatedTypeInfo;
- /// If the allocated type was expressed as a parenthesized type-id,
- /// the source range covering the parenthesized type-id.
- SourceRange TypeIdParens;
-
/// Range of the entire new expression.
SourceRange Range;
/// Source-range of a paren-delimited initializer.
SourceRange DirectInitRange;
- /// Was the usage ::new, i.e. is the global new to be used?
- unsigned GlobalNew : 1;
-
- /// Do we allocate an array? If so, the first SubExpr is the size expression.
- unsigned Array : 1;
-
- /// Should the alignment be passed to the allocation function?
- unsigned PassAlignment : 1;
-
- /// If this is an array allocation, does the usual deallocation
- /// function for the allocated type want to know the allocated size?
- unsigned UsualArrayDeleteWantsSize : 1;
+ // CXXNewExpr is followed by several optional trailing objects.
+ // They are in order:
+ //
+ // * An optional "Stmt *" for the array size expression.
+ // Present if and ony if isArray().
+ //
+ // * An optional "Stmt *" for the init expression.
+ // Present if and only if hasInitializer().
+ //
+ // * An array of getNumPlacementArgs() "Stmt *" for the placement new
+ // arguments, if any.
+ //
+ // * An optional SourceRange for the range covering the parenthesized type-id
+ // if the allocated type was expressed as a parenthesized type-id.
+ // Present if and only if isParenTypeId().
+ unsigned arraySizeOffset() const { return 0; }
+ unsigned initExprOffset() const { return arraySizeOffset() + isArray(); }
+ unsigned placementNewArgsOffset() const {
+ return initExprOffset() + hasInitializer();
+ }
- /// The number of placement new arguments.
- unsigned NumPlacementArgs : 26;
+ unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
+ return isArray() + hasInitializer() + getNumPlacementArgs();
+ }
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
- unsigned StoredInitializationStyle : 2;
+ unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
+ return isParenTypeId();
+ }
public:
enum InitializationStyle {
@@ -1930,18 +1974,35 @@ public:
ListInit
};
- CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
- FunctionDecl *operatorDelete, bool PassAlignment,
- bool usualArrayDeleteWantsSize, ArrayRef<Expr*> placementArgs,
- SourceRange typeIdParens, Expr *arraySize,
- InitializationStyle initializationStyle, Expr *initializer,
- QualType ty, TypeSourceInfo *AllocatedTypeInfo,
- SourceRange Range, SourceRange directInitRange);
- explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell) {}
+private:
+ /// Build a c++ new expression.
+ CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
+ FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
+ bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
+ SourceRange TypeIdParens, Expr *ArraySize,
+ InitializationStyle InitializationStyle, Expr *Initializer,
+ QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
+ SourceRange DirectInitRange);
+
+ /// Build an empty c++ new expression.
+ CXXNewExpr(EmptyShell Empty, bool IsArray, unsigned NumPlacementArgs,
+ bool IsParenTypeId);
- void AllocateArgsArray(const ASTContext &C, bool isArray,
- unsigned numPlaceArgs, bool hasInitializer);
+public:
+ /// Create a c++ new expression.
+ static CXXNewExpr *
+ Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
+ FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
+ bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
+ SourceRange TypeIdParens, Expr *ArraySize,
+ InitializationStyle InitializationStyle, Expr *Initializer,
+ QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
+ SourceRange DirectInitRange);
+
+ /// Create an empty c++ new expression.
+ static CXXNewExpr *CreateEmpty(const ASTContext &Ctx, bool IsArray,
+ bool HasInit, unsigned NumPlacementArgs,
+ bool IsParenTypeId);
QualType getAllocatedType() const {
assert(getType()->isPointerType());
@@ -1967,58 +2028,74 @@ public:
/// has a non-throwing exception-specification. The '03 rule is
/// identical except that the definition of a non-throwing
/// exception specification is just "is it throw()?".
- bool shouldNullCheckAllocation(const ASTContext &Ctx) const;
+ bool shouldNullCheckAllocation() const;
FunctionDecl *getOperatorNew() const { return OperatorNew; }
void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
- bool isArray() const { return Array; }
+ bool isArray() const { return CXXNewExprBits.IsArray; }
Expr *getArraySize() {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
+ return isArray()
+ ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()])
+ : nullptr;
}
const Expr *getArraySize() const {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
+ return isArray()
+ ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()])
+ : nullptr;
}
- unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
+ unsigned getNumPlacementArgs() const {
+ return CXXNewExprBits.NumPlacementArgs;
+ }
Expr **getPlacementArgs() {
- return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
+ return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>() +
+ placementNewArgsOffset());
}
- Expr *getPlacementArg(unsigned i) {
- assert(i < NumPlacementArgs && "Index out of range");
- return getPlacementArgs()[i];
+ Expr *getPlacementArg(unsigned I) {
+ assert((I < getNumPlacementArgs()) && "Index out of range!");
+ return getPlacementArgs()[I];
}
- const Expr *getPlacementArg(unsigned i) const {
- assert(i < NumPlacementArgs && "Index out of range");
- return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
+ const Expr *getPlacementArg(unsigned I) const {
+ return const_cast<CXXNewExpr *>(this)->getPlacementArg(I);
}
- bool isParenTypeId() const { return TypeIdParens.isValid(); }
- SourceRange getTypeIdParens() const { return TypeIdParens; }
+ bool isParenTypeId() const { return CXXNewExprBits.IsParenTypeId; }
+ SourceRange getTypeIdParens() const {
+ return isParenTypeId() ? getTrailingObjects<SourceRange>()[0]
+ : SourceRange();
+ }
- bool isGlobalNew() const { return GlobalNew; }
+ bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
/// Whether this new-expression has any initializer at all.
- bool hasInitializer() const { return StoredInitializationStyle > 0; }
+ bool hasInitializer() const {
+ return CXXNewExprBits.StoredInitializationStyle > 0;
+ }
/// The kind of initializer this new-expression has.
InitializationStyle getInitializationStyle() const {
- if (StoredInitializationStyle == 0)
+ if (CXXNewExprBits.StoredInitializationStyle == 0)
return NoInit;
- return static_cast<InitializationStyle>(StoredInitializationStyle-1);
+ return static_cast<InitializationStyle>(
+ CXXNewExprBits.StoredInitializationStyle - 1);
}
/// The initializer of this new-expression.
Expr *getInitializer() {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
+ return hasInitializer()
+ ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()])
+ : nullptr;
}
const Expr *getInitializer() const {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
+ return hasInitializer()
+ ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()])
+ : nullptr;
}
/// Returns the CXXConstructExpr from this new-expression, or null.
@@ -2028,15 +2105,13 @@ public:
/// Indicates whether the required alignment should be implicitly passed to
/// the allocation function.
- bool passAlignment() const {
- return PassAlignment;
- }
+ bool passAlignment() const { return CXXNewExprBits.ShouldPassAlignment; }
/// Answers whether the usual array deallocation function for the
/// allocated type expects the size of the allocation as a
/// parameter.
bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
+ return CXXNewExprBits.UsualArrayDeleteWantsSize;
}
using arg_iterator = ExprIterator;
@@ -2051,47 +2126,43 @@ public:
}
arg_iterator placement_arg_begin() {
- return SubExprs + Array + hasInitializer();
+ return getTrailingObjects<Stmt *>() + placementNewArgsOffset();
}
arg_iterator placement_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+ return placement_arg_begin() + getNumPlacementArgs();
}
const_arg_iterator placement_arg_begin() const {
- return SubExprs + Array + hasInitializer();
+ return getTrailingObjects<Stmt *>() + placementNewArgsOffset();
}
const_arg_iterator placement_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+ return placement_arg_begin() + getNumPlacementArgs();
}
using raw_arg_iterator = Stmt **;
- raw_arg_iterator raw_arg_begin() { return SubExprs; }
+ raw_arg_iterator raw_arg_begin() { return getTrailingObjects<Stmt *>(); }
raw_arg_iterator raw_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+ return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>());
+ }
+ const_arg_iterator raw_arg_begin() const {
+ return getTrailingObjects<Stmt *>();
}
- const_arg_iterator raw_arg_begin() const { return SubExprs; }
const_arg_iterator raw_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+ return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>());
}
SourceLocation getBeginLoc() const { return Range.getBegin(); }
SourceLocation getEndLoc() const { return Range.getEnd(); }
SourceRange getDirectInitRange() const { return DirectInitRange; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return Range;
- }
-
+ SourceRange getSourceRange() const { return Range; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNewExprClass;
}
// Iterators
- child_range children() {
- return child_range(raw_arg_begin(), raw_arg_end());
- }
+ child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); }
};
/// Represents a \c delete expression for memory deallocation and
@@ -2562,58 +2633,54 @@ public:
/// A reference to an overloaded function set, either an
/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
class OverloadExpr : public Expr {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
/// The common name of these declarations.
DeclarationNameInfo NameInfo;
/// The nested-name-specifier that qualifies the name, if any.
NestedNameSpecifierLoc QualifierLoc;
- /// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls. Access is relative to the naming
- /// class.
- // FIXME: Allocate this data after the OverloadExpr subclass.
- DeclAccessPair *Results = nullptr;
-
- unsigned NumResults = 0;
-
protected:
- /// Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo = false;
-
- OverloadExpr(StmtClass K, const ASTContext &C,
+ OverloadExpr(StmtClass SC, const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool KnownDependent,
- bool KnownInstantiationDependent,
+ bool KnownDependent, bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack);
- OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {}
+ OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo);
- /// Return the optional template keyword and arguments info.
- ASTTemplateKWAndArgsInfo *
- getTrailingASTTemplateKWAndArgsInfo(); // defined far below.
+ /// Return the results. Defined after UnresolvedMemberExpr.
+ inline DeclAccessPair *getTrailingResults();
+ const DeclAccessPair *getTrailingResults() const {
+ return const_cast<OverloadExpr *>(this)->getTrailingResults();
+ }
/// Return the optional template keyword and arguments info.
+ /// Defined after UnresolvedMemberExpr.
+ inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo();
const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
return const_cast<OverloadExpr *>(this)
->getTrailingASTTemplateKWAndArgsInfo();
}
- /// Return the optional template arguments.
- TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
+ /// Return the optional template arguments. Defined after
+ /// UnresolvedMemberExpr.
+ inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc();
+ const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const {
+ return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
+ }
- void initializeResults(const ASTContext &C,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
+ bool hasTemplateKWAndArgsInfo() const {
+ return OverloadExprBits.HasTemplateKWAndArgsInfo;
+ }
public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
struct FindResult {
OverloadExpr *Expression;
bool IsAddressOfOperand;
@@ -2649,20 +2716,26 @@ public:
}
/// Gets the naming class of this lookup, if any.
- CXXRecordDecl *getNamingClass() const;
+ /// Defined after UnresolvedMemberExpr.
+ inline CXXRecordDecl *getNamingClass();
+ const CXXRecordDecl *getNamingClass() const {
+ return const_cast<OverloadExpr *>(this)->getNamingClass();
+ }
using decls_iterator = UnresolvedSetImpl::iterator;
- decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
+ decls_iterator decls_begin() const {
+ return UnresolvedSetIterator(getTrailingResults());
+ }
decls_iterator decls_end() const {
- return UnresolvedSetIterator(Results + NumResults);
+ return UnresolvedSetIterator(getTrailingResults() + getNumDecls());
}
llvm::iterator_range<decls_iterator> decls() const {
return llvm::make_range(decls_begin(), decls_end());
}
/// Gets the number of declarations in the unresolved set.
- unsigned getNumDecls() const { return NumResults; }
+ unsigned getNumDecls() const { return OverloadExprBits.NumResults; }
/// Gets the full name info.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
@@ -2685,21 +2758,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
}
@@ -2751,86 +2827,82 @@ public:
/// members and therefore appear only in UnresolvedMemberLookupExprs.
class UnresolvedLookupExpr final
: public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
+ private llvm::TrailingObjects<UnresolvedLookupExpr, DeclAccessPair,
+ ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc> {
friend class ASTStmtReader;
friend class OverloadExpr;
friend TrailingObjects;
- /// True if these lookup results should be extended by
- /// argument-dependent lookup if this is the operand of a function
- /// call.
- bool RequiresADL = false;
-
- /// True if these lookup results are overloaded. This is pretty
- /// trivially rederivable if we urgently need to kill this field.
- bool Overloaded = false;
-
/// The naming class (C++ [class.access.base]p5) of the lookup, if
/// any. This can generally be recalculated from the context chain,
- /// but that can be fairly expensive for unqualified lookups. If we
- /// want to improve memory use here, this could go in a union
- /// against the qualified-lookup bits.
- CXXRecordDecl *NamingClass = nullptr;
-
- UnresolvedLookupExpr(const ASTContext &C,
- CXXRecordDecl *NamingClass,
+ /// but that can be fairly expensive for unqualified lookups.
+ CXXRecordDecl *NamingClass;
+
+ // UnresolvedLookupExpr is followed by several trailing objects.
+ // They are in order:
+ //
+ // * An array of getNumResults() DeclAccessPair for the results. These are
+ // undesugared, which is to say, they may include UsingShadowDecls.
+ // Access is relative to the naming class.
+ //
+ // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+ // template keyword and arguments. Present if and only if
+ // hasTemplateKWAndArgsInfo().
+ //
+ // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
+ // location information for the explicitly specified template arguments.
+
+ UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool RequiresADL, bool Overloaded,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL,
+ bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End)
- : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
- NameInfo, TemplateArgs, Begin, End, false, false, false),
- RequiresADL(RequiresADL),
- Overloaded(Overloaded), NamingClass(NamingClass) {}
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- UnresolvedLookupExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedLookupExprClass, Empty) {}
+ UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo);
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
+ return getNumDecls();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return hasTemplateKWAndArgsInfo();
}
public:
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL, bool Overloaded,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
- return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
- SourceLocation(), NameInfo,
- ADL, Overloaded, nullptr, Begin, End);
- }
-
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL,
- const TemplateArgumentListInfo *Args,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
-
- static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C,
+ static UnresolvedLookupExpr *
+ Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
+ NestedNameSpecifierLoc QualifierLoc,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+ static UnresolvedLookupExpr *
+ Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL,
+ const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End);
+
+ static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
+ unsigned NumResults,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
/// True if this declaration should be extended by
/// argument-dependent lookup.
- bool requiresADL() const { return RequiresADL; }
+ bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; }
/// True if this lookup is overloaded.
- bool isOverloaded() const { return Overloaded; }
+ bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; }
/// Gets the 'naming class' (in the sense of C++0x
/// [class.access.base]p5) of the lookup. This is the scope
/// that was looked in to find these results.
- CXXRecordDecl *getNamingClass() const { return NamingClass; }
+ CXXRecordDecl *getNamingClass() { return NamingClass; }
+ const CXXRecordDecl *getNamingClass() const { return NamingClass; }
SourceLocation getBeginLoc() const LLVM_READONLY {
if (NestedNameSpecifierLoc l = getQualifierLoc())
@@ -2872,6 +2944,10 @@ class DependentScopeDeclRefExpr final
private llvm::TrailingObjects<DependentScopeDeclRefExpr,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// The nested-name-specifier that qualifies this unresolved
/// declaration name.
NestedNameSpecifierLoc QualifierLoc;
@@ -2879,32 +2955,26 @@ class DependentScopeDeclRefExpr final
/// The name of the entity we will be referencing.
DeclarationNameInfo NameInfo;
- /// Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
-
- DependentScopeDeclRefExpr(QualType T,
- NestedNameSpecifierLoc QualifierLoc,
+ DependentScopeDeclRefExpr(QualType Ty, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *Args);
size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ return hasTemplateKWAndArgsInfo();
}
-public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
+ bool hasTemplateKWAndArgsInfo() const {
+ return DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo;
+ }
- static DependentScopeDeclRefExpr *Create(const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
+public:
+ static DependentScopeDeclRefExpr *
+ Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
+ const TemplateArgumentListInfo *TemplateArgs);
- static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C,
+ static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &Context,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
@@ -2932,21 +3002,24 @@ public:
/// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
@@ -3100,7 +3173,7 @@ class CXXUnresolvedConstructExpr final
friend TrailingObjects;
/// The type being constructed.
- TypeSourceInfo *Type = nullptr;
+ TypeSourceInfo *TSI;
/// The location of the left parentheses ('(').
SourceLocation LParenLoc;
@@ -3108,34 +3181,31 @@ class CXXUnresolvedConstructExpr final
/// The location of the right parentheses (')').
SourceLocation RParenLoc;
- /// The number of arguments used to construct the type.
- unsigned NumArgs;
-
- CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
- SourceLocation RParenLoc);
+ CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, SourceLocation LParenLoc,
+ ArrayRef<Expr *> Args, SourceLocation RParenLoc);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) {}
+ : Expr(CXXUnresolvedConstructExprClass, Empty) {
+ CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
+ }
public:
- static CXXUnresolvedConstructExpr *Create(const ASTContext &C,
+ static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
TypeSourceInfo *Type,
SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
+ ArrayRef<Expr *> Args,
SourceLocation RParenLoc);
- static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C,
+ static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context,
unsigned NumArgs);
/// Retrieve the type that is being constructed, as specified
/// in the source code.
- QualType getTypeAsWritten() const { return Type->getType(); }
+ QualType getTypeAsWritten() const { return TSI->getType(); }
/// Retrieve the type source information for the type being
/// constructed.
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+ TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
/// Retrieve the location of the left parentheses ('(') that
/// precedes the argument list.
@@ -3153,46 +3223,43 @@ public:
bool isListInitialization() const { return LParenLoc.isInvalid(); }
/// Retrieve the number of arguments.
- unsigned arg_size() const { return NumArgs; }
+ unsigned arg_size() const { return CXXUnresolvedConstructExprBits.NumArgs; }
using arg_iterator = Expr **;
using arg_range = llvm::iterator_range<arg_iterator>;
arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
- arg_iterator arg_end() { return arg_begin() + NumArgs; }
+ arg_iterator arg_end() { return arg_begin() + arg_size(); }
arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
using const_arg_iterator = const Expr* const *;
using const_arg_range = llvm::iterator_range<const_arg_iterator>;
const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
- const_arg_iterator arg_end() const {
- return arg_begin() + NumArgs;
- }
+ const_arg_iterator arg_end() const { return arg_begin() + arg_size(); }
const_arg_range arguments() const {
return const_arg_range(arg_begin(), arg_end());
}
Expr *getArg(unsigned I) {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
+ assert(I < arg_size() && "Argument index out-of-range");
+ return arg_begin()[I];
}
const Expr *getArg(unsigned I) const {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
+ assert(I < arg_size() && "Argument index out-of-range");
+ return arg_begin()[I];
}
void setArg(unsigned I, Expr *E) {
- assert(I < NumArgs && "Argument index out-of-range");
- *(arg_begin() + I) = E;
+ assert(I < arg_size() && "Argument index out-of-range");
+ arg_begin()[I] = E;
}
SourceLocation getBeginLoc() const LLVM_READONLY;
-
SourceLocation getEndLoc() const LLVM_READONLY {
- if (!RParenLoc.isValid() && NumArgs > 0)
- return getArg(NumArgs - 1)->getEndLoc();
+ if (!RParenLoc.isValid() && arg_size() > 0)
+ return getArg(arg_size() - 1)->getEndLoc();
return RParenLoc;
}
@@ -3203,7 +3270,7 @@ public:
// Iterators
child_range children() {
auto **begin = reinterpret_cast<Stmt **>(arg_begin());
- return child_range(begin, begin + NumArgs);
+ return child_range(begin, begin + arg_size());
}
};
@@ -3218,7 +3285,11 @@ class CXXDependentScopeMemberExpr final
: public Expr,
private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
+ TemplateArgumentLoc, NamedDecl *> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
/// The expression for the base pointer or class reference,
/// e.g., the \c x in x.f. Can be null in implicit accesses.
Stmt *Base;
@@ -3227,40 +3298,53 @@ class CXXDependentScopeMemberExpr final
/// implicit accesses.
QualType BaseType;
- /// Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// Whether this member expression has info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo : 1;
-
- /// The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
-
/// The nested-name-specifier that precedes the member name, if any.
+ /// FIXME: This could be in principle store as a trailing object.
+ /// However the performance impact of doing so should be investigated first.
NestedNameSpecifierLoc QualifierLoc;
- /// In a qualified member access expression such as t->Base::f, this
- /// member stores the resolves of name lookup in the context of the member
- /// access expression, to be used at instantiation time.
- ///
- /// FIXME: This member, along with the QualifierLoc, could
- /// be stuck into a structure that is optionally allocated at the end of
- /// the CXXDependentScopeMemberExpr, to save space in the common case.
- NamedDecl *FirstQualifierFoundInScope;
-
/// The member to which this member expression refers, which
/// can be name, overloaded operator, or destructor.
///
/// FIXME: could also be a template-id
DeclarationNameInfo MemberNameInfo;
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ // CXXDependentScopeMemberExpr is followed by several trailing objects,
+ // some of which optional. They are in order:
+ //
+ // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+ // template keyword and arguments. Present if and only if
+ // hasTemplateKWAndArgsInfo().
+ //
+ // * An array of getNumTemplateArgs() TemplateArgumentLoc containing location
+ // information for the explicitly specified template arguments.
+ //
+ // * An optional NamedDecl *. In a qualified member access expression such
+ // as t->Base::f, this member stores the resolves of name lookup in the
+ // context of the member access expression, to be used at instantiation
+ // time. Present if and only if hasFirstQualifierFoundInScope().
+
+ bool hasTemplateKWAndArgsInfo() const {
+ return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo;
+ }
+
+ bool hasFirstQualifierFoundInScope() const {
+ return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return hasTemplateKWAndArgsInfo();
}
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
+ unsigned numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
+ return getNumTemplateArgs();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<NamedDecl *>) const {
+ return hasFirstQualifierFoundInScope();
+ }
+
+ CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base,
QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc,
@@ -3269,33 +3353,29 @@ class CXXDependentScopeMemberExpr final
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
-public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
-
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo);
+ CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
+ bool HasFirstQualifierFoundInScope);
+public:
static CXXDependentScopeMemberExpr *
- Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
+ Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
static CXXDependentScopeMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
+ CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
+ unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope);
/// True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
- bool isImplicitAccess() const;
+ bool isImplicitAccess() const {
+ if (!Base)
+ return true;
+ return cast<Expr>(Base)->isImplicitCXXThis();
+ }
/// Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
@@ -3308,13 +3388,14 @@ public:
/// Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return IsArrow; }
+ bool isArrow() const { return CXXDependentScopeMemberExprBits.IsArrow; }
/// Retrieve the location of the '->' or '.' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
+ SourceLocation getOperatorLoc() const {
+ return CXXDependentScopeMemberExprBits.OperatorLoc;
+ }
- /// Retrieve the nested-name-specifier that qualifies the member
- /// name.
+ /// Retrieve the nested-name-specifier that qualifies the member name.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3335,17 +3416,17 @@ public:
/// combined with the results of name lookup into the type of the object
/// expression itself (the class type of x).
NamedDecl *getFirstQualifierFoundInScope() const {
- return FirstQualifierFoundInScope;
+ if (!hasFirstQualifierFoundInScope())
+ return nullptr;
+ return *getTrailingObjects<NamedDecl *>();
}
- /// Retrieve the name of the member that this expression
- /// refers to.
+ /// Retrieve the name of the member that this expression refers to.
const DeclarationNameInfo &getMemberNameInfo() const {
return MemberNameInfo;
}
- /// Retrieve the name of the member that this expression
- /// refers to.
+ /// Retrieve the name of the member that this expression refers to.
DeclarationName getMember() const { return MemberNameInfo.getName(); }
// Retrieve the location of the name of the member that this
@@ -3355,21 +3436,24 @@ public:
/// Retrieve the location of the template keyword preceding the
/// member name, if any.
SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
/// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the member name, if any.
SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
/// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the member name, if any.
SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+ if (!hasTemplateKWAndArgsInfo())
+ return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
@@ -3453,25 +3537,18 @@ public:
/// DeclRefExpr, depending on whether the member is static.
class UnresolvedMemberExpr final
: public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
+ private llvm::TrailingObjects<UnresolvedMemberExpr, DeclAccessPair,
+ ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc> {
friend class ASTStmtReader;
friend class OverloadExpr;
friend TrailingObjects;
- /// Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// Whether the lookup results contain an unresolved using
- /// declaration.
- bool HasUnresolvedUsing : 1;
-
/// The expression for the base pointer or class reference,
/// e.g., the \c x in x.f.
///
/// This can be null if this is an 'unbased' member expression.
- Stmt *Base = nullptr;
+ Stmt *Base;
/// The type of the base expression; never null.
QualType BaseType;
@@ -3479,7 +3556,21 @@ class UnresolvedMemberExpr final
/// The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
- UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
+ // UnresolvedMemberExpr is followed by several trailing objects.
+ // They are in order:
+ //
+ // * An array of getNumResults() DeclAccessPair for the results. These are
+ // undesugared, which is to say, they may include UsingShadowDecls.
+ // Access is relative to the naming class.
+ //
+ // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
+ // template keyword and arguments. Present if and only if
+ // hasTemplateKWAndArgsInfo().
+ //
+ // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
+ // location information for the explicitly specified template arguments.
+
+ UnresolvedMemberExpr(const ASTContext &Context, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc,
@@ -3488,28 +3579,30 @@ class UnresolvedMemberExpr final
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- UnresolvedMemberExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false) {}
+ UnresolvedMemberExpr(EmptyShell Empty, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo);
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
+ unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
+ return getNumDecls();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
+ return hasTemplateKWAndArgsInfo();
}
public:
static UnresolvedMemberExpr *
- Create(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
+ Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
+ QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- static UnresolvedMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
+ static UnresolvedMemberExpr *CreateEmpty(const ASTContext &Context,
+ unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo,
+ unsigned NumTemplateArgs);
/// True if this is an implicit access, i.e., one in which the
/// member being accessed was not written in the source.
@@ -3532,32 +3625,36 @@ public:
/// Determine whether the lookup results contain an unresolved using
/// declaration.
- bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
+ bool hasUnresolvedUsing() const {
+ return UnresolvedMemberExprBits.HasUnresolvedUsing;
+ }
/// Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return IsArrow; }
+ bool isArrow() const { return UnresolvedMemberExprBits.IsArrow; }
/// Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
/// Retrieve the naming class of this lookup.
- CXXRecordDecl *getNamingClass() const;
+ CXXRecordDecl *getNamingClass();
+ const CXXRecordDecl *getNamingClass() const {
+ return const_cast<UnresolvedMemberExpr *>(this)->getNamingClass();
+ }
/// Retrieve the full name info for the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
- /// Retrieve the name of the member that this expression
- /// refers to.
+ /// Retrieve the name of the member that this expression refers to.
DeclarationName getMemberName() const { return getName(); }
- // Retrieve the location of the name of the member that this
- // expression refers to.
+ /// Retrieve the location of the name of the member that this
+ /// expression refers to.
SourceLocation getMemberLoc() const { return getNameLoc(); }
- // Return the preferred location (the member name) for the arrow when
- // diagnosing a problem with this expression.
+ /// Return the preferred location (the member name) for the arrow when
+ /// diagnosing a problem with this expression.
SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
SourceLocation getBeginLoc() const LLVM_READONLY {
@@ -3586,26 +3683,33 @@ public:
}
};
-inline ASTTemplateKWAndArgsInfo *
-OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo)
+DeclAccessPair *OverloadExpr::getTrailingResults() {
+ if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
+ return ULE->getTrailingObjects<DeclAccessPair>();
+ return cast<UnresolvedMemberExpr>(this)->getTrailingObjects<DeclAccessPair>();
+}
+
+ASTTemplateKWAndArgsInfo *OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
+ if (!hasTemplateKWAndArgsInfo())
return nullptr;
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
+ if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
+ return ULE->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
+ return cast<UnresolvedMemberExpr>(this)
+ ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
}
-inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
+TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
+ if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
+ return ULE->getTrailingObjects<TemplateArgumentLoc>();
+ return cast<UnresolvedMemberExpr>(this)
+ ->getTrailingObjects<TemplateArgumentLoc>();
+}
+
+CXXRecordDecl *OverloadExpr::getNamingClass() {
+ if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
+ return ULE->getNamingClass();
+ return cast<UnresolvedMemberExpr>(this)->getNamingClass();
}
/// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
@@ -3615,7 +3719,6 @@ inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
class CXXNoexceptExpr : public Expr {
friend class ASTStmtReader;
- bool Value : 1;
Stmt *Operand;
SourceRange Range;
@@ -3623,21 +3726,23 @@ public:
CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
SourceLocation Keyword, SourceLocation RParen)
: Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
- /*TypeDependent*/false,
- /*ValueDependent*/Val == CT_Dependent,
+ /*TypeDependent*/ false,
+ /*ValueDependent*/ Val == CT_Dependent,
Val == CT_Dependent || Operand->isInstantiationDependent(),
Operand->containsUnexpandedParameterPack()),
- Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) {}
+ Operand(Operand), Range(Keyword, RParen) {
+ CXXNoexceptExprBits.Value = Val == CT_Cannot;
+ }
CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {}
- Expr *getOperand() const { return static_cast<Expr*>(Operand); }
+ Expr *getOperand() const { return static_cast<Expr *>(Operand); }
- SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+ SourceLocation getBeginLoc() const { return Range.getBegin(); }
+ SourceLocation getEndLoc() const { return Range.getEnd(); }
+ SourceRange getSourceRange() const { return Range; }
- bool getValue() const { return Value; }
+ bool getValue() const { return CXXNoexceptExprBits.Value; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNoexceptExprClass;
@@ -3860,27 +3965,27 @@ class SubstNonTypeTemplateParmExpr : public Expr {
/// The replacement expression.
Stmt *Replacement;
- /// The location of the non-type template parameter reference.
- SourceLocation NameLoc;
-
explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
: Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
public:
- SubstNonTypeTemplateParmExpr(QualType type,
- ExprValueKind valueKind,
- SourceLocation loc,
- NonTypeTemplateParmDecl *param,
- Expr *replacement)
- : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
- replacement->isTypeDependent(), replacement->isValueDependent(),
- replacement->isInstantiationDependent(),
- replacement->containsUnexpandedParameterPack()),
- Param(param), Replacement(replacement), NameLoc(loc) {}
-
- SourceLocation getNameLoc() const { return NameLoc; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
+ SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
+ SourceLocation Loc,
+ NonTypeTemplateParmDecl *Param,
+ Expr *Replacement)
+ : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary,
+ Replacement->isTypeDependent(), Replacement->isValueDependent(),
+ Replacement->isInstantiationDependent(),
+ Replacement->containsUnexpandedParameterPack()),
+ Param(Param), Replacement(Replacement) {
+ SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
+ }
+
+ SourceLocation getNameLoc() const {
+ return SubstNonTypeTemplateParmExprBits.NameLoc;
+ }
+ SourceLocation getBeginLoc() const { return getNameLoc(); }
+ SourceLocation getEndLoc() const { return getNameLoc(); }
Expr *getReplacement() const { return cast<Expr>(Replacement); }
@@ -3891,7 +3996,7 @@ public:
}
// Iterators
- child_range children() { return child_range(&Replacement, &Replacement+1); }
+ child_range children() { return child_range(&Replacement, &Replacement + 1); }
};
/// Represents a reference to a non-type template parameter pack that
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index ed3d3840b3..c7b305f330 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -1574,8 +1574,7 @@ public:
/// \endcode
class ObjCBridgedCastExpr final
: public ExplicitCastExpr,
- private llvm::TrailingObjects<
- ObjCBridgedCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
+ private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
friend class ASTStmtReader;
friend class ASTStmtWriter;
friend class CastExpr;
@@ -1585,10 +1584,6 @@ class ObjCBridgedCastExpr final
SourceLocation BridgeKeywordLoc;
unsigned Kind : 2;
- size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
- return path_empty() ? 0 : 1;
- }
-
public:
ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
CastKind CK, SourceLocation BridgeKeywordLoc,
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index c42fe91b32..309ed5a1a5 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_MANGLE_H
#define LLVM_CLANG_AST_MANGLE_H
+#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index e93f7e2b3e..bdcdf74b26 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -4061,8 +4061,19 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
return getUniqueDeclarationsNum() + getTotalComponentListNum();
}
- /// Map type modifier for the 'map' clause.
- OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
+public:
+ /// Number of allowed map-type-modifiers.
+ static constexpr unsigned NumberOfModifiers =
+ OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1;
+
+private:
+ /// Map-type-modifiers for the 'map' clause.
+ OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = {
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown
+ };
+
+ /// Location of map-type-modifiers for the 'map' clause.
+ SourceLocation MapTypeModifiersLoc[NumberOfModifiers];
/// Map type for the 'map' clause.
OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
@@ -4080,7 +4091,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
/// NumUniqueDeclarations declarations, \a NumComponentLists total component
/// lists, and \a NumComponents total expression components.
///
- /// \param MapTypeModifier Map type modifier.
+ /// \param MapModifiers Map-type-modifiers.
+ /// \param MapModifiersLoc Locations of map-type-modifiers.
/// \param MapType Map type.
/// \param MapTypeIsImplicit Map type is inferred implicitly.
/// \param MapLoc Location of the map type.
@@ -4091,7 +4103,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
- explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier,
+ explicit OMPMapClause(ArrayRef<OpenMPMapModifierKind> MapModifiers,
+ ArrayRef<SourceLocation> MapModifiersLoc,
OpenMPMapClauseKind MapType, bool MapTypeIsImplicit,
SourceLocation MapLoc, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc,
@@ -4100,8 +4113,17 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
: OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc,
NumVars, NumUniqueDeclarations,
NumComponentLists, NumComponents),
- MapTypeModifier(MapTypeModifier), MapType(MapType),
- MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {}
+ MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit),
+ MapLoc(MapLoc) {
+ assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size()
+ && "Unexpected number of map type modifiers.");
+ llvm::copy(MapModifiers, std::begin(MapTypeModifiers));
+
+ assert(llvm::array_lengthof(MapTypeModifiersLoc) ==
+ MapModifiersLoc.size() &&
+ "Unexpected number of map type modifier locations.");
+ llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc));
+ }
/// Build an empty clause.
///
@@ -4116,10 +4138,25 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(),
NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
- /// Set type modifier for the clause.
+ /// Set map-type-modifier for the clause.
///
- /// \param T Type Modifier for the clause.
- void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; }
+ /// \param I index for map-type-modifier.
+ /// \param T map-type-modifier for the clause.
+ void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) {
+ assert(I < NumberOfModifiers &&
+ "Unexpected index to store map type modifier, exceeds array size.");
+ MapTypeModifiers[I] = T;
+ }
+
+ /// Set location for the map-type-modifier.
+ ///
+ /// \param I index for map-type-modifier location.
+ /// \param TLoc map-type-modifier location.
+ void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) {
+ assert(I < NumberOfModifiers &&
+ "Index to store map type modifier location exceeds array size.");
+ MapTypeModifiersLoc[I] = TLoc;
+ }
/// Set type for the clause.
///
@@ -4143,7 +4180,8 @@ public:
/// \param Vars The original expression used in the clause.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
- /// \param TypeModifier Map type modifier.
+ /// \param MapModifiers Map-type-modifiers.
+ /// \param MapModifiersLoc Location of map-type-modifiers.
/// \param Type Map type.
/// \param TypeIsImplicit Map type is inferred implicitly.
/// \param TypeLoc Location of the map type.
@@ -4152,7 +4190,8 @@ public:
ArrayRef<Expr *> Vars,
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists,
- OpenMPMapClauseKind TypeModifier,
+ ArrayRef<OpenMPMapModifierKind> MapModifiers,
+ ArrayRef<SourceLocation> MapModifiersLoc,
OpenMPMapClauseKind Type, bool TypeIsImplicit,
SourceLocation TypeLoc);
@@ -4182,9 +4221,33 @@ public:
/// messages for some target directives.
bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; }
- /// Fetches the map type modifier for the clause.
- OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY {
- return MapTypeModifier;
+ /// Fetches the map-type-modifier at 'Cnt' index of array of modifiers.
+ ///
+ /// \param Cnt index for map-type-modifier.
+ OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY {
+ assert(Cnt < NumberOfModifiers &&
+ "Requested modifier exceeds the total number of modifiers.");
+ return MapTypeModifiers[Cnt];
+ }
+
+ /// Fetches the map-type-modifier location at 'Cnt' index of array of
+ /// modifiers' locations.
+ ///
+ /// \param Cnt index for map-type-modifier location.
+ SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY {
+ assert(Cnt < NumberOfModifiers &&
+ "Requested modifier location exceeds total number of modifiers.");
+ return MapTypeModifiersLoc[Cnt];
+ }
+
+ /// Fetches ArrayRef of map-type-modifiers.
+ ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY {
+ return llvm::makeArrayRef(MapTypeModifiers);
+ }
+
+ /// Fetches ArrayRef of location of map-type-modifiers.
+ ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY {
+ return llvm::makeArrayRef(MapTypeModifiersLoc);
}
/// Fetches location of clause mapping kind.
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 0a4dc42898..3c877f5ea1 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -51,7 +51,7 @@ struct PrintingPolicy {
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
MSVCFormatting(false), ConstantsAsWritten(false),
SuppressImplicitBase(false), FullyQualifiedName(false),
- RemapFilePaths(false) {}
+ RemapFilePaths(false), PrintCanonicalTypes(false) {}
/// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -228,6 +228,9 @@ struct PrintingPolicy {
/// Whether to apply -fdebug-prefix-map to any file paths.
unsigned RemapFilePaths : 1;
+ /// Whether to print types as written or canonically.
+ unsigned PrintCanonicalTypes : 1;
+
/// When RemapFilePaths is true, this function performs the action.
std::function<std::string(StringRef)> remapPath;
};
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index eb582c7a7a..44aba63557 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -298,14 +298,6 @@ public:
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
Expr *Init);
- /// Recursively visit the body of a lambda expression.
- ///
- /// This provides a hook for visitors that need more context when visiting
- /// \c LE->getBody().
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaBody(LambdaExpr *LE, DataRecursionQueue *Queue = nullptr);
-
/// Recursively visit the syntactic or semantic form of an
/// initialization list.
///
@@ -936,13 +928,6 @@ RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
return true;
}
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(
- LambdaExpr *LE, DataRecursionQueue *Queue) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(LE->getBody());
- return true;
-}
-
// ----------------- Type traversal -----------------
// This macro makes available a variable T, the passed-in type.
@@ -1383,9 +1368,14 @@ DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
template <typename Derived>
bool RecursiveASTVisitor<Derived>::canIgnoreChildDeclWhileTraversingDeclContext(
const Decl *Child) {
- // BlockDecls and CapturedDecls are traversed through BlockExprs and
- // CapturedStmts respectively.
- return isa<BlockDecl>(Child) || isa<CapturedDecl>(Child);
+ // BlockDecls are traversed through BlockExprs,
+ // CapturedDecls are traversed through CapturedStmts.
+ if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
+ return true;
+ // Lambda classes are traversed through LambdaExprs.
+ if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
+ return Cls->isLambda();
+ return false;
}
template <typename Derived>
@@ -2404,6 +2394,7 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
// Walk only the visible parts of lambda expressions.
DEF_TRAVERSE_STMT(LambdaExpr, {
+ // Visit the capture list.
for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
const LambdaCapture *C = S->capture_begin() + I;
if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
@@ -2411,32 +2402,31 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
}
}
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
-
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
+ if (getDerived().shouldVisitImplicitCode()) {
+ // The implicit model is simple: everything else is in the lambda class.
+ TRY_TO(TraverseDecl(S->getLambdaClass()));
} else {
+ // We need to poke around to find the bits that might be explicitly written.
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
+
if (S->hasExplicitParameters()) {
// Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else if (S->hasExplicitResultType()) {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
}
+ if (S->hasExplicitResultType())
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
auto *T = Proto.getTypePtr();
- for (const auto &E : T->exceptions()) {
+ for (const auto &E : T->exceptions())
TRY_TO(TraverseType(E));
- }
if (Expr *NE = T->getNoexceptExpr())
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
- }
- ReturnValue = TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue);
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
+ }
ShouldVisitChildren = false;
})
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 23ac5af7ae..ff5baa21ad 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -433,7 +433,16 @@ protected:
/// True if the callee of the call expression was found using ADL.
unsigned UsesADL : 1;
+
+ /// Padding used to align OffsetToTrailingObjects to a byte multiple.
+ unsigned : 24 - 2 - NumExprBits;
+
+ /// The offset in bytes from the this pointer to the start of the
+ /// trailing objects belonging to CallExpr. Intentionally byte sized
+ /// for faster access.
+ unsigned OffsetToTrailingObjects : 8;
};
+ enum { NumCallExprBits = 32 };
class MemberExprBitfields {
friend class MemberExpr;
@@ -472,7 +481,10 @@ protected:
unsigned Kind : 6;
unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
- unsigned BasePathIsEmpty : 1;
+
+ /// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
+ /// here. ([implimits] Direct and indirect base classes [16384]).
+ unsigned BasePathSize;
};
class BinaryOperatorBitfields {
@@ -523,6 +535,20 @@ protected:
//===--- C++ Expression bitfields classes ---===//
+ class CXXOperatorCallExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXOperatorCallExpr;
+
+ unsigned : NumCallExprBits;
+
+ /// The kind of this overloaded operator. One of the enumerator
+ /// value of OverloadedOperatorKind.
+ unsigned OperatorKind : 6;
+
+ // Only meaningful for floating point types.
+ unsigned FPFeatures : 3;
+ };
+
class CXXBoolLiteralExprBitfields {
friend class CXXBoolLiteralExpr;
@@ -589,6 +615,48 @@ protected:
SourceLocation Loc;
};
+ class CXXScalarValueInitExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXScalarValueInitExpr;
+
+ unsigned : NumExprBits;
+
+ SourceLocation RParenLoc;
+ };
+
+ class CXXNewExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class CXXNewExpr;
+
+ unsigned : NumExprBits;
+
+ /// Was the usage ::new, i.e. is the global new to be used?
+ unsigned IsGlobalNew : 1;
+
+ /// Do we allocate an array? If so, the first trailing "Stmt *" is the
+ /// size expression.
+ unsigned IsArray : 1;
+
+ /// Should the alignment be passed to the allocation function?
+ unsigned ShouldPassAlignment : 1;
+
+ /// If this is an array allocation, does the usual deallocation
+ /// function for the allocated type want to know the allocated size?
+ unsigned UsualArrayDeleteWantsSize : 1;
+
+ /// What kind of initializer do we have? Could be none, parens, or braces.
+ /// In storage, we distinguish between "none, and no initializer expr", and
+ /// "none, but an implicit initializer expr".
+ unsigned StoredInitializationStyle : 2;
+
+ /// True if the allocated type was expressed as a parenthesized type-id.
+ unsigned IsParenTypeId : 1;
+
+ /// The number of placement new arguments.
+ unsigned NumPlacementArgs;
+ };
+
class CXXDeleteExprBitfields {
friend class ASTStmtReader;
friend class CXXDeleteExpr;
@@ -632,6 +700,34 @@ protected:
unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
};
+ class DependentScopeDeclRefExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class DependentScopeDeclRefExpr;
+
+ unsigned : NumExprBits;
+
+ /// Whether the name includes info for explicit template
+ /// keyword and arguments.
+ unsigned HasTemplateKWAndArgsInfo : 1;
+ };
+
+ class CXXConstructExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXConstructExpr;
+
+ unsigned : NumExprBits;
+
+ unsigned Elidable : 1;
+ unsigned HadMultipleCandidates : 1;
+ unsigned ListInitialization : 1;
+ unsigned StdInitListInitialization : 1;
+ unsigned ZeroInitialization : 1;
+ unsigned ConstructionKind : 3;
+
+ SourceLocation Loc;
+ };
+
class ExprWithCleanupsBitfields {
friend class ASTStmtReader; // deserialization
friend class ExprWithCleanups;
@@ -644,6 +740,112 @@ protected:
unsigned NumObjects : 32 - 1 - NumExprBits;
};
+ class CXXUnresolvedConstructExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXUnresolvedConstructExpr;
+
+ unsigned : NumExprBits;
+
+ /// The number of arguments used to construct the type.
+ unsigned NumArgs;
+ };
+
+ class CXXDependentScopeMemberExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXDependentScopeMemberExpr;
+
+ unsigned : NumExprBits;
+
+ /// Whether this member expression used the '->' operator or
+ /// the '.' operator.
+ unsigned IsArrow : 1;
+
+ /// Whether this member expression has info for explicit template
+ /// keyword and arguments.
+ unsigned HasTemplateKWAndArgsInfo : 1;
+
+ /// See getFirstQualifierFoundInScope() and the comment listing
+ /// the trailing objects.
+ unsigned HasFirstQualifierFoundInScope : 1;
+
+ /// The location of the '->' or '.' operator.
+ SourceLocation OperatorLoc;
+ };
+
+ class OverloadExprBitfields {
+ friend class ASTStmtReader;
+ friend class OverloadExpr;
+
+ unsigned : NumExprBits;
+
+ /// Whether the name includes info for explicit template
+ /// keyword and arguments.
+ unsigned HasTemplateKWAndArgsInfo : 1;
+
+ /// Padding used by the derived classes to store various bits. If you
+ /// need to add some data here, shrink this padding and add your data
+ /// above. NumOverloadExprBits also needs to be updated.
+ unsigned : 32 - NumExprBits - 1;
+
+ /// The number of results.
+ unsigned NumResults;
+ };
+ enum { NumOverloadExprBits = NumExprBits + 1 };
+
+ class UnresolvedLookupExprBitfields {
+ friend class ASTStmtReader;
+ friend class UnresolvedLookupExpr;
+
+ unsigned : NumOverloadExprBits;
+
+ /// True if these lookup results should be extended by
+ /// argument-dependent lookup if this is the operand of a function call.
+ unsigned RequiresADL : 1;
+
+ /// True if these lookup results are overloaded. This is pretty trivially
+ /// rederivable if we urgently need to kill this field.
+ unsigned Overloaded : 1;
+ };
+ static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
+ "UnresolvedLookupExprBitfields must be <= than 4 bytes to"
+ "avoid trashing OverloadExprBitfields::NumResults!");
+
+ class UnresolvedMemberExprBitfields {
+ friend class ASTStmtReader;
+ friend class UnresolvedMemberExpr;
+
+ unsigned : NumOverloadExprBits;
+
+ /// Whether this member expression used the '->' operator or
+ /// the '.' operator.
+ unsigned IsArrow : 1;
+
+ /// Whether the lookup results contain an unresolved using declaration.
+ unsigned HasUnresolvedUsing : 1;
+ };
+ static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
+ "UnresolvedMemberExprBitfields must be <= than 4 bytes to"
+ "avoid trashing OverloadExprBitfields::NumResults!");
+
+ class CXXNoexceptExprBitfields {
+ friend class ASTStmtReader;
+ friend class CXXNoexceptExpr;
+
+ unsigned : NumExprBits;
+
+ unsigned Value : 1;
+ };
+
+ class SubstNonTypeTemplateParmExprBitfields {
+ friend class ASTStmtReader;
+ friend class SubstNonTypeTemplateParmExpr;
+
+ unsigned : NumExprBits;
+
+ /// The location of the non-type template parameter reference.
+ SourceLocation NameLoc;
+ };
+
//===--- C++ Coroutines TS bitfields classes ---===//
class CoawaitExprBitfields {
@@ -667,13 +869,16 @@ protected:
//===--- Clang Extensions bitfields classes ---===//
class OpaqueValueExprBitfields {
+ friend class ASTStmtReader;
friend class OpaqueValueExpr;
unsigned : NumExprBits;
- /// The OVE is a unique semantic reference to its source expressio if this
+ /// The OVE is a unique semantic reference to its source expression if this
/// bit is set to true.
unsigned IsUnique : 1;
+
+ SourceLocation Loc;
};
union {
@@ -714,15 +919,27 @@ protected:
PseudoObjectExprBitfields PseudoObjectExprBits;
// C++ Expressions
+ CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
CXXBoolLiteralExprBitfields CXXBoolLiteralExprBits;
CXXNullPtrLiteralExprBitfields CXXNullPtrLiteralExprBits;
CXXThisExprBitfields CXXThisExprBits;
CXXThrowExprBitfields CXXThrowExprBits;
CXXDefaultArgExprBitfields CXXDefaultArgExprBits;
CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
+ CXXScalarValueInitExprBitfields CXXScalarValueInitExprBits;
+ CXXNewExprBitfields CXXNewExprBits;
CXXDeleteExprBitfields CXXDeleteExprBits;
TypeTraitExprBitfields TypeTraitExprBits;
+ DependentScopeDeclRefExprBitfields DependentScopeDeclRefExprBits;
+ CXXConstructExprBitfields CXXConstructExprBits;
ExprWithCleanupsBitfields ExprWithCleanupsBits;
+ CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
+ CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
+ OverloadExprBitfields OverloadExprBits;
+ UnresolvedLookupExprBitfields UnresolvedLookupExprBits;
+ UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
+ CXXNoexceptExprBitfields CXXNoexceptExprBits;
+ SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
// C++ Coroutines TS expressions
CoawaitExprBitfields CoawaitBits;
diff --git a/include/clang/AST/TemplateArgumentVisitor.h b/include/clang/AST/TemplateArgumentVisitor.h
new file mode 100644
index 0000000000..e1cc392a17
--- /dev/null
+++ b/include/clang/AST/TemplateArgumentVisitor.h
@@ -0,0 +1,99 @@
+//===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- 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 TemplateArgumentVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
+#define LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
+
+#include "clang/AST/TemplateBase.h"
+
+namespace clang {
+
+namespace templateargumentvisitor {
+
+/// A simple visitor class that helps create template argument visitors.
+template <template <typename> class Ref, typename ImplClass,
+ typename RetTy = void, typename... ParamTys>
+class Base {
+public:
+#define REF(CLASS) typename Ref<CLASS>::type
+#define DISPATCH(NAME) \
+ case TemplateArgument::NAME: \
+ return static_cast<ImplClass *>(this)->Visit##NAME##TemplateArgument( \
+ TA, std::forward<ParamTys>(P)...)
+
+ RetTy Visit(REF(TemplateArgument) TA, ParamTys... P) {
+ switch (TA.getKind()) {
+ DISPATCH(Null);
+ DISPATCH(Type);
+ DISPATCH(Declaration);
+ DISPATCH(NullPtr);
+ DISPATCH(Integral);
+ DISPATCH(Template);
+ DISPATCH(TemplateExpansion);
+ DISPATCH(Expression);
+ DISPATCH(Pack);
+ }
+ llvm_unreachable("TemplateArgument is not covered in switch!");
+ }
+
+ // If the implementation chooses not to implement a certain visit
+ // method, fall back to the parent.
+
+#define VISIT_METHOD(CATEGORY) \
+ RetTy Visit##CATEGORY##TemplateArgument(REF(TemplateArgument) TA, \
+ ParamTys... P) { \
+ return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); \
+ }
+
+ VISIT_METHOD(Null);
+ VISIT_METHOD(Type);
+ VISIT_METHOD(Declaration);
+ VISIT_METHOD(NullPtr);
+ VISIT_METHOD(Integral);
+ VISIT_METHOD(Template);
+ VISIT_METHOD(TemplateExpansion);
+ VISIT_METHOD(Expression);
+ VISIT_METHOD(Pack);
+
+ RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) {
+ return RetTy();
+ }
+
+#undef REF
+#undef DISPATCH
+#undef VISIT_METHOD
+};
+
+} // namespace templateargumentvisitor
+
+/// A simple visitor class that helps create template argument visitors.
+///
+/// This class does not preserve constness of TemplateArgument references (see
+/// also ConstTemplateArgumentVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class TemplateArgumentVisitor
+ : public templateargumentvisitor::Base<std::add_lvalue_reference, ImplClass,
+ RetTy, ParamTys...> {};
+
+/// A simple visitor class that helps create template argument visitors.
+///
+/// This class preserves constness of TemplateArgument references (see also
+/// TemplateArgumentVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class ConstTemplateArgumentVisitor
+ : public templateargumentvisitor::Base<llvm::make_const_ref, ImplClass,
+ RetTy, ParamTys...> {};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 8f92e799d7..e3a773b4e4 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -530,19 +530,22 @@ public:
}
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
+ if (Argument.getKind() != TemplateArgument::Template &&
+ Argument.getKind() != TemplateArgument::TemplateExpansion)
+ return NestedNameSpecifierLoc();
return LocInfo.getTemplateQualifierLoc();
}
SourceLocation getTemplateNameLoc() const {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
+ if (Argument.getKind() != TemplateArgument::Template &&
+ Argument.getKind() != TemplateArgument::TemplateExpansion)
+ return SourceLocation();
return LocInfo.getTemplateNameLoc();
}
SourceLocation getTemplateEllipsisLoc() const {
- assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
+ if (Argument.getKind() != TemplateArgument::TemplateExpansion)
+ return SourceLocation();
return LocInfo.getTemplateEllipsisLoc();
}
};
@@ -617,13 +620,17 @@ public:
/// The number of template arguments in TemplateArgs.
unsigned NumTemplateArgs;
+ SourceLocation getLAngleLoc() const { return LAngleLoc; }
+ SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
/// Retrieve the template arguments
const TemplateArgumentLoc *getTemplateArgs() const {
return getTrailingObjects<TemplateArgumentLoc>();
}
+ unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
- return llvm::makeArrayRef(getTemplateArgs(), NumTemplateArgs);
+ return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
}
const TemplateArgumentLoc &operator[](unsigned I) const {
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index d88d58d0a2..48272597d4 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
#define LLVM_CLANG_AST_TEMPLATENAME_H
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h
index 5a1dbb40fa..7940663763 100644
--- a/include/clang/AST/TextNodeDumper.h
+++ b/include/clang/AST/TextNodeDumper.h
@@ -16,15 +16,120 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDumperUtils.h"
+#include "clang/AST/AttrVisitor.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/TypeVisitor.h"
namespace clang {
+class TextTreeStructure {
+ raw_ostream &OS;
+ const bool ShowColors;
+
+ /// Pending[i] is an action to dump an entity at level i.
+ llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;
+
+ /// Indicates whether we're at the top level.
+ bool TopLevel = true;
+
+ /// Indicates if we're handling the first child after entering a new depth.
+ bool FirstChild = true;
+
+ /// Prefix for currently-being-dumped entity.
+ std::string Prefix;
+
+public:
+ /// Add a child of the current node. Calls DoAddChild without arguments
+ template <typename Fn> void AddChild(Fn DoAddChild) {
+ return AddChild("", DoAddChild);
+ }
+
+ /// Add a child of the current node with an optional label.
+ /// Calls DoAddChild without arguments.
+ template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
+ // If we're at the top level, there's nothing interesting to do; just
+ // run the dumper.
+ if (TopLevel) {
+ TopLevel = false;
+ DoAddChild();
+ while (!Pending.empty()) {
+ Pending.back()(true);
+ Pending.pop_back();
+ }
+ Prefix.clear();
+ OS << "\n";
+ TopLevel = true;
+ return;
+ }
+
+ // We need to capture an owning-string in the lambda because the lambda
+ // is invoked in a deferred manner.
+ std::string LabelStr = Label;
+ auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) {
+ // Print out the appropriate tree structure and work out the prefix for
+ // children of this node. For instance:
+ //
+ // A Prefix = ""
+ // |-B Prefix = "| "
+ // | `-C Prefix = "| "
+ // `-D Prefix = " "
+ // |-E Prefix = " | "
+ // `-F Prefix = " "
+ // G Prefix = ""
+ //
+ // Note that the first level gets no prefix.
+ {
+ OS << '\n';
+ ColorScope Color(OS, ShowColors, IndentColor);
+ OS << Prefix << (IsLastChild ? '`' : '|') << '-';
+ if (!LabelStr.empty())
+ OS << LabelStr << ": ";
+
+ this->Prefix.push_back(IsLastChild ? ' ' : '|');
+ this->Prefix.push_back(' ');
+ }
+
+ FirstChild = true;
+ unsigned Depth = Pending.size();
+
+ DoAddChild();
+
+ // If any children are left, they're the last at their nesting level.
+ // Dump those ones out now.
+ while (Depth < Pending.size()) {
+ Pending.back()(true);
+ this->Pending.pop_back();
+ }
+
+ // Restore the old prefix.
+ this->Prefix.resize(Prefix.size() - 2);
+ };
+
+ if (FirstChild) {
+ Pending.push_back(std::move(DumpWithIndent));
+ } else {
+ Pending.back()(false);
+ Pending.back() = std::move(DumpWithIndent);
+ }
+ FirstChild = false;
+ }
+
+ TextTreeStructure(raw_ostream &OS, bool ShowColors)
+ : OS(OS), ShowColors(ShowColors) {}
+};
+
class TextNodeDumper
- : public comments::ConstCommentVisitor<TextNodeDumper, void,
- const comments::FullComment *> {
+ : public TextTreeStructure,
+ public comments::ConstCommentVisitor<TextNodeDumper, void,
+ const comments::FullComment *>,
+ public ConstAttrVisitor<TextNodeDumper>,
+ public ConstTemplateArgumentVisitor<TextNodeDumper>,
+ public ConstStmtVisitor<TextNodeDumper>,
+ public TypeVisitor<TextNodeDumper> {
raw_ostream &OS;
const bool ShowColors;
@@ -49,6 +154,25 @@ public:
void Visit(const comments::Comment *C, const comments::FullComment *FC);
+ void Visit(const Attr *A);
+
+ void Visit(const TemplateArgument &TA, SourceRange R,
+ const Decl *From = nullptr, StringRef Label = {});
+
+ void Visit(const Stmt *Node);
+
+ void Visit(const Type *T);
+
+ void Visit(QualType T);
+
+ void Visit(const Decl *D);
+
+ void Visit(const CXXCtorInitializer *Init);
+
+ void Visit(const OMPClause *C);
+
+ void Visit(const BlockDecl::Capture &C);
+
void dumpPointer(const void *Ptr);
void dumpLocation(SourceLocation Loc);
void dumpSourceRange(SourceRange R);
@@ -57,7 +181,8 @@ public:
void dumpBareDeclRef(const Decl *D);
void dumpName(const NamedDecl *ND);
void dumpAccessSpecifier(AccessSpecifier AS);
- void dumpCXXTemporary(const CXXTemporary *Temporary);
+
+ void dumpDeclRef(const Decl *D, StringRef Label = {});
void visitTextComment(const comments::TextComment *C,
const comments::FullComment *);
@@ -80,6 +205,92 @@ public:
const comments::FullComment *);
void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
const comments::FullComment *);
+
+// Implements Visit methods for Attrs.
+#include "clang/AST/AttrTextNodeDump.inc"
+
+ void VisitNullTemplateArgument(const TemplateArgument &TA);
+ void VisitTypeTemplateArgument(const TemplateArgument &TA);
+ void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
+ void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
+ void VisitIntegralTemplateArgument(const TemplateArgument &TA);
+ void VisitTemplateTemplateArgument(const TemplateArgument &TA);
+ void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
+ void VisitExpressionTemplateArgument(const TemplateArgument &TA);
+ void VisitPackTemplateArgument(const TemplateArgument &TA);
+
+ void VisitIfStmt(const IfStmt *Node);
+ void VisitSwitchStmt(const SwitchStmt *Node);
+ void VisitWhileStmt(const WhileStmt *Node);
+ void VisitLabelStmt(const LabelStmt *Node);
+ void VisitGotoStmt(const GotoStmt *Node);
+ void VisitCaseStmt(const CaseStmt *Node);
+ void VisitCallExpr(const CallExpr *Node);
+ void VisitCastExpr(const CastExpr *Node);
+ void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
+ void VisitDeclRefExpr(const DeclRefExpr *Node);
+ void VisitPredefinedExpr(const PredefinedExpr *Node);
+ void VisitCharacterLiteral(const CharacterLiteral *Node);
+ void VisitIntegerLiteral(const IntegerLiteral *Node);
+ void VisitFixedPointLiteral(const FixedPointLiteral *Node);
+ void VisitFloatingLiteral(const FloatingLiteral *Node);
+ void VisitStringLiteral(const StringLiteral *Str);
+ void VisitInitListExpr(const InitListExpr *ILE);
+ void VisitUnaryOperator(const UnaryOperator *Node);
+ void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
+ void VisitMemberExpr(const MemberExpr *Node);
+ void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
+ void VisitBinaryOperator(const BinaryOperator *Node);
+ void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
+ void VisitAddrLabelExpr(const AddrLabelExpr *Node);
+ void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
+ void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
+ void VisitCXXThisExpr(const CXXThisExpr *Node);
+ void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
+ void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
+ void VisitCXXConstructExpr(const CXXConstructExpr *Node);
+ void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
+ void VisitCXXNewExpr(const CXXNewExpr *Node);
+ void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
+ void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
+ void VisitExprWithCleanups(const ExprWithCleanups *Node);
+ void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
+ void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
+ void
+ VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node);
+ void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
+ void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
+ void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
+ void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
+ void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
+ void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
+ void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
+ void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
+ void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
+ void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
+
+ void VisitRValueReferenceType(const ReferenceType *T);
+ void VisitArrayType(const ArrayType *T);
+ void VisitConstantArrayType(const ConstantArrayType *T);
+ void VisitVariableArrayType(const VariableArrayType *T);
+ void VisitDependentSizedArrayType(const DependentSizedArrayType *T);
+ void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T);
+ void VisitVectorType(const VectorType *T);
+ void VisitFunctionType(const FunctionType *T);
+ void VisitFunctionProtoType(const FunctionProtoType *T);
+ void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
+ void VisitTypedefType(const TypedefType *T);
+ void VisitUnaryTransformType(const UnaryTransformType *T);
+ void VisitTagType(const TagType *T);
+ void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
+ void VisitAutoType(const AutoType *T);
+ void VisitTemplateSpecializationType(const TemplateSpecializationType *T);
+ void VisitInjectedClassNameType(const InjectedClassNameType *T);
+ void VisitObjCInterfaceType(const ObjCInterfaceType *T);
+ void VisitPackExpansionType(const PackExpansionType *T);
+
+private:
+ void dumpCXXTemporary(const CXXTemporary *Temporary);
};
} // namespace clang
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 5b69570aab..d4c97b1b5e 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -980,9 +980,7 @@ public:
void print(raw_ostream &OS, const PrintingPolicy &Policy,
const Twine &PlaceHolder = Twine(),
- unsigned Indentation = 0) const {
- print(split(), OS, Policy, PlaceHolder, Indentation);
- }
+ unsigned Indentation = 0) const;
static void print(SplitQualType split, raw_ostream &OS,
const PrintingPolicy &policy, const Twine &PlaceHolder,
@@ -996,9 +994,7 @@ public:
unsigned Indentation = 0);
void getAsStringInternal(std::string &Str,
- const PrintingPolicy &Policy) const {
- return getAsStringInternal(split(), Str, Policy);
- }
+ const PrintingPolicy &Policy) const;
static void getAsStringInternal(SplitQualType split, std::string &out,
const PrintingPolicy &policy) {
@@ -6705,6 +6701,24 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
return type;
}
+/// Insertion operator for diagnostics. This allows sending Qualifiers into a
+/// diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ Qualifiers Q) {
+ DB.AddTaggedVal(Q.getAsOpaqueValue(),
+ DiagnosticsEngine::ArgumentKind::ak_qual);
+ return DB;
+}
+
+/// Insertion operator for partial diagnostics. This allows sending Qualifiers
+/// into a diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ Qualifiers Q) {
+ PD.AddTaggedVal(Q.getAsOpaqueValue(),
+ DiagnosticsEngine::ArgumentKind::ak_qual);
+ return PD;
+}
+
/// Insertion operator for diagnostics. This allows sending QualType's into a
/// diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,