Update Clang for 3.5 rebase (r209713).
Change-Id: I8c9133b0f8f776dc915f270b60f94962e771bc83
diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h
index 8212728..ed3e8d9 100644
--- a/include/clang-c/BuildSystem.h
+++ b/include/clang-c/BuildSystem.h
@@ -1,4 +1,4 @@
-/*==-- clang-c/BuildSysetm.h - Utilities for use by build systems -*- C -*-===*\
+/*==-- clang-c/BuildSystem.h - Utilities for use by build systems -*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h
index 592c4dc..cf198cb 100644
--- a/include/clang-c/CXString.h
+++ b/include/clang-c/CXString.h
@@ -31,7 +31,7 @@
* \brief A character string.
*
* The \c CXString type is used to return strings from the interface when
- * the ownership of that string might different from one call to the next.
+ * the ownership of that string might differ from one call to the next.
* Use \c clang_getCString() to retrieve the string data and, once finished
* with the string data, call \c clang_disposeString() to free the string.
*/
diff --git a/include/clang-c/Documentation.h b/include/clang-c/Documentation.h
new file mode 100644
index 0000000..ad2da07
--- /dev/null
+++ b/include/clang-c/Documentation.h
@@ -0,0 +1,554 @@
+/*==-- clang-c/Documentation.h - Utilities for comment processing -*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This header provides a supplementary interface for inspecting *|
+|* documentation comments. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_DOCUMENTATION_H
+#define CLANG_C_DOCUMENTATION_H
+
+#include "clang-c/Index.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup CINDEX_COMMENT Comment introspection
+ *
+ * The routines in this group provide access to information in documentation
+ * comments. These facilities are distinct from the core and may be subject to
+ * their own schedule of stability and deprecation.
+ *
+ * @{
+ */
+
+/**
+ * \brief A parsed comment.
+ */
+typedef struct {
+ const void *ASTNode;
+ CXTranslationUnit TranslationUnit;
+} CXComment;
+
+/**
+ * \brief Given a cursor that represents a documentable entity (e.g.,
+ * declaration), return the associated parsed comment as a
+ * \c CXComment_FullComment AST node.
+ */
+CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C);
+
+/**
+ * \brief Describes the type of the comment AST node (\c CXComment). A comment
+ * node can be considered block content (e. g., paragraph), inline content
+ * (plain text) or neither (the root AST node).
+ */
+enum CXCommentKind {
+ /**
+ * \brief Null comment. No AST node is constructed at the requested location
+ * because there is no text or a syntax error.
+ */
+ CXComment_Null = 0,
+
+ /**
+ * \brief Plain text. Inline content.
+ */
+ CXComment_Text = 1,
+
+ /**
+ * \brief A command with word-like arguments that is considered inline content.
+ *
+ * For example: \\c command.
+ */
+ CXComment_InlineCommand = 2,
+
+ /**
+ * \brief HTML start tag with attributes (name-value pairs). Considered
+ * inline content.
+ *
+ * For example:
+ * \verbatim
+ * <br> <br /> <a href="http://example.org/">
+ * \endverbatim
+ */
+ CXComment_HTMLStartTag = 3,
+
+ /**
+ * \brief HTML end tag. Considered inline content.
+ *
+ * For example:
+ * \verbatim
+ * </a>
+ * \endverbatim
+ */
+ CXComment_HTMLEndTag = 4,
+
+ /**
+ * \brief A paragraph, contains inline comment. The paragraph itself is
+ * block content.
+ */
+ CXComment_Paragraph = 5,
+
+ /**
+ * \brief A command that has zero or more word-like arguments (number of
+ * word-like arguments depends on command name) and a paragraph as an
+ * argument. Block command is block content.
+ *
+ * Paragraph argument is also a child of the block command.
+ *
+ * For example: \\brief has 0 word-like arguments and a paragraph argument.
+ *
+ * AST nodes of special kinds that parser knows about (e. g., \\param
+ * command) have their own node kinds.
+ */
+ CXComment_BlockCommand = 6,
+
+ /**
+ * \brief A \\param or \\arg command that describes the function parameter
+ * (name, passing direction, description).
+ *
+ * For example: \\param [in] ParamName description.
+ */
+ CXComment_ParamCommand = 7,
+
+ /**
+ * \brief A \\tparam command that describes a template parameter (name and
+ * description).
+ *
+ * For example: \\tparam T description.
+ */
+ CXComment_TParamCommand = 8,
+
+ /**
+ * \brief A verbatim block command (e. g., preformatted code). Verbatim
+ * block has an opening and a closing command and contains multiple lines of
+ * text (\c CXComment_VerbatimBlockLine child nodes).
+ *
+ * For example:
+ * \\verbatim
+ * aaa
+ * \\endverbatim
+ */
+ CXComment_VerbatimBlockCommand = 9,
+
+ /**
+ * \brief A line of text that is contained within a
+ * CXComment_VerbatimBlockCommand node.
+ */
+ CXComment_VerbatimBlockLine = 10,
+
+ /**
+ * \brief A verbatim line command. Verbatim line has an opening command,
+ * a single line of text (up to the newline after the opening command) and
+ * has no closing command.
+ */
+ CXComment_VerbatimLine = 11,
+
+ /**
+ * \brief A full comment attached to a declaration, contains block content.
+ */
+ CXComment_FullComment = 12
+};
+
+/**
+ * \brief The most appropriate rendering mode for an inline command, chosen on
+ * command semantics in Doxygen.
+ */
+enum CXCommentInlineCommandRenderKind {
+ /**
+ * \brief Command argument should be rendered in a normal font.
+ */
+ CXCommentInlineCommandRenderKind_Normal,
+
+ /**
+ * \brief Command argument should be rendered in a bold font.
+ */
+ CXCommentInlineCommandRenderKind_Bold,
+
+ /**
+ * \brief Command argument should be rendered in a monospaced font.
+ */
+ CXCommentInlineCommandRenderKind_Monospaced,
+
+ /**
+ * \brief Command argument should be rendered emphasized (typically italic
+ * font).
+ */
+ CXCommentInlineCommandRenderKind_Emphasized
+};
+
+/**
+ * \brief Describes parameter passing direction for \\param or \\arg command.
+ */
+enum CXCommentParamPassDirection {
+ /**
+ * \brief The parameter is an input parameter.
+ */
+ CXCommentParamPassDirection_In,
+
+ /**
+ * \brief The parameter is an output parameter.
+ */
+ CXCommentParamPassDirection_Out,
+
+ /**
+ * \brief The parameter is an input and output parameter.
+ */
+ CXCommentParamPassDirection_InOut
+};
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \returns the type of the AST node.
+ */
+CINDEX_LINKAGE enum CXCommentKind clang_Comment_getKind(CXComment Comment);
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \returns number of children of the AST node.
+ */
+CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment);
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \param ChildIdx child index (zero-based).
+ *
+ * \returns the specified child of the AST node.
+ */
+CINDEX_LINKAGE
+CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);
+
+/**
+ * \brief A \c CXComment_Paragraph node is considered whitespace if it contains
+ * only \c CXComment_Text nodes that are empty or whitespace.
+ *
+ * Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are
+ * never considered whitespace.
+ *
+ * \returns non-zero if \c Comment is whitespace.
+ */
+CINDEX_LINKAGE unsigned clang_Comment_isWhitespace(CXComment Comment);
+
+/**
+ * \returns non-zero if \c Comment is inline content and has a newline
+ * immediately following it in the comment text. Newlines between paragraphs
+ * do not count.
+ */
+CINDEX_LINKAGE
+unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_Text AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns name of the inline command.
+ */
+CINDEX_LINKAGE
+CXString clang_InlineCommandComment_getCommandName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns the most appropriate rendering mode, chosen on command
+ * semantics in Doxygen.
+ */
+CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind
+clang_InlineCommandComment_getRenderKind(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns number of command arguments.
+ */
+CINDEX_LINKAGE
+unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \param ArgIdx argument index (zero-based).
+ *
+ * \returns text of the specified argument.
+ */
+CINDEX_LINKAGE
+CXString clang_InlineCommandComment_getArgText(CXComment Comment,
+ unsigned ArgIdx);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
+ * node.
+ *
+ * \returns HTML tag name.
+ */
+CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \returns non-zero if tag is self-closing (for example, <br />).
+ */
+CINDEX_LINKAGE
+unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \returns number of attributes (name-value pairs) attached to the start tag.
+ */
+CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \param AttrIdx attribute index (zero-based).
+ *
+ * \returns name of the specified attribute.
+ */
+CINDEX_LINKAGE
+CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \param AttrIdx attribute index (zero-based).
+ *
+ * \returns value of the specified attribute.
+ */
+CINDEX_LINKAGE
+CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \returns name of the block command.
+ */
+CINDEX_LINKAGE
+CXString clang_BlockCommandComment_getCommandName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \returns number of word-like arguments.
+ */
+CINDEX_LINKAGE
+unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \param ArgIdx argument index (zero-based).
+ *
+ * \returns text of the specified word-like argument.
+ */
+CINDEX_LINKAGE
+CXString clang_BlockCommandComment_getArgText(CXComment Comment,
+ unsigned ArgIdx);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand or
+ * \c CXComment_VerbatimBlockCommand AST node.
+ *
+ * \returns paragraph argument of the block command.
+ */
+CINDEX_LINKAGE
+CXComment clang_BlockCommandComment_getParagraph(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_ParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the function prototype and \c clang_ParamCommandComment_getParamIndex
+ * function will return a meaningful value.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns zero-based parameter index in function prototype.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns non-zero if parameter passing direction was specified explicitly in
+ * the comment.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns parameter passing direction.
+ */
+CINDEX_LINKAGE
+enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
+ CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns template parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_TParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the template parameter list and
+ * \c clang_TParamCommandComment_getDepth and
+ * \c clang_TParamCommandComment_getIndex functions will return a meaningful
+ * value.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based nesting depth of this parameter in the template parameter list.
+ *
+ * For example,
+ * \verbatim
+ * template<typename C, template<typename T> class TT>
+ * void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0,
+ * for T nesting depth is 1.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getDepth(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based parameter index in the template parameter list at a
+ * given nesting depth.
+ *
+ * For example,
+ * \verbatim
+ * template<typename C, template<typename T> class TT>
+ * void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0, so we can ask for index at depth 0:
+ * at depth 0 C's index is 0, TT's index is 1.
+ *
+ * For T nesting depth is 1, so we can ask for index at depth 0 and 1:
+ * at depth 0 T's index is 1 (same as TT's),
+ * at depth 1 T's index is 0.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);
+
+/**
+ * \param Comment a \c CXComment_VerbatimBlockLine AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE
+CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_VerbatimLine AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
+
+/**
+ * \brief Convert an HTML tag AST node to string.
+ *
+ * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
+ * node.
+ *
+ * \returns string containing an HTML tag.
+ */
+CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
+
+/**
+ * \brief Convert a given full parsed comment to an HTML fragment.
+ *
+ * Specific details of HTML layout are subject to change. Don't try to parse
+ * this HTML back into an AST, use other APIs instead.
+ *
+ * Currently the following CSS classes are used:
+ * \li "para-brief" for \\brief paragraph and equivalent commands;
+ * \li "para-returns" for \\returns paragraph and equivalent commands;
+ * \li "word-returns" for the "Returns" word in \\returns paragraph.
+ *
+ * Function argument documentation is rendered as a \<dl\> list with arguments
+ * sorted in function prototype order. CSS classes used:
+ * \li "param-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "param-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if
+ * parameter index is invalid.
+ *
+ * Template parameter documentation is rendered as a \<dl\> list with
+ * parameters sorted in template parameter list order. CSS classes used:
+ * \li "tparam-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "tparam-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for
+ * names inside template template parameters;
+ * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if
+ * parameter position is invalid.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an HTML fragment.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
+
+/**
+ * \brief Convert a given full parsed comment to an XML document.
+ *
+ * A Relax NG schema for the XML can be found in comment-xml-schema.rng file
+ * inside clang source tree.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an XML document.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLANG_C_DOCUMENTATION_H */
+
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 7eff0a4..3d4a229 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 24
+#define CINDEX_VERSION_MINOR 27
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -653,12 +653,6 @@
CXDiagnostic_Note = 1,
/**
- * \brief This diagnostic is a remark that provides additional information
- * for the user.
- */
- CXDiagnostic_Remark = 5,
-
- /**
* \brief This diagnostic indicates suspicious code that may not be
* wrong.
*/
@@ -1740,7 +1734,7 @@
/**
* \brief An expression that refers to some value declaration, such
- * as a function, varible, or enumerator.
+ * as a function, variable, or enumerator.
*/
CXCursor_DeclRefExpr = 101,
@@ -1978,7 +1972,7 @@
*/
CXCursor_ObjCBoolLiteralExpr = 145,
- /** \brief Represents the "self" expression in a ObjC method.
+ /** \brief Represents the "self" expression in an Objective-C method.
*/
CXCursor_ObjCSelfExpr = 146,
@@ -2171,7 +2165,10 @@
CXCursor_AnnotateAttr = 406,
CXCursor_AsmLabelAttr = 407,
CXCursor_PackedAttr = 408,
- CXCursor_LastAttr = CXCursor_PackedAttr,
+ CXCursor_PureAttr = 409,
+ CXCursor_ConstAttr = 410,
+ CXCursor_NoDuplicateAttr = 411,
+ CXCursor_LastAttr = CXCursor_NoDuplicateAttr,
/* Preprocessing */
CXCursor_PreprocessingDirective = 500,
@@ -2216,14 +2213,6 @@
} CXCursor;
/**
- * \brief A comment AST node.
- */
-typedef struct {
- const void *ASTNode;
- CXTranslationUnit TranslationUnit;
-} CXComment;
-
-/**
* \defgroup CINDEX_CURSOR_MANIP Cursor manipulations
*
* @{
@@ -2510,10 +2499,10 @@
* void C::f() { }
* \endcode
*
- * In the out-of-line definition of \c C::f, the semantic parent is the
+ * In the out-of-line definition of \c C::f, the semantic parent is
* the class \c C, of which this function is a member. The lexical parent is
* the place where the declaration actually occurs in the source code; in this
- * case, the definition occurs in the translation unit. In general, the
+ * case, the definition occurs in the translation unit. In general, the
* lexical parent for a given entity can change without affecting the semantics
* of the program, and the lexical parent of different declarations of the
* same entity may be different. Changing the semantic parent of a declaration,
@@ -2545,10 +2534,10 @@
* void C::f() { }
* \endcode
*
- * In the out-of-line definition of \c C::f, the semantic parent is the
+ * In the out-of-line definition of \c C::f, the semantic parent is
* the class \c C, of which this function is a member. The lexical parent is
* the place where the declaration actually occurs in the source code; in this
- * case, the definition occurs in the translation unit. In general, the
+ * case, the definition occurs in the translation unit. In general, the
* lexical parent for a given entity can change without affecting the semantics
* of the program, and the lexical parent of different declarations of the
* same entity may be different. Changing the semantic parent of a declaration,
@@ -2673,7 +2662,7 @@
*
* The extent of a cursor starts with the file/line/column pointing at the
* first character within the source construct that the cursor refers to and
- * ends with the last character withinin that source construct. For a
+ * ends with the last character within that source construct. For a
* declaration, the extent covers the declaration itself. For a reference,
* the extent covers the location of the reference (e.g., where the referenced
* entity was actually used).
@@ -2695,7 +2684,7 @@
*/
enum CXTypeKind {
/**
- * \brief Reprents an invalid type (e.g., where no type is available).
+ * \brief Represents an invalid type (e.g., where no type is available).
*/
CXType_Invalid = 0,
@@ -3367,8 +3356,8 @@
/**
* \brief Retrieve a range for a piece that forms the cursors spelling name.
* Most of the times there is only one range for the complete spelling but for
- * objc methods and objc message expressions, there are multiple pieces for each
- * selector identifier.
+ * Objective-C methods and Objective-C message expressions, there are multiple
+ * pieces for each selector identifier.
*
* \param pieceIndex the index of the spelling name piece. If this is greater
* than the actual number of pieces, it will return a NULL (invalid) range.
@@ -3464,25 +3453,25 @@
/**
- * \brief If the cursor points to a selector identifier in a objc method or
- * message expression, this returns the selector index.
+ * \brief If the cursor points to a selector identifier in an Objective-C
+ * method or message expression, this returns the selector index.
*
* After getting a cursor with #clang_getCursor, this can be called to
* determine if the location points to a selector identifier.
*
- * \returns The selector index if the cursor is an objc method or message
+ * \returns The selector index if the cursor is an Objective-C method or message
* expression and the cursor is pointing to a selector identifier, or -1
* otherwise.
*/
CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor);
/**
- * \brief Given a cursor pointing to a C++ method call or an ObjC message,
- * returns non-zero if the method/message is "dynamic", meaning:
+ * \brief Given a cursor pointing to a C++ method call or an Objective-C
+ * message, returns non-zero if the method/message is "dynamic", meaning:
*
* For a C++ method: the call is virtual.
- * For an ObjC message: the receiver is an object instance, not 'super' or a
- * specific class.
+ * For an Objective-C message: the receiver is an object instance, not 'super'
+ * or a specific class.
*
* If the method/message is "static" or the cursor does not point to a
* method/message, it will return zero.
@@ -3490,8 +3479,8 @@
CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C);
/**
- * \brief Given a cursor pointing to an ObjC message, returns the CXType of the
- * receiver.
+ * \brief Given a cursor pointing to an Objective-C message, returns the CXType
+ * of the receiver.
*/
CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C);
@@ -3526,7 +3515,7 @@
/**
* \brief 'Qualifiers' written next to the return and parameter types in
- * ObjC method declarations.
+ * Objective-C method declarations.
*/
typedef enum {
CXObjCDeclQualifier_None = 0x0,
@@ -3539,15 +3528,16 @@
} CXObjCDeclQualifierKind;
/**
- * \brief Given a cursor that represents an ObjC method or parameter
- * declaration, return the associated ObjC qualifiers for the return type or the
- * parameter respectively. The bits are formed from CXObjCDeclQualifierKind.
+ * \brief Given a cursor that represents an Objective-C method or parameter
+ * declaration, return the associated Objective-C qualifiers for the return
+ * type or the parameter respectively. The bits are formed from
+ * CXObjCDeclQualifierKind.
*/
CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C);
/**
- * \brief Given a cursor that represents an ObjC method or property declaration,
- * return non-zero if the declaration was affected by "@optional".
+ * \brief Given a cursor that represents an Objective-C method or property
+ * declaration, return non-zero if the declaration was affected by "@optional".
* Returns zero if the cursor is not such a declaration or it is "@required".
*/
CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
@@ -3578,13 +3568,6 @@
CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C);
/**
- * \brief Given a cursor that represents a documentable entity (e.g.,
- * declaration), return the associated parsed comment as a
- * \c CXComment_FullComment AST node.
- */
-CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C);
-
-/**
* @}
*/
@@ -3604,6 +3587,12 @@
CINDEX_LINKAGE CXModule clang_Cursor_getModule(CXCursor C);
/**
+ * \brief Given a CXFile header file, return the module that contains it, if one
+ * exists.
+ */
+CINDEX_LINKAGE CXModule clang_getModuleForFile(CXTranslationUnit, CXFile);
+
+/**
* \param Module a module object.
*
* \returns the module file where the provided module object came from.
@@ -3636,6 +3625,13 @@
/**
* \param Module a module object.
*
+ * \returns non-zero if the module is a system one.
+ */
+CINDEX_LINKAGE int clang_Module_isSystem(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
* \returns the number of top level headers associated with this module.
*/
CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit,
@@ -3657,514 +3653,6 @@
*/
/**
- * \defgroup CINDEX_COMMENT Comment AST introspection
- *
- * The routines in this group provide access to information in the
- * documentation comment ASTs.
- *
- * @{
- */
-
-/**
- * \brief Describes the type of the comment AST node (\c CXComment). A comment
- * node can be considered block content (e. g., paragraph), inline content
- * (plain text) or neither (the root AST node).
- */
-enum CXCommentKind {
- /**
- * \brief Null comment. No AST node is constructed at the requested location
- * because there is no text or a syntax error.
- */
- CXComment_Null = 0,
-
- /**
- * \brief Plain text. Inline content.
- */
- CXComment_Text = 1,
-
- /**
- * \brief A command with word-like arguments that is considered inline content.
- *
- * For example: \\c command.
- */
- CXComment_InlineCommand = 2,
-
- /**
- * \brief HTML start tag with attributes (name-value pairs). Considered
- * inline content.
- *
- * For example:
- * \verbatim
- * <br> <br /> <a href="http://example.org/">
- * \endverbatim
- */
- CXComment_HTMLStartTag = 3,
-
- /**
- * \brief HTML end tag. Considered inline content.
- *
- * For example:
- * \verbatim
- * </a>
- * \endverbatim
- */
- CXComment_HTMLEndTag = 4,
-
- /**
- * \brief A paragraph, contains inline comment. The paragraph itself is
- * block content.
- */
- CXComment_Paragraph = 5,
-
- /**
- * \brief A command that has zero or more word-like arguments (number of
- * word-like arguments depends on command name) and a paragraph as an
- * argument. Block command is block content.
- *
- * Paragraph argument is also a child of the block command.
- *
- * For example: \\brief has 0 word-like arguments and a paragraph argument.
- *
- * AST nodes of special kinds that parser knows about (e. g., \\param
- * command) have their own node kinds.
- */
- CXComment_BlockCommand = 6,
-
- /**
- * \brief A \\param or \\arg command that describes the function parameter
- * (name, passing direction, description).
- *
- * For example: \\param [in] ParamName description.
- */
- CXComment_ParamCommand = 7,
-
- /**
- * \brief A \\tparam command that describes a template parameter (name and
- * description).
- *
- * For example: \\tparam T description.
- */
- CXComment_TParamCommand = 8,
-
- /**
- * \brief A verbatim block command (e. g., preformatted code). Verbatim
- * block has an opening and a closing command and contains multiple lines of
- * text (\c CXComment_VerbatimBlockLine child nodes).
- *
- * For example:
- * \\verbatim
- * aaa
- * \\endverbatim
- */
- CXComment_VerbatimBlockCommand = 9,
-
- /**
- * \brief A line of text that is contained within a
- * CXComment_VerbatimBlockCommand node.
- */
- CXComment_VerbatimBlockLine = 10,
-
- /**
- * \brief A verbatim line command. Verbatim line has an opening command,
- * a single line of text (up to the newline after the opening command) and
- * has no closing command.
- */
- CXComment_VerbatimLine = 11,
-
- /**
- * \brief A full comment attached to a declaration, contains block content.
- */
- CXComment_FullComment = 12
-};
-
-/**
- * \brief The most appropriate rendering mode for an inline command, chosen on
- * command semantics in Doxygen.
- */
-enum CXCommentInlineCommandRenderKind {
- /**
- * \brief Command argument should be rendered in a normal font.
- */
- CXCommentInlineCommandRenderKind_Normal,
-
- /**
- * \brief Command argument should be rendered in a bold font.
- */
- CXCommentInlineCommandRenderKind_Bold,
-
- /**
- * \brief Command argument should be rendered in a monospaced font.
- */
- CXCommentInlineCommandRenderKind_Monospaced,
-
- /**
- * \brief Command argument should be rendered emphasized (typically italic
- * font).
- */
- CXCommentInlineCommandRenderKind_Emphasized
-};
-
-/**
- * \brief Describes parameter passing direction for \\param or \\arg command.
- */
-enum CXCommentParamPassDirection {
- /**
- * \brief The parameter is an input parameter.
- */
- CXCommentParamPassDirection_In,
-
- /**
- * \brief The parameter is an output parameter.
- */
- CXCommentParamPassDirection_Out,
-
- /**
- * \brief The parameter is an input and output parameter.
- */
- CXCommentParamPassDirection_InOut
-};
-
-/**
- * \param Comment AST node of any kind.
- *
- * \returns the type of the AST node.
- */
-CINDEX_LINKAGE enum CXCommentKind clang_Comment_getKind(CXComment Comment);
-
-/**
- * \param Comment AST node of any kind.
- *
- * \returns number of children of the AST node.
- */
-CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment);
-
-/**
- * \param Comment AST node of any kind.
- *
- * \param ChildIdx child index (zero-based).
- *
- * \returns the specified child of the AST node.
- */
-CINDEX_LINKAGE
-CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);
-
-/**
- * \brief A \c CXComment_Paragraph node is considered whitespace if it contains
- * only \c CXComment_Text nodes that are empty or whitespace.
- *
- * Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are
- * never considered whitespace.
- *
- * \returns non-zero if \c Comment is whitespace.
- */
-CINDEX_LINKAGE unsigned clang_Comment_isWhitespace(CXComment Comment);
-
-/**
- * \returns non-zero if \c Comment is inline content and has a newline
- * immediately following it in the comment text. Newlines between paragraphs
- * do not count.
- */
-CINDEX_LINKAGE
-unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_Text AST node.
- *
- * \returns text contained in the AST node.
- */
-CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_InlineCommand AST node.
- *
- * \returns name of the inline command.
- */
-CINDEX_LINKAGE
-CXString clang_InlineCommandComment_getCommandName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_InlineCommand AST node.
- *
- * \returns the most appropriate rendering mode, chosen on command
- * semantics in Doxygen.
- */
-CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind
-clang_InlineCommandComment_getRenderKind(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_InlineCommand AST node.
- *
- * \returns number of command arguments.
- */
-CINDEX_LINKAGE
-unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_InlineCommand AST node.
- *
- * \param ArgIdx argument index (zero-based).
- *
- * \returns text of the specified argument.
- */
-CINDEX_LINKAGE
-CXString clang_InlineCommandComment_getArgText(CXComment Comment,
- unsigned ArgIdx);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
- * node.
- *
- * \returns HTML tag name.
- */
-CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag AST node.
- *
- * \returns non-zero if tag is self-closing (for example, <br />).
- */
-CINDEX_LINKAGE
-unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag AST node.
- *
- * \returns number of attributes (name-value pairs) attached to the start tag.
- */
-CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag AST node.
- *
- * \param AttrIdx attribute index (zero-based).
- *
- * \returns name of the specified attribute.
- */
-CINDEX_LINKAGE
-CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag AST node.
- *
- * \param AttrIdx attribute index (zero-based).
- *
- * \returns value of the specified attribute.
- */
-CINDEX_LINKAGE
-CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx);
-
-/**
- * \param Comment a \c CXComment_BlockCommand AST node.
- *
- * \returns name of the block command.
- */
-CINDEX_LINKAGE
-CXString clang_BlockCommandComment_getCommandName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_BlockCommand AST node.
- *
- * \returns number of word-like arguments.
- */
-CINDEX_LINKAGE
-unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_BlockCommand AST node.
- *
- * \param ArgIdx argument index (zero-based).
- *
- * \returns text of the specified word-like argument.
- */
-CINDEX_LINKAGE
-CXString clang_BlockCommandComment_getArgText(CXComment Comment,
- unsigned ArgIdx);
-
-/**
- * \param Comment a \c CXComment_BlockCommand or
- * \c CXComment_VerbatimBlockCommand AST node.
- *
- * \returns paragraph argument of the block command.
- */
-CINDEX_LINKAGE
-CXComment clang_BlockCommandComment_getParagraph(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns parameter name.
- */
-CINDEX_LINKAGE
-CXString clang_ParamCommandComment_getParamName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns non-zero if the parameter that this AST node represents was found
- * in the function prototype and \c clang_ParamCommandComment_getParamIndex
- * function will return a meaningful value.
- */
-CINDEX_LINKAGE
-unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns zero-based parameter index in function prototype.
- */
-CINDEX_LINKAGE
-unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns non-zero if parameter passing direction was specified explicitly in
- * the comment.
- */
-CINDEX_LINKAGE
-unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns parameter passing direction.
- */
-CINDEX_LINKAGE
-enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
- CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_TParamCommand AST node.
- *
- * \returns template parameter name.
- */
-CINDEX_LINKAGE
-CXString clang_TParamCommandComment_getParamName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_TParamCommand AST node.
- *
- * \returns non-zero if the parameter that this AST node represents was found
- * in the template parameter list and
- * \c clang_TParamCommandComment_getDepth and
- * \c clang_TParamCommandComment_getIndex functions will return a meaningful
- * value.
- */
-CINDEX_LINKAGE
-unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_TParamCommand AST node.
- *
- * \returns zero-based nesting depth of this parameter in the template parameter list.
- *
- * For example,
- * \verbatim
- * template<typename C, template<typename T> class TT>
- * void test(TT<int> aaa);
- * \endverbatim
- * for C and TT nesting depth is 0,
- * for T nesting depth is 1.
- */
-CINDEX_LINKAGE
-unsigned clang_TParamCommandComment_getDepth(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_TParamCommand AST node.
- *
- * \returns zero-based parameter index in the template parameter list at a
- * given nesting depth.
- *
- * For example,
- * \verbatim
- * template<typename C, template<typename T> class TT>
- * void test(TT<int> aaa);
- * \endverbatim
- * for C and TT nesting depth is 0, so we can ask for index at depth 0:
- * at depth 0 C's index is 0, TT's index is 1.
- *
- * For T nesting depth is 1, so we can ask for index at depth 0 and 1:
- * at depth 0 T's index is 1 (same as TT's),
- * at depth 1 T's index is 0.
- */
-CINDEX_LINKAGE
-unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);
-
-/**
- * \param Comment a \c CXComment_VerbatimBlockLine AST node.
- *
- * \returns text contained in the AST node.
- */
-CINDEX_LINKAGE
-CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_VerbatimLine AST node.
- *
- * \returns text contained in the AST node.
- */
-CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
-
-/**
- * \brief Convert an HTML tag AST node to string.
- *
- * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
- * node.
- *
- * \returns string containing an HTML tag.
- */
-CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
-
-/**
- * \brief Convert a given full parsed comment to an HTML fragment.
- *
- * Specific details of HTML layout are subject to change. Don't try to parse
- * this HTML back into an AST, use other APIs instead.
- *
- * Currently the following CSS classes are used:
- * \li "para-brief" for \\brief paragraph and equivalent commands;
- * \li "para-returns" for \\returns paragraph and equivalent commands;
- * \li "word-returns" for the "Returns" word in \\returns paragraph.
- *
- * Function argument documentation is rendered as a \<dl\> list with arguments
- * sorted in function prototype order. CSS classes used:
- * \li "param-name-index-NUMBER" for parameter name (\<dt\>);
- * \li "param-descr-index-NUMBER" for parameter description (\<dd\>);
- * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if
- * parameter index is invalid.
- *
- * Template parameter documentation is rendered as a \<dl\> list with
- * parameters sorted in template parameter list order. CSS classes used:
- * \li "tparam-name-index-NUMBER" for parameter name (\<dt\>);
- * \li "tparam-descr-index-NUMBER" for parameter description (\<dd\>);
- * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for
- * names inside template template parameters;
- * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if
- * parameter position is invalid.
- *
- * \param Comment a \c CXComment_FullComment AST node.
- *
- * \returns string containing an HTML fragment.
- */
-CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
-
-/**
- * \brief Convert a given full parsed comment to an XML document.
- *
- * A Relax NG schema for the XML can be found in comment-xml-schema.rng file
- * inside clang source tree.
- *
- * \param Comment a \c CXComment_FullComment AST node.
- *
- * \returns string containing an XML document.
- */
-CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
-
-/**
- * @}
- */
-
-/**
* \defgroup CINDEX_CPP C++ AST introspection
*
* The routines in this group provide access information in the ASTs specific
@@ -4193,6 +3681,12 @@
CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
/**
+ * \brief Determine if a C++ member function or member function template is
+ * declared 'const'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isConst(CXCursor C);
+
+/**
* \brief Given a cursor that represents a template, determine
* the cursor kind of the specializations would be generated by instantiating
* the template.
@@ -4282,7 +3776,7 @@
* Non-contiguous names occur in Objective-C when a selector with two or more
* parameters is used, or in C++ when using an operator:
* \code
- * [object doSomething:here withValue:there]; // ObjC
+ * [object doSomething:here withValue:there]; // Objective-C
* return some_vector[1]; // C++
* \endcode
*/
@@ -5115,7 +4609,7 @@
unsigned Index);
/**
- * \brief Determines what compeltions are appropriate for the context
+ * \brief Determines what completions are appropriate for the context
* the given code completion.
*
* \param Results the code completion results to query
@@ -5565,7 +5059,7 @@
const CXIdxContainerInfo *declAsContainer;
/**
* \brief Whether the declaration exists in code or was created implicitly
- * by the compiler, e.g. implicit objc methods for properties.
+ * by the compiler, e.g. implicit Objective-C methods for properties.
*/
int isImplicit;
const CXIdxAttrInfo *const *attributes;
@@ -5638,8 +5132,8 @@
*/
CXIdxEntityRef_Direct = 1,
/**
- * \brief An implicit reference, e.g. a reference of an ObjC method via the
- * dot syntax.
+ * \brief An implicit reference, e.g. a reference of an Objective-C method
+ * via the dot syntax.
*/
CXIdxEntityRef_Implicit = 2
} CXIdxEntityRefKind;
@@ -5833,7 +5327,7 @@
/**
* \brief Skip a function/method body that was already parsed during an
- * indexing session assosiated with a \c CXIndexAction object.
+ * indexing session associated with a \c CXIndexAction object.
* Bodies in system headers are always skipped.
*/
CXIndexOpt_SkipParsedBodiesInSession = 0x10
@@ -5930,6 +5424,9 @@
* @}
*/
+/* Include the comment API for compatibility. This will eventually go away. */
+#include "clang-c/Documentation.h"
+
#ifdef __cplusplus
}
#endif
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index 196f6c0..ad4f23c 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -113,7 +113,7 @@
virtual void remove(CharSourceRange range) { }
};
- bool applyTransform(TransformFn trans, RewriteListener *listener = 0);
+ bool applyTransform(TransformFn trans, RewriteListener *listener = nullptr);
FileRemapper &getRemapper() { return Remapper; }
};
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index 079f25e..e58c219 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -80,7 +80,7 @@
struct Vec {
APValue *Elts;
unsigned NumElts;
- Vec() : Elts(0), NumElts(0) {}
+ Vec() : Elts(nullptr), NumElts(0) {}
~Vec() { delete[] Elts; }
};
struct Arr {
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 45d3067..6fa7cd8 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -18,6 +18,7 @@
namespace clang {
class ASTContext;
+ class CXXMethodDecl;
class CXXRecordDecl;
class Decl;
class DeclGroupRef;
@@ -56,6 +57,10 @@
/// \returns true to continue parsing, or false to abort parsing.
virtual bool HandleTopLevelDecl(DeclGroupRef D);
+ /// \brief This callback is invoked each time an inline method definition is
+ /// completed.
+ virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {}
+
/// HandleInterestingDecl - Handle the specified interesting declaration. This
/// is called by the AST reader when deserializing things that might interest
/// the consumer. The default implementation forwards to HandleTopLevelDecl.
@@ -135,12 +140,12 @@
/// \brief If the consumer is interested in entities getting modified after
/// their initial creation, it should return a pointer to
/// an ASTMutationListener here.
- virtual ASTMutationListener *GetASTMutationListener() { return 0; }
+ virtual ASTMutationListener *GetASTMutationListener() { return nullptr; }
/// \brief If the consumer is interested in entities being deserialized from
/// AST files, it should return a pointer to a ASTDeserializationListener here
virtual ASTDeserializationListener *GetASTDeserializationListener() {
- return 0;
+ return nullptr;
}
/// PrintStats - If desired, print any statistics.
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index ca1a906..b0de90c 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -19,6 +19,7 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
@@ -51,7 +52,6 @@
class CharUnits;
class DiagnosticsEngine;
class Expr;
- class ExternalASTSource;
class ASTMutationListener;
class IdentifierTable;
class MaterializeTemporaryExpr;
@@ -421,10 +421,12 @@
ASTMutationListener *Listener;
/// \brief Contains parents of a node.
- typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 1> ParentVector;
+ typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector;
/// \brief Maps from a node to its parents.
- typedef llvm::DenseMap<const void *, ParentVector> ParentMap;
+ typedef llvm::DenseMap<const void *,
+ llvm::PointerUnion<ast_type_traits::DynTypedNode *,
+ ParentVector *>> ParentMap;
/// \brief Returns the parents of the given node.
///
@@ -603,9 +605,9 @@
///
/// \param OriginalDecl if not NULL, is set to declaration AST node that had
/// the comment, if the comment we found comes from a redeclaration.
- const RawComment *getRawCommentForAnyRedecl(
- const Decl *D,
- const Decl **OriginalDecl = NULL) const;
+ const RawComment *
+ getRawCommentForAnyRedecl(const Decl *D,
+ const Decl **OriginalDecl = nullptr) const;
/// Return parsed documentation comment attached to a given declaration.
/// Returns NULL if no comment is attached.
@@ -799,11 +801,8 @@
// The type is built when constructing 'BuiltinVaListDecl'.
mutable QualType VaListTagTy;
- ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t,
- IdentifierTable &idents, SelectorTable &sels,
- Builtin::Context &builtins,
- unsigned size_reserve,
- bool DelayInitialization = false);
+ ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
+ SelectorTable &sels, Builtin::Context &builtins);
~ASTContext();
@@ -852,7 +851,7 @@
/// \brief Retrieve the declaration for a 128-bit float stub type.
TypeDecl *getFloat128StubType() const;
-
+
//===--------------------------------------------------------------------===//
// Type Constructors
//===--------------------------------------------------------------------===//
@@ -1061,7 +1060,7 @@
/// \brief Return the unique reference to the type for the specified type
/// declaration.
QualType getTypeDeclType(const TypeDecl *Decl,
- const TypeDecl *PrevDecl = 0) const {
+ const TypeDecl *PrevDecl = nullptr) const {
assert(Decl && "Passed null for Decl param");
if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
@@ -1095,9 +1094,10 @@
const TemplateTypeParmType *Replaced,
const TemplateArgument &ArgPack);
- QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
- bool ParameterPack,
- TemplateTypeParmDecl *ParmDecl = 0) const;
+ QualType
+ getTemplateTypeParmType(unsigned Depth, unsigned Index,
+ bool ParameterPack,
+ TemplateTypeParmDecl *ParmDecl = nullptr) const;
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
@@ -1141,7 +1141,7 @@
Optional<unsigned> NumExpansions);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
- ObjCInterfaceDecl *PrevDecl = 0) const;
+ ObjCInterfaceDecl *PrevDecl = nullptr) const;
QualType getObjCObjectType(QualType Base,
ObjCProtocolDecl * const *Protocols,
@@ -1371,7 +1371,7 @@
///
/// If \p Field is specified then record field names are also encoded.
void getObjCEncodingForType(QualType T, std::string &S,
- const FieldDecl *Field=0) const;
+ const FieldDecl *Field=nullptr) const;
void getLegacyIntegralTypeEncoding(QualType &t) const;
@@ -1573,7 +1573,7 @@
/// arguments to the builtin that are required to be integer constant
/// expressions.
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
- unsigned *IntegerConstantArgs = 0) const;
+ unsigned *IntegerConstantArgs = nullptr) const;
private:
CanQualType getFromTargetType(unsigned Type) const;
@@ -1778,6 +1778,10 @@
return getCanonicalType(T1) == getCanonicalType(T2);
}
+ bool hasSameType(const Type *T1, const Type *T2) const {
+ return getCanonicalType(T1) == getCanonicalType(T2);
+ }
+
/// \brief Return this type as a completely-unqualified array type,
/// capturing the qualifiers in \p Quals.
///
@@ -2041,7 +2045,7 @@
const FunctionProtoType *ToFunctionType);
void ResetObjCLayout(const ObjCContainerDecl *CD) {
- ObjCLayouts[CD] = 0;
+ ObjCLayouts[CD] = nullptr;
}
//===--------------------------------------------------------------------===//
@@ -2246,9 +2250,7 @@
/// \brief Initialize built-in types.
///
/// This routine may only be invoked once for a given ASTContext object.
- /// It is normally invoked by the ASTContext constructor. However, the
- /// constructor can be asked to delay initialization, which places the burden
- /// of calling this function on the user of that object.
+ /// It is normally invoked after ASTContext construction.
///
/// \param Target The target
void InitBuiltinTypes(const TargetInfo &Target);
@@ -2297,6 +2299,7 @@
friend class DeclContext;
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
+ void ReleaseParentMapEntries();
std::unique_ptr<ParentMap> AllParents;
@@ -2399,4 +2402,18 @@
C.Deallocate(Ptr);
}
+/// \brief Create the representation of a LazyGenerationalUpdatePtr.
+template <typename Owner, typename T,
+ void (clang::ExternalASTSource::*Update)(Owner)>
+typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
+ clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue(
+ const clang::ASTContext &Ctx, T Value) {
+ // Note, this is implemented here so that ExternalASTSource.h doesn't need to
+ // include ASTContext.h. We explicitly instantiate it for all relevant types
+ // in ASTContext.cpp.
+ if (auto *Source = Ctx.getExternalSource())
+ return new (Ctx) LazyData(Source, Value);
+ return Value;
+}
+
#endif
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index b74c8ee..a335f98 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -278,7 +278,7 @@
/// happens especially for anonymous structs. If the original of the second
/// RecordDecl can be found, we can complete it without the need for
/// importation, eliminating this loop.
- virtual Decl *GetOriginalDecl(Decl *To) { return NULL; }
+ virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
/// \brief Determine whether the given types are structurally
/// equivalent.
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index abc8857..0e06e26 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -59,7 +59,7 @@
/// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
/// \param Distance If non-null, used to return the distance between \c this
/// and \c Other in the class hierarchy.
- bool isBaseOf(ASTNodeKind Other, unsigned *Distance = 0) const;
+ bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
/// \brief String representation of the kind.
StringRef asStringRef() const;
@@ -237,7 +237,7 @@
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
- return NULL;
+ return nullptr;
}
static DynTypedNode create(const BaseT &Node) {
DynTypedNode Result;
@@ -252,7 +252,7 @@
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
return *reinterpret_cast<T *const *>(Storage);
- return NULL;
+ return nullptr;
}
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
@@ -267,7 +267,7 @@
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
return reinterpret_cast<const T *>(Storage);
- return NULL;
+ return nullptr;
}
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
@@ -355,7 +355,7 @@
} else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
}
- return NULL;
+ return nullptr;
}
} // end namespace ast_type_traits
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index e8be670..84b0842 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -32,9 +32,6 @@
DeclsTy Decls;
- ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
- void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
-
friend class LazyASTUnresolvedSet;
public:
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index d9d37b1..d92167e 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -45,13 +45,28 @@
public:
// Default ctor - Initialize to empty.
- ASTVector() : Begin(0), End(0), Capacity(0, false) {}
+ ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
+
+ ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
+ O.Begin = O.End = nullptr;
+ O.Capacity.setPointer(nullptr);
+ O.Capacity.setInt(false);
+ }
ASTVector(const ASTContext &C, unsigned N)
- : Begin(0), End(0), Capacity(0, false) {
+ : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
reserve(C, N);
}
+ ASTVector &operator=(ASTVector &&RHS) {
+ ASTVector O(std::move(RHS));
+ using std::swap;
+ swap(Begin, O.Begin);
+ swap(End, O.End);
+ swap(Capacity, O.Capacity);
+ return *this;
+ }
+
~ASTVector() {
if (std::is_class<T>::value) {
// Destroy the constructed elements in the vector.
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 655bcab..fc48816 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -26,8 +26,8 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
#include <cassert>
-#include <cstring>
namespace clang {
class ASTContext;
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index 4ecf98f..39ee81f 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -98,7 +98,7 @@
friend bool operator==(specific_attr_iterator Left,
specific_attr_iterator Right) {
- assert((Left.Current == 0) == (Right.Current == 0));
+ assert((Left.Current == nullptr) == (Right.Current == nullptr));
if (Left.Current < Right.Current)
Left.AdvanceToNext(Right.Current);
else
@@ -134,7 +134,7 @@
if (i != specific_attr_end<SpecificAttr>(container))
return *i;
else
- return 0;
+ return nullptr;
}
} // end namespace clang
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 3c7b7f0..37f6748 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -177,8 +177,8 @@
bool RecordPaths = true,
bool DetectVirtual = true)
: FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
- DetectVirtual(DetectVirtual), DetectedVirtual(0), DeclsFound(0),
- NumDeclsFound(0) { }
+ DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
+ DeclsFound(nullptr), NumDeclsFound(0) { }
~CXXBasePaths() { delete [] DeclsFound; }
@@ -232,7 +232,8 @@
/// \brief Uniquely identifies a virtual method within a class
/// hierarchy by the method itself and a class subobject number.
struct UniqueVirtualMethod {
- UniqueVirtualMethod() : Method(0), Subobject(0), InVirtualSubobject(0) { }
+ UniqueVirtualMethod()
+ : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
const CXXRecordDecl *InVirtualSubobject)
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 50e9196..e18fe9a 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -100,16 +100,26 @@
};
enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
+ class HTMLTagCommentBitfields {
+ friend class HTMLTagComment;
+
+ unsigned : NumInlineContentCommentBits;
+
+ /// True if we found that this tag is malformed in some way.
+ unsigned IsMalformed : 1;
+ };
+ enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
+
class HTMLStartTagCommentBitfields {
friend class HTMLStartTagComment;
- unsigned : NumInlineContentCommentBits;
+ unsigned : NumHTMLTagCommentBits;
/// True if this tag is self-closing (e. g., <br />). This is based on tag
/// spelling in comment (plain <br> would not set this flag).
unsigned IsSelfClosing : 1;
};
- enum { NumHTMLStartTagCommentBits = NumInlineContentCommentBits + 1 };
+ enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
class ParagraphCommentBitfields {
friend class ParagraphComment;
@@ -155,6 +165,7 @@
InlineContentCommentBitfields InlineContentCommentBits;
TextCommentBitfields TextCommentBits;
InlineCommandCommentBitfields InlineCommandCommentBits;
+ HTMLTagCommentBitfields HTMLTagCommentBits;
HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
ParagraphCommentBitfields ParagraphCommentBits;
BlockCommandCommentBitfields BlockCommandCommentBits;
@@ -267,9 +278,9 @@
return C->getCommentKind() == TextCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
StringRef getText() const LLVM_READONLY { return Text; }
@@ -325,9 +336,9 @@
return C->getCommentKind() == InlineCommandCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
unsigned getCommandID() const {
return InlineCommandCommentBits.CommandID;
@@ -360,8 +371,7 @@
};
/// Abstract class for opening and closing HTML tags. HTML tags are always
-/// treated as inline content (regardless HTML semantics); opening and closing
-/// tags are not matched.
+/// treated as inline content (regardless HTML semantics).
class HTMLTagComment : public InlineContentComment {
protected:
StringRef TagName;
@@ -377,6 +387,7 @@
TagName(TagName),
TagNameRange(TagNameBegin, TagNameEnd) {
setLocation(TagNameBegin);
+ HTMLTagCommentBits.IsMalformed = 0;
}
public:
@@ -392,6 +403,14 @@
return SourceRange(L.getLocWithOffset(1),
L.getLocWithOffset(1 + TagName.size()));
}
+
+ bool isMalformed() const {
+ return HTMLTagCommentBits.IsMalformed;
+ }
+
+ void setIsMalformed() {
+ HTMLTagCommentBits.IsMalformed = 1;
+ }
};
/// An opening HTML tag with attributes.
@@ -450,9 +469,9 @@
return C->getCommentKind() == HTMLStartTagCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
unsigned getNumAttrs() const {
return Attributes.size();
@@ -505,9 +524,9 @@
return C->getCommentKind() == HTMLEndTagCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
};
/// Block content (contains inline content).
@@ -601,7 +620,7 @@
unsigned CommandID,
CommandMarkerKind CommandMarker) :
BlockContentComment(K, LocBegin, LocEnd),
- Paragraph(NULL) {
+ Paragraph(nullptr) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
BlockCommandCommentBits.CommandMarker = CommandMarker;
@@ -613,7 +632,7 @@
unsigned CommandID,
CommandMarkerKind CommandMarker) :
BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
- Paragraph(NULL) {
+ Paragraph(nullptr) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
BlockCommandCommentBits.CommandMarker = CommandMarker;
@@ -861,9 +880,9 @@
return C->getCommentKind() == VerbatimBlockLineCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
StringRef getText() const LLVM_READONLY {
return Text;
@@ -948,9 +967,9 @@
return C->getCommentKind() == VerbatimLineCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
StringRef getText() const {
return Text;
diff --git a/include/clang/AST/CommentHTMLTags.td b/include/clang/AST/CommentHTMLTags.td
index f98e32d..2514900 100644
--- a/include/clang/AST/CommentHTMLTags.td
+++ b/include/clang/AST/CommentHTMLTags.td
@@ -52,3 +52,16 @@
def Th : Tag<"th"> { let EndTagOptional = 1; }
def Td : Tag<"td"> { let EndTagOptional = 1; }
+// Define a blacklist of attributes that are not safe to pass through to HTML
+// output if the input is untrusted.
+//
+// FIXME: this should be a whitelist. When changing this to a whitelist, don't
+// forget to change the default in the TableGen backend.
+class Attribute<string spelling> {
+ string Spelling = spelling;
+ bit IsSafeToPassThrough = 1;
+}
+class EventHandlerContentAttribute<string spelling> : Attribute<spelling> {
+ let IsSafeToPassThrough = 0;
+}
+
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index 8070615..a6e3ed8 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -352,7 +352,7 @@
StringRef getSpelling(const Token &Tok,
const SourceManager &SourceMgr,
- bool *Invalid = NULL) const;
+ bool *Invalid = nullptr) const;
};
} // end namespace comments
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 3910960..027c3b9 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -84,8 +84,8 @@
T *Mem = Allocator.Allocate<T>(Size);
std::uninitialized_copy(Source.begin(), Source.end(), Mem);
return llvm::makeArrayRef(Mem, Size);
- } else
- return llvm::makeArrayRef(static_cast<T *>(NULL), 0);
+ }
+ return ArrayRef<T>();
}
ParagraphComment *actOnParagraphComment(
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
index d10258e..109d623 100644
--- a/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -38,43 +38,40 @@
// using them is responsible for defining macro OPERATOR().
// All unary operators.
-#define UNARYOP_LIST() \
- OPERATOR(PostInc) OPERATOR(PostDec) \
- OPERATOR(PreInc) OPERATOR(PreDec) \
- OPERATOR(AddrOf) OPERATOR(Deref) \
- OPERATOR(Plus) OPERATOR(Minus) \
- OPERATOR(Not) OPERATOR(LNot) \
- OPERATOR(Real) OPERATOR(Imag) \
- OPERATOR(Extension)
+#define UNARYOP_LIST() \
+ OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \
+ OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \
+ OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \
+ OPERATOR(Extension)
// All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
- OPERATOR(PtrMemD) OPERATOR(PtrMemI) \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) \
- OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) \
- OPERATOR(Shr) \
- \
- OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) \
- OPERATOR(GE) OPERATOR(EQ) OPERATOR(NE) \
- OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
- OPERATOR(LAnd) OPERATOR(LOr) \
- \
- OPERATOR(Assign) \
- OPERATOR(Comma)
+#define BINOP_LIST() \
+ OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
+ OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
+ OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
+ OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \
+ OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
// All compound assign operators.
-#define CAO_LIST() \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
- OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
+#define CAO_LIST() \
+ OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
+ OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
namespace clang {
+// Reduce the diff between RecursiveASTVisitor / DataRecursiveASTVisitor to
+// make it easier to track changes and keep the two in sync.
+#define RecursiveASTVisitor DataRecursiveASTVisitor
+
// A helper macro to implement short-circuiting when recursing. It
// invokes CALL_EXPR, which must be a method call, on the derived
-// object (s.t. a user of DataRecursiveASTVisitor can override the method
+// object (s.t. a user of RecursiveASTVisitor can override the method
// in CALL_EXPR).
-#define TRY_TO(CALL_EXPR) \
- do { if (!getDerived().CALL_EXPR) return false; } while (0)
+#define TRY_TO(CALL_EXPR) \
+ do { \
+ if (!getDerived().CALL_EXPR) \
+ return false; \
+ } while (0)
/// \brief A class that does preorder depth-first traversal on the
/// entire Clang AST and visits each node.
@@ -110,7 +107,7 @@
/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
/// is Foo's super class) before calling VisitFoo(), the result is
/// that the Visit*() methods for a given node are called in the
-/// top-down order (e.g. for a node of type NamedDecl, the order will
+/// top-down order (e.g. for a node of type NamespaceDecl, the order will
/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
///
/// This scheme guarantees that all Visit*() calls for the same AST
@@ -140,11 +137,10 @@
/// to return true, in which case all known implicit and explicit
/// instantiations will be visited at the same time as the pattern
/// from which they were produced.
-template<typename Derived>
-class DataRecursiveASTVisitor {
+template <typename Derived> class RecursiveASTVisitor {
public:
/// \brief Return a reference to the derived class.
- Derived &getDerived() { return *static_cast<Derived*>(this); }
+ Derived &getDerived() { return *static_cast<Derived *>(this); }
/// \brief Return whether this visitor should recurse into
/// template instantiations.
@@ -244,121 +240,126 @@
/// \brief Recursively visit a lambda capture.
///
/// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaCapture(LambdaExpr::Capture C);
+ bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
+
+ /// \brief 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);
// ---- Methods on Attrs ----
// \brief Visit an attribute.
bool VisitAttr(Attr *A) { return true; }
- // Declare Traverse* and empty Visit* for all Attr classes.
+// Declare Traverse* and empty Visit* for all Attr classes.
#define ATTR_VISITOR_DECLS_ONLY
#include "clang/AST/AttrVisitor.inc"
#undef ATTR_VISITOR_DECLS_ONLY
- // ---- Methods on Stmts ----
+// ---- Methods on Stmts ----
- // Declare Traverse*() for all concrete Stmt classes.
+// Declare Traverse*() for all concrete Stmt classes.
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- bool Traverse##CLASS(CLASS *S);
+#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
#include "clang/AST/StmtNodes.inc"
// The above header #undefs ABSTRACT_STMT and STMT upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
bool VisitStmt(Stmt *S) { return true; }
-#define STMT(CLASS, PARENT) \
- bool WalkUpFrom##CLASS(CLASS *S) { \
- TRY_TO(WalkUpFrom##PARENT(S)); \
- TRY_TO(Visit##CLASS(S)); \
- return true; \
- } \
+#define STMT(CLASS, PARENT) \
+ bool WalkUpFrom##CLASS(CLASS *S) { \
+ TRY_TO(WalkUpFrom##PARENT(S)); \
+ TRY_TO(Visit##CLASS(S)); \
+ return true; \
+ } \
bool Visit##CLASS(CLASS *S) { return true; }
#include "clang/AST/StmtNodes.inc"
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
- // operator methods. Unary operators are not classes in themselves
- // (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME) \
- bool TraverseUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnary##NAME(S)); \
- StmtQueueAction StmtQueue(*this); \
- StmtQueue.queue(S->getSubExpr()); \
- return true; \
- } \
- bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnaryOperator(S)); \
- TRY_TO(VisitUnary##NAME(S)); \
- return true; \
- } \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+// operator methods. Unary operators are not classes in themselves
+// (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME) \
+ bool TraverseUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnary##NAME(S)); \
+ StmtQueueAction StmtQueue(*this); \
+ StmtQueue.queue(S->getSubExpr()); \
+ return true; \
+ } \
+ bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnaryOperator(S)); \
+ TRY_TO(VisitUnary##NAME(S)); \
+ return true; \
+ } \
bool VisitUnary##NAME(UnaryOperator *S) { return true; }
UNARYOP_LIST()
#undef OPERATOR
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
- // operator methods. Binary operators are not classes in themselves
- // (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
- bool TraverseBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFromBin##NAME(S)); \
- StmtQueueAction StmtQueue(*this); \
- StmtQueue.queue(S->getLHS()); \
- StmtQueue.queue(S->getRHS()); \
- return true; \
- } \
- bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
- TRY_TO(VisitBin##NAME(S)); \
- return true; \
- } \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+// operator methods. Binary operators are not classes in themselves
+// (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
+ bool TraverseBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFromBin##NAME(S)); \
+ StmtQueueAction StmtQueue(*this); \
+ StmtQueue.queue(S->getLHS()); \
+ StmtQueue.queue(S->getRHS()); \
+ return true; \
+ } \
+ bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
+ TRY_TO(VisitBin##NAME(S)); \
+ return true; \
+ } \
bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
BINOP_LIST()
#undef OPERATOR
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
- // assignment methods. Compound assignment operators are not
- // classes in themselves (they're all opcodes in
- // CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+// assignment methods. Compound assignment operators are not
+// classes in themselves (they're all opcodes in
+// CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME) \
GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
CAO_LIST()
#undef OPERATOR
#undef GENERAL_BINOP_FALLBACK
- // ---- Methods on Types ----
- // FIXME: revamp to take TypeLoc's rather than Types.
+// ---- Methods on Types ----
+// FIXME: revamp to take TypeLoc's rather than Types.
- // Declare Traverse*() for all concrete Type classes.
+// Declare Traverse*() for all concrete Type classes.
#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- bool Traverse##CLASS##Type(CLASS##Type *T);
+#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
#include "clang/AST/TypeNodes.def"
// The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Type classes.
bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
bool VisitType(Type *T) { return true; }
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
- TRY_TO(WalkUpFrom##BASE(T)); \
- TRY_TO(Visit##CLASS##Type(T)); \
- return true; \
- } \
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
+ TRY_TO(WalkUpFrom##BASE(T)); \
+ TRY_TO(Visit##CLASS##Type(T)); \
+ return true; \
+ } \
bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
#include "clang/AST/TypeNodes.def"
- // ---- Methods on TypeLocs ----
- // FIXME: this currently just calls the matching Type methods
+// ---- Methods on TypeLocs ----
+// FIXME: this currently just calls the matching Type methods
- // Declare Traverse*() for all concrete Type classes.
+// Declare Traverse*() for all concrete TypeLoc classes.
#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
#include "clang/AST/TypeLocNodes.def"
// The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
@@ -377,34 +378,33 @@
}
bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
- // Note that BASE includes trailing 'Type' which CLASS doesn't.
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
- TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
- TRY_TO(Visit##CLASS##TypeLoc(TL)); \
- return true; \
- } \
+// Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
+ TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
+ TRY_TO(Visit##CLASS##TypeLoc(TL)); \
+ return true; \
+ } \
bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
#include "clang/AST/TypeNodes.def"
- // ---- Methods on Decls ----
+// ---- Methods on Decls ----
- // Declare Traverse*() for all concrete Decl classes.
+// Declare Traverse*() for all concrete Decl classes.
#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
#include "clang/AST/DeclNodes.inc"
// The above header #undefs ABSTRACT_DECL and DECL upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Decl classes.
bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
bool VisitDecl(Decl *D) { return true; }
-#define DECL(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
- TRY_TO(WalkUpFrom##BASE(D)); \
- TRY_TO(Visit##CLASS##Decl(D)); \
- return true; \
- } \
+#define DECL(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
+ TRY_TO(WalkUpFrom##BASE(D)); \
+ TRY_TO(Visit##CLASS##Decl(D)); \
+ return true; \
+ } \
bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
#include "clang/AST/DeclNodes.inc"
@@ -413,7 +413,7 @@
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
bool TraverseClassInstantiations(ClassTemplateDecl *D);
bool TraverseVariableInstantiations(VarTemplateDecl *D);
- bool TraverseFunctionInstantiations(FunctionTemplateDecl *D) ;
+ bool TraverseFunctionInstantiations(FunctionTemplateDecl *D);
bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
unsigned Count);
bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
@@ -425,27 +425,24 @@
bool TraverseVarHelper(VarDecl *D);
bool TraverseOMPClause(OMPClause *C);
bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
-#define OPENMP_CLAUSE(Name, Class) \
- bool Visit##Class(Class *C);
+#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
#include "clang/Basic/OpenMPKinds.def"
/// \brief Process clauses with list of variables.
- template <typename T>
- void VisitOMPClauseList(T *Node);
+ template <typename T> void VisitOMPClauseList(T *Node);
typedef SmallVector<Stmt *, 16> StmtsTy;
typedef SmallVector<StmtsTy *, 4> QueuesTy;
-
+
QueuesTy Queues;
class NewQueueRAII {
- DataRecursiveASTVisitor &RAV;
+ RecursiveASTVisitor &RAV;
+
public:
- NewQueueRAII(StmtsTy &queue, DataRecursiveASTVisitor &RAV) : RAV(RAV) {
+ NewQueueRAII(StmtsTy &queue, RecursiveASTVisitor &RAV) : RAV(RAV) {
RAV.Queues.push_back(&queue);
}
- ~NewQueueRAII() {
- RAV.Queues.pop_back();
- }
+ ~NewQueueRAII() { RAV.Queues.pop_back(); }
};
StmtsTy &getCurrentQueue() {
@@ -456,113 +453,119 @@
public:
class StmtQueueAction {
StmtsTy &CurrQueue;
- public:
- explicit StmtQueueAction(DataRecursiveASTVisitor &RAV)
- : CurrQueue(RAV.getCurrentQueue()) { }
- void queue(Stmt *S) {
- CurrQueue.push_back(S);
- }
+ public:
+ explicit StmtQueueAction(RecursiveASTVisitor &RAV)
+ : CurrQueue(RAV.getCurrentQueue()) {}
+
+ void queue(Stmt *S) { CurrQueue.push_back(S); }
};
};
-#define DISPATCH(NAME, CLASS, VAR) \
- return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
+#define DISPATCH(NAME, CLASS, VAR) \
+ return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
if (!S)
return true;
- StmtsTy Queue, StmtsToEnqueu;
+ StmtsTy Queue, StmtsToEnqueue;
Queue.push_back(S);
- NewQueueRAII NQ(StmtsToEnqueu, *this);
+ NewQueueRAII NQ(StmtsToEnqueue, *this);
while (!Queue.empty()) {
S = Queue.pop_back_val();
if (!S)
continue;
- StmtsToEnqueu.clear();
+ StmtsToEnqueue.clear();
-#define DISPATCH_STMT(NAME, CLASS, VAR) \
- TRY_TO(Traverse##NAME(static_cast<CLASS*>(VAR))); break
+#define DISPATCH_STMT(NAME, CLASS, VAR) \
+ TRY_TO(Traverse##NAME(static_cast<CLASS *>(VAR))); \
+ break
// If we have a binary expr, dispatch to the subcode of the binop. A smart
// optimizer (e.g. LLVM) will fold this comparison into the switch stmt
// below.
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
-
- BINOP_LIST()
+#define OPERATOR(NAME) \
+ case BO_##NAME: \
+ DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
+
+ BINOP_LIST()
#undef OPERATOR
#undef BINOP_LIST
-
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
- DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
-
- CAO_LIST()
+
+#define OPERATOR(NAME) \
+ case BO_##NAME##Assign: \
+ DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+ CAO_LIST()
#undef OPERATOR
#undef CAO_LIST
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
-
- UNARYOP_LIST()
+#define OPERATOR(NAME) \
+ case UO_##NAME: \
+ DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
+
+ UNARYOP_LIST()
#undef OPERATOR
#undef UNARYOP_LIST
}
} else {
-
+
// Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
switch (S->getStmtClass()) {
- case Stmt::NoStmtClass: break;
+ case Stmt::NoStmtClass:
+ break;
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: DISPATCH_STMT(CLASS, CLASS, S);
+#define STMT(CLASS, PARENT) \
+ case Stmt::CLASS##Class: \
+ DISPATCH_STMT(CLASS, CLASS, S);
#include "clang/AST/StmtNodes.inc"
}
}
- for (SmallVectorImpl<Stmt *>::reverse_iterator
- RI = StmtsToEnqueu.rbegin(),
- RE = StmtsToEnqueu.rend(); RI != RE; ++RI)
+ for (SmallVectorImpl<Stmt *>::reverse_iterator RI = StmtsToEnqueue.rbegin(),
+ RE = StmtsToEnqueue.rend();
+ RI != RE; ++RI)
Queue.push_back(*RI);
}
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseType(QualType T) {
+#undef DISPATCH_STMT
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
if (T.isNull())
return true;
switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, \
- const_cast<Type*>(T.getTypePtr()));
+#define TYPE(CLASS, BASE) \
+ case Type::CLASS: \
+ DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
#include "clang/AST/TypeNodes.def"
}
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
if (TL.isNull())
return true;
switch (TL.getTypeLocClass()) {
#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- case TypeLoc::CLASS: \
+#define TYPELOC(CLASS, BASE) \
+ case TypeLoc::CLASS: \
return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
#include "clang/AST/TypeLocNodes.def"
}
@@ -570,14 +573,13 @@
return true;
}
-
// Define the Traverse*Attr(Attr* A) methods
-#define VISITORCLASS DataRecursiveASTVisitor
+#define VISITORCLASS RecursiveASTVisitor
#include "clang/AST/AttrVisitor.inc"
#undef VISITORCLASS
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
if (!D)
return true;
@@ -589,10 +591,10 @@
switch (D->getKind()) {
#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- case Decl::CLASS: \
- if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl*>(D))) \
- return false; \
+#define DECL(CLASS, BASE) \
+ case Decl::CLASS: \
+ if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
+ return false; \
break;
#include "clang/AST/DeclNodes.inc"
}
@@ -607,9 +609,9 @@
#undef DISPATCH
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
+ NestedNameSpecifier *NNS) {
if (!NNS)
return true;
@@ -631,14 +633,14 @@
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
- NestedNameSpecifierLoc NNS) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
+ NestedNameSpecifierLoc NNS) {
if (!NNS)
return true;
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+ if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+ TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
switch (NNS.getNestedNameSpecifier()->getKind()) {
case NestedNameSpecifier::Identifier:
@@ -656,9 +658,9 @@
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
- DeclarationNameInfo NameInfo) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
+ DeclarationNameInfo NameInfo) {
switch (NameInfo.getName().getNameKind()) {
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
@@ -681,8 +683,8 @@
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
@@ -691,9 +693,9 @@
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseTemplateArgument(
- const TemplateArgument &Arg) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
+ const TemplateArgument &Arg) {
switch (Arg.getKind()) {
case TemplateArgument::Null:
case TemplateArgument::Declaration:
@@ -707,7 +709,7 @@
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
+ Arg.getAsTemplateOrTemplatePattern());
case TemplateArgument::Expression:
return getDerived().TraverseStmt(Arg.getAsExpr());
@@ -722,9 +724,9 @@
// FIXME: no template name location?
// FIXME: no source locations for a template argument pack?
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
- const TemplateArgumentLoc &ArgLoc) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
+ const TemplateArgumentLoc &ArgLoc) {
const TemplateArgument &Arg = ArgLoc.getArgument();
switch (Arg.getKind()) {
@@ -746,9 +748,9 @@
case TemplateArgument::TemplateExpansion:
if (ArgLoc.getTemplateQualifierLoc())
TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
- ArgLoc.getTemplateQualifierLoc()));
+ ArgLoc.getTemplateQualifierLoc()));
return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
+ Arg.getAsTemplateOrTemplatePattern());
case TemplateArgument::Expression:
return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
@@ -761,10 +763,9 @@
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- const TemplateArgument *Args,
- unsigned NumArgs) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
+ const TemplateArgument *Args, unsigned NumArgs) {
for (unsigned I = 0; I != NumArgs; ++I) {
TRY_TO(TraverseTemplateArgument(Args[I]));
}
@@ -772,9 +773,9 @@
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
- CXXCtorInitializer *Init) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
+ CXXCtorInitializer *Init) {
if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
@@ -783,89 +784,83 @@
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr::Capture C){
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
+ const LambdaCapture *C) {
+ if (C->isInitCapture())
+ TRY_TO(TraverseDecl(C->getCapturedVar()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
+ StmtQueueAction StmtQueue(*this);
+ StmtQueue.queue(LE->getBody());
return true;
}
// ----------------- Type traversal -----------------
// This macro makes available a variable T, the passed-in type.
-#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
- template<typename Derived> \
- bool DataRecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) { \
- TRY_TO(WalkUpFrom##TYPE (T)); \
- { CODE; } \
- return true; \
+#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
+ TRY_TO(WalkUpFrom##TYPE(T)); \
+ { CODE; } \
+ return true; \
}
-DEF_TRAVERSE_TYPE(BuiltinType, { })
+DEF_TRAVERSE_TYPE(BuiltinType, {})
-DEF_TRAVERSE_TYPE(ComplexType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(PointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(BlockPointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(BlockPointerType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(LValueReferenceType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(LValueReferenceType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(RValueReferenceType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(RValueReferenceType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseType(QualType(T->getClass(), 0)));
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+ TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+ TRY_TO(TraverseType(T->getPointeeType()));
+})
-DEF_TRAVERSE_TYPE(DecayedType, {
- TRY_TO(TraverseType(T->getOriginalType()));
- })
+DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-DEF_TRAVERSE_TYPE(AdjustedType, {
- TRY_TO(TraverseType(T->getOriginalType()));
- })
+DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-DEF_TRAVERSE_TYPE(ConstantArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ConstantArrayType,
+ { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(IncompleteArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(IncompleteArrayType,
+ { TRY_TO(TraverseType(T->getElementType())); })
DEF_TRAVERSE_TYPE(VariableArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
+ TRY_TO(TraverseType(T->getElementType()));
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
+ TRY_TO(TraverseType(T->getElementType()));
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- TRY_TO(TraverseType(T->getElementType()));
- })
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+ TRY_TO(TraverseType(T->getElementType()));
+})
-DEF_TRAVERSE_TYPE(VectorType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(ExtVectorType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
DEF_TRAVERSE_TYPE(FunctionNoProtoType,
{ TRY_TO(TraverseType(T->getReturnType())); })
@@ -882,87 +877,72 @@
}
})
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPE(TypedefType, { })
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPE(TypedefType, {})
-DEF_TRAVERSE_TYPE(TypeOfExprType, {
- TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPE(TypeOfExprType,
+ { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-DEF_TRAVERSE_TYPE(TypeOfType, {
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
-DEF_TRAVERSE_TYPE(DecltypeType, {
- TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPE(DecltypeType,
+ { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
DEF_TRAVERSE_TYPE(UnaryTransformType, {
- TRY_TO(TraverseType(T->getBaseType()));
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
+ TRY_TO(TraverseType(T->getBaseType()));
+ TRY_TO(TraverseType(T->getUnderlyingType()));
+})
-DEF_TRAVERSE_TYPE(AutoType, {
- TRY_TO(TraverseType(T->getDeducedType()));
- })
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
-DEF_TRAVERSE_TYPE(RecordType, { })
-DEF_TRAVERSE_TYPE(EnumType, { })
-DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { })
+DEF_TRAVERSE_TYPE(RecordType, {})
+DEF_TRAVERSE_TYPE(EnumType, {})
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
- })
+ TRY_TO(TraverseTemplateName(T->getTemplateName()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
-DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
-DEF_TRAVERSE_TYPE(AttributedType, {
- TRY_TO(TraverseType(T->getModifiedType()));
- })
+DEF_TRAVERSE_TYPE(AttributedType,
+ { TRY_TO(TraverseType(T->getModifiedType())); })
-DEF_TRAVERSE_TYPE(ParenType, {
- TRY_TO(TraverseType(T->getInnerType()));
- })
+DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
DEF_TRAVERSE_TYPE(ElaboratedType, {
- if (T->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
- TRY_TO(TraverseType(T->getNamedType()));
- })
-
-DEF_TRAVERSE_TYPE(DependentNameType, {
+ if (T->getQualifier()) {
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- })
+ }
+ TRY_TO(TraverseType(T->getNamedType()));
+})
+
+DEF_TRAVERSE_TYPE(DependentNameType,
+ { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
- })
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
-DEF_TRAVERSE_TYPE(PackExpansionType, {
- TRY_TO(TraverseType(T->getPattern()));
- })
+DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
-DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPE(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (T->getBaseType().getTypePtr() != T)
- TRY_TO(TraverseType(T->getBaseType()));
- })
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (T->getBaseType().getTypePtr() != T)
+ TRY_TO(TraverseType(T->getBaseType()));
+})
-DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(AtomicType, {
- TRY_TO(TraverseType(T->getValueType()));
- })
+DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
#undef DEF_TRAVERSE_TYPE
@@ -973,19 +953,19 @@
// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
// continue to work.
-#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
- template<typename Derived> \
- bool DataRecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE*>(TL.getTypePtr()))); \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
- { CODE; } \
- return true; \
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
+ if (getDerived().shouldWalkTypesOfTypeLocs()) \
+ TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
+ TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
+ { CODE; } \
+ return true; \
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
- QualifiedTypeLoc TL) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
// Move this over to the 'main' typeloc tree. Note that this is a
// move -- we pretend that we were really looking at the unqualified
// typeloc all along -- rather than a recursion, so we don't follow
@@ -1004,203 +984,188 @@
return TraverseTypeLoc(TL.getUnqualifiedLoc());
}
-DEF_TRAVERSE_TYPELOC(BuiltinType, { })
+DEF_TRAVERSE_TYPELOC(BuiltinType, {})
// FIXME: ComplexTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ComplexType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
-DEF_TRAVERSE_TYPELOC(PointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(PointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(BlockPointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(BlockPointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(LValueReferenceType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(LValueReferenceType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(RValueReferenceType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(RValueReferenceType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
// FIXME: location of base class?
// We traverse this in the type case as well, but how is it not reached through
// the pointee type?
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+ TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+})
-DEF_TRAVERSE_TYPELOC(DecayedType, {
- TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AdjustedType,
+ { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-DEF_TRAVERSE_TYPELOC(AdjustedType, {
- TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
- })
+DEF_TRAVERSE_TYPELOC(DecayedType,
+ { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
// This isn't available for ArrayType, but is for the ArrayTypeLoc.
TRY_TO(TraverseStmt(TL.getSizeExpr()));
return true;
}
DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(VariableArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
// FIXME: order? why not size expr first?
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ if (TL.getTypePtr()->getSizeExpr())
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
// FIXME: VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(VectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
// FIXME: size and attributes
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ExtVectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
-DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
- })
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
+ { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
// FIXME: location of exception specifications (attributes?)
DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
+ TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
- const FunctionProtoType *T = TL.getTypePtr();
+ const FunctionProtoType *T = TL.getTypePtr();
- for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
- if (TL.getParam(I)) {
- TRY_TO(TraverseDecl(TL.getParam(I)));
- } else if (I < T->getNumParams()) {
- TRY_TO(TraverseType(T->getParamType(I)));
- }
+ for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+ if (TL.getParam(I)) {
+ TRY_TO(TraverseDecl(TL.getParam(I)));
+ } else if (I < T->getNumParams()) {
+ TRY_TO(TraverseType(T->getParamType(I)));
}
+ }
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
- })
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+})
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPELOC(TypedefType, { })
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPELOC(TypedefType, {})
-DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
- TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPELOC(TypeOfExprType,
+ { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
// FIXME: location of underlying expr
DEF_TRAVERSE_TYPELOC(DecltypeType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
- })
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+})
DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_TYPELOC(AutoType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
-DEF_TRAVERSE_TYPELOC(RecordType, { })
-DEF_TRAVERSE_TYPELOC(EnumType, { })
-DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { })
+DEF_TRAVERSE_TYPELOC(RecordType, {})
+DEF_TRAVERSE_TYPELOC(EnumType, {})
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
// FIXME: use the loc for the template name?
DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
+ TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+})
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
-DEF_TRAVERSE_TYPELOC(ParenType, {
- TRY_TO(TraverseTypeLoc(TL.getInnerLoc()));
- })
+DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
-DEF_TRAVERSE_TYPELOC(AttributedType, {
- TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AttributedType,
+ { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
- })
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
+ TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+})
DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+})
DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+})
-DEF_TRAVERSE_TYPELOC(PackExpansionType, {
- TRY_TO(TraverseTypeLoc(TL.getPatternLoc()));
- })
+DEF_TRAVERSE_TYPELOC(PackExpansionType,
+ { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
-DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
- TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
- })
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+ TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+})
-DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(AtomicType, {
- TRY_TO(TraverseTypeLoc(TL.getValueLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
#undef DEF_TRAVERSE_TYPELOC
@@ -1211,8 +1176,8 @@
// Therefore each Traverse* only needs to worry about children other
// than those.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
if (!DC)
return true;
@@ -1227,131 +1192,121 @@
}
// This macro makes available a variable D, the passed-in decl.
-#define DEF_TRAVERSE_DECL(DECL, CODE) \
-template<typename Derived> \
-bool DataRecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) { \
- TRY_TO(WalkUpFrom##DECL (D)); \
- { CODE; } \
- TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
- return true; \
-}
+#define DEF_TRAVERSE_DECL(DECL, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
+ TRY_TO(WalkUpFrom##DECL(D)); \
+ { CODE; } \
+ TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
+ return true; \
+ }
-DEF_TRAVERSE_DECL(AccessSpecDecl, { })
+DEF_TRAVERSE_DECL(AccessSpecDecl, {})
DEF_TRAVERSE_DECL(BlockDecl, {
- if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- TRY_TO(TraverseStmt(D->getBody()));
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(CapturedDecl, {
- TRY_TO(TraverseStmt(D->getBody()));
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(EmptyDecl, { })
-
-DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
- TRY_TO(TraverseStmt(D->getAsmString()));
- })
-
-DEF_TRAVERSE_DECL(ImportDecl, { })
-
-DEF_TRAVERSE_DECL(FriendDecl, {
- // Friend is either decl or a type.
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- })
-
-DEF_TRAVERSE_DECL(FriendTemplateDecl, {
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
- TemplateParameterList *TPL = D->getTemplateParameterList(I);
- for (TemplateParameterList::iterator ITPL = TPL->begin(),
- ETPL = TPL->end();
- ITPL != ETPL; ++ITPL) {
- TRY_TO(TraverseDecl(*ITPL));
- }
- }
- })
-
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
- TRY_TO(TraverseDecl(D->getSpecialization()));
- })
-
-DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
-
-DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {
- // FIXME: implement this
- })
-
-DEF_TRAVERSE_DECL(StaticAssertDecl, {
- TRY_TO(TraverseStmt(D->getAssertExpr()));
- TRY_TO(TraverseStmt(D->getMessage()));
- })
-
-DEF_TRAVERSE_DECL(TranslationUnitDecl, {
- // Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
-
-DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
- // We shouldn't traverse an aliased namespace, since it will be
- // defined (and, therefore, traversed) somewhere else.
- //
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(LabelDecl, {
- // There is no code in a LabelDecl.
+ if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+ TRY_TO(TraverseStmt(D->getBody()));
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
})
+DEF_TRAVERSE_DECL(CapturedDecl, {
+ TRY_TO(TraverseStmt(D->getBody()));
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+})
-DEF_TRAVERSE_DECL(NamespaceDecl, {
- // Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
+DEF_TRAVERSE_DECL(EmptyDecl, {})
-DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(FileScopeAsmDecl,
+ { TRY_TO(TraverseStmt(D->getAsmString())); })
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(ImportDecl, {})
-DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(FriendDecl, {
+ // Friend is either decl or a type.
+ if (D->getFriendType())
+ TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+ else
+ TRY_TO(TraverseDecl(D->getFriendDecl()));
+})
-DEF_TRAVERSE_DECL(ObjCImplementationDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+ if (D->getFriendType())
+ TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+ else
+ TRY_TO(TraverseDecl(D->getFriendDecl()));
+ for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+ TemplateParameterList *TPL = D->getTemplateParameterList(I);
+ for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
+ ITPL != ETPL; ++ITPL) {
+ TRY_TO(TraverseDecl(*ITPL));
+ }
+ }
+})
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl,
+ { TRY_TO(TraverseDecl(D->getSpecialization())); })
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
+ })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+ TRY_TO(TraverseStmt(D->getAssertExpr()));
+ TRY_TO(TraverseStmt(D->getMessage()));
+})
+
+DEF_TRAVERSE_DECL(
+ TranslationUnitDecl,
+ {// Code in an unnamed namespace shows up automatically in
+ // decls_begin()/decls_end(). Thus we don't need to recurse on
+ // D->getAnonymousNamespace().
+ })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+ // We shouldn't traverse an aliased namespace, since it will be
+ // defined (and, therefore, traversed) somewhere else.
+ //
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+})
+
+DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
+ })
+
+DEF_TRAVERSE_DECL(
+ NamespaceDecl,
+ {// Code in an unnamed namespace shows up automatically in
+ // decls_begin()/decls_end(). Thus we don't need to recurse on
+ // D->getAnonymousNamespace().
+ })
+
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
+ })
DEF_TRAVERSE_DECL(ObjCMethodDecl, {
if (D->getReturnTypeSourceInfo()) {
@@ -1367,30 +1322,29 @@
return true;
})
-DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {// FIXME: implement
+ })
DEF_TRAVERSE_DECL(UsingDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+})
-DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+DEF_TRAVERSE_DECL(UsingShadowDecl, {})
DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
- for (auto *I : D->varlists()) {
- TRY_TO(TraverseStmt(I));
- }
- })
+ for (auto *I : D->varlists()) {
+ TRY_TO(TraverseStmt(I));
+ }
+})
// A helper method for TemplateDecl's children.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
TemplateParameterList *TPL) {
if (TPL) {
for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
@@ -1403,8 +1357,8 @@
// A helper method for traversing the implicit instantiations of a
// class template.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseClassInstantiations(
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations(
ClassTemplateDecl *D) {
for (auto *SD : D->specializations()) {
for (auto *RD : SD->redecls()) {
@@ -1412,8 +1366,8 @@
if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
continue;
- switch (cast<ClassTemplateSpecializationDecl>(RD)->
- getSpecializationKind()) {
+ switch (
+ cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
// Visit the implicit instantiations with the requested pattern.
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
@@ -1435,34 +1389,34 @@
}
DEF_TRAVERSE_DECL(ClassTemplateDecl, {
- CXXRecordDecl* TempDecl = D->getTemplatedDecl();
- TRY_TO(TraverseDecl(TempDecl));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+ CXXRecordDecl *TempDecl = D->getTemplatedDecl();
+ TRY_TO(TraverseDecl(TempDecl));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- // By default, we do not traverse the instantiations of
- // class templates since they do not appear in the user code. The
- // following code optionally traverses them.
- //
- // We only traverse the class instantiations when we see the canonical
- // declaration of the template, to ensure we only visit them once.
- if (getDerived().shouldVisitTemplateInstantiations() &&
- D == D->getCanonicalDecl())
- TRY_TO(TraverseClassInstantiations(D));
+ // By default, we do not traverse the instantiations of
+ // class templates since they do not appear in the user code. The
+ // following code optionally traverses them.
+ //
+ // We only traverse the class instantiations when we see the canonical
+ // declaration of the template, to ensure we only visit them once.
+ if (getDerived().shouldVisitTemplateInstantiations() &&
+ D == D->getCanonicalDecl())
+ TRY_TO(TraverseClassInstantiations(D));
- // Note that getInstantiatedFromMemberTemplate() is just a link
- // from a template instantiation back to the template from which
- // it was instantiated, and thus should not be traversed.
- })
+ // Note that getInstantiatedFromMemberTemplate() is just a link
+ // from a template instantiation back to the template from which
+ // it was instantiated, and thus should not be traversed.
+})
// A helper method for traversing the implicit instantiations of a
// class template.
template <typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseVariableInstantiations(
+bool RecursiveASTVisitor<Derived>::TraverseVariableInstantiations(
VarTemplateDecl *D) {
for (auto *SD : D->specializations()) {
for (auto *RD : SD->redecls()) {
- switch (cast<VarTemplateSpecializationDecl>(RD)->
- getSpecializationKind()) {
+ switch (
+ cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
// Visit the implicit instantiations with the requested pattern.
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
@@ -1483,9 +1437,7 @@
return true;
}
-DEF_TRAVERSE_DECL(
- VarTemplateDecl,
- {
+DEF_TRAVERSE_DECL(VarTemplateDecl, {
VarDecl *TempDecl = D->getTemplatedDecl();
TRY_TO(TraverseDecl(TempDecl));
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
@@ -1500,15 +1452,15 @@
D == D->getCanonicalDecl())
TRY_TO(TraverseVariableInstantiations(D));
- // Note that getInstantiatedFromMemberTemplate() is just a link
- // from a template instantiation back to the template from which
- // it was instantiated, and thus should not be traversed.
+ // Note that getInstantiatedFromMemberTemplate() is just a link
+ // from a template instantiation back to the template from which
+ // it was instantiated, and thus should not be traversed.
})
// A helper method for traversing the instantiations of a
// function while skipping its specializations.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
FunctionTemplateDecl *D) {
for (auto *FD : D->specializations()) {
for (auto *RD : FD->redecls()) {
@@ -1537,80 +1489,78 @@
}
DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- // By default, we do not traverse the instantiations of
- // function templates since they do not appear in the user code. The
- // following code optionally traverses them.
- //
- // We only traverse the function instantiations when we see the canonical
- // declaration of the template, to ensure we only visit them once.
- if (getDerived().shouldVisitTemplateInstantiations() &&
- D == D->getCanonicalDecl())
- TRY_TO(TraverseFunctionInstantiations(D));
- })
+ // By default, we do not traverse the instantiations of
+ // function templates since they do not appear in the user code. The
+ // following code optionally traverses them.
+ //
+ // We only traverse the function instantiations when we see the canonical
+ // declaration of the template, to ensure we only visit them once.
+ if (getDerived().shouldVisitTemplateInstantiations() &&
+ D == D->getCanonicalDecl())
+ TRY_TO(TraverseFunctionInstantiations(D));
+})
DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
- // D is the "T" in something like
- // template <template <typename> class T> class container { };
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- if (D->hasDefaultArgument()) {
- TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
- }
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
+ // D is the "T" in something like
+ // template <template <typename> class T> class container { };
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ if (D->hasDefaultArgument()) {
+ TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+ }
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
- // D is the "T" in something like "template<typename T> class vector;"
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- if (D->hasDefaultArgument())
- TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
- })
+ // D is the "T" in something like "template<typename T> class vector;"
+ if (D->getTypeForDecl())
+ TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+ if (D->hasDefaultArgument())
+ TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_DECL(TypedefDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the typedef, not something that was written in the
- // source.
- })
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the typedef, not something that was written in the
+ // source.
+})
DEF_TRAVERSE_DECL(TypeAliasDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
- })
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type alias, not something that was written in the
+ // source.
+})
DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
- // A dependent using declaration which was marked with 'typename'.
- // template<class T> class A : public B<T> { using typename B<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the
- // source.
- })
+ // A dependent using declaration which was marked with 'typename'.
+ // template<class T> class A : public B<T> { using typename B<T>::foo; };
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type, not something that was written in the
+ // source.
+})
DEF_TRAVERSE_DECL(EnumDecl, {
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+ if (D->getTypeForDecl())
+ TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // The enumerators are already traversed by
- // decls_begin()/decls_end().
- })
-
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ // The enumerators are already traversed by
+ // decls_begin()/decls_end().
+})
// Helper methods for RecordDecl and its children.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseRecordHelper(
- RecordDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
// We shouldn't traverse D->getTypeForDecl(); it's a result of
// declaring the type, not something that was written in the source.
@@ -1618,9 +1568,8 @@
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
- CXXRecordDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
if (!TraverseRecordHelper(D))
return false;
if (D->isCompleteDefinition()) {
@@ -1633,37 +1582,33 @@
return true;
}
-DEF_TRAVERSE_DECL(RecordDecl, {
- TRY_TO(TraverseRecordHelper(D));
- })
+DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
-DEF_TRAVERSE_DECL(CXXRecordDecl, {
- TRY_TO(TraverseCXXRecordHelper(D));
- })
+DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
- // For implicit instantiations ("set<int> x;"), we don't want to
- // recurse at all, since the instatiated class isn't written in
- // the source code anywhere. (Note the instatiated *type* --
- // set<int> -- is written, and will still get a callback of
- // TemplateSpecializationType). For explicit instantiations
- // ("template set<int>;"), we do need a callback, since this
- // is the only callback that's made for this instantiation.
- // We use getTypeAsWritten() to distinguish.
- if (TypeSourceInfo *TSI = D->getTypeAsWritten())
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+ // For implicit instantiations ("set<int> x;"), we don't want to
+ // recurse at all, since the instatiated class isn't written in
+ // the source code anywhere. (Note the instatiated *type* --
+ // set<int> -- is written, and will still get a callback of
+ // TemplateSpecializationType). For explicit instantiations
+ // ("template set<int>;"), we do need a callback, since this
+ // is the only callback that's made for this instantiation.
+ // We use getTypeAsWritten() to distinguish.
+ if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
- if (!getDerived().shouldVisitTemplateInstantiations() &&
- D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
- // Returning from here skips traversing the
- // declaration context of the ClassTemplateSpecializationDecl
- // (embedded in the DEF_TRAVERSE_DECL() macro)
- // which contains the instantiated members of the class.
- return true;
- })
+ if (!getDerived().shouldVisitTemplateInstantiations() &&
+ D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+ // Returning from here skips traversing the
+ // declaration context of the ClassTemplateSpecializationDecl
+ // (embedded in the DEF_TRAVERSE_DECL() macro)
+ // which contains the instantiated members of the class.
+ return true;
+})
template <typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
const TemplateArgumentLoc *TAL, unsigned Count) {
for (unsigned I = 0; I < Count; ++I) {
TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
@@ -1672,41 +1617,39 @@
}
DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
- // The partial specialization.
- if (TemplateParameterList *TPL = D->getTemplateParameters()) {
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
+ // The partial specialization.
+ if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
}
- // The args that remains unspecialized.
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- D->getTemplateArgsAsWritten()->getTemplateArgs(),
- D->getTemplateArgsAsWritten()->NumTemplateArgs));
+ }
+ // The args that remains unspecialized.
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ D->getTemplateArgsAsWritten()->getTemplateArgs(),
+ D->getTemplateArgsAsWritten()->NumTemplateArgs));
- // Don't need the ClassTemplatePartialSpecializationHelper, even
- // though that's our parent class -- we already visit all the
- // template args here.
- TRY_TO(TraverseCXXRecordHelper(D));
+ // Don't need the ClassTemplatePartialSpecializationHelper, even
+ // though that's our parent class -- we already visit all the
+ // template args here.
+ TRY_TO(TraverseCXXRecordHelper(D));
- // Instantiations will have been visited with the primary template.
- })
+ // Instantiations will have been visited with the primary template.
+})
-DEF_TRAVERSE_DECL(EnumConstantDecl, {
- TRY_TO(TraverseStmt(D->getInitExpr()));
- })
+DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
- // Like UnresolvedUsingTypenameDecl, but without the 'typename':
- // template <class T> Class A : public Base<T> { using Base<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- })
+ // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+ // template <class T> Class A : public Base<T> { using Base<T>::foo; };
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
if (D->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
@@ -1715,34 +1658,32 @@
return true;
}
-DEF_TRAVERSE_DECL(FieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- else if (D->hasInClassInitializer())
- TRY_TO(TraverseStmt(D->getInClassInitializer()));
- })
+DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
-DEF_TRAVERSE_DECL(MSPropertyDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- })
+DEF_TRAVERSE_DECL(FieldDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ else if (D->hasInClassInitializer())
+ TRY_TO(TraverseStmt(D->getInClassInitializer()));
+})
DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
- })
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ // FIXME: implement the rest.
+})
DEF_TRAVERSE_DECL(ObjCIvarDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
- })
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ // FIXME: implement the rest.
+})
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
@@ -1752,13 +1693,13 @@
// the function args, but both are handled by the FunctionTypeLoc
// above, so we have to choose one side. I've decided to do before.
if (const FunctionTemplateSpecializationInfo *FTSI =
- D->getTemplateSpecializationInfo()) {
+ D->getTemplateSpecializationInfo()) {
if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
// A specialization might not have explicit template arguments if it has
// a templated return type and concrete arguments.
if (const ASTTemplateArgumentListInfo *TALI =
- FTSI->TemplateArgumentsAsWritten) {
+ FTSI->TemplateArgumentsAsWritten) {
TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
TALI->NumTemplateArgs));
}
@@ -1779,45 +1720,45 @@
}
if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody())); // Function body.
+ TRY_TO(TraverseStmt(D->getBody())); // Function body.
}
return true;
}
DEF_TRAVERSE_DECL(FunctionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
DEF_TRAVERSE_DECL(CXXMethodDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
DEF_TRAVERSE_DECL(CXXConstructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
// CXXConversionDecl is the declaration of a type conversion operator.
// It's not a cast expression.
DEF_TRAVERSE_DECL(CXXConversionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
DEF_TRAVERSE_DECL(CXXDestructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
TRY_TO(TraverseDeclaratorHelper(D));
// Default params are taken care of when we traverse the ParmVarDecl.
if (!isa<ParmVarDecl>(D))
@@ -1825,9 +1766,7 @@
return true;
}
-DEF_TRAVERSE_DECL(VarDecl, {
- TRY_TO(TraverseVarHelper(D));
- })
+DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, {
// For implicit instantiations, we don't want to
@@ -1844,8 +1783,7 @@
return true;
})
-DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl,
- {
+DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl, {
// The partial specialization.
if (TemplateParameterList *TPL = D->getTemplateParameters()) {
for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
@@ -1855,41 +1793,37 @@
}
// The args that remains unspecialized.
TRY_TO(TraverseTemplateArgumentLocsHelper(
- D->getTemplateArgsAsWritten()->getTemplateArgs(),
- D->getTemplateArgsAsWritten()->NumTemplateArgs));
+ D->getTemplateArgsAsWritten()->getTemplateArgs(),
+ D->getTemplateArgsAsWritten()->NumTemplateArgs));
// Don't need the VarTemplatePartialSpecializationHelper, even
// though that's our parent class -- we already visit all the
// template args here.
TRY_TO(TraverseVarHelper(D));
- // Instantiations will have been visited with the primary
- // template.
+ // Instantiations will have been visited with the primary
+ // template.
})
-DEF_TRAVERSE_DECL(ImplicitParamDecl, {
- TRY_TO(TraverseVarHelper(D));
- })
+DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
- // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
- TRY_TO(TraverseDeclaratorHelper(D));
- TRY_TO(TraverseStmt(D->getDefaultArgument()));
- })
+ // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+ TRY_TO(TraverseDeclaratorHelper(D));
+ TRY_TO(TraverseStmt(D->getDefaultArgument()));
+})
DEF_TRAVERSE_DECL(ParmVarDecl, {
- TRY_TO(TraverseVarHelper(D));
+ TRY_TO(TraverseVarHelper(D));
- if (D->hasDefaultArg() &&
- D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
+ if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
+ !D->hasUnparsedDefaultArg())
+ TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
- if (D->hasDefaultArg() &&
- !D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getDefaultArg()));
- })
+ if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
+ !D->hasUnparsedDefaultArg())
+ TRY_TO(TraverseStmt(D->getDefaultArg()));
+})
#undef DEF_TRAVERSE_DECL
@@ -1903,156 +1837,157 @@
// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
// This macro makes available a variable S, the passed-in stmt.
-#define DEF_TRAVERSE_STMT(STMT, CODE) \
-template<typename Derived> \
-bool DataRecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \
- TRY_TO(WalkUpFrom##STMT(S)); \
- StmtQueueAction StmtQueue(*this); \
- { CODE; } \
- for (Stmt::child_range range = S->children(); range; ++range) { \
- StmtQueue.queue(*range); \
- } \
- return true; \
-}
+#define DEF_TRAVERSE_STMT(STMT, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) { \
+ TRY_TO(WalkUpFrom##STMT(S)); \
+ StmtQueueAction StmtQueue(*this); \
+ { CODE; } \
+ for (Stmt::child_range range = S->children(); range; ++range) { \
+ StmtQueue.queue(*range); \
+ } \
+ return true; \
+ }
DEF_TRAVERSE_STMT(GCCAsmStmt, {
- StmtQueue.queue(S->getAsmString());
- for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
- StmtQueue.queue(S->getInputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
- StmtQueue.queue(S->getOutputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
- StmtQueue.queue(S->getClobberStringLiteral(I));
- }
- // children() iterates over inputExpr and outputExpr.
- })
+ StmtQueue.queue(S->getAsmString());
+ for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+ StmtQueue.queue(S->getInputConstraintLiteral(I));
+ }
+ for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+ StmtQueue.queue(S->getOutputConstraintLiteral(I));
+ }
+ for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+ StmtQueue.queue(S->getClobberStringLiteral(I));
+ }
+ // children() iterates over inputExpr and outputExpr.
+})
-DEF_TRAVERSE_STMT(MSAsmStmt, {
- // FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
- // added this needs to be implemented.
- })
+DEF_TRAVERSE_STMT(
+ MSAsmStmt,
+ {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
+ // added this needs to be implemented.
+ })
DEF_TRAVERSE_STMT(CXXCatchStmt, {
- TRY_TO(TraverseDecl(S->getExceptionDecl()));
- // children() iterates over the handler block.
- })
+ TRY_TO(TraverseDecl(S->getExceptionDecl()));
+ // children() iterates over the handler block.
+})
DEF_TRAVERSE_STMT(DeclStmt, {
- for (auto *I : S->decls()) {
- TRY_TO(TraverseDecl(I));
- }
- // Suppress the default iteration over children() by
- // returning. Here's why: A DeclStmt looks like 'type var [=
- // initializer]'. The decls above already traverse over the
- // initializers, so we don't have to do it again (which
- // children() would do).
- return true;
- })
-
+ for (auto *I : S->decls()) {
+ TRY_TO(TraverseDecl(I));
+ }
+ // Suppress the default iteration over children() by
+ // returning. Here's why: A DeclStmt looks like 'type var [=
+ // initializer]'. The decls above already traverse over the
+ // initializers, so we don't have to do it again (which
+ // children() would do).
+ return true;
+})
// These non-expr stmts (most of them), do not need any action except
// iterating over the children.
-DEF_TRAVERSE_STMT(BreakStmt, { })
-DEF_TRAVERSE_STMT(CXXTryStmt, { })
-DEF_TRAVERSE_STMT(CaseStmt, { })
-DEF_TRAVERSE_STMT(CompoundStmt, { })
-DEF_TRAVERSE_STMT(ContinueStmt, { })
-DEF_TRAVERSE_STMT(DefaultStmt, { })
-DEF_TRAVERSE_STMT(DoStmt, { })
-DEF_TRAVERSE_STMT(ForStmt, { })
-DEF_TRAVERSE_STMT(GotoStmt, { })
-DEF_TRAVERSE_STMT(IfStmt, { })
-DEF_TRAVERSE_STMT(IndirectGotoStmt, { })
-DEF_TRAVERSE_STMT(LabelStmt, { })
-DEF_TRAVERSE_STMT(AttributedStmt, { })
-DEF_TRAVERSE_STMT(NullStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtCatchStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
-DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
-DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { })
-DEF_TRAVERSE_STMT(CXXForRangeStmt, { })
+DEF_TRAVERSE_STMT(BreakStmt, {})
+DEF_TRAVERSE_STMT(CXXTryStmt, {})
+DEF_TRAVERSE_STMT(CaseStmt, {})
+DEF_TRAVERSE_STMT(CompoundStmt, {})
+DEF_TRAVERSE_STMT(ContinueStmt, {})
+DEF_TRAVERSE_STMT(DefaultStmt, {})
+DEF_TRAVERSE_STMT(DoStmt, {})
+DEF_TRAVERSE_STMT(ForStmt, {})
+DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(IfStmt, {})
+DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
+DEF_TRAVERSE_STMT(LabelStmt, {})
+DEF_TRAVERSE_STMT(AttributedStmt, {})
+DEF_TRAVERSE_STMT(NullStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
+DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
+DEF_TRAVERSE_STMT(CXXForRangeStmt, {})
DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
})
-DEF_TRAVERSE_STMT(ReturnStmt, { })
-DEF_TRAVERSE_STMT(SwitchStmt, { })
-DEF_TRAVERSE_STMT(WhileStmt, { })
+DEF_TRAVERSE_STMT(ReturnStmt, {})
+DEF_TRAVERSE_STMT(SwitchStmt, {})
+DEF_TRAVERSE_STMT(WhileStmt, {})
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- }
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
DEF_TRAVERSE_STMT(DeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+})
DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getExplicitTemplateArgs().getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ S->getExplicitTemplateArgs().getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
DEF_TRAVERSE_STMT(MemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+})
-DEF_TRAVERSE_STMT(ImplicitCastExpr, {
- // We don't traverse the cast type, as it's not written in the
- // source code.
- })
+DEF_TRAVERSE_STMT(
+ ImplicitCastExpr,
+ {// We don't traverse the cast type, as it's not written in the
+ // source code.
+ })
DEF_TRAVERSE_STMT(CStyleCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXConstCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
// InitListExpr is a tricky one, because we want to do all our work on
// the syntactic form of the listexpr, but this method takes the
// semantic form by default. We can't use the macro helper because it
// calls WalkUp*() on the semantic form, before our code can convert
// to the syntactic form.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
if (InitListExpr *Syn = S->getSyntacticForm())
S = Syn;
TRY_TO(WalkUpFromInitListExpr(S));
@@ -2067,9 +2002,9 @@
// GenericSelectionExpr is a special case because the types and expressions
// are interleaved. We also need to watch out for null types (default
// generic associations).
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::
-TraverseGenericSelectionExpr(GenericSelectionExpr *S) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr(
+ GenericSelectionExpr *S) {
TRY_TO(WalkUpFromGenericSelectionExpr(S));
StmtQueueAction StmtQueue(*this);
StmtQueue.queue(S->getControllingExpr());
@@ -2083,14 +2018,15 @@
// PseudoObjectExpr is a special case because of the wierdness with
// syntactic expressions and opaque values.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::
-TraversePseudoObjectExpr(PseudoObjectExpr *S) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) {
TRY_TO(WalkUpFromPseudoObjectExpr(S));
StmtQueueAction StmtQueue(*this);
StmtQueue.queue(S->getSyntacticForm());
- for (PseudoObjectExpr::semantics_iterator
- i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i) {
+ for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
+ e = S->semantics_end();
+ i != e; ++i) {
Expr *sub = *i;
if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
sub = OVE->getSourceExpr();
@@ -2100,44 +2036,48 @@
}
DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
- // This is called for code like 'return T()' where T is a built-in
- // (i.e. non-class) type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
+ // This is called for code like 'return T()' where T is a built-in
+ // (i.e. non-class) type.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXNewExpr, {
// The child-iterator will pick up the other arguments.
TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
- })
+})
DEF_TRAVERSE_STMT(OffsetOfExpr, {
- // The child-iterator will pick up the expression representing
- // the field.
- // FIMXE: for code like offsetof(Foo, a.b.c), should we get
- // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the expression representing
+ // the field.
+ // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+ // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isArgumentType())
- TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isArgumentType())
+ TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXTypeidExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isTypeOperand())
+ TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+})
DEF_TRAVERSE_STMT(CXXUuidofExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isTypeOperand())
+ TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(TypeTraitExpr, {
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
@@ -2145,32 +2085,31 @@
})
DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+})
-DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
- StmtQueue.queue(S->getQueriedExpression());
- })
+DEF_TRAVERSE_STMT(ExpressionTraitExpr,
+ { StmtQueue.queue(S->getQueriedExpression()); })
DEF_TRAVERSE_STMT(VAArgExpr, {
- // The child-iterator will pick up the expression argument.
- TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the expression argument.
+ TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
- // This is called for code like 'return T()' where T is a class type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
+ // This is called for code like 'return T()' where T is a class type.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
-// Walk only the visible parts of lambda expressions.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
+// Walk only the visible parts of lambda expressions.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
TRY_TO(WalkUpFromLambdaExpr(S));
for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
- CEnd = S->explicit_capture_end();
+ CEnd = S->explicit_capture_end();
C != CEnd; ++C) {
- TRY_TO(TraverseLambdaCapture(*C));
+ TRY_TO(TraverseLambdaCapture(S, C));
}
if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
@@ -2186,44 +2125,45 @@
}
} else {
TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
- }
+ }
}
}
- StmtQueueAction StmtQueue(*this);
- StmtQueue.queue(S->getBody());
+ TRY_TO(TraverseLambdaBody(S));
return true;
}
DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
- // This is called for code like 'T()', where T is a template argument.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
+ // This is called for code like 'T()', where T is a template argument.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
// These expressions all might take explicit template arguments.
// We traverse those if so. FIXME: implement these.
-DEF_TRAVERSE_STMT(CXXConstructExpr, { })
-DEF_TRAVERSE_STMT(CallExpr, { })
-DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
+DEF_TRAVERSE_STMT(CXXConstructExpr, {})
+DEF_TRAVERSE_STMT(CallExpr, {})
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
// These exprs (most of them), do not need any action except iterating
// over the children.
-DEF_TRAVERSE_STMT(AddrLabelExpr, { })
-DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
+DEF_TRAVERSE_STMT(AddrLabelExpr, {})
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
DEF_TRAVERSE_STMT(BlockExpr, {
TRY_TO(TraverseDecl(S->getBlockDecl()));
return true; // no child statements to loop through.
})
-DEF_TRAVERSE_STMT(ChooseExpr, { })
-DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
-DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { })
-DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
-DEF_TRAVERSE_STMT(ExprWithCleanups, { })
-DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })
+DEF_TRAVERSE_STMT(ChooseExpr, {})
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
+DEF_TRAVERSE_STMT(ExprWithCleanups, {})
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
@@ -2231,38 +2171,38 @@
if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(CXXThisExpr, { })
-DEF_TRAVERSE_STMT(CXXThrowExpr, { })
-DEF_TRAVERSE_STMT(UserDefinedLiteral, { })
-DEF_TRAVERSE_STMT(DesignatedInitExpr, { })
-DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
-DEF_TRAVERSE_STMT(GNUNullExpr, { })
-DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { })
-DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXThisExpr, {})
+DEF_TRAVERSE_STMT(CXXThrowExpr, {})
+DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
+DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
+DEF_TRAVERSE_STMT(GNUNullExpr, {})
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
-DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
DEF_TRAVERSE_STMT(ObjCMessageExpr, {
if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
-DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
-DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { })
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
+DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(ParenExpr, { })
-DEF_TRAVERSE_STMT(ParenListExpr, { })
-DEF_TRAVERSE_STMT(PredefinedExpr, { })
-DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
-DEF_TRAVERSE_STMT(ConvertVectorExpr, { })
-DEF_TRAVERSE_STMT(StmtExpr, { })
+DEF_TRAVERSE_STMT(ParenExpr, {})
+DEF_TRAVERSE_STMT(ParenListExpr, {})
+DEF_TRAVERSE_STMT(PredefinedExpr, {})
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
+DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
+DEF_TRAVERSE_STMT(StmtExpr, {})
DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (S->hasExplicitTemplateArgs()) {
@@ -2279,134 +2219,155 @@
}
})
-DEF_TRAVERSE_STMT(MSPropertyRefExpr, {})
DEF_TRAVERSE_STMT(SEHTryStmt, {})
DEF_TRAVERSE_STMT(SEHExceptStmt, {})
-DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
-DEF_TRAVERSE_STMT(CapturedStmt, {
- TRY_TO(TraverseDecl(S->getCapturedDecl()));
-})
+DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
-DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
-DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
-DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { })
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
+DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
// These operators (all of them) do not need any action except
// iterating over the children.
-DEF_TRAVERSE_STMT(BinaryConditionalOperator, { })
-DEF_TRAVERSE_STMT(ConditionalOperator, { })
-DEF_TRAVERSE_STMT(UnaryOperator, { })
-DEF_TRAVERSE_STMT(BinaryOperator, { })
-DEF_TRAVERSE_STMT(CompoundAssignOperator, { })
-DEF_TRAVERSE_STMT(CXXNoexceptExpr, { })
-DEF_TRAVERSE_STMT(PackExpansionExpr, { })
-DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
-DEF_TRAVERSE_STMT(FunctionParmPackExpr, { })
-DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
-DEF_TRAVERSE_STMT(AtomicExpr, { })
+DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
+DEF_TRAVERSE_STMT(ConditionalOperator, {})
+DEF_TRAVERSE_STMT(UnaryOperator, {})
+DEF_TRAVERSE_STMT(BinaryOperator, {})
+DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
+DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
+DEF_TRAVERSE_STMT(PackExpansionExpr, {})
+DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
+DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
+DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(AtomicExpr, {})
// These literals (all of them) do not need any action.
-DEF_TRAVERSE_STMT(IntegerLiteral, { })
-DEF_TRAVERSE_STMT(CharacterLiteral, { })
-DEF_TRAVERSE_STMT(FloatingLiteral, { })
-DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
-DEF_TRAVERSE_STMT(StringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCBoxedExpr, { })
-DEF_TRAVERSE_STMT(ObjCArrayLiteral, { })
-DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
-
+DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(CharacterLiteral, {})
+DEF_TRAVERSE_STMT(FloatingLiteral, {})
+DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
+DEF_TRAVERSE_STMT(StringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
+DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
+DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
+
// Traverse OpenCL: AsType, Convert.
-DEF_TRAVERSE_STMT(AsTypeExpr, { })
+DEF_TRAVERSE_STMT(AsTypeExpr, {})
// OpenMP directives.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
- OMPExecutableDirective *S) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
+ OMPExecutableDirective *S) {
ArrayRef<OMPClause *> Clauses = S->clauses();
for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
I != E; ++I)
- if (!TraverseOMPClause(*I)) return false;
+ if (!TraverseOMPClause(*I))
+ return false;
return true;
}
DEF_TRAVERSE_STMT(OMPParallelDirective, {
- if (!TraverseOMPExecutableDirective(S)) return false;
+ if (!TraverseOMPExecutableDirective(S))
+ return false;
})
DEF_TRAVERSE_STMT(OMPSimdDirective, {
- if (!TraverseOMPExecutableDirective(S)) return false;
+ if (!TraverseOMPExecutableDirective(S))
+ return false;
})
// OpenMP clauses.
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
- if (!C) return true;
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
+ if (!C)
+ return true;
switch (C->getClauseKind()) {
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_##Name: \
- return getDerived().Visit##Class(static_cast<Class*>(C));
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name: \
+ return getDerived().Visit##Class(static_cast<Class *>(C));
#include "clang/Basic/OpenMPKinds.def"
- default: break;
+ default:
+ break;
}
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
TraverseStmt(C->getCondition());
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(
- OMPNumThreadsClause *C) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
TraverseStmt(C->getNumThreads());
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::VisitOMPSafelenClause(
- OMPSafelenClause *C) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
TraverseStmt(C->getSafelen());
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
+ TraverseStmt(C->getNumForLoops());
return true;
}
-template<typename Derived>
-template<typename T>
-void DataRecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *C) {
+ return true;
+}
+
+template <typename Derived>
+template <typename T>
+void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *I : Node->varlists())
TraverseStmt(I);
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
VisitOMPClauseList(C);
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
- OMPFirstprivateClause *C) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
+ OMPFirstprivateClause *C) {
VisitOMPClauseList(C);
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
VisitOMPClauseList(C);
return true;
}
-template<typename Derived>
-bool DataRecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
+ VisitOMPClauseList(C);
+ TraverseStmt(C->getStep());
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
VisitOMPClauseList(C);
return true;
}
@@ -2432,6 +2393,8 @@
#undef TRY_TO
+#undef RecursiveASTVisitor
+
} // end namespace clang
#endif // LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 526187e..f654791 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -21,6 +21,7 @@
#include "clang/AST/Redeclarable.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Linkage.h"
+#include "clang/Basic/OperatorKinds.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Compiler.h"
@@ -79,9 +80,9 @@
NamespaceDecl *AnonymousNamespace;
explicit TranslationUnitDecl(ASTContext &ctx)
- : Decl(TranslationUnit, 0, SourceLocation()),
+ : Decl(TranslationUnit, nullptr, SourceLocation()),
DeclContext(TranslationUnit),
- Ctx(ctx), AnonymousNamespace(0) {}
+ Ctx(ctx), AnonymousNamespace(nullptr) {}
public:
ASTContext &getASTContext() const { return Ctx; }
@@ -354,12 +355,12 @@
/// boolean value indicating whether this is an inline namespace.
llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
- NamespaceDecl(DeclContext *DC, bool Inline, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- NamespaceDecl *PrevDecl);
+ NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, NamespaceDecl *PrevDecl);
typedef Redeclarable<NamespaceDecl> redeclarable_base;
- NamespaceDecl *getNextRedeclaration() override;
+ NamespaceDecl *getNextRedeclarationImpl() override;
NamespaceDecl *getPreviousDeclImpl() override;
NamespaceDecl *getMostRecentDeclImpl() override;
@@ -508,7 +509,8 @@
TemplateParameterList** TemplParamLists;
/// Default constructor.
- QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {}
+ QualifierInfo()
+ : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {}
/// setTemplateParameterListsInfo - Sets info about "outer" template
/// parameter lists.
@@ -579,7 +581,7 @@
/// declaration, if it was present in the source.
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
- : 0;
+ : nullptr;
}
/// \brief Retrieve the nested-name-specifier (with source-location
@@ -767,12 +769,14 @@
ParmVarDeclBitfields ParmVarDeclBits;
};
- VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass SC);
typedef Redeclarable<VarDecl> redeclarable_base;
- VarDecl *getNextRedeclaration() override { return RedeclLink.getNext(); }
+ VarDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
+ }
VarDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
@@ -808,22 +812,12 @@
void setTSCSpec(ThreadStorageClassSpecifier TSC) {
VarDeclBits.TSCSpec = TSC;
+ assert(VarDeclBits.TSCSpec == TSC && "truncation");
}
ThreadStorageClassSpecifier getTSCSpec() const {
return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec);
}
- TLSKind getTLSKind() const {
- switch (VarDeclBits.TSCSpec) {
- case TSCS_unspecified:
- return TLS_None;
- case TSCS___thread: // Fall through.
- case TSCS__Thread_local:
- return TLS_Static;
- case TSCS_thread_local:
- return TLS_Dynamic;
- }
- llvm_unreachable("Unknown thread storage class specifier!");
- }
+ TLSKind getTLSKind() const;
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
@@ -832,6 +826,10 @@
// Second check is for C++11 [dcl.stc]p4.
return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
+ // Global Named Register (GNU extension)
+ if (getStorageClass() == SC_Register && !isLocalVarDecl())
+ return false;
+
// Return true for: Auto, Register.
// Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
@@ -1001,7 +999,7 @@
}
const Expr *getInit() const {
if (Init.isNull())
- return 0;
+ return nullptr;
const Stmt *S = Init.dyn_cast<Stmt *>();
if (!S) {
@@ -1012,7 +1010,7 @@
}
Expr *getInit() {
if (Init.isNull())
- return 0;
+ return nullptr;
Stmt *S = Init.dyn_cast<Stmt *>();
if (!S) {
@@ -1063,7 +1061,7 @@
if (Eval->WasEvaluated)
return &Eval->Evaluated;
- return 0;
+ return nullptr;
}
/// \brief Determines whether it is already known whether the
@@ -1220,11 +1218,11 @@
QualType T);
static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc,
+
+ ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
IdentifierInfo *Id, QualType Type)
- : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type,
- /*tinfo*/ 0, SC_None) {
+ : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
+ /*tinfo*/ nullptr, SC_None) {
setImplicit();
}
@@ -1240,11 +1238,10 @@
enum { MaxFunctionScopeIndex = 255 };
protected:
- ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg)
- : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
+ ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
+ : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
assert(ParmVarDeclBits.IsKNRPromoted == false);
assert(ParmVarDeclBits.IsObjCMethodParam == false);
@@ -1367,9 +1364,7 @@
/// real default argument via setDefaultArg when the class
/// definition enclosing the function declaration that owns this
/// default argument is completed.
- void setUnparsedDefaultArg() {
- Init = (UnparsedDefaultArgument *)0;
- }
+ void setUnparsedDefaultArg() { Init = (UnparsedDefaultArgument *)nullptr; }
bool hasInheritedDefaultArg() const {
return ParmVarDeclBits.HasInheritedDefaultArg;
@@ -1543,7 +1538,7 @@
void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
protected:
- FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, bool isInlineSpecified,
@@ -1551,7 +1546,8 @@
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
DeclContext(DK),
- ParamInfo(0), Body(),
+ redeclarable_base(C),
+ ParamInfo(nullptr), Body(),
SClass(S),
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
@@ -1564,7 +1560,9 @@
DNLoc(NameInfo.getInfo()) {}
typedef Redeclarable<FunctionDecl> redeclarable_base;
- FunctionDecl *getNextRedeclaration() override { return RedeclLink.getNext(); }
+ FunctionDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
+ }
FunctionDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
@@ -2007,7 +2005,7 @@
/// \brief Determine whether this function is a function template
/// specialization.
bool isFunctionTemplateSpecialization() const {
- return getPrimaryTemplate() != 0;
+ return getPrimaryTemplate() != nullptr;
}
/// \brief Retrieve the class scope template pattern that this function
@@ -2080,11 +2078,11 @@
/// \param PointOfInstantiation point at which the function template
/// specialization was first instantiated.
void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
- const TemplateArgumentListInfo *TemplateArgsAsWritten = 0,
- SourceLocation PointOfInstantiation = SourceLocation()) {
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos,
+ TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr,
+ SourceLocation PointOfInstantiation = SourceLocation()) {
setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
InsertPos, TSK, TemplateArgsAsWritten,
PointOfInstantiation);
@@ -2207,7 +2205,7 @@
bool isAnonymousStructOrUnion() const;
Expr *getBitWidth() const {
- return isBitField() ? InitializerOrBitWidth.getPointer() : 0;
+ return isBitField() ? InitializerOrBitWidth.getPointer() : nullptr;
}
unsigned getBitWidthValue(const ASTContext &Ctx) const;
@@ -2218,7 +2216,7 @@
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
- InitializerOrBitWidth.setPointer(0);
+ InitializerOrBitWidth.setPointer(nullptr);
}
/// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
@@ -2237,7 +2235,8 @@
/// in-class initializer, but this returns null, then we have not parsed and
/// attached it yet.
Expr *getInClassInitializer() const {
- return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0;
+ return hasInClassInitializer() ? InitializerOrBitWidth.getPointer()
+ : nullptr;
}
/// setInClassInitializer - Set the C++11 in-class initializer for this
/// member.
@@ -2246,7 +2245,7 @@
/// member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
- InitializerOrBitWidth.setPointer(0);
+ InitializerOrBitWidth.setPointer(nullptr);
InitializerOrBitWidth.setInt(ICIS_NoInit);
}
@@ -2374,16 +2373,11 @@
/// LocStart - The start of the source range for this declaration.
SourceLocation LocStart;
friend class ASTContext;
- friend class DeclContext;
- friend class TagDecl;
- friend class TemplateTypeParmDecl;
- friend class TagType;
- friend class ASTReader;
protected:
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
SourceLocation StartL = SourceLocation())
- : NamedDecl(DK, DC, L, Id), TypeForDecl(0), LocStart(StartL) {}
+ : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {}
public:
// Low-level accessor. If you just want the type defined by this node,
@@ -2415,14 +2409,15 @@
llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
protected:
- TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- TypeSourceInfo *TInfo)
- : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {}
+ TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
+ MaybeModedTInfo(TInfo) {}
typedef Redeclarable<TypedefNameDecl> redeclarable_base;
- TypedefNameDecl *getNextRedeclaration() override {
- return RedeclLink.getNext();
+ TypedefNameDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
TypedefNameDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
@@ -2474,9 +2469,9 @@
/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
/// type specifier.
class TypedefDecl : public TypedefNameDecl {
- TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {}
+ TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {}
public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2494,9 +2489,9 @@
/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
/// alias-declaration.
class TypeAliasDecl : public TypedefNameDecl {
- TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {}
+ TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {}
public:
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2592,20 +2587,23 @@
}
protected:
- TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL)
- : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK),
- IsCompleteDefinition(false), IsBeingDefined(false),
+ TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
+ SourceLocation StartL)
+ : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
+ TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false),
IsEmbeddedInDeclarator(false), IsFreeStanding(false),
IsCompleteDefinitionRequired(false),
- NamedDeclOrQualifier((NamedDecl *)0) {
+ NamedDeclOrQualifier((NamedDecl *)nullptr) {
assert((DK != Enum || TK == TTK_Enum) &&
"EnumDecl not matched with TTK_Enum");
setPreviousDecl(PrevDecl);
}
typedef Redeclarable<TagDecl> redeclarable_base;
- TagDecl *getNextRedeclaration() override { return RedeclLink.getNext(); }
+ TagDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
+ }
TagDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
@@ -2640,8 +2638,8 @@
SourceLocation getOuterLocStart() const;
SourceRange getSourceRange() const override LLVM_READONLY;
- TagDecl* getCanonicalDecl() override;
- const TagDecl* getCanonicalDecl() const {
+ TagDecl *getCanonicalDecl() override;
+ const TagDecl *getCanonicalDecl() const {
return const_cast<TagDecl*>(this)->getCanonicalDecl();
}
@@ -2708,8 +2706,7 @@
IsCompleteDefinitionRequired = V;
}
- // FIXME: Return StringRef;
- const char *getKindName() const {
+ StringRef getKindName() const {
return TypeWithKeyword::getTagTypeKindName(getTagKind());
}
@@ -2749,12 +2746,12 @@
NamedDeclOrQualifier.get<NamedDecl *>());
}
DeclaratorDecl *getDeclaratorForAnonDecl() const {
- return hasExtInfo() ? 0 : dyn_cast_or_null<DeclaratorDecl>(
+ return hasExtInfo() ? nullptr : dyn_cast_or_null<DeclaratorDecl>(
NamedDeclOrQualifier.get<NamedDecl *>());
}
TypedefNameDecl *getTypedefNameForAnonDecl() const {
- return hasExtInfo() ? 0 : dyn_cast_or_null<TypedefNameDecl>(
+ return hasExtInfo() ? nullptr : dyn_cast_or_null<TypedefNameDecl>(
NamedDeclOrQualifier.get<NamedDecl *>());
}
@@ -2766,7 +2763,7 @@
/// declaration, if it was present in the source.
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
- : 0;
+ : nullptr;
}
/// \brief Retrieve the nested-name-specifier (with source-location
@@ -2837,13 +2834,13 @@
/// information.
MemberSpecializationInfo *SpecializationInfo;
- EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, EnumDecl *PrevDecl,
+ EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
- : TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc),
- SpecializationInfo(0) {
+ : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc),
+ SpecializationInfo(nullptr) {
assert(Scoped || !ScopedUsingClassTag);
- IntegerType = (const Type*)0;
+ IntegerType = (const Type *)nullptr;
NumNegativeBits = 0;
NumPositiveBits = 0;
IsScoped = Scoped;
@@ -3070,14 +3067,14 @@
friend class DeclContext;
protected:
- RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
+ RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl *PrevDecl);
public:
static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, RecordDecl* PrevDecl = 0);
+ IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr);
static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
RecordDecl *getPreviousDecl() {
@@ -3254,7 +3251,7 @@
/// is not from outside the immediately enclosing function/block.
bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; }
- bool hasCopyExpr() const { return CopyExpr != 0; }
+ bool hasCopyExpr() const { return CopyExpr != nullptr; }
Expr *getCopyExpr() const { return CopyExpr; }
void setCopyExpr(Expr *e) { CopyExpr = e; }
};
@@ -3285,9 +3282,9 @@
: Decl(Block, DC, CaretLoc), DeclContext(Block),
IsVariadic(false), CapturesCXXThis(false),
BlockMissingReturnType(true), IsConversionFromLambda(false),
- ParamInfo(0), NumParams(0), Body(0),
- SignatureAsWritten(0), Captures(0), NumCaptures(0),
- ManglingNumber(0), ManglingContextDecl(0) {}
+ ParamInfo(nullptr), NumParams(0), Body(nullptr),
+ SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0),
+ ManglingNumber(0), ManglingContextDecl(nullptr) {}
public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
@@ -3416,12 +3413,14 @@
private:
/// \brief The number of parameters to the outlined function.
unsigned NumParams;
+ /// \brief The position of context parameter in list of parameters.
+ unsigned ContextParam;
/// \brief The body of the outlined function.
- Stmt *Body;
+ llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
explicit CapturedDecl(DeclContext *DC, unsigned NumParams)
: Decl(Captured, DC, SourceLocation()), DeclContext(Captured),
- NumParams(NumParams), Body(0) { }
+ NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) { }
ImplicitParamDecl **getParams() const {
return reinterpret_cast<ImplicitParamDecl **>(
@@ -3429,12 +3428,16 @@
}
public:
- static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams);
+ static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
+ unsigned NumParams);
static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumParams);
- Stmt *getBody() const override { return Body; }
- void setBody(Stmt *B) { Body = B; }
+ Stmt *getBody() const override { return BodyAndNothrow.getPointer(); }
+ void setBody(Stmt *B) { BodyAndNothrow.setPointer(B); }
+
+ bool isNothrow() const { return BodyAndNothrow.getInt(); }
+ void setNothrow(bool Nothrow = true) { BodyAndNothrow.setInt(Nothrow); }
unsigned getNumParams() const { return NumParams; }
@@ -3448,8 +3451,16 @@
}
/// \brief Retrieve the parameter containing captured variables.
- ImplicitParamDecl *getContextParam() const { return getParam(0); }
- void setContextParam(ImplicitParamDecl *P) { setParam(0, P); }
+ ImplicitParamDecl *getContextParam() const {
+ assert(ContextParam < NumParams);
+ return getParam(ContextParam);
+ }
+ void setContextParam(unsigned i, ImplicitParamDecl *P) {
+ assert(i < NumParams);
+ ContextParam = i;
+ setParam(i, P);
+ }
+ unsigned getContextParamPosition() const { return ContextParam; }
typedef ImplicitParamDecl **param_iterator;
typedef llvm::iterator_range<param_iterator> param_range;
@@ -3577,6 +3588,8 @@
void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// Note: This routine is implemented here because we need both NamedDecl
// and Redeclarable to be defined.
+ assert(RedeclLink.NextIsLatest() &&
+ "setPreviousDecl on a decl already in a redeclaration chain");
decl_type *First;
@@ -3586,7 +3599,7 @@
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
First = PrevDecl->getFirstDecl();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
- decl_type *MostRecent = First->RedeclLink.getNext();
+ decl_type *MostRecent = First->getNextRedeclaration();
RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
// If the declaration was previously visible, a redeclaration of it remains
@@ -3600,7 +3613,8 @@
}
// First one will point to this one as latest.
- First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
+ First->RedeclLink.setLatest(static_cast<decl_type*>(this));
+
assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||
cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid());
}
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 6c31358..c77b2b6 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -16,7 +16,6 @@
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
-#include "clang/Basic/Linkage.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/iterator_range.h"
@@ -34,6 +33,7 @@
class EnumDecl;
class FunctionDecl;
class FunctionType;
+enum Linkage : unsigned char;
class LinkageComputer;
class LinkageSpecDecl;
class Module;
@@ -397,6 +397,8 @@
bool isInAnonymousNamespace() const;
+ bool isInStdNamespace() const;
+
ASTContext &getASTContext() const LLVM_READONLY;
void setAccess(AccessSpecifier AS) {
@@ -440,10 +442,10 @@
}
attr_iterator attr_begin() const {
- return hasAttrs() ? getAttrs().begin() : 0;
+ return hasAttrs() ? getAttrs().begin() : nullptr;
}
attr_iterator attr_end() const {
- return hasAttrs() ? getAttrs().end() : 0;
+ return hasAttrs() ? getAttrs().end() : nullptr;
}
template <typename T>
@@ -473,7 +475,7 @@
}
template<typename T> T *getAttr() const {
- return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : 0;
+ return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
}
template<typename T> bool hasAttr() const {
return hasAttrs() && hasSpecificAttr<T>(getAttrs());
@@ -570,14 +572,14 @@
/// AR_Available, will be set to a (possibly empty) message
/// describing why the declaration has not been introduced, is
/// deprecated, or is unavailable.
- AvailabilityResult getAvailability(std::string *Message = 0) const;
+ AvailabilityResult getAvailability(std::string *Message = nullptr) const;
/// \brief Determine whether this declaration is marked 'deprecated'.
///
/// \param Message If non-NULL and the declaration is deprecated,
/// this will be set to the message describing why the declaration
/// was deprecated (which may be empty).
- bool isDeprecated(std::string *Message = 0) const {
+ bool isDeprecated(std::string *Message = nullptr) const {
return getAvailability(Message) == AR_Deprecated;
}
@@ -586,7 +588,7 @@
/// \param Message If non-NULL and the declaration is unavailable,
/// this will be set to the message describing why the declaration
/// was made unavailable (which may be empty).
- bool isUnavailable(std::string *Message = 0) const {
+ bool isUnavailable(std::string *Message = nullptr) const {
return getAvailability(Message) == AR_Unavailable;
}
@@ -633,7 +635,7 @@
public:
Module *getOwningModule() const {
if (!isFromASTFile())
- return 0;
+ return nullptr;
return getOwningModuleSlow();
}
@@ -688,7 +690,7 @@
/// roughly global variables and functions, but also handles enums (which
/// could be defined inside or outside a function etc).
bool isDefinedOutsideFunctionOrMethod() const {
- return getParentFunctionOrMethod() == 0;
+ return getParentFunctionOrMethod() == nullptr;
}
/// \brief If this decl is defined inside a function/method/block it returns
@@ -713,16 +715,16 @@
///
/// Decl subclasses that can be redeclared should override this method so that
/// Decl::redecl_iterator can iterate over them.
- virtual Decl *getNextRedeclaration() { return this; }
+ virtual Decl *getNextRedeclarationImpl() { return this; }
/// \brief Implementation of getPreviousDecl(), to be overridden by any
/// subclass that has a redeclaration chain.
- virtual Decl *getPreviousDeclImpl() { return 0; }
-
+ virtual Decl *getPreviousDeclImpl() { return nullptr; }
+
/// \brief Implementation of getMostRecentDecl(), to be overridden by any
- /// subclass that has a redeclaration chain.
+ /// subclass that has a redeclaration chain.
virtual Decl *getMostRecentDeclImpl() { return this; }
-
+
public:
/// \brief Iterates through all the redeclarations of the same decl.
class redecl_iterator {
@@ -737,7 +739,7 @@
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- redecl_iterator() : Current(0) { }
+ redecl_iterator() : Current(nullptr) { }
explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
reference operator*() const { return Current; }
@@ -746,9 +748,9 @@
redecl_iterator& operator++() {
assert(Current && "Advancing while iterator has reached end");
// Get either previous decl or latest decl.
- Decl *Next = Current->getNextRedeclaration();
+ Decl *Next = Current->getNextRedeclarationImpl();
assert(Next && "Should return next redeclaration or itself, never null!");
- Current = (Next != Starter ? Next : 0);
+ Current = (Next != Starter) ? Next : nullptr;
return *this;
}
@@ -791,7 +793,7 @@
/// \brief True if this is the first declaration in its redeclaration chain.
bool isFirstDecl() const {
- return getPreviousDecl() == 0;
+ return getPreviousDecl() == nullptr;
}
/// \brief Retrieve the most recent declaration that declares the same entity
@@ -807,13 +809,13 @@
/// getBody - If this Decl represents a declaration for a body of code,
/// such as a function or method definition, this method returns the
/// top-level Stmt* of that body. Otherwise this method returns null.
- virtual Stmt* getBody() const { return 0; }
+ virtual Stmt* getBody() const { return nullptr; }
/// \brief Returns true if this \c Decl represents a declaration for a body of
/// code, such as a function or method definition.
/// Note that \c hasBody can also return true if any redeclaration of this
/// \c Decl represents a declaration for a body of code.
- virtual bool hasBody() const { return getBody() != 0; }
+ virtual bool hasBody() const { return getBody() != nullptr; }
/// getBodyRBrace - Gets the right brace of the body, if a body exists.
/// This works whether the body is a CompoundStmt or a CXXTryStmt.
@@ -1068,8 +1070,8 @@
DeclContext(Decl::Kind K)
: DeclKind(K), ExternalLexicalStorage(false),
ExternalVisibleStorage(false),
- NeedToReconcileExternalVisibleStorage(false), LookupPtr(0, false),
- FirstDecl(0), LastDecl(0) {}
+ NeedToReconcileExternalVisibleStorage(false), LookupPtr(nullptr, false),
+ FirstDecl(nullptr), LastDecl(nullptr) {}
public:
~DeclContext();
@@ -1156,6 +1158,8 @@
return DeclKind == Decl::Namespace;
}
+ bool isStdNamespace() const;
+
bool isInlineNamespace() const;
/// \brief Determines whether this context is dependent on a
@@ -1276,7 +1280,7 @@
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- decl_iterator() : Current(0) { }
+ decl_iterator() : Current(nullptr) { }
explicit decl_iterator(Decl *C) : Current(C) { }
reference operator*() const { return Current; }
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index f64ef8b..01af64a 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -20,11 +20,9 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/TypeLoc.h"
+#include "clang/AST/LambdaCapture.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Compiler.h"
namespace clang {
@@ -259,10 +257,31 @@
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
+/// \brief A lazy pointer to the definition data for a declaration.
+/// FIXME: This is a little CXXRecordDecl-specific that the moment.
+template<typename Decl, typename T> class LazyDefinitionDataPtr {
+ llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
+
+ LazyDefinitionDataPtr update() {
+ if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
+ if (Canon->isCanonicalDecl())
+ Canon->getMostRecentDecl();
+ else
+ // Declaration isn't canonical any more;
+ // update it and perform path compression.
+ *this = Canon->getPreviousDecl()->DefinitionData.update();
+ }
+ return *this;
+ }
+
+public:
+ LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
+ LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
+ T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
+ T *get() { return update().getNotUpdated(); }
+};
+
/// \brief Represents a C++ struct/union/class.
-///
-/// FIXME: This class will disappear once we've properly taught RecordDecl
-/// to deal with C++-specific things.
class CXXRecordDecl : public RecordDecl {
friend void TagDecl::startDefinition();
@@ -405,7 +424,7 @@
/// \brief True if this class has a constexpr default constructor.
///
/// This is true for either a user-declared constexpr default constructor
- /// or an implicitly declared constexpr default constructor..
+ /// or an implicitly declared constexpr default constructor.
bool HasConstexprDefaultConstructor : 1;
/// \brief True when this class contains at least one non-static data
@@ -482,33 +501,39 @@
/// \brief Retrieve the set of direct base classes.
CXXBaseSpecifier *getBases() const {
if (!Bases.isOffset())
- return Bases.get(0);
+ return Bases.get(nullptr);
return getBasesSlowCase();
}
/// \brief Retrieve the set of virtual base classes.
CXXBaseSpecifier *getVBases() const {
if (!VBases.isOffset())
- return VBases.get(0);
+ return VBases.get(nullptr);
return getVBasesSlowCase();
}
private:
CXXBaseSpecifier *getBasesSlowCase() const;
CXXBaseSpecifier *getVBasesSlowCase() const;
- } *DefinitionData;
+ };
+
+ typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
+ DefinitionDataPtr;
+ friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
+
+ mutable DefinitionDataPtr DefinitionData;
/// \brief Describes a C++ closure type (generated by a lambda expression).
struct LambdaDefinitionData : public DefinitionData {
- typedef LambdaExpr::Capture Capture;
-
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
+ typedef LambdaCapture Capture;
+
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
bool Dependent, bool IsGeneric,
LambdaCaptureDefault CaptureDefault)
: DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
- ManglingNumber(0), ContextDecl(0), Captures(0), MethodTyInfo(Info)
- {
+ ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
+ MethodTyInfo(Info) {
IsLambda = true;
}
@@ -553,23 +578,20 @@
};
- struct DefinitionData &data() {
- assert(DefinitionData && "queried property of class with no definition");
- return *DefinitionData;
- }
-
- const struct DefinitionData &data() const {
- assert(DefinitionData && "queried property of class with no definition");
- return *DefinitionData;
+ struct DefinitionData &data() const {
+ auto *DD = DefinitionData.get();
+ assert(DD && "queried property of class with no definition");
+ return *DD;
}
struct LambdaDefinitionData &getLambdaData() const {
- assert(DefinitionData && "queried property of lambda with no definition");
- assert(DefinitionData->IsLambda &&
- "queried lambda property of non-lambda class");
- return static_cast<LambdaDefinitionData &>(*DefinitionData);
+ // No update required: a merged definition cannot change any lambda
+ // properties.
+ auto *DD = DefinitionData.getNotUpdated();
+ assert(DD && DD->IsLambda && "queried lambda property of non-lambda class");
+ return static_cast<LambdaDefinitionData&>(*DD);
}
-
+
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
@@ -606,7 +628,7 @@
FriendDecl *getFirstFriend() const;
protected:
- CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
+ CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
@@ -642,19 +664,20 @@
}
CXXRecordDecl *getDefinition() const {
- if (!DefinitionData) return 0;
- return data().Definition;
+ auto *DD = DefinitionData.get();
+ return DD ? DD->Definition : nullptr;
}
- bool hasDefinition() const { return DefinitionData != 0; }
+ bool hasDefinition() const { return DefinitionData.get(); }
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
+ IdentifierInfo *Id,
+ CXXRecordDecl *PrevDecl = nullptr,
bool DelayTypeCreation = false);
static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
TypeSourceInfo *Info, SourceLocation Loc,
- bool DependentLambda, bool IsGeneric,
+ bool DependentLambda, bool IsGeneric,
LambdaCaptureDefault CaptureDefault);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
@@ -977,7 +1000,11 @@
}
/// \brief Determine whether this class describes a lambda function object.
- bool isLambda() const { return hasDefinition() && data().IsLambda; }
+ bool isLambda() const {
+ // An update record can't turn a non-lambda into a lambda.
+ auto *DD = DefinitionData.getNotUpdated();
+ return DD && DD->IsLambda;
+ }
/// \brief Determine whether this class describes a generic
/// lambda function object (i.e. function call operator is
@@ -1018,17 +1045,18 @@
void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
FieldDecl *&ThisCapture) const;
- typedef const LambdaExpr::Capture* capture_const_iterator;
+ typedef const LambdaCapture *capture_const_iterator;
typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
capture_const_range captures() const {
return capture_const_range(captures_begin(), captures_end());
}
capture_const_iterator captures_begin() const {
- return isLambda() ? getLambdaData().Captures : NULL;
+ return isLambda() ? getLambdaData().Captures : nullptr;
}
capture_const_iterator captures_end() const {
- return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL;
+ return isLambda() ? captures_begin() + getLambdaData().NumCaptures
+ : nullptr;
}
typedef UnresolvedSetIterator conversion_iterator;
@@ -1658,12 +1686,12 @@
class CXXMethodDecl : public FunctionDecl {
void anchor() override;
protected:
- CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
+ CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass SC, bool isInline,
bool isConstexpr, SourceLocation EndLocation)
- : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
+ : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo,
SC, isInline, isConstexpr) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
@@ -1941,7 +1969,7 @@
/// In-class member initializers (also known as "non-static data member
/// initializations", NSDMIs) were introduced in C++11.
bool isInClassMemberInitializer() const {
- return isa<CXXDefaultInitExpr>(Init);
+ return Init->getStmtClass() == Stmt::CXXDefaultInitExprClass;
}
/// \brief Determine whether this initializer is creating a delegating
@@ -1988,20 +2016,20 @@
FieldDecl *getMember() const {
if (isMemberInitializer())
return Initializee.get<FieldDecl*>();
- return 0;
+ return nullptr;
}
FieldDecl *getAnyMember() const {
if (isMemberInitializer())
return Initializee.get<FieldDecl*>();
if (isIndirectMemberInitializer())
return Initializee.get<IndirectFieldDecl*>()->getAnonField();
- return 0;
+ return nullptr;
}
IndirectFieldDecl *getIndirectMember() const {
if (isIndirectMemberInitializer())
return Initializee.get<IndirectFieldDecl*>();
- return 0;
+ return nullptr;
}
SourceLocation getMemberLocation() const {
@@ -2098,14 +2126,14 @@
unsigned NumCtorInitializers;
/// \}
- CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared, bool isConstexpr)
- : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, SourceLocation()),
- IsExplicitSpecified(isExplicitSpecified), CtorInitializers(0),
+ IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
NumCtorInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -2298,13 +2326,13 @@
FunctionDecl *OperatorDelete;
- CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
- OperatorDelete(0) {
+ OperatorDelete(nullptr) {
setImplicit(isImplicitlyDeclared);
}
@@ -2349,12 +2377,12 @@
/// explicitly wrote a cast. This is a C++0x feature.
bool IsExplicitSpecified : 1;
- CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified,
bool isConstexpr, SourceLocation EndLocation)
- : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, EndLocation),
IsExplicitSpecified(isExplicitSpecified) { }
@@ -2706,10 +2734,10 @@
NamedDecl *UsingOrNextShadow;
friend class UsingDecl;
- UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
- NamedDecl *Target)
+ UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
+ UsingDecl *Using, NamedDecl *Target)
: NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
- Underlying(Target),
+ redeclarable_base(C), Underlying(Target),
UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
if (Target) {
setDeclName(Target->getDeclName());
@@ -2719,8 +2747,8 @@
}
typedef Redeclarable<UsingShadowDecl> redeclarable_base;
- UsingShadowDecl *getNextRedeclaration() override {
- return RedeclLink.getNext();
+ UsingShadowDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
UsingShadowDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
@@ -2733,7 +2761,7 @@
static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target) {
- return new (C, DC) UsingShadowDecl(DC, Loc, Using, Target);
+ return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
}
static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2812,7 +2840,7 @@
const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
: NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
UsingLocation(UL), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, HasTypenameKeyword) {
+ DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) {
}
public:
@@ -2857,7 +2885,7 @@
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- shadow_iterator() : Current(0) { }
+ shadow_iterator() : Current(nullptr) { }
explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
reference operator*() const { return Current; }
@@ -3137,9 +3165,9 @@
static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
- bool hasGetter() const { return GetterId != NULL; }
+ bool hasGetter() const { return GetterId != nullptr; }
IdentifierInfo* getGetterId() const { return GetterId; }
- bool hasSetter() const { return SetterId != NULL; }
+ bool hasSetter() const { return SetterId != nullptr; }
IdentifierInfo* getSetterId() const { return SetterId; }
friend class ASTDeclReader;
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index f85cea5..9068c00 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -47,7 +47,7 @@
StoredDeclsList() {}
StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
- RHS.Data = (NamedDecl *)0;
+ RHS.Data = (NamedDecl *)nullptr;
}
~StoredDeclsList() {
@@ -60,7 +60,7 @@
if (DeclsTy *Vector = getAsVector())
delete Vector;
Data = RHS.Data;
- RHS.Data = (NamedDecl *)0;
+ RHS.Data = (NamedDecl *)nullptr;
return *this;
}
@@ -107,7 +107,7 @@
if (NamedDecl *Singleton = getAsDecl()) {
assert(Singleton == D && "list is different singleton");
(void)Singleton;
- Data = (NamedDecl *)0;
+ Data = (NamedDecl *)nullptr;
return;
}
@@ -142,8 +142,8 @@
/// represents.
DeclContext::lookup_result getLookupResult() {
if (isNull())
- return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
- DeclContext::lookup_iterator(0));
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(nullptr),
+ DeclContext::lookup_iterator(nullptr));
// If we have a single NamedDecl, return it.
if (getAsDecl()) {
@@ -252,7 +252,7 @@
class DependentStoredDeclsMap : public StoredDeclsMap {
public:
- DependentStoredDeclsMap() : FirstDiagnostic(0) {}
+ DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
private:
friend class DependentDiagnostic;
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index bb852d0..97741c1 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -17,6 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TypeLoc.h"
#include "llvm/Support/Compiler.h"
namespace clang {
@@ -91,7 +92,7 @@
FriendDecl *getNextFriend() {
if (!NextFriend.isOffset())
- return cast_or_null<FriendDecl>(NextFriend.get(0));
+ return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
return getNextFriendSlowCase();
}
FriendDecl *getNextFriendSlowCase();
@@ -224,7 +225,7 @@
}
inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
- return friend_iterator(0);
+ return friend_iterator(nullptr);
}
inline CXXRecordDecl::friend_range CXXRecordDecl::friends() const {
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index cda6ae5..bd3dbd8 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -63,7 +63,7 @@
}
public:
- DeclGroupRef() : D(0) {}
+ DeclGroupRef() : D(nullptr) {}
explicit DeclGroupRef(Decl* d) : D(d) {}
explicit DeclGroupRef(DeclGroup* dg)
@@ -80,7 +80,7 @@
typedef Decl** iterator;
typedef Decl* const * const_iterator;
- bool isNull() const { return D == 0; }
+ bool isNull() const { return D == nullptr; }
bool isSingleDecl() const { return getKind() == SingleDeclKind; }
bool isDeclGroup() const { return getKind() == DeclGroupKind; }
@@ -102,26 +102,26 @@
iterator begin() {
if (isSingleDecl())
- return D ? &D : 0;
+ return D ? &D : nullptr;
return &getDeclGroup()[0];
}
iterator end() {
if (isSingleDecl())
- return D ? &D+1 : 0;
+ return D ? &D+1 : nullptr;
DeclGroup &G = getDeclGroup();
return &G[0] + G.size();
}
const_iterator begin() const {
if (isSingleDecl())
- return D ? &D : 0;
+ return D ? &D : nullptr;
return &getDeclGroup()[0];
}
const_iterator end() const {
if (isSingleDecl())
- return D ? &D+1 : 0;
+ return D ? &D+1 : nullptr;
const DeclGroup &G = getDeclGroup();
return &G[0] + G.size();
}
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index cdd7d26..4ca02d2 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -41,7 +41,7 @@
unsigned NumElts;
public:
- ObjCListBase() : List(0), NumElts(0) {}
+ ObjCListBase() : List(nullptr), NumElts(0) {}
unsigned size() const { return NumElts; }
bool empty() const { return NumElts == 0; }
@@ -79,7 +79,7 @@
using ObjCList<ObjCProtocolDecl>::set;
public:
- ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { }
+ ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
typedef const SourceLocation *loc_iterator;
loc_iterator loc_begin() const { return Locations; }
@@ -238,15 +238,16 @@
objcDeclQualifier(OBJC_TQ_None),
RelatedResultType(HasRelatedResultType),
SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
- MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(0),
- NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
+ MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr),
+ NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
+ CmdDecl(nullptr) {
setImplicit(isImplicitlyDeclared);
}
/// \brief A definition will return its interface declaration.
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
- ObjCMethodDecl *getNextRedeclaration() override;
+ ObjCMethodDecl *getNextRedeclarationImpl() override;
public:
static ObjCMethodDecl *
@@ -470,7 +471,7 @@
/// the method declaration that was marked with the designated initializer
/// attribute.
bool isDesignatedInitializerForTheInterface(
- const ObjCMethodDecl **InitMethod = 0) const;
+ const ObjCMethodDecl **InitMethod = nullptr) const;
/// \brief Determine whether this method has a body.
bool hasBody() const override { return Body.isValid(); }
@@ -733,9 +734,9 @@
InheritedDesignatedInitializers(IDI_Unknown) { }
};
- ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
- SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
- bool isInternal);
+ ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
+ IdentifierInfo *Id, SourceLocation CLoc,
+ ObjCInterfaceDecl *PrevDecl, bool IsInternal);
void LoadExternalDefinition() const;
@@ -755,8 +756,8 @@
void allocateDefinitionData();
typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
- ObjCInterfaceDecl *getNextRedeclaration() override {
- return RedeclLink.getNext();
+ ObjCInterfaceDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
ObjCInterfaceDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
@@ -773,7 +774,7 @@
SourceLocation ClassLoc = SourceLocation(),
bool isInternal = false);
- static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
SourceRange getSourceRange() const override LLVM_READONLY {
if (isThisDeclarationADefinition())
@@ -972,8 +973,9 @@
///
/// \param InitMethod if non-null and the function returns true, it receives
/// the method that was marked as a designated initializer.
- bool isDesignatedInitializer(Selector Sel,
- const ObjCMethodDecl **InitMethod = 0) const;
+ bool
+ isDesignatedInitializer(Selector Sel,
+ const ObjCMethodDecl **InitMethod = nullptr) const;
/// \brief Determine whether this particular declaration of this class is
/// actually also a definition.
@@ -1002,14 +1004,14 @@
/// has been forward-declared (with \@class) but not yet defined (with
/// \@interface).
ObjCInterfaceDecl *getDefinition() {
- return hasDefinition()? Data.getPointer()->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
/// \brief Retrieve the definition of this class, or NULL if this class
/// has been forward-declared (with \@class) but not yet defined (with
/// \@interface).
const ObjCInterfaceDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
/// \brief Starts the definition of this Objective-C class, taking it from
@@ -1019,7 +1021,7 @@
ObjCInterfaceDecl *getSuperClass() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
@@ -1051,7 +1053,7 @@
typedef std::ptrdiff_t difference_type;
typedef std::input_iterator_tag iterator_category;
- filtered_category_iterator() : Current(0) { }
+ filtered_category_iterator() : Current(nullptr) { }
explicit filtered_category_iterator(ObjCCategoryDecl *Current)
: Current(Current)
{
@@ -1225,7 +1227,7 @@
ObjCCategoryDecl* getCategoryListRaw() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
@@ -1249,7 +1251,7 @@
/// super class of the specified interface class.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
// If RHS is derived from LHS it is OK; else it is not OK.
- while (I != NULL) {
+ while (I != nullptr) {
if (declaresSameEntity(this, I))
return true;
@@ -1281,7 +1283,7 @@
ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
bool shallowCategoryLookup = false,
bool followSuper = true,
- const ObjCCategoryDecl *C = 0) const;
+ const ObjCCategoryDecl *C = nullptr) const;
/// Lookup an instance method for a given selector.
ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
@@ -1398,14 +1400,14 @@
bool synthesized)
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
/*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
+ NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW = NULL,
+ AccessControl ac, Expr *BW = nullptr,
bool synthesized=false);
static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1452,7 +1454,7 @@
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, Expr *BW)
: FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
- /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
+ /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
public:
@@ -1522,15 +1524,15 @@
return *Data.getPointer();
}
- ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
+ ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
SourceLocation nameLoc, SourceLocation atStartLoc,
ObjCProtocolDecl *PrevDecl);
void allocateDefinitionData();
typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
- ObjCProtocolDecl *getNextRedeclaration() override {
- return RedeclLink.getNext();
+ ObjCProtocolDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
ObjCProtocolDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
@@ -1547,7 +1549,7 @@
ObjCProtocolDecl *PrevDecl);
static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
+
const ObjCProtocolList &getReferencedProtocols() const {
assert(hasDefinition() && "No definition available!");
return data().ReferencedProtocols;
@@ -1634,12 +1636,12 @@
/// \brief Retrieve the definition of this protocol, if any.
ObjCProtocolDecl *getDefinition() {
- return hasDefinition()? Data.getPointer()->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
/// \brief Retrieve the definition of this protocol, if any.
const ObjCProtocolDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
/// \brief Determine whether this particular declaration is also the
@@ -1728,7 +1730,7 @@
SourceLocation IvarLBraceLoc=SourceLocation(),
SourceLocation IvarRBraceLoc=SourceLocation())
: ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
- ClassInterface(IDecl), NextClassCategory(0),
+ ClassInterface(IDecl), NextClassCategory(nullptr),
CategoryNameLoc(CategoryNameLoc),
IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
}
@@ -1794,7 +1796,7 @@
return NextClassCategory;
}
- bool IsClassExtension() const { return getIdentifier() == 0; }
+ bool IsClassExtension() const { return getIdentifier() == nullptr; }
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
@@ -1839,7 +1841,8 @@
ObjCInterfaceDecl *classInterface,
SourceLocation nameLoc, SourceLocation atStartLoc)
: ObjCContainerDecl(DK, DC,
- classInterface? classInterface->getIdentifier() : 0,
+ classInterface? classInterface->getIdentifier()
+ : nullptr,
nameLoc, atStartLoc),
ClassInterface(classInterface) {}
@@ -1973,11 +1976,14 @@
/// \@end
/// @endcode
///
-/// Typically, instance variables are specified in the class interface,
-/// *not* in the implementation. Nevertheless (for legacy reasons), we
-/// allow instance variables to be specified in the implementation. When
-/// specified, they need to be *identical* to the interface.
+/// In a non-fragile runtime, instance variables can appear in the class
+/// interface, class extensions (nameless categories), and in the implementation
+/// itself, as well as being synthesized as backing storage for properties.
///
+/// In a fragile runtime, instance variables are specified in the class
+/// interface, \em not in the implementation. Nevertheless (for legacy reasons),
+/// we allow instance variables to be specified in the implementation. When
+/// specified, they need to be \em identical to the interface.
class ObjCImplementationDecl : public ObjCImplDecl {
void anchor() override;
/// Implementation Class's super class.
@@ -2010,7 +2016,7 @@
: ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
IvarRBraceLoc(IvarRBraceLoc),
- IvarInitializers(0), NumIvarInitializers(0),
+ IvarInitializers(nullptr), NumIvarInitializers(0),
HasNonZeroConstructors(false), HasDestructors(false) {}
public:
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2220,7 +2226,9 @@
PropertyImplementation(None),
GetterName(Selector()),
SetterName(Selector()),
- GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
+ GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
+ PropertyIvarDecl(nullptr) {}
+
public:
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -2384,7 +2392,7 @@
SourceLocation ivarLoc)
: Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
- GetterCXXConstructor(0), SetterCXXAssignment(0) {
+ GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
assert (PK == Dynamic || PropertyIvarDecl);
}
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index d55582a..483ea79 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -232,13 +232,15 @@
// This is probably never used.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
+ : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
+ TemplateParams(nullptr) {}
// Construct a template decl with the given name and parameters.
// Used when there is not templated element (tt-params, alias?).
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
+ : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
+ TemplateParams(Params) {}
// Construct a template decl with name, parameters, and templated element.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -274,8 +276,8 @@
/// \brief Initialize the underlying templated declaration and
/// template parameters.
void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
- assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
- assert(TemplateParams == 0 && "TemplateParams already set!");
+ assert(!TemplatedDecl && "TemplatedDecl already set!");
+ assert(!TemplateParams && "TemplateParams already set!");
TemplatedDecl = templatedDecl;
TemplateParams = templateParams;
}
@@ -530,8 +532,8 @@
public Redeclarable<RedeclarableTemplateDecl>
{
typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
- RedeclarableTemplateDecl *getNextRedeclaration() override {
- return RedeclLink.getNext();
+ RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
RedeclarableTemplateDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
@@ -599,7 +601,7 @@
void *&InsertPos);
struct CommonBase {
- CommonBase() : InstantiatedFromMember(0, false) { }
+ CommonBase() : InstantiatedFromMember(nullptr, false) { }
/// \brief The template from which this was most
/// directly instantiated (or null).
@@ -622,10 +624,11 @@
virtual CommonBase *newCommon(ASTContext &C) const = 0;
// Construct a template decl with name, parameters, and templated element.
- RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { }
+ RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl)
+ : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
+ Common() {}
public:
template <class decl_type> friend class RedeclarableTemplate;
@@ -773,9 +776,11 @@
uint32_t *LazySpecializations;
};
- FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+ FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
+ Decl) {}
CommonBase *newCommon(ASTContext &C) const override;
@@ -972,7 +977,7 @@
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const { return DefaultArgument != 0; }
+ bool hasDefaultArgument() const { return DefaultArgument != nullptr; }
/// \brief Retrieve the default argument, if any.
QualType getDefaultArgument() const { return DefaultArgument->getType(); }
@@ -997,7 +1002,7 @@
/// \brief Removes the default argument of this template parameter.
void removeDefaultArgument() {
- DefaultArgument = 0;
+ DefaultArgument = nullptr;
InheritedDefault = false;
}
@@ -1051,7 +1056,7 @@
IdentifierInfo *Id, QualType T,
bool ParameterPack, TypeSourceInfo *TInfo)
: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
+ TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
ParameterPack(ParameterPack), ExpandedParameterPack(false),
NumExpandedTypes(0)
{ }
@@ -1096,7 +1101,7 @@
/// \brief Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const {
- return DefaultArgumentAndInherited.getPointer() != 0;
+ return DefaultArgumentAndInherited.getPointer() != nullptr;
}
/// \brief Retrieve the default argument, if any.
@@ -1123,7 +1128,7 @@
/// \brief Removes the default argument of this template parameter.
void removeDefaultArgument() {
- DefaultArgumentAndInherited.setPointer(0);
+ DefaultArgumentAndInherited.setPointer(nullptr);
DefaultArgumentAndInherited.setInt(false);
}
@@ -1410,7 +1415,7 @@
SourceLocation TemplateKeywordLoc;
ExplicitSpecializationInfo()
- : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+ : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
};
/// \brief Further info for explicit template specialization/instantiation.
@@ -1436,7 +1441,7 @@
unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl);
- explicit ClassTemplateSpecializationDecl(Kind DK);
+ explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
public:
static ClassTemplateSpecializationDecl *
@@ -1595,7 +1600,7 @@
/// \brief Gets the type of this specialization as it was written by
/// the user, if it was so written.
TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+ return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
}
/// \brief Gets the location of the extern keyword, if present.
@@ -1674,9 +1679,10 @@
const ASTTemplateArgumentListInfo *ArgsAsWritten,
ClassTemplatePartialSpecializationDecl *PrevDecl);
- ClassTemplatePartialSpecializationDecl()
- : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
- TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { }
+ ClassTemplatePartialSpecializationDecl(ASTContext &C)
+ : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
+ TemplateParams(nullptr), ArgsAsWritten(nullptr),
+ InstantiatedFromMember(nullptr, false) {}
public:
static ClassTemplatePartialSpecializationDecl *
@@ -1835,13 +1841,10 @@
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations();
- ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
-
- ClassTemplateDecl(EmptyShell Empty)
- : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
- DeclarationName(), 0, 0) { }
+ ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
CommonBase *newCommon(ASTContext &C) const override;
@@ -2042,7 +2045,7 @@
FriendTemplateDecl(EmptyShell Empty)
: Decl(Decl::FriendTemplate, Empty),
NumParams(0),
- Params(0)
+ Params(nullptr)
{}
public:
@@ -2102,9 +2105,11 @@
protected:
typedef CommonBase Common;
- TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
+ TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
+ Decl) {}
CommonBase *newCommon(ASTContext &C) const override;
@@ -2275,7 +2280,7 @@
SourceLocation TemplateKeywordLoc;
ExplicitSpecializationInfo()
- : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+ : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
};
/// \brief Further info for explicit template specialization/instantiation.
@@ -2294,14 +2299,14 @@
unsigned SpecializationKind : 3;
protected:
- VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC,
+ VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
VarTemplateDecl *SpecializedTemplate,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, const TemplateArgument *Args,
unsigned NumArgs);
- explicit VarTemplateSpecializationDecl(Kind DK);
+ explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
public:
static VarTemplateSpecializationDecl *
@@ -2456,7 +2461,7 @@
/// \brief Gets the type of this specialization as it was written by
/// the user, if it was so written.
TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+ return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
}
/// \brief Gets the location of the extern keyword, if present.
@@ -2529,9 +2534,10 @@
StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
const ASTTemplateArgumentListInfo *ArgInfos);
- VarTemplatePartialSpecializationDecl()
- : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization),
- TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {}
+ VarTemplatePartialSpecializationDecl(ASTContext &Context)
+ : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
+ TemplateParams(nullptr), ArgsAsWritten(nullptr),
+ InstantiatedFromMember(nullptr, false) {}
public:
static VarTemplatePartialSpecializationDecl *
@@ -2672,13 +2678,10 @@
llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations();
- VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {}
-
- VarTemplateDecl(EmptyShell Empty)
- : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(),
- DeclarationName(), 0, 0) {}
+ VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
CommonBase *newCommon(ASTContext &C) const override;
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 00766c2..3076b30 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -29,6 +29,7 @@
class DeclarationNameExtra;
class IdentifierInfo;
class MultiKeywordSelector;
+ enum OverloadedOperatorKind : int;
class QualType;
class Type;
class TypeSourceInfo;
@@ -116,20 +117,20 @@
NameKind Kind = getNameKind();
if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
- return 0;
+ return nullptr;
}
/// getAsCXXOperatorIdName
CXXOperatorIdName *getAsCXXOperatorIdName() const {
if (getNameKind() == CXXOperatorName)
return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
- return 0;
+ return nullptr;
}
CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
if (getNameKind() == CXXLiteralOperatorName)
return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
- return 0;
+ return nullptr;
}
// Construct a declaration name from the name of a C++ constructor,
@@ -221,7 +222,7 @@
IdentifierInfo *getAsIdentifierInfo() const {
if (isIdentifier())
return reinterpret_cast<IdentifierInfo *>(Ptr);
- return 0;
+ return nullptr;
}
/// getAsOpaqueInteger - Get the representation of this declaration
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 0c783d2..63047ec 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -123,7 +123,7 @@
/// An iterator over the dependent diagnostics in a dependent context.
class DeclContext::ddiag_iterator {
public:
- ddiag_iterator() : Ptr(0) {}
+ ddiag_iterator() : Ptr(nullptr) {}
explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
typedef DependentDiagnostic *value_type;
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index adc8308..e0b3c05 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -293,8 +293,8 @@
/// \param Loc [in,out] - A source location which *may* be filled
/// in with the location of the expression making this a
/// non-modifiable lvalue, if specified.
- isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
- SourceLocation *Loc = 0) const;
+ isModifiableLvalueResult
+ isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
/// \brief The return type of classify(). Represents the C++11 expression
/// taxonomy.
@@ -372,7 +372,7 @@
/// lvalues and xvalues are collectively referred to as glvalues, while
/// prvalues and xvalues together form rvalues.
Classification Classify(ASTContext &Ctx) const {
- return ClassifyImpl(Ctx, 0);
+ return ClassifyImpl(Ctx, nullptr);
}
/// \brief ClassifyModifiable - Classify this expression according to the
@@ -483,10 +483,10 @@
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
- SourceLocation *Loc = 0,
+ SourceLocation *Loc = nullptr,
bool isEvaluated = true) const;
bool isIntegerConstantExpr(const ASTContext &Ctx,
- SourceLocation *Loc = 0) const;
+ SourceLocation *Loc = nullptr) const;
/// isCXX98IntegralConstantExpr - Return true if this expression is an
/// integral constant expression in C++98. Can only be used in C++.
@@ -497,8 +497,8 @@
///
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
- bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = 0,
- SourceLocation *Loc = 0) const;
+ bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = nullptr,
+ SourceLocation *Loc = nullptr) const;
/// isPotentialConstantExpr - Return true if this function's definition
/// might be usable in a constant expression in C++11, if it were marked
@@ -520,7 +520,10 @@
/// isConstantInitializer - Returns true if this expression can be emitted to
/// IR as a constant, and thus can be used as a constant initializer in C.
- bool isConstantInitializer(ASTContext &Ctx, bool ForRef) const;
+ /// If this expression is not constant and Culprit is non-null,
+ /// it is used to store the address of first non constant expr.
+ bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
+ const Expr **Culprit = nullptr) const;
/// EvalStatus is a struct with detailed info about an evaluation in progress.
struct EvalStatus {
@@ -537,7 +540,7 @@
/// expression *is* a constant expression, no notes will be produced.
SmallVectorImpl<PartialDiagnosticAt> *Diag;
- EvalStatus() : HasSideEffects(false), Diag(0) {}
+ EvalStatus() : HasSideEffects(false), Diag(nullptr) {}
// hasSideEffects - Return true if the evaluated expression has
// side effects.
@@ -594,7 +597,7 @@
/// integer. This must be called on an expression that constant folds to an
/// integer.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
- SmallVectorImpl<PartialDiagnosticAt> *Diag=0) const;
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
void EvaluateForOverflow(const ASTContext &Ctx) const;
@@ -699,6 +702,9 @@
/// or CastExprs, returning their operand.
Expr *IgnoreParenCasts() LLVM_READONLY;
+ /// Ignore casts. Strip off any CastExprs, returning their operand.
+ Expr *IgnoreCasts() LLVM_READONLY;
+
/// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
/// any ParenExpr or ImplicitCastExprs, returning their operand.
Expr *IgnoreParenImpCasts() LLVM_READONLY;
@@ -760,6 +766,11 @@
const Expr *IgnoreParenCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenCasts();
}
+ /// Strip off casts, but keep parentheses.
+ const Expr *IgnoreCasts() const LLVM_READONLY {
+ return const_cast<Expr*>(this)->IgnoreCasts();
+ }
+
const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
}
@@ -806,7 +817,7 @@
public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
ExprObjectKind OK = OK_Ordinary,
- Expr *SourceExpr = 0)
+ Expr *SourceExpr = nullptr)
: Expr(OpaqueValueExprClass, T, VK, OK,
T->isDependentType(),
T->isDependentType() ||
@@ -950,25 +961,19 @@
computeDependence(D->getASTContext());
}
- static DeclRefExpr *Create(const ASTContext &Context,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D,
- bool isEnclosingLocal,
- SourceLocation NameLoc,
- QualType T, ExprValueKind VK,
- NamedDecl *FoundD = 0,
- const TemplateArgumentListInfo *TemplateArgs = 0);
+ static DeclRefExpr *
+ Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+ SourceLocation NameLoc, QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = nullptr,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr);
- static DeclRefExpr *Create(const ASTContext &Context,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D,
- bool isEnclosingLocal,
- const DeclarationNameInfo &NameInfo,
- QualType T, ExprValueKind VK,
- NamedDecl *FoundD = 0,
- const TemplateArgumentListInfo *TemplateArgs = 0);
+ static DeclRefExpr *
+ Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+ const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = nullptr,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr);
/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(const ASTContext &Context,
@@ -998,7 +1003,7 @@
/// that precedes the name. Otherwise, returns NULL.
NestedNameSpecifier *getQualifier() const {
if (!hasQualifier())
- return 0;
+ return nullptr;
return getInternalQualifierLoc().getNestedNameSpecifier();
}
@@ -1034,7 +1039,7 @@
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
if (!hasTemplateKWAndArgsInfo())
- return 0;
+ return nullptr;
if (hasFoundDecl())
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
@@ -1098,7 +1103,7 @@
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -1113,7 +1118,7 @@
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
- return 0;
+ return nullptr;
return getExplicitTemplateArgs().getTemplateArgs();
}
@@ -1164,6 +1169,7 @@
Function,
LFunction, // Same as Function, but as wide string.
FuncDName,
+ FuncSig,
PrettyFunction,
/// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
@@ -1875,7 +1881,7 @@
explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
: Expr(OffsetOfExprClass, EmptyShell()),
- TSInfo(0), NumComps(numComps), NumExprs(numExprs) {}
+ TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
public:
@@ -2226,6 +2232,13 @@
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
+ typedef llvm::iterator_range<arg_iterator> arg_range;
+ typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+ arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+ arg_const_range arguments() const {
+ return arg_const_range(arg_begin(), arg_end());
+ }
arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
arg_iterator arg_end() {
@@ -2405,14 +2418,14 @@
/// \brief Determines whether this member expression actually had
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
/// x->Base::foo.
- bool hasQualifier() const { return getQualifier() != 0; }
+ bool hasQualifier() const { return getQualifier() != nullptr; }
/// \brief If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
NestedNameSpecifier *getQualifier() const {
if (!HasQualifierOrFoundDecl)
- return 0;
+ return nullptr;
return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier();
}
@@ -2430,7 +2443,7 @@
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
if (!HasTemplateKWAndArgsInfo)
- return 0;
+ return nullptr;
if (!HasQualifierOrFoundDecl)
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1);
@@ -2498,7 +2511,7 @@
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -2506,7 +2519,7 @@
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
- return 0;
+ return nullptr;
return getExplicitTemplateArgs().getTemplateArgs();
}
@@ -3433,7 +3446,7 @@
/// \brief Build an empty vector-shuffle expression.
explicit ShuffleVectorExpr(EmptyShell Empty)
- : Expr(ShuffleVectorExprClass, Empty), SubExprs(0) { }
+ : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
@@ -3843,8 +3856,8 @@
return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
}
void setInitializedFieldInUnion(FieldDecl *FD) {
- assert((FD == 0
- || getInitializedFieldInUnion() == 0
+ assert((FD == nullptr
+ || getInitializedFieldInUnion() == nullptr
|| getInitializedFieldInUnion() == FD)
&& "Only one field of a union may be initialized at a time!");
ArrayFillerOrUnionFieldInit = FD;
@@ -3867,10 +3880,10 @@
bool isSemanticForm() const { return AltForm.getInt(); }
InitListExpr *getSemanticForm() const {
- return isSemanticForm() ? 0 : AltForm.getPointer();
+ return isSemanticForm() ? nullptr : AltForm.getPointer();
}
InitListExpr *getSyntacticForm() const {
- return isSemanticForm() ? AltForm.getPointer() : 0;
+ return isSemanticForm() ? AltForm.getPointer() : nullptr;
}
void setSyntacticForm(InitListExpr *Init) {
@@ -3972,7 +3985,7 @@
explicit DesignatedInitExpr(unsigned NumSubExprs)
: Expr(DesignatedInitExprClass, EmptyShell()),
- NumDesignators(0), NumSubExprs(NumSubExprs), Designators(0) { }
+ NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
public:
/// A field designator, e.g., ".x".
@@ -4069,7 +4082,7 @@
FieldDecl *getField() const {
assert(Kind == FieldDesignator && "Only valid on a field designator");
if (Field.NameOrField & 0x01)
- return 0;
+ return nullptr;
else
return reinterpret_cast<FieldDecl *>(Field.NameOrField);
}
@@ -4661,7 +4674,7 @@
/// Return the result-bearing expression, or null if there is none.
Expr *getResultExpr() {
if (PseudoObjectExprBits.ResultIndex == 0)
- return 0;
+ return nullptr;
return getSubExprsBuffer()[PseudoObjectExprBits.ResultIndex];
}
const Expr *getResultExpr() const {
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6ed55ca..4403b08 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -20,7 +20,7 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/Lambda.h"
+#include "clang/AST/LambdaCapture.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/Support/Compiler.h"
@@ -486,7 +486,7 @@
Stmt *SubExpr;
CXXStdInitializerListExpr(EmptyShell Empty)
- : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(0) {}
+ : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
public:
CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
@@ -553,9 +553,9 @@
CXXTypeidExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXTypeidExprClass, Empty) {
if (isExpr)
- Operand = (Expr*)0;
+ Operand = (Expr*)nullptr;
else
- Operand = (TypeSourceInfo*)0;
+ Operand = (TypeSourceInfo*)nullptr;
}
/// Determine whether this typeid has a type operand which is potentially
@@ -692,9 +692,9 @@
CXXUuidofExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXUuidofExprClass, Empty) {
if (isExpr)
- Operand = (Expr*)0;
+ Operand = (Expr*)nullptr;
else
- Operand = (TypeSourceInfo*)0;
+ Operand = (TypeSourceInfo*)nullptr;
}
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
@@ -738,7 +738,7 @@
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
/// a single GUID.
static UuidAttr *GetUuidAttrOfType(QualType QT,
- bool *HasMultipleGUIDsPtr = 0);
+ bool *HasMultipleGUIDsPtr = nullptr);
// Iterators
child_range children() {
@@ -832,7 +832,7 @@
SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
- if (getSubExpr() == 0)
+ if (!getSubExpr())
return ThrowLoc;
return getSubExpr()->getLocEnd();
}
@@ -1031,7 +1031,7 @@
public:
CXXBindTemporaryExpr(EmptyShell Empty)
- : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
+ : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
Expr* SubExpr);
@@ -1094,18 +1094,18 @@
/// \brief Construct an empty C++ construction expression.
CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(false),
+ : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0), Args(0)
+ ZeroInitialization(false), ConstructKind(0), Args(nullptr)
{ }
public:
/// \brief Construct an empty C++ construction expression.
explicit CXXConstructExpr(EmptyShell Empty)
- : Expr(CXXConstructExprClass, Empty), Constructor(0),
+ : Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
NumArgs(0), Elidable(false), HadMultipleCandidates(false),
ListInitialization(false), ZeroInitialization(false),
- ConstructKind(0), Args(0)
+ ConstructKind(0), Args(nullptr)
{ }
static CXXConstructExpr *Create(const ASTContext &C, QualType T,
@@ -1310,18 +1310,6 @@
/// includes an initializing expression (rather than capturing a variable),
/// and which can never occur implicitly.
class LambdaExpr : public Expr {
- enum {
- /// \brief Flag used by the Capture class to indicate that the given
- /// capture was implicit.
- Capture_Implicit = 0x01,
-
- /// \brief Flag used by the Capture class to indicate that the
- /// given capture was by-copy.
- ///
- /// This includes the case of a non-reference init-capture.
- Capture_ByCopy = 0x02
- };
-
/// \brief The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
@@ -1360,93 +1348,8 @@
// expression, along with the index variables used to initialize by-copy
// array captures.
-public:
- /// \brief Describes the capture of a variable or of \c this, or of a
- /// C++1y init-capture.
- class Capture {
- llvm::PointerIntPair<Decl *, 2> DeclAndBits;
- SourceLocation Loc;
- SourceLocation EllipsisLoc;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- public:
- /// \brief Create a new capture of a variable or of \c this.
- ///
- /// \param Loc The source location associated with this capture.
- ///
- /// \param Kind The kind of capture (this, byref, bycopy), which must
- /// not be init-capture.
- ///
- /// \param Implicit Whether the capture was implicit or explicit.
- ///
- /// \param Var The local variable being captured, or null if capturing
- /// \c this.
- ///
- /// \param EllipsisLoc The location of the ellipsis (...) for a
- /// capture that is a pack expansion, or an invalid source
- /// location to indicate that this is not a pack expansion.
- Capture(SourceLocation Loc, bool Implicit,
- LambdaCaptureKind Kind, VarDecl *Var = 0,
- SourceLocation EllipsisLoc = SourceLocation());
+ typedef LambdaCapture Capture;
- /// \brief Determine the kind of capture.
- LambdaCaptureKind getCaptureKind() const;
-
- /// \brief Determine whether this capture handles the C++ \c this
- /// pointer.
- bool capturesThis() const { return DeclAndBits.getPointer() == 0; }
-
- /// \brief Determine whether this capture handles a variable.
- bool capturesVariable() const {
- return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this is an init-capture.
- bool isInitCapture() const {
- return capturesVariable() && getCapturedVar()->isInitCapture();
- }
-
- /// \brief Retrieve the declaration of the local variable being
- /// captured.
- ///
- /// This operation is only valid if this capture is a variable capture
- /// (other than a capture of \c this).
- VarDecl *getCapturedVar() const {
- assert(capturesVariable() && "No variable available for 'this' capture");
- return cast<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this was an implicit capture (not
- /// written between the square brackets introducing the lambda).
- bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
-
- /// \brief Determine whether this was an explicit capture (written
- /// between the square brackets introducing the lambda).
- bool isExplicit() const { return !isImplicit(); }
-
- /// \brief Retrieve the source location of the capture.
- ///
- /// For an explicit capture, this returns the location of the
- /// explicit capture in the source. For an implicit capture, this
- /// returns the location at which the variable or \c this was first
- /// used.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Determine whether this capture is a pack expansion,
- /// which captures a function parameter pack.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-
- /// \brief Retrieve the location of the ellipsis for a capture
- /// that is a pack expansion.
- SourceLocation getEllipsisLoc() const {
- assert(isPackExpansion() && "No ellipsis location for a non-expansion");
- return EllipsisLoc;
- }
- };
-
-private:
/// \brief Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
@@ -1465,7 +1368,7 @@
: Expr(LambdaExprClass, Empty),
NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
ExplicitResultType(false), HasArrayIndexVars(true) {
- getStoredStmts()[NumCaptures] = 0;
+ getStoredStmts()[NumCaptures] = nullptr;
}
Stmt **getStoredStmts() const {
@@ -1523,6 +1426,12 @@
/// both implicit and explicit.
typedef const Capture *capture_iterator;
+ /// \brief An iterator over a range of lambda captures.
+ typedef llvm::iterator_range<capture_iterator> capture_range;
+
+ /// \brief Retrieve this lambda's captures.
+ capture_range captures() const;
+
/// \brief Retrieve an iterator pointing to the first lambda capture.
capture_iterator capture_begin() const;
@@ -1532,6 +1441,9 @@
/// \brief Determine the number of captures in this lambda.
unsigned capture_size() const { return NumCaptures; }
+
+ /// \brief Retrieve this lambda's explicit captures.
+ capture_range explicit_captures() const;
/// \brief Retrieve an iterator pointing to the first explicit
/// lambda capture.
@@ -1541,6 +1453,9 @@
/// explicit lambda captures.
capture_iterator explicit_capture_end() const;
+ /// \brief Retrieve this lambda's implicit captures.
+ capture_range implicit_captures() const;
+
/// \brief Retrieve an iterator pointing to the first implicit
/// lambda capture.
capture_iterator implicit_capture_begin() const;
@@ -1720,7 +1635,7 @@
QualType ty, TypeSourceInfo *AllocatedTypeInfo,
SourceRange Range, SourceRange directInitRange);
explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
+ : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
void AllocateArgsArray(const ASTContext &C, bool isArray,
unsigned numPlaceArgs, bool hasInitializer);
@@ -1754,10 +1669,10 @@
bool isArray() const { return Array; }
Expr *getArraySize() {
- return Array ? cast<Expr>(SubExprs[0]) : 0;
+ return Array ? cast<Expr>(SubExprs[0]) : nullptr;
}
const Expr *getArraySize() const {
- return Array ? cast<Expr>(SubExprs[0]) : 0;
+ return Array ? cast<Expr>(SubExprs[0]) : nullptr;
}
unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
@@ -1791,10 +1706,10 @@
/// \brief The initializer of this new-expression.
Expr *getInitializer() {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+ return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
}
const Expr *getInitializer() const {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+ return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
}
/// \brief Returns the CXXConstructExpr from this new-expression, or null.
@@ -1888,7 +1803,8 @@
ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
explicit CXXDeleteExpr(EmptyShell Shell)
- : Expr(CXXDeleteExprClass, Shell), OperatorDelete(0), Argument(0) { }
+ : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
+ Argument(nullptr) {}
bool isGlobalDelete() const { return GlobalDelete; }
bool isArrayForm() const { return ArrayForm; }
@@ -2020,7 +1936,7 @@
explicit CXXPseudoDestructorExpr(EmptyShell Shell)
: Expr(CXXPseudoDestructorExprClass, Shell),
- Base(0), IsArrow(false), QualifierLoc(), ScopeType(0) { }
+ Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
Expr *getBase() const { return cast<Expr>(Base); }
@@ -2381,7 +2297,7 @@
bool KnownContainsUnexpandedParameterPack);
OverloadExpr(StmtClass K, EmptyShell Empty)
- : Expr(K, Empty), QualifierLoc(), Results(0), NumResults(0),
+ : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
HasTemplateKWAndArgsInfo(false) { }
void initializeResults(const ASTContext &C,
@@ -2431,6 +2347,9 @@
decls_iterator decls_end() const {
return UnresolvedSetIterator(Results + NumResults);
}
+ llvm::iterator_range<decls_iterator> decls() const {
+ return llvm::iterator_range<decls_iterator>(decls_begin(), decls_end());
+ }
/// \brief Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return NumResults; }
@@ -2511,7 +2430,7 @@
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -2568,7 +2487,7 @@
UnresolvedLookupExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), Overloaded(false), NamingClass(0)
+ RequiresADL(false), Overloaded(false), NamingClass(nullptr)
{}
friend class ASTStmtReader;
@@ -2583,7 +2502,7 @@
UnresolvedSetIterator End) {
return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
SourceLocation(), NameInfo,
- ADL, Overloaded, 0, Begin, End);
+ ADL, Overloaded, nullptr, Begin, End);
}
static UnresolvedLookupExpr *Create(const ASTContext &C,
@@ -2658,7 +2577,7 @@
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
@@ -2752,7 +2671,7 @@
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -3028,7 +2947,7 @@
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
@@ -3173,7 +3092,7 @@
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -3275,7 +3194,7 @@
UnresolvedMemberExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false), Base(0) { }
+ HasUnresolvedUsing(false), Base(nullptr) { }
friend class ASTStmtReader;
@@ -3489,7 +3408,7 @@
};
inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
if (isa<UnresolvedLookupExpr>(this))
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>
(cast<UnresolvedLookupExpr>(this) + 1);
@@ -3781,39 +3700,51 @@
/// temporary. When either happens, the expression will also track the
/// declaration which is responsible for the lifetime extension.
class MaterializeTemporaryExpr : public Expr {
-public:
- /// \brief The temporary-generating expression whose value will be
- /// materialized.
- Stmt *Temporary;
+private:
+ struct ExtraState {
+ /// \brief The temporary-generating expression whose value will be
+ /// materialized.
+ Stmt *Temporary;
- /// \brief The declaration which lifetime-extended this reference, if any.
- /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
- const ValueDecl *ExtendingDecl;
+ /// \brief The declaration which lifetime-extended this reference, if any.
+ /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
+ const ValueDecl *ExtendingDecl;
+
+ unsigned ManglingNumber;
+ };
+ llvm::PointerUnion<Stmt *, ExtraState *> State;
friend class ASTStmtReader;
friend class ASTStmtWriter;
+ void initializeExtraState(const ValueDecl *ExtendedBy,
+ unsigned ManglingNumber);
+
public:
MaterializeTemporaryExpr(QualType T, Expr *Temporary,
- bool BoundToLvalueReference,
- const ValueDecl *ExtendedBy)
+ bool BoundToLvalueReference)
: Expr(MaterializeTemporaryExprClass, T,
BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
Temporary->isTypeDependent(), Temporary->isValueDependent(),
Temporary->isInstantiationDependent(),
Temporary->containsUnexpandedParameterPack()),
- Temporary(Temporary), ExtendingDecl(ExtendedBy) {
- }
+ State(Temporary) {}
MaterializeTemporaryExpr(EmptyShell Empty)
: Expr(MaterializeTemporaryExprClass, Empty) { }
+ Stmt *getTemporary() const {
+ return State.is<Stmt *>() ? State.get<Stmt *>()
+ : State.get<ExtraState *>()->Temporary;
+ }
+
/// \brief Retrieve the temporary-generating subexpression whose value will
/// be materialized into a glvalue.
- Expr *GetTemporaryExpr() const { return static_cast<Expr *>(Temporary); }
+ Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
/// \brief Retrieve the storage duration for the materialized temporary.
StorageDuration getStorageDuration() const {
+ const ValueDecl *ExtendingDecl = getExtendingDecl();
if (!ExtendingDecl)
return SD_FullExpression;
// FIXME: This is not necessarily correct for a temporary materialized
@@ -3825,10 +3756,15 @@
/// \brief Get the declaration which triggered the lifetime-extension of this
/// temporary, if any.
- const ValueDecl *getExtendingDecl() const { return ExtendingDecl; }
+ const ValueDecl *getExtendingDecl() const {
+ return State.is<Stmt *>() ? nullptr
+ : State.get<ExtraState *>()->ExtendingDecl;
+ }
- void setExtendingDecl(const ValueDecl *ExtendedBy) {
- ExtendingDecl = ExtendedBy;
+ void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
+
+ unsigned getManglingNumber() const {
+ return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
}
/// \brief Determine whether this materialized temporary is bound to an
@@ -3838,10 +3774,10 @@
}
SourceLocation getLocStart() const LLVM_READONLY {
- return Temporary->getLocStart();
+ return getTemporary()->getLocStart();
}
SourceLocation getLocEnd() const LLVM_READONLY {
- return Temporary->getLocEnd();
+ return getTemporary()->getLocEnd();
}
static bool classof(const Stmt *T) {
@@ -3849,7 +3785,13 @@
}
// Iterators
- child_range children() { return child_range(&Temporary, &Temporary + 1); }
+ child_range children() {
+ if (State.is<Stmt *>())
+ return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
+
+ auto ES = State.get<ExtraState *>();
+ return child_range(&ES->Temporary, &ES->Temporary + 1);
+ }
};
} // end namespace clang
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index fc78e89..817c0cc 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -277,14 +277,14 @@
ExpansionData *getExpansionData() {
if (!HasPackExpansions)
- return 0;
+ return nullptr;
return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
}
const ExpansionData *getExpansionData() const {
if (!HasPackExpansions)
- return 0;
+ return nullptr;
return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
}
@@ -743,7 +743,7 @@
void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
PropertyOrGetter.setPointer(D);
PropertyOrGetter.setInt(false);
- SetterAndMethodRefFlags.setPointer(0);
+ SetterAndMethodRefFlags.setPointer(nullptr);
SetterAndMethodRefFlags.setInt(methRefFlags);
}
void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
@@ -1174,7 +1174,7 @@
if (getReceiverKind() == Instance)
return static_cast<Expr *>(getReceiverPointer());
- return 0;
+ return nullptr;
}
const Expr *getInstanceReceiver() const {
return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
@@ -1201,7 +1201,7 @@
TypeSourceInfo *getClassReceiverTypeInfo() const {
if (getReceiverKind() == Class)
return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
- return 0;
+ return nullptr;
}
void setClassReceiver(TypeSourceInfo *TSInfo) {
@@ -1270,14 +1270,14 @@
if (HasMethod)
return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
- return 0;
+ return nullptr;
}
ObjCMethodDecl *getMethodDecl() {
if (HasMethod)
return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
- return 0;
+ return nullptr;
}
void setMethodDecl(ObjCMethodDecl *MD) {
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 54e96d9..1e8eff3 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -45,7 +45,7 @@
/// no additional processing is required.
ELR_AlreadyLoaded
};
-
+
/// \brief Abstract interface for external sources of AST nodes.
///
/// External AST sources provide AST nodes constructed from some
@@ -54,6 +54,10 @@
/// actual type and declaration nodes, and read parts of declaration
/// contexts.
class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
+ /// Generation number for this external AST source. Must be increased
+ /// whenever we might have added new redeclarations for existing decls.
+ uint32_t CurrentGeneration;
+
/// \brief Whether this AST source also provides information for
/// semantic analysis.
bool SemaSource;
@@ -61,7 +65,7 @@
friend class ExternalSemaSource;
public:
- ExternalASTSource() : SemaSource(false) { }
+ ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
virtual ~ExternalASTSource();
@@ -79,6 +83,11 @@
}
};
+ /// \brief Get the current generation of this AST source. This number
+ /// is incremented each time the AST source lazily extends an existing
+ /// entity.
+ uint32_t getGeneration() const { return CurrentGeneration; }
+
/// \brief Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
///
@@ -138,7 +147,7 @@
virtual void completeVisibleDeclsMap(const DeclContext *DC);
/// \brief Retrieve the module that corresponds to the given module ID.
- virtual Module *getModule(unsigned ID) { return 0; }
+ virtual Module *getModule(unsigned ID) { return nullptr; }
/// \brief Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
@@ -160,7 +169,7 @@
/// \return true if an error occurred
ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
SmallVectorImpl<Decl*> &Result) {
- return FindExternalLexicalDecls(DC, 0, Result);
+ return FindExternalLexicalDecls(DC, nullptr, Result);
}
template <typename DeclTy>
@@ -171,43 +180,50 @@
/// \brief Get the decls that are contained in a file in the Offset/Length
/// range. \p Length can be 0 to indicate a point at \p Offset instead of
- /// a range.
- virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
- SmallVectorImpl<Decl *> &Decls) {}
+ /// a range.
+ virtual void FindFileRegionDecls(FileID File, unsigned Offset,
+ unsigned Length,
+ SmallVectorImpl<Decl *> &Decls);
+
+ /// \brief Gives the external AST source an opportunity to complete
+ /// the redeclaration chain for a declaration. Called each time we
+ /// need the most recent declaration of a declaration after the
+ /// generation count is incremented.
+ virtual void CompleteRedeclChain(const Decl *D);
/// \brief Gives the external AST source an opportunity to complete
/// an incomplete type.
- virtual void CompleteType(TagDecl *Tag) {}
+ virtual void CompleteType(TagDecl *Tag);
/// \brief Gives the external AST source an opportunity to complete an
/// incomplete Objective-C class.
///
/// This routine will only be invoked if the "externally completed" bit is
- /// set on the ObjCInterfaceDecl via the function
+ /// set on the ObjCInterfaceDecl via the function
/// \c ObjCInterfaceDecl::setExternallyCompleted().
- virtual void CompleteType(ObjCInterfaceDecl *Class) { }
+ virtual void CompleteType(ObjCInterfaceDecl *Class);
/// \brief Loads comment ranges.
- virtual void ReadComments() { }
+ virtual void ReadComments();
/// \brief Notify ExternalASTSource that we started deserialization of
/// a decl or type so until FinishedDeserializing is called there may be
/// decls that are initializing. Must be paired with FinishedDeserializing.
///
/// The default implementation of this method is a no-op.
- virtual void StartedDeserializing() { }
+ virtual void StartedDeserializing();
/// \brief Notify ExternalASTSource that we finished the deserialization of
/// a decl or type. Must be paired with StartedDeserializing.
///
/// The default implementation of this method is a no-op.
- virtual void FinishedDeserializing() { }
+ virtual void FinishedDeserializing();
/// \brief Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
///
/// The default implementation of this method is a no-op.
- virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
+ virtual void StartTranslationUnit(ASTConsumer *Consumer);
/// \brief Print any statistics that have been gathered regarding
/// the external AST source.
@@ -243,16 +259,12 @@
/// out according to the ABI.
///
/// \returns true if the record layout was provided, false otherwise.
- virtual bool
- layoutRecordType(const RecordDecl *Record,
- uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets)
- {
- return false;
- }
-
+ virtual bool layoutRecordType(
+ const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
+ llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
+
//===--------------------------------------------------------------------===//
// Queries for performance analysis.
//===--------------------------------------------------------------------===//
@@ -284,6 +296,9 @@
static DeclContextLookupResult
SetNoExternalVisibleDeclsForName(const DeclContext *DC,
DeclarationName Name);
+
+ /// \brief Increment the current generation.
+ uint32_t incrementGeneration(ASTContext &C);
};
/// \brief A lazy pointer to an AST node (of base type T) that resides
@@ -354,6 +369,100 @@
}
};
+/// \brief A lazy value (of type T) that is within an AST node of type Owner,
+/// where the value might change in later generations of the external AST
+/// source.
+template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
+struct LazyGenerationalUpdatePtr {
+ /// A cache of the value of this pointer, in the most recent generation in
+ /// which we queried it.
+ struct LazyData {
+ LazyData(ExternalASTSource *Source, T Value)
+ : ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
+ ExternalASTSource *ExternalSource;
+ uint32_t LastGeneration;
+ T LastValue;
+ };
+
+ // Our value is represented as simply T if there is no external AST source.
+ typedef llvm::PointerUnion<T, LazyData*> ValueType;
+ ValueType Value;
+
+ LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
+
+ // Defined in ASTContext.h
+ static ValueType makeValue(const ASTContext &Ctx, T Value);
+
+public:
+ explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
+ : Value(makeValue(Ctx, Value)) {}
+
+ /// Create a pointer that is not potentially updated by later generations of
+ /// the external AST source.
+ enum NotUpdatedTag { NotUpdated };
+ LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
+ : Value(Value) {}
+
+ /// Forcibly set this pointer (which must be lazy) as needing updates.
+ void markIncomplete() {
+ Value.template get<LazyData *>()->LastGeneration = 0;
+ }
+
+ /// Set the value of this pointer, in the current generation.
+ void set(T NewValue) {
+ if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+ LazyVal->LastValue = NewValue;
+ return;
+ }
+ Value = NewValue;
+ }
+
+ /// Set the value of this pointer, for this and all future generations.
+ void setNotUpdated(T NewValue) { Value = NewValue; }
+
+ /// Get the value of this pointer, updating its owner if necessary.
+ T get(Owner O) {
+ if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+ if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
+ LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
+ (LazyVal->ExternalSource->*Update)(O);
+ }
+ return LazyVal->LastValue;
+ }
+ return Value.template get<T>();
+ }
+
+ /// Get the most recently computed value of this pointer without updating it.
+ T getNotUpdated() const {
+ if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
+ return LazyVal->LastValue;
+ return Value.template get<T>();
+ }
+
+ void *getOpaqueValue() { return Value.getOpaqueValue(); }
+ static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
+ return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
+ }
+};
+} // end namespace clang
+
+/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
+/// placed into a PointerUnion.
+namespace llvm {
+template<typename Owner, typename T,
+ void (clang::ExternalASTSource::*Update)(Owner)>
+struct PointerLikeTypeTraits<
+ clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
+ typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
+ static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
+ static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
+ enum {
+ NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
+ };
+};
+}
+
+namespace clang {
/// \brief Represents a lazily-loaded vector of data.
///
/// The lazily-loaded vector of data contains data that is partially loaded
@@ -519,7 +628,7 @@
if (From.Position < 0) {
Loaded.erase(Loaded.end() + From.Position, Loaded.end());
- From = begin(0, true);
+ From = begin(nullptr, true);
}
Local.erase(Local.begin() + From.Position, Local.begin() + To.Position);
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
new file mode 100644
index 0000000..8633c97
--- /dev/null
+++ b/include/clang/AST/LambdaCapture.h
@@ -0,0 +1,123 @@
+//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the LambdaCapture class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H
+#define LLVM_CLANG_AST_LAMBDACAPTURE_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Lambda.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+
+/// \brief Describes the capture of a variable or of \c this, or of a
+/// C++1y init-capture.
+class LambdaCapture {
+ enum {
+ /// \brief Flag used by the Capture class to indicate that the given
+ /// capture was implicit.
+ Capture_Implicit = 0x01,
+
+ /// \brief Flag used by the Capture class to indicate that the
+ /// given capture was by-copy.
+ ///
+ /// This includes the case of a non-reference init-capture.
+ Capture_ByCopy = 0x02
+ };
+
+ llvm::PointerIntPair<Decl *, 2> DeclAndBits;
+ SourceLocation Loc;
+ SourceLocation EllipsisLoc;
+
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+public:
+ /// \brief Create a new capture of a variable or of \c this.
+ ///
+ /// \param Loc The source location associated with this capture.
+ ///
+ /// \param Kind The kind of capture (this, byref, bycopy), which must
+ /// not be init-capture.
+ ///
+ /// \param Implicit Whether the capture was implicit or explicit.
+ ///
+ /// \param Var The local variable being captured, or null if capturing
+ /// \c this.
+ ///
+ /// \param EllipsisLoc The location of the ellipsis (...) for a
+ /// capture that is a pack expansion, or an invalid source
+ /// location to indicate that this is not a pack expansion.
+ LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
+ VarDecl *Var = nullptr,
+ SourceLocation EllipsisLoc = SourceLocation());
+
+ /// \brief Determine the kind of capture.
+ LambdaCaptureKind getCaptureKind() const;
+
+ /// \brief Determine whether this capture handles the C++ \c this
+ /// pointer.
+ bool capturesThis() const { return DeclAndBits.getPointer() == nullptr; }
+
+ /// \brief Determine whether this capture handles a variable.
+ bool capturesVariable() const {
+ return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
+ }
+
+ /// \brief Determine whether this is an init-capture.
+ bool isInitCapture() const {
+ return capturesVariable() && getCapturedVar()->isInitCapture();
+ }
+
+ /// \brief Retrieve the declaration of the local variable being
+ /// captured.
+ ///
+ /// This operation is only valid if this capture is a variable capture
+ /// (other than a capture of \c this).
+ VarDecl *getCapturedVar() const {
+ assert(capturesVariable() && "No variable available for 'this' capture");
+ return cast<VarDecl>(DeclAndBits.getPointer());
+ }
+
+ /// \brief Determine whether this was an implicit capture (not
+ /// written between the square brackets introducing the lambda).
+ bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
+
+ /// \brief Determine whether this was an explicit capture (written
+ /// between the square brackets introducing the lambda).
+ bool isExplicit() const { return !isImplicit(); }
+
+ /// \brief Retrieve the source location of the capture.
+ ///
+ /// For an explicit capture, this returns the location of the
+ /// explicit capture in the source. For an implicit capture, this
+ /// returns the location at which the variable or \c this was first
+ /// used.
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Determine whether this capture is a pack expansion,
+ /// which captures a function parameter pack.
+ bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+
+ /// \brief Retrieve the location of the ellipsis for a capture
+ /// that is a pack expansion.
+ SourceLocation getEllipsisLoc() const {
+ assert(isPackExpansion() && "No ellipsis location for a non-expansion");
+ return EllipsisLoc;
+ }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index 28bcd8b..e740836 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -130,6 +130,7 @@
const ThisAdjustment &ThisAdjustment,
raw_ostream &) = 0;
virtual void mangleReferenceTemporary(const VarDecl *D,
+ unsigned ManglingNumber,
raw_ostream &) = 0;
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
@@ -212,6 +213,21 @@
virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
raw_ostream &) = 0;
+ virtual void mangleCXXRTTIBaseClassDescriptor(
+ const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
+ uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
+
+ virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
+ raw_ostream &Out) = 0;
+ virtual void
+ mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
+ raw_ostream &Out) = 0;
+
+ virtual void
+ mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
+ ArrayRef<const CXXRecordDecl *> BasePath,
+ raw_ostream &Out) = 0;
+
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Microsoft;
}
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index b332b15..fc719bd 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -88,7 +88,8 @@
private:
/// \brief Builds the global specifier.
- NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { }
+ NestedNameSpecifier()
+ : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
/// \brief Copy constructor used internally to clone nested name
/// specifiers.
@@ -160,7 +161,7 @@
if (Prefix.getInt() == StoredIdentifier)
return (IdentifierInfo *)Specifier;
- return 0;
+ return nullptr;
}
/// \brief Retrieve the namespace stored in this nested name
@@ -177,7 +178,7 @@
Prefix.getInt() == StoredTypeSpecWithTemplate)
return (const Type *)Specifier;
- return 0;
+ return nullptr;
}
/// \brief Whether this nested name specifier refers to a dependent
@@ -222,7 +223,7 @@
public:
/// \brief Construct an empty nested-name-specifier.
- NestedNameSpecifierLoc() : Qualifier(0), Data(0) { }
+ NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
/// \brief Construct a nested-name-specifier with source location information
/// from
@@ -344,7 +345,8 @@
public:
NestedNameSpecifierLocBuilder()
- : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
+ : Representation(nullptr), Buffer(nullptr), BufferSize(0),
+ BufferCapacity(0) {}
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
@@ -457,7 +459,7 @@
/// \brief Clear out this builder, and prepare it to build another
/// nested-name-specifier with source-location information.
void Clear() {
- Representation = 0;
+ Representation = nullptr;
BufferSize = 0;
}
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 64b5ce4..2be6882 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -179,7 +179,7 @@
///
OMPIfClause()
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Condition(0) {}
+ LParenLoc(SourceLocation()), Condition(nullptr) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -233,7 +233,7 @@
///
OMPNumThreadsClause()
: OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumThreads(0) {}
+ LParenLoc(SourceLocation()), NumThreads(nullptr) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -289,7 +289,7 @@
///
explicit OMPSafelenClause()
: OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Safelen(0) {}
+ LParenLoc(SourceLocation()), Safelen(nullptr) {}
/// \brief Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -306,6 +306,62 @@
StmtRange children() { return StmtRange(&Safelen, &Safelen + 1); }
};
+/// \brief This represents 'collapse' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp simd collapse(3)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'collapse'
+/// with single expression '3'.
+/// The parameter must be a constant positive integer expression, it specifies
+/// the number of nested loops that should be collapsed into a single iteration
+/// space.
+///
+class OMPCollapseClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Number of for-loops.
+ Stmt *NumForLoops;
+
+ /// \brief Set the number of associated for-loops.
+ void setNumForLoops(Expr *Num) { NumForLoops = Num; }
+
+public:
+ /// \brief Build 'collapse' clause.
+ ///
+ /// \param Num Expression associated with this clause.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ NumForLoops(Num) {}
+
+ /// \brief Build an empty clause.
+ ///
+ explicit OMPCollapseClause()
+ : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Return the number of associated for-loops.
+ Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_collapse;
+ }
+
+ StmtRange children() { return StmtRange(&NumForLoops, &NumForLoops + 1); }
+};
+
/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
///
/// \code
@@ -375,6 +431,76 @@
StmtRange children() { return StmtRange(); }
};
+/// \brief This represents 'proc_bind' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel proc_bind(master)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
+/// clause with kind 'master'.
+///
+class OMPProcBindClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief A kind of the 'proc_bind' clause.
+ OpenMPProcBindClauseKind Kind;
+ /// \brief Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// \brief Set kind of the clause.
+ ///
+ /// \param K Kind of clause.
+ ///
+ void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
+
+ /// \brief Set clause kind location.
+ ///
+ /// \param KLoc Kind location.
+ ///
+ void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+ /// \brief Build 'proc_bind' clause with argument \a A ('master', 'close' or
+ /// 'spread').
+ ///
+ /// \param A Argument of the clause ('master', 'close' or 'spread').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Kind(A), KindKwLoc(ALoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPProcBindClause()
+ : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown),
+ KindKwLoc(SourceLocation()) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns kind of the clause.
+ OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
+
+ /// \brief Returns location of clause kind.
+ SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_proc_bind;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
///
/// \code
@@ -553,6 +679,91 @@
}
};
+/// \brief This represents clause 'linear' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd linear(a,b : 2)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'linear'
+/// with variables 'a', 'b' and linear step '2'.
+///
+class OMPLinearClause : public OMPVarListClause<OMPLinearClause> {
+ friend class OMPClauseReader;
+ /// \brief Location of ':'.
+ SourceLocation ColonLoc;
+
+ /// \brief Sets the linear step for clause.
+ void setStep(Expr *Step) { *varlist_end() = Step; }
+
+ /// \brief Build 'linear' clause with given number of variables \a NumVars.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param NumVars Number of variables.
+ ///
+ OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ unsigned NumVars)
+ : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc,
+ EndLoc, NumVars),
+ ColonLoc(ColonLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param NumVars Number of variables.
+ ///
+ explicit OMPLinearClause(unsigned NumVars)
+ : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ NumVars),
+ ColonLoc(SourceLocation()) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL and a linear step
+ /// \a Step.
+ ///
+ /// \param C AST Context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ /// \param Step Linear step.
+ static OMPLinearClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL, Expr *Step);
+
+ /// \brief Creates an empty clause with the place for \a NumVars variables.
+ ///
+ /// \param C AST context.
+ /// \param NumVars Number of variables.
+ ///
+ static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+ /// \brief Sets the location of ':'.
+ void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+
+ /// \brief Returns linear step.
+ Expr *getStep() { return *varlist_end(); }
+ /// \brief Returns linear step.
+ const Expr *getStep() const { return *varlist_end(); }
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end() + 1));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_linear;
+ }
+};
+
/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
///
/// \code
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
index bd2ebf5..eece851 100644
--- a/include/clang/AST/ParentMap.h
+++ b/include/clang/AST/ParentMap.h
@@ -53,7 +53,7 @@
}
bool hasParent(Stmt* S) const {
- return getParent(S) != 0;
+ return getParent(S) != nullptr;
}
bool isConsumedExpr(Expr *E) const;
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 1a2ce44..d000ae7 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -38,34 +38,24 @@
// using them is responsible for defining macro OPERATOR().
// All unary operators.
-#define UNARYOP_LIST() \
- OPERATOR(PostInc) OPERATOR(PostDec) \
- OPERATOR(PreInc) OPERATOR(PreDec) \
- OPERATOR(AddrOf) OPERATOR(Deref) \
- OPERATOR(Plus) OPERATOR(Minus) \
- OPERATOR(Not) OPERATOR(LNot) \
- OPERATOR(Real) OPERATOR(Imag) \
- OPERATOR(Extension)
+#define UNARYOP_LIST() \
+ OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \
+ OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \
+ OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \
+ OPERATOR(Extension)
// All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
- OPERATOR(PtrMemD) OPERATOR(PtrMemI) \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) \
- OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) \
- OPERATOR(Shr) \
- \
- OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) \
- OPERATOR(GE) OPERATOR(EQ) OPERATOR(NE) \
- OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
- OPERATOR(LAnd) OPERATOR(LOr) \
- \
- OPERATOR(Assign) \
- OPERATOR(Comma)
+#define BINOP_LIST() \
+ OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
+ OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
+ OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
+ OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \
+ OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
// All compound assign operators.
-#define CAO_LIST() \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
- OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
+#define CAO_LIST() \
+ OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
+ OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
namespace clang {
@@ -73,8 +63,11 @@
// invokes CALL_EXPR, which must be a method call, on the derived
// object (s.t. a user of RecursiveASTVisitor can override the method
// in CALL_EXPR).
-#define TRY_TO(CALL_EXPR) \
- do { if (!getDerived().CALL_EXPR) return false; } while (0)
+#define TRY_TO(CALL_EXPR) \
+ do { \
+ if (!getDerived().CALL_EXPR) \
+ return false; \
+ } while (0)
/// \brief A class that does preorder depth-first traversal on the
/// entire Clang AST and visits each node.
@@ -137,11 +130,10 @@
/// to return true, in which case all known implicit and explicit
/// instantiations will be visited at the same time as the pattern
/// from which they were produced.
-template<typename Derived>
-class RecursiveASTVisitor {
+template <typename Derived> class RecursiveASTVisitor {
public:
/// \brief Return a reference to the derived class.
- Derived &getDerived() { return *static_cast<Derived*>(this); }
+ Derived &getDerived() { return *static_cast<Derived *>(this); }
/// \brief Return whether this visitor should recurse into
/// template instantiations.
@@ -252,7 +244,7 @@
/// \brief Recursively visit a lambda capture.
///
/// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaExpr::Capture *C);
+ bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
/// \brief Recursively visit the body of a lambda expression.
///
@@ -267,112 +259,109 @@
// \brief Visit an attribute.
bool VisitAttr(Attr *A) { return true; }
- // Declare Traverse* and empty Visit* for all Attr classes.
+// Declare Traverse* and empty Visit* for all Attr classes.
#define ATTR_VISITOR_DECLS_ONLY
#include "clang/AST/AttrVisitor.inc"
#undef ATTR_VISITOR_DECLS_ONLY
- // ---- Methods on Stmts ----
+// ---- Methods on Stmts ----
- // Declare Traverse*() for all concrete Stmt classes.
+// Declare Traverse*() for all concrete Stmt classes.
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- bool Traverse##CLASS(CLASS *S);
+#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
#include "clang/AST/StmtNodes.inc"
// The above header #undefs ABSTRACT_STMT and STMT upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
bool VisitStmt(Stmt *S) { return true; }
-#define STMT(CLASS, PARENT) \
- bool WalkUpFrom##CLASS(CLASS *S) { \
- TRY_TO(WalkUpFrom##PARENT(S)); \
- TRY_TO(Visit##CLASS(S)); \
- return true; \
- } \
+#define STMT(CLASS, PARENT) \
+ bool WalkUpFrom##CLASS(CLASS *S) { \
+ TRY_TO(WalkUpFrom##PARENT(S)); \
+ TRY_TO(Visit##CLASS(S)); \
+ return true; \
+ } \
bool Visit##CLASS(CLASS *S) { return true; }
#include "clang/AST/StmtNodes.inc"
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
- // operator methods. Unary operators are not classes in themselves
- // (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME) \
- bool TraverseUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnary##NAME(S)); \
- TRY_TO(TraverseStmt(S->getSubExpr())); \
- return true; \
- } \
- bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnaryOperator(S)); \
- TRY_TO(VisitUnary##NAME(S)); \
- return true; \
- } \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+// operator methods. Unary operators are not classes in themselves
+// (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME) \
+ bool TraverseUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnary##NAME(S)); \
+ TRY_TO(TraverseStmt(S->getSubExpr())); \
+ return true; \
+ } \
+ bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnaryOperator(S)); \
+ TRY_TO(VisitUnary##NAME(S)); \
+ return true; \
+ } \
bool VisitUnary##NAME(UnaryOperator *S) { return true; }
UNARYOP_LIST()
#undef OPERATOR
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
- // operator methods. Binary operators are not classes in themselves
- // (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
- bool TraverseBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFromBin##NAME(S)); \
- TRY_TO(TraverseStmt(S->getLHS())); \
- TRY_TO(TraverseStmt(S->getRHS())); \
- return true; \
- } \
- bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
- TRY_TO(VisitBin##NAME(S)); \
- return true; \
- } \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+// operator methods. Binary operators are not classes in themselves
+// (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
+ bool TraverseBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFromBin##NAME(S)); \
+ TRY_TO(TraverseStmt(S->getLHS())); \
+ TRY_TO(TraverseStmt(S->getRHS())); \
+ return true; \
+ } \
+ bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
+ TRY_TO(VisitBin##NAME(S)); \
+ return true; \
+ } \
bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
BINOP_LIST()
#undef OPERATOR
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
- // assignment methods. Compound assignment operators are not
- // classes in themselves (they're all opcodes in
- // CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+// assignment methods. Compound assignment operators are not
+// classes in themselves (they're all opcodes in
+// CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME) \
GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
CAO_LIST()
#undef OPERATOR
#undef GENERAL_BINOP_FALLBACK
- // ---- Methods on Types ----
- // FIXME: revamp to take TypeLoc's rather than Types.
+// ---- Methods on Types ----
+// FIXME: revamp to take TypeLoc's rather than Types.
- // Declare Traverse*() for all concrete Type classes.
+// Declare Traverse*() for all concrete Type classes.
#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- bool Traverse##CLASS##Type(CLASS##Type *T);
+#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
#include "clang/AST/TypeNodes.def"
// The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Type classes.
bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
bool VisitType(Type *T) { return true; }
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
- TRY_TO(WalkUpFrom##BASE(T)); \
- TRY_TO(Visit##CLASS##Type(T)); \
- return true; \
- } \
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
+ TRY_TO(WalkUpFrom##BASE(T)); \
+ TRY_TO(Visit##CLASS##Type(T)); \
+ return true; \
+ } \
bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
#include "clang/AST/TypeNodes.def"
- // ---- Methods on TypeLocs ----
- // FIXME: this currently just calls the matching Type methods
+// ---- Methods on TypeLocs ----
+// FIXME: this currently just calls the matching Type methods
- // Declare Traverse*() for all concrete TypeLoc classes.
+// Declare Traverse*() for all concrete TypeLoc classes.
#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
#include "clang/AST/TypeLocNodes.def"
// The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
@@ -391,34 +380,33 @@
}
bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
- // Note that BASE includes trailing 'Type' which CLASS doesn't.
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
- TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
- TRY_TO(Visit##CLASS##TypeLoc(TL)); \
- return true; \
- } \
+// Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
+ TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
+ TRY_TO(Visit##CLASS##TypeLoc(TL)); \
+ return true; \
+ } \
bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
#include "clang/AST/TypeNodes.def"
- // ---- Methods on Decls ----
+// ---- Methods on Decls ----
- // Declare Traverse*() for all concrete Decl classes.
+// Declare Traverse*() for all concrete Decl classes.
#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
#include "clang/AST/DeclNodes.inc"
// The above header #undefs ABSTRACT_DECL and DECL upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Decl classes.
bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
bool VisitDecl(Decl *D) { return true; }
-#define DECL(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
- TRY_TO(WalkUpFrom##BASE(D)); \
- TRY_TO(Visit##CLASS##Decl(D)); \
- return true; \
- } \
+#define DECL(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
+ TRY_TO(WalkUpFrom##BASE(D)); \
+ TRY_TO(Visit##CLASS##Decl(D)); \
+ return true; \
+ } \
bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
#include "clang/AST/DeclNodes.inc"
@@ -442,12 +430,10 @@
bool TraverseVarHelper(VarDecl *D);
bool TraverseOMPClause(OMPClause *C);
bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
-#define OPENMP_CLAUSE(Name, Class) \
- bool Visit##Class(Class *C);
+#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
#include "clang/Basic/OpenMPKinds.def"
/// \brief Process clauses with list of variables.
- template <typename T>
- void VisitOMPClauseList(T *Node);
+ template <typename T> void VisitOMPClauseList(T *Node);
struct EnqueueJob {
Stmt *S;
@@ -459,7 +445,7 @@
bool dataTraverseNode(Stmt *S, bool &EnqueueChildren);
};
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) {
SmallVector<EnqueueJob, 16> Queue;
@@ -476,7 +462,8 @@
if (getDerived().shouldUseDataRecursionFor(CurrS)) {
if (job.StmtIt == Stmt::child_iterator()) {
bool EnqueueChildren = true;
- if (!dataTraverseNode(CurrS, EnqueueChildren)) return false;
+ if (!dataTraverseNode(CurrS, EnqueueChildren))
+ return false;
if (!EnqueueChildren) {
Queue.pop_back();
continue;
@@ -500,53 +487,57 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
bool &EnqueueChildren) {
- // Dispatch to the corresponding WalkUpFrom* function only if the derived
- // class didn't override Traverse* (and thus the traversal is trivial).
-#define DISPATCH_WALK(NAME, CLASS, VAR) \
- { \
- bool (Derived::*DerivedFn)(CLASS*) = &Derived::Traverse##NAME; \
- bool (Derived::*BaseFn)(CLASS*) = &RecursiveASTVisitor::Traverse##NAME; \
- if (DerivedFn == BaseFn) \
- return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR)); \
- } \
- EnqueueChildren = false; \
- return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR));
+// Dispatch to the corresponding WalkUpFrom* function only if the derived
+// class didn't override Traverse* (and thus the traversal is trivial).
+#define DISPATCH_WALK(NAME, CLASS, VAR) \
+ { \
+ bool (Derived::*DerivedFn)(CLASS *) = &Derived::Traverse##NAME; \
+ bool (Derived::*BaseFn)(CLASS *) = &RecursiveASTVisitor::Traverse##NAME; \
+ if (DerivedFn == BaseFn) \
+ return getDerived().WalkUpFrom##NAME(static_cast<CLASS *>(VAR)); \
+ } \
+ EnqueueChildren = false; \
+ return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR));
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
+#define OPERATOR(NAME) \
+ case BO_##NAME: \
+ DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
- BINOP_LIST()
+ BINOP_LIST()
#undef OPERATOR
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
+#define OPERATOR(NAME) \
+ case BO_##NAME##Assign: \
DISPATCH_WALK(Bin##NAME##Assign, CompoundAssignOperator, S);
- CAO_LIST()
+ CAO_LIST()
#undef OPERATOR
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
+#define OPERATOR(NAME) \
+ case UO_##NAME: \
+ DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
- UNARYOP_LIST()
+ UNARYOP_LIST()
#undef OPERATOR
}
}
// Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
switch (S->getStmtClass()) {
- case Stmt::NoStmtClass: break;
+ case Stmt::NoStmtClass:
+ break;
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: DISPATCH_WALK(CLASS, CLASS, S);
+#define STMT(CLASS, PARENT) \
+ case Stmt::CLASS##Class: \
+ DISPATCH_WALK(CLASS, CLASS, S);
#include "clang/AST/StmtNodes.inc"
}
@@ -555,14 +546,16 @@
return true;
}
-#define DISPATCH(NAME, CLASS, VAR) \
- return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
+#define DISPATCH(NAME, CLASS, VAR) \
+ return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
if (!S)
return true;
+#define DISPATCH_STMT(NAME, CLASS, VAR) DISPATCH(NAME, CLASS, VAR)
+
if (getDerived().shouldUseDataRecursionFor(S))
return dataTraverse(S);
@@ -571,27 +564,29 @@
// below.
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: DISPATCH(Bin##NAME, BinaryOperator, S);
+#define OPERATOR(NAME) \
+ case BO_##NAME: \
+ DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
- BINOP_LIST()
+ BINOP_LIST()
#undef OPERATOR
#undef BINOP_LIST
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
- DISPATCH(Bin##NAME##Assign, CompoundAssignOperator, S);
+#define OPERATOR(NAME) \
+ case BO_##NAME##Assign: \
+ DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
- CAO_LIST()
+ CAO_LIST()
#undef OPERATOR
#undef CAO_LIST
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: DISPATCH(Unary##NAME, UnaryOperator, S);
+#define OPERATOR(NAME) \
+ case UO_##NAME: \
+ DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
- UNARYOP_LIST()
+ UNARYOP_LIST()
#undef OPERATOR
#undef UNARYOP_LIST
}
@@ -599,41 +594,45 @@
// Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
switch (S->getStmtClass()) {
- case Stmt::NoStmtClass: break;
+ case Stmt::NoStmtClass:
+ break;
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: DISPATCH(CLASS, CLASS, S);
+#define STMT(CLASS, PARENT) \
+ case Stmt::CLASS##Class: \
+ DISPATCH_STMT(CLASS, CLASS, S);
#include "clang/AST/StmtNodes.inc"
}
return true;
}
-template<typename Derived>
+#undef DISPATCH_STMT
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
if (T.isNull())
return true;
switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, \
- const_cast<Type*>(T.getTypePtr()));
+#define TYPE(CLASS, BASE) \
+ case Type::CLASS: \
+ DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
#include "clang/AST/TypeNodes.def"
}
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
if (TL.isNull())
return true;
switch (TL.getTypeLocClass()) {
#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- case TypeLoc::CLASS: \
+#define TYPELOC(CLASS, BASE) \
+ case TypeLoc::CLASS: \
return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
#include "clang/AST/TypeLocNodes.def"
}
@@ -641,14 +640,12 @@
return true;
}
-
// Define the Traverse*Attr(Attr* A) methods
#define VISITORCLASS RecursiveASTVisitor
#include "clang/AST/AttrVisitor.inc"
#undef VISITORCLASS
-
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
if (!D)
return true;
@@ -660,10 +657,10 @@
switch (D->getKind()) {
#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- case Decl::CLASS: \
- if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl*>(D))) \
- return false; \
+#define DECL(CLASS, BASE) \
+ case Decl::CLASS: \
+ if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
+ return false; \
break;
#include "clang/AST/DeclNodes.inc"
}
@@ -678,9 +675,9 @@
#undef DISPATCH
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
+ NestedNameSpecifier *NNS) {
if (!NNS)
return true;
@@ -702,14 +699,14 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
- NestedNameSpecifierLoc NNS) {
+ NestedNameSpecifierLoc NNS) {
if (!NNS)
return true;
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+ if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+ TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
switch (NNS.getNestedNameSpecifier()->getKind()) {
case NestedNameSpecifier::Identifier:
@@ -727,9 +724,9 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
- DeclarationNameInfo NameInfo) {
+ DeclarationNameInfo NameInfo) {
switch (NameInfo.getName().getNameKind()) {
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
@@ -752,7 +749,7 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
@@ -762,9 +759,9 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
- const TemplateArgument &Arg) {
+ const TemplateArgument &Arg) {
switch (Arg.getKind()) {
case TemplateArgument::Null:
case TemplateArgument::Declaration:
@@ -778,7 +775,7 @@
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
+ Arg.getAsTemplateOrTemplatePattern());
case TemplateArgument::Expression:
return getDerived().TraverseStmt(Arg.getAsExpr());
@@ -793,9 +790,9 @@
// FIXME: no template name location?
// FIXME: no source locations for a template argument pack?
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
- const TemplateArgumentLoc &ArgLoc) {
+ const TemplateArgumentLoc &ArgLoc) {
const TemplateArgument &Arg = ArgLoc.getArgument();
switch (Arg.getKind()) {
@@ -817,9 +814,9 @@
case TemplateArgument::TemplateExpansion:
if (ArgLoc.getTemplateQualifierLoc())
TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
- ArgLoc.getTemplateQualifierLoc()));
+ ArgLoc.getTemplateQualifierLoc()));
return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
+ Arg.getAsTemplateOrTemplatePattern());
case TemplateArgument::Expression:
return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
@@ -832,10 +829,9 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- const TemplateArgument *Args,
- unsigned NumArgs) {
+ const TemplateArgument *Args, unsigned NumArgs) {
for (unsigned I = 0; I != NumArgs; ++I) {
TRY_TO(TraverseTemplateArgument(Args[I]));
}
@@ -843,9 +839,9 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
- CXXCtorInitializer *Init) {
+ CXXCtorInitializer *Init) {
if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
@@ -854,99 +850,82 @@
return true;
}
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(
- LambdaExpr *LE, const LambdaExpr::Capture *C) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
+ const LambdaCapture *C) {
if (C->isInitCapture())
TRY_TO(TraverseDecl(C->getCapturedVar()));
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
TRY_TO(TraverseStmt(LE->getBody()));
return true;
}
-
// ----------------- Type traversal -----------------
// This macro makes available a variable T, the passed-in type.
-#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
- template<typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) { \
- TRY_TO(WalkUpFrom##TYPE (T)); \
- { CODE; } \
- return true; \
+#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
+ TRY_TO(WalkUpFrom##TYPE(T)); \
+ { CODE; } \
+ return true; \
}
-DEF_TRAVERSE_TYPE(BuiltinType, { })
+DEF_TRAVERSE_TYPE(BuiltinType, {})
-DEF_TRAVERSE_TYPE(ComplexType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(PointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(BlockPointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(BlockPointerType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(LValueReferenceType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(LValueReferenceType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(RValueReferenceType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(RValueReferenceType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseType(QualType(T->getClass(), 0)));
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+ TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+ TRY_TO(TraverseType(T->getPointeeType()));
+})
-DEF_TRAVERSE_TYPE(AdjustedType, {
- TRY_TO(TraverseType(T->getOriginalType()));
- })
+DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-DEF_TRAVERSE_TYPE(DecayedType, {
- TRY_TO(TraverseType(T->getOriginalType()));
- })
+DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-DEF_TRAVERSE_TYPE(ConstantArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ConstantArrayType,
+ { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(IncompleteArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(IncompleteArrayType,
+ { TRY_TO(TraverseType(T->getElementType())); })
DEF_TRAVERSE_TYPE(VariableArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
+ TRY_TO(TraverseType(T->getElementType()));
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
+ TRY_TO(TraverseType(T->getElementType()));
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- TRY_TO(TraverseType(T->getElementType()));
- })
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+ TRY_TO(TraverseType(T->getElementType()));
+})
-DEF_TRAVERSE_TYPE(VectorType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(ExtVectorType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
DEF_TRAVERSE_TYPE(FunctionNoProtoType,
{ TRY_TO(TraverseType(T->getReturnType())); })
@@ -963,87 +942,72 @@
}
})
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPE(TypedefType, { })
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPE(TypedefType, {})
-DEF_TRAVERSE_TYPE(TypeOfExprType, {
- TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPE(TypeOfExprType,
+ { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-DEF_TRAVERSE_TYPE(TypeOfType, {
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
-DEF_TRAVERSE_TYPE(DecltypeType, {
- TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPE(DecltypeType,
+ { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
DEF_TRAVERSE_TYPE(UnaryTransformType, {
- TRY_TO(TraverseType(T->getBaseType()));
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
+ TRY_TO(TraverseType(T->getBaseType()));
+ TRY_TO(TraverseType(T->getUnderlyingType()));
+})
-DEF_TRAVERSE_TYPE(AutoType, {
- TRY_TO(TraverseType(T->getDeducedType()));
- })
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
-DEF_TRAVERSE_TYPE(RecordType, { })
-DEF_TRAVERSE_TYPE(EnumType, { })
-DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { })
+DEF_TRAVERSE_TYPE(RecordType, {})
+DEF_TRAVERSE_TYPE(EnumType, {})
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
- })
+ TRY_TO(TraverseTemplateName(T->getTemplateName()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
-DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
-DEF_TRAVERSE_TYPE(AttributedType, {
- TRY_TO(TraverseType(T->getModifiedType()));
- })
+DEF_TRAVERSE_TYPE(AttributedType,
+ { TRY_TO(TraverseType(T->getModifiedType())); })
-DEF_TRAVERSE_TYPE(ParenType, {
- TRY_TO(TraverseType(T->getInnerType()));
- })
+DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
DEF_TRAVERSE_TYPE(ElaboratedType, {
- if (T->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
- TRY_TO(TraverseType(T->getNamedType()));
- })
-
-DEF_TRAVERSE_TYPE(DependentNameType, {
+ if (T->getQualifier()) {
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- })
+ }
+ TRY_TO(TraverseType(T->getNamedType()));
+})
+
+DEF_TRAVERSE_TYPE(DependentNameType,
+ { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
- })
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
-DEF_TRAVERSE_TYPE(PackExpansionType, {
- TRY_TO(TraverseType(T->getPattern()));
- })
+DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
-DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPE(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (T->getBaseType().getTypePtr() != T)
- TRY_TO(TraverseType(T->getBaseType()));
- })
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (T->getBaseType().getTypePtr() != T)
+ TRY_TO(TraverseType(T->getBaseType()));
+})
-DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(AtomicType, {
- TRY_TO(TraverseType(T->getValueType()));
- })
+DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
#undef DEF_TRAVERSE_TYPE
@@ -1054,19 +1018,19 @@
// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
// continue to work.
-#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
- template<typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE*>(TL.getTypePtr()))); \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
- { CODE; } \
- return true; \
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
+ if (getDerived().shouldWalkTypesOfTypeLocs()) \
+ TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
+ TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
+ { CODE; } \
+ return true; \
}
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
- QualifiedTypeLoc TL) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
// Move this over to the 'main' typeloc tree. Note that this is a
// move -- we pretend that we were really looking at the unqualified
// typeloc all along -- rather than a recursion, so we don't follow
@@ -1085,46 +1049,40 @@
return TraverseTypeLoc(TL.getUnqualifiedLoc());
}
-DEF_TRAVERSE_TYPELOC(BuiltinType, { })
+DEF_TRAVERSE_TYPELOC(BuiltinType, {})
// FIXME: ComplexTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ComplexType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
-DEF_TRAVERSE_TYPELOC(PointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(PointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(BlockPointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(BlockPointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(LValueReferenceType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(LValueReferenceType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(RValueReferenceType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(RValueReferenceType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
// FIXME: location of base class?
// We traverse this in the type case as well, but how is it not reached through
// the pointee type?
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+ TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+})
-DEF_TRAVERSE_TYPELOC(AdjustedType, {
- TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AdjustedType,
+ { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-DEF_TRAVERSE_TYPELOC(DecayedType, {
- TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
- })
+DEF_TRAVERSE_TYPELOC(DecayedType,
+ { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
// This isn't available for ArrayType, but is for the ArrayTypeLoc.
TRY_TO(TraverseStmt(TL.getSizeExpr()));
@@ -1132,156 +1090,147 @@
}
DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(VariableArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
// FIXME: order? why not size expr first?
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ if (TL.getTypePtr()->getSizeExpr())
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
// FIXME: VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(VectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
// FIXME: size and attributes
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ExtVectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
-DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
- })
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
+ { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
// FIXME: location of exception specifications (attributes?)
DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
+ TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
- const FunctionProtoType *T = TL.getTypePtr();
+ const FunctionProtoType *T = TL.getTypePtr();
- for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
- if (TL.getParam(I)) {
- TRY_TO(TraverseDecl(TL.getParam(I)));
- } else if (I < T->getNumParams()) {
- TRY_TO(TraverseType(T->getParamType(I)));
- }
+ for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+ if (TL.getParam(I)) {
+ TRY_TO(TraverseDecl(TL.getParam(I)));
+ } else if (I < T->getNumParams()) {
+ TRY_TO(TraverseType(T->getParamType(I)));
}
+ }
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
- })
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+})
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPELOC(TypedefType, { })
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPELOC(TypedefType, {})
-DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
- TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPELOC(TypeOfExprType,
+ { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
// FIXME: location of underlying expr
DEF_TRAVERSE_TYPELOC(DecltypeType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
- })
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+})
DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_TYPELOC(AutoType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
-DEF_TRAVERSE_TYPELOC(RecordType, { })
-DEF_TRAVERSE_TYPELOC(EnumType, { })
-DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { })
+DEF_TRAVERSE_TYPELOC(RecordType, {})
+DEF_TRAVERSE_TYPELOC(EnumType, {})
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
// FIXME: use the loc for the template name?
DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
+ TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+})
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
-DEF_TRAVERSE_TYPELOC(ParenType, {
- TRY_TO(TraverseTypeLoc(TL.getInnerLoc()));
- })
+DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
-DEF_TRAVERSE_TYPELOC(AttributedType, {
- TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AttributedType,
+ { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
- })
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
+ TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+})
DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+})
DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+})
-DEF_TRAVERSE_TYPELOC(PackExpansionType, {
- TRY_TO(TraverseTypeLoc(TL.getPatternLoc()));
- })
+DEF_TRAVERSE_TYPELOC(PackExpansionType,
+ { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
-DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
- TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
- })
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+ TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+})
-DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(AtomicType, {
- TRY_TO(TraverseTypeLoc(TL.getValueLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
#undef DEF_TRAVERSE_TYPELOC
@@ -1292,7 +1241,7 @@
// Therefore each Traverse* only needs to worry about children other
// than those.
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
if (!DC)
return true;
@@ -1308,137 +1257,128 @@
}
// This macro makes available a variable D, the passed-in decl.
-#define DEF_TRAVERSE_DECL(DECL, CODE) \
-template<typename Derived> \
-bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) { \
- TRY_TO(WalkUpFrom##DECL (D)); \
- { CODE; } \
- TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
- return true; \
-}
+#define DEF_TRAVERSE_DECL(DECL, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
+ TRY_TO(WalkUpFrom##DECL(D)); \
+ { CODE; } \
+ TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
+ return true; \
+ }
-DEF_TRAVERSE_DECL(AccessSpecDecl, { })
+DEF_TRAVERSE_DECL(AccessSpecDecl, {})
DEF_TRAVERSE_DECL(BlockDecl, {
- if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- TRY_TO(TraverseStmt(D->getBody()));
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(CapturedDecl, {
- TRY_TO(TraverseStmt(D->getBody()));
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(EmptyDecl, { })
-
-DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
- TRY_TO(TraverseStmt(D->getAsmString()));
- })
-
-DEF_TRAVERSE_DECL(ImportDecl, { })
-
-DEF_TRAVERSE_DECL(FriendDecl, {
- // Friend is either decl or a type.
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- })
-
-DEF_TRAVERSE_DECL(FriendTemplateDecl, {
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
- TemplateParameterList *TPL = D->getTemplateParameterList(I);
- for (TemplateParameterList::iterator ITPL = TPL->begin(),
- ETPL = TPL->end();
- ITPL != ETPL; ++ITPL) {
- TRY_TO(TraverseDecl(*ITPL));
- }
- }
- })
-
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
- TRY_TO(TraverseDecl(D->getSpecialization()));
-
- if (D->hasExplicitTemplateArgs()) {
- const TemplateArgumentListInfo& args = D->templateArgs();
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- args.getArgumentArray(), args.size()));
- }
- })
-
-DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
-
-DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {
- // FIXME: implement this
- })
-
-DEF_TRAVERSE_DECL(StaticAssertDecl, {
- TRY_TO(TraverseStmt(D->getAssertExpr()));
- TRY_TO(TraverseStmt(D->getMessage()));
- })
-
-DEF_TRAVERSE_DECL(TranslationUnitDecl, {
- // Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
-
-DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
- // We shouldn't traverse an aliased namespace, since it will be
- // defined (and, therefore, traversed) somewhere else.
- //
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
- })
-
-DEF_TRAVERSE_DECL(LabelDecl, {
- // There is no code in a LabelDecl.
+ if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+ TRY_TO(TraverseStmt(D->getBody()));
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
})
+DEF_TRAVERSE_DECL(CapturedDecl, {
+ TRY_TO(TraverseStmt(D->getBody()));
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+})
-DEF_TRAVERSE_DECL(NamespaceDecl, {
- // Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
+DEF_TRAVERSE_DECL(EmptyDecl, {})
-DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(FileScopeAsmDecl,
+ { TRY_TO(TraverseStmt(D->getAsmString())); })
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(ImportDecl, {})
-DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(FriendDecl, {
+ // Friend is either decl or a type.
+ if (D->getFriendType())
+ TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+ else
+ TRY_TO(TraverseDecl(D->getFriendDecl()));
+})
-DEF_TRAVERSE_DECL(ObjCImplementationDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+ if (D->getFriendType())
+ TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+ else
+ TRY_TO(TraverseDecl(D->getFriendDecl()));
+ for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+ TemplateParameterList *TPL = D->getTemplateParameterList(I);
+ for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
+ ITPL != ETPL; ++ITPL) {
+ TRY_TO(TraverseDecl(*ITPL));
+ }
+ }
+})
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
+ TRY_TO(TraverseDecl(D->getSpecialization()));
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
- // FIXME: implement
- })
+ if (D->hasExplicitTemplateArgs()) {
+ const TemplateArgumentListInfo &args = D->templateArgs();
+ TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(),
+ args.size()));
+ }
+})
+
+DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
+ })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+ TRY_TO(TraverseStmt(D->getAssertExpr()));
+ TRY_TO(TraverseStmt(D->getMessage()));
+})
+
+DEF_TRAVERSE_DECL(
+ TranslationUnitDecl,
+ {// Code in an unnamed namespace shows up automatically in
+ // decls_begin()/decls_end(). Thus we don't need to recurse on
+ // D->getAnonymousNamespace().
+ })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+ // We shouldn't traverse an aliased namespace, since it will be
+ // defined (and, therefore, traversed) somewhere else.
+ //
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+})
+
+DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
+ })
+
+DEF_TRAVERSE_DECL(
+ NamespaceDecl,
+ {// Code in an unnamed namespace shows up automatically in
+ // decls_begin()/decls_end(). Thus we don't need to recurse on
+ // D->getAnonymousNamespace().
+ })
+
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
+ })
DEF_TRAVERSE_DECL(ObjCMethodDecl, {
if (D->getReturnTypeSourceInfo()) {
@@ -1454,29 +1394,28 @@
return true;
})
-DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
- // FIXME: implement
- })
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {// FIXME: implement
+ })
DEF_TRAVERSE_DECL(UsingDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+})
-DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+DEF_TRAVERSE_DECL(UsingShadowDecl, {})
DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
- for (auto *I : D->varlists()) {
- TRY_TO(TraverseStmt(I));
- }
- })
+ for (auto *I : D->varlists()) {
+ TRY_TO(TraverseStmt(I));
+ }
+})
// A helper method for TemplateDecl's children.
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
TemplateParameterList *TPL) {
if (TPL) {
@@ -1488,7 +1427,7 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
ClassTemplateDecl *D) {
for (auto *SD : D->specializations()) {
@@ -1497,8 +1436,8 @@
if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
continue;
- switch (cast<ClassTemplateSpecializationDecl>(RD)->
- getSpecializationKind()) {
+ switch (
+ cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
// Visit the implicit instantiations with the requested pattern.
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
@@ -1519,13 +1458,13 @@
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
VarTemplateDecl *D) {
for (auto *SD : D->specializations()) {
for (auto *RD : SD->redecls()) {
- switch (cast<VarTemplateSpecializationDecl>(RD)->
- getSpecializationKind()) {
+ switch (
+ cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
TRY_TO(TraverseDecl(RD));
@@ -1544,7 +1483,7 @@
// A helper method for traversing the instantiations of a
// function while skipping its specializations.
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
FunctionTemplateDecl *D) {
for (auto *FD : D->specializations()) {
@@ -1574,8 +1513,8 @@
// This macro unifies the traversal of class, variable and function
// template declarations.
-#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
-DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
+#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
+ DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
\
@@ -1599,65 +1538,63 @@
DEF_TRAVERSE_TMPL_DECL(Function)
DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
- // D is the "T" in something like
- // template <template <typename> class T> class container { };
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
- TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
- }
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
+ // D is the "T" in something like
+ // template <template <typename> class T> class container { };
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
+ TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+ }
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
- // D is the "T" in something like "template<typename T> class vector;"
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
- })
+ // D is the "T" in something like "template<typename T> class vector;"
+ if (D->getTypeForDecl())
+ TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+ if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
+ TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_DECL(TypedefDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the typedef, not something that was written in the
- // source.
- })
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the typedef, not something that was written in the
+ // source.
+})
DEF_TRAVERSE_DECL(TypeAliasDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
- })
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type alias, not something that was written in the
+ // source.
+})
DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
- // A dependent using declaration which was marked with 'typename'.
- // template<class T> class A : public B<T> { using typename B<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the
- // source.
- })
+ // A dependent using declaration which was marked with 'typename'.
+ // template<class T> class A : public B<T> { using typename B<T>::foo; };
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type, not something that was written in the
+ // source.
+})
DEF_TRAVERSE_DECL(EnumDecl, {
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+ if (D->getTypeForDecl())
+ TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // The enumerators are already traversed by
- // decls_begin()/decls_end().
- })
-
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ // The enumerators are already traversed by
+ // decls_begin()/decls_end().
+})
// Helper methods for RecordDecl and its children.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(
- RecordDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
// We shouldn't traverse D->getTypeForDecl(); it's a result of
// declaring the type, not something that was written in the source.
@@ -1665,9 +1602,8 @@
return true;
}
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
- CXXRecordDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
if (!TraverseRecordHelper(D))
return false;
if (D->isCompleteDefinition()) {
@@ -1680,34 +1616,30 @@
return true;
}
-DEF_TRAVERSE_DECL(RecordDecl, {
- TRY_TO(TraverseRecordHelper(D));
- })
+DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
-DEF_TRAVERSE_DECL(CXXRecordDecl, {
- TRY_TO(TraverseCXXRecordHelper(D));
- })
+DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
-#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \
-DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
- /* For implicit instantiations ("set<int> x;"), we don't want to
- recurse at all, since the instatiated template isn't written in
- the source code anywhere. (Note the instatiated *type* --
- set<int> -- is written, and will still get a callback of
- TemplateSpecializationType). For explicit instantiations
- ("template set<int>;"), we do need a callback, since this
- is the only callback that's made for this instantiation.
- We use getTypeAsWritten() to distinguish. */ \
- if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
- \
- if (!getDerived().shouldVisitTemplateInstantiations() && \
- D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \
- /* Returning from here skips traversing the
- declaration context of the *TemplateSpecializationDecl
- (embedded in the DEF_TRAVERSE_DECL() macro)
- which contains the instantiated members of the template. */ \
- return true; \
+#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \
+ DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
+ /* For implicit instantiations ("set<int> x;"), we don't want to \
+ recurse at all, since the instatiated template isn't written in \
+ the source code anywhere. (Note the instatiated *type* -- \
+ set<int> -- is written, and will still get a callback of \
+ TemplateSpecializationType). For explicit instantiations \
+ ("template set<int>;"), we do need a callback, since this \
+ is the only callback that's made for this instantiation. \
+ We use getTypeAsWritten() to distinguish. */ \
+ if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
+ \
+ if (!getDerived().shouldVisitTemplateInstantiations() && \
+ D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \
+ /* Returning from here skips traversing the \
+ declaration context of the *TemplateSpecializationDecl \
+ (embedded in the DEF_TRAVERSE_DECL() macro) \
+ which contains the instantiated members of the template. */ \
+ return true; \
})
DEF_TRAVERSE_TMPL_SPEC_DECL(Class)
@@ -1722,8 +1654,8 @@
return true;
}
-#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
-DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
+#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
+ DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
/* The partial specialization. */ \
if (TemplateParameterList *TPL = D->getTemplateParameters()) { \
for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
@@ -1747,20 +1679,18 @@
DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)
-DEF_TRAVERSE_DECL(EnumConstantDecl, {
- TRY_TO(TraverseStmt(D->getInitExpr()));
- })
+DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
- // Like UnresolvedUsingTypenameDecl, but without the 'typename':
- // template <class T> Class A : public Base<T> { using Base<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- })
+ // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+ // template <class T> Class A : public Base<T> { using Base<T>::foo; };
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
if (D->getTypeSourceInfo())
@@ -1770,33 +1700,31 @@
return true;
}
-DEF_TRAVERSE_DECL(MSPropertyDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- })
+DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
DEF_TRAVERSE_DECL(FieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- else if (D->hasInClassInitializer())
- TRY_TO(TraverseStmt(D->getInClassInitializer()));
- })
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ else if (D->hasInClassInitializer())
+ TRY_TO(TraverseStmt(D->getInClassInitializer()));
+})
DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
- })
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ // FIXME: implement the rest.
+})
DEF_TRAVERSE_DECL(ObjCIvarDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
- })
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ // FIXME: implement the rest.
+})
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
@@ -1807,13 +1735,13 @@
// the function args, but both are handled by the FunctionTypeLoc
// above, so we have to choose one side. I've decided to do before.
if (const FunctionTemplateSpecializationInfo *FTSI =
- D->getTemplateSpecializationInfo()) {
+ D->getTemplateSpecializationInfo()) {
if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
// A specialization might not have explicit template arguments if it has
// a templated return type and concrete arguments.
if (const ASTTemplateArgumentListInfo *TALI =
- FTSI->TemplateArgumentsAsWritten) {
+ FTSI->TemplateArgumentsAsWritten) {
TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
TALI->NumTemplateArgs));
}
@@ -1832,7 +1760,8 @@
// declarations do not have valid TypeSourceInfo, so to visit them
// we need to traverse the declarations explicitly.
for (FunctionDecl::param_const_iterator I = D->param_begin(),
- E = D->param_end(); I != E; ++I)
+ E = D->param_end();
+ I != E; ++I)
TRY_TO(TraverseDecl(*I));
}
@@ -1844,44 +1773,44 @@
}
if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody())); // Function body.
+ TRY_TO(TraverseStmt(D->getBody())); // Function body.
}
return true;
}
DEF_TRAVERSE_DECL(FunctionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
DEF_TRAVERSE_DECL(CXXMethodDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
DEF_TRAVERSE_DECL(CXXConstructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
// CXXConversionDecl is the declaration of a type conversion operator.
// It's not a cast expression.
DEF_TRAVERSE_DECL(CXXConversionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
DEF_TRAVERSE_DECL(CXXDestructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
- })
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
TRY_TO(TraverseDeclaratorHelper(D));
// Default params are taken care of when we traverse the ParmVarDecl.
@@ -1891,34 +1820,28 @@
return true;
}
-DEF_TRAVERSE_DECL(VarDecl, {
- TRY_TO(TraverseVarHelper(D));
- })
+DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
-DEF_TRAVERSE_DECL(ImplicitParamDecl, {
- TRY_TO(TraverseVarHelper(D));
- })
+DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
- // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseStmt(D->getDefaultArgument()));
- })
+ // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
+ TRY_TO(TraverseStmt(D->getDefaultArgument()));
+})
DEF_TRAVERSE_DECL(ParmVarDecl, {
- TRY_TO(TraverseVarHelper(D));
+ TRY_TO(TraverseVarHelper(D));
- if (D->hasDefaultArg() &&
- D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
+ if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
+ !D->hasUnparsedDefaultArg())
+ TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
- if (D->hasDefaultArg() &&
- !D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getDefaultArg()));
- })
+ if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
+ !D->hasUnparsedDefaultArg())
+ TRY_TO(TraverseStmt(D->getDefaultArg()));
+})
#undef DEF_TRAVERSE_DECL
@@ -1932,77 +1855,77 @@
// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
// This macro makes available a variable S, the passed-in stmt.
-#define DEF_TRAVERSE_STMT(STMT, CODE) \
-template<typename Derived> \
-bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \
- TRY_TO(WalkUpFrom##STMT(S)); \
- { CODE; } \
- for (Stmt::child_range range = S->children(); range; ++range) { \
- TRY_TO(TraverseStmt(*range)); \
- } \
- return true; \
-}
+#define DEF_TRAVERSE_STMT(STMT, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) { \
+ TRY_TO(WalkUpFrom##STMT(S)); \
+ { CODE; } \
+ for (Stmt::child_range range = S->children(); range; ++range) { \
+ TRY_TO(TraverseStmt(*range)); \
+ } \
+ return true; \
+ }
DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO(TraverseStmt(S->getAsmString()));
- for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
- TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
- }
- for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
- TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
- }
- for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
- TRY_TO(TraverseStmt(S->getClobberStringLiteral(I)));
- }
- // children() iterates over inputExpr and outputExpr.
- })
+ TRY_TO(TraverseStmt(S->getAsmString()));
+ for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+ TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
+ }
+ for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+ TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
+ }
+ for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+ TRY_TO(TraverseStmt(S->getClobberStringLiteral(I)));
+ }
+ // children() iterates over inputExpr and outputExpr.
+})
-DEF_TRAVERSE_STMT(MSAsmStmt, {
- // FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
- // added this needs to be implemented.
- })
+DEF_TRAVERSE_STMT(
+ MSAsmStmt,
+ {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
+ // added this needs to be implemented.
+ })
DEF_TRAVERSE_STMT(CXXCatchStmt, {
- TRY_TO(TraverseDecl(S->getExceptionDecl()));
- // children() iterates over the handler block.
- })
+ TRY_TO(TraverseDecl(S->getExceptionDecl()));
+ // children() iterates over the handler block.
+})
DEF_TRAVERSE_STMT(DeclStmt, {
- for (auto *I : S->decls()) {
- TRY_TO(TraverseDecl(I));
- }
- // Suppress the default iteration over children() by
- // returning. Here's why: A DeclStmt looks like 'type var [=
- // initializer]'. The decls above already traverse over the
- // initializers, so we don't have to do it again (which
- // children() would do).
- return true;
- })
-
+ for (auto *I : S->decls()) {
+ TRY_TO(TraverseDecl(I));
+ }
+ // Suppress the default iteration over children() by
+ // returning. Here's why: A DeclStmt looks like 'type var [=
+ // initializer]'. The decls above already traverse over the
+ // initializers, so we don't have to do it again (which
+ // children() would do).
+ return true;
+})
// These non-expr stmts (most of them), do not need any action except
// iterating over the children.
-DEF_TRAVERSE_STMT(BreakStmt, { })
-DEF_TRAVERSE_STMT(CXXTryStmt, { })
-DEF_TRAVERSE_STMT(CaseStmt, { })
-DEF_TRAVERSE_STMT(CompoundStmt, { })
-DEF_TRAVERSE_STMT(ContinueStmt, { })
-DEF_TRAVERSE_STMT(DefaultStmt, { })
-DEF_TRAVERSE_STMT(DoStmt, { })
-DEF_TRAVERSE_STMT(ForStmt, { })
-DEF_TRAVERSE_STMT(GotoStmt, { })
-DEF_TRAVERSE_STMT(IfStmt, { })
-DEF_TRAVERSE_STMT(IndirectGotoStmt, { })
-DEF_TRAVERSE_STMT(LabelStmt, { })
-DEF_TRAVERSE_STMT(AttributedStmt, { })
-DEF_TRAVERSE_STMT(NullStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtCatchStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
-DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
-DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { })
+DEF_TRAVERSE_STMT(BreakStmt, {})
+DEF_TRAVERSE_STMT(CXXTryStmt, {})
+DEF_TRAVERSE_STMT(CaseStmt, {})
+DEF_TRAVERSE_STMT(CompoundStmt, {})
+DEF_TRAVERSE_STMT(ContinueStmt, {})
+DEF_TRAVERSE_STMT(DefaultStmt, {})
+DEF_TRAVERSE_STMT(DoStmt, {})
+DEF_TRAVERSE_STMT(ForStmt, {})
+DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(IfStmt, {})
+DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
+DEF_TRAVERSE_STMT(LabelStmt, {})
+DEF_TRAVERSE_STMT(AttributedStmt, {})
+DEF_TRAVERSE_STMT(NullStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
+DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
DEF_TRAVERSE_STMT(CXXForRangeStmt, {
if (!getDerived().shouldVisitImplicitCode()) {
TRY_TO(TraverseStmt(S->getLoopVarStmt()));
@@ -2013,82 +1936,82 @@
}
})
DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
})
-DEF_TRAVERSE_STMT(ReturnStmt, { })
-DEF_TRAVERSE_STMT(SwitchStmt, { })
-DEF_TRAVERSE_STMT(WhileStmt, { })
-
+DEF_TRAVERSE_STMT(ReturnStmt, {})
+DEF_TRAVERSE_STMT(SwitchStmt, {})
+DEF_TRAVERSE_STMT(WhileStmt, {})
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- }
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
DEF_TRAVERSE_STMT(DeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+})
DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getExplicitTemplateArgs().getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ S->getExplicitTemplateArgs().getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
DEF_TRAVERSE_STMT(MemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- S->getTemplateArgs(), S->getNumTemplateArgs()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+})
-DEF_TRAVERSE_STMT(ImplicitCastExpr, {
- // We don't traverse the cast type, as it's not written in the
- // source code.
- })
+DEF_TRAVERSE_STMT(
+ ImplicitCastExpr,
+ {// We don't traverse the cast type, as it's not written in the
+ // source code.
+ })
DEF_TRAVERSE_STMT(CStyleCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXConstCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
// InitListExpr is a tricky one, because we want to do all our work on
// the syntactic form of the listexpr, but this method takes the
// semantic form by default. We can't use the macro helper because it
// calls WalkUp*() on the semantic form, before our code can convert
// to the syntactic form.
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
if (InitListExpr *Syn = S->getSyntacticForm())
S = Syn;
@@ -2103,9 +2026,9 @@
// GenericSelectionExpr is a special case because the types and expressions
// are interleaved. We also need to watch out for null types (default
// generic associations).
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::
-TraverseGenericSelectionExpr(GenericSelectionExpr *S) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr(
+ GenericSelectionExpr *S) {
TRY_TO(WalkUpFromGenericSelectionExpr(S));
TRY_TO(TraverseStmt(S->getControllingExpr()));
for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
@@ -2118,13 +2041,14 @@
// PseudoObjectExpr is a special case because of the wierdness with
// syntactic expressions and opaque values.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::
-TraversePseudoObjectExpr(PseudoObjectExpr *S) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) {
TRY_TO(WalkUpFromPseudoObjectExpr(S));
TRY_TO(TraverseStmt(S->getSyntacticForm()));
- for (PseudoObjectExpr::semantics_iterator
- i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i) {
+ for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
+ e = S->semantics_end();
+ i != e; ++i) {
Expr *sub = *i;
if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
sub = OVE->getSourceExpr();
@@ -2134,48 +2058,48 @@
}
DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
- // This is called for code like 'return T()' where T is a built-in
- // (i.e. non-class) type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
+ // This is called for code like 'return T()' where T is a built-in
+ // (i.e. non-class) type.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXNewExpr, {
// The child-iterator will pick up the other arguments.
TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
- })
+})
DEF_TRAVERSE_STMT(OffsetOfExpr, {
- // The child-iterator will pick up the expression representing
- // the field.
- // FIMXE: for code like offsetof(Foo, a.b.c), should we get
- // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the expression representing
+ // the field.
+ // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+ // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isArgumentType())
- TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isArgumentType())
+ TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXTypeidExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isTypeOperand())
+ TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
})
DEF_TRAVERSE_STMT(CXXUuidofExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isTypeOperand())
+ TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(TypeTraitExpr, {
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
@@ -2183,30 +2107,29 @@
})
DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+})
-DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
- TRY_TO(TraverseStmt(S->getQueriedExpression()));
- })
+DEF_TRAVERSE_STMT(ExpressionTraitExpr,
+ { TRY_TO(TraverseStmt(S->getQueriedExpression())); })
DEF_TRAVERSE_STMT(VAArgExpr, {
- // The child-iterator will pick up the expression argument.
- TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
- })
+ // The child-iterator will pick up the expression argument.
+ TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
- // This is called for code like 'return T()' where T is a class type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
+ // This is called for code like 'return T()' where T is a class type.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
-// Walk only the visible parts of lambda expressions.
-template<typename Derived>
+// Walk only the visible parts of lambda expressions.
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
TRY_TO(WalkUpFromLambdaExpr(S));
for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
- CEnd = S->explicit_capture_end();
+ CEnd = S->explicit_capture_end();
C != CEnd; ++C) {
TRY_TO(TraverseLambdaCapture(S, C));
}
@@ -2224,7 +2147,7 @@
}
} else {
TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
- }
+ }
}
}
@@ -2233,36 +2156,36 @@
}
DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
- // This is called for code like 'T()', where T is a template argument.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
+ // This is called for code like 'T()', where T is a template argument.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
// These expressions all might take explicit template arguments.
// We traverse those if so. FIXME: implement these.
-DEF_TRAVERSE_STMT(CXXConstructExpr, { })
-DEF_TRAVERSE_STMT(CallExpr, { })
-DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
+DEF_TRAVERSE_STMT(CXXConstructExpr, {})
+DEF_TRAVERSE_STMT(CallExpr, {})
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
// These exprs (most of them), do not need any action except iterating
// over the children.
-DEF_TRAVERSE_STMT(AddrLabelExpr, { })
-DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
+DEF_TRAVERSE_STMT(AddrLabelExpr, {})
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
DEF_TRAVERSE_STMT(BlockExpr, {
TRY_TO(TraverseDecl(S->getBlockDecl()));
return true; // no child statements to loop through.
})
-DEF_TRAVERSE_STMT(ChooseExpr, { })
+DEF_TRAVERSE_STMT(ChooseExpr, {})
DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
-DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { })
-DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
-DEF_TRAVERSE_STMT(ExprWithCleanups, { })
-DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
+DEF_TRAVERSE_STMT(ExprWithCleanups, {})
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
@@ -2270,38 +2193,38 @@
if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(CXXThisExpr, { })
-DEF_TRAVERSE_STMT(CXXThrowExpr, { })
-DEF_TRAVERSE_STMT(UserDefinedLiteral, { })
-DEF_TRAVERSE_STMT(DesignatedInitExpr, { })
-DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
-DEF_TRAVERSE_STMT(GNUNullExpr, { })
-DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { })
-DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXThisExpr, {})
+DEF_TRAVERSE_STMT(CXXThrowExpr, {})
+DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
+DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
+DEF_TRAVERSE_STMT(GNUNullExpr, {})
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
-DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
DEF_TRAVERSE_STMT(ObjCMessageExpr, {
if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
-DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
-DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { })
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
+DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(ParenExpr, { })
-DEF_TRAVERSE_STMT(ParenListExpr, { })
-DEF_TRAVERSE_STMT(PredefinedExpr, { })
-DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
-DEF_TRAVERSE_STMT(ConvertVectorExpr, { })
-DEF_TRAVERSE_STMT(StmtExpr, { })
+DEF_TRAVERSE_STMT(ParenExpr, {})
+DEF_TRAVERSE_STMT(ParenListExpr, {})
+DEF_TRAVERSE_STMT(PredefinedExpr, {})
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
+DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
+DEF_TRAVERSE_STMT(StmtExpr, {})
DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (S->hasExplicitTemplateArgs()) {
@@ -2320,129 +2243,151 @@
DEF_TRAVERSE_STMT(SEHTryStmt, {})
DEF_TRAVERSE_STMT(SEHExceptStmt, {})
-DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
-DEF_TRAVERSE_STMT(CapturedStmt, {
- TRY_TO(TraverseDecl(S->getCapturedDecl()));
-})
+DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
-DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
-DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
-DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { })
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
+DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
// These operators (all of them) do not need any action except
// iterating over the children.
-DEF_TRAVERSE_STMT(BinaryConditionalOperator, { })
-DEF_TRAVERSE_STMT(ConditionalOperator, { })
-DEF_TRAVERSE_STMT(UnaryOperator, { })
-DEF_TRAVERSE_STMT(BinaryOperator, { })
-DEF_TRAVERSE_STMT(CompoundAssignOperator, { })
-DEF_TRAVERSE_STMT(CXXNoexceptExpr, { })
-DEF_TRAVERSE_STMT(PackExpansionExpr, { })
-DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
-DEF_TRAVERSE_STMT(FunctionParmPackExpr, { })
-DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
-DEF_TRAVERSE_STMT(AtomicExpr, { })
+DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
+DEF_TRAVERSE_STMT(ConditionalOperator, {})
+DEF_TRAVERSE_STMT(UnaryOperator, {})
+DEF_TRAVERSE_STMT(BinaryOperator, {})
+DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
+DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
+DEF_TRAVERSE_STMT(PackExpansionExpr, {})
+DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
+DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
+DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(AtomicExpr, {})
// These literals (all of them) do not need any action.
-DEF_TRAVERSE_STMT(IntegerLiteral, { })
-DEF_TRAVERSE_STMT(CharacterLiteral, { })
-DEF_TRAVERSE_STMT(FloatingLiteral, { })
-DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
-DEF_TRAVERSE_STMT(StringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCBoxedExpr, { })
-DEF_TRAVERSE_STMT(ObjCArrayLiteral, { })
-DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
-
+DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(CharacterLiteral, {})
+DEF_TRAVERSE_STMT(FloatingLiteral, {})
+DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
+DEF_TRAVERSE_STMT(StringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
+DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
+DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
+
// Traverse OpenCL: AsType, Convert.
-DEF_TRAVERSE_STMT(AsTypeExpr, { })
+DEF_TRAVERSE_STMT(AsTypeExpr, {})
// OpenMP directives.
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
- OMPExecutableDirective *S) {
+ OMPExecutableDirective *S) {
ArrayRef<OMPClause *> Clauses = S->clauses();
for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
I != E; ++I)
- if (!TraverseOMPClause(*I)) return false;
+ if (!TraverseOMPClause(*I))
+ return false;
return true;
}
DEF_TRAVERSE_STMT(OMPParallelDirective, {
- if (!TraverseOMPExecutableDirective(S)) return false;
+ if (!TraverseOMPExecutableDirective(S))
+ return false;
})
DEF_TRAVERSE_STMT(OMPSimdDirective, {
- if (!TraverseOMPExecutableDirective(S)) return false;
+ if (!TraverseOMPExecutableDirective(S))
+ return false;
})
// OpenMP clauses.
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
- if (!C) return true;
+ if (!C)
+ return true;
switch (C->getClauseKind()) {
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_##Name: \
- return getDerived().Visit##Class(static_cast<Class*>(C));
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name: \
+ return getDerived().Visit##Class(static_cast<Class *>(C));
#include "clang/Basic/OpenMPKinds.def"
- default: break;
+ default:
+ break;
}
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
TraverseStmt(C->getCondition());
return true;
}
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(
- OMPNumThreadsClause *C) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
TraverseStmt(C->getNumThreads());
return true;
}
-template <typename Derived>
+template<typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
TraverseStmt(C->getSafelen());
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
+ TraverseStmt(C->getNumForLoops());
+ return true;
+}
+
template<typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
return true;
}
-template<typename Derived>
-template<typename T>
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *C) {
+ return true;
+}
+
+template <typename Derived>
+template <typename T>
void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
for (auto *I : Node->varlists())
TraverseStmt(I);
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
VisitOMPClauseList(C);
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
- OMPFirstprivateClause *C) {
+ OMPFirstprivateClause *C) {
VisitOMPClauseList(C);
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
VisitOMPClauseList(C);
return true;
}
-template<typename Derived>
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
+ VisitOMPClauseList(C);
+ TraverseStmt(C->getStep());
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
VisitOMPClauseList(C);
return true;
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 1170eda..7aa11d4 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_REDECLARABLE_H
#define LLVM_CLANG_AST_REDECLARABLE_H
+#include "clang/AST/ExternalASTSource.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Casting.h"
#include <iterator>
@@ -23,26 +24,82 @@
/// \brief Provides common interface for the Decls that can be redeclared.
template<typename decl_type>
class Redeclarable {
-
protected:
class DeclLink {
- llvm::PointerIntPair<decl_type *, 1, bool> NextAndIsPrevious;
- public:
- DeclLink(decl_type *D, bool isLatest)
- : NextAndIsPrevious(D, isLatest) { }
+ /// A pointer to a known latest declaration, either statically known or
+ /// generationally updated as decls are added by an external source.
+ typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
+ &ExternalASTSource::CompleteRedeclChain>
+ KnownLatest;
- bool NextIsPrevious() const { return !NextAndIsPrevious.getInt(); }
- bool NextIsLatest() const { return NextAndIsPrevious.getInt(); }
- decl_type *getNext() const { return NextAndIsPrevious.getPointer(); }
- void setNext(decl_type *D) { NextAndIsPrevious.setPointer(D); }
+ typedef const ASTContext *UninitializedLatest;
+ typedef Decl *Previous;
+
+ /// A pointer to either an uninitialized latest declaration (where either
+ /// we've not yet set the previous decl or there isn't one), or to a known
+ /// previous declaration.
+ typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
+
+ mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
+
+ public:
+ enum PreviousTag { PreviousLink };
+ enum LatestTag { LatestLink };
+
+ DeclLink(LatestTag, const ASTContext &Ctx)
+ : Next(NotKnownLatest(&Ctx)) {}
+ DeclLink(PreviousTag, decl_type *D)
+ : Next(NotKnownLatest(Previous(D))) {}
+
+ bool NextIsPrevious() const {
+ return Next.is<NotKnownLatest>() &&
+ // FIXME: 'template' is required on the next line due to an
+ // apparent clang bug.
+ Next.get<NotKnownLatest>().template is<Previous>();
+ }
+
+ bool NextIsLatest() const { return !NextIsPrevious(); }
+
+ decl_type *getNext(const decl_type *D) const {
+ if (Next.is<NotKnownLatest>()) {
+ NotKnownLatest NKL = Next.get<NotKnownLatest>();
+ if (NKL.is<Previous>())
+ return static_cast<decl_type*>(NKL.get<Previous>());
+
+ // Allocate the generational 'most recent' cache now, if needed.
+ Next = KnownLatest(*NKL.get<UninitializedLatest>(),
+ const_cast<decl_type *>(D));
+ }
+
+ return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
+ }
+
+ void setPrevious(decl_type *D) {
+ assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
+ Next = Previous(D);
+ }
+
+ void setLatest(decl_type *D) {
+ assert(NextIsLatest() && "decl became canonical unexpectedly");
+ if (Next.is<NotKnownLatest>()) {
+ NotKnownLatest NKL = Next.get<NotKnownLatest>();
+ Next = KnownLatest(*NKL.get<UninitializedLatest>(), D);
+ } else {
+ auto Latest = Next.get<KnownLatest>();
+ Latest.set(D);
+ Next = Latest;
+ }
+ }
+
+ void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
};
static DeclLink PreviousDeclLink(decl_type *D) {
- return DeclLink(D, false);
+ return DeclLink(DeclLink::PreviousLink, D);
}
- static DeclLink LatestDeclLink(decl_type *D) {
- return DeclLink(D, true);
+ static DeclLink LatestDeclLink(const ASTContext &Ctx) {
+ return DeclLink(DeclLink::LatestLink, Ctx);
}
/// \brief Points to the next redeclaration in the chain.
@@ -58,15 +115,20 @@
/// If there is only one declaration, it is <pointer to self, true>
DeclLink RedeclLink;
+ decl_type *getNextRedeclaration() const {
+ return RedeclLink.getNext(static_cast<const decl_type *>(this));
+ }
+
public:
- Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { }
+ Redeclarable(const ASTContext &Ctx)
+ : RedeclLink(LatestDeclLink(Ctx)) {}
/// \brief Return the previous declaration of this declaration or NULL if this
/// is the first declaration.
decl_type *getPreviousDecl() {
if (RedeclLink.NextIsPrevious())
- return RedeclLink.getNext();
- return 0;
+ return getNextRedeclaration();
+ return nullptr;
}
const decl_type *getPreviousDecl() const {
return const_cast<decl_type *>(
@@ -96,14 +158,14 @@
/// \brief Returns the most recent (re)declaration of this declaration.
decl_type *getMostRecentDecl() {
- return getFirstDecl()->RedeclLink.getNext();
+ return getFirstDecl()->getNextRedeclaration();
}
/// \brief Returns the most recent (re)declaration of this declaration.
const decl_type *getMostRecentDecl() const {
- return getFirstDecl()->RedeclLink.getNext();
+ return getFirstDecl()->getNextRedeclaration();
}
-
+
/// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
/// first and only declaration.
void setPreviousDecl(decl_type *PrevDecl);
@@ -122,7 +184,7 @@
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- redecl_iterator() : Current(0) { }
+ redecl_iterator() : Current(nullptr) { }
explicit redecl_iterator(decl_type *C)
: Current(C), Starter(C), PassedFirst(false) { }
@@ -135,15 +197,15 @@
if (Current->isFirstDecl()) {
if (PassedFirst) {
assert(0 && "Passed first decl twice, invalid redecl chain!");
- Current = 0;
+ Current = nullptr;
return *this;
}
PassedFirst = true;
}
// Get either previous decl or latest decl.
- decl_type *Next = Current->RedeclLink.getNext();
- Current = (Next != Starter ? Next : 0);
+ decl_type *Next = Current->getNextRedeclaration();
+ Current = (Next != Starter) ? Next : nullptr;
return *this;
}
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index ae34f42..88cbb21 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -62,7 +62,7 @@
Stmt** I;
public:
ExprIterator(Stmt** i) : I(i) {}
- ExprIterator() : I(0) {}
+ ExprIterator() : I(nullptr) {}
ExprIterator& operator++() { ++I; return *this; }
ExprIterator operator-(size_t i) { return I-i; }
ExprIterator operator+(size_t i) { return I+i; }
@@ -81,7 +81,7 @@
const Stmt * const *I;
public:
ConstExprIterator(const Stmt * const *i) : I(i) {}
- ConstExprIterator() : I(0) {}
+ ConstExprIterator() : I(nullptr) {}
ConstExprIterator& operator++() { ++I; return *this; }
ConstExprIterator operator+(size_t i) const { return I+i; }
ConstExprIterator operator-(size_t i) const { return I-i; }
@@ -555,13 +555,13 @@
// \brief Build an empty compound statement with a location.
explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), Body(0), LBracLoc(Loc), RBracLoc(Loc) {
+ : Stmt(CompoundStmtClass), Body(nullptr), LBracLoc(Loc), RBracLoc(Loc) {
CompoundStmtBits.NumStmts = 0;
}
// \brief Build an empty compound statement.
explicit CompoundStmt(EmptyShell Empty)
- : Stmt(CompoundStmtClass, Empty), Body(0) {
+ : Stmt(CompoundStmtClass, Empty), Body(nullptr) {
CompoundStmtBits.NumStmts = 0;
}
@@ -576,7 +576,7 @@
body_range body() { return body_range(body_begin(), body_end()); }
body_iterator body_begin() { return Body; }
body_iterator body_end() { return Body + size(); }
- Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; }
+ Stmt *body_back() { return !body_empty() ? Body[size()-1] : nullptr; }
void setLastStmt(Stmt *S) {
assert(!body_empty() && "setLastStmt");
@@ -591,7 +591,9 @@
}
const_body_iterator body_begin() const { return Body; }
const_body_iterator body_end() const { return Body + size(); }
- const Stmt *body_back() const { return !body_empty() ? Body[size()-1] : 0; }
+ const Stmt *body_back() const {
+ return !body_empty() ? Body[size() - 1] : nullptr;
+ }
typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
reverse_body_iterator body_rbegin() {
@@ -644,10 +646,11 @@
SourceLocation ColonLoc;
SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
- : Stmt(SC), NextSwitchCase(0), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {}
+ : Stmt(SC), NextSwitchCase(nullptr), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {
+ }
SwitchCase(StmtClass SC, EmptyShell)
- : Stmt(SC), NextSwitchCase(0) {}
+ : Stmt(SC), NextSwitchCase(nullptr) {}
public:
const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
@@ -684,7 +687,7 @@
CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
SourceLocation ellipsisLoc, SourceLocation colonLoc)
: SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
- SubExprs[SUBSTMT] = 0;
+ SubExprs[SUBSTMT] = nullptr;
SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
EllipsisLoc = ellipsisLoc;
@@ -816,21 +819,25 @@
Stmt *SubStmt;
SourceLocation AttrLoc;
unsigned NumAttrs;
- const Attr *Attrs[1];
friend class ASTStmtReader;
AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
: Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
NumAttrs(Attrs.size()) {
- memcpy(this->Attrs, Attrs.data(), Attrs.size() * sizeof(Attr*));
+ memcpy(getAttrArrayPtr(), Attrs.data(), Attrs.size() * sizeof(Attr *));
}
explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
: Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
- memset(Attrs, 0, NumAttrs * sizeof(Attr*));
+ memset(getAttrArrayPtr(), 0, NumAttrs * sizeof(Attr *));
}
+ Attr *const *getAttrArrayPtr() const {
+ return reinterpret_cast<Attr *const *>(this + 1);
+ }
+ Attr **getAttrArrayPtr() { return reinterpret_cast<Attr **>(this + 1); }
+
public:
static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
@@ -839,7 +846,7 @@
SourceLocation getAttrLoc() const { return AttrLoc; }
ArrayRef<const Attr*> getAttrs() const {
- return ArrayRef<const Attr*>(Attrs, NumAttrs);
+ return ArrayRef<const Attr*>(getAttrArrayPtr(), NumAttrs);
}
Stmt *getSubStmt() { return SubStmt; }
const Stmt *getSubStmt() const { return SubStmt; }
@@ -866,7 +873,8 @@
public:
IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
- Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0);
+ Stmt *then, SourceLocation EL = SourceLocation(),
+ Stmt *elsev = nullptr);
/// \brief Build an empty if/then/else statement
explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
@@ -1334,7 +1342,8 @@
public:
ReturnStmt(SourceLocation RL)
- : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
+ : Stmt(ReturnStmtClass), RetExpr(nullptr), RetLoc(RL),
+ NRVOCandidate(nullptr) {}
ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
: Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
@@ -1403,7 +1412,7 @@
public:
/// \brief Build an empty inline-assembly statement.
explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
- Stmt(SC, Empty), Exprs(0) { }
+ Stmt(SC, Empty), Exprs(nullptr) { }
SourceLocation getAsmLoc() const { return AsmLoc; }
void setAsmLoc(SourceLocation L) { AsmLoc = L; }
@@ -1531,7 +1540,7 @@
/// \brief Build an empty inline-assembly statement.
explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
- Constraints(0), Clobbers(0), Names(0) { }
+ Constraints(nullptr), Clobbers(nullptr), Names(nullptr) { }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
@@ -1707,7 +1716,7 @@
/// \brief Build an empty MS-style inline-assembly statement.
explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
- NumAsmToks(0), AsmToks(0), Constraints(0), Clobbers(0) { }
+ NumAsmToks(0), AsmToks(nullptr), Constraints(nullptr), Clobbers(nullptr) { }
SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
@@ -1942,11 +1951,12 @@
///
/// \param Var The variable being captured, or null if capturing this.
///
- Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0)
+ Capture(SourceLocation Loc, VariableCaptureKind Kind,
+ VarDecl *Var = nullptr)
: VarAndKind(Var, Kind), Loc(Loc) {
switch (Kind) {
case VCK_This:
- assert(Var == 0 && "'this' capture cannot have a variable!");
+ assert(!Var && "'this' capture cannot have a variable!");
break;
case VCK_ByRef:
assert(Var && "capturing by reference must have a variable!");
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index df98d41..837dc45 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -39,7 +39,7 @@
HandlerBlock(handlerBlock) {}
CXXCatchStmt(EmptyShell Empty)
- : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
+ : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index a31632f..18c5516 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -64,10 +64,10 @@
Stmt*& GetDeclExpr() const;
- StmtIteratorBase(Stmt **s) : stmt(s), DGI(0), RawVAPtr(0) {}
+ StmtIteratorBase(Stmt **s) : stmt(s), DGI(nullptr), RawVAPtr(0) {}
StmtIteratorBase(const VariableArrayType *t);
StmtIteratorBase(Decl **dgi, Decl **dge);
- StmtIteratorBase() : stmt(0), DGI(0), RawVAPtr(0) {}
+ StmtIteratorBase() : stmt(nullptr), DGI(nullptr), RawVAPtr(0) {}
};
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index bfb4a9b..d0527e2 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -107,7 +107,7 @@
SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; }
SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); }
- bool hasEllipsis() const { return getCatchParamDecl() == 0; }
+ bool hasEllipsis() const { return getCatchParamDecl() == nullptr; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtCatchStmtClass;
@@ -222,13 +222,13 @@
/// \brief Retrieve the \@finally statement, if any.
const ObjCAtFinallyStmt *getFinallyStmt() const {
if (!HasFinally)
- return 0;
+ return nullptr;
return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
}
ObjCAtFinallyStmt *getFinallyStmt() {
if (!HasFinally)
- return 0;
+ return nullptr;
return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
}
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index abe106c..d1f428d 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -204,7 +204,7 @@
}
static TemplateArgument getEmptyPack() {
- return TemplateArgument((TemplateArgument*)0, 0);
+ return TemplateArgument((TemplateArgument*)nullptr, 0);
}
/// \brief Create a new template argument pack by copying the given set of
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index 0b9d4c8..f3d23b9 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -15,7 +15,6 @@
#define LLVM_CLANG_AST_TEMPLATENAME_H
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/OperatorKinds.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
@@ -25,13 +24,14 @@
class DependentTemplateName;
class DiagnosticBuilder;
class IdentifierInfo;
+class NamedDecl;
class NestedNameSpecifier;
+enum OverloadedOperatorKind : int;
class OverloadedTemplateStorage;
struct PrintingPolicy;
class QualifiedTemplateName;
-class NamedDecl;
-class SubstTemplateTemplateParmStorage;
class SubstTemplateTemplateParmPackStorage;
+class SubstTemplateTemplateParmStorage;
class TemplateArgument;
class TemplateDecl;
class TemplateTemplateParmDecl;
@@ -71,19 +71,19 @@
OverloadedTemplateStorage *getAsOverloadedStorage() {
return Bits.Kind == Overloaded
? reinterpret_cast<OverloadedTemplateStorage *>(this)
- : 0;
+ : nullptr;
}
SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
return Bits.Kind == SubstTemplateTemplateParm
? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
- : 0;
+ : nullptr;
}
SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
return Bits.Kind == SubstTemplateTemplateParmPack
? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
- : 0;
+ : nullptr;
}
};
@@ -243,7 +243,7 @@
Storage.dyn_cast<UncommonTemplateNameStorage *>())
return Uncommon->getAsOverloadedStorage();
- return 0;
+ return nullptr;
}
/// \brief Retrieve the substituted template template parameter, if
@@ -256,7 +256,7 @@
Storage.dyn_cast<UncommonTemplateNameStorage *>())
return uncommon->getAsSubstTemplateTemplateParm();
- return 0;
+ return nullptr;
}
/// \brief Retrieve the substituted template template parameter pack, if
@@ -270,7 +270,7 @@
Storage.dyn_cast<UncommonTemplateNameStorage *>())
return Uncommon->getAsSubstTemplateTemplateParmPack();
- return 0;
+ return nullptr;
}
/// \brief Retrieve the underlying qualified template name
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 7be6fcd..1727762 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -18,13 +18,12 @@
#include "clang/AST/TemplateName.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/ExceptionSpecificationType.h"
-#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/Visibility.h"
-#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/Optional.h"
@@ -500,7 +499,7 @@
/// The local qualifiers.
Qualifiers Quals;
- SplitQualType() : Ty(0), Quals() {}
+ SplitQualType() : Ty(nullptr), Quals() {}
SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
SplitQualType getSingleStepDesugaredType() const; // end of this file
@@ -1438,7 +1437,7 @@
/// \brief Def If non-NULL, and the type refers to some kind of declaration
/// that can be completed (such as a C struct, C++ class, or Objective-C
/// class), will be set to the declaration.
- bool isIncompleteType(NamedDecl **Def = 0) const;
+ bool isIncompleteType(NamedDecl **Def = nullptr) const;
/// isIncompleteOrObjectType - Return true if this is an incomplete or object
/// type, in other words, not a function type.
@@ -2850,14 +2849,16 @@
ExtProtoInfo()
: Variadic(false), HasTrailingReturn(false), TypeQuals(0),
ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
- Exceptions(0), NoexceptExpr(0), ExceptionSpecDecl(0),
- ExceptionSpecTemplate(0), ConsumedParameters(0) {}
+ Exceptions(nullptr), NoexceptExpr(nullptr),
+ ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
+ ConsumedParameters(nullptr) {}
ExtProtoInfo(CallingConv CC)
: ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
- Exceptions(0), NoexceptExpr(0), ExceptionSpecDecl(0),
- ExceptionSpecTemplate(0), ConsumedParameters(0) {}
+ Exceptions(nullptr), NoexceptExpr(nullptr),
+ ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
+ ConsumedParameters(nullptr) {}
FunctionType::ExtInfo ExtInfo;
bool Variadic : 1;
@@ -3011,7 +3012,7 @@
}
Expr *getNoexceptExpr() const {
if (getExceptionSpecType() != EST_ComputedNoexcept)
- return 0;
+ return nullptr;
// NoexceptExpr sits where the arguments end.
return *reinterpret_cast<Expr *const *>(param_type_end());
}
@@ -3022,7 +3023,7 @@
FunctionDecl *getExceptionSpecDecl() const {
if (getExceptionSpecType() != EST_Uninstantiated &&
getExceptionSpecType() != EST_Unevaluated)
- return 0;
+ return nullptr;
return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
}
/// \brief If this function type has an uninstantiated exception
@@ -3031,7 +3032,7 @@
/// this type.
FunctionDecl *getExceptionSpecTemplate() const {
if (getExceptionSpecType() != EST_Uninstantiated)
- return 0;
+ return nullptr;
return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
}
/// \brief Determine whether this function type has a non-throwing exception
@@ -3519,7 +3520,7 @@
bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
TemplateTypeParmDecl *getDecl() const {
- return isCanonicalUnqualified() ? 0 : TTPDecl;
+ return isCanonicalUnqualified() ? nullptr : TTPDecl;
}
IdentifierInfo *getIdentifier() const;
@@ -3980,9 +3981,9 @@
static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
- static const char *getKeywordName(ElaboratedTypeKeyword Keyword);
+ static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
- static const char *getTagTypeKindName(TagTypeKind Kind) {
+ static StringRef getTagTypeKindName(TagTypeKind Kind) {
return getKeywordName(getKeywordForTagTypeKind(Kind));
}
@@ -4014,7 +4015,7 @@
NamedType->isVariablyModifiedType(),
NamedType->containsUnexpandedParameterPack()),
NNS(NNS), NamedType(NamedType) {
- assert(!(Keyword == ETK_None && NNS == 0) &&
+ assert(!(Keyword == ETK_None && NNS == nullptr) &&
"ElaboratedType cannot have elaborated type keyword "
"and name qualifier both null.");
}
@@ -4223,7 +4224,7 @@
Optional<unsigned> NumExpansions)
: Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
/*InstantiationDependent=*/true,
- /*VariableModified=*/Pattern->isVariablyModifiedType(),
+ /*VariablyModified=*/Pattern->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false),
Pattern(Pattern),
NumExpansions(NumExpansions? *NumExpansions + 1: 0) { }
@@ -4456,7 +4457,7 @@
if (const ObjCInterfaceType *T =
getBaseType()->getAs<ObjCInterfaceType>())
return T->getDecl();
- return 0;
+ return nullptr;
}
/// ObjCObjectPointerType - Used to represent a pointer to an
@@ -4661,7 +4662,7 @@
}
inline const Type *QualType::getTypePtrOrNull() const {
- return (isNull() ? 0 : getCommonPtr()->BaseType);
+ return (isNull() ? nullptr : getCommonPtr()->BaseType);
}
inline SplitQualType QualType::split() const {
@@ -5050,7 +5051,7 @@
if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
if (BT->isPlaceholderType())
return BT;
- return 0;
+ return nullptr;
}
inline bool Type::isSpecificPlaceholderType(unsigned K) const {
@@ -5205,7 +5206,7 @@
// If the canonical form of this type isn't the right kind, reject it.
if (!isa<T>(CanonicalType))
- return 0;
+ return nullptr;
// If this is a typedef for the type, strip the typedef off without
// losing all typedef information.
@@ -5219,7 +5220,7 @@
// If the canonical form of this type isn't the right kind, reject it.
if (!isa<ArrayType>(CanonicalType))
- return 0;
+ return nullptr;
// If this is a typedef for the type, strip the typedef off without
// losing all typedef information.
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index a54aee8..3648d2a 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -81,7 +81,7 @@
Qualified
};
- TypeLoc() : Ty(0), Data(0) { }
+ TypeLoc() : Ty(nullptr), Data(nullptr) { }
TypeLoc(QualType ty, void *opaqueData)
: Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
TypeLoc(const Type *ty, void *opaqueData)
@@ -631,7 +631,7 @@
bool isDefinition() const {
TagDecl *D = getDecl();
return D->isCompleteDefinition() &&
- (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
+ (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
}
};
@@ -786,7 +786,7 @@
setAttrNameLoc(loc);
if (hasAttrExprOperand()) {
setAttrOperandParensRange(SourceRange(loc));
- setAttrExprOperand(0);
+ setAttrExprOperand(nullptr);
} else if (hasAttrEnumOperand()) {
setAttrOperandParensRange(SourceRange(loc));
setAttrEnumOperandLoc(loc);
@@ -1101,7 +1101,7 @@
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
- setClassTInfo(0);
+ setClassTInfo(nullptr);
}
SourceRange getLocalSourceRange() const {
@@ -1238,7 +1238,7 @@
setRParenLoc(Loc);
setLocalRangeEnd(Loc);
for (unsigned i = 0, e = getNumParams(); i != e; ++i)
- setParam(i, NULL);
+ setParam(i, nullptr);
}
/// \brief Returns the size of the type source info data block that is
@@ -1314,7 +1314,7 @@
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLBracketLoc(Loc);
setRBracketLoc(Loc);
- setSizeExpr(NULL);
+ setSizeExpr(nullptr);
}
QualType getInnerType() const { return getTypePtr()->getElementType(); }
@@ -1774,7 +1774,7 @@
// template specialization type, we won't record the nested-name-specifier
// location information when this type-source location information is
// part of a nested-name-specifier.
- getLocalData()->QualifierData = 0;
+ getLocalData()->QualifierData = nullptr;
return;
}
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index 02132d8..4e24bdd 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -297,7 +297,7 @@
ThunksMapTy::const_iterator I = Thunks.find(MD);
if (I == Thunks.end()) {
// We did not find a thunk for this method.
- return 0;
+ return nullptr;
}
return &I->second;
@@ -419,7 +419,7 @@
/// The vptr is stored inside the non-virtual component of this virtual base.
const CXXRecordDecl *getVBaseWithVPtr() const {
- return ContainingVBases.empty() ? 0 : ContainingVBases.front();
+ return ContainingVBases.empty() ? nullptr : ContainingVBases.front();
}
};
@@ -458,7 +458,7 @@
uint64_t Index;
MethodVFTableLocation()
- : VBTableIndex(0), VBase(0), VFPtrOffset(CharUnits::Zero()),
+ : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()),
Index(0) {}
MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase,
@@ -524,7 +524,7 @@
// Complete destructors don't have a slot in a vftable, so no thunks needed.
if (isa<CXXDestructorDecl>(GD.getDecl()) &&
GD.getDtorType() == Dtor_Complete)
- return 0;
+ return nullptr;
return VTableContextBase::getThunkInfo(GD);
}
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index 8c8a509..8af0546 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -222,7 +222,7 @@
if (NodeT *Node = I->getNodeAs<NodeT>(BoundTo))
return Node;
}
- return NULL;
+ return nullptr;
}
namespace internal {
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 15621b7..0bfdc14 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -311,6 +311,12 @@
return Node.getAccess() == AS_private;
}
+/// \brief Matches a declaration that has been implicitly added
+/// by the compiler (eg. implicit default/copy constructors).
+AST_MATCHER(Decl, isImplicit) {
+ return Node.isImplicit();
+}
+
/// \brief Matches classTemplateSpecializations that have at least one
/// TemplateArgument matching the given InnerMatcher.
///
@@ -890,7 +896,7 @@
AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
InnerMatcher) {
const Stmt *const Increment = Node.getInc();
- return (Increment != NULL &&
+ return (Increment != nullptr &&
InnerMatcher.matches(*Increment, Finder, Builder));
}
@@ -905,7 +911,7 @@
AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
InnerMatcher) {
const Stmt *const Init = Node.getInit();
- return (Init != NULL && InnerMatcher.matches(*Init, Finder, Builder));
+ return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
}
/// \brief Matches range-based for statements.
@@ -928,7 +934,21 @@
AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>,
InnerMatcher) {
const VarDecl *const Var = Node.getLoopVariable();
- return (Var != NULL && InnerMatcher.matches(*Var, Finder, Builder));
+ return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder));
+}
+
+/// \brief Matches the range initialization statement of a for loop.
+///
+/// Example:
+/// forStmt(hasRangeInit(anything()))
+/// matches 'a' in
+/// \code
+/// for (int x : a) { }
+/// \endcode
+AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,
+ InnerMatcher) {
+ const Expr *const Init = Node.getRangeInit();
+ return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
}
/// \brief Matches while statements.
@@ -1766,7 +1786,7 @@
InnerMatcher) {
const Expr *ExprNode = Node.getImplicitObjectArgument()
->IgnoreParenImpCasts();
- return (ExprNode != NULL &&
+ return (ExprNode != nullptr &&
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
@@ -1789,7 +1809,7 @@
AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
InnerMatcher) {
const Expr *ExprNode = Node.getCallee();
- return (ExprNode != NULL &&
+ return (ExprNode != nullptr &&
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
@@ -1944,7 +1964,7 @@
AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
internal::Matcher<Expr>, InnerMatcher) {
const Expr *ExprNode = Node.getImplicitObjectArgument();
- return (ExprNode != NULL &&
+ return (ExprNode != nullptr &&
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
@@ -1977,7 +1997,7 @@
AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
InnerMatcher) {
const Decl *DeclNode = Node.getDecl();
- return (DeclNode != NULL &&
+ return (DeclNode != nullptr &&
InnerMatcher.matches(*DeclNode, Finder, Builder));
}
@@ -2034,7 +2054,7 @@
VarDecl, hasInitializer, internal::Matcher<Expr>,
InnerMatcher) {
const Expr *Initializer = Node.getAnyInitializer();
- return (Initializer != NULL &&
+ return (Initializer != nullptr &&
InnerMatcher.matches(*Initializer, Finder, Builder));
}
@@ -2146,7 +2166,7 @@
AST_MATCHER_P(CXXCtorInitializer, forField,
internal::Matcher<FieldDecl>, InnerMatcher) {
const FieldDecl *NodeAsDecl = Node.getMember();
- return (NodeAsDecl != NULL &&
+ return (NodeAsDecl != nullptr &&
InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
}
@@ -2166,7 +2186,7 @@
AST_MATCHER_P(CXXCtorInitializer, withInitializer,
internal::Matcher<Expr>, InnerMatcher) {
const Expr* NodeAsExpr = Node.getInit();
- return (NodeAsExpr != NULL &&
+ return (NodeAsExpr != nullptr &&
InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
}
@@ -2187,12 +2207,6 @@
return Node.isWritten();
}
-/// \brief Matches a constructor declaration that has been implicitly added
-/// by the compiler (eg. implicit default/copy constructors).
-AST_MATCHER(CXXConstructorDecl, isImplicit) {
- return Node.isImplicit();
-}
-
/// \brief Matches any argument of a call expression or a constructor call
/// expression.
///
@@ -2316,10 +2330,34 @@
IfStmt, ForStmt, WhileStmt, DoStmt, ConditionalOperator),
internal::Matcher<Expr>, InnerMatcher) {
const Expr *const Condition = Node.getCond();
- return (Condition != NULL &&
+ return (Condition != nullptr &&
InnerMatcher.matches(*Condition, Finder, Builder));
}
+/// \brief Matches the then-statement of an if statement.
+///
+/// Examples matches the if statement
+/// (matcher = ifStmt(hasThen(boolLiteral(equals(true)))))
+/// \code
+/// if (false) true; else false;
+/// \endcode
+AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher) {
+ const Stmt *const Then = Node.getThen();
+ return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder));
+}
+
+/// \brief Matches the else-statement of an if statement.
+///
+/// Examples matches the if statement
+/// (matcher = ifStmt(hasElse(boolLiteral(equals(true)))))
+/// \code
+/// if (false) false; else true;
+/// \endcode
+AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) {
+ const Stmt *const Else = Node.getElse();
+ return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder));
+}
+
/// \brief Matches if a node equals a previously bound node.
///
/// Matches a node if it equals the node previously bound to \p ID.
@@ -2368,7 +2406,7 @@
internal::Matcher<DeclStmt>, InnerMatcher) {
const DeclStmt* const DeclarationStatement =
Node.getConditionVariableDeclStmt();
- return DeclarationStatement != NULL &&
+ return DeclarationStatement != nullptr &&
InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
}
@@ -2416,11 +2454,13 @@
/// matches 'for (;;) {}'
/// with compoundStmt()
/// matching '{}'
-AST_POLYMORPHIC_MATCHER_P(
- hasBody, AST_POLYMORPHIC_SUPPORTED_TYPES_3(DoStmt, ForStmt, WhileStmt),
- internal::Matcher<Stmt>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(hasBody,
+ AST_POLYMORPHIC_SUPPORTED_TYPES_4(DoStmt, ForStmt,
+ WhileStmt,
+ CXXForRangeStmt),
+ internal::Matcher<Stmt>, InnerMatcher) {
const Stmt *const Statement = Node.getBody();
- return (Statement != NULL &&
+ return (Statement != nullptr &&
InnerMatcher.matches(*Statement, Finder, Builder));
}
@@ -2494,7 +2534,7 @@
AST_MATCHER_P(BinaryOperator, hasLHS,
internal::Matcher<Expr>, InnerMatcher) {
Expr *LeftHandSide = Node.getLHS();
- return (LeftHandSide != NULL &&
+ return (LeftHandSide != nullptr &&
InnerMatcher.matches(*LeftHandSide, Finder, Builder));
}
@@ -2507,7 +2547,7 @@
AST_MATCHER_P(BinaryOperator, hasRHS,
internal::Matcher<Expr>, InnerMatcher) {
Expr *RightHandSide = Node.getRHS();
- return (RightHandSide != NULL &&
+ return (RightHandSide != nullptr &&
InnerMatcher.matches(*RightHandSide, Finder, Builder));
}
@@ -2527,7 +2567,7 @@
AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
internal::Matcher<Expr>, InnerMatcher) {
const Expr * const Operand = Node.getSubExpr();
- return (Operand != NULL &&
+ return (Operand != nullptr &&
InnerMatcher.matches(*Operand, Finder, Builder));
}
@@ -2541,7 +2581,7 @@
AST_MATCHER_P(CastExpr, hasSourceExpression,
internal::Matcher<Expr>, InnerMatcher) {
const Expr* const SubExpression = Node.getSubExpr();
- return (SubExpression != NULL &&
+ return (SubExpression != nullptr &&
InnerMatcher.matches(*SubExpression, Finder, Builder));
}
@@ -2573,7 +2613,7 @@
AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
internal::Matcher<Expr>, InnerMatcher) {
Expr *Expression = Node.getTrueExpr();
- return (Expression != NULL &&
+ return (Expression != nullptr &&
InnerMatcher.matches(*Expression, Finder, Builder));
}
@@ -2586,7 +2626,7 @@
AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
internal::Matcher<Expr>, InnerMatcher) {
Expr *Expression = Node.getFalseExpr();
- return (Expression != NULL &&
+ return (Expression != nullptr &&
InnerMatcher.matches(*Expression, Finder, Builder));
}
@@ -2628,7 +2668,7 @@
AST_MATCHER_P(CXXMethodDecl, ofClass,
internal::Matcher<CXXRecordDecl>, InnerMatcher) {
const CXXRecordDecl *Parent = Node.getParent();
- return (Parent != NULL &&
+ return (Parent != nullptr &&
InnerMatcher.matches(*Parent, Finder, Builder));
}
@@ -3383,7 +3423,7 @@
/// matches "A::"
AST_MATCHER_P(NestedNameSpecifier, specifiesType,
internal::Matcher<QualType>, InnerMatcher) {
- if (Node.getAsType() == NULL)
+ if (!Node.getAsType())
return false;
return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
}
@@ -3417,7 +3457,7 @@
internal::Matcher<NestedNameSpecifier>, InnerMatcher,
0) {
NestedNameSpecifier *NextNode = Node.getPrefix();
- if (NextNode == NULL)
+ if (!NextNode)
return false;
return InnerMatcher.matches(*NextNode, Finder, Builder);
}
@@ -3452,7 +3492,7 @@
/// matches "ns::"
AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
internal::Matcher<NamespaceDecl>, InnerMatcher) {
- if (Node.getAsNamespace() == NULL)
+ if (!Node.getAsNamespace())
return false;
return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
}
@@ -3464,15 +3504,15 @@
/// \brief Matches if a node equals another node.
///
/// \c Decl has pointer identity in the AST.
-AST_MATCHER_P_OVERLOAD(Decl, equalsNode, Decl*, Other, 0) {
- return &Node == Other;
+inline internal::Matcher<Decl> equalsNode(const Decl *Node) {
+ return internal::makeMatcher(new internal::EqualsNodeMatcher<Decl>(Node));
}
/// \brief Matches if a node equals another node.
///
/// \c Stmt has pointer identity in the AST.
///
-AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, Stmt*, Other, 1) {
- return &Node == Other;
+inline internal::Matcher<Stmt> equalsNode(const Stmt *Node) {
+ return internal::makeMatcher(new internal::EqualsNodeMatcher<Stmt>(Node));
}
/// @}
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 23885a1..c0dd7b8 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -74,7 +74,7 @@
const T *getNodeAs(StringRef ID) const {
IDToNodeMap::const_iterator It = NodeMap.find(ID);
if (It == NodeMap.end()) {
- return NULL;
+ return nullptr;
}
return It->second.get<T>();
}
@@ -507,7 +507,7 @@
static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
template<typename C> static char (&f(...))[2];
- static bool const value = sizeof(f<Derived>(0)) == 2;
+ static bool const value = sizeof(f<Derived>(nullptr)) == 2;
};
/// \brief Matches overloaded operators with a specific name.
@@ -626,7 +626,7 @@
bool matchesDecl(const Decl *Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- return Node != NULL && InnerMatcher.matches(*Node, Finder, Builder);
+ return Node != nullptr && InnerMatcher.matches(*Node, Finder, Builder);
}
const Matcher<Decl> InnerMatcher;
@@ -1387,6 +1387,20 @@
const ValueT ExpectedValue;
};
+template <typename T>
+class EqualsNodeMatcher : public SingleNodeMatcherInterface<T> {
+public:
+ explicit EqualsNodeMatcher(const T *ExpectedNode)
+ : ExpectedNode(ExpectedNode) {}
+
+ bool matchesNode(const T &Node) const override {
+ return &Node == ExpectedNode;
+ }
+
+private:
+ const T *ExpectedNode;
+};
+
/// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
/// variadic functor that takes a number of Matcher<TargetT> and returns a
/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
index 53629bf..82a14f1 100644
--- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -60,11 +60,12 @@
enum ErrorType {
ET_None = 0,
- ET_RegistryNotFound = 1,
+ ET_RegistryMatcherNotFound = 1,
ET_RegistryWrongArgCount = 2,
ET_RegistryWrongArgType = 3,
ET_RegistryNotBindable = 4,
ET_RegistryAmbiguousOverload = 5,
+ ET_RegistryValueNotFound = 6,
ET_ParserStringError = 100,
ET_ParserNoOpenParen = 101,
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
index 5901495..4045f57 100644
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -18,13 +18,14 @@
///
/// \code
/// Grammar for the expressions supported:
-/// <Expression> := <Literal> | <MatcherExpression>
+/// <Expression> := <Literal> | <NamedValue> | <MatcherExpression>
/// <Literal> := <StringLiteral> | <Unsigned>
/// <StringLiteral> := "quoted string"
/// <Unsigned> := [0-9]+
-/// <MatcherExpression> := <MatcherName>(<ArgumentList>) |
-/// <MatcherName>(<ArgumentList>).bind(<StringLiteral>)
-/// <MatcherName> := [a-zA-Z]+
+/// <NamedValue> := <Identifier>
+/// <MatcherExpression> := <Identifier>(<ArgumentList>) |
+/// <Identifier>(<ArgumentList>).bind(<StringLiteral>)
+/// <Identifier> := [a-zA-Z]+
/// <ArgumentList> := <Expression> | <Expression>,<ArgumentList>
/// \endcode
///
@@ -62,6 +63,17 @@
public:
virtual ~Sema();
+ /// \brief Lookup a value by name.
+ ///
+ /// This can be used in the Sema layer to declare known constants or to
+ /// allow to split an expression in pieces.
+ ///
+ /// \param Name The name of the value to lookup.
+ ///
+ /// \return The named value. It could be any type that VariantValue
+ /// supports. An empty value means that the name is not recognized.
+ virtual VariantValue getNamedValue(StringRef Name);
+
/// \brief Process a matcher expression.
///
/// All the arguments passed here have already been processed.
@@ -89,15 +101,26 @@
///
/// \param MatcherName The matcher name found by the parser.
///
- /// \param NameRange The location of the name in the matcher source.
- /// Useful for error reporting.
- ///
- /// \return The matcher constructor, or Optional<MatcherCtor>() if an error
- /// occurred. In that case, \c Error will contain a description of the
- /// error.
+ /// \return The matcher constructor, or Optional<MatcherCtor>() if not
+ /// found.
virtual llvm::Optional<MatcherCtor>
- lookupMatcherCtor(StringRef MatcherName, const SourceRange &NameRange,
- Diagnostics *Error) = 0;
+ lookupMatcherCtor(StringRef MatcherName) = 0;
+ };
+
+ /// \brief Sema implementation that uses the matcher registry to process the
+ /// tokens.
+ class RegistrySema : public Parser::Sema {
+ public:
+ virtual ~RegistrySema();
+
+ llvm::Optional<MatcherCtor>
+ lookupMatcherCtor(StringRef MatcherName) override;
+
+ VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
+ const SourceRange &NameRange,
+ StringRef BindID,
+ ArrayRef<ParserValue> Args,
+ Diagnostics *Error) override;
};
/// \brief Parse a matcher expression, creating matchers from the registry.
@@ -160,7 +183,9 @@
Diagnostics *Error);
bool parseExpressionImpl(VariantValue *Value);
- bool parseMatcherExpressionImpl(VariantValue *Value);
+ bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
+ VariantValue *Value);
+ bool parseIdentifierPrefixImpl(VariantValue *Value);
void addCompletion(const TokenInfo &CompToken, StringRef TypedText,
StringRef Decl);
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index d7df698..72ae612 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -55,11 +55,8 @@
/// \brief Look up a matcher in the registry by name,
///
/// \return An opaque value which may be used to refer to the matcher
- /// constructor, or Optional<MatcherCtor>() if not found. In that case
- /// \c Error will contain the description of the error.
- static llvm::Optional<MatcherCtor>
- lookupMatcherCtor(StringRef MatcherName, const SourceRange &NameRange,
- Diagnostics *Error);
+ /// constructor, or Optional<MatcherCtor>() if not found.
+ static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
/// \brief Compute the list of completions for \p Context.
///
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
index c685357..b25267b 100644
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -78,7 +78,8 @@
/// \brief Clones the provided matchers.
///
/// They should be the result of a polymorphic matcher.
- static VariantMatcher PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
+ static VariantMatcher
+ PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
/// \brief Creates a 'variadic' operator matcher.
///
@@ -173,7 +174,7 @@
Func, DynMatchers)));
}
- bool hasMatcher() const { return Out.get() != NULL; }
+ bool hasMatcher() const { return Out.get() != nullptr; }
const MatcherT &matcher() const { return *Out; }
private:
@@ -208,6 +209,10 @@
VariantValue(const std::string &String);
VariantValue(const VariantMatcher &Matchers);
+ /// \brief Returns true iff this is not an empty value.
+ LLVM_EXPLICIT operator bool() const { return hasValue(); }
+ bool hasValue() const { return Type != VT_Nothing; }
+
/// \brief Unsigned value functions.
bool isUnsigned() const;
unsigned getUnsigned() const;
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index 7de4b59..36e07c2 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -142,7 +142,7 @@
TmpMapType TmpMap;
public:
- ConsumedStateMap() : Reachable(true), From(NULL) {}
+ ConsumedStateMap() : Reachable(true), From(nullptr) {}
ConsumedStateMap(const ConsumedStateMap &Other)
: Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap),
TmpMap() {}
@@ -185,8 +185,8 @@
/// \brief Set the consumed state of a given temporary value.
void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State);
- /// \brief Remove the variable from our state map.
- void remove(const VarDecl *Var);
+ /// \brief Remove the temporary value from our state map.
+ void remove(const CXXBindTemporaryExpr *Tmp);
/// \brief Tests to see if there is a mismatch in the states stored in two
/// maps.
@@ -201,9 +201,10 @@
public:
ConsumedBlockInfo() { }
-
+ ~ConsumedBlockInfo() { llvm::DeleteContainerPointers(StateMapsArray); }
+
ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph)
- : StateMapsArray(NumBlocks, 0), VisitOrder(NumBlocks, 0) {
+ : StateMapsArray(NumBlocks, nullptr), VisitOrder(NumBlocks, 0) {
unsigned int VisitOrderCounter = 0;
for (PostOrderCFGView::iterator BI = SortedGraph->begin(),
BE = SortedGraph->end(); BI != BE; ++BI) {
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 1bfd05d..6c6d923 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -153,7 +153,7 @@
/// \brief This method converts the dominator tree to human readable form.
///
- virtual void print(raw_ostream &OS, const llvm::Module* M= 0) const {
+ virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const {
DT->print(OS);
}
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index 3bffcd3..76fe9dd 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -83,7 +83,7 @@
};
LengthModifier()
- : Position(0), kind(None) {}
+ : Position(nullptr), kind(None) {}
LengthModifier(const char *pos, Kind k)
: Position(pos), kind(k) {}
@@ -169,10 +169,11 @@
};
ConversionSpecifier(bool isPrintf = true)
- : IsPrintf(isPrintf), Position(0), EndScanList(0), kind(InvalidSpecifier) {}
+ : IsPrintf(isPrintf), Position(nullptr), EndScanList(nullptr),
+ kind(InvalidSpecifier) {}
ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
- : IsPrintf(isPrintf), Position(pos), EndScanList(0), kind(k) {}
+ : IsPrintf(isPrintf), Position(pos), EndScanList(nullptr), kind(k) {}
const char *getStart() const {
return Position;
@@ -226,10 +227,11 @@
const char *Name;
bool Ptr;
public:
- ArgType(Kind k = UnknownTy, const char *n = 0) : K(k), Name(n), Ptr(false) {}
- ArgType(QualType t, const char *n = 0)
+ ArgType(Kind k = UnknownTy, const char *n = nullptr)
+ : K(k), Name(n), Ptr(false) {}
+ ArgType(QualType t, const char *n = nullptr)
: K(SpecificTy), T(t), Name(n), Ptr(false) {}
- ArgType(CanQualType t) : K(SpecificTy), T(t), Name(0), Ptr(false) {}
+ ArgType(CanQualType t) : K(SpecificTy), T(t), Name(nullptr), Ptr(false) {}
static ArgType Invalid() { return ArgType(InvalidTy); }
bool isValid() const { return K != InvalidTy; }
@@ -262,7 +264,7 @@
UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
OptionalAmount(bool valid = true)
- : start(0),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
+ : start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
UsesPositionalArg(0), UsesDotPrefix(0) {}
bool isInvalid() const {
@@ -389,7 +391,7 @@
public analyze_format_string::ConversionSpecifier {
public:
PrintfConversionSpecifier()
- : ConversionSpecifier(true, 0, InvalidSpecifier) {}
+ : ConversionSpecifier(true, nullptr, InvalidSpecifier) {}
PrintfConversionSpecifier(const char *pos, Kind k)
: ConversionSpecifier(true, pos, k) {}
@@ -525,7 +527,7 @@
public analyze_format_string::ConversionSpecifier {
public:
ScanfConversionSpecifier()
- : ConversionSpecifier(false, 0, InvalidSpecifier) {}
+ : ConversionSpecifier(false, nullptr, InvalidSpecifier) {}
ScanfConversionSpecifier(const char *pos, Kind k)
: ConversionSpecifier(false, pos, k) {}
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index bbd2b02..7842271 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -38,7 +38,7 @@
bool equals(const LivenessValues &V) const;
LivenessValues()
- : liveStmts(0), liveDecls(0) {}
+ : liveStmts(nullptr), liveDecls(nullptr) {}
LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts,
llvm::ImmutableSet<const VarDecl *> LiveDecls)
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
index 4e3244e..91bf51c 100644
--- a/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -52,7 +52,7 @@
// make sure that Block is non-null. Moreover, the CFGBlock iterator will
// occasionally hand out null pointers for pruned edges, so we catch those
// here.
- if (Block == 0)
+ if (!Block)
return false; // if an edge is trivially false.
if (VisitedBlockIDs.test(Block->getBlockID()))
return false;
@@ -76,14 +76,18 @@
BlockOrderTy BlockOrder;
public:
- typedef std::vector<const CFGBlock*>::reverse_iterator iterator;
+ typedef std::vector<const CFGBlock *>::reverse_iterator iterator;
+ typedef std::vector<const CFGBlock *>::const_reverse_iterator const_iterator;
PostOrderCFGView(const CFG *cfg);
iterator begin() { return Blocks.rbegin(); }
iterator end() { return Blocks.rend(); }
- bool empty() { return begin() == end(); }
+ const_iterator begin() const { return Blocks.rbegin(); }
+ const_iterator end() const { return Blocks.rend(); }
+
+ bool empty() const { return begin() == end(); }
struct BlockOrderCompare;
friend struct BlockOrderCompare;
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index d8c0801..b533c1d 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -159,7 +159,7 @@
virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
ProtectedOperationKind POK, Name LockName,
LockKind LK, SourceLocation Loc,
- Name *PossibleMatch = 0) {}
+ Name *PossibleMatch = nullptr) {}
/// Warn when a function is called while an excluded mutex is locked. For
/// example, the mutex may be locked inside the function.
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
new file mode 100644
index 0000000..a83cbc5
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -0,0 +1,393 @@
+//===- ThreadSafetyCommon.h ------------------------------------*- C++ --*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Parts of thread safety analysis that are not specific to thread safety
+// itself have been factored into classes here, where they can be potentially
+// used by other analyses. Currently these include:
+//
+// * Generalize clang CFG visitors.
+// * Conversion of the clang CFG to SSA form.
+// * Translation of clang Exprs to TIL SExprs
+//
+// UNDER CONSTRUCTION. USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_COMMON_H
+#define LLVM_CLANG_THREAD_SAFETY_COMMON_H
+
+#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/OperatorKinds.h"
+
+#include <memory>
+#include <vector>
+
+
+namespace clang {
+namespace threadSafety {
+
+// This class defines the interface of a clang CFG Visitor.
+// CFGWalker will invoke the following methods.
+// Note that methods are not virtual; the visitor is templatized.
+class CFGVisitor {
+ // Enter the CFG for Decl D, and perform any initial setup operations.
+ void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First) {}
+
+ // Enter a CFGBlock.
+ void enterCFGBlock(const CFGBlock *B) {}
+
+ // Returns true if this visitor implements handlePredecessor
+ bool visitPredecessors() { return true; }
+
+ // Process a predecessor edge.
+ void handlePredecessor(const CFGBlock *Pred) {}
+
+ // Process a successor back edge to a previously visited block.
+ void handlePredecessorBackEdge(const CFGBlock *Pred) {}
+
+ // Called just before processing statements.
+ void enterCFGBlockBody(const CFGBlock *B) {}
+
+ // Process an ordinary statement.
+ void handleStatement(const Stmt *S) {}
+
+ // Process a destructor call
+ void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD) {}
+
+ // Called after all statements have been handled.
+ void exitCFGBlockBody(const CFGBlock *B) {}
+
+ // Return true
+ bool visitSuccessors() { return true; }
+
+ // Process a successor edge.
+ void handleSuccessor(const CFGBlock *Succ) {}
+
+ // Process a successor back edge to a previously visited block.
+ void handleSuccessorBackEdge(const CFGBlock *Succ) {}
+
+ // Leave a CFGBlock.
+ void exitCFGBlock(const CFGBlock *B) {}
+
+ // Leave the CFG, and perform any final cleanup operations.
+ void exitCFG(const CFGBlock *Last) {}
+};
+
+
+// Walks the clang CFG, and invokes methods on a given CFGVisitor.
+class CFGWalker {
+public:
+ CFGWalker() : CFGraph(nullptr), ACtx(nullptr), SortedGraph(nullptr) {}
+
+ // Initialize the CFGWalker. This setup only needs to be done once, even
+ // if there are multiple passes over the CFG.
+ bool init(AnalysisDeclContext &AC) {
+ ACtx = &AC;
+ CFGraph = AC.getCFG();
+ if (!CFGraph)
+ return false;
+
+ // Ignore anonymous functions.
+ if (!dyn_cast_or_null<NamedDecl>(AC.getDecl()))
+ return false;
+
+ SortedGraph = AC.getAnalysis<PostOrderCFGView>();
+ if (!SortedGraph)
+ return false;
+
+ return true;
+ }
+
+ // Traverse the CFG, calling methods on V as appropriate.
+ template <class Visitor>
+ void walk(Visitor &V) {
+ PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
+
+ V.enterCFG(CFGraph, getDecl(), &CFGraph->getEntry());
+
+ for (const auto *CurrBlock : *SortedGraph) {
+ VisitedBlocks.insert(CurrBlock);
+
+ V.enterCFGBlock(CurrBlock);
+
+ // Process predecessors, handling back edges last
+ if (V.visitPredecessors()) {
+ SmallVector<CFGBlock*, 4> BackEdges;
+ // Process successors
+ for (CFGBlock::const_pred_iterator SI = CurrBlock->pred_begin(),
+ SE = CurrBlock->pred_end();
+ SI != SE; ++SI) {
+ if (*SI == nullptr)
+ continue;
+
+ if (!VisitedBlocks.alreadySet(*SI)) {
+ BackEdges.push_back(*SI);
+ continue;
+ }
+ V.handlePredecessor(*SI);
+ }
+
+ for (auto *Blk : BackEdges)
+ V.handlePredecessorBackEdge(Blk);
+ }
+
+ V.enterCFGBlockBody(CurrBlock);
+
+ // Process statements
+ for (const auto &BI : *CurrBlock) {
+ switch (BI.getKind()) {
+ case CFGElement::Statement: {
+ V.handleStatement(BI.castAs<CFGStmt>().getStmt());
+ break;
+ }
+ case CFGElement::AutomaticObjectDtor: {
+ CFGAutomaticObjDtor AD = BI.castAs<CFGAutomaticObjDtor>();
+ CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
+ AD.getDestructorDecl(ACtx->getASTContext()));
+ VarDecl *VD = const_cast<VarDecl*>(AD.getVarDecl());
+ V.handleDestructorCall(VD, DD);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ V.exitCFGBlockBody(CurrBlock);
+
+ // Process successors, handling back edges first.
+ if (V.visitSuccessors()) {
+ SmallVector<CFGBlock*, 8> ForwardEdges;
+
+ // Process successors
+ for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
+ SE = CurrBlock->succ_end();
+ SI != SE; ++SI) {
+ if (*SI == nullptr)
+ continue;
+
+ if (!VisitedBlocks.alreadySet(*SI)) {
+ ForwardEdges.push_back(*SI);
+ continue;
+ }
+ V.handleSuccessorBackEdge(*SI);
+ }
+
+ for (auto *Blk : ForwardEdges)
+ V.handleSuccessor(Blk);
+ }
+
+ V.exitCFGBlock(CurrBlock);
+ }
+ V.exitCFG(&CFGraph->getExit());
+ }
+
+ const CFG *getGraph() const { return CFGraph; }
+ CFG *getGraph() { return CFGraph; }
+
+ const NamedDecl *getDecl() const {
+ return dyn_cast<NamedDecl>(ACtx->getDecl());
+ }
+
+ const PostOrderCFGView *getSortedGraph() const { return SortedGraph; }
+
+private:
+ CFG *CFGraph;
+ AnalysisDeclContext *ACtx;
+ PostOrderCFGView *SortedGraph;
+};
+
+
+// Translate clang::Expr to til::SExpr.
+class SExprBuilder {
+public:
+ /// \brief Encapsulates the lexical context of a function call. The lexical
+ /// context includes the arguments to the call, including the implicit object
+ /// argument. When an attribute containing a mutex expression is attached to
+ /// a method, the expression may refer to formal parameters of the method.
+ /// Actual arguments must be substituted for formal parameters to derive
+ /// the appropriate mutex expression in the lexical context where the function
+ /// is called. PrevCtx holds the context in which the arguments themselves
+ /// should be evaluated; multiple calling contexts can be chained together
+ /// by the lock_returned attribute.
+ struct CallingContext {
+ const NamedDecl *AttrDecl; // The decl to which the attr is attached.
+ const Expr *SelfArg; // Implicit object argument -- e.g. 'this'
+ unsigned NumArgs; // Number of funArgs
+ const Expr *const *FunArgs; // Function arguments
+ CallingContext *Prev; // The previous context; or 0 if none.
+ bool SelfArrow; // is Self referred to with -> or .?
+
+ CallingContext(const NamedDecl *D = nullptr, const Expr *S = nullptr,
+ unsigned N = 0, const Expr *const *A = nullptr,
+ CallingContext *P = nullptr)
+ : AttrDecl(D), SelfArg(S), NumArgs(N), FunArgs(A), Prev(P),
+ SelfArrow(false)
+ {}
+ };
+
+ SExprBuilder(til::MemRegionRef A)
+ : Arena(A), SelfVar(nullptr), Scfg(nullptr), CurrentBB(nullptr),
+ CurrentBlockInfo(nullptr) {
+ // FIXME: we don't always have a self-variable.
+ SelfVar = new (Arena) til::Variable();
+ SelfVar->setKind(til::Variable::VK_SFun);
+ }
+
+ // Translate a clang statement or expression to a TIL expression.
+ // Also performs substitution of variables; Ctx provides the context.
+ // Dispatches on the type of S.
+ til::SExpr *translate(const Stmt *S, CallingContext *Ctx);
+ til::SCFG *buildCFG(CFGWalker &Walker);
+
+ til::SExpr *lookupStmt(const Stmt *S);
+
+ til::BasicBlock *lookupBlock(const CFGBlock *B) {
+ return BlockMap[B->getBlockID()];
+ }
+
+ const til::SCFG *getCFG() const { return Scfg; }
+ til::SCFG *getCFG() { return Scfg; }
+
+private:
+ til::SExpr *translateDeclRefExpr(const DeclRefExpr *DRE,
+ CallingContext *Ctx) ;
+ til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
+ til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx);
+ til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx);
+ til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
+ CallingContext *Ctx);
+ til::SExpr *translateCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE,
+ CallingContext *Ctx);
+ til::SExpr *translateUnaryOperator(const UnaryOperator *UO,
+ CallingContext *Ctx);
+ til::SExpr *translateBinOp(til::TIL_BinaryOpcode Op,
+ const BinaryOperator *BO,
+ CallingContext *Ctx, bool Reverse = false);
+ til::SExpr *translateBinAssign(til::TIL_BinaryOpcode Op,
+ const BinaryOperator *BO,
+ CallingContext *Ctx, bool Assign = false);
+ til::SExpr *translateBinaryOperator(const BinaryOperator *BO,
+ CallingContext *Ctx);
+ til::SExpr *translateCastExpr(const CastExpr *CE, CallingContext *Ctx);
+ til::SExpr *translateArraySubscriptExpr(const ArraySubscriptExpr *E,
+ CallingContext *Ctx);
+ til::SExpr *translateConditionalOperator(const ConditionalOperator *C,
+ CallingContext *Ctx);
+ til::SExpr *translateBinaryConditionalOperator(
+ const BinaryConditionalOperator *C, CallingContext *Ctx);
+
+ til::SExpr *translateDeclStmt(const DeclStmt *S, CallingContext *Ctx);
+
+ // Map from statements in the clang CFG to SExprs in the til::SCFG.
+ typedef llvm::DenseMap<const Stmt*, til::SExpr*> StatementMap;
+
+ // Map from clang local variables to indices in a LVarDefinitionMap.
+ typedef llvm::DenseMap<const ValueDecl *, unsigned> LVarIndexMap;
+
+ // Map from local variable indices to SSA variables (or constants).
+ typedef std::pair<const ValueDecl *, til::SExpr *> NameVarPair;
+ typedef CopyOnWriteVector<NameVarPair> LVarDefinitionMap;
+
+ struct BlockInfo {
+ LVarDefinitionMap ExitMap;
+ bool HasBackEdges;
+ unsigned UnprocessedSuccessors; // Successors yet to be processed
+ unsigned ProcessedPredecessors; // Predecessors already processed
+
+ BlockInfo()
+ : HasBackEdges(false), UnprocessedSuccessors(0),
+ ProcessedPredecessors(0) {}
+ BlockInfo(BlockInfo &&RHS)
+ : ExitMap(std::move(RHS.ExitMap)),
+ HasBackEdges(RHS.HasBackEdges),
+ UnprocessedSuccessors(RHS.UnprocessedSuccessors),
+ ProcessedPredecessors(RHS.ProcessedPredecessors) {}
+
+ BlockInfo &operator=(BlockInfo &&RHS) {
+ if (this != &RHS) {
+ ExitMap = std::move(RHS.ExitMap);
+ HasBackEdges = RHS.HasBackEdges;
+ UnprocessedSuccessors = RHS.UnprocessedSuccessors;
+ ProcessedPredecessors = RHS.ProcessedPredecessors;
+ }
+ return *this;
+ }
+
+ private:
+ BlockInfo(const BlockInfo &) LLVM_DELETED_FUNCTION;
+ void operator=(const BlockInfo &) LLVM_DELETED_FUNCTION;
+ };
+
+ // We implement the CFGVisitor API
+ friend class CFGWalker;
+
+ void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First);
+ void enterCFGBlock(const CFGBlock *B);
+ bool visitPredecessors() { return true; }
+ void handlePredecessor(const CFGBlock *Pred);
+ void handlePredecessorBackEdge(const CFGBlock *Pred);
+ void enterCFGBlockBody(const CFGBlock *B);
+ void handleStatement(const Stmt *S);
+ void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD);
+ void exitCFGBlockBody(const CFGBlock *B);
+ bool visitSuccessors() { return true; }
+ void handleSuccessor(const CFGBlock *Succ);
+ void handleSuccessorBackEdge(const CFGBlock *Succ);
+ void exitCFGBlock(const CFGBlock *B);
+ void exitCFG(const CFGBlock *Last);
+
+ void insertStmt(const Stmt *S, til::SExpr *E) {
+ SMap.insert(std::make_pair(S, E));
+ }
+ til::SExpr *getCurrentLVarDefinition(const ValueDecl *VD);
+
+ til::SExpr *addStatement(til::SExpr *E, const Stmt *S,
+ const ValueDecl *VD = nullptr);
+ til::SExpr *lookupVarDecl(const ValueDecl *VD);
+ til::SExpr *addVarDecl(const ValueDecl *VD, til::SExpr *E);
+ til::SExpr *updateVarDecl(const ValueDecl *VD, til::SExpr *E);
+
+ void makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E);
+ void mergeEntryMap(LVarDefinitionMap Map);
+ void mergeEntryMapBackEdge();
+ void mergePhiNodesBackEdge(const CFGBlock *Blk);
+
+private:
+ til::MemRegionRef Arena;
+ til::Variable *SelfVar; // Variable to use for 'this'. May be null.
+ til::SCFG *Scfg;
+
+ StatementMap SMap; // Map from Stmt to TIL Variables
+ LVarIndexMap LVarIdxMap; // Indices of clang local vars.
+ std::vector<til::BasicBlock *> BlockMap; // Map from clang to til BBs.
+ std::vector<BlockInfo> BBInfo; // Extra information per BB.
+ // Indexed by clang BlockID.
+ std::unique_ptr<SExprBuilder::CallingContext> CallCtx; // Root calling context
+
+ LVarDefinitionMap CurrentLVarMap;
+ std::vector<til::Variable*> CurrentArguments;
+ std::vector<til::Variable*> CurrentInstructions;
+ std::vector<til::Variable*> IncompleteArgs;
+ til::BasicBlock *CurrentBB;
+ BlockInfo *CurrentBlockInfo;
+};
+
+
+// Dump an SCFG to llvm::errs().
+void printSCFG(CFGWalker &Walker);
+
+
+} // end namespace threadSafety
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_THREAD_SAFETY_COMMON_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
new file mode 100644
index 0000000..c4f4b21
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
@@ -0,0 +1,108 @@
+//===- ThreadSafetyLogical.h -----------------------------------*- 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 a representation for logical expressions with SExpr leaves
+// that are used as part of fact-checking capability expressions.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+#define LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+
+namespace clang {
+namespace threadSafety {
+namespace lexpr {
+
+class LExpr {
+public:
+ enum Opcode {
+ Terminal,
+ And,
+ Or,
+ Not
+ };
+ Opcode kind() const { return Kind; }
+
+ /// \brief Logical implication. Returns true if the LExpr implies RHS, i.e. if
+ /// the LExpr holds, then RHS must hold. For example, (A & B) implies A.
+ inline bool implies(const LExpr *RHS) const;
+
+protected:
+ LExpr(Opcode Kind) : Kind(Kind) {}
+
+private:
+ Opcode Kind;
+};
+
+class Terminal : public LExpr {
+ til::SExprRef Expr;
+
+public:
+ Terminal(til::SExpr *Expr) : LExpr(LExpr::Terminal), Expr(Expr) {}
+
+ const til::SExpr *expr() const { return Expr.get(); }
+ til::SExpr *expr() { return Expr.get(); }
+
+ static bool classof(const LExpr *E) { return E->kind() == LExpr::Terminal; }
+};
+
+class BinOp : public LExpr {
+ LExpr *LHS, *RHS;
+
+protected:
+ BinOp(LExpr *LHS, LExpr *RHS, Opcode Code) : LExpr(Code), LHS(LHS), RHS(RHS) {}
+
+public:
+ const LExpr *left() const { return LHS; }
+ LExpr *left() { return LHS; }
+
+ const LExpr *right() const { return RHS; }
+ LExpr *right() { return RHS; }
+};
+
+class And : public BinOp {
+public:
+ And(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::And) {}
+
+ static bool classof(const LExpr *E) { return E->kind() == LExpr::And; }
+};
+
+class Or : public BinOp {
+public:
+ Or(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::Or) {}
+
+ static bool classof(const LExpr *E) { return E->kind() == LExpr::Or; }
+};
+
+class Not : public LExpr {
+ LExpr *Exp;
+
+public:
+ Not(LExpr *Exp) : LExpr(LExpr::Not), Exp(Exp) {}
+
+ const LExpr *exp() const { return Exp; }
+ LExpr *exp() { return Exp; }
+
+ static bool classof(const LExpr *E) { return E->kind() == LExpr::Not; }
+};
+
+/// \brief Logical implication. Returns true if LHS implies RHS, i.e. if LHS
+/// holds, then RHS must hold. For example, (A & B) implies A.
+bool implies(const LExpr *LHS, const LExpr *RHS);
+
+bool LExpr::implies(const LExpr *RHS) const {
+ return lexpr::implies(this, RHS);
+}
+
+}
+}
+}
+
+#endif // LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
new file mode 100644
index 0000000..c8784b6
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
@@ -0,0 +1,53 @@
+//===- ThreadSafetyTIL.h ---------------------------------------*- 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 list of core opcodes for the Thread Safety
+// Typed Intermediate language. Please see ThreadSafetyTIL.h for more
+// information.
+//
+//===----------------------------------------------------------------------===//
+
+
+TIL_OPCODE_DEF(Future)
+TIL_OPCODE_DEF(Undefined)
+TIL_OPCODE_DEF(Wildcard)
+
+TIL_OPCODE_DEF(Literal)
+TIL_OPCODE_DEF(LiteralPtr)
+TIL_OPCODE_DEF(Variable)
+TIL_OPCODE_DEF(Function)
+TIL_OPCODE_DEF(SFunction)
+TIL_OPCODE_DEF(Code)
+TIL_OPCODE_DEF(Field)
+
+TIL_OPCODE_DEF(Apply)
+TIL_OPCODE_DEF(SApply)
+TIL_OPCODE_DEF(Project)
+
+TIL_OPCODE_DEF(Call)
+TIL_OPCODE_DEF(Alloc)
+TIL_OPCODE_DEF(Load)
+TIL_OPCODE_DEF(Store)
+TIL_OPCODE_DEF(ArrayFirst)
+TIL_OPCODE_DEF(ArrayAdd)
+
+TIL_OPCODE_DEF(UnaryOp)
+TIL_OPCODE_DEF(BinaryOp)
+TIL_OPCODE_DEF(Cast)
+
+TIL_OPCODE_DEF(SCFG)
+TIL_OPCODE_DEF(Phi)
+TIL_OPCODE_DEF(Goto)
+TIL_OPCODE_DEF(Branch)
+
+// pseudo-terms
+TIL_OPCODE_DEF(Identifier)
+TIL_OPCODE_DEF(IfThenElse)
+TIL_OPCODE_DEF(Let)
+
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
new file mode 100644
index 0000000..dcb196f
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -0,0 +1,1670 @@
+//===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT in the llvm repository for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple Typed Intermediate Language, or TIL, that is used
+// by the thread safety analysis (See ThreadSafety.cpp). The TIL is intended
+// to be largely independent of clang, in the hope that the analysis can be
+// reused for other non-C++ languages. All dependencies on clang/llvm should
+// go in ThreadSafetyUtil.h.
+//
+// Thread safety analysis works by comparing mutex expressions, e.g.
+//
+// class A { Mutex mu; int dat GUARDED_BY(this->mu); }
+// class B { A a; }
+//
+// void foo(B* b) {
+// (*b).a.mu.lock(); // locks (*b).a.mu
+// b->a.dat = 0; // substitute &b->a for 'this';
+// // requires lock on (&b->a)->mu
+// (b->a.mu).unlock(); // unlocks (b->a.mu)
+// }
+//
+// As illustrated by the above example, clang Exprs are not well-suited to
+// represent mutex expressions directly, since there is no easy way to compare
+// Exprs for equivalence. The thread safety analysis thus lowers clang Exprs
+// into a simple intermediate language (IL). The IL supports:
+//
+// (1) comparisons for semantic equality of expressions
+// (2) SSA renaming of variables
+// (3) wildcards and pattern matching over expressions
+// (4) hash-based expression lookup
+//
+// The TIL is currently very experimental, is intended only for use within
+// the thread safety analysis, and is subject to change without notice.
+// After the API stabilizes and matures, it may be appropriate to make this
+// more generally available to other analyses.
+//
+// UNDER CONSTRUCTION. USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_TIL_H
+#define LLVM_CLANG_THREAD_SAFETY_TIL_H
+
+// All clang include dependencies for this file must be put in
+// ThreadSafetyUtil.h.
+#include "ThreadSafetyUtil.h"
+
+#include <stdint.h>
+#include <cassert>
+#include <cstddef>
+#include <utility>
+
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+
+enum TIL_Opcode {
+#define TIL_OPCODE_DEF(X) COP_##X,
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+};
+
+enum TIL_UnaryOpcode : unsigned char {
+ UOP_Minus, // -
+ UOP_BitNot, // ~
+ UOP_LogicNot // !
+};
+
+enum TIL_BinaryOpcode : unsigned char {
+ BOP_Mul, // *
+ BOP_Div, // /
+ BOP_Rem, // %
+ BOP_Add, // +
+ BOP_Sub, // -
+ BOP_Shl, // <<
+ BOP_Shr, // >>
+ BOP_BitAnd, // &
+ BOP_BitXor, // ^
+ BOP_BitOr, // |
+ BOP_Eq, // ==
+ BOP_Neq, // !=
+ BOP_Lt, // <
+ BOP_Leq, // <=
+ BOP_LogicAnd, // &&
+ BOP_LogicOr // ||
+};
+
+enum TIL_CastOpcode : unsigned char {
+ CAST_none = 0,
+ CAST_extendNum, // extend precision of numeric type
+ CAST_truncNum, // truncate precision of numeric type
+ CAST_toFloat, // convert to floating point type
+ CAST_toInt, // convert to integer type
+};
+
+const TIL_Opcode COP_Min = COP_Future;
+const TIL_Opcode COP_Max = COP_Branch;
+const TIL_UnaryOpcode UOP_Min = UOP_Minus;
+const TIL_UnaryOpcode UOP_Max = UOP_LogicNot;
+const TIL_BinaryOpcode BOP_Min = BOP_Mul;
+const TIL_BinaryOpcode BOP_Max = BOP_LogicOr;
+const TIL_CastOpcode CAST_Min = CAST_none;
+const TIL_CastOpcode CAST_Max = CAST_toInt;
+
+StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op);
+StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op);
+
+
+// ValueTypes are data types that can actually be held in registers.
+// All variables and expressions must have a vBNF_Nonealue type.
+// Pointer types are further subdivided into the various heap-allocated
+// types, such as functions, records, etc.
+// Structured types that are passed by value (e.g. complex numbers)
+// require special handling; they use BT_ValueRef, and size ST_0.
+struct ValueType {
+ enum BaseType : unsigned char {
+ BT_Void = 0,
+ BT_Bool,
+ BT_Int,
+ BT_Float,
+ BT_String, // String literals
+ BT_Pointer,
+ BT_ValueRef
+ };
+
+ enum SizeType : unsigned char {
+ ST_0 = 0,
+ ST_1,
+ ST_8,
+ ST_16,
+ ST_32,
+ ST_64,
+ ST_128
+ };
+
+ inline static SizeType getSizeType(unsigned nbytes);
+
+ template <class T>
+ inline static ValueType getValueType();
+
+ ValueType(BaseType B, SizeType Sz, bool S, unsigned char VS)
+ : Base(B), Size(Sz), Signed(S), VectSize(VS)
+ { }
+
+ BaseType Base;
+ SizeType Size;
+ bool Signed;
+ unsigned char VectSize; // 0 for scalar, otherwise num elements in vector
+};
+
+
+inline ValueType::SizeType ValueType::getSizeType(unsigned nbytes) {
+ switch (nbytes) {
+ case 1: return ST_8;
+ case 2: return ST_16;
+ case 4: return ST_32;
+ case 8: return ST_64;
+ case 16: return ST_128;
+ default: return ST_0;
+ }
+}
+
+
+template<>
+inline ValueType ValueType::getValueType<void>() {
+ return ValueType(BT_Void, ST_0, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<bool>() {
+ return ValueType(BT_Bool, ST_1, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int8_t>() {
+ return ValueType(BT_Int, ST_8, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint8_t>() {
+ return ValueType(BT_Int, ST_8, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int16_t>() {
+ return ValueType(BT_Int, ST_16, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint16_t>() {
+ return ValueType(BT_Int, ST_16, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int32_t>() {
+ return ValueType(BT_Int, ST_32, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint32_t>() {
+ return ValueType(BT_Int, ST_32, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int64_t>() {
+ return ValueType(BT_Int, ST_64, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint64_t>() {
+ return ValueType(BT_Int, ST_64, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<float>() {
+ return ValueType(BT_Float, ST_32, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<double>() {
+ return ValueType(BT_Float, ST_64, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<long double>() {
+ return ValueType(BT_Float, ST_128, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<StringRef>() {
+ return ValueType(BT_Pointer, getSizeType(sizeof(StringRef)), false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<void*>() {
+ return ValueType(BT_Pointer, getSizeType(sizeof(void*)), false, 0);
+}
+
+
+
+enum TraversalKind {
+ TRV_Normal,
+ TRV_Lazy, // subexpression may need to be traversed lazily
+ TRV_Tail // subexpression occurs in a tail position
+};
+
+
+// Base class for AST nodes in the typed intermediate language.
+class SExpr {
+public:
+ TIL_Opcode opcode() const { return static_cast<TIL_Opcode>(Opcode); }
+
+ // Subclasses of SExpr must define the following:
+ //
+ // This(const This& E, ...) {
+ // copy constructor: construct copy of E, with some additional arguments.
+ // }
+ //
+ // template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ // traverse all subexpressions, following the traversal/rewriter interface
+ // }
+ //
+ // template <class C> typename C::CType compare(CType* E, C& Cmp) {
+ // compare all subexpressions, following the comparator interface
+ // }
+
+ void *operator new(size_t S, MemRegionRef &R) {
+ return ::operator new(S, R);
+ }
+
+ // SExpr objects cannot be deleted.
+ // This declaration is public to workaround a gcc bug that breaks building
+ // with REQUIRES_EH=1.
+ void operator delete(void *) LLVM_DELETED_FUNCTION;
+
+protected:
+ SExpr(TIL_Opcode Op) : Opcode(Op), Reserved(0), Flags(0) {}
+ SExpr(const SExpr &E) : Opcode(E.Opcode), Reserved(0), Flags(E.Flags) {}
+
+ const unsigned char Opcode;
+ unsigned char Reserved;
+ unsigned short Flags;
+
+private:
+ SExpr() LLVM_DELETED_FUNCTION;
+
+ // SExpr objects must be created in an arena.
+ void *operator new(size_t) LLVM_DELETED_FUNCTION;
+};
+
+
+// Class for owning references to SExprs.
+// Includes attach/detach logic for counting variable references and lazy
+// rewriting strategies.
+class SExprRef {
+public:
+ SExprRef() : Ptr(nullptr) { }
+ SExprRef(std::nullptr_t P) : Ptr(nullptr) { }
+ SExprRef(SExprRef &&R) : Ptr(R.Ptr) { R.Ptr = nullptr; }
+
+ // Defined after Variable and Future, below.
+ inline SExprRef(SExpr *P);
+ inline ~SExprRef();
+
+ SExpr *get() { return Ptr; }
+ const SExpr *get() const { return Ptr; }
+
+ SExpr *operator->() { return get(); }
+ const SExpr *operator->() const { return get(); }
+
+ SExpr &operator*() { return *Ptr; }
+ const SExpr &operator*() const { return *Ptr; }
+
+ bool operator==(const SExprRef &R) const { return Ptr == R.Ptr; }
+ bool operator!=(const SExprRef &R) const { return !operator==(R); }
+ bool operator==(const SExpr *P) const { return Ptr == P; }
+ bool operator!=(const SExpr *P) const { return !operator==(P); }
+ bool operator==(std::nullptr_t) const { return Ptr == nullptr; }
+ bool operator!=(std::nullptr_t) const { return Ptr != nullptr; }
+
+ inline void reset(SExpr *E);
+
+private:
+ inline void attach();
+ inline void detach();
+
+ SExpr *Ptr;
+};
+
+
+// Contains various helper functions for SExprs.
+namespace ThreadSafetyTIL {
+ inline bool isTrivial(const SExpr *E) {
+ unsigned Op = E->opcode();
+ return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
+ }
+}
+
+// Nodes which declare variables
+class Function;
+class SFunction;
+class BasicBlock;
+class Let;
+
+
+// A named variable, e.g. "x".
+//
+// There are two distinct places in which a Variable can appear in the AST.
+// A variable declaration introduces a new variable, and can occur in 3 places:
+// Let-expressions: (Let (x = t) u)
+// Functions: (Function (x : t) u)
+// Self-applicable functions (SFunction (x) t)
+//
+// If a variable occurs in any other location, it is a reference to an existing
+// variable declaration -- e.g. 'x' in (x * y + z). To save space, we don't
+// allocate a separate AST node for variable references; a reference is just a
+// pointer to the original declaration.
+class Variable : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Variable; }
+
+ // Let-variable, function parameter, or self-variable
+ enum VariableKind {
+ VK_Let,
+ VK_Fun,
+ VK_SFun
+ };
+
+ // These are defined after SExprRef contructor, below
+ inline Variable(StringRef s, SExpr *D = nullptr);
+ inline Variable(SExpr *D = nullptr, const clang::ValueDecl *Cvd = nullptr);
+ inline Variable(const Variable &Vd, SExpr *D);
+
+ VariableKind kind() const { return static_cast<VariableKind>(Flags); }
+
+ const StringRef name() const { return Name; }
+ const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+
+ // Returns the definition (for let vars) or type (for parameter & self vars)
+ SExpr *definition() { return Definition.get(); }
+ const SExpr *definition() const { return Definition.get(); }
+
+ void attachVar() const { ++NumUses; }
+ void detachVar() const { assert(NumUses > 0); --NumUses; }
+
+ unsigned getID() const { return Id; }
+ unsigned getBlockID() const { return BlockID; }
+
+ void setID(unsigned Bid, unsigned I) {
+ BlockID = static_cast<unsigned short>(Bid);
+ Id = static_cast<unsigned short>(I);
+ }
+ void setClangDecl(const clang::ValueDecl *VD) { Cvdecl = VD; }
+ void setDefinition(SExpr *E);
+ void setKind(VariableKind K) { Flags = K; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ // This routine is only called for variable references.
+ return Visitor.reduceVariableRef(this);
+ }
+
+ template <class C> typename C::CType compare(Variable* E, C& Cmp) {
+ return Cmp.compareVariableRefs(this, E);
+ }
+
+private:
+ friend class Function;
+ friend class SFunction;
+ friend class BasicBlock;
+ friend class Let;
+
+ StringRef Name; // The name of the variable.
+ SExprRef Definition; // The TIL type or definition
+ const clang::ValueDecl *Cvdecl; // The clang declaration for this variable.
+
+ unsigned short BlockID;
+ unsigned short Id;
+ mutable unsigned NumUses;
+};
+
+
+// Placeholder for an expression that has not yet been created.
+// Used to implement lazy copy and rewriting strategies.
+class Future : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Future; }
+
+ enum FutureStatus {
+ FS_pending,
+ FS_evaluating,
+ FS_done
+ };
+
+ Future() :
+ SExpr(COP_Future), Status(FS_pending), Result(nullptr), Location(nullptr)
+ {}
+private:
+ virtual ~Future() LLVM_DELETED_FUNCTION;
+public:
+
+ // Registers the location in the AST where this future is stored.
+ // Forcing the future will automatically update the AST.
+ static inline void registerLocation(SExprRef *Member) {
+ if (Future *F = dyn_cast_or_null<Future>(Member->get()))
+ F->Location = Member;
+ }
+
+ // A lazy rewriting strategy should subclass Future and override this method.
+ virtual SExpr *create() { return nullptr; }
+
+ // Return the result of this future if it exists, otherwise return null.
+ SExpr *maybeGetResult() {
+ return Result;
+ }
+
+ // Return the result of this future; forcing it if necessary.
+ SExpr *result() {
+ switch (Status) {
+ case FS_pending:
+ force();
+ return Result;
+ case FS_evaluating:
+ return nullptr; // infinite loop; illegal recursion.
+ case FS_done:
+ return Result;
+ }
+ }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ assert(Result && "Cannot traverse Future that has not been forced.");
+ return Visitor.traverse(Result);
+ }
+
+ template <class C> typename C::CType compare(Future* E, C& Cmp) {
+ if (!Result || !E->Result)
+ return Cmp.comparePointers(this, E);
+ return Cmp.compare(Result, E->Result);
+ }
+
+private:
+ // Force the future.
+ inline void force();
+
+ FutureStatus Status;
+ SExpr *Result;
+ SExprRef *Location;
+};
+
+
+inline void SExprRef::attach() {
+ if (!Ptr)
+ return;
+
+ TIL_Opcode Op = Ptr->opcode();
+ if (Op == COP_Variable) {
+ cast<Variable>(Ptr)->attachVar();
+ } else if (Op == COP_Future) {
+ cast<Future>(Ptr)->registerLocation(this);
+ }
+}
+
+inline void SExprRef::detach() {
+ if (Ptr && Ptr->opcode() == COP_Variable) {
+ cast<Variable>(Ptr)->detachVar();
+ }
+}
+
+inline SExprRef::SExprRef(SExpr *P) : Ptr(P) {
+ attach();
+}
+
+inline SExprRef::~SExprRef() {
+ detach();
+}
+
+inline void SExprRef::reset(SExpr *P) {
+ detach();
+ Ptr = P;
+ attach();
+}
+
+
+inline Variable::Variable(StringRef s, SExpr *D)
+ : SExpr(COP_Variable), Name(s), Definition(D), Cvdecl(nullptr),
+ BlockID(0), Id(0), NumUses(0) {
+ Flags = VK_Let;
+}
+
+inline Variable::Variable(SExpr *D, const clang::ValueDecl *Cvd)
+ : SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"),
+ Definition(D), Cvdecl(Cvd), BlockID(0), Id(0), NumUses(0) {
+ Flags = VK_Let;
+}
+
+inline Variable::Variable(const Variable &Vd, SExpr *D) // rewrite constructor
+ : SExpr(Vd), Name(Vd.Name), Definition(D), Cvdecl(Vd.Cvdecl),
+ BlockID(0), Id(0), NumUses(0) {
+ Flags = Vd.kind();
+}
+
+inline void Variable::setDefinition(SExpr *E) {
+ Definition.reset(E);
+}
+
+void Future::force() {
+ Status = FS_evaluating;
+ SExpr *R = create();
+ Result = R;
+ if (Location)
+ Location->reset(R);
+ Status = FS_done;
+}
+
+
+// Placeholder for C++ expressions that cannot be represented in the TIL.
+class Undefined : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
+
+ Undefined(const clang::Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
+ Undefined(const Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ return Visitor.reduceUndefined(*this);
+ }
+
+ template <class C> typename C::CType compare(Undefined* E, C& Cmp) {
+ return Cmp.comparePointers(Cstmt, E->Cstmt);
+ }
+
+private:
+ const clang::Stmt *Cstmt;
+};
+
+
+// Placeholder for a wildcard that matches any other expression.
+class Wildcard : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; }
+
+ Wildcard() : SExpr(COP_Wildcard) {}
+ Wildcard(const Wildcard &W) : SExpr(W) {}
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ return Visitor.reduceWildcard(*this);
+ }
+
+ template <class C> typename C::CType compare(Wildcard* E, C& Cmp) {
+ return Cmp.trueResult();
+ }
+};
+
+
+// Base class for literal values.
+class Literal : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
+
+ Literal(const clang::Expr *C)
+ : SExpr(COP_Literal), ValType(ValueType::getValueType<void>())
+ { }
+ Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT) {}
+ Literal(const Literal &L) : SExpr(L), ValType(L.ValType), Cexpr(L.Cexpr) {}
+
+ // The clang expression for this literal.
+ const clang::Expr *clangExpr() const { return Cexpr; }
+
+ ValueType valueType() const { return ValType; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ return Visitor.reduceLiteral(*this);
+ }
+
+ template <class C> typename C::CType compare(Literal* E, C& Cmp) {
+ // TODO -- use value, not pointer equality
+ return Cmp.comparePointers(Cexpr, E->Cexpr);
+ }
+
+private:
+ const ValueType ValType;
+ const clang::Expr *Cexpr;
+};
+
+
+// Derived class for literal values, which stores the actual value.
+template<class T>
+class LiteralT : public Literal {
+public:
+ LiteralT(T Dat) : Literal(ValueType::getValueType<T>()), Val(Dat) { }
+ LiteralT(const LiteralT<T> &L) : Literal(L), Val(L.Val) { }
+
+ T value() const { return Val;}
+ T& value() { return Val; }
+
+private:
+ T Val;
+};
+
+
+// Literal pointer to an object allocated in memory.
+// At compile time, pointer literals are represented by symbolic names.
+class LiteralPtr : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
+
+ LiteralPtr(const clang::ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
+ LiteralPtr(const LiteralPtr &R) : SExpr(R), Cvdecl(R.Cvdecl) {}
+
+ // The clang declaration for the value that this pointer points to.
+ const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ return Visitor.reduceLiteralPtr(*this);
+ }
+
+ template <class C> typename C::CType compare(LiteralPtr* E, C& Cmp) {
+ return Cmp.comparePointers(Cvdecl, E->Cvdecl);
+ }
+
+private:
+ const clang::ValueDecl *Cvdecl;
+};
+
+
+// A function -- a.k.a. lambda abstraction.
+// Functions with multiple arguments are created by currying,
+// e.g. (function (x: Int) (function (y: Int) (add x y)))
+class Function : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Function; }
+
+ Function(Variable *Vd, SExpr *Bd)
+ : SExpr(COP_Function), VarDecl(Vd), Body(Bd) {
+ Vd->setKind(Variable::VK_Fun);
+ }
+ Function(const Function &F, Variable *Vd, SExpr *Bd) // rewrite constructor
+ : SExpr(F), VarDecl(Vd), Body(Bd) {
+ Vd->setKind(Variable::VK_Fun);
+ }
+
+ Variable *variableDecl() { return VarDecl; }
+ const Variable *variableDecl() const { return VarDecl; }
+
+ SExpr *body() { return Body.get(); }
+ const SExpr *body() const { return Body.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ // This is a variable declaration, so traverse the definition.
+ typename V::R_SExpr E0 = Visitor.traverse(VarDecl->Definition, TRV_Lazy);
+ // Tell the rewriter to enter the scope of the function.
+ Variable *Nvd = Visitor.enterScope(*VarDecl, E0);
+ typename V::R_SExpr E1 = Visitor.traverse(Body);
+ Visitor.exitScope(*VarDecl);
+ return Visitor.reduceFunction(*this, Nvd, E1);
+ }
+
+ template <class C> typename C::CType compare(Function* E, C& Cmp) {
+ typename C::CType Ct =
+ Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ Cmp.enterScope(variableDecl(), E->variableDecl());
+ Ct = Cmp.compare(body(), E->body());
+ Cmp.leaveScope();
+ return Ct;
+ }
+
+private:
+ Variable *VarDecl;
+ SExprRef Body;
+};
+
+
+// A self-applicable function.
+// A self-applicable function can be applied to itself. It's useful for
+// implementing objects and late binding
+class SFunction : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_SFunction; }
+
+ SFunction(Variable *Vd, SExpr *B)
+ : SExpr(COP_SFunction), VarDecl(Vd), Body(B) {
+ assert(Vd->Definition == nullptr);
+ Vd->setKind(Variable::VK_SFun);
+ Vd->Definition.reset(this);
+ }
+ SFunction(const SFunction &F, Variable *Vd, SExpr *B) // rewrite constructor
+ : SExpr(F), VarDecl(Vd), Body(B) {
+ assert(Vd->Definition == nullptr);
+ Vd->setKind(Variable::VK_SFun);
+ Vd->Definition.reset(this);
+ }
+
+ Variable *variableDecl() { return VarDecl; }
+ const Variable *variableDecl() const { return VarDecl; }
+
+ SExpr *body() { return Body.get(); }
+ const SExpr *body() const { return Body.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ // A self-variable points to the SFunction itself.
+ // A rewrite must introduce the variable with a null definition, and update
+ // it after 'this' has been rewritten.
+ Variable *Nvd = Visitor.enterScope(*VarDecl, nullptr /* def */);
+ typename V::R_SExpr E1 = Visitor.traverse(Body);
+ Visitor.exitScope(*VarDecl);
+ // A rewrite operation will call SFun constructor to set Vvd->Definition.
+ return Visitor.reduceSFunction(*this, Nvd, E1);
+ }
+
+ template <class C> typename C::CType compare(SFunction* E, C& Cmp) {
+ Cmp.enterScope(variableDecl(), E->variableDecl());
+ typename C::CType Ct = Cmp.compare(body(), E->body());
+ Cmp.leaveScope();
+ return Ct;
+ }
+
+private:
+ Variable *VarDecl;
+ SExprRef Body;
+};
+
+
+// A block of code -- e.g. the body of a function.
+class Code : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Code; }
+
+ Code(SExpr *T, SExpr *B) : SExpr(COP_Code), ReturnType(T), Body(B) {}
+ Code(const Code &C, SExpr *T, SExpr *B) // rewrite constructor
+ : SExpr(C), ReturnType(T), Body(B) {}
+
+ SExpr *returnType() { return ReturnType.get(); }
+ const SExpr *returnType() const { return ReturnType.get(); }
+
+ SExpr *body() { return Body.get(); }
+ const SExpr *body() const { return Body.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nt = Visitor.traverse(ReturnType, TRV_Lazy);
+ typename V::R_SExpr Nb = Visitor.traverse(Body, TRV_Lazy);
+ return Visitor.reduceCode(*this, Nt, Nb);
+ }
+
+ template <class C> typename C::CType compare(Code* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compare(returnType(), E->returnType());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(body(), E->body());
+ }
+
+private:
+ SExprRef ReturnType;
+ SExprRef Body;
+};
+
+
+// A typed, writable location in memory
+class Field : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Field; }
+
+ Field(SExpr *R, SExpr *B) : SExpr(COP_Field), Range(R), Body(B) {}
+ Field(const Field &C, SExpr *R, SExpr *B) // rewrite constructor
+ : SExpr(C), Range(R), Body(B) {}
+
+ SExpr *range() { return Range.get(); }
+ const SExpr *range() const { return Range.get(); }
+
+ SExpr *body() { return Body.get(); }
+ const SExpr *body() const { return Body.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nr = Visitor.traverse(Range, TRV_Lazy);
+ typename V::R_SExpr Nb = Visitor.traverse(Body, TRV_Lazy);
+ return Visitor.reduceField(*this, Nr, Nb);
+ }
+
+ template <class C> typename C::CType compare(Field* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compare(range(), E->range());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(body(), E->body());
+ }
+
+private:
+ SExprRef Range;
+ SExprRef Body;
+};
+
+
+// Apply an argument to a function
+class Apply : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; }
+
+ Apply(SExpr *F, SExpr *A) : SExpr(COP_Apply), Fun(F), Arg(A) {}
+ Apply(const Apply &A, SExpr *F, SExpr *Ar) // rewrite constructor
+ : SExpr(A), Fun(F), Arg(Ar)
+ {}
+
+ SExpr *fun() { return Fun.get(); }
+ const SExpr *fun() const { return Fun.get(); }
+
+ SExpr *arg() { return Arg.get(); }
+ const SExpr *arg() const { return Arg.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nf = Visitor.traverse(Fun);
+ typename V::R_SExpr Na = Visitor.traverse(Arg);
+ return Visitor.reduceApply(*this, Nf, Na);
+ }
+
+ template <class C> typename C::CType compare(Apply* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compare(fun(), E->fun());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(arg(), E->arg());
+ }
+
+private:
+ SExprRef Fun;
+ SExprRef Arg;
+};
+
+
+// Apply a self-argument to a self-applicable function
+class SApply : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_SApply; }
+
+ SApply(SExpr *Sf, SExpr *A = nullptr) : SExpr(COP_SApply), Sfun(Sf), Arg(A) {}
+ SApply(SApply &A, SExpr *Sf, SExpr *Ar = nullptr) // rewrite constructor
+ : SExpr(A), Sfun(Sf), Arg(Ar) {}
+
+ SExpr *sfun() { return Sfun.get(); }
+ const SExpr *sfun() const { return Sfun.get(); }
+
+ SExpr *arg() { return Arg.get() ? Arg.get() : Sfun.get(); }
+ const SExpr *arg() const { return Arg.get() ? Arg.get() : Sfun.get(); }
+
+ bool isDelegation() const { return Arg == nullptr; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nf = Visitor.traverse(Sfun);
+ typename V::R_SExpr Na = Arg.get() ? Visitor.traverse(Arg) : nullptr;
+ return Visitor.reduceSApply(*this, Nf, Na);
+ }
+
+ template <class C> typename C::CType compare(SApply* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compare(sfun(), E->sfun());
+ if (Cmp.notTrue(Ct) || (!arg() && !E->arg()))
+ return Ct;
+ return Cmp.compare(arg(), E->arg());
+ }
+
+private:
+ SExprRef Sfun;
+ SExprRef Arg;
+};
+
+
+// Project a named slot from a C++ struct or class.
+class Project : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
+
+ Project(SExpr *R, StringRef SName)
+ : SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
+ { }
+ Project(SExpr *R, clang::ValueDecl *Cvd)
+ : SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
+ { }
+ Project(const Project &P, SExpr *R)
+ : SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
+ { }
+
+ SExpr *record() { return Rec.get(); }
+ const SExpr *record() const { return Rec.get(); }
+
+ const clang::ValueDecl *clangValueDecl() const { return Cvdecl; }
+
+ StringRef slotName() const {
+ if (Cvdecl)
+ return Cvdecl->getName();
+ else
+ return SlotName;
+ }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nr = Visitor.traverse(Rec);
+ return Visitor.reduceProject(*this, Nr);
+ }
+
+ template <class C> typename C::CType compare(Project* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compare(record(), E->record());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.comparePointers(Cvdecl, E->Cvdecl);
+ }
+
+private:
+ SExprRef Rec;
+ StringRef SlotName;
+ clang::ValueDecl *Cvdecl;
+};
+
+
+// Call a function (after all arguments have been applied).
+class Call : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
+
+ Call(SExpr *T, const clang::CallExpr *Ce = nullptr)
+ : SExpr(COP_Call), Target(T), Cexpr(Ce) {}
+ Call(const Call &C, SExpr *T) : SExpr(C), Target(T), Cexpr(C.Cexpr) {}
+
+ SExpr *target() { return Target.get(); }
+ const SExpr *target() const { return Target.get(); }
+
+ const clang::CallExpr *clangCallExpr() const { return Cexpr; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nt = Visitor.traverse(Target);
+ return Visitor.reduceCall(*this, Nt);
+ }
+
+ template <class C> typename C::CType compare(Call* E, C& Cmp) {
+ return Cmp.compare(target(), E->target());
+ }
+
+private:
+ SExprRef Target;
+ const clang::CallExpr *Cexpr;
+};
+
+
+// Allocate memory for a new value on the heap or stack.
+class Alloc : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
+
+ enum AllocKind {
+ AK_Stack,
+ AK_Heap
+ };
+
+ Alloc(SExpr *D, AllocKind K) : SExpr(COP_Alloc), Dtype(D) { Flags = K; }
+ Alloc(const Alloc &A, SExpr *Dt) : SExpr(A), Dtype(Dt) { Flags = A.kind(); }
+
+ AllocKind kind() const { return static_cast<AllocKind>(Flags); }
+
+ SExpr *dataType() { return Dtype.get(); }
+ const SExpr *dataType() const { return Dtype.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nd = Visitor.traverse(Dtype);
+ return Visitor.reduceAlloc(*this, Nd);
+ }
+
+ template <class C> typename C::CType compare(Alloc* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(dataType(), E->dataType());
+ }
+
+private:
+ SExprRef Dtype;
+};
+
+
+// Load a value from memory.
+class Load : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Load; }
+
+ Load(SExpr *P) : SExpr(COP_Load), Ptr(P) {}
+ Load(const Load &L, SExpr *P) : SExpr(L), Ptr(P) {}
+
+ SExpr *pointer() { return Ptr.get(); }
+ const SExpr *pointer() const { return Ptr.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Np = Visitor.traverse(Ptr);
+ return Visitor.reduceLoad(*this, Np);
+ }
+
+ template <class C> typename C::CType compare(Load* E, C& Cmp) {
+ return Cmp.compare(pointer(), E->pointer());
+ }
+
+private:
+ SExprRef Ptr;
+};
+
+
+// Store a value to memory.
+// Source is a pointer, destination is the value to store.
+class Store : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Store; }
+
+ Store(SExpr *P, SExpr *V) : SExpr(COP_Store), Dest(P), Source(V) {}
+ Store(const Store &S, SExpr *P, SExpr *V) : SExpr(S), Dest(P), Source(V) {}
+
+ SExpr *destination() { return Dest.get(); } // Address to store to
+ const SExpr *destination() const { return Dest.get(); }
+
+ SExpr *source() { return Source.get(); } // Value to store
+ const SExpr *source() const { return Source.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Np = Visitor.traverse(Dest);
+ typename V::R_SExpr Nv = Visitor.traverse(Source);
+ return Visitor.reduceStore(*this, Np, Nv);
+ }
+
+ template <class C> typename C::CType compare(Store* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compare(destination(), E->destination());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(source(), E->source());
+ }
+
+private:
+ SExprRef Dest;
+ SExprRef Source;
+};
+
+
+// If p is a reference to an array, then first(p) is a reference to the first
+// element. The usual array notation p[i] becomes first(p + i).
+class ArrayFirst : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayFirst; }
+
+ ArrayFirst(SExpr *A) : SExpr(COP_ArrayFirst), Array(A) {}
+ ArrayFirst(const ArrayFirst &E, SExpr *A) : SExpr(E), Array(A) {}
+
+ SExpr *array() { return Array.get(); }
+ const SExpr *array() const { return Array.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Na = Visitor.traverse(Array);
+ return Visitor.reduceArrayFirst(*this, Na);
+ }
+
+ template <class C> typename C::CType compare(ArrayFirst* E, C& Cmp) {
+ return Cmp.compare(array(), E->array());
+ }
+
+private:
+ SExprRef Array;
+};
+
+
+// Pointer arithmetic, restricted to arrays only.
+// If p is a reference to an array, then p + n, where n is an integer, is
+// a reference to a subarray.
+class ArrayAdd : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayAdd; }
+
+ ArrayAdd(SExpr *A, SExpr *N) : SExpr(COP_ArrayAdd), Array(A), Index(N) {}
+ ArrayAdd(const ArrayAdd &E, SExpr *A, SExpr *N)
+ : SExpr(E), Array(A), Index(N) {}
+
+ SExpr *array() { return Array.get(); }
+ const SExpr *array() const { return Array.get(); }
+
+ SExpr *index() { return Index.get(); }
+ const SExpr *index() const { return Index.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Na = Visitor.traverse(Array);
+ typename V::R_SExpr Ni = Visitor.traverse(Index);
+ return Visitor.reduceArrayAdd(*this, Na, Ni);
+ }
+
+ template <class C> typename C::CType compare(ArrayAdd* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compare(array(), E->array());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(index(), E->index());
+ }
+
+private:
+ SExprRef Array;
+ SExprRef Index;
+};
+
+
+// Simple unary operation -- e.g. !, ~, etc.
+class UnaryOp : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_UnaryOp; }
+
+ UnaryOp(TIL_UnaryOpcode Op, SExpr *E) : SExpr(COP_UnaryOp), Expr0(E) {
+ Flags = Op;
+ }
+ UnaryOp(const UnaryOp &U, SExpr *E) : SExpr(U), Expr0(E) { Flags = U.Flags; }
+
+ TIL_UnaryOpcode unaryOpcode() const {
+ return static_cast<TIL_UnaryOpcode>(Flags);
+ }
+
+ SExpr *expr() { return Expr0.get(); }
+ const SExpr *expr() const { return Expr0.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Ne = Visitor.traverse(Expr0);
+ return Visitor.reduceUnaryOp(*this, Ne);
+ }
+
+ template <class C> typename C::CType compare(UnaryOp* E, C& Cmp) {
+ typename C::CType Ct =
+ Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(expr(), E->expr());
+ }
+
+private:
+ SExprRef Expr0;
+};
+
+
+// Simple binary operation -- e.g. +, -, etc.
+class BinaryOp : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_BinaryOp; }
+
+ BinaryOp(TIL_BinaryOpcode Op, SExpr *E0, SExpr *E1)
+ : SExpr(COP_BinaryOp), Expr0(E0), Expr1(E1) {
+ Flags = Op;
+ }
+ BinaryOp(const BinaryOp &B, SExpr *E0, SExpr *E1)
+ : SExpr(B), Expr0(E0), Expr1(E1) {
+ Flags = B.Flags;
+ }
+
+ TIL_BinaryOpcode binaryOpcode() const {
+ return static_cast<TIL_BinaryOpcode>(Flags);
+ }
+
+ SExpr *expr0() { return Expr0.get(); }
+ const SExpr *expr0() const { return Expr0.get(); }
+
+ SExpr *expr1() { return Expr1.get(); }
+ const SExpr *expr1() const { return Expr1.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Ne0 = Visitor.traverse(Expr0);
+ typename V::R_SExpr Ne1 = Visitor.traverse(Expr1);
+ return Visitor.reduceBinaryOp(*this, Ne0, Ne1);
+ }
+
+ template <class C> typename C::CType compare(BinaryOp* E, C& Cmp) {
+ typename C::CType Ct =
+ Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ Ct = Cmp.compare(expr0(), E->expr0());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(expr1(), E->expr1());
+ }
+
+private:
+ SExprRef Expr0;
+ SExprRef Expr1;
+};
+
+
+// Cast expression
+class Cast : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Cast; }
+
+ Cast(TIL_CastOpcode Op, SExpr *E) : SExpr(COP_Cast), Expr0(E) { Flags = Op; }
+ Cast(const Cast &C, SExpr *E) : SExpr(C), Expr0(E) { Flags = C.Flags; }
+
+ TIL_CastOpcode castOpcode() const {
+ return static_cast<TIL_CastOpcode>(Flags);
+ }
+
+ SExpr *expr() { return Expr0.get(); }
+ const SExpr *expr() const { return Expr0.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Ne = Visitor.traverse(Expr0);
+ return Visitor.reduceCast(*this, Ne);
+ }
+
+ template <class C> typename C::CType compare(Cast* E, C& Cmp) {
+ typename C::CType Ct =
+ Cmp.compareIntegers(castOpcode(), E->castOpcode());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(expr(), E->expr());
+ }
+
+private:
+ SExprRef Expr0;
+};
+
+
+
+class BasicBlock;
+
+// An SCFG is a control-flow graph. It consists of a set of basic blocks, each
+// of which terminates in a branch to another basic block. There is one
+// entry point, and one exit point.
+class SCFG : public SExpr {
+public:
+ typedef SimpleArray<BasicBlock *> BlockArray;
+ typedef BlockArray::iterator iterator;
+ typedef BlockArray::const_iterator const_iterator;
+
+ static bool classof(const SExpr *E) { return E->opcode() == COP_SCFG; }
+
+ SCFG(MemRegionRef A, unsigned Nblocks)
+ : SExpr(COP_SCFG), Blocks(A, Nblocks),
+ Entry(nullptr), Exit(nullptr) {}
+ SCFG(const SCFG &Cfg, BlockArray &&Ba) // steals memory from Ba
+ : SExpr(COP_SCFG), Blocks(std::move(Ba)), Entry(nullptr), Exit(nullptr) {
+ // TODO: set entry and exit!
+ }
+
+ iterator begin() { return Blocks.begin(); }
+ iterator end() { return Blocks.end(); }
+
+ const_iterator begin() const { return cbegin(); }
+ const_iterator end() const { return cend(); }
+
+ const_iterator cbegin() const { return Blocks.cbegin(); }
+ const_iterator cend() const { return Blocks.cend(); }
+
+ const BasicBlock *entry() const { return Entry; }
+ BasicBlock *entry() { return Entry; }
+ const BasicBlock *exit() const { return Exit; }
+ BasicBlock *exit() { return Exit; }
+
+ void add(BasicBlock *BB);
+ void setEntry(BasicBlock *BB) { Entry = BB; }
+ void setExit(BasicBlock *BB) { Exit = BB; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor);
+
+ template <class C> typename C::CType compare(SCFG *E, C &Cmp) {
+ // TODO -- implement CFG comparisons
+ return Cmp.comparePointers(this, E);
+ }
+
+private:
+ BlockArray Blocks;
+ BasicBlock *Entry;
+ BasicBlock *Exit;
+};
+
+
+// A basic block is part of an SCFG, and can be treated as a function in
+// continuation passing style. It consists of a sequence of phi nodes, which
+// are "arguments" to the function, followed by a sequence of instructions.
+// Both arguments and instructions define new variables. It ends with a
+// branch or goto to another basic block in the same SCFG.
+class BasicBlock {
+public:
+ typedef SimpleArray<Variable*> VarArray;
+
+ BasicBlock(MemRegionRef A, unsigned Nargs, unsigned Nins,
+ SExpr *Term = nullptr)
+ : BlockID(0), NumVars(0), NumPredecessors(0), Parent(nullptr),
+ Args(A, Nargs), Instrs(A, Nins), Terminator(Term) {}
+ BasicBlock(const BasicBlock &B, VarArray &&As, VarArray &&Is, SExpr *T)
+ : BlockID(0), NumVars(B.NumVars), NumPredecessors(B.NumPredecessors),
+ Parent(nullptr), Args(std::move(As)), Instrs(std::move(Is)),
+ Terminator(T) {}
+
+ unsigned blockID() const { return BlockID; }
+ unsigned numPredecessors() const { return NumPredecessors; }
+
+ const BasicBlock *parent() const { return Parent; }
+ BasicBlock *parent() { return Parent; }
+
+ const VarArray &arguments() const { return Args; }
+ VarArray &arguments() { return Args; }
+
+ const VarArray &instructions() const { return Instrs; }
+ VarArray &instructions() { return Instrs; }
+
+ const SExpr *terminator() const { return Terminator.get(); }
+ SExpr *terminator() { return Terminator.get(); }
+
+ void setBlockID(unsigned i) { BlockID = i; }
+ void setParent(BasicBlock *P) { Parent = P; }
+ void setNumPredecessors(unsigned NP) { NumPredecessors = NP; }
+ void setTerminator(SExpr *E) { Terminator.reset(E); }
+
+ void addArgument(Variable *V) {
+ V->setID(BlockID, NumVars++);
+ Args.push_back(V);
+ }
+ void addInstruction(Variable *V) {
+ V->setID(BlockID, NumVars++);
+ Instrs.push_back(V);
+ }
+
+ template <class V> BasicBlock *traverse(V &Visitor) {
+ typename V::template Container<Variable*> Nas(Visitor, Args.size());
+ typename V::template Container<Variable*> Nis(Visitor, Instrs.size());
+
+ for (auto *A : Args) {
+ typename V::R_SExpr Ne = Visitor.traverse(A->Definition);
+ Variable *Nvd = Visitor.enterScope(*A, Ne);
+ Nas.push_back(Nvd);
+ }
+ for (auto *I : Instrs) {
+ typename V::R_SExpr Ne = Visitor.traverse(I->Definition);
+ Variable *Nvd = Visitor.enterScope(*I, Ne);
+ Nis.push_back(Nvd);
+ }
+ typename V::R_SExpr Nt = Visitor.traverse(Terminator);
+
+ // TODO: use reverse iterator
+ for (unsigned J = 0, JN = Instrs.size(); J < JN; ++J)
+ Visitor.exitScope(*Instrs[JN-J]);
+ for (unsigned I = 0, IN = Instrs.size(); I < IN; ++I)
+ Visitor.exitScope(*Args[IN-I]);
+
+ return Visitor.reduceBasicBlock(*this, Nas, Nis, Nt);
+ }
+
+ template <class C> typename C::CType compare(BasicBlock *E, C &Cmp) {
+ // TODO: implement CFG comparisons
+ return Cmp.comparePointers(this, E);
+ }
+
+private:
+ friend class SCFG;
+
+ unsigned BlockID;
+ unsigned NumVars;
+ unsigned NumPredecessors; // Number of blocks which jump to this one.
+
+ BasicBlock *Parent; // The parent block is the enclosing lexical scope.
+ // The parent dominates this block.
+ VarArray Args; // Phi nodes. One argument per predecessor.
+ VarArray Instrs;
+ SExprRef Terminator;
+};
+
+
+inline void SCFG::add(BasicBlock *BB) {
+ BB->setBlockID(Blocks.size());
+ Blocks.push_back(BB);
+}
+
+
+template <class V>
+typename V::R_SExpr SCFG::traverse(V &Visitor) {
+ Visitor.enterCFG(*this);
+ typename V::template Container<BasicBlock *> Bbs(Visitor, Blocks.size());
+ for (auto *B : Blocks) {
+ BasicBlock *Nbb = B->traverse(Visitor);
+ Bbs.push_back(Nbb);
+ }
+ Visitor.exitCFG(*this);
+ return Visitor.reduceSCFG(*this, Bbs);
+}
+
+
+class Phi : public SExpr {
+public:
+ // TODO: change to SExprRef
+ typedef SimpleArray<SExpr *> ValArray;
+
+ // In minimal SSA form, all Phi nodes are MultiVal.
+ // During conversion to SSA, incomplete Phi nodes may be introduced, which
+ // are later determined to be SingleVal.
+ enum Status {
+ PH_MultiVal = 0, // Phi node has multiple distinct values. (Normal)
+ PH_SingleVal, // Phi node has one distinct value, and can be eliminated
+ PH_Incomplete // Phi node is incomplete
+ };
+
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
+
+ Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {}
+ Phi(const Phi &P, ValArray &&Vs) // steals memory of Vs
+ : SExpr(COP_Phi), Values(std::move(Vs)) {}
+
+ const ValArray &values() const { return Values; }
+ ValArray &values() { return Values; }
+
+ Status status() const { return static_cast<Status>(Flags); }
+ void setStatus(Status s) { Flags = s; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::template Container<typename V::R_SExpr> Nvs(Visitor,
+ Values.size());
+ for (auto *Val : Values) {
+ typename V::R_SExpr Nv = Visitor.traverse(Val);
+ Nvs.push_back(Nv);
+ }
+ return Visitor.reducePhi(*this, Nvs);
+ }
+
+ template <class C> typename C::CType compare(Phi *E, C &Cmp) {
+ // TODO: implement CFG comparisons
+ return Cmp.comparePointers(this, E);
+ }
+
+private:
+ ValArray Values;
+};
+
+
+class Goto : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
+
+ Goto(BasicBlock *B, unsigned Index)
+ : SExpr(COP_Goto), TargetBlock(B), Index(0) {}
+ Goto(const Goto &G, BasicBlock *B, unsigned I)
+ : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
+
+ const BasicBlock *targetBlock() const { return TargetBlock; }
+ BasicBlock *targetBlock() { return TargetBlock; }
+
+ unsigned index() const { return Index; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ // TODO -- rewrite indices properly
+ BasicBlock *Ntb = Visitor.reduceBasicBlockRef(TargetBlock);
+ return Visitor.reduceGoto(*this, Ntb, Index);
+ }
+
+ template <class C> typename C::CType compare(Goto *E, C &Cmp) {
+ // TODO -- implement CFG comparisons
+ return Cmp.comparePointers(this, E);
+ }
+
+private:
+ BasicBlock *TargetBlock;
+ unsigned Index; // Index into Phi nodes of target block.
+};
+
+
+class Branch : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
+
+ Branch(SExpr *C, BasicBlock *T, BasicBlock *E)
+ : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
+ ThenIndex(0), ElseIndex(0)
+ {}
+ Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E)
+ : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
+ ThenIndex(0), ElseIndex(0)
+ {}
+
+ const SExpr *condition() const { return Condition; }
+ SExpr *condition() { return Condition; }
+
+ const BasicBlock *thenBlock() const { return ThenBlock; }
+ BasicBlock *thenBlock() { return ThenBlock; }
+
+ const BasicBlock *elseBlock() const { return ElseBlock; }
+ BasicBlock *elseBlock() { return ElseBlock; }
+
+ unsigned thenIndex() const { return ThenIndex; }
+ unsigned elseIndex() const { return ElseIndex; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nc = Visitor.traverse(Condition);
+ BasicBlock *Ntb = Visitor.reduceBasicBlockRef(ThenBlock);
+ BasicBlock *Nte = Visitor.reduceBasicBlockRef(ElseBlock);
+ return Visitor.reduceBranch(*this, Nc, Ntb, Nte);
+ }
+
+ template <class C> typename C::CType compare(Branch *E, C &Cmp) {
+ // TODO -- implement CFG comparisons
+ return Cmp.comparePointers(this, E);
+ }
+
+private:
+ SExpr *Condition;
+ BasicBlock *ThenBlock;
+ BasicBlock *ElseBlock;
+ unsigned ThenIndex;
+ unsigned ElseIndex;
+};
+
+
+// An identifier, e.g. 'foo' or 'x'.
+// This is a pseduo-term; it will be lowered to a variable or projection.
+class Identifier : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Identifier; }
+
+ Identifier(StringRef Id): SExpr(COP_Identifier), Name(Id) { }
+ Identifier(const Identifier& I) : SExpr(I), Name(I.Name) { }
+
+ StringRef name() const { return Name; }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ return Visitor.reduceIdentifier(*this);
+ }
+
+ template <class C> typename C::CType compare(Identifier* E, C& Cmp) {
+ return Cmp.compareStrings(name(), E->name());
+ }
+
+private:
+ StringRef Name;
+};
+
+
+// An if-then-else expression.
+// This is a pseduo-term; it will be lowered to a CFG.
+class IfThenElse : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; }
+
+ IfThenElse(SExpr *C, SExpr *T, SExpr *E)
+ : SExpr(COP_IfThenElse), Condition(C), ThenExpr(T), ElseExpr(E)
+ { }
+ IfThenElse(const IfThenElse &I, SExpr *C, SExpr *T, SExpr *E)
+ : SExpr(I), Condition(C), ThenExpr(T), ElseExpr(E)
+ { }
+
+ SExpr *condition() { return Condition.get(); } // Address to store to
+ const SExpr *condition() const { return Condition.get(); }
+
+ SExpr *thenExpr() { return ThenExpr.get(); } // Value to store
+ const SExpr *thenExpr() const { return ThenExpr.get(); }
+
+ SExpr *elseExpr() { return ElseExpr.get(); } // Value to store
+ const SExpr *elseExpr() const { return ElseExpr.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ typename V::R_SExpr Nc = Visitor.traverse(Condition);
+ typename V::R_SExpr Nt = Visitor.traverse(ThenExpr);
+ typename V::R_SExpr Ne = Visitor.traverse(ElseExpr);
+ return Visitor.reduceIfThenElse(*this, Nc, Nt, Ne);
+ }
+
+ template <class C> typename C::CType compare(IfThenElse* E, C& Cmp) {
+ typename C::CType Ct = Cmp.compare(condition(), E->condition());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ Ct = Cmp.compare(thenExpr(), E->thenExpr());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ return Cmp.compare(elseExpr(), E->elseExpr());
+ }
+
+private:
+ SExprRef Condition;
+ SExprRef ThenExpr;
+ SExprRef ElseExpr;
+};
+
+
+// A let-expression, e.g. let x=t; u.
+// This is a pseduo-term; it will be lowered to a CFG.
+class Let : public SExpr {
+public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Let; }
+
+ Let(Variable *Vd, SExpr *Bd) : SExpr(COP_Let), VarDecl(Vd), Body(Bd) {
+ Vd->setKind(Variable::VK_Let);
+ }
+ Let(const Let &L, Variable *Vd, SExpr *Bd) : SExpr(L), VarDecl(Vd), Body(Bd) {
+ Vd->setKind(Variable::VK_Let);
+ }
+
+ Variable *variableDecl() { return VarDecl; }
+ const Variable *variableDecl() const { return VarDecl; }
+
+ SExpr *body() { return Body.get(); }
+ const SExpr *body() const { return Body.get(); }
+
+ template <class V> typename V::R_SExpr traverse(V &Visitor) {
+ // This is a variable declaration, so traverse the definition.
+ typename V::R_SExpr E0 = Visitor.traverse(VarDecl->Definition, TRV_Lazy);
+ // Tell the rewriter to enter the scope of the let variable.
+ Variable *Nvd = Visitor.enterScope(*VarDecl, E0);
+ typename V::R_SExpr E1 = Visitor.traverse(Body);
+ Visitor.exitScope(*VarDecl);
+ return Visitor.reduceLet(*this, Nvd, E1);
+ }
+
+ template <class C> typename C::CType compare(Let* E, C& Cmp) {
+ typename C::CType Ct =
+ Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
+ if (Cmp.notTrue(Ct))
+ return Ct;
+ Cmp.enterScope(variableDecl(), E->variableDecl());
+ Ct = Cmp.compare(body(), E->body());
+ Cmp.leaveScope();
+ return Ct;
+ }
+
+private:
+ Variable *VarDecl;
+ SExprRef Body;
+};
+
+
+
+SExpr *getCanonicalVal(SExpr *E);
+void simplifyIncompleteArg(Variable *V, til::Phi *Ph);
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif // LLVM_CLANG_THREAD_SAFETY_TIL_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
new file mode 100644
index 0000000..b28085b
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -0,0 +1,883 @@
+//===- ThreadSafetyTraverse.h ----------------------------------*- 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 a framework for doing generic traversals and rewriting
+// operations over the Thread Safety TIL.
+//
+// UNDER CONSTRUCTION. USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
+#define LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
+
+#include "ThreadSafetyTIL.h"
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+// Defines an interface used to traverse SExprs. Traversals have been made as
+// generic as possible, and are intended to handle any kind of pass over the
+// AST, e.g. visiters, copying, non-destructive rewriting, destructive
+// (in-place) rewriting, hashing, typing, etc.
+//
+// Traversals implement the functional notion of a "fold" operation on SExprs.
+// Each SExpr class provides a traverse method, which does the following:
+// * e->traverse(v):
+// // compute a result r_i for each subexpression e_i
+// for (i = 1..n) r_i = v.traverse(e_i);
+// // combine results into a result for e, where X is the class of e
+// return v.reduceX(*e, r_1, .. r_n).
+//
+// A visitor can control the traversal by overriding the following methods:
+// * v.traverse(e):
+// return v.traverseByCase(e), which returns v.traverseX(e)
+// * v.traverseX(e): (X is the class of e)
+// return e->traverse(v).
+// * v.reduceX(*e, r_1, .. r_n):
+// compute a result for a node of type X
+//
+// The reduceX methods control the kind of traversal (visitor, copy, etc.).
+// These are separated into a separate class R for the purpose of code reuse.
+// The full reducer interface also has methods to handle scopes
+template <class Self, class R> class Traversal : public R {
+public:
+ Self *self() { return reinterpret_cast<Self *>(this); }
+
+ // Traverse an expression -- returning a result of type R_SExpr.
+ // Override this method to do something for every expression, regardless
+ // of which kind it is. TraversalKind indicates the context in which
+ // the expression occurs, and can be:
+ // TRV_Normal
+ // TRV_Lazy -- e may need to be traversed lazily, using a Future.
+ // TRV_Tail -- e occurs in a tail position
+ typename R::R_SExpr traverse(SExprRef &E, TraversalKind K = TRV_Normal) {
+ return traverse(E.get(), K);
+ }
+
+ typename R::R_SExpr traverse(SExpr *E, TraversalKind K = TRV_Normal) {
+ return traverseByCase(E);
+ }
+
+ // Helper method to call traverseX(e) on the appropriate type.
+ typename R::R_SExpr traverseByCase(SExpr *E) {
+ switch (E->opcode()) {
+#define TIL_OPCODE_DEF(X) \
+ case COP_##X: \
+ return self()->traverse##X(cast<X>(E));
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+ }
+ }
+
+// Traverse e, by static dispatch on the type "X" of e.
+// Override these methods to do something for a particular kind of term.
+#define TIL_OPCODE_DEF(X) \
+ typename R::R_SExpr traverse##X(X *e) { return e->traverse(*self()); }
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+};
+
+
+// Implements a Reducer that makes a deep copy of an SExpr.
+// The default behavior of reduce##X(...) is to create a copy of the original.
+// Subclasses can override reduce##X to implement non-destructive rewriting
+// passes.
+class CopyReducer {
+public:
+ CopyReducer() {}
+
+ void setArena(MemRegionRef A) { Arena = A; }
+
+ // R_SExpr is the result type for a traversal.
+ // A copy or non-destructive rewrite returns a newly allocated term.
+ typedef SExpr *R_SExpr;
+
+ // Container is a minimal interface used to store results when traversing
+ // SExprs of variable arity, such as Phi, Goto, and SCFG.
+ template <class T> class Container {
+ public:
+ // Allocate a new container with a capacity for n elements.
+ Container(CopyReducer &R, unsigned N) : Elems(R.Arena, N) {}
+
+ // Push a new element onto the container.
+ void push_back(T E) { Elems.push_back(E); }
+
+ private:
+ friend class CopyReducer;
+ SimpleArray<T> Elems;
+ };
+
+public:
+ R_SExpr reduceNull() {
+ return nullptr;
+ }
+ // R_SExpr reduceFuture(...) is never used.
+
+ R_SExpr reduceUndefined(Undefined &Orig) {
+ return new (Arena) Undefined(Orig);
+ }
+ R_SExpr reduceWildcard(Wildcard &Orig) {
+ return new (Arena) Wildcard(Orig);
+ }
+
+ R_SExpr reduceLiteral(Literal &Orig) {
+ return new (Arena) Literal(Orig);
+ }
+ R_SExpr reduceLiteralPtr(LiteralPtr &Orig) {
+ return new (Arena) LiteralPtr(Orig);
+ }
+
+ R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
+ return new (Arena) Function(Orig, Nvd, E0);
+ }
+ R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) {
+ return new (Arena) SFunction(Orig, Nvd, E0);
+ }
+ R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) {
+ return new (Arena) Code(Orig, E0, E1);
+ }
+ R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) {
+ return new (Arena) Field(Orig, E0, E1);
+ }
+
+ R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) {
+ return new (Arena) Apply(Orig, E0, E1);
+ }
+ R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) {
+ return new (Arena) SApply(Orig, E0, E1);
+ }
+ R_SExpr reduceProject(Project &Orig, R_SExpr E0) {
+ return new (Arena) Project(Orig, E0);
+ }
+ R_SExpr reduceCall(Call &Orig, R_SExpr E0) {
+ return new (Arena) Call(Orig, E0);
+ }
+
+ R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) {
+ return new (Arena) Alloc(Orig, E0);
+ }
+ R_SExpr reduceLoad(Load &Orig, R_SExpr E0) {
+ return new (Arena) Load(Orig, E0);
+ }
+ R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) {
+ return new (Arena) Store(Orig, E0, E1);
+ }
+ R_SExpr reduceArrayFirst(ArrayFirst &Orig, R_SExpr E0) {
+ return new (Arena) ArrayFirst(Orig, E0);
+ }
+ R_SExpr reduceArrayAdd(ArrayAdd &Orig, R_SExpr E0, R_SExpr E1) {
+ return new (Arena) ArrayAdd(Orig, E0, E1);
+ }
+ R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) {
+ return new (Arena) UnaryOp(Orig, E0);
+ }
+ R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) {
+ return new (Arena) BinaryOp(Orig, E0, E1);
+ }
+ R_SExpr reduceCast(Cast &Orig, R_SExpr E0) {
+ return new (Arena) Cast(Orig, E0);
+ }
+
+ R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> &Bbs) {
+ return new (Arena) SCFG(Orig, std::move(Bbs.Elems));
+ }
+ R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
+ return new (Arena) Phi(Orig, std::move(As.Elems));
+ }
+ R_SExpr reduceGoto(Goto &Orig, BasicBlock *B, unsigned Index) {
+ return new (Arena) Goto(Orig, B, Index);
+ }
+ R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
+ return new (Arena) Branch(O, C, B0, B1);
+ }
+
+ R_SExpr reduceIdentifier(Identifier &Orig) {
+ return new (Arena) Identifier(Orig);
+ }
+ R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) {
+ return new (Arena) IfThenElse(Orig, C, T, E);
+ }
+ R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) {
+ return new (Arena) Let(Orig, Nvd, B);
+ }
+
+ BasicBlock *reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
+ Container<Variable *> &Is, R_SExpr T) {
+ return new (Arena) BasicBlock(Orig, std::move(As.Elems),
+ std::move(Is.Elems), T);
+ }
+
+ // Create a new variable from orig, and push it onto the lexical scope.
+ Variable *enterScope(Variable &Orig, R_SExpr E0) {
+ return new (Arena) Variable(Orig, E0);
+ }
+ // Exit the lexical scope of orig.
+ void exitScope(const Variable &Orig) {}
+
+ void enterCFG(SCFG &Cfg) {}
+ void exitCFG(SCFG &Cfg) {}
+
+ // Map Variable references to their rewritten definitions.
+ Variable *reduceVariableRef(Variable *Ovd) { return Ovd; }
+
+ // Map BasicBlock references to their rewritten defs.
+ BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
+
+private:
+ MemRegionRef Arena;
+};
+
+
+class SExprCopier : public Traversal<SExprCopier, CopyReducer> {
+public:
+ SExprCopier(MemRegionRef A) { setArena(A); }
+
+ // Create a copy of e in region a.
+ static SExpr *copy(SExpr *E, MemRegionRef A) {
+ SExprCopier Copier(A);
+ return Copier.traverse(E);
+ }
+};
+
+
+// Implements a Reducer that visits each subexpression, and returns either
+// true or false.
+class VisitReducer {
+public:
+ VisitReducer() {}
+
+ // A visitor returns a bool, representing success or failure.
+ typedef bool R_SExpr;
+
+ // A visitor "container" is a single bool, which accumulates success.
+ template <class T> class Container {
+ public:
+ Container(VisitReducer &R, unsigned N) : Success(true) {}
+ void push_back(bool E) { Success = Success && E; }
+
+ private:
+ friend class VisitReducer;
+ bool Success;
+ };
+
+public:
+ R_SExpr reduceNull() { return true; }
+ R_SExpr reduceUndefined(Undefined &Orig) { return true; }
+ R_SExpr reduceWildcard(Wildcard &Orig) { return true; }
+
+ R_SExpr reduceLiteral(Literal &Orig) { return true; }
+ R_SExpr reduceLiteralPtr(Literal &Orig) { return true; }
+
+ R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
+ return Nvd && E0;
+ }
+ R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) {
+ return Nvd && E0;
+ }
+ R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) {
+ return E0 && E1;
+ }
+ R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) {
+ return E0 && E1;
+ }
+ R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) {
+ return E0 && E1;
+ }
+ R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) {
+ return E0 && E1;
+ }
+ R_SExpr reduceProject(Project &Orig, R_SExpr E0) { return E0; }
+ R_SExpr reduceCall(Call &Orig, R_SExpr E0) { return E0; }
+ R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) { return E0; }
+ R_SExpr reduceLoad(Load &Orig, R_SExpr E0) { return E0; }
+ R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; }
+ R_SExpr reduceArrayFirst(Store &Orig, R_SExpr E0) { return E0; }
+ R_SExpr reduceArrayAdd(Store &Orig, R_SExpr E0, R_SExpr E1) {
+ return E0 && E1;
+ }
+ R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) { return E0; }
+ R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) {
+ return E0 && E1;
+ }
+ R_SExpr reduceCast(Cast &Orig, R_SExpr E0) { return E0; }
+
+ R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> Bbs) {
+ return Bbs.Success;
+ }
+ R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
+ return As.Success;
+ }
+ R_SExpr reduceGoto(Goto &Orig, BasicBlock *B, unsigned Index) {
+ return true;
+ }
+ R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
+ return C;
+ }
+
+ R_SExpr reduceIdentifier(Identifier &Orig) {
+ return true;
+ }
+ R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) {
+ return C && T && E;
+ }
+ R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) {
+ return Nvd && B;
+ }
+
+ BasicBlock *reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
+ Container<Variable *> &Is, R_SExpr T) {
+ return (As.Success && Is.Success && T) ? &Orig : nullptr;
+ }
+
+ Variable *enterScope(Variable &Orig, R_SExpr E0) {
+ return E0 ? &Orig : nullptr;
+ }
+ void exitScope(const Variable &Orig) {}
+
+ void enterCFG(SCFG &Cfg) {}
+ void exitCFG(SCFG &Cfg) {}
+
+ Variable *reduceVariableRef(Variable *Ovd) { return Ovd; }
+
+ BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
+};
+
+
+// A visitor will visit each node, and halt if any reducer returns false.
+template <class Self>
+class SExprVisitor : public Traversal<Self, VisitReducer> {
+public:
+ SExprVisitor() : Success(true) {}
+
+ bool traverse(SExpr *E, TraversalKind K = TRV_Normal) {
+ Success = Success && this->traverseByCase(E);
+ return Success;
+ }
+
+ static bool visit(SExpr *E) {
+ SExprVisitor Visitor;
+ return Visitor.traverse(E);
+ }
+
+private:
+ bool Success;
+};
+
+
+// Basic class for comparison operations over expressions.
+template <typename Self>
+class Comparator {
+protected:
+ Self *self() { return reinterpret_cast<Self *>(this); }
+
+public:
+ bool compareByCase(SExpr *E1, SExpr* E2) {
+ switch (E1->opcode()) {
+#define TIL_OPCODE_DEF(X) \
+ case COP_##X: \
+ return cast<X>(E1)->compare(cast<X>(E2), *self());
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+ }
+ }
+};
+
+
+class EqualsComparator : public Comparator<EqualsComparator> {
+public:
+ // Result type for the comparison, e.g. bool for simple equality,
+ // or int for lexigraphic comparison (-1, 0, 1). Must have one value which
+ // denotes "true".
+ typedef bool CType;
+
+ CType trueResult() { return true; }
+ bool notTrue(CType ct) { return !ct; }
+
+ bool compareIntegers(unsigned i, unsigned j) { return i == j; }
+ bool compareStrings (StringRef s, StringRef r) { return s == r; }
+ bool comparePointers(const void* P, const void* Q) { return P == Q; }
+
+ bool compare(SExpr *E1, SExpr* E2) {
+ if (E1->opcode() != E2->opcode())
+ return false;
+ return compareByCase(E1, E2);
+ }
+
+ // TODO -- handle alpha-renaming of variables
+ void enterScope(Variable* V1, Variable* V2) { }
+ void leaveScope() { }
+
+ bool compareVariableRefs(Variable* V1, Variable* V2) {
+ return V1 == V2;
+ }
+
+ static bool compareExprs(SExpr *E1, SExpr* E2) {
+ EqualsComparator Eq;
+ return Eq.compare(E1, E2);
+ }
+};
+
+
+// Pretty printer for TIL expressions
+template <typename Self, typename StreamType>
+class PrettyPrinter {
+private:
+ bool Verbose; // Print out additional information
+
+public:
+ PrettyPrinter(bool V = false) : Verbose(V) { }
+
+ static void print(SExpr *E, StreamType &SS) {
+ Self printer;
+ printer.printSExpr(E, SS, Prec_MAX);
+ }
+
+protected:
+ Self *self() { return reinterpret_cast<Self *>(this); }
+
+ void newline(StreamType &SS) {
+ SS << "\n";
+ }
+
+ void printBlockLabel(StreamType & SS, BasicBlock *BB, unsigned index) {
+ if (!BB) {
+ SS << "BB_null";
+ return;
+ }
+ SS << "BB_";
+ SS << BB->blockID();
+ }
+
+ // TODO: further distinguish between binary operations.
+ static const unsigned Prec_Atom = 0;
+ static const unsigned Prec_Postfix = 1;
+ static const unsigned Prec_Unary = 2;
+ static const unsigned Prec_Binary = 3;
+ static const unsigned Prec_Other = 4;
+ static const unsigned Prec_Decl = 5;
+ static const unsigned Prec_MAX = 6;
+
+ // Return the precedence of a given node, for use in pretty printing.
+ unsigned precedence(SExpr *E) {
+ switch (E->opcode()) {
+ case COP_Future: return Prec_Atom;
+ case COP_Undefined: return Prec_Atom;
+ case COP_Wildcard: return Prec_Atom;
+
+ case COP_Literal: return Prec_Atom;
+ case COP_LiteralPtr: return Prec_Atom;
+ case COP_Variable: return Prec_Atom;
+ case COP_Function: return Prec_Decl;
+ case COP_SFunction: return Prec_Decl;
+ case COP_Code: return Prec_Decl;
+ case COP_Field: return Prec_Decl;
+
+ case COP_Apply: return Prec_Postfix;
+ case COP_SApply: return Prec_Postfix;
+ case COP_Project: return Prec_Postfix;
+
+ case COP_Call: return Prec_Postfix;
+ case COP_Alloc: return Prec_Other;
+ case COP_Load: return Prec_Postfix;
+ case COP_Store: return Prec_Other;
+ case COP_ArrayFirst: return Prec_Postfix;
+ case COP_ArrayAdd: return Prec_Postfix;
+
+ case COP_UnaryOp: return Prec_Unary;
+ case COP_BinaryOp: return Prec_Binary;
+ case COP_Cast: return Prec_Unary;
+
+ case COP_SCFG: return Prec_Decl;
+ case COP_Phi: return Prec_Atom;
+ case COP_Goto: return Prec_Atom;
+ case COP_Branch: return Prec_Atom;
+
+ case COP_Identifier: return Prec_Atom;
+ case COP_IfThenElse: return Prec_Other;
+ case COP_Let: return Prec_Decl;
+ }
+ return Prec_MAX;
+ }
+
+ void printSExpr(SExpr *E, StreamType &SS, unsigned P) {
+ if (!E) {
+ self()->printNull(SS);
+ return;
+ }
+ if (self()->precedence(E) > P) {
+ // Wrap expr in () if necessary.
+ SS << "(";
+ self()->printSExpr(E, SS, Prec_MAX);
+ SS << ")";
+ return;
+ }
+
+ switch (E->opcode()) {
+#define TIL_OPCODE_DEF(X) \
+ case COP_##X: \
+ self()->print##X(cast<X>(E), SS); \
+ return;
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+ }
+ }
+
+ void printNull(StreamType &SS) {
+ SS << "#null";
+ }
+
+ void printFuture(Future *E, StreamType &SS) {
+ self()->printSExpr(E->maybeGetResult(), SS, Prec_Atom);
+ }
+
+ void printUndefined(Undefined *E, StreamType &SS) {
+ SS << "#undefined";
+ }
+
+ void printWildcard(Wildcard *E, StreamType &SS) {
+ SS << "_";
+ }
+
+ template<class T>
+ void printLiteralT(LiteralT<T> *E, StreamType &SS) {
+ SS << E->value();
+ }
+
+ void printLiteral(Literal *E, StreamType &SS) {
+ if (E->clangExpr())
+ SS << getSourceLiteralString(E->clangExpr());
+ else {
+ ValueType VT = E->valueType();
+ switch (VT.Base) {
+ case ValueType::BT_Void: {
+ SS << "void";
+ return;
+ }
+ case ValueType::BT_Bool: {
+ if (reinterpret_cast<LiteralT<bool>*>(E)->value())
+ SS << "true";
+ else
+ SS << "false";
+ return;
+ }
+ case ValueType::BT_Int: {
+ switch (VT.Size) {
+ case ValueType::ST_8:
+ if (VT.Signed)
+ printLiteralT(reinterpret_cast<LiteralT<int8_t>*>(E), SS);
+ else
+ printLiteralT(reinterpret_cast<LiteralT<uint8_t>*>(E), SS);
+ return;
+ case ValueType::ST_16:
+ if (VT.Signed)
+ printLiteralT(reinterpret_cast<LiteralT<int16_t>*>(E), SS);
+ else
+ printLiteralT(reinterpret_cast<LiteralT<uint16_t>*>(E), SS);
+ return;
+ case ValueType::ST_32:
+ if (VT.Signed)
+ printLiteralT(reinterpret_cast<LiteralT<int32_t>*>(E), SS);
+ else
+ printLiteralT(reinterpret_cast<LiteralT<uint32_t>*>(E), SS);
+ return;
+ case ValueType::ST_64:
+ if (VT.Signed)
+ printLiteralT(reinterpret_cast<LiteralT<int64_t>*>(E), SS);
+ else
+ printLiteralT(reinterpret_cast<LiteralT<uint64_t>*>(E), SS);
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ case ValueType::BT_Float: {
+ switch (VT.Size) {
+ case ValueType::ST_32:
+ printLiteralT(reinterpret_cast<LiteralT<float>*>(E), SS);
+ return;
+ case ValueType::ST_64:
+ printLiteralT(reinterpret_cast<LiteralT<double>*>(E), SS);
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ case ValueType::BT_String: {
+ SS << "\"";
+ printLiteralT(reinterpret_cast<LiteralT<bool>*>(E), SS);
+ SS << "\"";
+ return;
+ }
+ case ValueType::BT_Pointer: {
+ SS << "#ptr";
+ return;
+ }
+ case ValueType::BT_ValueRef: {
+ SS << "#vref";
+ return;
+ }
+ }
+ }
+ SS << "#lit";
+ }
+
+ void printLiteralPtr(LiteralPtr *E, StreamType &SS) {
+ SS << E->clangDecl()->getNameAsString();
+ }
+
+ void printVariable(Variable *V, StreamType &SS, bool IsVarDecl = false) {
+ SExpr* E = nullptr;
+ if (!IsVarDecl) {
+ E = getCanonicalVal(V);
+ if (E != V) {
+ printSExpr(E, SS, Prec_Atom);
+ if (Verbose) {
+ SS << " /*";
+ SS << V->name() << V->getBlockID() << "_" << V->getID();
+ SS << "*/";
+ }
+ return;
+ }
+ }
+ SS << V->name() << V->getBlockID() << "_" << V->getID();
+ }
+
+ void printFunction(Function *E, StreamType &SS, unsigned sugared = 0) {
+ switch (sugared) {
+ default:
+ SS << "\\("; // Lambda
+ break;
+ case 1:
+ SS << "("; // Slot declarations
+ break;
+ case 2:
+ SS << ", "; // Curried functions
+ break;
+ }
+ self()->printVariable(E->variableDecl(), SS, true);
+ SS << ": ";
+ self()->printSExpr(E->variableDecl()->definition(), SS, Prec_MAX);
+
+ SExpr *B = E->body();
+ if (B && B->opcode() == COP_Function)
+ self()->printFunction(cast<Function>(B), SS, 2);
+ else {
+ SS << ")";
+ self()->printSExpr(B, SS, Prec_Decl);
+ }
+ }
+
+ void printSFunction(SFunction *E, StreamType &SS) {
+ SS << "@";
+ self()->printVariable(E->variableDecl(), SS, true);
+ SS << " ";
+ self()->printSExpr(E->body(), SS, Prec_Decl);
+ }
+
+ void printCode(Code *E, StreamType &SS) {
+ SS << ": ";
+ self()->printSExpr(E->returnType(), SS, Prec_Decl-1);
+ SS << " -> ";
+ self()->printSExpr(E->body(), SS, Prec_Decl);
+ }
+
+ void printField(Field *E, StreamType &SS) {
+ SS << ": ";
+ self()->printSExpr(E->range(), SS, Prec_Decl-1);
+ SS << " = ";
+ self()->printSExpr(E->body(), SS, Prec_Decl);
+ }
+
+ void printApply(Apply *E, StreamType &SS, bool sugared = false) {
+ SExpr *F = E->fun();
+ if (F->opcode() == COP_Apply) {
+ printApply(cast<Apply>(F), SS, true);
+ SS << ", ";
+ } else {
+ self()->printSExpr(F, SS, Prec_Postfix);
+ SS << "(";
+ }
+ self()->printSExpr(E->arg(), SS, Prec_MAX);
+ if (!sugared)
+ SS << ")$";
+ }
+
+ void printSApply(SApply *E, StreamType &SS) {
+ self()->printSExpr(E->sfun(), SS, Prec_Postfix);
+ if (E->isDelegation()) {
+ SS << "@(";
+ self()->printSExpr(E->arg(), SS, Prec_MAX);
+ SS << ")";
+ }
+ }
+
+ void printProject(Project *E, StreamType &SS) {
+ self()->printSExpr(E->record(), SS, Prec_Postfix);
+ SS << ".";
+ SS << E->slotName();
+ }
+
+ void printCall(Call *E, StreamType &SS) {
+ SExpr *T = E->target();
+ if (T->opcode() == COP_Apply) {
+ self()->printApply(cast<Apply>(T), SS, true);
+ SS << ")";
+ }
+ else {
+ self()->printSExpr(T, SS, Prec_Postfix);
+ SS << "()";
+ }
+ }
+
+ void printAlloc(Alloc *E, StreamType &SS) {
+ SS << "new ";
+ self()->printSExpr(E->dataType(), SS, Prec_Other-1);
+ }
+
+ void printLoad(Load *E, StreamType &SS) {
+ self()->printSExpr(E->pointer(), SS, Prec_Postfix);
+ SS << "^";
+ }
+
+ void printStore(Store *E, StreamType &SS) {
+ self()->printSExpr(E->destination(), SS, Prec_Other-1);
+ SS << " := ";
+ self()->printSExpr(E->source(), SS, Prec_Other-1);
+ }
+
+ void printArrayFirst(ArrayFirst *E, StreamType &SS) {
+ self()->printSExpr(E->array(), SS, Prec_Postfix);
+ if (ArrayAdd *A = dyn_cast_or_null<ArrayAdd>(E->array())) {
+ SS << "[";
+ printSExpr(A->index(), SS, Prec_MAX);
+ SS << "]";
+ return;
+ }
+ SS << "[0]";
+ }
+
+ void printArrayAdd(ArrayAdd *E, StreamType &SS) {
+ self()->printSExpr(E->array(), SS, Prec_Postfix);
+ SS << " + ";
+ self()->printSExpr(E->index(), SS, Prec_Atom);
+ }
+
+ void printUnaryOp(UnaryOp *E, StreamType &SS) {
+ SS << getUnaryOpcodeString(E->unaryOpcode());
+ self()->printSExpr(E->expr(), SS, Prec_Unary);
+ }
+
+ void printBinaryOp(BinaryOp *E, StreamType &SS) {
+ self()->printSExpr(E->expr0(), SS, Prec_Binary-1);
+ SS << " " << getBinaryOpcodeString(E->binaryOpcode()) << " ";
+ self()->printSExpr(E->expr1(), SS, Prec_Binary-1);
+ }
+
+ void printCast(Cast *E, StreamType &SS) {
+ SS << "%";
+ self()->printSExpr(E->expr(), SS, Prec_Unary);
+ }
+
+ void printSCFG(SCFG *E, StreamType &SS) {
+ SS << "#CFG {\n";
+ for (auto BBI : *E) {
+ SS << "BB_" << BBI->blockID() << ":";
+ newline(SS);
+ for (auto A : BBI->arguments()) {
+ SS << "let ";
+ self()->printVariable(A, SS, true);
+ SS << " = ";
+ self()->printSExpr(A->definition(), SS, Prec_MAX);
+ SS << ";";
+ newline(SS);
+ }
+ for (auto I : BBI->instructions()) {
+ if (I->definition()->opcode() != COP_Store) {
+ SS << "let ";
+ self()->printVariable(I, SS, true);
+ SS << " = ";
+ }
+ self()->printSExpr(I->definition(), SS, Prec_MAX);
+ SS << ";";
+ newline(SS);
+ }
+ SExpr *T = BBI->terminator();
+ if (T) {
+ self()->printSExpr(T, SS, Prec_MAX);
+ SS << ";";
+ newline(SS);
+ }
+ newline(SS);
+ }
+ SS << "}";
+ newline(SS);
+ }
+
+ void printPhi(Phi *E, StreamType &SS) {
+ SS << "phi(";
+ if (E->status() == Phi::PH_SingleVal)
+ self()->printSExpr(E->values()[0], SS, Prec_MAX);
+ else {
+ unsigned i = 0;
+ for (auto V : E->values()) {
+ if (i++ > 0)
+ SS << ", ";
+ self()->printSExpr(V, SS, Prec_MAX);
+ }
+ }
+ SS << ")";
+ }
+
+ void printGoto(Goto *E, StreamType &SS) {
+ SS << "goto ";
+ printBlockLabel(SS, E->targetBlock(), E->index());
+ }
+
+ void printBranch(Branch *E, StreamType &SS) {
+ SS << "branch (";
+ self()->printSExpr(E->condition(), SS, Prec_MAX);
+ SS << ") ";
+ printBlockLabel(SS, E->thenBlock(), E->thenIndex());
+ SS << " ";
+ printBlockLabel(SS, E->elseBlock(), E->elseIndex());
+ }
+
+ void printIdentifier(Identifier *E, StreamType &SS) {
+ SS << E->name();
+ }
+
+ void printIfThenElse(IfThenElse *E, StreamType &SS) {
+ SS << "if (";
+ printSExpr(E->condition(), SS, Prec_MAX);
+ SS << ") then ";
+ printSExpr(E->thenExpr(), SS, Prec_Other);
+ SS << " else ";
+ printSExpr(E->elseExpr(), SS, Prec_Other);
+ }
+
+ void printLet(Let *E, StreamType &SS) {
+ SS << "let ";
+ printVariable(E->variableDecl(), SS, true);
+ SS << " = ";
+ printSExpr(E->variableDecl()->definition(), SS, Prec_Decl-1);
+ SS << "; ";
+ printSExpr(E->body(), SS, Prec_Decl-1);
+ }
+};
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif // LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
new file mode 100644
index 0000000..986103d
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -0,0 +1,301 @@
+//===- ThreadSafetyUtil.h --------------------------------------*- 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 some basic utility classes for use by ThreadSafetyTIL.h
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_UTIL_H
+#define LLVM_CLANG_THREAD_SAFETY_UTIL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "clang/AST/ExprCXX.h"
+
+#include <cassert>
+#include <cstddef>
+#include <vector>
+#include <utility>
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+// Simple wrapper class to abstract away from the details of memory management.
+// SExprs are allocated in pools, and deallocated all at once.
+class MemRegionRef {
+private:
+ union AlignmentType {
+ double d;
+ void *p;
+ long double dd;
+ long long ii;
+ };
+
+public:
+ MemRegionRef() : Allocator(nullptr) {}
+ MemRegionRef(llvm::BumpPtrAllocator *A) : Allocator(A) {}
+
+ void *allocate(size_t Sz) {
+ return Allocator->Allocate(Sz, llvm::AlignOf<AlignmentType>::Alignment);
+ }
+
+ template <typename T> T *allocateT() { return Allocator->Allocate<T>(); }
+
+ template <typename T> T *allocateT(size_t NumElems) {
+ return Allocator->Allocate<T>(NumElems);
+ }
+
+private:
+ llvm::BumpPtrAllocator *Allocator;
+};
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+
+inline void *operator new(size_t Sz,
+ clang::threadSafety::til::MemRegionRef &R) {
+ return R.allocate(Sz);
+}
+
+
+namespace clang {
+namespace threadSafety {
+
+std::string getSourceLiteralString(const clang::Expr *CE);
+
+using llvm::StringRef;
+using clang::SourceLocation;
+
+namespace til {
+
+
+// A simple fixed size array class that does not manage its own memory,
+// suitable for use with bump pointer allocation.
+template <class T> class SimpleArray {
+public:
+ SimpleArray() : Data(nullptr), Size(0), Capacity(0) {}
+ SimpleArray(T *Dat, size_t Cp, size_t Sz = 0)
+ : Data(Dat), Size(Sz), Capacity(Cp) {}
+ SimpleArray(MemRegionRef A, size_t Cp)
+ : Data(Cp == 0 ? nullptr : A.allocateT<T>(Cp)), Size(0), Capacity(Cp) {}
+ SimpleArray(SimpleArray<T> &&A)
+ : Data(A.Data), Size(A.Size), Capacity(A.Capacity) {
+ A.Data = nullptr;
+ A.Size = 0;
+ A.Capacity = 0;
+ }
+
+ SimpleArray &operator=(SimpleArray &&RHS) {
+ if (this != &RHS) {
+ Data = RHS.Data;
+ Size = RHS.Size;
+ Capacity = RHS.Capacity;
+
+ RHS.Data = nullptr;
+ RHS.Size = RHS.Capacity = 0;
+ }
+ return *this;
+ }
+
+ void reserve(size_t Ncp, MemRegionRef A) {
+ if (Ncp < Capacity)
+ return;
+ T *Odata = Data;
+ Data = A.allocateT<T>(Ncp);
+ Capacity = Ncp;
+ memcpy(Data, Odata, sizeof(T) * Size);
+ return;
+ }
+
+ typedef T *iterator;
+ typedef const T *const_iterator;
+
+ size_t size() const { return Size; }
+ size_t capacity() const { return Capacity; }
+
+ T &operator[](unsigned i) {
+ assert(i < Size && "Array index out of bounds.");
+ return Data[i];
+ }
+ const T &operator[](unsigned i) const {
+ assert(i < Size && "Array index out of bounds.");
+ return Data[i];
+ }
+
+ iterator begin() { return Data; }
+ iterator end() { return Data + Size; }
+
+ const_iterator cbegin() const { return Data; }
+ const_iterator cend() const { return Data + Size; }
+
+ void push_back(const T &Elem) {
+ assert(Size < Capacity);
+ Data[Size++] = Elem;
+ }
+
+ void setValues(unsigned Sz, const T& C) {
+ assert(Sz <= Capacity);
+ Size = Sz;
+ for (unsigned i = 0; i < Sz; ++i) {
+ Data[i] = C;
+ }
+ }
+
+ template <class Iter> unsigned append(Iter I, Iter E) {
+ size_t Osz = Size;
+ size_t J = Osz;
+ for (; J < Capacity && I != E; ++J, ++I)
+ Data[J] = *I;
+ Size = J;
+ return J - Osz;
+ }
+
+private:
+ SimpleArray(const SimpleArray<T> &A) LLVM_DELETED_FUNCTION;
+
+ T *Data;
+ size_t Size;
+ size_t Capacity;
+};
+
+} // end namespace til
+
+
+// A copy on write vector.
+// The vector can be in one of three states:
+// * invalid -- no operations are permitted.
+// * read-only -- read operations are permitted.
+// * writable -- read and write operations are permitted.
+// The init(), destroy(), and makeWritable() methods will change state.
+template<typename T>
+class CopyOnWriteVector {
+ class VectorData {
+ public:
+ VectorData() : NumRefs(1) { }
+ VectorData(const VectorData &VD) : NumRefs(1), Vect(VD.Vect) { }
+
+ unsigned NumRefs;
+ std::vector<T> Vect;
+ };
+
+ // No copy constructor or copy assignment. Use clone() with move assignment.
+ CopyOnWriteVector(const CopyOnWriteVector &V) LLVM_DELETED_FUNCTION;
+ void operator=(const CopyOnWriteVector &V) LLVM_DELETED_FUNCTION;
+
+public:
+ CopyOnWriteVector() : Data(nullptr) {}
+ CopyOnWriteVector(CopyOnWriteVector &&V) : Data(V.Data) { V.Data = nullptr; }
+ ~CopyOnWriteVector() { destroy(); }
+
+ // Returns true if this holds a valid vector.
+ bool valid() const { return Data; }
+
+ // Returns true if this vector is writable.
+ bool writable() const { return Data && Data->NumRefs == 1; }
+
+ // If this vector is not valid, initialize it to a valid vector.
+ void init() {
+ if (!Data) {
+ Data = new VectorData();
+ }
+ }
+
+ // Destroy this vector; thus making it invalid.
+ void destroy() {
+ if (!Data)
+ return;
+ if (Data->NumRefs <= 1)
+ delete Data;
+ else
+ --Data->NumRefs;
+ Data = nullptr;
+ }
+
+ // Make this vector writable, creating a copy if needed.
+ void makeWritable() {
+ if (!Data) {
+ Data = new VectorData();
+ return;
+ }
+ if (Data->NumRefs == 1)
+ return; // already writeable.
+ --Data->NumRefs;
+ Data = new VectorData(*Data);
+ }
+
+ // Create a lazy copy of this vector.
+ CopyOnWriteVector clone() { return CopyOnWriteVector(Data); }
+
+ CopyOnWriteVector &operator=(CopyOnWriteVector &&V) {
+ destroy();
+ Data = V.Data;
+ V.Data = nullptr;
+ return *this;
+ }
+
+ typedef typename std::vector<T>::const_iterator const_iterator;
+
+ const std::vector<T> &elements() const { return Data->Vect; }
+
+ const_iterator begin() const { return elements().cbegin(); }
+ const_iterator end() const { return elements().cend(); }
+
+ const T& operator[](unsigned i) const { return elements()[i]; }
+
+ unsigned size() const { return Data ? elements().size() : 0; }
+
+ // Return true if V and this vector refer to the same data.
+ bool sameAs(const CopyOnWriteVector &V) const { return Data == V.Data; }
+
+ // Clear vector. The vector must be writable.
+ void clear() {
+ assert(writable() && "Vector is not writable!");
+ Data->Vect.clear();
+ }
+
+ // Push a new element onto the end. The vector must be writable.
+ void push_back(const T &Elem) {
+ assert(writable() && "Vector is not writable!");
+ Data->Vect.push_back(Elem);
+ }
+
+ // Gets a mutable reference to the element at index(i).
+ // The vector must be writable.
+ T& elem(unsigned i) {
+ assert(writable() && "Vector is not writable!");
+ return Data->Vect[i];
+ }
+
+ // Drops elements from the back until the vector has size i.
+ void downsize(unsigned i) {
+ assert(writable() && "Vector is not writable!");
+ Data->Vect.erase(Data->Vect.begin() + i, Data->Vect.end());
+ }
+
+private:
+ CopyOnWriteVector(VectorData *D) : Data(D) {
+ if (!Data)
+ return;
+ ++Data->NumRefs;
+ }
+
+ VectorData *Data;
+};
+
+
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif // LLVM_CLANG_THREAD_SAFETY_UTIL_H
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 73b38b7..08e3354 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -287,7 +287,7 @@
const CFGBlock *getCallSiteBlock() const { return Block; }
/// Return true if the current LocationContext has no caller context.
- bool inTopFrame() const override { return getParent() == 0; }
+ bool inTopFrame() const override { return getParent() == nullptr; }
unsigned getIndex() const { return Index; }
@@ -438,7 +438,8 @@
// Get the top level stack frame.
const StackFrameContext *getStackFrame(const Decl *D) {
- return LocContexts.getStackFrame(getContext(D), 0, 0, 0, 0);
+ return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr,
+ 0);
}
// Get a stack frame with parent.
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 123d144..7909fdc 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -47,6 +47,7 @@
class CXXRecordDecl;
class CXXDeleteExpr;
class CXXNewExpr;
+ class BinaryOperator;
/// CFGElement - Represents a top-level expression in a basic block.
class CFGElement {
@@ -71,7 +72,7 @@
llvm::PointerIntPair<void *, 2> Data1;
llvm::PointerIntPair<void *, 2> Data2;
- CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = 0)
+ CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
: Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
assert(getKind() == kind);
@@ -170,7 +171,7 @@
class CFGImplicitDtor : public CFGElement {
protected:
CFGImplicitDtor() {}
- CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0)
+ CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
: CFGElement(kind, data1, data2) {
assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
}
@@ -261,7 +262,7 @@
class CFGMemberDtor : public CFGImplicitDtor {
public:
CFGMemberDtor(const FieldDecl *field)
- : CFGImplicitDtor(MemberDtor, field, 0) {}
+ : CFGImplicitDtor(MemberDtor, field, nullptr) {}
const FieldDecl *getFieldDecl() const {
return static_cast<const FieldDecl*>(Data1.getPointer());
@@ -280,7 +281,7 @@
class CFGTemporaryDtor : public CFGImplicitDtor {
public:
CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
- : CFGImplicitDtor(TemporaryDtor, expr, 0) {}
+ : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {}
const CXXBindTemporaryExpr *getBindTemporaryExpr() const {
return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
@@ -489,7 +490,7 @@
public:
explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
- : Elements(C), Label(NULL), Terminator(NULL), LoopTarget(NULL),
+ : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr),
BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
Parent(parent) {}
~CFGBlock() {}
@@ -690,7 +691,8 @@
// the elements beginning at the last position in prepared space.
iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt,
BumpVectorContext &C) {
- return iterator(Elements.insert(I.base(), Cnt, CFGAutomaticObjDtor(0, 0), C));
+ return iterator(Elements.insert(I.base(), Cnt,
+ CFGAutomaticObjDtor(nullptr, 0), C));
}
iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) {
*I = CFGAutomaticObjDtor(VD, S);
@@ -698,6 +700,17 @@
}
};
+/// \brief CFGCallback defines methods that should be called when a logical
+/// operator error is found when building the CFG.
+class CFGCallback {
+public:
+ CFGCallback() {}
+ virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
+ virtual void compareBitwiseEquality(const BinaryOperator *B,
+ bool isAlwaysTrue) {}
+ virtual ~CFGCallback() {}
+};
+
/// CFG - Represents a source-level, intra-procedural CFG that represents the
/// control-flow of a Stmt. The Stmt can represent an entire function body,
/// or a single expression. A CFG will always contain one empty block that
@@ -716,7 +729,7 @@
public:
typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
ForcedBlkExprs **forcedBlkExprs;
-
+ CFGCallback *Observer;
bool PruneTriviallyFalseEdges;
bool AddEHEdges;
bool AddInitializers;
@@ -740,13 +753,11 @@
}
BuildOptions()
- : forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
- ,AddEHEdges(false)
- ,AddInitializers(false)
- ,AddImplicitDtors(false)
- ,AddTemporaryDtors(false)
- ,AddStaticInitBranches(false)
- ,AddCXXNewAllocator(false) {}
+ : forcedBlkExprs(nullptr), Observer(nullptr),
+ PruneTriviallyFalseEdges(true), AddEHEdges(false),
+ AddInitializers(false), AddImplicitDtors(false),
+ AddTemporaryDtors(false), AddStaticInitBranches(false),
+ AddCXXNewAllocator(false) {}
};
/// \brief Provides a custom implementation of the iterator class to have the
@@ -936,8 +947,9 @@
// Internal: constructors and data.
//===--------------------------------------------------------------------===//
- CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
- Blocks(BlkBVC, 10) {}
+ CFG()
+ : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
+ Blocks(BlkBVC, 10) {}
llvm::BumpPtrAllocator& getAllocator() {
return BlkBVC.getAllocator();
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
deleted file mode 100644
index 5b99f1d..0000000
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ /dev/null
@@ -1,342 +0,0 @@
-//===--- DataflowSolver.h - Skeleton Dataflow Analysis Code -----*- 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 skeleton code for implementing dataflow analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
-#define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
-
-#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/FlowSensitive/DataflowValues.h"
-#include "clang/Analysis/ProgramPoint.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include <functional>
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-/// DataflowWorkListTy - Data structure representing the worklist used for
-/// dataflow algorithms.
-//===----------------------------------------------------------------------===//
-
-class DataflowWorkListTy {
- llvm::DenseMap<const CFGBlock*, unsigned char> BlockSet;
- SmallVector<const CFGBlock *, 10> BlockQueue;
-public:
- /// enqueue - Add a block to the worklist. Blocks already on the
- /// worklist are not added a second time.
- void enqueue(const CFGBlock *B) {
- unsigned char &x = BlockSet[B];
- if (x == 1)
- return;
- x = 1;
- BlockQueue.push_back(B);
- }
-
- /// dequeue - Remove a block from the worklist.
- const CFGBlock *dequeue() {
- assert(!BlockQueue.empty());
- const CFGBlock *B = BlockQueue.pop_back_val();
- BlockSet[B] = 0;
- return B;
- }
-
- /// isEmpty - Return true if the worklist is empty.
- bool isEmpty() const { return BlockQueue.empty(); }
-};
-
-//===----------------------------------------------------------------------===//
-// BlockItrTraits - Traits classes that allow transparent iteration
-// over successors/predecessors of a block depending on the direction
-// of our dataflow analysis.
-//===----------------------------------------------------------------------===//
-
-namespace dataflow {
-template<typename Tag> struct ItrTraits {};
-
-template <> struct ItrTraits<forward_analysis_tag> {
- typedef CFGBlock::const_pred_iterator PrevBItr;
- typedef CFGBlock::const_succ_iterator NextBItr;
- typedef CFGBlock::const_iterator StmtItr;
-
- static PrevBItr PrevBegin(const CFGBlock *B) { return B->pred_begin(); }
- static PrevBItr PrevEnd(const CFGBlock *B) { return B->pred_end(); }
-
- static NextBItr NextBegin(const CFGBlock *B) { return B->succ_begin(); }
- static NextBItr NextEnd(const CFGBlock *B) { return B->succ_end(); }
-
- static StmtItr StmtBegin(const CFGBlock *B) { return B->begin(); }
- static StmtItr StmtEnd(const CFGBlock *B) { return B->end(); }
-
- static BlockEdge PrevEdge(const CFGBlock *B, const CFGBlock *Prev) {
- return BlockEdge(Prev, B, 0);
- }
-
- static BlockEdge NextEdge(const CFGBlock *B, const CFGBlock *Next) {
- return BlockEdge(B, Next, 0);
- }
-};
-
-template <> struct ItrTraits<backward_analysis_tag> {
- typedef CFGBlock::const_succ_iterator PrevBItr;
- typedef CFGBlock::const_pred_iterator NextBItr;
- typedef CFGBlock::const_reverse_iterator StmtItr;
-
- static PrevBItr PrevBegin(const CFGBlock *B) { return B->succ_begin(); }
- static PrevBItr PrevEnd(const CFGBlock *B) { return B->succ_end(); }
-
- static NextBItr NextBegin(const CFGBlock *B) { return B->pred_begin(); }
- static NextBItr NextEnd(const CFGBlock *B) { return B->pred_end(); }
-
- static StmtItr StmtBegin(const CFGBlock *B) { return B->rbegin(); }
- static StmtItr StmtEnd(const CFGBlock *B) { return B->rend(); }
-
- static BlockEdge PrevEdge(const CFGBlock *B, const CFGBlock *Prev) {
- return BlockEdge(B, Prev, 0);
- }
-
- static BlockEdge NextEdge(const CFGBlock *B, const CFGBlock *Next) {
- return BlockEdge(Next, B, 0);
- }
-};
-} // end namespace dataflow
-
-//===----------------------------------------------------------------------===//
-/// DataflowSolverTy - Generic dataflow solver.
-//===----------------------------------------------------------------------===//
-
-template <typename _DFValuesTy, // Usually a subclass of DataflowValues
- typename _TransferFuncsTy,
- typename _MergeOperatorTy,
- typename _Equal = std::equal_to<typename _DFValuesTy::ValTy> >
-class DataflowSolver {
-
- //===----------------------------------------------------===//
- // Type declarations.
- //===----------------------------------------------------===//
-
-public:
- typedef _DFValuesTy DFValuesTy;
- typedef _TransferFuncsTy TransferFuncsTy;
- typedef _MergeOperatorTy MergeOperatorTy;
-
- typedef typename _DFValuesTy::AnalysisDirTag AnalysisDirTag;
- typedef typename _DFValuesTy::ValTy ValTy;
- typedef typename _DFValuesTy::EdgeDataMapTy EdgeDataMapTy;
- typedef typename _DFValuesTy::BlockDataMapTy BlockDataMapTy;
-
- typedef dataflow::ItrTraits<AnalysisDirTag> ItrTraits;
- typedef typename ItrTraits::NextBItr NextBItr;
- typedef typename ItrTraits::PrevBItr PrevBItr;
- typedef typename ItrTraits::StmtItr StmtItr;
-
- //===----------------------------------------------------===//
- // External interface: constructing and running the solver.
- //===----------------------------------------------------===//
-
-public:
- DataflowSolver(DFValuesTy& d) : D(d), TF(d.getAnalysisData()) {}
- ~DataflowSolver() {}
-
- /// runOnCFG - Computes dataflow values for all blocks in a CFG.
- void runOnCFG(CFG& cfg, bool recordStmtValues = false) {
- // Set initial dataflow values and boundary conditions.
- D.InitializeValues(cfg);
- // Solve the dataflow equations. This will populate D.EdgeDataMap
- // with dataflow values.
- SolveDataflowEquations(cfg, recordStmtValues);
- }
-
- /// runOnBlock - Computes dataflow values for a given block. This
- /// should usually be invoked only after previously computing
- /// dataflow values using runOnCFG, as runOnBlock is intended to
- /// only be used for querying the dataflow values within a block
- /// with and Observer object.
- void runOnBlock(const CFGBlock *B, bool recordStmtValues) {
- BlockDataMapTy& M = D.getBlockDataMap();
- typename BlockDataMapTy::iterator I = M.find(B);
-
- if (I != M.end()) {
- TF.getVal().copyValues(I->second);
- ProcessBlock(B, recordStmtValues, AnalysisDirTag());
- }
- }
-
- void runOnBlock(const CFGBlock &B, bool recordStmtValues) {
- runOnBlock(&B, recordStmtValues);
- }
- void runOnBlock(CFG::iterator &I, bool recordStmtValues) {
- runOnBlock(*I, recordStmtValues);
- }
- void runOnBlock(CFG::const_iterator &I, bool recordStmtValues) {
- runOnBlock(*I, recordStmtValues);
- }
-
- void runOnAllBlocks(const CFG& cfg, bool recordStmtValues = false) {
- for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
- runOnBlock(I, recordStmtValues);
- }
-
- //===----------------------------------------------------===//
- // Internal solver logic.
- //===----------------------------------------------------===//
-
-private:
-
- /// SolveDataflowEquations - Perform the actual worklist algorithm
- /// to compute dataflow values.
- void SolveDataflowEquations(CFG& cfg, bool recordStmtValues) {
- EnqueueBlocksOnWorklist(cfg, AnalysisDirTag());
-
- while (!WorkList.isEmpty()) {
- const CFGBlock *B = WorkList.dequeue();
- ProcessMerge(cfg, B);
- ProcessBlock(B, recordStmtValues, AnalysisDirTag());
- UpdateEdges(cfg, B, TF.getVal());
- }
- }
-
- void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::forward_analysis_tag) {
- // Enqueue all blocks to ensure the dataflow values are computed
- // for every block. Not all blocks are guaranteed to reach the exit block.
- for (CFG::iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
- WorkList.enqueue(&**I);
- }
-
- void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::backward_analysis_tag) {
- // Enqueue all blocks to ensure the dataflow values are computed
- // for every block. Not all blocks are guaranteed to reach the exit block.
- // Enqueue in reverse order since that will more likely match with
- // the order they should ideally processed by the dataflow algorithm.
- for (CFG::reverse_iterator I=cfg.rbegin(), E=cfg.rend(); I!=E; ++I)
- WorkList.enqueue(&**I);
- }
-
- void ProcessMerge(CFG& cfg, const CFGBlock *B) {
- ValTy& V = TF.getVal();
- TF.SetTopValue(V);
-
- // Merge dataflow values from all predecessors of this block.
- MergeOperatorTy Merge;
-
- EdgeDataMapTy& M = D.getEdgeDataMap();
- bool firstMerge = true;
- bool noEdges = true;
- for (PrevBItr I=ItrTraits::PrevBegin(B),E=ItrTraits::PrevEnd(B); I!=E; ++I){
-
- CFGBlock *PrevBlk = *I;
-
- if (!PrevBlk)
- continue;
-
- typename EdgeDataMapTy::iterator EI =
- M.find(ItrTraits::PrevEdge(B, PrevBlk));
-
- if (EI != M.end()) {
- noEdges = false;
- if (firstMerge) {
- firstMerge = false;
- V.copyValues(EI->second);
- }
- else
- Merge(V, EI->second);
- }
- }
-
- bool isInitialized = true;
- typename BlockDataMapTy::iterator BI = D.getBlockDataMap().find(B);
- if(BI == D.getBlockDataMap().end()) {
- isInitialized = false;
- BI = D.getBlockDataMap().insert( std::make_pair(B,ValTy()) ).first;
- }
- // If no edges have been found, it means this is the first time the solver
- // has been called on block B, we copy the initialization values (if any)
- // as current value for V (which will be used as edge data)
- if(noEdges && isInitialized)
- Merge(V, BI->second);
-
- // Set the data for the block.
- BI->second.copyValues(V);
- }
-
- /// ProcessBlock - Process the transfer functions for a given block.
- void ProcessBlock(const CFGBlock *B, bool recordStmtValues,
- dataflow::forward_analysis_tag) {
-
- TF.setCurrentBlock(B);
-
- for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
- CFGElement El = *I;
- if (const CFGStmt *S = El.getAs<CFGStmt>())
- ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag());
- }
-
- TF.VisitTerminator(const_cast<CFGBlock*>(B));
- }
-
- void ProcessBlock(const CFGBlock *B, bool recordStmtValues,
- dataflow::backward_analysis_tag) {
-
- TF.setCurrentBlock(B);
-
- TF.VisitTerminator(const_cast<CFGBlock*>(B));
-
- for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
- CFGElement El = *I;
- if (const CFGStmt *S = El.getAs<CFGStmt>())
- ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag());
- }
- }
-
- void ProcessStmt(const Stmt *S, bool record, dataflow::forward_analysis_tag) {
- if (record) D.getStmtDataMap()[S] = TF.getVal();
- TF.BlockStmt_Visit(const_cast<Stmt*>(S));
- }
-
- void ProcessStmt(const Stmt *S, bool record, dataflow::backward_analysis_tag){
- TF.BlockStmt_Visit(const_cast<Stmt*>(S));
- if (record) D.getStmtDataMap()[S] = TF.getVal();
- }
-
- /// UpdateEdges - After processing the transfer functions for a
- /// block, update the dataflow value associated with the block's
- /// outgoing/incoming edges (depending on whether we do a
- // forward/backward analysis respectively)
- void UpdateEdges(CFG& cfg, const CFGBlock *B, ValTy& V) {
- for (NextBItr I=ItrTraits::NextBegin(B), E=ItrTraits::NextEnd(B); I!=E; ++I)
- if (CFGBlock *NextBlk = *I)
- UpdateEdgeValue(ItrTraits::NextEdge(B, NextBlk),V, NextBlk);
- }
-
- /// UpdateEdgeValue - Update the value associated with a given edge.
- void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock *TargetBlock) {
- EdgeDataMapTy& M = D.getEdgeDataMap();
- typename EdgeDataMapTy::iterator I = M.find(E);
-
- if (I == M.end()) { // First computed value for this edge?
- M[E].copyValues(V);
- WorkList.enqueue(TargetBlock);
- }
- else if (!_Equal()(V,I->second)) {
- I->second.copyValues(V);
- WorkList.enqueue(TargetBlock);
- }
- }
-
-private:
- DFValuesTy& D;
- DataflowWorkListTy WorkList;
- TransferFuncsTy TF;
-};
-
-} // end namespace clang
-#endif
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 1423e01..57324d0 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -77,9 +77,9 @@
ProgramPoint(const void *P,
Kind k,
const LocationContext *l,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: Data1(P),
- Data2(0, (((unsigned) k) >> 0) & 0x3),
+ Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
L(l, (((unsigned) k) >> 2) & 0x3),
Tag(tag, (((unsigned) k) >> 4) & 0x3) {
assert(getKind() == k);
@@ -91,7 +91,7 @@
const void *P2,
Kind k,
const LocationContext *l,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: Data1(P1),
Data2(P2, (((unsigned) k) >> 0) & 0x3),
L(l, (((unsigned) k) >> 2) & 0x3),
@@ -193,7 +193,7 @@
class BlockEntrance : public ProgramPoint {
public:
BlockEntrance(const CFGBlock *B, const LocationContext *L,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: ProgramPoint(B, BlockEntranceKind, L, tag) {
assert(B && "BlockEntrance requires non-null block");
}
@@ -263,7 +263,7 @@
class PreStmt : public StmtPoint {
public:
PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag,
- const Stmt *SubStmt = 0)
+ const Stmt *SubStmt = nullptr)
: StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
@@ -280,17 +280,17 @@
protected:
PostStmt() {}
PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: StmtPoint(S, data, k, L, tag) {}
public:
- explicit PostStmt(const Stmt *S, Kind k,
- const LocationContext *L, const ProgramPointTag *tag = 0)
- : StmtPoint(S, NULL, k, L, tag) {}
+ explicit PostStmt(const Stmt *S, Kind k, const LocationContext *L,
+ const ProgramPointTag *tag = nullptr)
+ : StmtPoint(S, nullptr, k, L, tag) {}
explicit PostStmt(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = 0)
- : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
+ const ProgramPointTag *tag = nullptr)
+ : StmtPoint(S, nullptr, PostStmtKind, L, tag) {}
private:
friend class ProgramPoint;
@@ -304,7 +304,7 @@
class PostCondition : public PostStmt {
public:
PostCondition(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: PostStmt(S, PostConditionKind, L, tag) {}
private:
@@ -320,7 +320,7 @@
LocationCheck() {}
LocationCheck(const Stmt *S, const LocationContext *L,
ProgramPoint::Kind K, const ProgramPointTag *tag)
- : StmtPoint(S, NULL, K, L, tag) {}
+ : StmtPoint(S, nullptr, K, L, tag) {}
private:
friend class ProgramPoint;
@@ -333,7 +333,7 @@
class PreLoad : public LocationCheck {
public:
PreLoad(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: LocationCheck(S, L, PreLoadKind, tag) {}
private:
@@ -347,7 +347,7 @@
class PreStore : public LocationCheck {
public:
PreStore(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: LocationCheck(S, L, PreStoreKind, tag) {}
private:
@@ -361,7 +361,7 @@
class PostLoad : public PostStmt {
public:
PostLoad(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: PostStmt(S, PostLoadKind, L, tag) {}
private:
@@ -379,9 +379,9 @@
/// \param Loc can be used to store the information about the location
/// used in the form it was uttered in the code.
PostStore(const Stmt *S, const LocationContext *L, const void *Loc,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: PostStmt(S, PostStoreKind, L, tag) {
- assert(getData2() == 0);
+ assert(getData2() == nullptr);
setData2(Loc);
}
@@ -402,7 +402,7 @@
class PostLValue : public PostStmt {
public:
PostLValue(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = 0)
+ const ProgramPointTag *tag = nullptr)
: PostStmt(S, PostLValueKind, L, tag) {}
private:
@@ -418,8 +418,8 @@
class PreStmtPurgeDeadSymbols : public StmtPoint {
public:
PreStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = 0)
- : StmtPoint(S, 0, PreStmtPurgeDeadSymbolsKind, L, tag) { }
+ const ProgramPointTag *tag = nullptr)
+ : StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { }
private:
friend class ProgramPoint;
@@ -434,8 +434,8 @@
class PostStmtPurgeDeadSymbols : public StmtPoint {
public:
PostStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
- const ProgramPointTag *tag = 0)
- : StmtPoint(S, 0, PostStmtPurgeDeadSymbolsKind, L, tag) { }
+ const ProgramPointTag *tag = nullptr)
+ : StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { }
private:
friend class ProgramPoint;
@@ -527,8 +527,8 @@
/// Explicit calls will appear as PreStmt program points.
class PreImplicitCall : public ImplicitCallPoint {
public:
- PreImplicitCall(const Decl *D, SourceLocation Loc,
- const LocationContext *L, const ProgramPointTag *Tag = 0)
+ PreImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
+ const ProgramPointTag *Tag = nullptr)
: ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
private:
@@ -544,8 +544,8 @@
/// Explicit calls will appear as PostStmt program points.
class PostImplicitCall : public ImplicitCallPoint {
public:
- PostImplicitCall(const Decl *D, SourceLocation Loc,
- const LocationContext *L, const ProgramPointTag *Tag = 0)
+ PostImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
+ const ProgramPointTag *Tag = nullptr)
: ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
private:
@@ -562,7 +562,7 @@
public:
CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx,
const LocationContext *callerCtx)
- : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {}
+ : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {}
const Stmt *getCallExpr() const {
return static_cast<const Stmt *>(getData1());
@@ -593,7 +593,7 @@
public:
// CallExitBegin uses the callee's location context.
CallExitBegin(const StackFrameContext *L)
- : ProgramPoint(0, CallExitBeginKind, L, 0) {}
+ : ProgramPoint(nullptr, CallExitBeginKind, L, nullptr) {}
private:
friend class ProgramPoint;
@@ -610,7 +610,7 @@
// CallExitEnd uses the caller's location context.
CallExitEnd(const StackFrameContext *CalleeCtx,
const LocationContext *CallerCtx)
- : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, 0) {}
+ : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
const StackFrameContext *getCalleeContext() const {
return static_cast<const StackFrameContext *>(getData1());
@@ -629,7 +629,8 @@
class EpsilonPoint : public ProgramPoint {
public:
EpsilonPoint(const LocationContext *L, const void *Data1,
- const void *Data2 = 0, const ProgramPointTag *tag = 0)
+ const void *Data2 = nullptr,
+ const ProgramPointTag *tag = nullptr)
: ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {}
const void *getData() const { return getData1(); }
@@ -647,7 +648,7 @@
/// description and potentially other information.
class ProgramPointTag {
public:
- ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {}
+ ProgramPointTag(void *tagKind = nullptr) : TagKind(tagKind) {}
virtual ~ProgramPointTag();
virtual StringRef getTagDescription() const = 0;
@@ -676,13 +677,13 @@
static inline clang::ProgramPoint getEmptyKey() {
uintptr_t x =
reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
- return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
+ return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
}
static inline clang::ProgramPoint getTombstoneKey() {
uintptr_t x =
reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
- return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
+ return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
}
static unsigned getHashValue(const clang::ProgramPoint &Loc) {
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index e246712..6d0427b 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -55,7 +55,7 @@
public:
// Default ctor - Initialize to empty.
explicit BumpVector(BumpVectorContext &C, unsigned N)
- : Begin(NULL), End(NULL), Capacity(NULL) {
+ : Begin(nullptr), End(nullptr), Capacity(nullptr) {
reserve(C, N);
}
diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h
index 3b3d59e..9e8ef2e 100644
--- a/include/clang/Basic/ABI.h
+++ b/include/clang/Basic/ABI.h
@@ -186,10 +186,10 @@
/// an ABI-specific comparator.
const CXXMethodDecl *Method;
- ThunkInfo() : Method(0) { }
+ ThunkInfo() : Method(nullptr) { }
ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
- const CXXMethodDecl *Method = 0)
+ const CXXMethodDecl *Method = nullptr)
: This(This), Return(Return), Method(Method) {}
friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
@@ -197,7 +197,9 @@
LHS.Method == RHS.Method;
}
- bool isEmpty() const { return This.isEmpty() && Return.isEmpty() && Method == 0; }
+ bool isEmpty() const {
+ return This.isEmpty() && Return.isEmpty() && Method == nullptr;
+ }
};
} // end namespace clang
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 7360683..047c307 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -233,7 +233,7 @@
def TargetARM : TargetArch<["arm", "thumb"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
def TargetX86 : TargetArch<["x86"]>;
-def TargetX86Win : TargetArch<["x86", "x86_64"]> {
+def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
let OSes = ["Win32"];
}
def TargetMips : TargetArch<["mips", "mipsel"]>;
@@ -673,6 +673,12 @@
let Documentation = [Undocumented];
}
+def Flatten : InheritableAttr {
+ let Spellings = [GCC<"flatten">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [FlattenDocs];
+}
+
def Format : InheritableAttr {
let Spellings = [GCC<"format">];
let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
@@ -828,6 +834,12 @@
let Documentation = [Undocumented];
}
+def NoSplitStack : InheritableAttr {
+ let Spellings = [GCC<"no_split_stack">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [NoSplitStackDocs];
+}
+
def NonNull : InheritableAttr {
let Spellings = [GCC<"nonnull">];
let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
@@ -835,9 +847,8 @@
let Args = [VariadicUnsignedArgument<"Args">];
let AdditionalMembers =
[{bool isNonNull(unsigned idx) const {
- for (args_iterator i = args_begin(), e = args_end();
- i != e; ++i)
- if (*i == idx)
+ for (const auto &V : args())
+ if (V == idx)
return true;
return false;
} }];
@@ -1080,7 +1091,7 @@
}
def Section : InheritableAttr {
- let Spellings = [GCC<"section">];
+ let Spellings = [GCC<"section">, Declspec<"allocate">];
let Args = [StringArgument<"Name">];
let Subjects = SubjectList<[Function, GlobalVar,
ObjCMethod, ObjCProperty], ErrorDiag,
@@ -1262,21 +1273,21 @@
def NoSanitizeAddress : InheritableAttr {
let Spellings = [GCC<"no_address_safety_analysis">,
GCC<"no_sanitize_address">];
- let Subjects = SubjectList<[Function, FunctionTemplate], ErrorDiag>;
+ let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSanitizeAddressDocs];
}
// Attribute to disable ThreadSanitizer checks.
def NoSanitizeThread : InheritableAttr {
let Spellings = [GNU<"no_sanitize_thread">];
- let Subjects = SubjectList<[Function, FunctionTemplate], ErrorDiag>;
+ let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSanitizeThreadDocs];
}
// Attribute to disable MemorySanitizer checks.
def NoSanitizeMemory : InheritableAttr {
let Spellings = [GNU<"no_sanitize_memory">];
- let Subjects = SubjectList<[Function, FunctionTemplate], ErrorDiag>;
+ let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSanitizeMemoryDocs];
}
@@ -1331,7 +1342,7 @@
CXX11<"clang", "assert_capability">,
GNU<"assert_shared_capability">,
CXX11<"clang", "assert_shared_capability">];
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
@@ -1350,7 +1361,7 @@
CXX11<"clang", "acquire_shared_capability">,
GNU<"exclusive_lock_function">,
GNU<"shared_lock_function">];
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
@@ -1368,7 +1379,7 @@
CXX11<"clang", "try_acquire_capability">,
GNU<"try_acquire_shared_capability">,
CXX11<"clang", "try_acquire_shared_capability">];
- let Subjects = SubjectList<[Function, FunctionTemplate],
+ let Subjects = SubjectList<[Function],
ErrorDiag>;
let LateParsed = 1;
let TemplateDependent = 1;
@@ -1389,7 +1400,7 @@
GNU<"release_generic_capability">,
CXX11<"clang", "release_generic_capability">,
GNU<"unlock_function">];
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
@@ -1417,7 +1428,7 @@
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let Accessors = [Accessor<"isShared", [GNU<"requires_shared_capability">,
GNU<"shared_locks_required">,
CXX11<"clang","requires_shared_capability">]>];
@@ -1426,7 +1437,7 @@
def NoThreadSafetyAnalysis : InheritableAttr {
let Spellings = [GNU<"no_thread_safety_analysis">];
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -1485,7 +1496,7 @@
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -1496,7 +1507,7 @@
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -1509,7 +1520,7 @@
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -1522,7 +1533,7 @@
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -1532,7 +1543,7 @@
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -1543,7 +1554,7 @@
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -1573,7 +1584,7 @@
def CallableWhen : InheritableAttr {
let Spellings = [GNU<"callable_when">];
let Subjects = SubjectList<[CXXMethod]>;
- let Args = [VariadicEnumArgument<"CallableState", "ConsumedState",
+ let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
let Documentation = [CallableWhenDocs];
@@ -1651,16 +1662,15 @@
let Documentation = [Undocumented];
}
-def DLLExport : InheritableAttr, TargetSpecificAttr<TargetX86Win> {
+def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
let Subjects = SubjectList<[Function, Var]>;
let Documentation = [Undocumented];
}
-def DLLImport : InheritableAttr, TargetSpecificAttr<TargetX86Win> {
+def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
- // Technically, the subjects for DllImport are Function and Var, but there is
- // custom semantic handling required when MicrosoftExt is true.
+ let Subjects = SubjectList<[Function, Var]>;
let Documentation = [Undocumented];
}
@@ -1670,6 +1680,13 @@
let Documentation = [Undocumented];
}
+def Thread : Attr {
+ let Spellings = [Declspec<"thread">];
+ let LangOpts = [MicrosoftExt];
+ let Documentation = [ThreadDocs];
+ let Subjects = SubjectList<[Var]>;
+}
+
def Win64 : IgnoredAttr {
let Spellings = [Keyword<"__w64">];
let LangOpts = [MicrosoftExt];
@@ -1702,6 +1719,7 @@
Keyword<"__multiple_inheritance">,
Keyword<"__virtual_inheritance">,
Keyword<"__unspecified_inheritance">];
+ let Documentation = [SectionDocs];
let AdditionalMembers = [{
static bool hasVBPtrOffsetField(Spelling Inheritance) {
return Inheritance == Keyword_unspecified_inheritance;
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 2f62175..6195960 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -27,6 +27,14 @@
}];
}
+def SectionDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``section`` attribute allows you to specify a specific section a
+global variable or function should be in after translation.
+ }];
+}
+
def TLSModelDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
@@ -42,20 +50,37 @@
}];
}
+def ThreadDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``__declspec(thread)`` attribute declares a variable with thread local
+storage. It is available under the ``-fms-extensions`` flag for MSVC
+compatibility. Documentation for the Visual C++ attribute is available on MSDN_.
+
+.. _MSDN: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
+
+In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the
+GNU ``__thread`` keyword. The variable must not have a destructor and must have
+a constant initializer, if any. The attribute only applies to variables
+declared with static storage duration, such as globals, class static data
+members, and static locals.
+ }];
+}
+
def CarriesDependencyDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``carries_dependency`` attribute specifies dependency propagation into and
out of functions.
-When specified on a function or Objective-C method, the ``carries_depedency``
+When specified on a function or Objective-C method, the ``carries_dependency``
attribute means that the return value carries a dependency out of the function,
so that the implementation need not constrain ordering upon return from that
function. Implementations of the function and its caller may choose to preserve
dependencies instead of emitting memory ordering instructions such as fences.
Note, this attribute does not change the meaning of the program, but may result
-in generatation of more efficient code.
+in generation of more efficient code.
}];
}
@@ -346,6 +371,15 @@
}];
}
+def NoSplitStackDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``no_split_stack`` attribute disables the emission of the split stack
+preamble for a particular function. It has no effect if ``-fsplit-stack``
+is not specified.
+ }];
+}
+
def ObjCRequiresSuperDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -843,6 +877,15 @@
}];
}
+def FlattenDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``flatten`` attribute causes calls within the attributed function to
+be inlined unless it is impossible to do so, for example if the body of the
+callee is unavailable or if the callee has the ``noinline`` attribute.
+ }];
+}
+
def FormatDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 540ec25..3a1c58f 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -733,11 +733,16 @@
LIBBUILTIN(vfscanf, "iP*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES)
// C99
+// In some systems setjmp is a macro that expands to _setjmp. We undefine
+// it here to avoid having two identical LIBBUILTIN entries.
#undef setjmp
LIBBUILTIN(setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(longjmp, "vJi", "fr", "setjmp.h", ALL_LANGUAGES)
// Non-C library functions, active in GNU mode only.
+// Functions with (returns_twice) attribute (marked as "j") are still active in
+// all languages, because losing this attribute would result in miscompilation
+// when these functions are used in non-GNU mode. PR16138.
LIBBUILTIN(alloca, "v*z", "f", "stdlib.h", ALL_GNU_LANGUAGES)
// POSIX string.h
LIBBUILTIN(stpcpy, "c*c*cC*", "f", "string.h", ALL_GNU_LANGUAGES)
@@ -756,18 +761,16 @@
LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_GNU_LANGUAGES)
// POSIX unistd.h
LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_LANGUAGES)
// POSIX setjmp.h
-// In some systems setjmp is a macro that expands to _setjmp. We undefine
-// it here to avoid having two identical LIBBUILTIN entries.
-LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(__sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(setjmp_syscall, "iJ", "fj", "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(savectx, "iJ", "fj", "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(qsetjmp, "iJ", "fj", "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(getcontext, "iK*", "fj", "setjmp.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(__sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(setjmp_syscall, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(savectx, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(qsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(getcontext, "iK*", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(_longjmp, "vJi", "fr", "setjmp.h", ALL_GNU_LANGUAGES)
LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h", ALL_GNU_LANGUAGES)
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index fd8fd42..f9d30e4 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -94,53 +94,53 @@
/// \brief Return true if this function has no side effects and doesn't
/// read memory.
bool isConst(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'c') != 0;
+ return strchr(GetRecord(ID).Attributes, 'c') != nullptr;
}
/// \brief Return true if we know this builtin never throws an exception.
bool isNoThrow(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'n') != 0;
+ return strchr(GetRecord(ID).Attributes, 'n') != nullptr;
}
/// \brief Return true if we know this builtin never returns.
bool isNoReturn(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'r') != 0;
+ return strchr(GetRecord(ID).Attributes, 'r') != nullptr;
}
/// \brief Return true if we know this builtin can return twice.
bool isReturnsTwice(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'j') != 0;
+ return strchr(GetRecord(ID).Attributes, 'j') != nullptr;
}
/// \brief Returns true if this builtin does not perform the side-effects
/// of its arguments.
bool isUnevaluated(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'u') != 0;
+ return strchr(GetRecord(ID).Attributes, 'u') != nullptr;
}
/// \brief Return true if this is a builtin for a libc/libm function,
/// with a "__builtin_" prefix (e.g. __builtin_abs).
bool isLibFunction(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'F') != 0;
+ return strchr(GetRecord(ID).Attributes, 'F') != nullptr;
}
/// \brief Determines whether this builtin is a predefined libc/libm
/// function, such as "malloc", where we know the signature a
/// priori.
bool isPredefinedLibFunction(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'f') != 0;
+ return strchr(GetRecord(ID).Attributes, 'f') != nullptr;
}
/// \brief Determines whether this builtin is a predefined compiler-rt/libgcc
/// function, such as "__clear_cache", where we know the signature a
/// priori.
bool isPredefinedRuntimeFunction(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'i') != 0;
+ return strchr(GetRecord(ID).Attributes, 'i') != nullptr;
}
/// \brief Determines whether this builtin has custom typechecking.
bool hasCustomTypechecking(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 't') != 0;
+ return strchr(GetRecord(ID).Attributes, 't') != nullptr;
}
/// \brief Completely forget that the given ID was ever considered a builtin,
@@ -168,7 +168,7 @@
///
/// Such functions can be const when the MathErrno lang option is disabled.
bool isConstWithoutErrno(unsigned ID) const {
- return strchr(GetRecord(ID).Attributes, 'e') != 0;
+ return strchr(GetRecord(ID).Attributes, 'e') != nullptr;
}
private:
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index a0a0a5d..36dcb9f 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -1,4 +1,4 @@
-//===-- BuiltinsAArch64.def - AArch64 Builtin function database -*- C++ -*-===//
+//==- BuiltinsAArch64.def - AArch64 Builtin function database ----*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -17,4 +17,18 @@
// In libgcc
BUILTIN(__clear_cache, "vv*v*", "i")
+BUILTIN(__builtin_arm_ldrex, "v.", "t")
+BUILTIN(__builtin_arm_strex, "i.", "t")
+BUILTIN(__builtin_arm_clrex, "v", "")
+
+// CRC32
+BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
+BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
+BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
+BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
+BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
+BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
+BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc")
+BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc")
+
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index aab9255..9f650cc 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -59,7 +59,11 @@
BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
// HINT
-BUILTIN(__builtin_arm_sevl, "v", "")
+BUILTIN(__yield, "v", "")
+BUILTIN(__wfe, "v", "")
+BUILTIN(__wfi, "v", "")
+BUILTIN(__sev, "v", "")
+BUILTIN(__sevl, "v", "")
// Data barrier
BUILTIN(__builtin_arm_dmb, "vUi", "nc")
diff --git a/include/clang/Basic/BuiltinsARM64.def b/include/clang/Basic/BuiltinsARM64.def
deleted file mode 100644
index dcc1b51..0000000
--- a/include/clang/Basic/BuiltinsARM64.def
+++ /dev/null
@@ -1,34 +0,0 @@
-//===--- BuiltinsARM64.def - ARM64 Builtin function database ----*- 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 ARM64-specific builtin function database. Users of
-// this file must define the BUILTIN macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-// The format of this database matches clang/Basic/Builtins.def.
-
-// In libgcc
-BUILTIN(__clear_cache, "vv*v*", "")
-
-BUILTIN(__builtin_arm_ldrex, "v.", "t")
-BUILTIN(__builtin_arm_strex, "i.", "t")
-BUILTIN(__builtin_arm_clrex, "v", "")
-
-// CRC32
-BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc")
-BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc")
-
-#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 4a67fc1..8faaea3 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -760,5 +760,7 @@
BUILTIN(__builtin_ia32_xend, "v", "")
BUILTIN(__builtin_ia32_xabort, "vIc", "")
BUILTIN(__builtin_ia32_xtest, "i", "")
+BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
+BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
#undef BUILTIN
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 6082ec8..4926cec 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -21,18 +21,19 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/iterator_range.h"
#include <list>
#include <vector>
namespace clang {
- class DiagnosticConsumer;
+ class DeclContext;
class DiagnosticBuilder;
+ class DiagnosticConsumer;
+ class DiagnosticErrorTrap;
class DiagnosticOptions;
class IdentifierInfo;
- class DeclContext;
class LangOptions;
class Preprocessor;
- class DiagnosticErrorTrap;
class StoredDiagnostic;
namespace tok {
enum TokenKind : unsigned short;
@@ -131,6 +132,9 @@
/// the user. DiagnosticsEngine is tied to one translation unit and one
/// SourceManager.
class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
+ DiagnosticsEngine(const DiagnosticsEngine &) LLVM_DELETED_FUNCTION;
+ void operator=(const DiagnosticsEngine &) LLVM_DELETED_FUNCTION;
+
public:
/// \brief The level of the diagnostic, after it has been through mapping.
enum Level {
@@ -341,11 +345,19 @@
/// \brief Second string argument for the delayed diagnostic.
std::string DelayedDiagArg2;
+ /// \brief Flag name value.
+ ///
+ /// Some flags accept values. For instance, -Wframe-larger-than or -Rpass.
+ /// When reporting a diagnostic with those flags, it is useful to also
+ /// report the value that actually triggered the flag. The content of this
+ /// string is a value to be emitted after the flag name.
+ std::string FlagNameValue;
+
public:
explicit DiagnosticsEngine(
const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
DiagnosticOptions *DiagOpts,
- DiagnosticConsumer *client = 0,
+ DiagnosticConsumer *client = nullptr,
bool ShouldOwnClient = true);
~DiagnosticsEngine();
@@ -356,6 +368,14 @@
/// \brief Retrieve the diagnostic options.
DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
+ typedef llvm::iterator_range<DiagState::const_iterator> diag_mapping_range;
+
+ /// \brief Get the current set of diagnostic mappings.
+ diag_mapping_range getDiagnosticMappings() const {
+ const DiagState &DS = *GetCurDiagState();
+ return diag_mapping_range(DS.begin(), DS.end());
+ }
+
DiagnosticConsumer *getClient() { return Client; }
const DiagnosticConsumer *getClient() const { return Client; }
@@ -369,7 +389,7 @@
return Client;
}
- bool hasSourceManager() const { return SourceMgr != 0; }
+ bool hasSourceManager() const { return SourceMgr != nullptr; }
SourceManager &getSourceManager() const {
assert(SourceMgr && "SourceManager not set!");
return *SourceMgr;
@@ -681,6 +701,12 @@
/// \brief Clear out the current diagnostic.
void Clear() { CurDiagID = ~0U; }
+ /// \brief Return the value associated to this diagnostic flag.
+ StringRef getFlagNameValue() const { return StringRef(FlagNameValue); }
+
+ /// \brief Set the value associated to this diagnostic flag.
+ void setFlagNameValue(StringRef V) { FlagNameValue = V; }
+
private:
/// \brief Report the delayed diagnostic.
void ReportDelayed();
@@ -712,20 +738,10 @@
/// diagnostic with more than that almost certainly has to be simplified
/// anyway.
MaxArguments = 10,
-
- /// \brief The maximum number of ranges we can hold.
- MaxRanges = 10,
-
- /// \brief The maximum number of ranges we can hold.
- MaxFixItHints = 10
};
/// \brief The number of entries in Arguments.
signed char NumDiagArgs;
- /// \brief The number of ranges in the DiagRanges array.
- unsigned char NumDiagRanges;
- /// \brief The number of hints in the DiagFixItHints array.
- unsigned char NumDiagFixItHints;
/// \brief Specifies whether an argument is in DiagArgumentsStr or
/// in DiagArguments.
@@ -748,11 +764,11 @@
intptr_t DiagArgumentsVal[MaxArguments];
/// \brief The list of ranges added to this diagnostic.
- CharSourceRange DiagRanges[MaxRanges];
+ SmallVector<CharSourceRange, 8> DiagRanges;
/// \brief If valid, provides a hint with some code to insert, remove,
/// or modify at a particular position.
- FixItHint DiagFixItHints[MaxFixItHints];
+ SmallVector<FixItHint, 8> DiagFixItHints;
DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) {
bool isPragma = L.isValid();
@@ -849,7 +865,7 @@
/// for example.
class DiagnosticBuilder {
mutable DiagnosticsEngine *DiagObj;
- mutable unsigned NumArgs, NumRanges, NumFixits;
+ mutable unsigned NumArgs;
/// \brief Status variable indicating if this diagnostic is still active.
///
@@ -864,15 +880,15 @@
void operator=(const DiagnosticBuilder &) LLVM_DELETED_FUNCTION;
friend class DiagnosticsEngine;
-
+
DiagnosticBuilder()
- : DiagObj(0), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(false),
- IsForceEmit(false) { }
+ : DiagObj(nullptr), NumArgs(0), IsActive(false), IsForceEmit(false) {}
explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
- : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(true),
- IsForceEmit(false) {
+ : DiagObj(diagObj), NumArgs(0), IsActive(true), IsForceEmit(false) {
assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
+ diagObj->DiagRanges.clear();
+ diagObj->DiagFixItHints.clear();
}
friend class PartialDiagnostic;
@@ -880,13 +896,11 @@
protected:
void FlushCounts() {
DiagObj->NumDiagArgs = NumArgs;
- DiagObj->NumDiagRanges = NumRanges;
- DiagObj->NumDiagFixItHints = NumFixits;
}
/// \brief Clear out the current diagnostic.
void Clear() const {
- DiagObj = 0;
+ DiagObj = nullptr;
IsActive = false;
IsForceEmit = false;
}
@@ -928,8 +942,6 @@
IsForceEmit = D.IsForceEmit;
D.Clear();
NumArgs = D.NumArgs;
- NumRanges = D.NumRanges;
- NumFixits = D.NumFixits;
}
/// \brief Retrieve an empty diagnostic builder.
@@ -975,27 +987,32 @@
void AddSourceRange(const CharSourceRange &R) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
- assert(NumRanges < DiagnosticsEngine::MaxRanges &&
- "Too many arguments to diagnostic!");
- DiagObj->DiagRanges[NumRanges++] = R;
+ DiagObj->DiagRanges.push_back(R);
}
void AddFixItHint(const FixItHint &Hint) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
- assert(NumFixits < DiagnosticsEngine::MaxFixItHints &&
- "Too many arguments to diagnostic!");
- DiagObj->DiagFixItHints[NumFixits++] = Hint;
+ DiagObj->DiagFixItHints.push_back(Hint);
}
- bool hasMaxRanges() const {
- return NumRanges == DiagnosticsEngine::MaxRanges;
- }
-
- bool hasMaxFixItHints() const {
- return NumFixits == DiagnosticsEngine::MaxFixItHints;
- }
+ void addFlagValue(StringRef V) const { DiagObj->setFlagNameValue(V); }
};
+struct AddFlagValue {
+ explicit AddFlagValue(StringRef V) : Val(V) {}
+ StringRef Val;
+};
+
+/// \brief Register a value for the flag in the current diagnostic. This
+/// value will be shown as the suffix "=value" after the flag name. It is
+/// useful in cases where the diagnostic flag accepts values (e.g.,
+/// -Rpass or -Wframe-larger-than).
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const AddFlagValue V) {
+ DB.addFlagValue(V.Val);
+ return DB;
+}
+
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
StringRef S) {
DB.AddString(S);
@@ -1089,8 +1106,10 @@
assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
CurDiagLoc = Loc;
CurDiagID = DiagID;
+ FlagNameValue.clear();
return DiagnosticBuilder(this);
}
+
inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
return Report(SourceLocation(), DiagID);
}
@@ -1179,22 +1198,22 @@
/// \brief Return the number of source ranges associated with this diagnostic.
unsigned getNumRanges() const {
- return DiagObj->NumDiagRanges;
+ return DiagObj->DiagRanges.size();
}
/// \pre Idx < getNumRanges()
const CharSourceRange &getRange(unsigned Idx) const {
- assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
+ assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
return DiagObj->DiagRanges[Idx];
}
/// \brief Return an array reference for this diagnostic's ranges.
ArrayRef<CharSourceRange> getRanges() const {
- return llvm::makeArrayRef(DiagObj->DiagRanges, DiagObj->NumDiagRanges);
+ return DiagObj->DiagRanges;
}
unsigned getNumFixItHints() const {
- return DiagObj->NumDiagFixItHints;
+ return DiagObj->DiagFixItHints.size();
}
const FixItHint &getFixItHint(unsigned Idx) const {
@@ -1202,8 +1221,8 @@
return DiagObj->DiagFixItHints[Idx];
}
- const FixItHint *getFixItHints() const {
- return getNumFixItHints()? DiagObj->DiagFixItHints : 0;
+ ArrayRef<FixItHint> getFixItHints() const {
+ return DiagObj->DiagFixItHints;
}
/// \brief Format this diagnostic into a string, substituting the
@@ -1299,7 +1318,7 @@
/// \param PP The preprocessor object being used for the source; this is
/// optional, e.g., it may not be present when processing AST source files.
virtual void BeginSourceFile(const LangOptions &LangOpts,
- const Preprocessor *PP = 0) {}
+ const Preprocessor *PP = nullptr) {}
/// \brief Callback to inform the diagnostic client that processing
/// of a source file has ended.
@@ -1371,6 +1390,13 @@
/// attribute. The character itself will be not be printed.
const char ToggleHighlight = 127;
+
+/// ProcessWarningOptions - Initialize the diagnostic client and process the
+/// warning options specified on the command line.
+void ProcessWarningOptions(DiagnosticsEngine &Diags,
+ const DiagnosticOptions &Opts,
+ bool ReportDiags = true);
+
} // end namespace clang
#endif
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index 61a4508..5bcc2d5 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -102,6 +102,7 @@
class DefaultWarnShowInSystemHeader {
bit WarningShowInSystemHeader = 1;
}
+class DefaultRemark { DiagMapping DefaultMapping = MAP_REMARK; }
// Definitions for Diagnostics.
include "DiagnosticASTKinds.td"
diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td
index 49781fe..6dc8b27 100644
--- a/include/clang/Basic/DiagnosticCommentKinds.td
+++ b/include/clang/Basic/DiagnosticCommentKinds.td
@@ -11,7 +11,7 @@
let CategoryName = "Documentation Issue" in {
// HTML parsing errors. These are under -Wdocumentation to make sure the user
-// knows that we didn't parse something as he might expect.
+// knows that we didn't parse something as they might expect.
def warn_doc_html_start_tag_expected_quoted_string : Warning<
"expected quoted string after equals sign">,
@@ -41,6 +41,10 @@
def note_doc_html_end_tag : Note<
"end tag">;
+def warn_doc_html_missing_end_tag : Warning<
+ "HTML tag '%0' requires an end tag">,
+ InGroup<DocumentationHTML>, DefaultIgnore;
+
// Commands
def warn_doc_block_command_empty_paragraph : Warning<
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 0430b1d..74d628e 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -143,7 +143,7 @@
def note_mt_message : Note<"[rewriter] %0">;
// ARCMigrate
-def err_arcmt_nsalloc_realloc : Error<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
+def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
}
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 71080ba..1da7a16 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -82,6 +82,9 @@
def err_drv_malformed_sanitizer_blacklist : Error<
"malformed sanitizer blacklist: '%0'">;
+def err_target_unsupported_arch
+ : Error<"the target architecture '%0' is not supported by the target '%1'">;
+
def err_drv_I_dash_not_supported : Error<
"'%0' not supported, please use -iquote instead">;
def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
@@ -111,6 +114,8 @@
"unknown or ill-formed Objective-C runtime '%0'">;
def err_drv_emit_llvm_link : Error<
"-emit-llvm cannot be used when linking">;
+def err_drv_optimization_remark_pattern : Error<
+ "%0 in '%1'">;
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
def warn_drv_optimization_value : Warning<"optimization level '%0' is unsupported; using '%1%2' instead">,
@@ -170,5 +175,8 @@
"'-fbuild-session-timestamp=<seconds since Epoch>'">;
def warn_drv_invoking_fallback : Warning<"falling back to %0">,
- InGroup<DiagGroup<"fallback">>;
+ InGroup<Fallback>;
+def warn_drv_rtti_fallback :
+ Warning<"cannot compile RTTI yet, falling back to %0">,
+ InGroup<Fallback>;
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 32c824a..91faa0a 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -32,6 +32,14 @@
def remark_fe_backend_plugin: Remark<"%0">, CatBackend, InGroup<RemarkBackendPlugin>;
def note_fe_backend_plugin: Note<"%0">, CatBackend;
+def remark_fe_backend_optimization_remark : Remark<"%0">, CatBackend,
+ InGroup<BackendOptimizationRemark>, DefaultRemark;
+def note_fe_backend_optimization_remark_missing_loc : Note<"use "
+ "-gline-tables-only -gcolumn-info to track source location information "
+ "for this optimization remark">;
+def note_fe_backend_optimization_remark_invalid_loc : Note<"could "
+ "not determine the original source location for %0:%1:%2">;
+
def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
@@ -161,6 +169,8 @@
InGroup<ConfigMacros>;
def note_module_def_undef_here : Note<
"macro was %select{defined|#undef'd}0 here">;
+def remark_module_build : Remark<"building module '%0' as '%1'">,
+ InGroup<DiagGroup<"module-build">>, DefaultIgnore;
def err_missing_vfs_overlay_file : Error<
"virtual filesystem overlay file '%0' not found">, DefaultFatal;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 5df740f..485b48d 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -41,6 +41,7 @@
def BoolConversion : DiagGroup<"bool-conversion", [ PointerBoolConversion ] >;
def IntConversion : DiagGroup<"int-conversion">;
def EnumConversion : DiagGroup<"enum-conversion">;
+def FloatConversion : DiagGroup<"float-conversion">;
def EnumTooLarge : DiagGroup<"enum-too-large">;
def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">;
def NullConversion : DiagGroup<"null-conversion">;
@@ -48,6 +49,7 @@
DiagGroup<"implicit-conversion-floating-point-to-bool">;
def ObjCLiteralConversion : DiagGroup<"objc-literal-conversion">;
def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
+def MacroRedefined : DiagGroup<"macro-redefined">;
def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
def C99Compat : DiagGroup<"c99-compat">;
@@ -80,11 +82,11 @@
def DeprecatedRegister : DiagGroup<"deprecated-register">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
[CXX11CompatDeprecatedWritableStr]>;
-// FIXME: Why are DeprecatedImplementations and DeprecatedWritableStr
-// not in this group?
+// FIXME: Why is DeprecatedImplementations not in this group?
def Deprecated : DiagGroup<"deprecated", [DeprecatedDeclarations,
DeprecatedIncrementBool,
- DeprecatedRegister]>,
+ DeprecatedRegister,
+ DeprecatedWritableStr]>,
DiagCategory<"Deprecations">;
def : DiagGroup<"disabled-optimization">;
@@ -184,6 +186,10 @@
[IncompatiblePointerTypesDiscardsQualifiers]>;
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
def IncompleteModule : DiagGroup<"incomplete-module", [IncompleteUmbrella]>;
+def NonModularIncludeInFrameworkModule
+ : DiagGroup<"non-modular-include-in-framework-module">;
+def NonModularIncludeInModule : DiagGroup<"non-modular-include-in-module",
+ [NonModularIncludeInFrameworkModule]>;
def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
@@ -290,9 +296,11 @@
def StrncatSize : DiagGroup<"strncat-size">;
def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
+def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
def TautologicalCompare : DiagGroup<"tautological-compare",
[TautologicalOutOfRangeCompare,
- TautologicalPointerCompare]>;
+ TautologicalPointerCompare,
+ TautologicalOverlapCompare]>;
def HeaderHygiene : DiagGroup<"header-hygiene">;
def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
@@ -417,9 +425,20 @@
def ZeroLengthArray : DiagGroup<"zero-length-array">;
def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">;
+def Fallback : DiagGroup<"fallback">;
+
+// This covers both the deprecated case (in C++98)
+// and the extension case (in C++11 onwards).
+def WritableStrings : DiagGroup<"writable-strings", [DeprecatedWritableStr]>;
// GCC calls -Wdeprecated-writable-strings -Wwrite-strings.
-def GCCWriteStrings : DiagGroup<"write-strings" , [DeprecatedWritableStr]>;
+//
+// Bizarrely, this warning flag enables -fconst-strings in C. This is
+// GCC-compatible, but really weird.
+//
+// FIXME: Should this affect C++11 (where this is an error,
+// not just deprecated) or not?
+def GCCWriteStrings : DiagGroup<"write-strings" , [WritableStrings]>;
def CharSubscript : DiagGroup<"char-subscripts">;
def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
@@ -473,6 +492,7 @@
[BoolConversion,
ConstantConversion,
EnumConversion,
+ FloatConversion,
Shorten64To32,
IntConversion,
LiteralConversion,
@@ -656,9 +676,14 @@
// OpenMP warnings.
def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
+def OpenMPClauses : DiagGroup<"openmp-clauses">;
// Backend warnings.
def BackendInlineAsm : DiagGroup<"inline-asm">;
def BackendFrameLargerThan : DiagGroup<"frame-larger-than">;
def BackendPlugin : DiagGroup<"backend-plugin">;
def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
+def BackendOptimizationRemark : DiagGroup<"pass">;
+
+// Instrumentation based profiling warnings.
+def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index f9b8456..c952e49 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -154,6 +154,9 @@
/// default.
static bool isDefaultMappingAsError(unsigned DiagID);
+ /// \brief Return true if the specified diagnostic is a Remark.
+ static bool isRemark(unsigned DiagID);
+
/// \brief Determine whether the given built-in diagnostic ID is a Note.
static bool isBuiltinNote(unsigned DiagID);
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index e1fc72f..cb9236b 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -316,7 +316,7 @@
def ext_pp_comma_expr : Extension<"comma operator in operand of #if">;
def ext_pp_bad_vaargs_use : Extension<
"__VA_ARGS__ can only appear in the expansion of a C99 variadic macro">;
-def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">;
+def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">, InGroup<MacroRedefined>;
def ext_variadic_macro : Extension<"variadic macros are a C99 feature">,
InGroup<VariadicMacros>;
def warn_cxx98_compat_variadic_macro : Warning<
@@ -353,7 +353,7 @@
def err_pp_empty_filename : Error<"empty filename">;
def err_pp_include_too_deep : Error<"#include nested too deeply">;
def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">;
-def err_pp_macro_not_identifier : Error<"macro names must be identifiers">;
+def err_pp_macro_not_identifier : Error<"macro name must be an identifier">;
def err_pp_missing_macro_name : Error<"macro name missing">;
def err_pp_missing_rparen_in_macro_def : Error<
"missing ')' in macro parameter list">;
@@ -379,8 +379,6 @@
def err_pp_expected_rparen : Error<"expected ')' in preprocessor expression">;
def err_pp_expected_eol : Error<
"expected end of line in preprocessor expression">;
-def err_pp_defined_requires_identifier : Error<
- "operator 'defined' requires an identifier">;
def err_pp_expected_after : Error<"missing %1 after %0">;
def err_pp_colon_without_question : Error<"':' without preceding '?'">;
def err_pp_division_by_zero : Error<
@@ -502,7 +500,7 @@
"pasting formed '%0', an invalid preprocessing token">, DefaultError,
InGroup<DiagGroup<"invalid-token-paste">>;
def err_pp_operator_used_as_macro_name : Error<
- "C++ operator '%0' cannot be used as a macro name">;
+ "C++ operator '%0' (aka %1) cannot be used as a macro name">;
def err_pp_illegal_floating_literal : Error<
"floating point literal in preprocessor expression">;
def err_pp_line_requires_integer : Error<
@@ -620,6 +618,13 @@
"use of private header from outside its module: '%0'">;
def error_undeclared_use_of_module : Error<
"module %0 does not depend on a module exporting '%1'">;
+def warn_non_modular_include_in_framework_module : Warning<
+ "include of non-modular header inside framework module '%0'">,
+ InGroup<NonModularIncludeInFrameworkModule>, DefaultIgnore;
+def warn_non_modular_include_in_module : Warning<
+ "include of non-modular header inside module '%0'">,
+ InGroup<NonModularIncludeInModule>, DefaultIgnore;
+
def warn_header_guard : Warning<
"%0 is used as a header guard here, followed by #define of a different macro">,
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
index 2fba384..a9c8cf5 100644
--- a/include/clang/Basic/DiagnosticOptions.h
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -19,7 +19,7 @@
/// \brief Specifies which overload candidates to display when overload
/// resolution fails.
-enum OverloadsShown {
+enum OverloadsShown : unsigned {
Ovl_All, ///< Show all overloads.
Ovl_Best ///< Show just the "best" overload candidates.
};
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 40fab75..6a01dfc 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -69,7 +69,7 @@
def err_invalid_long_spec : Error<"'long %0' is invalid">;
def err_invalid_longlong_spec : Error<"'long long %0' is invalid">;
def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">;
-def err_friend_storage_spec : Error<"'%0' is invalid in friend declarations">;
+def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">;
def ext_ident_list_in_param : Extension<
"type-less parameter names in function declaration">;
@@ -204,6 +204,8 @@
def err_expected_semi_after_static_assert : Error<
"expected ';' after static_assert">;
def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
+def err_single_decl_assign_in_for_range : Error<
+ "range-based 'for' statement uses ':', not '='">;
def warn_missing_selector_name : Warning<
"%0 used as the name of the previous parameter rather than as part "
"of the selector">,
@@ -225,7 +227,7 @@
def err_unexpected_at : Error<"unexpected '@' in program">;
def err_atimport : Error<
-"use of '@import' when modules are disabled, add -fmodules">;
+"use of '@import' when modules are disabled">;
def err_invalid_reference_qualifier_application : Error<
"'%0' qualifier may not be applied to a reference">;
@@ -339,8 +341,10 @@
"cannot template a using directive">;
def err_templated_using_declaration : Error<
"cannot template a using declaration">;
-def err_unexected_colon_in_nested_name_spec : Error<
+def err_unexpected_colon_in_nested_name_spec : Error<
"unexpected ':' in nested name specifier; did you mean '::'?">;
+def err_unexpected_token_in_nested_name_spec : Error<
+ "'%0' cannot be a part of nested name specifier; did you mean ':'?">;
def err_bool_redeclaration : Error<
"redeclaration of C++ built-in type 'bool'">;
def ext_c11_static_assert : Extension<
@@ -524,7 +528,9 @@
"C++11 attribute syntax is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_cxx11_attribute_forbids_arguments : Error<
- "attribute '%0' cannot have an argument list">;
+ "attribute %0 cannot have an argument list">;
+def err_attribute_requires_arguments : Error<
+ "parentheses must be omitted if %0 attribute's argument list is empty">;
def err_cxx11_attribute_forbids_ellipsis : Error<
"attribute '%0' cannot be used as an attribute pack">;
def err_cxx11_attribute_repeated : Error<
@@ -771,6 +777,15 @@
"missing ')' after '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_identifier : Warning<
"expected identifier in '#pragma %0' - ignored">, InGroup<IgnoredPragmas>;
+def warn_pragma_expected_section_name : Warning<
+ "expected a string literal for the section name in '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
+def warn_pragma_expected_section_push_pop_or_name : Warning<
+ "expected push, pop or a string literal for the section name in '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
+def warn_pragma_expected_section_label_or_name : Warning<
+ "expected a stack label or a string literal for the section name in '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_expected_integer : Warning<
"expected integer between %0 and %1 inclusive in '#pragma %2' - ignored">,
InGroup<IgnoredPragmas>;
@@ -793,6 +808,15 @@
"invalid alignment option in '#pragma %select{align|options align}0' - ignored">,
InGroup<IgnoredPragmas>;
// - #pragma pack
+def warn_pragma_unsupported_action : Warning<
+ "known but unsupported action '%1' for '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
+def warn_pragma_invalid_specific_action : Warning<
+ "unknown action '%1' for '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
+def warn_pragma_expected_action_or_r_paren : Warning<
+ "expected action or ')' in '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_invalid_action : Warning<
"unknown action for '#pragma %0' - ignored">,
InGroup<IgnoredPragmas>;
@@ -819,6 +843,14 @@
def err_pragma_pointers_to_members_unknown_kind : Error<
"unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1"
"'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'">;
+// - #pragma clang optimize on/off
+def err_pragma_optimize_missing_argument : Error<
+ "missing argument to '#pragma clang optimize'; expected 'on' or 'off'">;
+def err_pragma_optimize_invalid_argument : Error<
+ "unexpected argument '%0' to '#pragma clang optimize'; "
+ "expected 'on' or 'off'">;
+def err_pragma_optimize_extra_argument : Error<
+ "unexpected extra argument '%0' to '#pragma clang optimize'">;
// OpenCL Section 6.8.g
def err_not_opencl_storage_class_specifier : Error<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b138619..0215486 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -35,7 +35,7 @@
"taking the absolute value of unsigned type %0 has no effect">,
InGroup<AbsoluteValue>;
def note_remove_abs : Note<
- "remove the call to %0 since unsigned values cannot be negative">;
+ "remove the call to '%0' since unsigned values cannot be negative">;
def warn_abs_too_small : Warning<
"absolute value function %0 given an argument of type %1 but has parameter "
"of type %2 which may cause truncation of value">, InGroup<AbsoluteValue>;
@@ -234,8 +234,8 @@
InGroup<ImplicitFunctionDeclare>;
def note_function_suggestion : Note<"did you mean %0?">;
-def err_ellipsis_first_arg : Error<
- "ISO C requires a named argument before '...'">;
+def err_ellipsis_first_param : Error<
+ "ISO C requires a named parameter before '...'">;
def err_declarator_need_ident : Error<"declarator requires an identifier">;
def err_language_linkage_spec_unknown : Error<"unknown linkage language">;
def err_language_linkage_spec_not_ascii : Error<
@@ -433,9 +433,9 @@
def warn_memsize_comparison : Warning<
"size argument in %0 call is a comparison">,
InGroup<DiagGroup<"memsize-comparison">>;
-def warn_memsize_comparison_paren_note : Note<
+def note_memsize_comparison_paren : Note<
"did you mean to compare the result of %0 instead?">;
-def warn_memsize_comparison_cast_note : Note<
+def note_memsize_comparison_cast_silence : Note<
"explicitly cast the argument to size_t to silence this warning">;
def warn_strncat_large_size : Warning<
@@ -498,8 +498,8 @@
def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">;
def err_opencl_half_declaration : Error<
"declaring variable of type %0 is not allowed">;
-def err_opencl_half_argument : Error<
- "declaring function argument of type %0 is not allowed; did you forget * ?">;
+def err_opencl_half_param : Error<
+ "declaring function parameter of type %0 is not allowed; did you forget * ?">;
def err_opencl_half_return : Error<
"declaring function return value of type %0 is not allowed; did you forget * ?">;
def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
@@ -521,6 +521,7 @@
Warning<"ms_struct may not produce MSVC-compatible layouts for classes "
"with base classes or virtual functions">,
DefaultError, InGroup<IncompatibleMSStruct>;
+def err_section_conflict : Error<"%0 causes a section type conflict with %1">;
def warn_pragma_unused_undeclared_var : Warning<
"undeclared variable %0 used as an argument for '#pragma unused'">,
@@ -1168,7 +1169,10 @@
def warn_cxx98_compat_enum_nested_name_spec : Warning<
"enumeration type in nested name specifier is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
-
+def err_nested_name_spec_is_not_class : Error<
+ "%0 cannot appear before '::' because it is not a class"
+ "%select{ or namespace|, namespace, or scoped enumeration}1; did you mean ':'?">;
+
// C++ class members
def err_storageclass_invalid_for_member : Error<
"storage class specified for a member declaration">;
@@ -1858,8 +1862,6 @@
// Attributes
def err_nsobject_attribute : Error<
"'NSObject' attribute is for pointer types only">;
-def err_attribute_can_be_applied_only_to_symbol_declaration : Error<
- "%0 attribute can be applied only to symbol declaration">;
def err_attributes_are_not_compatible : Error<
"%0 and %1 attributes are not compatible">;
def err_attribute_wrong_number_arguments : Error<
@@ -2000,6 +2002,8 @@
InGroup<ObjCStringConcatenation>;
def note_objc_literal_comparison_isequal : Note<
"use 'isEqual:' instead">;
+def err_attribute_argument_is_zero : Error<
+ "%0 attribute must be greater than 0">;
let CategoryName = "Cocoa API Issue" in {
def warn_objc_redundant_literal_use : Warning<
@@ -2031,7 +2035,7 @@
def err_attribute_aligned_too_great : Error<
"requested alignment must be %0 bytes or smaller">;
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
- "%0 redeclared without %1 attribute: previous %1 ignored">;
+ "%q0 redeclared without %1 attribute: previous %1 ignored">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">,
InGroup<IgnoredAttributes>;
def warn_attribute_after_definition_ignored : Warning<
@@ -2077,6 +2081,9 @@
"weak declaration cannot have internal linkage">;
def err_attribute_selectany_non_extern_data : Error<
"'selectany' can only be applied to data items with external linkage">;
+def err_declspec_thread_on_thread_variable : Error<
+ "'__declspec(thread)' applied to variable that already has a "
+ "thread-local storage specifier">;
def err_attribute_dll_not_extern : Error<
"%q0 must have external linkage when declared %q1">;
def warn_attribute_invalid_on_definition : Warning<
@@ -2084,6 +2091,8 @@
InGroup<IgnoredAttributes>;
def err_attribute_dll_redeclaration : Error<
"redeclaration of %q0 cannot add %q1 attribute">;
+def err_attribute_dllimport_function_definition : Error<
+ "dllimport cannot be applied to non-inline function definition">;
def err_attribute_dllimport_data_definition : Error<
"definition of dllimport data">;
def err_attribute_weakref_not_static : Error<
@@ -2099,6 +2108,9 @@
def warn_alias_to_weak_alias : Warning<
"alias will always resolve to %0 even if weak definition of alias %1 is overridden">,
InGroup<IgnoredAttributes>;
+def warn_alias_with_section : Warning<
+ "alias will not be in section '%0' but in the same section as the aliasee">,
+ InGroup<IgnoredAttributes>;
def err_duplicate_mangled_name : Error<
"definition with same mangled name as another definition">;
def err_cyclic_alias : Error<
@@ -2315,7 +2327,7 @@
InGroup<Conversion>, DefaultIgnore;
def warn_impcast_float_integer : Warning<
"implicit conversion turns floating-point number into integer: %0 to %1">,
- InGroup<Conversion>, DefaultIgnore;
+ InGroup<FloatConversion>, DefaultIgnore;
def warn_impcast_integer_sign : Warning<
"implicit conversion changes signedness: %0 to %1">,
InGroup<SignConversion>, DefaultIgnore;
@@ -2527,10 +2539,10 @@
"designated initializer invoked a non-designated initializer">,
InGroup<ObjCDesignatedInit>;
def warn_objc_secondary_init_super_init_call : Warning<
- "secondary initializer should not invoke an initializer on 'super'">,
+ "convenience initializer should not invoke an initializer on 'super'">,
InGroup<ObjCDesignatedInit>;
def warn_objc_secondary_init_missing_init_call : Warning<
- "secondary initializer missing a 'self' call to another initializer">,
+ "convenience initializer missing a 'self' call to another initializer">,
InGroup<ObjCDesignatedInit>;
def warn_objc_implementation_missing_designated_init_override : Warning<
"method override for the designated initializer of the superclass %objcinstance0 not found">,
@@ -3263,8 +3275,8 @@
"nested name specifier '%0' for declaration does not refer into a class, "
"class template or class template partial specialization">;
def err_specialize_member_of_template : Error<
- "cannot specialize (with 'template<>') a member of an unspecialized "
- "template">;
+ "cannot specialize %select{|(with 'template<>') }0a member of an "
+ "unspecialized template">;
// C++ Class Template Partial Specialization
def err_default_arg_in_partial_spec : Error<
@@ -3304,6 +3316,9 @@
"previous declaration of variable template partial specialization is here">;
def err_var_spec_no_template : Error<
"no variable template matches%select{| partial}0 specialization">;
+def err_var_spec_no_template_but_method : Error<
+ "no variable template matches specialization; "
+ "did you mean to use %0 as function template instead?">;
// C++ Function template specializations
def err_function_template_spec_no_match : Error<
@@ -3383,6 +3398,9 @@
// C++ Explicit Instantiation
def err_explicit_instantiation_duplicate : Error<
"duplicate explicit instantiation of %0">;
+def warn_explicit_instantiation_duplicate : ExtWarn<
+ "duplicate explicit instantiation of %0 ignored as a Microsoft extension">,
+ InGroup<Microsoft>;
def note_previous_explicit_instantiation : Note<
"previous explicit instantiation is here">;
def ext_explicit_instantiation_after_specialization : Extension<
@@ -3935,8 +3953,8 @@
"constant expression evaluates to %0 which cannot be narrowed to type %1 in "
"C++11">,
InGroup<CXX11Narrowing>, DefaultIgnore;
-def note_init_list_narrowing_override : Note<
- "override this message by inserting an explicit cast">;
+def note_init_list_narrowing_silence : Note<
+ "insert an explicit cast to silence this issue">;
def err_init_objc_class : Error<
"cannot initialize Objective-C class type %0">;
def err_implicit_empty_initializer : Error<
@@ -4634,12 +4652,10 @@
InGroup<CXX11CompatDeprecatedWritableStr>;
def ext_deprecated_string_literal_conversion : ExtWarn<
"ISO C++11 does not allow conversion from string literal to %0">,
- InGroup<CXX11CompatDeprecatedWritableStr>, SFINAEFailure;
+ InGroup<WritableStrings>, SFINAEFailure;
def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
def err_typecheck_sclass_fscope : Error<
"illegal storage class on file-scoped variable">;
-def err_unsupported_global_register : Error<
- "global register variables are not supported">;
def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">,
InGroup<MissingDeclarations>;
def ext_standalone_specifier : ExtWarn<"'%0' is not permitted on a declaration "
@@ -4675,6 +4691,9 @@
"invalid argument type %0 to unary expression">;
def err_typecheck_indirection_requires_pointer : Error<
"indirection requires pointer operand (%0 invalid)">;
+def ext_typecheck_indirection_through_void_pointer : Extension<
+ "ISO C++ does not allow indirection on operand of type %0">,
+ InGroup<DiagGroup<"void-ptr-dereference">>;
def warn_indirection_through_null : Warning<
"indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>;
def note_indirection_through_null : Note<
@@ -4728,8 +4747,9 @@
"comparison of unsigned%select{| enum}2 expression %0 is always %1">,
InGroup<TautologicalCompare>;
def warn_out_of_range_compare : Warning<
- "comparison of constant %0 with expression of type %1 is always "
- "%select{false|true}2">, InGroup<TautologicalOutOfRangeCompare>;
+ "comparison of %select{constant %0|true|false}1 with "
+ "%select{expression of type %2|boolean expression}3 is always "
+ "%select{false|true}4">, InGroup<TautologicalOutOfRangeCompare>;
def warn_runsigned_always_true_comparison : Warning<
"comparison of %0 unsigned%select{| enum}2 expression is always %1">,
InGroup<TautologicalCompare>;
@@ -6382,6 +6402,12 @@
def warn_comparison_always : Warning<
"%select{self-|array }0comparison always evaluates to %select{false|true|a constant}1">,
InGroup<TautologicalCompare>;
+def warn_comparison_bitwise_always : Warning<
+ "bitwise comparison always evaluates to %select{false|true}0">,
+ InGroup<TautologicalCompare>;
+def warn_tautological_overlap_comparison : Warning<
+ "overlapping comparisons always evaluate to %select{false|true}0">,
+ InGroup<TautologicalOverlapCompare>, DefaultIgnore;
def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
@@ -6920,6 +6946,16 @@
"enumeration type">;
def err_omp_required_access : Error<
"%0 variable must be %1">;
+def err_omp_const_variable : Error<
+ "const-qualified variable cannot be %0">;
+def err_omp_linear_incomplete_type : Error<
+ "a linear variable with incomplete type %0">;
+def err_omp_linear_expected_int_or_ptr : Error<
+ "argument of a linear clause should be of integral or pointer "
+ "type, not %0">;
+def warn_omp_linear_step_zero : Warning<
+ "zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
+ InGroup<OpenMPClauses>;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -6969,6 +7005,8 @@
def err_module_import_not_at_top_level : Error<
"import of module '%0' appears within %1">;
def note_module_import_not_at_top_level : Note<"%0 begins here">;
+def err_module_self_import : Error<
+ "import of module '%0' appears within same top-level module '%1'">;
}
let CategoryName = "Documentation Issue" in {
@@ -6976,4 +7014,11 @@
"not a Doxygen trailing comment">, InGroup<Documentation>, DefaultIgnore;
} // end of documentation issue category
+let CategoryName = "Instrumentation Issue" in {
+def warn_profile_data_out_of_date : Warning<
+ "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1"
+ " no data and %2 %plural{1:has|:have}2 mismatched data that will be ignored">,
+ InGroup<ProfileInstrOutOfDate>;
+} // end of instrumentation issue category
+
} // end of sema component.
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 57ba0a4..be9d2bd 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -39,6 +39,8 @@
"PCH file but is currently %select{disabled|enabled}2">;
def err_pch_langopt_value_mismatch : Error<
"%0 differs in PCH file vs. current file">;
+def err_pch_diagopt_mismatch : Error<"%0 is currently enabled, but was not in "
+ "the PCH file">;
def err_pch_version_too_old : Error<
"PCH file uses an older PCH format that is no longer supported">;
@@ -48,7 +50,12 @@
"PCH file built from a different branch (%0) than the compiler (%1)">;
def err_pch_with_compiler_errors : Error<
"PCH file contains compiler errors">;
-
+
+def err_imported_module_not_found : Error<
+ "module '%0' imported by AST file '%1' not found">, DefaultFatal;
+def err_imported_module_modmap_changed : Error<
+ "module '%0' imported by AST file '%1' found in a different module map file"
+ " (%2) than when the importing AST file was built (%3)">, DefaultFatal;
def warn_module_conflict : Warning<
"module '%0' conflicts with already-imported module '%1': %2">,
InGroup<ModuleConflict>;
@@ -78,6 +85,13 @@
"definition has no member %0">;
def note_module_odr_violation_possible_decl : Note<
"declaration of %0 does not match">;
+def err_module_odr_violation_different_definitions : Error<
+ "%q0 has different definitions in different modules; "
+ "%select{definition in module '%2' is here|defined here}1">;
+def note_module_odr_violation_different_definitions : Note<
+ "definition in module '%0' is here">;
+def err_module_odr_violation_different_instantiations : Error<
+ "instantiation of %q0 is different in different modules">;
} // let CategoryName
} // let Component
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index cc9e4e4..023433b 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -49,7 +49,7 @@
const char *Name; // Name of the directory.
friend class FileManager;
public:
- DirectoryEntry() : Name(0) {}
+ DirectoryEntry() : Name(nullptr) {}
const char *getName() const { return Name; }
};
@@ -74,7 +74,7 @@
friend class FileManager;
void closeFile() const {
- File.reset(0); // rely on destructor to close File
+ File.reset(nullptr); // rely on destructor to close File
}
void operator=(const FileEntry &) LLVM_DELETED_FUNCTION;
@@ -180,7 +180,7 @@
public:
FileManager(const FileSystemOptions &FileSystemOpts,
- IntrusiveRefCntPtr<vfs::FileSystem> FS = 0);
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
~FileManager();
/// \brief Installs the provided FileSystemStatCache object within
@@ -241,10 +241,10 @@
/// \brief Open the specified file as a MemoryBuffer, returning a new
/// MemoryBuffer if successful, otherwise returning null.
llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry,
- std::string *ErrorStr = 0,
+ std::string *ErrorStr = nullptr,
bool isVolatile = false);
llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
- std::string *ErrorStr = 0);
+ std::string *ErrorStr = nullptr);
/// \brief Get the 'stat' information for the given \p Path.
///
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index c4a89b3..af25356 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -38,6 +38,10 @@
bool IsDirectory;
bool IsNamedPipe;
bool InPCH;
+ bool IsVFSMapped; // FIXME: remove this when files support multiple names
+ FileData()
+ : Size(0), ModTime(0), IsDirectory(false), IsNamedPipe(false),
+ InPCH(false), IsVFSMapped(false) {}
};
/// \brief Abstract interface for introducing a FileManager cache for 'stat'
@@ -95,7 +99,7 @@
// If we hit the end of the list of stat caches to try, just compute and
// return it without a cache.
- return get(Path, Data, isFile, F, 0, FS) ? CacheMissing : CacheExists;
+ return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
}
};
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index abf5b93..0c278a1 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -17,12 +17,9 @@
#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/TokenKinds.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
#include <string>
@@ -428,7 +425,7 @@
/// \brief Create the identifier table, populating it with info about the
/// language keywords for the language specified by \p LangOpts.
IdentifierTable(const LangOptions &LangOpts,
- IdentifierInfoLookup* externalLookup = 0);
+ IdentifierInfoLookup* externalLookup = nullptr);
/// \brief Set the external identifier lookup mechanism.
void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
@@ -625,7 +622,7 @@
IdentifierInfo *getAsIdentifierInfo() const {
if (getIdentifierInfoFlag() < MultiArg)
return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
- return 0;
+ return nullptr;
}
MultiKeywordSelector *getMultiKeywordSelector() const {
return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
@@ -814,6 +811,8 @@
template <>
struct isPodLike<clang::Selector> { static const bool value = true; };
+template <typename T> class PointerLikeTypeTraits;
+
template<>
class PointerLikeTypeTraits<clang::Selector> {
public:
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 7b21482..0752eeb 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -96,6 +96,9 @@
BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time")
LANGOPT(Modules , 1, 0, "modules extension to C")
LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
+LANGOPT(ModulesSearchAll , 1, 1, "search even non-imported modules to find unresolved references")
+LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules")
+LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery")
LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro")
LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
index 247c6e7..f3b4769 100644
--- a/include/clang/Basic/Linkage.h
+++ b/include/clang/Basic/Linkage.h
@@ -18,7 +18,7 @@
/// \brief Describes the different kinds of linkage
/// (C++ [basic.link], C99 6.2.2) that an entity may have.
-enum Linkage {
+enum Linkage : unsigned char {
/// \brief No linkage, which means that the entity is unique and
/// can only be referred to from within its scope.
NoLinkage = 0,
@@ -59,10 +59,9 @@
/// This is relevant to CodeGen and AST file reading.
enum GVALinkage {
GVA_Internal,
- GVA_C99Inline,
- GVA_CXXInline,
+ GVA_AvailableExternally,
+ GVA_DiscardableODR,
GVA_StrongExternal,
- GVA_TemplateInstantiation,
GVA_StrongODR
};
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 1f7f71d..89fd388 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -51,10 +51,21 @@
/// \brief The location of the module definition.
SourceLocation DefinitionLoc;
-
+
/// \brief The parent of this module. This will be NULL for the top-level
/// module.
Module *Parent;
+
+ /// \brief The module map file that (along with the module name) uniquely
+ /// identifies this module.
+ ///
+ /// The particular module that \c Name refers to may depend on how the module
+ /// was found in header search. However, the combination of \c Name and
+ /// \c ModuleMap will be globally unique for top-level modules. In the case of
+ /// inferred modules, \c ModuleMap will contain the module map that allowed
+ /// the inference (e.g. contained 'Module *') rather than the virtual
+ /// inferred module map file.
+ const FileEntry *ModuleMap;
/// \brief The umbrella header or directory.
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
@@ -112,8 +123,13 @@
/// will be false to indicate that this (sub)module is not available.
SmallVector<Requirement, 2> Requirements;
- /// \brief Whether this module is available in the current
- /// translation unit.
+ /// \brief Whether this module is missing a feature from \c Requirements.
+ unsigned IsMissingRequirement : 1;
+
+ /// \brief Whether this module is available in the current translation unit.
+ ///
+ /// If the module is missing headers or does not meet all requirements then
+ /// this bit will be 0.
unsigned IsAvailable : 1;
/// \brief Whether this module was loaded from a module file.
@@ -134,6 +150,9 @@
/// imported within such a block).
unsigned IsExternC : 1;
+ /// \brief Whether this is an inferred submodule (module * { ... }).
+ unsigned IsInferred : 1;
+
/// \brief Whether we should infer submodules for this module based on
/// the headers.
///
@@ -264,8 +283,10 @@
std::vector<Conflict> Conflicts;
/// \brief Construct a new module or submodule.
- Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
- bool IsFramework, bool IsExplicit);
+ ///
+ /// For an explanation of \p ModuleMap, see Module::ModuleMap.
+ Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
+ const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit);
~Module();
@@ -290,11 +311,11 @@
HeaderDirective &MissingHeader) const;
/// \brief Determine whether this module is a submodule.
- bool isSubModule() const { return Parent != 0; }
+ bool isSubModule() const { return Parent != nullptr; }
/// \brief Determine whether this module is a submodule of the given other
/// module.
- bool isSubModuleOf(Module *Other) const;
+ bool isSubModuleOf(const Module *Other) const;
/// \brief Determine whether this module is a part of a framework,
/// either because it is a framework module or because it is a submodule
@@ -341,8 +362,8 @@
/// \brief Set the serialized AST file for the top-level module of this module.
void setASTFile(const FileEntry *File) {
- assert((File == 0 || getASTFile() == 0 || getASTFile() == File) &&
- "file path changed");
+ assert((File == nullptr || getASTFile() == nullptr ||
+ getASTFile() == File) && "file path changed");
getTopLevelModule()->ASTFile = File;
}
@@ -394,6 +415,9 @@
const LangOptions &LangOpts,
const TargetInfo &Target);
+ /// \brief Mark this module and all of its submodules as unavailable.
+ void markUnavailable(bool MissingRequirement = false);
+
/// \brief Find the submodule with the given name.
///
/// \returns The submodule if found, or NULL otherwise.
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
deleted file mode 100644
index 8c2cd8d..0000000
--- a/include/clang/Basic/OnDiskHashTable.h
+++ /dev/null
@@ -1,419 +0,0 @@
-//===--- OnDiskHashTable.h - On-Disk Hash Table Implementation --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines facilities for reading and writing on-disk hash tables.
-///
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
-#define LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/EndianStream.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cassert>
-#include <cstdlib>
-
-namespace clang {
-
-namespace io {
-
-typedef uint32_t Offset;
-
-inline void Pad(raw_ostream& Out, unsigned A) {
- using namespace llvm::support;
- Offset off = (Offset) Out.tell();
- for (uint32_t n = llvm::OffsetToAlignment(off, A); n; --n)
- endian::Writer<little>(Out).write<uint8_t>(0);
-}
-
-} // end namespace io
-
-template<typename Info>
-class OnDiskChainedHashTableGenerator {
- unsigned NumBuckets;
- unsigned NumEntries;
- llvm::BumpPtrAllocator BA;
-
- class Item {
- public:
- typename Info::key_type key;
- typename Info::data_type data;
- Item *next;
- const uint32_t hash;
-
- Item(typename Info::key_type_ref k, typename Info::data_type_ref d,
- Info &InfoObj)
- : key(k), data(d), next(0), hash(InfoObj.ComputeHash(k)) {}
- };
-
- class Bucket {
- public:
- io::Offset off;
- Item* head;
- unsigned length;
-
- Bucket() {}
- };
-
- Bucket* Buckets;
-
-private:
- void insert(Bucket* b, size_t size, Item* E) {
- unsigned idx = E->hash & (size - 1);
- Bucket& B = b[idx];
- E->next = B.head;
- ++B.length;
- B.head = E;
- }
-
- void resize(size_t newsize) {
- Bucket* newBuckets = (Bucket*) std::calloc(newsize, sizeof(Bucket));
- // Populate newBuckets with the old entries.
- for (unsigned i = 0; i < NumBuckets; ++i)
- for (Item* E = Buckets[i].head; E ; ) {
- Item* N = E->next;
- E->next = 0;
- insert(newBuckets, newsize, E);
- E = N;
- }
-
- free(Buckets);
- NumBuckets = newsize;
- Buckets = newBuckets;
- }
-
-public:
-
- void insert(typename Info::key_type_ref key,
- typename Info::data_type_ref data) {
- Info InfoObj;
- insert(key, data, InfoObj);
- }
-
- void insert(typename Info::key_type_ref key,
- typename Info::data_type_ref data, Info &InfoObj) {
-
- ++NumEntries;
- if (4*NumEntries >= 3*NumBuckets) resize(NumBuckets*2);
- insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data,
- InfoObj));
- }
-
- io::Offset Emit(raw_ostream &out) {
- Info InfoObj;
- return Emit(out, InfoObj);
- }
-
- io::Offset Emit(raw_ostream &out, Info &InfoObj) {
- using namespace llvm::support;
- endian::Writer<little> LE(out);
-
- // Emit the payload of the table.
- for (unsigned i = 0; i < NumBuckets; ++i) {
- Bucket& B = Buckets[i];
- if (!B.head) continue;
-
- // Store the offset for the data of this bucket.
- B.off = out.tell();
- assert(B.off && "Cannot write a bucket at offset 0. Please add padding.");
-
- // Write out the number of items in the bucket.
- LE.write<uint16_t>(B.length);
- assert(B.length != 0 && "Bucket has a head but zero length?");
-
- // Write out the entries in the bucket.
- for (Item *I = B.head; I ; I = I->next) {
- LE.write<uint32_t>(I->hash);
- const std::pair<unsigned, unsigned>& Len =
- InfoObj.EmitKeyDataLength(out, I->key, I->data);
- InfoObj.EmitKey(out, I->key, Len.first);
- InfoObj.EmitData(out, I->key, I->data, Len.second);
- }
- }
-
- // Emit the hashtable itself.
- io::Pad(out, 4);
- io::Offset TableOff = out.tell();
- LE.write<uint32_t>(NumBuckets);
- LE.write<uint32_t>(NumEntries);
- for (unsigned i = 0; i < NumBuckets; ++i)
- LE.write<uint32_t>(Buckets[i].off);
-
- return TableOff;
- }
-
- OnDiskChainedHashTableGenerator() {
- NumEntries = 0;
- NumBuckets = 64;
- // Note that we do not need to run the constructors of the individual
- // Bucket objects since 'calloc' returns bytes that are all 0.
- Buckets = (Bucket*) std::calloc(NumBuckets, sizeof(Bucket));
- }
-
- ~OnDiskChainedHashTableGenerator() {
- std::free(Buckets);
- }
-};
-
-template<typename Info>
-class OnDiskChainedHashTable {
- const unsigned NumBuckets;
- const unsigned NumEntries;
- const unsigned char* const Buckets;
- const unsigned char* const Base;
- Info InfoObj;
-
-public:
- typedef typename Info::internal_key_type internal_key_type;
- typedef typename Info::external_key_type external_key_type;
- typedef typename Info::data_type data_type;
-
- OnDiskChainedHashTable(unsigned numBuckets, unsigned numEntries,
- const unsigned char* buckets,
- const unsigned char* base,
- const Info &InfoObj = Info())
- : NumBuckets(numBuckets), NumEntries(numEntries),
- Buckets(buckets), Base(base), InfoObj(InfoObj) {
- assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
- "'buckets' must have a 4-byte alignment");
- }
-
- unsigned getNumBuckets() const { return NumBuckets; }
- unsigned getNumEntries() const { return NumEntries; }
- const unsigned char* getBase() const { return Base; }
- const unsigned char* getBuckets() const { return Buckets; }
-
- bool isEmpty() const { return NumEntries == 0; }
-
- class iterator {
- internal_key_type key;
- const unsigned char* const data;
- const unsigned len;
- Info *InfoObj;
- public:
- iterator() : data(0), len(0) {}
- iterator(const internal_key_type k, const unsigned char* d, unsigned l,
- Info *InfoObj)
- : key(k), data(d), len(l), InfoObj(InfoObj) {}
-
- data_type operator*() const { return InfoObj->ReadData(key, data, len); }
- bool operator==(const iterator& X) const { return X.data == data; }
- bool operator!=(const iterator& X) const { return X.data != data; }
- };
-
- iterator find(const external_key_type& eKey, Info *InfoPtr = 0) {
- if (!InfoPtr)
- InfoPtr = &InfoObj;
-
- using namespace llvm::support;
- const internal_key_type& iKey = InfoObj.GetInternalKey(eKey);
- unsigned key_hash = InfoObj.ComputeHash(iKey);
-
- // Each bucket is just a 32-bit offset into the hash table file.
- unsigned idx = key_hash & (NumBuckets - 1);
- const unsigned char* Bucket = Buckets + sizeof(uint32_t)*idx;
-
- unsigned offset = endian::readNext<uint32_t, little, aligned>(Bucket);
- if (offset == 0) return iterator(); // Empty bucket.
- const unsigned char* Items = Base + offset;
-
- // 'Items' starts with a 16-bit unsigned integer representing the
- // number of items in this bucket.
- unsigned len = endian::readNext<uint16_t, little, unaligned>(Items);
-
- for (unsigned i = 0; i < len; ++i) {
- // Read the hash.
- uint32_t item_hash = endian::readNext<uint32_t, little, unaligned>(Items);
-
- // Determine the length of the key and the data.
- const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Items);
- unsigned item_len = L.first + L.second;
-
- // Compare the hashes. If they are not the same, skip the entry entirely.
- if (item_hash != key_hash) {
- Items += item_len;
- continue;
- }
-
- // Read the key.
- const internal_key_type& X =
- InfoPtr->ReadKey((const unsigned char* const) Items, L.first);
-
- // If the key doesn't match just skip reading the value.
- if (!InfoPtr->EqualKey(X, iKey)) {
- Items += item_len;
- continue;
- }
-
- // The key matches!
- return iterator(X, Items + L.first, L.second, InfoPtr);
- }
-
- return iterator();
- }
-
- iterator end() const { return iterator(); }
-
- /// \brief Iterates over all of the keys in the table.
- class key_iterator {
- const unsigned char* Ptr;
- unsigned NumItemsInBucketLeft;
- unsigned NumEntriesLeft;
- Info *InfoObj;
- public:
- typedef external_key_type value_type;
-
- key_iterator(const unsigned char* const Ptr, unsigned NumEntries,
- Info *InfoObj)
- : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
- InfoObj(InfoObj) { }
- key_iterator()
- : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { }
-
- friend bool operator==(const key_iterator &X, const key_iterator &Y) {
- return X.NumEntriesLeft == Y.NumEntriesLeft;
- }
- friend bool operator!=(const key_iterator& X, const key_iterator &Y) {
- return X.NumEntriesLeft != Y.NumEntriesLeft;
- }
-
- key_iterator& operator++() { // Preincrement
- using namespace llvm::support;
- if (!NumItemsInBucketLeft) {
- // 'Items' starts with a 16-bit unsigned integer representing the
- // number of items in this bucket.
- NumItemsInBucketLeft =
- endian::readNext<uint16_t, little, unaligned>(Ptr);
- }
- Ptr += 4; // Skip the hash.
- // Determine the length of the key and the data.
- const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Ptr);
- Ptr += L.first + L.second;
- assert(NumItemsInBucketLeft);
- --NumItemsInBucketLeft;
- assert(NumEntriesLeft);
- --NumEntriesLeft;
- return *this;
- }
- key_iterator operator++(int) { // Postincrement
- key_iterator tmp = *this; ++*this; return tmp;
- }
-
- value_type operator*() const {
- const unsigned char* LocalPtr = Ptr;
- if (!NumItemsInBucketLeft)
- LocalPtr += 2; // number of items in bucket
- LocalPtr += 4; // Skip the hash.
-
- // Determine the length of the key and the data.
- const std::pair<unsigned, unsigned>& L
- = Info::ReadKeyDataLength(LocalPtr);
-
- // Read the key.
- const internal_key_type& Key = InfoObj->ReadKey(LocalPtr, L.first);
- return InfoObj->GetExternalKey(Key);
- }
- };
-
- key_iterator key_begin() {
- return key_iterator(Base + 4, getNumEntries(), &InfoObj);
- }
- key_iterator key_end() { return key_iterator(); }
-
- /// \brief Iterates over all the entries in the table, returning the data.
- class data_iterator {
- const unsigned char* Ptr;
- unsigned NumItemsInBucketLeft;
- unsigned NumEntriesLeft;
- Info *InfoObj;
- public:
- typedef data_type value_type;
-
- data_iterator(const unsigned char* const Ptr, unsigned NumEntries,
- Info *InfoObj)
- : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
- InfoObj(InfoObj) { }
- data_iterator()
- : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { }
-
- bool operator==(const data_iterator& X) const {
- return X.NumEntriesLeft == NumEntriesLeft;
- }
- bool operator!=(const data_iterator& X) const {
- return X.NumEntriesLeft != NumEntriesLeft;
- }
-
- data_iterator& operator++() { // Preincrement
- using namespace llvm::support;
- if (!NumItemsInBucketLeft) {
- // 'Items' starts with a 16-bit unsigned integer representing the
- // number of items in this bucket.
- NumItemsInBucketLeft =
- endian::readNext<uint16_t, little, unaligned>(Ptr);
- }
- Ptr += 4; // Skip the hash.
- // Determine the length of the key and the data.
- const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Ptr);
- Ptr += L.first + L.second;
- assert(NumItemsInBucketLeft);
- --NumItemsInBucketLeft;
- assert(NumEntriesLeft);
- --NumEntriesLeft;
- return *this;
- }
- data_iterator operator++(int) { // Postincrement
- data_iterator tmp = *this; ++*this; return tmp;
- }
-
- value_type operator*() const {
- const unsigned char* LocalPtr = Ptr;
- if (!NumItemsInBucketLeft)
- LocalPtr += 2; // number of items in bucket
- LocalPtr += 4; // Skip the hash.
-
- // Determine the length of the key and the data.
- const std::pair<unsigned, unsigned>& L =Info::ReadKeyDataLength(LocalPtr);
-
- // Read the key.
- const internal_key_type& Key =
- InfoObj->ReadKey(LocalPtr, L.first);
- return InfoObj->ReadData(Key, LocalPtr + L.first, L.second);
- }
- };
-
- data_iterator data_begin() {
- return data_iterator(Base + 4, getNumEntries(), &InfoObj);
- }
- data_iterator data_end() { return data_iterator(); }
-
- Info &getInfoObj() { return InfoObj; }
-
- static OnDiskChainedHashTable* Create(const unsigned char* buckets,
- const unsigned char* const base,
- const Info &InfoObj = Info()) {
- using namespace llvm::support;
- assert(buckets > base);
- assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
- "buckets should be 4-byte aligned.");
-
- unsigned numBuckets = endian::readNext<uint32_t, little, aligned>(buckets);
- unsigned numEntries = endian::readNext<uint32_t, little, aligned>(buckets);
- return new OnDiskChainedHashTable<Info>(numBuckets, numEntries, buckets,
- base, InfoObj);
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 348f40f..0adc984 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -27,6 +27,9 @@
#ifndef OPENMP_DEFAULT_KIND
# define OPENMP_DEFAULT_KIND(Name)
#endif
+#ifndef OPENMP_PROC_BIND_KIND
+# define OPENMP_PROC_BIND_KIND(Name)
+#endif
// OpenMP directives.
OPENMP_DIRECTIVE(threadprivate)
@@ -38,16 +41,20 @@
OPENMP_CLAUSE(if, OMPIfClause)
OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
OPENMP_CLAUSE(safelen, OMPSafelenClause)
+OPENMP_CLAUSE(collapse, OMPCollapseClause)
OPENMP_CLAUSE(default, OMPDefaultClause)
OPENMP_CLAUSE(private, OMPPrivateClause)
OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
OPENMP_CLAUSE(shared, OMPSharedClause)
+OPENMP_CLAUSE(linear, OMPLinearClause)
OPENMP_CLAUSE(copyin, OMPCopyinClause)
+OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
OPENMP_PARALLEL_CLAUSE(num_threads)
OPENMP_PARALLEL_CLAUSE(default)
+OPENMP_PARALLEL_CLAUSE(proc_bind)
OPENMP_PARALLEL_CLAUSE(private)
OPENMP_PARALLEL_CLAUSE(firstprivate)
OPENMP_PARALLEL_CLAUSE(shared)
@@ -55,12 +62,20 @@
// FIXME: more clauses allowed for directive 'omp simd'.
OPENMP_SIMD_CLAUSE(private)
+OPENMP_SIMD_CLAUSE(linear)
OPENMP_SIMD_CLAUSE(safelen)
+OPENMP_SIMD_CLAUSE(collapse)
// Static attributes for 'default' clause.
OPENMP_DEFAULT_KIND(none)
OPENMP_DEFAULT_KIND(shared)
+// Static attributes for 'proc_bind' clause.
+OPENMP_PROC_BIND_KIND(master)
+OPENMP_PROC_BIND_KIND(close)
+OPENMP_PROC_BIND_KIND(spread)
+
+#undef OPENMP_PROC_BIND_KIND
#undef OPENMP_DEFAULT_KIND
#undef OPENMP_DIRECTIVE
#undef OPENMP_CLAUSE
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index 5b45731..2ee246e 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -21,30 +21,35 @@
/// \brief OpenMP directives.
enum OpenMPDirectiveKind {
- OMPD_unknown = 0,
#define OPENMP_DIRECTIVE(Name) \
OMPD_##Name,
#include "clang/Basic/OpenMPKinds.def"
- NUM_OPENMP_DIRECTIVES
+ OMPD_unknown
};
/// \brief OpenMP clauses.
enum OpenMPClauseKind {
- OMPC_unknown = 0,
#define OPENMP_CLAUSE(Name, Class) \
OMPC_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPC_threadprivate,
- NUM_OPENMP_CLAUSES
+ OMPC_unknown
};
/// \brief OpenMP attributes for 'default' clause.
enum OpenMPDefaultClauseKind {
- OMPC_DEFAULT_unknown = 0,
#define OPENMP_DEFAULT_KIND(Name) \
OMPC_DEFAULT_##Name,
#include "clang/Basic/OpenMPKinds.def"
- NUM_OPENMP_DEFAULT_KINDS
+ OMPC_DEFAULT_unknown
+};
+
+/// \brief OpenMP attributes for 'proc_bind' clause.
+enum OpenMPProcBindClauseKind {
+#define OPENMP_PROC_BIND_KIND(Name) \
+ OMPC_PROC_BIND_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_PROC_BIND_unknown
};
OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h
index 2ceab9c..d3b70c2 100644
--- a/include/clang/Basic/OperatorKinds.h
+++ b/include/clang/Basic/OperatorKinds.h
@@ -19,7 +19,7 @@
/// \brief Enumeration specifying the different kinds of C++ overloaded
/// operators.
-enum OverloadedOperatorKind {
+enum OverloadedOperatorKind : int {
OO_None, ///< Not an overloaded operator
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
OO_##Name,
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 314b9ef..8ae3b22 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -36,7 +36,7 @@
};
struct Storage {
- Storage() : NumDiagArgs(0), NumDiagRanges(0) { }
+ Storage() : NumDiagArgs(0) { }
enum {
/// \brief The maximum number of arguments we can hold. We
@@ -50,9 +50,6 @@
/// \brief The number of entries in Arguments.
unsigned char NumDiagArgs;
- /// \brief This is the number of ranges in the DiagRanges array.
- unsigned char NumDiagRanges;
-
/// \brief Specifies for each argument whether it is in DiagArgumentsStr
/// or in DiagArguments.
unsigned char DiagArgumentsKind[MaxArguments];
@@ -69,9 +66,7 @@
std::string DiagArgumentsStr[MaxArguments];
/// \brief The list of ranges added to this diagnostic.
- ///
- /// It currently only support 10 ranges, could easily be extended if needed.
- CharSourceRange DiagRanges[10];
+ SmallVector<CharSourceRange, 8> DiagRanges;
/// \brief If valid, provides a hint with some code to insert, remove, or
/// modify at a particular position.
@@ -97,7 +92,7 @@
Storage *Result = FreeList[--NumFreeListEntries];
Result->NumDiagArgs = 0;
- Result->NumDiagRanges = 0;
+ Result->DiagRanges.clear();
Result->FixItHints.clear();
return Result;
}
@@ -159,17 +154,14 @@
Allocator->Deallocate(DiagStorage);
else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
delete DiagStorage;
- DiagStorage = 0;
+ DiagStorage = nullptr;
}
void AddSourceRange(const CharSourceRange &R) const {
if (!DiagStorage)
DiagStorage = getStorage();
- assert(DiagStorage->NumDiagRanges <
- llvm::array_lengthof(DiagStorage->DiagRanges) &&
- "Too many arguments to diagnostic!");
- DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R;
+ DiagStorage->DiagRanges.push_back(R);
}
void AddFixItHint(const FixItHint &Hint) const {
@@ -187,13 +179,13 @@
/// \brief Create a null partial diagnostic, which cannot carry a payload,
/// and only exists to be swapped with a real partial diagnostic.
PartialDiagnostic(NullDiagnostic)
- : DiagID(0), DiagStorage(0), Allocator(0) { }
+ : DiagID(0), DiagStorage(nullptr), Allocator(nullptr) { }
PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
- : DiagID(DiagID), DiagStorage(0), Allocator(&Allocator) { }
+ : DiagID(DiagID), DiagStorage(nullptr), Allocator(&Allocator) { }
PartialDiagnostic(const PartialDiagnostic &Other)
- : DiagID(Other.DiagID), DiagStorage(0), Allocator(Other.Allocator)
+ : DiagID(Other.DiagID), DiagStorage(nullptr), Allocator(Other.Allocator)
{
if (Other.DiagStorage) {
DiagStorage = getStorage();
@@ -204,7 +196,7 @@
PartialDiagnostic(PartialDiagnostic &&Other)
: DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
Allocator(Other.Allocator) {
- Other.DiagStorage = 0;
+ Other.DiagStorage = nullptr;
}
PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
@@ -216,7 +208,7 @@
}
PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator)
- : DiagID(Other.getID()), DiagStorage(0), Allocator(&Allocator)
+ : DiagID(Other.getID()), DiagStorage(nullptr), Allocator(&Allocator)
{
// Copy arguments.
for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) {
@@ -256,7 +248,7 @@
DiagStorage = Other.DiagStorage;
Allocator = Other.Allocator;
- Other.DiagStorage = 0;
+ Other.DiagStorage = nullptr;
return *this;
}
@@ -308,12 +300,12 @@
}
// Add all ranges.
- for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i)
- DB.AddSourceRange(DiagStorage->DiagRanges[i]);
+ for (const CharSourceRange &Range : DiagStorage->DiagRanges)
+ DB.AddSourceRange(Range);
// Add all fix-its.
- for (unsigned i = 0, e = DiagStorage->FixItHints.size(); i != e; ++i)
- DB.AddFixItHint(DiagStorage->FixItHints[i]);
+ for (const FixItHint &Fix : DiagStorage->FixItHints)
+ DB.AddFixItHint(Fix);
}
void EmitToString(DiagnosticsEngine &Diags,
@@ -335,7 +327,7 @@
freeStorage();
}
- bool hasStorage() const { return DiagStorage != 0; }
+ bool hasStorage() const { return DiagStorage != nullptr; }
friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
unsigned I) {
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 01ca9a5..7b637d7 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -268,7 +268,7 @@
const SourceManager *SrcMgr;
public:
/// \brief Creates a FullSourceLoc where isValid() returns \c false.
- explicit FullSourceLoc() : SrcMgr(0) {}
+ explicit FullSourceLoc() : SrcMgr(nullptr) {}
explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
@@ -284,19 +284,19 @@
FullSourceLoc getExpansionLoc() const;
FullSourceLoc getSpellingLoc() const;
- unsigned getExpansionLineNumber(bool *Invalid = 0) const;
- unsigned getExpansionColumnNumber(bool *Invalid = 0) const;
+ unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
+ unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
- unsigned getSpellingLineNumber(bool *Invalid = 0) const;
- unsigned getSpellingColumnNumber(bool *Invalid = 0) const;
+ unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
+ unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
- const char *getCharacterData(bool *Invalid = 0) const;
+ const char *getCharacterData(bool *Invalid = nullptr) const;
- const llvm::MemoryBuffer* getBuffer(bool *Invalid = 0) const;
+ const llvm::MemoryBuffer* getBuffer(bool *Invalid = nullptr) const;
/// \brief Return a StringRef to the source buffer data for the
/// specified FileID.
- StringRef getBufferData(bool *Invalid = 0) const;
+ StringRef getBufferData(bool *Invalid = nullptr) const;
/// \brief Decompose the specified location into a raw FileID + Offset pair.
///
@@ -358,7 +358,7 @@
unsigned Line, Col;
SourceLocation IncludeLoc;
public:
- PresumedLoc() : Filename(0) {}
+ PresumedLoc() : Filename(nullptr) {}
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
}
@@ -367,8 +367,8 @@
///
/// This occurs when created with invalid source locations or when walking
/// off the top of a \#include stack.
- bool isInvalid() const { return Filename == 0; }
- bool isValid() const { return Filename != 0; }
+ bool isInvalid() const { return Filename == nullptr; }
+ bool isValid() const { return Filename != nullptr; }
/// \brief Return the presumed filename of this location.
///
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index c2130ac..bea4890 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -44,6 +44,7 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -89,6 +90,15 @@
DoNotFreeFlag = 0x02
};
+ // Note that the first member of this class is an aligned character buffer
+ // to ensure that this class has an alignment of 8 bytes. This wastes
+ // 8 bytes for every ContentCache object, but each of these corresponds to
+ // a file loaded into memory, so the 8 bytes doesn't seem terribly
+ // important. It is quite awkward to fit this aligner into any other part
+ // of the class due to the lack of portable ways to combine it with other
+ // members.
+ llvm::AlignedCharArray<8, 1> NonceAligner;
+
/// \brief The actual buffer containing the characters from the input
/// file.
///
@@ -133,14 +143,16 @@
/// file considered as a system one.
unsigned IsSystemFile : 1;
- ContentCache(const FileEntry *Ent = 0)
- : Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent),
- SourceLineCache(0), NumLines(0), BufferOverridden(false),
- IsSystemFile(false) {}
+ ContentCache(const FileEntry *Ent = nullptr)
+ : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(Ent),
+ SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
+ IsSystemFile(false) {
+ (void)NonceAligner; // Silence warnings about unused member.
+ }
ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
- : Buffer(0, false), OrigEntry(Ent), ContentsEntry(contentEnt),
- SourceLineCache(0), NumLines(0), BufferOverridden(false),
+ : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt),
+ SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
IsSystemFile(false) {}
~ContentCache();
@@ -149,15 +161,15 @@
/// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
/// is not transferred, so this is a logical error.
ContentCache(const ContentCache &RHS)
- : Buffer(0, false), SourceLineCache(0), BufferOverridden(false),
- IsSystemFile(false)
- {
+ : Buffer(nullptr, false), SourceLineCache(nullptr),
+ BufferOverridden(false), IsSystemFile(false) {
OrigEntry = RHS.OrigEntry;
ContentsEntry = RHS.ContentsEntry;
-
- assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 &&
- "Passed ContentCache object cannot own a buffer.");
-
+
+ assert(RHS.Buffer.getPointer() == nullptr &&
+ RHS.SourceLineCache == nullptr &&
+ "Passed ContentCache object cannot own a buffer.");
+
NumLines = RHS.NumLines;
}
@@ -173,7 +185,7 @@
const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
const SourceManager &SM,
SourceLocation Loc = SourceLocation(),
- bool *Invalid = 0) const;
+ bool *Invalid = nullptr) const;
/// \brief Returns the size of the content encapsulated by this
/// ContentCache.
@@ -224,6 +236,11 @@
ContentCache &operator=(const ContentCache& RHS) LLVM_DELETED_FUNCTION;
};
+ // Assert that the \c ContentCache objects will always be 8-byte aligned so
+ // that we can pack 3 bits of integer into pointers to such objects.
+ static_assert(llvm::AlignOf<ContentCache>::Alignment >= 8,
+ "ContentCache must be 8-byte aligned.");
+
/// \brief Information about a FileID, basically just the logical file
/// that it represents and include stack information.
///
@@ -729,18 +746,6 @@
StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc));
}
- /// \brief Create the FileID for a memory buffer that will represent the
- /// FileID for the main source.
- ///
- /// One example of when this would be used is when the main source is read
- /// from STDIN.
- FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
- SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) {
- assert(MainFileID.isInvalid() && "MainFileID already set!");
- MainFileID = createFileIDForMemBuffer(Buffer, Kind);
- return MainFileID;
- }
-
//===--------------------------------------------------------------------===//
// MainFileID creation and querying methods.
//===--------------------------------------------------------------------===//
@@ -748,14 +753,6 @@
/// \brief Returns the FileID of the main source file.
FileID getMainFileID() const { return MainFileID; }
- /// \brief Create the FileID for the main source file.
- FileID createMainFileID(const FileEntry *SourceFile,
- SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) {
- assert(MainFileID.isInvalid() && "MainFileID already set!");
- MainFileID = createFileID(SourceFile, SourceLocation(), Kind);
- return MainFileID;
- }
-
/// \brief Set the file ID for the main source file.
void setMainFileID(FileID FID) {
assert(MainFileID.isInvalid() && "MainFileID already set!");
@@ -793,10 +790,10 @@
///
/// This does no caching of the buffer and takes ownership of the
/// MemoryBuffer, so only pass a MemoryBuffer to this once.
- FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
+ FileID createFileID(const llvm::MemoryBuffer *Buffer,
SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
- int LoadedID = 0, unsigned LoadedOffset = 0,
- SourceLocation IncludeLoc = SourceLocation()) {
+ int LoadedID = 0, unsigned LoadedOffset = 0,
+ SourceLocation IncludeLoc = SourceLocation()) {
return createFileID(createMemBufferContentCache(Buffer), IncludeLoc,
FileCharacter, LoadedID, LoadedOffset);
}
@@ -824,7 +821,7 @@
/// \param Invalid If non-NULL, will be set \c true if an error
/// occurs while retrieving the memory buffer.
const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
- bool *Invalid = 0);
+ bool *Invalid = nullptr);
/// \brief Override the contents of the given source file by providing an
/// already-allocated buffer.
@@ -876,7 +873,7 @@
/// If there is an error opening this buffer the first time, this
/// manufactures a temporary buffer and returns a non-empty error string.
const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
- bool *Invalid = 0) const {
+ bool *Invalid = nullptr) const {
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
if (MyInvalid || !Entry.isFile()) {
@@ -890,7 +887,8 @@
Invalid);
}
- const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
+ const llvm::MemoryBuffer *getBuffer(FileID FID,
+ bool *Invalid = nullptr) const {
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
if (MyInvalid || !Entry.isFile()) {
@@ -910,11 +908,11 @@
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
if (MyInvalid || !Entry.isFile())
- return 0;
+ return nullptr;
const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache();
if (!Content)
- return 0;
+ return nullptr;
return Content->OrigEntry;
}
@@ -923,7 +921,7 @@
{
const SrcMgr::ContentCache *Content = sloc.getFile().getContentCache();
if (!Content)
- return 0;
+ return nullptr;
return Content->OrigEntry;
}
@@ -932,7 +930,7 @@
///
/// \param FID The file ID whose contents will be returned.
/// \param Invalid If non-NULL, will be set true if an error occurred.
- StringRef getBufferData(FileID FID, bool *Invalid = 0) const;
+ StringRef getBufferData(FileID FID, bool *Invalid = nullptr) const;
/// \brief Get the number of FileIDs (files and macros) that were created
/// during preprocessing of \p FID, including it.
@@ -1167,15 +1165,16 @@
/// \param MacroBegin If non-null and function returns true, it is set to the
/// begin location of the immediate macro expansion.
bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc,
- SourceLocation *MacroBegin = 0) const;
+ SourceLocation *MacroBegin = nullptr) const;
/// \brief Returns true if the given MacroID location points at the character
/// end of the immediate macro expansion.
///
/// \param MacroEnd If non-null and function returns true, it is set to the
/// character end location of the immediate macro expansion.
- bool isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
- SourceLocation *MacroEnd = 0) const;
+ bool
+ isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
+ SourceLocation *MacroEnd = nullptr) const;
/// \brief Returns true if \p Loc is inside the [\p Start, +\p Length)
/// chunk of the source location address space.
@@ -1184,7 +1183,7 @@
/// relative offset of \p Loc inside the chunk.
bool isInSLocAddrSpace(SourceLocation Loc,
SourceLocation Start, unsigned Length,
- unsigned *RelativeOffset = 0) const {
+ unsigned *RelativeOffset = nullptr) const {
assert(((Start.getOffset() < NextLocalOffset &&
Start.getOffset()+Length <= NextLocalOffset) ||
(Start.getOffset() >= CurrentLoadedOffset &&
@@ -1230,7 +1229,8 @@
/// in the appropriate spelling MemoryBuffer.
///
/// \param Invalid If non-NULL, will be set \c true if an error occurs.
- const char *getCharacterData(SourceLocation SL, bool *Invalid = 0) const;
+ const char *getCharacterData(SourceLocation SL,
+ bool *Invalid = nullptr) const;
/// \brief Return the column # for the specified file position.
///
@@ -1239,12 +1239,13 @@
/// on a file sloc, so you must choose a spelling or expansion location
/// before calling this method.
unsigned getColumnNumber(FileID FID, unsigned FilePos,
- bool *Invalid = 0) const;
- unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid = 0) const;
+ bool *Invalid = nullptr) const;
+ unsigned getSpellingColumnNumber(SourceLocation Loc,
+ bool *Invalid = nullptr) const;
unsigned getExpansionColumnNumber(SourceLocation Loc,
- bool *Invalid = 0) const;
- unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid = 0) const;
-
+ bool *Invalid = nullptr) const;
+ unsigned getPresumedColumnNumber(SourceLocation Loc,
+ bool *Invalid = nullptr) const;
/// \brief Given a SourceLocation, return the spelling line number
/// for the position indicated.
@@ -1252,17 +1253,17 @@
/// This requires building and caching a table of line offsets for the
/// MemoryBuffer, so this is not cheap: use only when about to emit a
/// diagnostic.
- unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const;
- unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
- unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
- unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
+ unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = nullptr) const;
+ unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+ unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+ unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
/// \brief Return the filename or buffer identifier of the buffer the
/// location is in.
///
/// Note that this name does not respect \#line directives. Use
/// getPresumedLoc for normal clients.
- const char *getBufferName(SourceLocation Loc, bool *Invalid = 0) const;
+ const char *getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
/// \brief Return the file characteristic of the specified source
/// location, indicating whether this is a normal file, a system
@@ -1339,7 +1340,7 @@
/// FileID chunk and sets relative offset (offset of \p Loc from beginning
/// of FileID) to \p relativeOffset.
bool isInFileID(SourceLocation Loc, FileID FID,
- unsigned *RelativeOffset = 0) const {
+ unsigned *RelativeOffset = nullptr) const {
unsigned Offs = Loc.getOffset();
if (isOffsetInFileID(FID, Offs)) {
if (RelativeOffset)
@@ -1368,7 +1369,7 @@
bool IsSystemHeader, bool IsExternCHeader);
/// \brief Determine if the source manager has a line table.
- bool hasLineTable() const { return LineTable != 0; }
+ bool hasLineTable() const { return LineTable != nullptr; }
/// \brief Retrieve the stored line table.
LineTableInfo &getLineTable();
@@ -1475,7 +1476,7 @@
/// \brief Get a local SLocEntry. This is exposed for indexing.
const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index,
- bool *Invalid = 0) const {
+ bool *Invalid = nullptr) const {
assert(Index < LocalSLocEntryTable.size() && "Invalid index");
return LocalSLocEntryTable[Index];
}
@@ -1485,14 +1486,15 @@
/// \brief Get a loaded SLocEntry. This is exposed for indexing.
const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index,
- bool *Invalid = 0) const {
+ bool *Invalid = nullptr) const {
assert(Index < LoadedSLocEntryTable.size() && "Invalid index");
if (SLocEntryLoaded[Index])
return LoadedSLocEntryTable[Index];
return loadSLocEntry(Index, Invalid);
}
- const SrcMgr::SLocEntry &getSLocEntry(FileID FID, bool *Invalid = 0) const {
+ const SrcMgr::SLocEntry &getSLocEntry(FileID FID,
+ bool *Invalid = nullptr) const {
if (FID.ID == 0 || FID.ID == -1) {
if (Invalid) *Invalid = true;
return LocalSLocEntryTable[0];
@@ -1561,15 +1563,16 @@
const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
/// \brief Get the entry with the given unwrapped FileID.
- const SrcMgr::SLocEntry &getSLocEntryByID(int ID, bool *Invalid = 0) const {
+ const SrcMgr::SLocEntry &getSLocEntryByID(int ID,
+ bool *Invalid = nullptr) const {
assert(ID != -1 && "Using FileID sentinel value");
if (ID < 0)
return getLoadedSLocEntryByID(ID, Invalid);
return getLocalSLocEntry(static_cast<unsigned>(ID), Invalid);
}
- const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID,
- bool *Invalid = 0) const {
+ const SrcMgr::SLocEntry &
+ getLoadedSLocEntryByID(int ID, bool *Invalid = nullptr) const {
return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2), Invalid);
}
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index e6cc9ab..953f6bd 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -30,16 +30,6 @@
};
}
- /// \brief AArch64 builtins
- namespace AArch64 {
- enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
- LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
-#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsAArch64.def"
- LastTSBuiltin
- };
- }
/// \brief ARM builtins
namespace ARM {
enum {
@@ -51,13 +41,13 @@
};
}
- /// \brief ARM64 builtins
- namespace ARM64 {
+ /// \brief AArch64 builtins
+ namespace AArch64 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
- #include "clang/Basic/BuiltinsARM64.def"
+ #include "clang/Basic/BuiltinsAArch64.def"
LastTSBuiltin
};
}
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 24a6fa6..29de915 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -283,7 +283,7 @@
unsigned getLongLongAlign() const { return LongLongAlign; }
/// \brief Determine whether the __int128 type is supported on this target.
- bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME
+ virtual bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME
/// \brief Return the alignment that is suitable for storing any
/// object with a fundamental alignment requirement.
@@ -735,7 +735,7 @@
/// \brief Return the section to use for C++ static initialization functions.
virtual const char *getStaticInitSectionSpecifier() const {
- return 0;
+ return nullptr;
}
const LangAS::Map &getAddressSpaceMap() const {
@@ -801,7 +801,7 @@
unsigned &NumAliases) const = 0;
virtual void getGCCAddlRegNames(const AddlRegName *&Addl,
unsigned &NumAddl) const {
- Addl = 0;
+ Addl = nullptr;
NumAddl = 0;
}
virtual bool validateAsmConstraint(const char *&Name,
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 42ebcf8..845a8b0 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -365,6 +365,7 @@
// MS Extensions
KEYWORD(__FUNCDNAME__ , KEYMS)
+KEYWORD(__FUNCSIG__ , KEYMS)
KEYWORD(L__FUNCTION__ , KEYMS)
TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS)
TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
@@ -684,6 +685,11 @@
// handles them.
ANNOTATION(pragma_ms_vtordisp)
+// Annotation for all microsoft #pragmas...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_pragma)
+
// Annotation for #pragma OPENCL EXTENSION...
// The lexer produces these so that they only take effect when the parser
// handles them.
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
index 5595e14..0a99496 100644
--- a/include/clang/Basic/VirtualFileSystem.h
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -15,8 +15,10 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
namespace llvm {
@@ -38,6 +40,9 @@
llvm::sys::fs::perms Perms;
public:
+ bool IsVFSMapped; // FIXME: remove when files support multiple names
+
+public:
Status() : Type(llvm::sys::fs::file_type::status_error) {}
Status(const llvm::sys::fs::file_status &Status);
Status(StringRef Name, StringRef RealName, llvm::sys::fs::UniqueID UID,
@@ -86,7 +91,8 @@
/// \brief Get the contents of the file as a \p MemoryBuffer.
virtual llvm::error_code
getBuffer(const Twine &Name, std::unique_ptr<llvm::MemoryBuffer> &Result,
- int64_t FileSize = -1, bool RequiresNullTerminator = true) = 0;
+ int64_t FileSize = -1, bool RequiresNullTerminator = true,
+ bool IsVolatile = false) = 0;
/// \brief Closes the file.
virtual llvm::error_code close() = 0;
/// \brief Sets the name to use for this file.
@@ -109,7 +115,8 @@
llvm::error_code getBufferForFile(const Twine &Name,
std::unique_ptr<llvm::MemoryBuffer> &Result,
int64_t FileSize = -1,
- bool RequiresNullTerminator = true);
+ bool RequiresNullTerminator = true,
+ bool IsVolatile = false);
};
/// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by
@@ -161,9 +168,29 @@
IntrusiveRefCntPtr<FileSystem>
getVFSFromYAML(llvm::MemoryBuffer *Buffer,
llvm::SourceMgr::DiagHandlerTy DiagHandler,
- void *DiagContext = 0,
+ void *DiagContext = nullptr,
IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
+struct YAMLVFSEntry {
+ template <typename T1, typename T2> YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
+ : VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)) {}
+ std::string VPath;
+ std::string RPath;
+};
+
+class YAMLVFSWriter {
+ std::vector<YAMLVFSEntry> Mappings;
+ Optional<bool> IsCaseSensitive;
+
+public:
+ YAMLVFSWriter() {}
+ void addFileMapping(StringRef VirtualPath, StringRef RealPath);
+ void setCaseSensitivity(bool CaseSensitive) {
+ IsCaseSensitive = CaseSensitive;
+ }
+ void write(llvm::raw_ostream &OS);
+};
+
} // end namespace vfs
} // end namespace clang
#endif // LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index e4a9272..449827e 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -35,7 +35,7 @@
/// specific C type should be passed to or returned from a function.
class ABIArgInfo {
public:
- enum Kind {
+ enum Kind : uint8_t {
/// Direct - Pass the argument directly using the normal converted LLVM
/// type, or by coercing to another specified type stored in
/// 'CoerceToType'). If an offset is specified (in UIntData), then the
@@ -68,65 +68,92 @@
/// type, it means the value is returned indirectly via an implicit sret
/// parameter stored in the argument struct.
InAlloca,
-
KindFirst = Direct,
KindLast = InAlloca
};
private:
- Kind TheKind;
- llvm::Type *TypeData;
+ llvm::Type *TypeData; // isDirect() || isExtend()
llvm::Type *PaddingType;
- unsigned UIntData;
- bool BoolData0;
- bool BoolData1;
- bool InReg;
- bool PaddingInReg;
+ union {
+ unsigned DirectOffset; // isDirect() || isExtend()
+ unsigned IndirectAlign; // isIndirect()
+ unsigned AllocaFieldIndex; // isInAlloca()
+ };
+ Kind TheKind;
+ bool PaddingInReg : 1;
+ bool InAllocaSRet : 1; // isInAlloca()
+ bool IndirectByVal : 1; // isIndirect()
+ bool IndirectRealign : 1; // isIndirect()
+ bool SRetAfterThis : 1; // isIndirect()
+ bool InReg : 1; // isDirect() || isExtend() || isIndirect()
- ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR,
- bool PIR, llvm::Type* P)
- : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0),
- BoolData1(B1), InReg(IR), PaddingInReg(PIR) {}
+ ABIArgInfo(Kind K)
+ : PaddingType(nullptr), TheKind(K), PaddingInReg(false), InReg(false) {}
public:
- ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
+ ABIArgInfo()
+ : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
+ TheKind(Direct), PaddingInReg(false), InReg(false) {}
- static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0,
- llvm::Type *Padding = 0) {
- return ABIArgInfo(Direct, T, Offset, false, false, false, false, Padding);
+ static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
+ llvm::Type *Padding = nullptr) {
+ auto AI = ABIArgInfo(Direct);
+ AI.setCoerceToType(T);
+ AI.setDirectOffset(Offset);
+ AI.setPaddingType(Padding);
+ return AI;
}
- static ABIArgInfo getDirectInReg(llvm::Type *T = 0) {
- return ABIArgInfo(Direct, T, 0, false, false, true, false, 0);
+ static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
+ auto AI = getDirect(T);
+ AI.setInReg(true);
+ return AI;
}
- static ABIArgInfo getExtend(llvm::Type *T = 0) {
- return ABIArgInfo(Extend, T, 0, false, false, false, false, 0);
+ static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
+ auto AI = ABIArgInfo(Extend);
+ AI.setCoerceToType(T);
+ AI.setDirectOffset(0);
+ return AI;
}
- static ABIArgInfo getExtendInReg(llvm::Type *T = 0) {
- return ABIArgInfo(Extend, T, 0, false, false, true, false, 0);
+ static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
+ auto AI = getExtend(T);
+ AI.setInReg(true);
+ return AI;
}
static ABIArgInfo getIgnore() {
- return ABIArgInfo(Ignore, 0, 0, false, false, false, false, 0);
+ return ABIArgInfo(Ignore);
}
- static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true
- , bool Realign = false
- , llvm::Type *Padding = 0) {
- return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false,
- Padding);
+ static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true,
+ bool Realign = false,
+ llvm::Type *Padding = nullptr) {
+ auto AI = ABIArgInfo(Indirect);
+ AI.setIndirectAlign(Alignment);
+ AI.setIndirectByVal(ByVal);
+ AI.setIndirectRealign(Realign);
+ AI.setSRetAfterThis(false);
+ AI.setPaddingType(Padding);
+ return AI;
+ }
+ static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true,
+ bool Realign = false) {
+ auto AI = getIndirect(Alignment, ByVal, Realign);
+ AI.setInReg(true);
+ return AI;
}
static ABIArgInfo getInAlloca(unsigned FieldIndex) {
- return ABIArgInfo(InAlloca, 0, FieldIndex, false, false, false, false, 0);
- }
- static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true
- , bool Realign = false) {
- return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, false, 0);
+ auto AI = ABIArgInfo(InAlloca);
+ AI.setInAllocaFieldIndex(FieldIndex);
+ return AI;
}
static ABIArgInfo getExpand() {
- return ABIArgInfo(Expand, 0, 0, false, false, false, false, 0);
+ return ABIArgInfo(Expand);
}
static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
llvm::Type *Padding) {
- return ABIArgInfo(Expand, 0, 0, false, false, false, PaddingInReg,
- Padding);
+ auto AI = getExpand();
+ AI.setPaddingInReg(PaddingInReg);
+ AI.setPaddingType(Padding);
+ return AI;
}
Kind getKind() const { return TheKind; }
@@ -137,23 +164,28 @@
bool isIndirect() const { return TheKind == Indirect; }
bool isExpand() const { return TheKind == Expand; }
- bool canHaveCoerceToType() const {
- return TheKind == Direct || TheKind == Extend;
- }
+ bool canHaveCoerceToType() const { return isDirect() || isExtend(); }
// Direct/Extend accessors
unsigned getDirectOffset() const {
assert((isDirect() || isExtend()) && "Not a direct or extend kind");
- return UIntData;
+ return DirectOffset;
+ }
+ void setDirectOffset(unsigned Offset) {
+ assert((isDirect() || isExtend()) && "Not a direct or extend kind");
+ DirectOffset = Offset;
}
- llvm::Type *getPaddingType() const {
- return PaddingType;
- }
+ llvm::Type *getPaddingType() const { return PaddingType; }
+
+ void setPaddingType(llvm::Type *T) { PaddingType = T; }
bool getPaddingInReg() const {
return PaddingInReg;
}
+ void setPaddingInReg(bool PIR) {
+ PaddingInReg = PIR;
+ }
llvm::Type *getCoerceToType() const {
assert(canHaveCoerceToType() && "Invalid kind!");
@@ -170,37 +202,67 @@
return InReg;
}
+ void setInReg(bool IR) {
+ assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
+ InReg = IR;
+ }
+
// Indirect accessors
unsigned getIndirectAlign() const {
- assert(TheKind == Indirect && "Invalid kind!");
- return UIntData;
+ assert(isIndirect() && "Invalid kind!");
+ return IndirectAlign;
+ }
+ void setIndirectAlign(unsigned IA) {
+ assert(isIndirect() && "Invalid kind!");
+ IndirectAlign = IA;
}
bool getIndirectByVal() const {
- assert(TheKind == Indirect && "Invalid kind!");
- return BoolData0;
+ assert(isIndirect() && "Invalid kind!");
+ return IndirectByVal;
+ }
+ void setIndirectByVal(unsigned IBV) {
+ assert(isIndirect() && "Invalid kind!");
+ IndirectByVal = IBV;
}
bool getIndirectRealign() const {
- assert(TheKind == Indirect && "Invalid kind!");
- return BoolData1;
+ assert(isIndirect() && "Invalid kind!");
+ return IndirectRealign;
+ }
+ void setIndirectRealign(bool IR) {
+ assert(isIndirect() && "Invalid kind!");
+ IndirectRealign = IR;
+ }
+
+ bool isSRetAfterThis() const {
+ assert(isIndirect() && "Invalid kind!");
+ return SRetAfterThis;
+ }
+ void setSRetAfterThis(bool AfterThis) {
+ assert(isIndirect() && "Invalid kind!");
+ SRetAfterThis = AfterThis;
}
unsigned getInAllocaFieldIndex() const {
- assert(TheKind == InAlloca && "Invalid kind!");
- return UIntData;
+ assert(isInAlloca() && "Invalid kind!");
+ return AllocaFieldIndex;
+ }
+ void setInAllocaFieldIndex(unsigned FieldIndex) {
+ assert(isInAlloca() && "Invalid kind!");
+ AllocaFieldIndex = FieldIndex;
}
/// \brief Return true if this field of an inalloca struct should be returned
/// to implement a struct return calling convention.
bool getInAllocaSRet() const {
- assert(TheKind == InAlloca && "Invalid kind!");
- return BoolData0;
+ assert(isInAlloca() && "Invalid kind!");
+ return InAllocaSRet;
}
void setInAllocaSRet(bool SRet) {
- assert(TheKind == InAlloca && "Invalid kind!");
- BoolData0 = SRet;
+ assert(isInAlloca() && "Invalid kind!");
+ InAllocaSRet = SRet;
}
void dump() const;
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
index 2300d29..37819c7 100644
--- a/include/clang/CodeGen/CodeGenAction.h
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -33,7 +33,7 @@
/// Create a new code generation action. If the optional \p _VMContext
/// parameter is supplied, the action uses it without taking ownership,
/// otherwise it creates a fresh LLVM context and takes ownership.
- CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = 0);
+ CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = nullptr);
bool hasIRSupport() const override;
@@ -65,37 +65,37 @@
class EmitAssemblyAction : public CodeGenAction {
virtual void anchor();
public:
- EmitAssemblyAction(llvm::LLVMContext *_VMContext = 0);
+ EmitAssemblyAction(llvm::LLVMContext *_VMContext = nullptr);
};
class EmitBCAction : public CodeGenAction {
virtual void anchor();
public:
- EmitBCAction(llvm::LLVMContext *_VMContext = 0);
+ EmitBCAction(llvm::LLVMContext *_VMContext = nullptr);
};
class EmitLLVMAction : public CodeGenAction {
virtual void anchor();
public:
- EmitLLVMAction(llvm::LLVMContext *_VMContext = 0);
+ EmitLLVMAction(llvm::LLVMContext *_VMContext = nullptr);
};
class EmitLLVMOnlyAction : public CodeGenAction {
virtual void anchor();
public:
- EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = 0);
+ EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
};
class EmitCodeGenOnlyAction : public CodeGenAction {
virtual void anchor();
public:
- EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = 0);
+ EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
};
class EmitObjAction : public CodeGenAction {
virtual void anchor();
public:
- EmitObjAction(llvm::LLVMContext *_VMContext = 0);
+ EmitObjAction(llvm::LLVMContext *_VMContext = nullptr);
};
}
diff --git a/include/clang/Driver/CC1AsOptions.td b/include/clang/Driver/CC1AsOptions.td
index 3e130d0..34d6084 100644
--- a/include/clang/Driver/CC1AsOptions.td
+++ b/include/clang/Driver/CC1AsOptions.td
@@ -88,6 +88,13 @@
def g : Flag<["-"], "g">, HelpText<"Generate source level debug information">;
+def gdwarf_2 : Flag<["-"], "gdwarf-2">,
+ HelpText<"Generate source level debug information with dwarf version 2">;
+def gdwarf_3 : Flag<["-"], "gdwarf-3">,
+ HelpText<"Generate source level debug information with dwarf version 3">;
+def gdwarf_4 : Flag<["-"], "gdwarf-4">,
+ HelpText<"Generate source level debug information with dwarf version 4">;
+
def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
HelpText<"The compilation directory to embed in the debug info.">;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index e84a20b..b33198d 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -314,6 +314,8 @@
HelpText<"Include name lookup table dumps in AST dumps">;
def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
HelpText<"Do not automatically generate or update the global module index">;
+def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">,
+ HelpText<"Do not automatically import modules for error recovery">;
let Group = Action_Group in {
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index d33e6b6..a4881e2 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -66,6 +66,10 @@
Alias<ffunction_sections>;
def _SLASH_Gy_ : CLFlag<"Gy-">, HelpText<"Don't put each function in its own section">,
Alias<fno_function_sections>;
+def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">,
+ Alias<fdata_sections>;
+def _SLASH_Gw_ : CLFlag<"Gw-">, HelpText<"Don't put each data item in its own section">,
+ Alias<fno_data_sections>;
def _SLASH_help : CLFlag<"help">, Alias<help>,
HelpText<"Display available options">;
def _SLASH_HELP : CLFlag<"HELP">, Alias<help>;
@@ -121,6 +125,8 @@
def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">,
Alias<W_Joined>, AliasArgs<["no-error"]>;
def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>;
+def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>,
+ AliasArgs<["no-macro-redefined"]>;
def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">,
Alias<vtordisp_mode_EQ>;
def _SLASH_Z7 : CLFlag<"Z7">, Alias<gline_tables_only>;
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 0448725..df974ad 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -188,12 +188,11 @@
// getFinalPhase - Determine which compilation mode we are in and record
// which option we used to determine the final phase.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
- llvm::opt::Arg **FinalPhaseArg = 0) const;
+ llvm::opt::Arg **FinalPhaseArg = nullptr) const;
public:
Driver(StringRef _ClangExecutable,
StringRef _DefaultTargetTriple,
- StringRef _DefaultImageName,
DiagnosticsEngine &_Diags);
~Driver();
@@ -259,7 +258,7 @@
/// \param Args - The input arguments.
/// \param Inputs - The list to store the resulting compilation
/// inputs onto.
- void BuildInputs(const ToolChain &TC, const llvm::opt::DerivedArgList &Args,
+ void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args,
InputList &Inputs) const;
/// BuildActions - Construct the list of actions to perform for the
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 33e058f..0e251aa 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -60,6 +60,7 @@
def M_Group : OptionGroup<"<M group>">, Group<CompileOnly_Group>;
def T_Group : OptionGroup<"<T group>">;
def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
+def R_Group : OptionGroup<"<R group>">, Group<CompileOnly_Group>;
def W_Group : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
def d_Group : OptionGroup<"<d group>">;
def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
@@ -253,7 +254,9 @@
def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>,
HelpText<"Don't emit warning for unused driver arguments">;
def Q : Flag<["-"], "Q">;
-def R : Flag<["-"], "R">;
+def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_Group>, Flags<[CC1Option]>,
+ HelpText<"Report transformations performed by optimization passes whose "
+ "name matches the given POSIX regular expression">;
def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
HelpText<"Only run preprocess and compilation steps">;
def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>;
@@ -438,8 +441,8 @@
HelpText<"Print a template comparison tree for differing templates">;
def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group<f_Group>,
HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>;
-def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<f_Group>;
-def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group<f_Group>, Flags<[CC1Option]>;
+def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
+def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
def fdwarf_directory_asm : Flag<["-"], "fdwarf-directory-asm">, Group<f_Group>;
def fno_dwarf_directory_asm : Flag<["-"], "fno-dwarf-directory-asm">, Group<f_Group>, Flags<[CC1Option]>;
def felide_constructors : Flag<["-"], "felide-constructors">, Group<f_Group>;
@@ -477,7 +480,7 @@
"undefined (miscellaneous undefined behavior)">;
def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>;
def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
+ Group<f_clang_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Path to blacklist file for sanitizers">;
def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
Group<f_clang_Group>,
@@ -580,6 +583,9 @@
def fmodules_prune_after : Joined<["-"], "fmodules-prune-after=">, Group<i_Group>,
Flags<[CC1Option]>, MetaVarName<"<seconds>">,
HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">;
+def fmodules_search_all : Flag <["-"], "fmodules-search-all">, Group<f_Group>,
+ Flags<[DriverOption, CC1Option]>,
+ HelpText<"Search even non-imported modules to resolve references">;
def fbuild_session_timestamp : Joined<["-"], "fbuild-session-timestamp=">,
Group<i_Group>, Flags<[CC1Option]>, MetaVarName<"<time since Epoch in seconds>">,
HelpText<"Time when the current build session started">;
@@ -607,6 +613,11 @@
def fmodules_decluse : Flag <["-"], "fmodules-decluse">, Group<f_Group>,
Flags<[DriverOption,CC1Option]>,
HelpText<"Require declaration of modules used within a module">;
+def fmodules_strict_decluse : Flag <["-"], "fmodules-strict-decluse">, Group<f_Group>,
+ Flags<[DriverOption,CC1Option]>,
+ HelpText<"Like -fmodules-decluse but requires all headers to be in modules">;
+def fno_modules_search_all : Flag <["-"], "fno-modules-search-all">, Group<f_Group>,
+ Flags<[DriverOption, CC1Option]>;
def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>;
def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>;
@@ -666,6 +677,8 @@
Flags<[DriverOption]>;
def fno_modules_decluse : Flag <["-"], "fno-modules-decluse">, Group<f_Group>,
Flags<[DriverOption]>;
+def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, Group<f_Group>,
+ Flags<[DriverOption]>;
def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>;
def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>;
def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>;
@@ -687,7 +700,8 @@
Flags<[CC1Option]>, HelpText<"Disable spell-checking">;
def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>,
HelpText<"Disable the use of stack protectors">;
-def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>;
+def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
+ Flags<[DriverOption, CoreOption]>;
def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
@@ -799,7 +813,8 @@
HelpText<"Limit debug information produced to reduce size of debug binary">;
def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Alias<fno_standalone_debug>;
def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Alias<fstandalone_debug>;
-def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>;
+def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>,
+ Flags<[DriverOption, CoreOption]>;
def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable optimizations based on the strict definition of an enum's "
"value range">;
@@ -977,8 +992,10 @@
def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>;
def lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>;
def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>;
-def EL : Flag<["-"], "EL">, Flags<[DriverOption]>;
-def EB : Flag<["-"], "EB">, Flags<[DriverOption]>;
+def mlittle_endian : Flag<["-"], "mlittle-endian">, Flags<[DriverOption]>;
+def EL : Flag<["-"], "EL">, Alias<mlittle_endian>;
+def mbig_endian : Flag<["-"], "mbig-endian">, Flags<[DriverOption]>;
+def EB : Flag<["-"], "EB">, Alias<mbig_endian>;
def m16 : Flag<["-"], "m16">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[DriverOption,CC1Option]>,
@@ -988,6 +1005,7 @@
def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
+def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
def mconstant_cfstrings : Flag<["-"], "mconstant-cfstrings">, Group<clang_ignored_m_Group>;
def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>;
@@ -1008,7 +1026,7 @@
def mkernel : Flag<["-"], "mkernel">, Group<m_Group>;
def mlinker_version_EQ : Joined<["-"], "mlinker-version=">,
Flags<[DriverOption]>;
-def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option]>,
+def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option, CoreOption]>,
HelpText<"Additional arguments to forward to LLVM's option processing">;
def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">, Group<m_Group>;
def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>,
@@ -1063,11 +1081,11 @@
def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>;
def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
- HelpText<"Allow memory accesses to be unaligned (ARM only)">;
+ HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_arm_Features_Group>,
- HelpText<"Force all memory accesses to be aligned (ARM only)">;
+ HelpText<"Force all memory accesses to be aligned (AArch32/AArch64 only)">;
def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>, Flags<[CC1Option,HelpHidden]>,
- HelpText<"Force all memory accesses to be aligned (ARM only, same as mno-unaligned-access)">;
+ HelpText<"Force all memory accesses to be aligned (AArch64 only, same as mno-unaligned-access)">;
def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>;
def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>,
HelpText<"Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.">;
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 953229c..f3db2c1 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -147,7 +147,7 @@
virtual llvm::opt::DerivedArgList *
TranslateArgs(const llvm::opt::DerivedArgList &Args,
const char *BoundArch) const {
- return 0;
+ return nullptr;
}
/// Choose a tool to use to handle the action \p JA.
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index d4f52d3..3209679 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -54,22 +54,22 @@
// C family input files to precompile.
TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", "p")
-TYPE("c-header", CHeader, PP_CHeader, 0, "pu")
-TYPE("cl-header", CLHeader, PP_CHeader, 0, "pu")
+TYPE("c-header", CHeader, PP_CHeader, nullptr, "pu")
+TYPE("cl-header", CLHeader, PP_CHeader, nullptr, "pu")
TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID, "mi", "p")
-TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, 0, "pu")
+TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, nullptr, "pu")
TYPE("c++-header-cpp-output", PP_CXXHeader, INVALID, "ii", "p")
-TYPE("c++-header", CXXHeader, PP_CXXHeader, 0, "pu")
+TYPE("c++-header", CXXHeader, PP_CXXHeader, nullptr, "pu")
TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
-TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, 0, "pu")
+TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, nullptr, "pu")
// Other languages.
-TYPE("ada", Ada, INVALID, 0, "u")
+TYPE("ada", Ada, INVALID, nullptr, "u")
TYPE("assembler", PP_Asm, INVALID, "s", "au")
TYPE("assembler-with-cpp", Asm, PP_Asm, "S", "au")
-TYPE("f95", PP_Fortran, INVALID, 0, "u")
-TYPE("f95-cpp-input", Fortran, PP_Fortran, 0, "u")
-TYPE("java", Java, INVALID, 0, "u")
+TYPE("f95", PP_Fortran, INVALID, nullptr, "u")
+TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, "u")
+TYPE("java", Java, INVALID, nullptr, "u")
// LLVM IR/LTO types. We define separate types for IR and LTO because LTO
// outputs should use the standard suffixes.
@@ -87,8 +87,8 @@
TYPE("remap", Remap, INVALID, "remap", "")
TYPE("precompiled-header", PCH, INVALID, "gch", "A")
TYPE("object", Object, INVALID, "o", "")
-TYPE("treelang", Treelang, INVALID, 0, "u")
+TYPE("treelang", Treelang, INVALID, nullptr, "u")
TYPE("image", Image, INVALID, "out", "")
TYPE("dSYM", dSYM, INVALID, "dSYM", "A")
TYPE("dependencies", Dependencies, INVALID, "d", "")
-TYPE("none", Nothing, INVALID, 0, "u")
+TYPE("none", Nothing, INVALID, nullptr, "u")
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
index 626b1dd..5cc5b9c 100644
--- a/include/clang/Edit/Commit.h
+++ b/include/clang/Edit/Commit.h
@@ -49,8 +49,7 @@
const LangOptions &LangOpts;
const PPConditionalDirectiveRecord *PPRec;
EditedSource *Editor;
-
- const bool ForceCommitInSystemHeader;
+
bool IsCommitable;
SmallVector<Edit, 8> CachedEdits;
@@ -59,9 +58,9 @@
public:
explicit Commit(EditedSource &Editor);
Commit(const SourceManager &SM, const LangOptions &LangOpts,
- const PPConditionalDirectiveRecord *PPRec = 0)
- : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
- ForceCommitInSystemHeader(true), IsCommitable(true) { }
+ const PPConditionalDirectiveRecord *PPRec = nullptr)
+ : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(nullptr),
+ IsCommitable(true) { }
bool isCommitable() const { return IsCommitable; }
@@ -132,9 +131,9 @@
void commitRemove(FileOffset offset, unsigned length);
bool isAtStartOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroBegin = 0) const;
+ SourceLocation *MacroBegin = nullptr) const;
bool isAtEndOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroEnd = 0) const;
+ SourceLocation *MacroEnd = nullptr) const;
StringRef copyString(StringRef str) {
char *buf = StrAlloc.Allocate<char>(str.size());
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
index f95b797..150a5b4 100644
--- a/include/clang/Edit/EditedSource.h
+++ b/include/clang/Edit/EditedSource.h
@@ -28,7 +28,6 @@
const SourceManager &SourceMgr;
const LangOptions &LangOpts;
const PPConditionalDirectiveRecord *PPRec;
- const bool ForceCommitInSystemHeader;
struct FileEdit {
StringRef Text;
@@ -46,10 +45,8 @@
public:
EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
- const PPConditionalDirectiveRecord *PPRec = 0,
- const bool FCommitInSystemHeader = true)
+ const PPConditionalDirectiveRecord *PPRec = nullptr)
: SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
- ForceCommitInSystemHeader(FCommitInSystemHeader),
StrAlloc() { }
const SourceManager &getSourceManager() const { return SourceMgr; }
@@ -57,10 +54,6 @@
const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const {
return PPRec;
}
-
- bool getForceCommitInSystemHeader() const {
- return ForceCommitInSystemHeader;
- }
bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index cded911..244a9c6 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -120,7 +120,11 @@
/// \brief The indentation used for namespaces.
NamespaceIndentationKind NamespaceIndentation;
- /// \brief The number of spaces to before trailing line comments.
+ /// \brief The number of spaces before trailing line comments
+ /// (\c // - comments).
+ ///
+ /// This does not affect trailing block comments (\c /**/ - comments) as those
+ /// commonly have different usage patterns and a number of special cases.
unsigned SpacesBeforeTrailingComments;
/// \brief If \c false, a function call's or function definition's parameters
@@ -155,6 +159,11 @@
/// the commas with the colon.
bool BreakConstructorInitializersBeforeComma;
+ /// \brief Allows contracting simple braced statements to a single line.
+ ///
+ /// E.g., this allows <tt>if (a) { return; }</tt> to be put on a single line.
+ bool AllowShortBlocksOnASingleLine;
+
/// \brief If \c true, <tt>if (a) return;</tt> can be put on a single
/// line.
bool AllowShortIfStatementsOnASingleLine;
@@ -163,12 +172,23 @@
/// single line.
bool AllowShortLoopsOnASingleLine;
- /// \brief If \c true, <tt>int f() { return 0; }</tt> can be put on a single
- /// line.
- bool AllowShortFunctionsOnASingleLine;
+ /// \brief Different styles for merging short functions containing at most one
+ /// statement.
+ enum ShortFunctionStyle {
+ /// \brief Never merge functions into a single line.
+ SFS_None,
+ /// \brief Only merge functions defined inside a class.
+ SFS_Inline,
+ /// \brief Merge all functions fitting on a single line.
+ SFS_All,
+ };
+
+ /// \brief Dependent on the value, <tt>int f() { return 0; }</tt> can be put
+ /// on a single line.
+ ShortFunctionStyle AllowShortFunctionsOnASingleLine;
/// \brief Add a space after \c @property in Objective-C, i.e. use
- /// <tt>@property (readonly)</tt> instead of <tt>@property(readonly)</tt>.
+ /// <tt>\@property (readonly)</tt> instead of <tt>\@property(readonly)</tt>.
bool ObjCSpaceAfterProperty;
/// \brief Add a space in front of an Objective-C protocol list, i.e. use
@@ -302,6 +322,9 @@
/// which should not be split into lines or otherwise changed.
std::string CommentPragmas;
+ /// \brief Disables formatting at all.
+ bool DisableFormat;
+
/// \brief A vector of macros that should be interpreted as foreach loops
/// instead of as function calls.
///
@@ -324,6 +347,7 @@
R.AllowAllParametersOfDeclarationOnNextLine &&
AllowShortFunctionsOnASingleLine ==
R.AllowShortFunctionsOnASingleLine &&
+ AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine &&
AllowShortIfStatementsOnASingleLine ==
R.AllowShortIfStatementsOnASingleLine &&
AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
@@ -401,6 +425,9 @@
/// http://www.gnu.org/prep/standards/standards.html
FormatStyle getGNUStyle();
+/// \brief Returns style indicating formatting should be not applied at all.
+FormatStyle getNoStyle();
+
/// \brief Gets a predefined style for the specified language by name.
///
/// Currently supported names: LLVM, Google, Chromium, Mozilla. Names are
@@ -446,8 +473,8 @@
///
/// \param Standard determines lexing mode: LC_Cpp11 and LS_Auto turn on C++11
/// lexing mode, LS_Cpp03 - C++03 mode.
-LangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard =
- FormatStyle::LS_Cpp11);
+LangOptions getFormattingLangOpts(
+ FormatStyle::LanguageStandard Standard = FormatStyle::LS_Cpp11);
/// \brief Description to be used for help text for a llvm::cl option for
/// specifying format style. The description is closely related to the operation
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 3a26df3..3d7d0f2 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -189,7 +189,7 @@
mutable unsigned NumLines;
public:
- PreambleData() : File(0), NumLines(0) { }
+ PreambleData() : File(nullptr), NumLines(0) { }
void assign(const FileEntry *F, const char *begin, const char *end) {
File = F;
@@ -197,7 +197,7 @@
NumLines = 0;
}
- void clear() { Buffer.clear(); File = 0; NumLines = 0; }
+ void clear() { Buffer.clear(); File = nullptr; NumLines = 0; }
size_t size() const { return Buffer.size(); }
bool empty() const { return Buffer.empty(); }
@@ -499,7 +499,12 @@
bool hasSema() const { return (bool)TheSema; }
Sema &getSema() const {
assert(TheSema && "ASTUnit does not have a Sema object!");
- return *TheSema;
+ return *TheSema;
+ }
+
+ const LangOptions &getLangOpts() const {
+ assert(LangOpts && " ASTUnit does not have language options");
+ return *LangOpts;
}
const FileManager &getFileManager() const { return *FileMgr; }
@@ -680,7 +685,7 @@
bool isModuleFile();
llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
- std::string *ErrorStr = 0);
+ std::string *ErrorStr = nullptr);
/// \brief Determine what kind of translation unit this AST represents.
TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
@@ -752,12 +757,13 @@
///
static ASTUnit *LoadFromCompilerInvocationAction(
CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- ASTFrontendAction *Action = 0, ASTUnit *Unit = 0, bool Persistent = true,
- StringRef ResourceFilesPath = StringRef(), bool OnlyLocalDecls = false,
- bool CaptureDiagnostics = false, bool PrecompilePreamble = false,
- bool CacheCodeCompletionResults = false,
+ ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
+ bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
+ bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+ bool PrecompilePreamble = false, bool CacheCodeCompletionResults = false,
bool IncludeBriefCommentsInCodeCompletion = false,
- bool UserFilesAreVolatile = false, std::unique_ptr<ASTUnit> *ErrAST = 0);
+ bool UserFilesAreVolatile = false,
+ std::unique_ptr<ASTUnit> *ErrAST = nullptr);
/// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
/// CompilerInvocation object.
@@ -770,15 +776,13 @@
//
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
// shouldn't need to specify them at construction time.
- static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- bool OnlyLocalDecls = false,
- bool CaptureDiagnostics = false,
- bool PrecompilePreamble = false,
- TranslationUnitKind TUKind = TU_Complete,
- bool CacheCodeCompletionResults = false,
- bool IncludeBriefCommentsInCodeCompletion = false,
- bool UserFilesAreVolatile = false);
+ static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
+ CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+ bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+ bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+ bool CacheCodeCompletionResults = false,
+ bool IncludeBriefCommentsInCodeCompletion = false,
+ bool UserFilesAreVolatile = false);
/// LoadFromCommandLine - Create an ASTUnit from a vector of command line
/// arguments, which must specify exactly one source file.
@@ -809,7 +813,7 @@
bool IncludeBriefCommentsInCodeCompletion = false,
bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false,
bool UserFilesAreVolatile = false, bool ForSerialization = false,
- std::unique_ptr<ASTUnit> *ErrAST = 0);
+ std::unique_ptr<ASTUnit> *ErrAST = nullptr);
/// \brief Reparse the source files using the same command-line options that
/// were originally used to produce this translation unit.
@@ -869,6 +873,10 @@
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
SourceLocation ImportLoc, bool Complain) override {}
+ GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+ { return nullptr; }
+ bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+ { return 0; };
};
} // namespace clang
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 753b641..8959185 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -68,7 +68,6 @@
///< be generated.
CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled.
-CODEGENOPT(NoDwarf2CFIAsm , 1, 0) ///< Set when -fno-dwarf2-cfi-asm is enabled.
CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is
///< enabled.
CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index da97e5c..9c8de1b 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -16,6 +16,7 @@
#include <string>
#include <vector>
+#include "llvm/Support/Regex.h"
namespace clang {
@@ -145,6 +146,13 @@
/// Name of the profile file to use as input for -fprofile-instr-use
std::string InstrProfileInput;
+ /// Regular expression to select optimizations for which we should enable
+ /// optimization remarks. Transformation passes whose name matches this
+ /// expression (and support this feature), will emit a diagnostic
+ /// whenever they perform a transformation. This is enabled by the
+ /// -Rpass=regexp flag.
+ std::shared_ptr<llvm::Regex> OptimizationRemarkPattern;
+
public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index ee97d9b..97c140e 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -124,6 +124,9 @@
/// have finished with this translation unit.
bool BuildGlobalModuleIndex;
+ /// \brief We have a full global module index, with all modules.
+ bool HaveFullGlobalModuleIndex;
+
/// \brief One or more modules failed to build.
bool ModuleBuildFailed;
@@ -148,7 +151,7 @@
CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION;
void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION;
public:
- CompilerInstance();
+ explicit CompilerInstance(bool BuildingModule = false);
~CompilerInstance();
/// @name High-Level Operations
@@ -190,7 +193,7 @@
/// @name Compiler Invocation and Options
/// {
- bool hasInvocation() const { return Invocation != 0; }
+ bool hasInvocation() const { return Invocation != nullptr; }
CompilerInvocation &getInvocation() {
assert(Invocation && "Compiler instance has no invocation!");
@@ -288,7 +291,7 @@
/// @name Diagnostics Engine
/// {
- bool hasDiagnostics() const { return Diagnostics != 0; }
+ bool hasDiagnostics() const { return Diagnostics != nullptr; }
/// Get the current diagnostics engine.
DiagnosticsEngine &getDiagnostics() const {
@@ -309,7 +312,7 @@
/// @name Target Info
/// {
- bool hasTarget() const { return Target != 0; }
+ bool hasTarget() const { return Target != nullptr; }
TargetInfo &getTarget() const {
assert(Target && "Compiler instance has no target!");
@@ -323,7 +326,7 @@
/// @name Virtual File System
/// {
- bool hasVirtualFileSystem() const { return VirtualFileSystem != 0; }
+ bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; }
vfs::FileSystem &getVirtualFileSystem() const {
assert(hasVirtualFileSystem() &&
@@ -343,7 +346,7 @@
/// @name File Manager
/// {
- bool hasFileManager() const { return FileMgr != 0; }
+ bool hasFileManager() const { return FileMgr != nullptr; }
/// Return the current file manager to the caller.
FileManager &getFileManager() const {
@@ -363,7 +366,7 @@
/// @name Source Manager
/// {
- bool hasSourceManager() const { return SourceMgr != 0; }
+ bool hasSourceManager() const { return SourceMgr != nullptr; }
/// Return the current source manager.
SourceManager &getSourceManager() const {
@@ -383,7 +386,7 @@
/// @name Preprocessor
/// {
- bool hasPreprocessor() const { return PP != 0; }
+ bool hasPreprocessor() const { return PP != nullptr; }
/// Return the current preprocessor.
Preprocessor &getPreprocessor() const {
@@ -403,7 +406,7 @@
/// @name ASTContext
/// {
- bool hasASTContext() const { return Context != 0; }
+ bool hasASTContext() const { return Context != nullptr; }
ASTContext &getASTContext() const {
assert(Context && "Compiler instance has no AST context!");
@@ -452,6 +455,7 @@
}
Sema *takeSema() { return TheSema.release(); }
+ void resetAndLeakSema() { BuryPointer(TheSema.release()); }
/// }
/// @name Module Management
@@ -524,7 +528,7 @@
///
/// \param ShouldOwnClient If Client is non-NULL, specifies whether
/// the diagnostic object should take ownership of the client.
- void createDiagnostics(DiagnosticConsumer *Client = 0,
+ void createDiagnostics(DiagnosticConsumer *Client = nullptr,
bool ShouldOwnClient = true);
/// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
@@ -547,9 +551,9 @@
/// \return The new object on success, or null on failure.
static IntrusiveRefCntPtr<DiagnosticsEngine>
createDiagnostics(DiagnosticOptions *Opts,
- DiagnosticConsumer *Client = 0,
+ DiagnosticConsumer *Client = nullptr,
bool ShouldOwnClient = true,
- const CodeGenOptions *CodeGenOpts = 0);
+ const CodeGenOptions *CodeGenOpts = nullptr);
/// Create the file manager and replace any existing one with it.
void createFileManager();
@@ -566,21 +570,19 @@
/// Create an external AST source to read a PCH file and attach it to the AST
/// context.
- void createPCHExternalASTSource(StringRef Path,
- bool DisablePCHValidation,
+ void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation,
bool AllowPCHWithCompilerErrors,
- void *DeserializationListener);
+ void *DeserializationListener,
+ bool OwnDeserializationListener);
/// Create an external AST source to read a PCH file.
///
/// \return - The new object on success, or null on failure.
- static ExternalASTSource *
- createPCHExternalASTSource(StringRef Path, const std::string &Sysroot,
- bool DisablePCHValidation,
- bool AllowPCHWithCompilerErrors,
- Preprocessor &PP, ASTContext &Context,
- void *DeserializationListener, bool Preamble,
- bool UseGlobalModuleIndex);
+ static ExternalASTSource *createPCHExternalASTSource(
+ StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
+ bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+ void *DeserializationListener, bool OwnDeserializationListener,
+ bool Preamble, bool UseGlobalModuleIndex);
/// Create a code completion consumer using the invocation; note that this
/// will cause the source manager to truncate the input source file at the
@@ -683,6 +685,9 @@
/// }
+ // Create module manager.
+ void createModuleManager();
+
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective) override;
@@ -694,6 +699,9 @@
return ModuleLoader::HadFatalFailure;
}
+ GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
+
+ bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
};
} // end namespace clang
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index f64773c..3d7467c 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -47,9 +47,11 @@
/// When errors are encountered, return false and, if Diags is non-null,
/// report the error(s).
bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
- DiagnosticsEngine *Diags = 0);
+ DiagnosticsEngine *Diags = nullptr);
class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
+ void operator=(const CompilerInvocationBase &) LLVM_DELETED_FUNCTION;
+
protected:
/// Options controlling the language variant.
IntrusiveRefCntPtr<LangOptions> LangOpts;
@@ -68,6 +70,7 @@
public:
CompilerInvocationBase();
+ ~CompilerInvocationBase();
CompilerInvocationBase(const CompilerInvocationBase &X);
@@ -204,6 +207,14 @@
/// @}
};
+namespace vfs {
+ class FileSystem;
+}
+
+IntrusiveRefCntPtr<vfs::FileSystem>
+createVFSFromCompilerInvocation(const CompilerInvocation &CI,
+ DiagnosticsEngine &Diags);
+
} // end namespace clang
#endif
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index f554b88..019eec5 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -144,7 +144,7 @@
StringRef Message, ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
const SourceManager *SM,
- DiagOrStoredDiag D = (Diagnostic *)0);
+ DiagOrStoredDiag D = (Diagnostic *)nullptr);
void emitStoredDiagnostic(StoredDiagnostic &Diag);
};
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 8c24513..9ac9d28 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -148,7 +148,8 @@
ASTUnit *takeCurrentASTUnit() { return CurrentASTUnit.release(); }
- void setCurrentInput(const FrontendInputFile &CurrentInput, ASTUnit *AST = 0);
+ void setCurrentInput(const FrontendInputFile &CurrentInput,
+ ASTUnit *AST = nullptr);
/// @}
/// @name Supported Modes
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index a5db252..84cc82c 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -17,6 +17,7 @@
namespace clang {
class Module;
+class FileEntry;
//===----------------------------------------------------------------------===//
// Custom Consumer Actions
@@ -93,6 +94,7 @@
class GenerateModuleAction : public ASTFrontendAction {
clang::Module *Module;
+ const FileEntry *ModuleMapForUniquing;
bool IsSystem;
protected:
@@ -106,8 +108,10 @@
bool hasASTFileSupport() const override { return false; }
public:
- explicit GenerateModuleAction(bool IsSystem = false)
- : ASTFrontendAction(), IsSystem(IsSystem) { }
+ GenerateModuleAction(const FileEntry *ModuleMap = nullptr,
+ bool IsSystem = false)
+ : ASTFrontendAction(), ModuleMapForUniquing(ModuleMap), IsSystem(IsSystem)
+ { }
bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
@@ -115,11 +119,11 @@
/// create the PCHGenerator instance returned by CreateASTConsumer.
///
/// \returns true if an error occurred, false otherwise.
- static bool ComputeASTConsumerArguments(CompilerInstance &CI,
- StringRef InFile,
- std::string &Sysroot,
- std::string &OutputFile,
- raw_ostream *&OS);
+ bool ComputeASTConsumerArguments(CompilerInstance &CI,
+ StringRef InFile,
+ std::string &Sysroot,
+ std::string &OutputFile,
+ raw_ostream *&OS);
};
class SyntaxOnlyAction : public ASTFrontendAction {
@@ -197,7 +201,7 @@
protected:
void ExecuteAction() override;
ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) override {
- return 0;
+ return nullptr;
}
bool usesPreprocessorOnly() const override { return true; }
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index fc13b19..e87da8d 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -90,9 +90,9 @@
bool IsSystem;
public:
- FrontendInputFile() : Buffer(0), Kind(IK_None) { }
+ FrontendInputFile() : Buffer(nullptr), Kind(IK_None) { }
FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
- : File(File.str()), Buffer(0), Kind(Kind), IsSystem(IsSystem) { }
+ : File(File.str()), Buffer(nullptr), Kind(Kind), IsSystem(IsSystem) { }
FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind,
bool IsSystem = false)
: Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { }
@@ -100,9 +100,9 @@
InputKind getKind() const { return Kind; }
bool isSystem() const { return IsSystem; }
- bool isEmpty() const { return File.empty() && Buffer == 0; }
+ bool isEmpty() const { return File.empty() && Buffer == nullptr; }
bool isFile() const { return !isBuffer(); }
- bool isBuffer() const { return Buffer != 0; }
+ bool isBuffer() const { return Buffer != nullptr; }
StringRef getFile() const {
assert(isFile());
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
index 6ea1d73..a7e0444 100644
--- a/include/clang/Frontend/MultiplexConsumer.h
+++ b/include/clang/Frontend/MultiplexConsumer.h
@@ -36,6 +36,7 @@
void Initialize(ASTContext &Context) override;
void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override;
bool HandleTopLevelDecl(DeclGroupRef D) override;
+ void HandleInlineMethodDefinition(CXXMethodDecl *D) override;
void HandleInterestingDecl(DeclGroupRef D) override;
void HandleTranslationUnit(ASTContext &Ctx) override;
void HandleTagDeclDefinition(TagDecl *D) override;
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
index feff798..fe5aa3e 100644
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -28,7 +28,7 @@
typedef DiagList::iterator iterator;
typedef DiagList::const_iterator const_iterator;
private:
- DiagList Errors, Warnings, Notes;
+ DiagList Errors, Warnings, Remarks, Notes;
public:
const_iterator err_begin() const { return Errors.begin(); }
const_iterator err_end() const { return Errors.end(); }
@@ -36,6 +36,9 @@
const_iterator warn_begin() const { return Warnings.begin(); }
const_iterator warn_end() const { return Warnings.end(); }
+ const_iterator remark_begin() const { return Remarks.begin(); }
+ const_iterator remark_end() const { return Remarks.end(); }
+
const_iterator note_begin() const { return Notes.begin(); }
const_iterator note_end() const { return Notes.end(); }
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 63eecb1..8fb536f 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -63,12 +63,6 @@
const HeaderSearchOptions &HSOpts,
const FrontendOptions &FEOpts);
-/// ProcessWarningOptions - Initialize the diagnostic client and process the
-/// warning options specified on the command line.
-void ProcessWarningOptions(DiagnosticsEngine &Diags,
- const DiagnosticOptions &Opts,
- bool ReportDiags = true);
-
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
const PreprocessorOutputOptions &Opts);
@@ -124,7 +118,7 @@
/// is non-null, emits an error if the argument is given, but non-integral.
int getLastArgIntValue(const llvm::opt::ArgList &Args,
llvm::opt::OptSpecifier Id, int Default,
- DiagnosticsEngine *Diags = 0);
+ DiagnosticsEngine *Diags = nullptr);
inline int getLastArgIntValue(const llvm::opt::ArgList &Args,
llvm::opt::OptSpecifier Id, int Default,
@@ -134,7 +128,7 @@
uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
llvm::opt::OptSpecifier Id, uint64_t Default,
- DiagnosticsEngine *Diags = 0);
+ DiagnosticsEngine *Diags = nullptr);
inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
llvm::opt::OptSpecifier Id,
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index 39678ef..084eb66 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -34,12 +34,12 @@
/// comment on the line that has the diagnostic, use:
///
/// \code
-/// expected-{error,warning,note}
+/// expected-{error,warning,remark,note}
/// \endcode
///
-/// to tag if it's an expected error or warning, and place the expected text
-/// between {{ and }} markers. The full text doesn't have to be included, only
-/// enough to ensure that the correct diagnostic was emitted.
+/// to tag if it's an expected error, remark or warning, and place the expected
+/// text between {{ and }} markers. The full text doesn't have to be included,
+/// only enough to ensure that the correct diagnostic was emitted.
///
/// Here's an example:
///
@@ -184,13 +184,17 @@
struct ExpectedData {
DirectiveList Errors;
DirectiveList Warnings;
+ DirectiveList Remarks;
DirectiveList Notes;
- ~ExpectedData() {
+ void Reset() {
llvm::DeleteContainerPointers(Errors);
llvm::DeleteContainerPointers(Warnings);
+ llvm::DeleteContainerPointers(Remarks);
llvm::DeleteContainerPointers(Notes);
}
+
+ ~ExpectedData() { Reset(); }
};
enum DirectiveStatus {
diff --git a/include/clang/Index/CommentToXML.h b/include/clang/Index/CommentToXML.h
index 8444b14..bb7b71a 100644
--- a/include/clang/Index/CommentToXML.h
+++ b/include/clang/Index/CommentToXML.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_INDEX_COMMENTTOXML_H
#include "clang/Basic/LLVM.h"
+#include <memory>
namespace clang {
class ASTContext;
@@ -24,11 +25,12 @@
class SimpleFormatContext;
class CommentToXMLConverter {
- SimpleFormatContext *FormatContext;
+ std::unique_ptr<SimpleFormatContext> FormatContext;
unsigned FormatInMemoryUniqueId;
public:
- CommentToXMLConverter() : FormatContext(0), FormatInMemoryUniqueId(0) {}
+ CommentToXMLConverter();
+ ~CommentToXMLConverter();
void convertCommentToHTML(const comments::FullComment *FC,
SmallVectorImpl<char> &HTML,
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index 16899a0..9edf119 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -92,17 +92,21 @@
/// getDir - Return the directory that this entry refers to.
///
- const DirectoryEntry *getDir() const { return isNormalDir() ? u.Dir : 0; }
+ const DirectoryEntry *getDir() const {
+ return isNormalDir() ? u.Dir : nullptr;
+ }
/// getFrameworkDir - Return the directory that this framework refers to.
///
const DirectoryEntry *getFrameworkDir() const {
- return isFramework() ? u.Dir : 0;
+ return isFramework() ? u.Dir : nullptr;
}
/// getHeaderMap - Return the directory that this entry refers to.
///
- const HeaderMap *getHeaderMap() const { return isHeaderMap() ? u.Map : 0; }
+ const HeaderMap *getHeaderMap() const {
+ return isHeaderMap() ? u.Map : nullptr;
+ }
/// isNormalDir - Return true if this is a normal directory, not a header map.
bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index c3af633..0342629 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -106,7 +106,7 @@
External(false), isModuleHeader(false), isCompilingModuleHeader(false),
HeaderRole(ModuleMap::NormalHeader),
Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
- NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {}
+ NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr) {}
/// \brief Retrieve the controlling macro for this header file, if
/// any.
@@ -493,9 +493,12 @@
///
/// \param ModuleName The module whose module file name will be returned.
///
+ /// \param ModuleMapPath A path that when combined with \c ModuleName
+ /// uniquely identifies this module. See Module::ModuleMap.
+ ///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(StringRef ModuleName);
+ std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);
/// \brief Lookup a module Search for a module with the given name.
///
@@ -508,7 +511,6 @@
/// \returns The module with the given name.
Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
-
/// \brief Try to find a module map file in the given directory, returning
/// \c nullptr if none is found.
const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir,
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 513eb88..edcf883 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -205,7 +205,7 @@
/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
/// uninterpreted string. This switches the lexer out of directive mode.
- void ReadToEndOfLine(SmallVectorImpl<char> *Result = 0);
+ void ReadToEndOfLine(SmallVectorImpl<char> *Result = nullptr);
/// Diag - Forwarding function for diagnostics. This translate a source
@@ -248,7 +248,7 @@
static unsigned getSpelling(const Token &Tok, const char *&Buffer,
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
- bool *Invalid = 0);
+ bool *Invalid = nullptr);
/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
/// token is the characters used to represent the token in the source file
@@ -258,7 +258,7 @@
static std::string getSpelling(const Token &Tok,
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
- bool *Invalid = 0);
+ bool *Invalid = nullptr);
/// getSpelling - This method is used to get the spelling of the
/// token at the given source location. If, as is usually true, it
@@ -272,7 +272,7 @@
SmallVectorImpl<char> &buffer,
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
- bool *invalid = 0);
+ bool *invalid = nullptr);
/// MeasureTokenLength - Relex the token at the specified location and return
/// its length in bytes in the input file. If the token needs cleaning (e.g.
@@ -331,7 +331,7 @@
static bool isAtStartOfMacroExpansion(SourceLocation loc,
const SourceManager &SM,
const LangOptions &LangOpts,
- SourceLocation *MacroBegin = 0);
+ SourceLocation *MacroBegin = nullptr);
/// \brief Returns true if the given MacroID location points at the last
/// token of the macro expansion.
@@ -341,7 +341,7 @@
static bool isAtEndOfMacroExpansion(SourceLocation loc,
const SourceManager &SM,
const LangOptions &LangOpts,
- SourceLocation *MacroEnd = 0);
+ SourceLocation *MacroEnd = nullptr);
/// \brief Accepts a range and returns a character range with file locations.
///
@@ -377,7 +377,7 @@
static StringRef getSourceText(CharSourceRange Range,
const SourceManager &SM,
const LangOptions &LangOpts,
- bool *Invalid = 0);
+ bool *Invalid = nullptr);
/// \brief Retrieve the name of the immediate macro expansion.
///
@@ -548,7 +548,8 @@
/// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize
/// method.
- char getCharAndSizeSlow(const char *Ptr, unsigned &Size, Token *Tok = 0);
+ char getCharAndSizeSlow(const char *Ptr, unsigned &Size,
+ Token *Tok = nullptr);
/// getEscapedNewLineSize - Return the size of the specified escaped newline,
/// or 0 if it is not an escaped newline. P[-1] is known to be a "\" on entry
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 3e52418..2eb7751 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -200,7 +200,8 @@
Preprocessor &PP, bool Complain = true);
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
const SourceManager &sm, const LangOptions &features,
- const TargetInfo &target, DiagnosticsEngine *diags = 0)
+ const TargetInfo &target,
+ DiagnosticsEngine *diags = nullptr)
: SM(sm), Features(features), Target(target), Diags(diags),
MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
index 1fd295e..4c0120c 100644
--- a/include/clang/Lex/MacroArgs.h
+++ b/include/clang/Lex/MacroArgs.h
@@ -52,9 +52,10 @@
/// ArgCache - This is a linked list of MacroArgs objects that the
/// Preprocessor owns which we use to avoid thrashing malloc/free.
MacroArgs *ArgCache;
-
+
MacroArgs(unsigned NumToks, bool varargsElided)
- : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), ArgCache(0) {}
+ : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided),
+ ArgCache(nullptr) {}
~MacroArgs() {}
public:
/// MacroArgs ctor function - Create a new MacroArgs object with the specified
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 1580d1b..7c04031 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -104,8 +104,11 @@
/// \brief Whether this macro info was loaded from an AST file.
unsigned FromASTFile : 1;
+ /// \brief Whether this macro was used as header guard.
+ bool UsedForHeaderGuard : 1;
+
~MacroInfo() {
- assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
+ assert(!ArgumentList && "Didn't call destroy before dtor!");
}
public:
@@ -116,7 +119,7 @@
/// This restores this MacroInfo to a state where it can be reused for other
/// devious purposes.
void FreeArgumentList() {
- ArgumentList = 0;
+ ArgumentList = nullptr;
NumArguments = 0;
}
@@ -176,7 +179,7 @@
/// this macro.
void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
llvm::BumpPtrAllocator &PPAllocator) {
- assert(ArgumentList == 0 && NumArguments == 0 &&
+ assert(ArgumentList == nullptr && NumArguments == 0 &&
"Argument list already set!");
if (NumArgs == 0) return;
@@ -282,6 +285,11 @@
/// a precompiled header or module) rather than having been parsed.
bool isFromASTFile() const { return FromASTFile; }
+ /// \brief Determine whether this macro was used for a header guard.
+ bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; }
+
+ void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; }
+
/// \brief Retrieve the global ID of the module that owns this particular
/// macro info.
unsigned getOwningModuleID() const {
@@ -354,7 +362,7 @@
bool IsPublic : 1;
MacroDirective(Kind K, SourceLocation Loc)
- : Previous(0), Loc(Loc), MDKind(K), IsFromPCH(false),
+ : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
IsImported(false), IsAmbiguous(false),
IsPublic(true) {
}
@@ -386,7 +394,7 @@
bool IsPublic;
public:
- DefInfo() : DefDirective(0) { }
+ DefInfo() : DefDirective(nullptr) { }
DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
bool isPublic)
@@ -406,7 +414,7 @@
bool isPublic() const { return IsPublic; }
- bool isValid() const { return DefDirective != 0; }
+ bool isValid() const { return DefDirective != nullptr; }
bool isInvalid() const { return !isValid(); }
LLVM_EXPLICIT operator bool() const { return isValid(); }
@@ -521,13 +529,13 @@
inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
if (isInvalid())
- return 0;
+ return nullptr;
return DefDirective->getInfo();
}
inline MacroDirective::DefInfo
MacroDirective::DefInfo::getPreviousDefinition() {
- if (isInvalid() || DefDirective->getPrevious() == 0)
+ if (isInvalid() || DefDirective->getPrevious() == nullptr)
return DefInfo();
return DefDirective->getPrevious()->getDefinition();
}
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 254ab36..7869799 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -21,6 +21,7 @@
namespace clang {
+class GlobalModuleIndex;
class IdentifierInfo;
class Module;
@@ -53,11 +54,24 @@
/// for resolving a module name (e.g., "std") to an actual module file, and
/// then loading that module.
class ModuleLoader {
+ // Building a module if true.
+ bool BuildingModule;
public:
- ModuleLoader() : HadFatalFailure(false) {}
+ explicit ModuleLoader(bool BuildingModule = false) :
+ BuildingModule(BuildingModule),
+ HadFatalFailure(false) {}
virtual ~ModuleLoader();
+ /// \brief Returns true if this instance is building a module.
+ bool buildingModule() const {
+ return BuildingModule;
+ }
+ /// \brief Flag indicating whether this instance is building a module.
+ void setBuildingModule(bool BuildingModuleFlag) {
+ BuildingModule = BuildingModuleFlag;
+ }
+
/// \brief Attempt to load the given module.
///
/// This routine attempts to load the module described by the given
@@ -88,6 +102,26 @@
SourceLocation ImportLoc,
bool Complain) = 0;
+ /// \brief Load, create, or return global module.
+ /// This function returns an existing global module index, if one
+ /// had already been loaded or created, or loads one if it
+ /// exists, or creates one if it doesn't exist.
+ /// Also, importantly, if the index doesn't cover all the modules
+ /// in the module map, it will be update to do so here, because
+ /// of its use in searching for needed module imports and
+ /// associated fixit messages.
+ /// \param TriggerLoc The location for what triggered the load.
+ /// \returns Returns null if load failed.
+ virtual GlobalModuleIndex *loadGlobalModuleIndex(
+ SourceLocation TriggerLoc) = 0;
+
+ /// Check global module index for missing imports.
+ /// \param Name The symbol name to look for.
+ /// \param TriggerLoc The location for what triggered the load.
+ /// \returns Returns true if any modules with that symbol found.
+ virtual bool lookupMissingImports(StringRef Name,
+ SourceLocation TriggerLoc) = 0;
+
bool HadFatalFailure;
};
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 1cd6d38..a86a927 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -86,7 +86,7 @@
llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage;
public:
- KnownHeader() : Storage(0, NormalHeader) { }
+ KnownHeader() : Storage(nullptr, NormalHeader) { }
KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { }
/// \brief Retrieve the module the header is stored in.
@@ -102,7 +102,9 @@
// \brief Whether this known header is valid (i.e., it has an
// associated module).
- LLVM_EXPLICIT operator bool() const { return Storage.getPointer() != 0; }
+ LLVM_EXPLICIT operator bool() const {
+ return Storage.getPointer() != nullptr;
+ }
};
private:
@@ -131,6 +133,10 @@
/// \brief Whether the modules we infer are [system] modules.
unsigned InferSystemModules : 1;
+ /// \brief If \c InferModules is non-zero, the module map file that allowed
+ /// inferred modules. Otherwise, nullptr.
+ const FileEntry *ModuleMapFile;
+
/// \brief The names of modules that cannot be inferred within this
/// directory.
SmallVector<std::string, 2> ExcludedModules;
@@ -182,6 +188,22 @@
/// associated with a specific module (e.g. in /usr/include).
HeadersMap::iterator findKnownHeader(const FileEntry *File);
+ /// \brief Searches for a module whose umbrella directory contains \p File.
+ ///
+ /// \param File The header to search for.
+ ///
+ /// \param IntermediateDirs On success, contains the set of directories
+ /// searched before finding \p File.
+ KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File,
+ SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs);
+
+ /// \brief A convenience method to determine if \p File is (possibly nested)
+ /// in an umbrella directory.
+ bool isHeaderInUmbrellaDirs(const FileEntry *File) {
+ SmallVector<const DirectoryEntry *, 2> IntermediateDirs;
+ return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs));
+ }
+
public:
/// \brief Construct a new module map.
///
@@ -223,7 +245,7 @@
/// given header file. The KnownHeader is default constructed to indicate
/// that no module owns this header file.
KnownHeader findModuleForHeader(const FileEntry *File,
- Module *RequestingModule = NULL);
+ Module *RequestingModule = nullptr);
/// \brief Reports errors if a module must not include a specific file.
///
@@ -242,6 +264,11 @@
/// marked 'unavailable'.
bool isHeaderInUnavailableModule(const FileEntry *Header) const;
+ /// \brief Determine whether the given header is unavailable as part
+ /// of the specified module.
+ bool isHeaderUnavailableInModule(const FileEntry *Header,
+ const Module *RequestingModule) const;
+
/// \brief Retrieve a module with the given name.
///
/// \param Name The name of the module to look up.
@@ -279,13 +306,17 @@
/// \param Parent The module that will act as the parent of this submodule,
/// or NULL to indicate that this is a top-level module.
///
+ /// \param ModuleMap The module map that defines or allows the inference of
+ /// this module.
+ ///
/// \param IsFramework Whether this is a framework module.
///
/// \param IsExplicit Whether this is an explicit submodule.
///
/// \returns The found or newly-created module, along with a boolean value
/// that will be true if the module is newly-created.
- std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
+ std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
+ const FileEntry *ModuleMap,
bool IsFramework,
bool IsExplicit);
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
index b532bf8..e3c6de5 100644
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -60,8 +60,8 @@
ReadAnyTokens = false;
ImmediatelyAfterTopLevelIfndef = false;
DidMacroExpansion = false;
- TheMacro = 0;
- DefinedMacro = 0;
+ TheMacro = nullptr;
+ DefinedMacro = nullptr;
}
SourceLocation GetMacroLocation() const {
@@ -88,8 +88,8 @@
// below can never "accept".
ReadAnyTokens = true;
ImmediatelyAfterTopLevelIfndef = false;
- DefinedMacro = 0;
- TheMacro = 0;
+ DefinedMacro = nullptr;
+ TheMacro = nullptr;
}
/// getHasReadAnyTokensVal - This is used for the \#ifndef hande-shake at the
@@ -166,7 +166,7 @@
// macro if it's valid (if it isn't, it will be null).
if (!ReadAnyTokens)
return TheMacro;
- return 0;
+ return nullptr;
}
/// \brief If the ControllingMacro is followed by a macro definition, return
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index f263820..4a695a0 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -69,7 +69,7 @@
/// getIfNamespace - If this is a namespace, return it. This is equivalent to
/// using a dynamic_cast, but doesn't require RTTI.
- virtual PragmaNamespace *getIfNamespace() { return 0; }
+ virtual PragmaNamespace *getIfNamespace() { return nullptr; }
};
/// EmptyPragmaHandler - A pragma handler which takes no action, which can be
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 495da76..4609fe3 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -403,7 +403,7 @@
typedef std::random_access_iterator_tag iterator_category;
typedef int difference_type;
- iterator() : Self(0), Position(0) { }
+ iterator() : Self(nullptr), Position(0) { }
iterator(PreprocessingRecord *Self, int Position)
: Self(Self), Position(Position) { }
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 54dee61..d4b4ba2 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -65,7 +65,7 @@
IdentifierInfo *II;
public:
- TokenValue(tok::TokenKind Kind) : Kind(Kind), II(0) {
+ TokenValue(tok::TokenKind Kind) : Kind(Kind), II(nullptr) {
assert(Kind != tok::raw_identifier && "Raw identifiers are not supported.");
assert(Kind != tok::identifier &&
"Identifiers should be created by TokenValue(IdentifierInfo *)");
@@ -125,6 +125,7 @@
IdentifierInfo *Ident__has_include; // __has_include
IdentifierInfo *Ident__has_include_next; // __has_include_next
IdentifierInfo *Ident__has_warning; // __has_warning
+ IdentifierInfo *Ident__is_identifier; // __is_identifier
IdentifierInfo *Ident__building_module; // __building_module
IdentifierInfo *Ident__MODULE__; // __MODULE__
@@ -372,7 +373,7 @@
llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
// Various statistics we track for performance analysis.
- unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
+ unsigned NumDirectives, NumDefined, NumUndefined, NumPragma;
unsigned NumIf, NumElse, NumEndif;
unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
@@ -454,21 +455,18 @@
public:
Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
DiagnosticsEngine &diags, LangOptions &opts,
- const TargetInfo *target,
SourceManager &SM, HeaderSearch &Headers,
ModuleLoader &TheModuleLoader,
- IdentifierInfoLookup *IILookup = 0,
+ IdentifierInfoLookup *IILookup = nullptr,
bool OwnsHeaderSearch = false,
- bool DelayInitialization = false,
- bool IncrProcessing = false,
TranslationUnitKind TUKind = TU_Complete);
~Preprocessor();
- /// \brief Initialize the preprocessor, if the constructor did not already
- /// perform the initialization.
+ /// \brief Initialize the preprocessor using information about the target.
///
- /// \param Target Information about the target.
+ /// \param Target is owned by the caller and must remain valid for the
+ /// lifetime of the preprocessor.
void Initialize(const TargetInfo &Target);
/// \brief Retrieve the preprocessor options used to initialize this
@@ -579,7 +577,7 @@
/// \#defined or null if it isn't \#define'd.
MacroDirective *getMacroDirective(IdentifierInfo *II) const {
if (!II->hasMacroDefinition())
- return 0;
+ return nullptr;
MacroDirective *MD = getMacroDirectiveHistory(II);
assert(MD->isDefined() && "Macro is undefined!");
@@ -593,7 +591,7 @@
MacroInfo *getMacroInfo(IdentifierInfo *II) {
if (MacroDirective *MD = getMacroDirective(II))
return MD->getMacroInfo();
- return 0;
+ return nullptr;
}
/// \brief Given an identifier, return the (probably #undef'd) MacroInfo
@@ -666,6 +664,9 @@
RemovePragmaHandler(StringRef(), Handler);
}
+ /// Install empty handlers for all pragmas (making them ignored).
+ void IgnorePragmas();
+
/// \brief Add the specified comment handler to the preprocessor.
void addCommentHandler(CommentHandler *Handler);
@@ -686,7 +687,7 @@
/// \brief Clear out the code completion handler.
void clearCodeCompletionHandler() {
- CodeComplete = 0;
+ CodeComplete = nullptr;
}
/// \brief Hook used by the lexer to invoke the "natural language" code
@@ -947,7 +948,7 @@
unsigned Line, unsigned Column);
/// \brief Determine if we are performing code completion.
- bool isCodeCompletionEnabled() const { return CodeCompletionFile != 0; }
+ bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; }
/// \brief Returns the location of the code-completion point.
///
@@ -1020,7 +1021,7 @@
/// \param invalid If non-null, will be set \c true if an error occurs.
StringRef getSpelling(SourceLocation loc,
SmallVectorImpl<char> &buffer,
- bool *invalid = 0) const {
+ bool *invalid = nullptr) const {
return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
}
@@ -1032,7 +1033,7 @@
/// things like digraphs, UCNs, etc.
///
/// \param Invalid If non-null, will be set \c true if an error occurs.
- std::string getSpelling(const Token &Tok, bool *Invalid = 0) const {
+ std::string getSpelling(const Token &Tok, bool *Invalid = nullptr) const {
return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
}
@@ -1049,7 +1050,7 @@
/// copy). The caller is not allowed to modify the returned buffer pointer
/// if an internal buffer is returned.
unsigned getSpelling(const Token &Tok, const char *&Buffer,
- bool *Invalid = 0) const {
+ bool *Invalid = nullptr) const {
return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
}
@@ -1059,7 +1060,7 @@
/// supplied buffer if a copy can be avoided.
StringRef getSpelling(const Token &Tok,
SmallVectorImpl<char> &Buffer,
- bool *Invalid = 0) const;
+ bool *Invalid = nullptr) const;
/// \brief Relex the token at the specified location.
/// \returns true if there was a failure, false on success.
@@ -1070,8 +1071,9 @@
/// \brief Given a Token \p Tok that is a numeric constant with length 1,
/// return the character.
- char getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
- bool *Invalid = 0) const {
+ char
+ getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
+ bool *Invalid = nullptr) const {
assert(Tok.is(tok::numeric_constant) &&
Tok.getLength() == 1 && "Called on unsupported token");
assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1");
@@ -1131,7 +1133,7 @@
/// \param MacroBegin If non-null and function returns true, it is set to
/// begin location of the macro.
bool isAtStartOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroBegin = 0) const {
+ SourceLocation *MacroBegin = nullptr) const {
return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts,
MacroBegin);
}
@@ -1142,7 +1144,7 @@
/// \param MacroEnd If non-null and function returns true, it is set to
/// end location of the macro.
bool isAtEndOfMacroExpansion(SourceLocation loc,
- SourceLocation *MacroEnd = 0) const {
+ SourceLocation *MacroEnd = nullptr) const {
return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
}
@@ -1341,13 +1343,15 @@
/// followed by EOD. Return true if the token is not a valid on-off-switch.
bool LexOnOffSwitch(tok::OnOffSwitch &OOS);
+ bool CheckMacroName(Token &MacroNameTok, char isDefineUndef);
+
private:
void PushIncludeMacroStack() {
IncludeMacroStack.push_back(IncludeStackInfo(
CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
CurPPLexer, std::move(CurTokenLexer), CurDirLookup));
- CurPPLexer = 0;
+ CurPPLexer = nullptr;
}
void PopIncludeMacroStack() {
@@ -1474,7 +1478,7 @@
/// \brief Returns true if we are lexing from a file and not a
/// pragma or a macro.
static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
- return L ? !L->isPragmaLexer() : P != 0;
+ return L ? !L->isPragmaLexer() : P != nullptr;
}
static bool IsFileLexer(const IncludeStackInfo& I) {
@@ -1516,7 +1520,7 @@
// File inclusion.
void HandleIncludeDirective(SourceLocation HashLoc,
Token &Tok,
- const DirectoryLookup *LookupFrom = 0,
+ const DirectoryLookup *LookupFrom = nullptr,
bool isImport = false);
void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index 27a8df4..ed226ae 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -76,7 +76,7 @@
PreprocessorLexer(Preprocessor *pp, FileID fid);
PreprocessorLexer()
- : PP(0), InitialNumSLocEntries(0),
+ : PP(nullptr), InitialNumSLocEntries(0),
ParsingPreprocessorDirective(false),
ParsingFilename(false),
LexingRawMode(false) {}
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 580bb12..c8b77d1 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -18,6 +18,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/StringRef.h"
#include <cstdlib>
namespace clang {
@@ -150,7 +151,7 @@
void startToken() {
Kind = tok::unknown;
Flags = 0;
- PtrData = 0;
+ PtrData = nullptr;
UintData = 0;
Loc = SourceLocation();
}
@@ -160,19 +161,19 @@
"getIdentifierInfo() on a tok::raw_identifier token!");
assert(!isAnnotation() &&
"getIdentifierInfo() on an annotation token!");
- if (isLiteral()) return 0;
+ if (isLiteral()) return nullptr;
return (IdentifierInfo*) PtrData;
}
void setIdentifierInfo(IdentifierInfo *II) {
PtrData = (void*) II;
}
- /// getRawIdentifierData - For a raw identifier token (i.e., an identifier
- /// lexed in raw mode), returns a pointer to the start of it in the text
- /// buffer if known, null otherwise.
- const char *getRawIdentifierData() const {
+ /// getRawIdentifier - For a raw identifier token (i.e., an identifier
+ /// lexed in raw mode), returns a reference to the text substring in the
+ /// buffer if known.
+ StringRef getRawIdentifier() const {
assert(is(tok::raw_identifier));
- return reinterpret_cast<const char*>(PtrData);
+ return StringRef(reinterpret_cast<const char *>(PtrData), getLength());
}
void setRawIdentifierData(const char *Ptr) {
assert(is(tok::raw_identifier));
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index 659643d..a873a2e 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -108,7 +108,7 @@
/// identifier for an object-like macro.
TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
MacroArgs *ActualArgs, Preprocessor &pp)
- : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
+ : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
Init(Tok, ILEnd, MI, ActualArgs);
}
@@ -124,7 +124,7 @@
/// the token lexer is empty.
TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion,
bool ownsTokens, Preprocessor &pp)
- : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
+ : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
Init(TokArray, NumToks, DisableExpansion, ownsTokens);
}
diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h
index 2405a0c..21f9701 100644
--- a/include/clang/Parse/ParseAST.h
+++ b/include/clang/Parse/ParseAST.h
@@ -36,7 +36,7 @@
void ParseAST(Preprocessor &pp, ASTConsumer *C,
ASTContext &Ctx, bool PrintStats = false,
TranslationUnitKind TUKind = TU_Complete,
- CodeCompleteConsumer *CompletionConsumer = 0,
+ CodeCompleteConsumer *CompletionConsumer = nullptr,
bool SkipFunctionBodies = false);
/// \brief Parse the main file known to the preprocessor, producing an
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 44f7cb1..83fa1a5 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -154,6 +154,13 @@
std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
std::unique_ptr<PragmaHandler> MSPointersToMembers;
std::unique_ptr<PragmaHandler> MSVtorDisp;
+ std::unique_ptr<PragmaHandler> MSInitSeg;
+ std::unique_ptr<PragmaHandler> MSDataSeg;
+ std::unique_ptr<PragmaHandler> MSBSSSeg;
+ std::unique_ptr<PragmaHandler> MSConstSeg;
+ std::unique_ptr<PragmaHandler> MSCodeSeg;
+ std::unique_ptr<PragmaHandler> MSSection;
+ std::unique_ptr<PragmaHandler> OptimizeHandler;
std::unique_ptr<CommentHandler> CommentSemaHandler;
@@ -413,8 +420,9 @@
/// \brief Consume the current code-completion token.
///
- /// This routine should be called to consume the code-completion token once
- /// a code-completion action has already been invoked.
+ /// This routine can be called to consume the code-completion token and
+ /// continue processing in special cases where \c cutOffParsing() isn't
+ /// desired, such as token caching or completion with lookahead.
SourceLocation ConsumeCodeCompletionToken() {
assert(Tok.is(tok::code_completion));
PrevTokLocation = Tok.getLocation();
@@ -475,6 +483,14 @@
void HandlePragmaMSVtorDisp();
+ void HandlePragmaMSPragma();
+ unsigned HandlePragmaMSSection(llvm::StringRef PragmaName,
+ SourceLocation PragmaLocation);
+ unsigned HandlePragmaMSSegment(llvm::StringRef PragmaName,
+ SourceLocation PragmaLocation);
+ unsigned HandlePragmaMSInitSeg(llvm::StringRef PragmaName,
+ SourceLocation PragmaLocation);
+
/// \brief Handle the annotation token produced for
/// #pragma align...
void HandlePragmaAlign();
@@ -569,7 +585,7 @@
ANK_Success
};
AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand,
- CorrectionCandidateCallback *CCC = 0);
+ CorrectionCandidateCallback *CCC = nullptr);
/// Push a tok::annot_cxxscope token onto the token stream.
void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
@@ -682,7 +698,7 @@
public:
explicit ObjCDeclContextSwitch(Parser &p)
: P(p), DC(p.getObjCDeclContext()),
- WithinObjCContainer(P.ParsingInObjCContainer, DC != 0) {
+ WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
if (DC)
P.Actions.ActOnObjCTemporaryExitContainerContext(cast<DeclContext>(DC));
}
@@ -750,7 +766,7 @@
if (BeforeCompoundStmt)
Self->incrementMSLocalManglingNumber();
- this->Self = 0;
+ this->Self = nullptr;
}
}
@@ -759,7 +775,7 @@
void Exit() {
if (Self) {
Self->ExitScope();
- Self = 0;
+ Self = nullptr;
}
}
@@ -946,7 +962,7 @@
/// (C++ [class.mem]p2).
struct LateParsedDefaultArgument {
explicit LateParsedDefaultArgument(Decl *P,
- CachedTokens *Toks = 0)
+ CachedTokens *Toks = nullptr)
: Param(P), Toks(Toks) { }
/// Param - The parameter declaration for this parameter.
@@ -965,7 +981,8 @@
/// argument (C++ [class.mem]p2).
struct LateParsedMethodDeclaration : public LateParsedDeclaration {
explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
- : Self(P), Method(M), TemplateScope(false), ExceptionSpecTokens(0) { }
+ : Self(P), Method(M), TemplateScope(false),
+ ExceptionSpecTokens(nullptr) {}
void ParseLexedMethodDeclarations() override;
@@ -1088,7 +1105,7 @@
/// specifiers.
struct ParsedTemplateInfo {
ParsedTemplateInfo()
- : Kind(NonTemplate), TemplateParams(0), TemplateLoc() { }
+ : Kind(NonTemplate), TemplateParams(nullptr), TemplateLoc() { }
ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
bool isSpecialization,
@@ -1099,7 +1116,7 @@
explicit ParsedTemplateInfo(SourceLocation ExternLoc,
SourceLocation TemplateLoc)
- : Kind(ExplicitInstantiation), TemplateParams(0),
+ : Kind(ExplicitInstantiation), TemplateParams(nullptr),
ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
LastParameterListWasEmpty(false){ }
@@ -1192,12 +1209,12 @@
};
DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
- ParsingDeclSpec *DS = 0);
+ ParsingDeclSpec *DS = nullptr);
bool isDeclarationAfterDeclarator();
bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
ParsedAttributesWithRange &attrs,
- ParsingDeclSpec *DS = 0,
+ ParsingDeclSpec *DS = nullptr,
AccessSpecifier AS = AS_none);
DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
ParsingDeclSpec &DS,
@@ -1205,11 +1222,11 @@
Decl *ParseFunctionDefinition(ParsingDeclarator &D,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- LateParsedAttrList *LateParsedAttrs = 0);
+ LateParsedAttrList *LateParsedAttrs = nullptr);
void ParseKNRParamDeclarations(Declarator &D);
// EndLoc, if non-NULL, is filled with the location of the last token of
// the simple-asm.
- ExprResult ParseSimpleAsm(SourceLocation *EndLoc = 0);
+ ExprResult ParseSimpleAsm(SourceLocation *EndLoc = nullptr);
ExprResult ParseAsmStringLiteral();
// Objective-C External Declarations
@@ -1349,12 +1366,12 @@
typedef SmallVector<SourceLocation, 20> CommaLocsTy;
/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
- bool ParseExpressionList(SmallVectorImpl<Expr*> &Exprs,
- SmallVectorImpl<SourceLocation> &CommaLocs,
- void (Sema::*Completer)(Scope *S,
- Expr *Data,
- ArrayRef<Expr *> Args) = 0,
- Expr *Data = 0);
+ bool
+ ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
+ SmallVectorImpl<SourceLocation> &CommaLocs,
+ void (Sema::*Completer)(Scope *S, Expr *Data,
+ ArrayRef<Expr *> Args) = nullptr,
+ Expr *Data = nullptr);
/// ParseSimpleExpressionList - A simple comma-separated list of expressions,
/// used for misc language extensions.
@@ -1375,9 +1392,9 @@
ParsedType &CastTy,
SourceLocation &RParenLoc);
- ExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
- ParsedType &CastTy,
- BalancedDelimiterTracker &Tracker);
+ ExprResult ParseCXXAmbiguousParenExpression(
+ ParenParseOption &ExprType, ParsedType &CastTy,
+ BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt);
ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
SourceLocation LParenLoc,
SourceLocation RParenLoc);
@@ -1401,9 +1418,9 @@
bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
ParsedType ObjectType,
bool EnteringContext,
- bool *MayBePseudoDestructor = 0,
+ bool *MayBePseudoDestructor = nullptr,
bool IsTypename = false,
- IdentifierInfo **LastII = 0);
+ IdentifierInfo **LastII = nullptr);
void CheckForLParenAfterColonColon();
@@ -1414,7 +1431,7 @@
ExprResult ParseLambdaExpression();
ExprResult TryParseLambdaExpression();
Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro,
- bool *SkippedInits = 0);
+ bool *SkippedInits = nullptr);
bool TryParseLambdaIntroducer(LambdaIntroducer &Intro);
ExprResult ParseLambdaExpressionAfterIntroducer(
LambdaIntroducer &Intro);
@@ -1550,10 +1567,10 @@
/// A SmallVector of types.
typedef SmallVector<ParsedType, 12> TypeVector;
- StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0);
- StmtResult ParseStatementOrDeclaration(StmtVector &Stmts,
- bool OnlyStatement,
- SourceLocation *TrailingElseLoc = 0);
+ StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr);
+ StmtResult
+ ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement,
+ SourceLocation *TrailingElseLoc = nullptr);
StmtResult ParseStatementOrDeclarationAfterAttributes(
StmtVector &Stmts,
bool OnlyStatement,
@@ -1702,17 +1719,19 @@
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs,
bool RequireSemi,
- ForRangeInit *FRI = 0);
+ ForRangeInit *FRI = nullptr);
bool MightBeDeclarator(unsigned Context);
DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
bool AllowFunctionDefinitions,
- SourceLocation *DeclEnd = 0,
- ForRangeInit *FRI = 0);
+ SourceLocation *DeclEnd = nullptr,
+ ForRangeInit *FRI = nullptr);
Decl *ParseDeclarationAfterDeclarator(Declarator &D,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
bool ParseAsmAttributesAfterDeclarator(Declarator &D);
- Decl *ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+ Decl *ParseDeclarationAfterDeclaratorAndAttributes(
+ Declarator &D,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+ ForRangeInit *FRI = nullptr);
Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);
Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
@@ -1731,10 +1750,10 @@
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
AccessSpecifier AS = AS_none,
DeclSpecContext DSC = DSC_normal,
- LateParsedAttrList *LateAttrs = 0);
+ LateParsedAttrList *LateAttrs = nullptr);
bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
- DeclSpecContext DSContext,
- LateParsedAttrList *LateAttrs = 0);
+ DeclSpecContext DSContext,
+ LateParsedAttrList *LateAttrs = nullptr);
void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none,
DeclSpecContext DSC = DSC_normal);
@@ -1774,7 +1793,7 @@
/// cast. Return false if it's no a decl-specifier, or we're not sure.
bool isKnownToBeDeclarationSpecifier() {
if (getLangOpts().CPlusPlus)
- return isCXXDeclarationSpecifier() == TPResult::True();
+ return isCXXDeclarationSpecifier() == TPResult::True;
return isDeclarationSpecifier(true);
}
@@ -1858,7 +1877,7 @@
/// might be a constructor-style initializer.
/// If during the disambiguation process a parsing error is encountered,
/// the function returns true to let the declaration parsing code handle it.
- bool isCXXFunctionDeclarator(bool *IsAmbiguous = 0);
+ bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr);
/// isCXXConditionDeclaration - Disambiguates between a declaration or an
/// expression for a condition of a if/switch/while/for statement.
@@ -1874,25 +1893,8 @@
/// TPResult - Used as the result value for functions whose purpose is to
/// disambiguate C++ constructs by "tentatively parsing" them.
- /// This is a class instead of a simple enum because the implicit enum-to-bool
- /// conversions may cause subtle bugs.
- class TPResult {
- enum Result {
- TPR_true,
- TPR_false,
- TPR_ambiguous,
- TPR_error
- };
- Result Res;
- TPResult(Result result) : Res(result) {}
- public:
- static TPResult True() { return TPR_true; }
- static TPResult False() { return TPR_false; }
- static TPResult Ambiguous() { return TPR_ambiguous; }
- static TPResult Error() { return TPR_error; }
-
- bool operator==(const TPResult &RHS) const { return Res == RHS.Res; }
- bool operator!=(const TPResult &RHS) const { return Res != RHS.Res; }
+ enum class TPResult {
+ True, False, Ambiguous, Error
};
/// \brief Based only on the given token kind, determine whether we know that
@@ -1907,16 +1909,16 @@
/// tell.
TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind);
- /// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a
- /// declaration specifier, TPResult::False() if it is not,
- /// TPResult::Ambiguous() if it could be either a decl-specifier or a
- /// function-style cast, and TPResult::Error() if a parsing error was
+ /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a
+ /// declaration specifier, TPResult::False if it is not,
+ /// TPResult::Ambiguous if it could be either a decl-specifier or a
+ /// function-style cast, and TPResult::Error if a parsing error was
/// encountered. If it could be a braced C++11 function-style cast, returns
/// BracedCastResult.
/// Doesn't consume tokens.
TPResult
- isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False(),
- bool *HasMissingTypename = 0);
+ isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False,
+ bool *HasMissingTypename = nullptr);
/// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
/// \c TPResult::Ambiguous, determine whether the decl-specifier would be
@@ -1929,9 +1931,9 @@
bool isTentativelyDeclared(IdentifierInfo *II);
// "Tentative parsing" functions, used for disambiguation. If a parsing error
- // is encountered they will return TPResult::Error().
- // Returning TPResult::True()/False() indicates that the ambiguity was
- // resolved and tentative parsing may stop. TPResult::Ambiguous() indicates
+ // is encountered they will return TPResult::Error.
+ // Returning TPResult::True/False indicates that the ambiguity was
+ // resolved and tentative parsing may stop. TPResult::Ambiguous indicates
// that more tentative parsing is necessary for disambiguation.
// They all consume tokens, so backtracking should be used after calling them.
@@ -1942,19 +1944,20 @@
TPResult TryParseOperatorId();
TPResult TryParseInitDeclaratorList();
TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
- TPResult TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = 0,
- bool VersusTemplateArg = false);
+ TPResult
+ TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr,
+ bool VersusTemplateArg = false);
TPResult TryParseFunctionDeclarator();
TPResult TryParseBracketDeclarator();
TPResult TryConsumeDeclarationSpecifier();
public:
- TypeResult ParseTypeName(SourceRange *Range = 0,
+ TypeResult ParseTypeName(SourceRange *Range = nullptr,
Declarator::TheContext Context
= Declarator::TypeNameContext,
AccessSpecifier AS = AS_none,
- Decl **OwnedType = 0,
- ParsedAttributes *Attrs = 0);
+ Decl **OwnedType = nullptr,
+ ParsedAttributes *Attrs = nullptr);
private:
void ParseBlockId(SourceLocation CaretLoc);
@@ -1998,16 +2001,16 @@
/// \brief Parses syntax-generic attribute arguments for attributes which are
/// known to the implementation, and adds them to the given ParsedAttributes
- /// list with the given attribute syntax.
- void ParseAttributeArgsCommon(IdentifierInfo *AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs, SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ /// list with the given attribute syntax. Returns the number of arguments
+ /// parsed for the attribute.
+ unsigned
+ ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+ ParsedAttributes &Attrs, SourceLocation *EndLoc,
+ IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+ AttributeList::Syntax Syntax);
void MaybeParseGNUAttributes(Declarator &D,
- LateParsedAttrList *LateAttrs = 0) {
+ LateParsedAttrList *LateAttrs = nullptr) {
if (Tok.is(tok::kw___attribute)) {
ParsedAttributes attrs(AttrFactory);
SourceLocation endLoc;
@@ -2016,15 +2019,15 @@
}
}
void MaybeParseGNUAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = 0,
- LateParsedAttrList *LateAttrs = 0) {
+ SourceLocation *endLoc = nullptr,
+ LateParsedAttrList *LateAttrs = nullptr) {
if (Tok.is(tok::kw___attribute))
ParseGNUAttributes(attrs, endLoc, LateAttrs);
}
void ParseGNUAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = 0,
- LateParsedAttrList *LateAttrs = 0,
- Declarator *D = 0);
+ SourceLocation *endLoc = nullptr,
+ LateParsedAttrList *LateAttrs = nullptr,
+ Declarator *D = nullptr);
void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs,
@@ -2044,7 +2047,7 @@
}
}
void MaybeParseCXX11Attributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = 0) {
+ SourceLocation *endLoc = nullptr) {
if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
ParsedAttributesWithRange attrsWithRange(AttrFactory);
ParseCXX11Attributes(attrsWithRange, endLoc);
@@ -2052,7 +2055,7 @@
}
}
void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
- SourceLocation *endLoc = 0,
+ SourceLocation *endLoc = nullptr,
bool OuterMightBeMessageSend = false) {
if (getLangOpts().CPlusPlus11 &&
isCXX11AttributeSpecifier(false, OuterMightBeMessageSend))
@@ -2060,9 +2063,9 @@
}
void ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
- SourceLocation *EndLoc = 0);
+ SourceLocation *EndLoc = nullptr);
void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
- SourceLocation *EndLoc = 0);
+ SourceLocation *EndLoc = nullptr);
/// \brief Parses a C++-style attribute argument list. Returns true if this
/// results in adding an attribute to the ParsedAttributes list.
bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
@@ -2074,12 +2077,12 @@
IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc);
void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = 0) {
+ SourceLocation *endLoc = nullptr) {
if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
ParseMicrosoftAttributes(attrs, endLoc);
}
void ParseMicrosoftAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = 0);
+ SourceLocation *endLoc = nullptr);
void ParseMicrosoftDeclSpec(ParsedAttributes &Attrs);
bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
@@ -2122,7 +2125,7 @@
ExprResult ParseAlignArgument(SourceLocation Start,
SourceLocation &EllipsisLoc);
void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
- SourceLocation *endLoc = 0);
+ SourceLocation *endLoc = nullptr);
VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
@@ -2226,7 +2229,7 @@
const ParsedTemplateInfo &TemplateInfo,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs,
- Decl **OwnedType = 0);
+ Decl **OwnedType = nullptr);
Decl *ParseUsingDirective(unsigned Context,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
@@ -2236,7 +2239,7 @@
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
AccessSpecifier AS = AS_none,
- Decl **OwnedType = 0);
+ Decl **OwnedType = nullptr);
Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
SourceLocation AliasLoc, IdentifierInfo *Alias,
@@ -2262,8 +2265,8 @@
ExprResult &BitfieldSize,
LateParsedAttrList &LateAttrs);
void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- ParsingDeclRAIIObject *DiagsFromTParams = 0);
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+ ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
void ParseConstructorInitializer(Decl *ConstructorDecl);
MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
@@ -2343,9 +2346,9 @@
// C++ 14.1: Template Parameters [temp.param]
Decl *ParseDeclarationStartingWithTemplate(unsigned Context,
- SourceLocation &DeclEnd,
- AccessSpecifier AS = AS_none,
- AttributeList *AccessAttrs = 0);
+ SourceLocation &DeclEnd,
+ AccessSpecifier AS = AS_none,
+ AttributeList *AccessAttrs = nullptr);
Decl *ParseTemplateDeclarationOrSpecialization(unsigned Context,
SourceLocation &DeclEnd,
AccessSpecifier AS,
@@ -2356,7 +2359,7 @@
ParsingDeclRAIIObject &DiagsFromParams,
SourceLocation &DeclEnd,
AccessSpecifier AS=AS_none,
- AttributeList *AccessAttrs = 0);
+ AttributeList *AccessAttrs = nullptr);
bool ParseTemplateParameters(unsigned Depth,
SmallVectorImpl<Decl*> &TemplateParams,
SourceLocation &LAngleLoc,
diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h
index 3cd0461..ec061dc 100644
--- a/include/clang/Rewrite/Core/HTMLRewrite.h
+++ b/include/clang/Rewrite/Core/HTMLRewrite.h
@@ -63,7 +63,7 @@
void AddLineNumbers(Rewriter& R, FileID FID);
void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
- const char *title = NULL);
+ const char *title = nullptr);
/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
/// information about keywords, comments, etc.
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
index 5167c50..f312aed 100644
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -61,7 +61,7 @@
unsigned StartOffs;
unsigned EndOffs;
- RopePiece() : StrData(0), StartOffs(0), EndOffs(0) {}
+ RopePiece() : StrData(nullptr), StartOffs(0), EndOffs(0) {}
RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
: StrData(Str), StartOffs(Start), EndOffs(End) {
@@ -122,7 +122,8 @@
// begin iterator.
RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
// end iterator
- RopePieceBTreeIterator() : CurNode(0), CurPiece(0), CurChar(0) {}
+ RopePieceBTreeIterator()
+ : CurNode(nullptr), CurPiece(nullptr), CurChar(0) {}
char operator*() const {
return (*CurPiece)[CurChar];
@@ -195,9 +196,9 @@
enum { AllocChunkSize = 4080 };
public:
- RewriteRope() : AllocBuffer(0), AllocOffs(AllocChunkSize) {}
+ RewriteRope() : AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {}
RewriteRope(const RewriteRope &RHS)
- : Chunks(RHS.Chunks), AllocBuffer(0), AllocOffs(AllocChunkSize) {
+ : Chunks(RHS.Chunks), AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {
}
~RewriteRope() {
diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h
index 2d2917b..7b22fb4 100644
--- a/include/clang/Rewrite/Core/Rewriter.h
+++ b/include/clang/Rewrite/Core/Rewriter.h
@@ -151,7 +151,7 @@
explicit Rewriter(SourceManager &SM, const LangOptions &LO)
: SourceMgr(&SM), LangOpts(&LO) {}
- explicit Rewriter() : SourceMgr(0), LangOpts(0) {}
+ explicit Rewriter() : SourceMgr(nullptr), LangOpts(nullptr) {}
void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
SourceMgr = &SM;
@@ -275,7 +275,7 @@
const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
std::map<FileID, RewriteBuffer>::const_iterator I =
RewriteBuffers.find(FID);
- return I == RewriteBuffers.end() ? 0 : &I->second;
+ return I == RewriteBuffers.end() ? nullptr : &I->second;
}
// Iterators over rewrite buffers.
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
index ff03eff..3ad8f40 100644
--- a/include/clang/Rewrite/Frontend/FixItRewriter.h
+++ b/include/clang/Rewrite/Frontend/FixItRewriter.h
@@ -90,7 +90,7 @@
/// \brief Check whether there are modifications for a given file.
bool IsModified(FileID ID) const {
- return Rewrite.getRewriteBufferFor(ID) != NULL;
+ return Rewrite.getRewriteBufferFor(ID) != nullptr;
}
// Iteration over files with changes.
@@ -106,7 +106,7 @@
///
/// \returns true if there was an error, false otherwise.
bool WriteFixedFiles(
- std::vector<std::pair<std::string, std::string> > *RewrittenFiles = 0);
+ std::vector<std::pair<std::string, std::string> > *RewrittenFiles=nullptr);
/// IncludeInDiagnosticCounts - This method (whose default implementation
/// returns true) indicates whether the diagnostics handled by this
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 171f9f9..6872ccc 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -218,7 +218,7 @@
ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
- HasParsedType(false), NextInPosition(0), NextInPool(0) {
+ HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -237,7 +237,7 @@
Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
UnavailableLoc(unavailable), MessageExpr(messageExpr),
- NextInPosition(0), NextInPool(0) {
+ NextInPosition(nullptr), NextInPool(nullptr) {
ArgsUnion PVal(Parm);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
@@ -257,7 +257,7 @@
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- NextInPosition(0), NextInPool(0) {
+ NextInPosition(nullptr), NextInPool(nullptr) {
ArgsVector Args;
Args.push_back(Parm1);
Args.push_back(Parm2);
@@ -275,7 +275,7 @@
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
- NextInPosition(NULL), NextInPool(NULL) {
+ NextInPosition(nullptr), NextInPool(nullptr) {
ArgsUnion PVal(ArgKind);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
@@ -293,7 +293,7 @@
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
- NextInPosition(0), NextInPool(0) {
+ NextInPosition(nullptr), NextInPool(nullptr) {
new (&getTypeBuffer()) ParsedType(typeArg);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -307,7 +307,7 @@
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
- NextInPosition(0), NextInPool(0) {
+ NextInPosition(nullptr), NextInPool(nullptr) {
new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -546,11 +546,11 @@
public:
/// Create a new pool for a factory.
- AttributePool(AttributeFactory &factory) : Factory(factory), Head(0) {}
+ AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
/// Move the given pool's allocations to this pool.
AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
- pool.Head = 0;
+ pool.Head = nullptr;
}
AttributeFactory &getFactory() const { return Factory; }
@@ -558,7 +558,7 @@
void clear() {
if (Head) {
Factory.reclaimPool(Head);
- Head = 0;
+ Head = nullptr;
}
}
@@ -566,7 +566,7 @@
void takeAllFrom(AttributePool &pool) {
if (pool.Head) {
takePool(pool.Head);
- pool.Head = 0;
+ pool.Head = nullptr;
}
}
@@ -664,18 +664,18 @@
class ParsedAttributes {
public:
ParsedAttributes(AttributeFactory &factory)
- : pool(factory), list(0) {
+ : pool(factory), list(nullptr) {
}
ParsedAttributes(const ParsedAttributes &) LLVM_DELETED_FUNCTION;
AttributePool &getPool() const { return pool; }
- bool empty() const { return list == 0; }
+ bool empty() const { return list == nullptr; }
void add(AttributeList *newAttr) {
assert(newAttr);
- assert(newAttr->getNext() == 0);
+ assert(newAttr->getNext() == nullptr);
newAttr->setNext(list);
list = newAttr;
}
@@ -697,11 +697,11 @@
void takeAllFrom(ParsedAttributes &attrs) {
addAll(attrs.list);
- attrs.list = 0;
+ attrs.list = nullptr;
pool.takeAllFrom(attrs.pool);
}
- void clear() { list = 0; pool.clear(); }
+ void clear() { list = nullptr; pool.clear(); }
AttributeList *getList() const { return list; }
/// Returns a reference to the attribute list. Try not to introduce
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 11bdb76..92a4e9a 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -397,7 +397,7 @@
CodeCompletionString *Optional;
};
- Chunk() : Kind(CK_Text), Text(0) { }
+ Chunk() : Kind(CK_Text), Text(nullptr) { }
explicit Chunk(ChunkKind Kind, const char *Text = "");
@@ -575,14 +575,14 @@
CodeCompletionTUInfo &CCTUInfo)
: Allocator(Allocator), CCTUInfo(CCTUInfo),
Priority(0), Availability(CXAvailability_Available),
- BriefComment(NULL) { }
+ BriefComment(nullptr) { }
CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo,
unsigned Priority, CXAvailabilityKind Availability)
: Allocator(Allocator), CCTUInfo(CCTUInfo),
Priority(Priority), Availability(Availability),
- BriefComment(NULL) { }
+ BriefComment(nullptr) { }
/// \brief Retrieve the allocator into which the code completion
/// strings should be allocated.
@@ -700,7 +700,7 @@
/// \brief Build a result that refers to a declaration.
CodeCompletionResult(const NamedDecl *Declaration,
unsigned Priority,
- NestedNameSpecifier *Qualifier = 0,
+ NestedNameSpecifier *Qualifier = nullptr,
bool QualifierIsInformative = false,
bool Accessible = true)
: Declaration(Declaration), Priority(Priority),
@@ -714,36 +714,34 @@
/// \brief Build a result that refers to a keyword or symbol.
CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword)
- : Declaration(0), Keyword(Keyword), Priority(Priority), StartParameter(0),
- Kind(RK_Keyword), CursorKind(CXCursor_NotImplemented),
+ : Declaration(nullptr), Keyword(Keyword), Priority(Priority),
+ StartParameter(0), Kind(RK_Keyword), CursorKind(CXCursor_NotImplemented),
Availability(CXAvailability_Available), Hidden(false),
QualifierIsInformative(0), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0)
- {
- }
+ AllParametersAreInformative(false), DeclaringEntity(false),
+ Qualifier(nullptr) {}
/// \brief Build a result that refers to a macro.
CodeCompletionResult(const IdentifierInfo *Macro,
unsigned Priority = CCP_Macro)
- : Declaration(0), Macro(Macro), Priority(Priority), StartParameter(0),
+ : Declaration(nullptr), Macro(Macro), Priority(Priority), StartParameter(0),
Kind(RK_Macro), CursorKind(CXCursor_MacroDefinition),
Availability(CXAvailability_Available), Hidden(false),
QualifierIsInformative(0), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0)
- {
- }
+ AllParametersAreInformative(false), DeclaringEntity(false),
+ Qualifier(nullptr) {}
/// \brief Build a result that refers to a pattern.
CodeCompletionResult(CodeCompletionString *Pattern,
unsigned Priority = CCP_CodePattern,
CXCursorKind CursorKind = CXCursor_NotImplemented,
CXAvailabilityKind Availability = CXAvailability_Available,
- const NamedDecl *D = 0)
+ const NamedDecl *D = nullptr)
: Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
Kind(RK_Pattern), CursorKind(CursorKind), Availability(Availability),
Hidden(false), QualifierIsInformative(0),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- DeclaringEntity(false), Qualifier(0)
+ DeclaringEntity(false), Qualifier(nullptr)
{
}
@@ -754,7 +752,8 @@
: Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
Kind(RK_Pattern), Availability(CXAvailability_Available), Hidden(false),
QualifierIsInformative(false), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0) {
+ AllParametersAreInformative(false), DeclaringEntity(false),
+ Qualifier(nullptr) {
computeCursorKindAndAvailability();
}
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 2cd10da..99941b2 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -178,9 +178,9 @@
bool isNotEmpty() const { return !isEmpty(); }
/// An error occurred during parsing of the scope specifier.
- bool isInvalid() const { return isNotEmpty() && getScopeRep() == 0; }
+ bool isInvalid() const { return isNotEmpty() && getScopeRep() == nullptr; }
/// A scope specifier is present, and it refers to a real scope.
- bool isValid() const { return isNotEmpty() && getScopeRep() != 0; }
+ bool isValid() const { return isNotEmpty() && getScopeRep() != nullptr; }
/// \brief Indicate that this nested-name-specifier is invalid.
void SetInvalid(SourceRange R) {
@@ -193,7 +193,7 @@
/// Deprecated. Some call sites intend isNotEmpty() while others intend
/// isValid().
- bool isSet() const { return getScopeRep() != 0; }
+ bool isSet() const { return getScopeRep() != nullptr; }
void clear() {
Range = SourceRange();
@@ -420,11 +420,11 @@
Friend_specified(false),
Constexpr_specified(false),
Attrs(attrFactory),
- ProtocolQualifiers(0),
+ ProtocolQualifiers(nullptr),
NumProtocolQualifiers(0),
- ProtocolLocs(0),
+ ProtocolLocs(nullptr),
writtenBS(),
- ObjCQualifiers(0) {
+ ObjCQualifiers(nullptr) {
}
~DeclSpec() {
delete [] ProtocolQualifiers;
@@ -791,7 +791,7 @@
ObjCDeclSpec()
: objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
- GetterName(0), SetterName(0) { }
+ GetterName(nullptr), SetterName(nullptr) { }
ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
void setObjCDeclQualifier(ObjCDeclQualifier DQVal) {
objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal);
@@ -905,13 +905,13 @@
/// \brief The location of the last token that describes this unqualified-id.
SourceLocation EndLocation;
- UnqualifiedId() : Kind(IK_Identifier), Identifier(0) { }
+ UnqualifiedId() : Kind(IK_Identifier), Identifier(nullptr) { }
/// \brief Clear out this unqualified-id, setting it to default (invalid)
/// state.
void clear() {
Kind = IK_Identifier;
- Identifier = 0;
+ Identifier = nullptr;
StartLocation = SourceLocation();
EndLocation = SourceLocation();
}
@@ -1126,7 +1126,7 @@
ParamInfo() {}
ParamInfo(IdentifierInfo *ident, SourceLocation iloc,
Decl *param,
- CachedTokens *DefArgTokens = 0)
+ CachedTokens *DefArgTokens = nullptr)
: Ident(ident), IdentLoc(iloc), Param(param),
DefaultArgTokens(DefArgTokens) {}
};
@@ -1231,6 +1231,10 @@
///
/// This is used in various places for error recovery.
void freeParams() {
+ for (unsigned I = 0; I < NumParams; ++I) {
+ delete Params[I].DefaultArgTokens;
+ Params[I].DefaultArgTokens = nullptr;
+ }
if (DeleteParams) {
delete[] Params;
DeleteParams = false;
@@ -1380,7 +1384,7 @@
I.Ptr.ConstQualLoc = ConstQualLoc.getRawEncoding();
I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding();
I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding();
- I.Ptr.AttrList = 0;
+ I.Ptr.AttrList = nullptr;
return I;
}
@@ -1392,7 +1396,7 @@
I.Loc = Loc;
I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
I.Ref.LValueRef = lvalue;
- I.Ref.AttrList = 0;
+ I.Ref.AttrList = nullptr;
return I;
}
@@ -1404,7 +1408,7 @@
I.Kind = Array;
I.Loc = LBLoc;
I.EndLoc = RBLoc;
- I.Arr.AttrList = 0;
+ I.Arr.AttrList = nullptr;
I.Arr.TypeQuals = TypeQuals;
I.Arr.hasStatic = isStatic;
I.Arr.isStar = isStar;
@@ -1414,8 +1418,8 @@
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
/// "TheDeclarator" is the declarator that this will be added to.
- static DeclaratorChunk getFunction(bool hasProto,
- bool isAmbiguous,
+ static DeclaratorChunk getFunction(bool HasProto,
+ bool IsAmbiguous,
SourceLocation LParenLoc,
ParamInfo *Params, unsigned NumParams,
SourceLocation EllipsisLoc,
@@ -1445,7 +1449,7 @@
I.Kind = BlockPointer;
I.Loc = Loc;
I.Cls.TypeQuals = TypeQuals;
- I.Cls.AttrList = 0;
+ I.Cls.AttrList = nullptr;
return I;
}
@@ -1456,7 +1460,7 @@
I.Kind = MemberPointer;
I.Loc = Loc;
I.Mem.TypeQuals = TypeQuals;
- I.Mem.AttrList = 0;
+ I.Mem.AttrList = nullptr;
new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
return I;
}
@@ -1468,7 +1472,7 @@
I.Kind = Paren;
I.Loc = LParenLoc;
I.EndLoc = RParenLoc;
- I.Common.AttrList = 0;
+ I.Common.AttrList = nullptr;
return I;
}
@@ -1586,7 +1590,7 @@
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
GroupingParens(false), FunctionDefinition(FDK_Declaration),
Redeclaration(false),
- Attrs(ds.getAttributePool().getFactory()), AsmLabel(0),
+ Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
InlineParamsUsed(false), Extension(false) {
}
@@ -1663,7 +1667,7 @@
DeclTypeInfo[i].destroy();
DeclTypeInfo.clear();
Attrs.clear();
- AsmLabel = 0;
+ AsmLabel = nullptr;
InlineParamsUsed = false;
CommaLoc = SourceLocation();
EllipsisLoc = SourceLocation();
@@ -1836,7 +1840,7 @@
if (Name.getKind() == UnqualifiedId::IK_Identifier)
return Name.Identifier;
- return 0;
+ return nullptr;
}
SourceLocation getIdentifierLoc() const { return Name.StartLocation; }
@@ -1891,7 +1895,7 @@
if (!DeclTypeInfo[i].isParen())
return &DeclTypeInfo[i];
}
- return 0;
+ return nullptr;
}
/// Return the outermost (furthest from the declarator) chunk of
@@ -1902,7 +1906,7 @@
if (!DeclTypeInfo[i-1].isParen())
return &DeclTypeInfo[i-1];
}
- return 0;
+ return nullptr;
}
/// isArrayOfUnknownBound - This method returns true if the declarator
@@ -2113,7 +2117,7 @@
Declarator D;
Expr *BitfieldSize;
explicit FieldDeclarator(const DeclSpec &DS)
- : D(DS, Declarator::MemberContext), BitfieldSize(0) { }
+ : D(DS, Declarator::MemberContext), BitfieldSize(nullptr) { }
};
/// \brief Represents a C++11 virt-specifier-seq.
@@ -2153,25 +2157,23 @@
SourceLocation LastLocation;
};
-/// \brief An individual capture in a lambda introducer.
-struct LambdaCapture {
- LambdaCaptureKind Kind;
- SourceLocation Loc;
- IdentifierInfo *Id;
- SourceLocation EllipsisLoc;
- ExprResult Init;
- ParsedType InitCaptureType;
- LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
- IdentifierInfo* Id,
- SourceLocation EllipsisLoc,
- ExprResult Init, ParsedType InitCaptureType)
- : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init),
- InitCaptureType(InitCaptureType)
- {}
-};
-
/// \brief Represents a complete lambda introducer.
struct LambdaIntroducer {
+ /// \brief An individual capture in a lambda introducer.
+ struct LambdaCapture {
+ LambdaCaptureKind Kind;
+ SourceLocation Loc;
+ IdentifierInfo *Id;
+ SourceLocation EllipsisLoc;
+ ExprResult Init;
+ ParsedType InitCaptureType;
+ LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
+ IdentifierInfo *Id, SourceLocation EllipsisLoc,
+ ExprResult Init, ParsedType InitCaptureType)
+ : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init),
+ InitCaptureType(InitCaptureType) {}
+ };
+
SourceRange Range;
SourceLocation DefaultLoc;
LambdaCaptureDefault Default;
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index 9a0541d..d33a723 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -248,7 +248,7 @@
/// Does this pool, or any of its ancestors, contain any diagnostics?
bool empty() const {
- return (Diagnostics.empty() && (Parent == NULL || Parent->empty()));
+ return (Diagnostics.empty() && (!Parent || Parent->empty()));
}
/// Add a diagnostic to this pool.
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
index abe974c..b2404bc 100644
--- a/include/clang/Sema/IdentifierResolver.h
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -156,7 +156,7 @@
/// template instantiation or specialization). In this case, a
/// declaration is in scope if it's in the inline namespace set of the
/// context.
- bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0,
+ bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr,
bool AllowInlineNamespace = false) const;
/// AddDecl - Link the decl to its shadowed decl chain.
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 83fb2be..64e3745 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -103,6 +103,9 @@
/// \brief The type of the object or reference being initialized.
QualType Type;
+ /// \brief The mangling number for the next reference temporary to be created.
+ mutable unsigned ManglingNumber;
+
struct LN {
/// \brief When Kind == EK_Result, EK_Exception, EK_New, the
/// location of the 'return', 'throw', or 'new' keyword,
@@ -155,19 +158,19 @@
struct C Capture;
};
- InitializedEntity() { }
+ InitializedEntity() : ManglingNumber(0) {}
/// \brief Create the initialization entity for a variable.
InitializedEntity(VarDecl *Var)
- : Kind(EK_Variable), Parent(0), Type(Var->getType()),
- VariableOrMember(Var) { }
+ : Kind(EK_Variable), Parent(nullptr), Type(Var->getType()),
+ ManglingNumber(0), VariableOrMember(Var) { }
/// \brief Create the initialization entity for the result of a
/// function, throwing an object, performing an explicit cast, or
/// initializing a parameter for which there is no declaration.
InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
bool NRVO = false)
- : Kind(Kind), Parent(0), Type(Type)
+ : Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0)
{
LocAndNRVO.Location = Loc.getRawEncoding();
LocAndNRVO.NRVO = NRVO;
@@ -176,7 +179,7 @@
/// \brief Create the initialization entity for a member subobject.
InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent)
: Kind(EK_Member), Parent(Parent), Type(Member->getType()),
- VariableOrMember(Member) { }
+ ManglingNumber(0), VariableOrMember(Member) { }
/// \brief Create the initialization entity for an array element.
InitializedEntity(ASTContext &Context, unsigned Index,
@@ -184,7 +187,8 @@
/// \brief Create the initialization entity for a lambda capture.
InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
- : Kind(EK_LambdaCapture), Parent(0), Type(FieldType)
+ : Kind(EK_LambdaCapture), Parent(nullptr), Type(FieldType),
+ ManglingNumber(0)
{
Capture.VarID = VarID;
Capture.Location = Loc.getRawEncoding();
@@ -214,7 +218,7 @@
Entity.Kind = EK_Parameter;
Entity.Type =
Context.getVariableArrayDecayedType(Type.getUnqualifiedType());
- Entity.Parent = 0;
+ Entity.Parent = nullptr;
Entity.Parameter
= (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm));
return Entity;
@@ -228,7 +232,7 @@
InitializedEntity Entity;
Entity.Kind = EK_Parameter;
Entity.Type = Context.getVariableArrayDecayedType(Type);
- Entity.Parent = 0;
+ Entity.Parent = nullptr;
Entity.Parameter = (Consumed);
return Entity;
}
@@ -258,7 +262,7 @@
/// \brief Create the initialization entity for a temporary.
static InitializedEntity InitializeTemporary(QualType Type) {
InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
- Result.TypeInfo = 0;
+ Result.TypeInfo = nullptr;
return Result;
}
@@ -290,14 +294,16 @@
}
/// \brief Create the initialization entity for a member subobject.
- static InitializedEntity InitializeMember(FieldDecl *Member,
- const InitializedEntity *Parent = 0) {
+ static InitializedEntity
+ InitializeMember(FieldDecl *Member,
+ const InitializedEntity *Parent = nullptr) {
return InitializedEntity(Member, Parent);
}
/// \brief Create the initialization entity for a member subobject.
- static InitializedEntity InitializeMember(IndirectFieldDecl *Member,
- const InitializedEntity *Parent = 0) {
+ static InitializedEntity
+ InitializeMember(IndirectFieldDecl *Member,
+ const InitializedEntity *Parent = nullptr) {
return InitializedEntity(Member->getAnonField(), Parent);
}
@@ -341,7 +347,7 @@
if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit)
return TypeInfo;
- return 0;
+ return nullptr;
}
/// \brief Retrieve the name of the entity being initialized.
@@ -418,6 +424,8 @@
Kind = EK_Parameter_CF_Audited;
}
+ unsigned allocateManglingNumber() const { return ++ManglingNumber; }
+
/// Dump a representation of the initialized entity to standard error,
/// for debugging purposes.
void dump() const;
@@ -882,7 +890,7 @@
const InitializedEntity &Entity,
const InitializationKind &Kind,
MultiExprArg Args,
- QualType *ResultType = 0);
+ QualType *ResultType = nullptr);
/// \brief Diagnose an potentially-invalid initialization sequence.
///
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index 03643b0..00cc164 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -130,8 +130,8 @@
Sema::LookupNameKind LookupKind,
Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
: ResultKind(NotFound),
- Paths(0),
- NamingClass(0),
+ Paths(nullptr),
+ NamingClass(nullptr),
SemaRef(SemaRef),
NameInfo(NameInfo),
LookupKind(LookupKind),
@@ -152,8 +152,8 @@
SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
: ResultKind(NotFound),
- Paths(0),
- NamingClass(0),
+ Paths(nullptr),
+ NamingClass(nullptr),
SemaRef(SemaRef),
NameInfo(Name, NameLoc),
LookupKind(LookupKind),
@@ -172,8 +172,8 @@
/// disabled.
LookupResult(TemporaryToken _, const LookupResult &Other)
: ResultKind(NotFound),
- Paths(0),
- NamingClass(0),
+ Paths(nullptr),
+ NamingClass(nullptr),
SemaRef(Other.SemaRef),
NameInfo(Other.NameInfo),
LookupKind(Other.LookupKind),
@@ -303,7 +303,7 @@
/// if there is one.
NamedDecl *getAcceptableDecl(NamedDecl *D) const {
if (!D->isInIdentifierNamespace(IDNS))
- return 0;
+ return nullptr;
if (isHiddenDeclarationVisible() || isVisible(SemaRef, D))
return D;
@@ -324,7 +324,7 @@
/// \brief Returns whether these results arose from performing a
/// lookup into a class.
bool isClassLookup() const {
- return NamingClass != 0;
+ return NamingClass != nullptr;
}
/// \brief Returns the 'naming class' for this lookup, i.e. the
@@ -421,7 +421,7 @@
if (Paths) {
deletePaths(Paths);
- Paths = 0;
+ Paths = nullptr;
}
} else {
AmbiguityKind SavedAK = Ambiguity;
@@ -434,14 +434,14 @@
Ambiguity = SavedAK;
} else if (Paths) {
deletePaths(Paths);
- Paths = 0;
+ Paths = nullptr;
}
}
}
template <class DeclClass>
DeclClass *getAsSingle() const {
- if (getResultKind() != Found) return 0;
+ if (getResultKind() != Found) return nullptr;
return dyn_cast<DeclClass>(getFoundDecl());
}
@@ -491,8 +491,8 @@
ResultKind = NotFound;
Decls.clear();
if (Paths) deletePaths(Paths);
- Paths = NULL;
- NamingClass = 0;
+ Paths = nullptr;
+ NamingClass = nullptr;
Shadowed = false;
}
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index 1f517e7..7860b6d 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -67,6 +67,10 @@
/// building a new declaration.
Decl *GetExternalDecl(uint32_t ID) override;
+ /// \brief Complete the redeclaration chain if it's been extended since the
+ /// previous generation of the AST source.
+ void CompleteRedeclChain(const Decl *D) override;
+
/// \brief Resolve a selector ID into a selector.
Selector GetExternalSelector(uint32_t ID) override;
@@ -109,7 +113,7 @@
/// \return true if an error occurred
ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
SmallVectorImpl<Decl*> &Result) {
- return FindExternalLexicalDecls(DC, 0, Result);
+ return FindExternalLexicalDecls(DC, nullptr, Result);
}
template <typename DeclTy>
diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h
index 94e3807..2003356 100644
--- a/include/clang/Sema/ObjCMethodList.h
+++ b/include/clang/Sema/ObjCMethodList.h
@@ -26,7 +26,7 @@
/// \brief The next list object and 2 bits for extra info.
llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits;
- ObjCMethodList() : Method(0) { }
+ ObjCMethodList() : Method(nullptr) { }
ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C)
: Method(M), NextAndExtraBits(C, 0) { }
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 7086b72..9618f8f 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -364,7 +364,7 @@
}
void init(FailureKind K, QualType From, QualType To) {
Kind = K;
- FromExpr = 0;
+ FromExpr = nullptr;
setFromType(From);
setToType(To);
}
@@ -679,11 +679,35 @@
return CanFix;
}
+
+ unsigned getNumParams() const {
+ if (IsSurrogate) {
+ auto STy = Surrogate->getConversionType();
+ while (STy->isPointerType() || STy->isReferenceType())
+ STy = STy->getPointeeType();
+ return STy->getAs<FunctionProtoType>()->getNumParams();
+ }
+ if (Function)
+ return Function->getNumParams();
+ return ExplicitCallArguments;
+ }
};
/// OverloadCandidateSet - A set of overload candidates, used in C++
/// overload resolution (C++ 13.3).
class OverloadCandidateSet {
+ public:
+ enum CandidateSetKind {
+ /// Normal lookup.
+ CSK_Normal,
+ /// Lookup for candidates for a call using operator syntax. Candidates
+ /// that have no parameters of class type will be skipped unless there
+ /// is a parameter of (reference to) enum type and the corresponding
+ /// argument is of the same enum type.
+ CSK_Operator
+ };
+
+ private:
SmallVector<OverloadCandidate, 16> Candidates;
llvm::SmallPtrSet<Decl *, 16> Functions;
@@ -692,6 +716,7 @@
llvm::BumpPtrAllocator ConversionSequenceAllocator;
SourceLocation Loc;
+ CandidateSetKind Kind;
unsigned NumInlineSequences;
char InlineSpace[16 * sizeof(ImplicitConversionSequence)];
@@ -702,10 +727,12 @@
void destroyCandidates();
public:
- OverloadCandidateSet(SourceLocation Loc) : Loc(Loc), NumInlineSequences(0){}
+ OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
+ : Loc(Loc), Kind(CSK), NumInlineSequences(0) {}
~OverloadCandidateSet() { destroyCandidates(); }
SourceLocation getLocation() const { return Loc; }
+ CandidateSetKind getKind() const { return Kind; }
/// \brief Determine when this overload candidate will be new to the
/// overload set.
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index 4bbefcb..189c5af 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -49,7 +49,7 @@
typedef llvm::PointerLikeTypeTraits<PtrTy> Traits;
public:
- OpaquePtr() : Ptr(0) {}
+ OpaquePtr() : Ptr(nullptr) {}
static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
@@ -79,7 +79,7 @@
Ptr = Traits::getAsVoidPointer(P);
}
- LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
+ LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; }
void *getAsOpaquePtr() const { return Ptr; }
static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h
index 94db454..b36425f 100644
--- a/include/clang/Sema/ParsedTemplate.h
+++ b/include/clang/Sema/ParsedTemplate.h
@@ -35,7 +35,7 @@
/// \brief Build an empty template argument.
///
/// This template argument is invalid.
- ParsedTemplateArgument() : Kind(Type), Arg(0) { }
+ ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
/// \brief Create a template type argument or non-type template argument.
///
@@ -61,7 +61,7 @@
SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
/// \brief Determine whether the given template argument is invalid.
- bool isInvalid() const { return Arg == 0; }
+ bool isInvalid() const { return Arg == nullptr; }
/// \brief Determine what kind of template argument we have.
KindType getKind() const { return Kind; }
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index 54ca2a6..d1867b3 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_SEMA_SCOPE_H
#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -28,6 +29,7 @@
class Decl;
class UsingDirectiveDecl;
+class VarDecl;
/// Scope - A scope is a transient data structure that is used while parsing the
/// program. It assists with resolving identifiers to the appropriate
@@ -167,7 +169,11 @@
/// \brief Used to determine if errors occurred in this scope.
DiagnosticErrorTrap ErrorTrap;
-
+
+ /// A lattice consisting of undefined, a single NRVO candidate variable in
+ /// this scope, or over-defined. The bit is true when over-defined.
+ llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
+
public:
Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
: ErrorTrap(Diag) {
@@ -373,6 +379,24 @@
UsingDirectives.end());
}
+ void addNRVOCandidate(VarDecl *VD) {
+ if (NRVO.getInt())
+ return;
+ if (NRVO.getPointer() == nullptr) {
+ NRVO.setPointer(VD);
+ return;
+ }
+ if (NRVO.getPointer() != VD)
+ setNoNRVO();
+ }
+
+ void setNoNRVO() {
+ NRVO.setInt(1);
+ NRVO.setPointer(nullptr);
+ }
+
+ void mergeNRVOIntoParent();
+
/// Init - This is used by the parser to implement scope caching.
///
void Init(Scope *parent, unsigned flags);
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 98af371..63427aa 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -405,7 +405,7 @@
enum IsThisCapture { ThisCapture };
Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
QualType CaptureType, Expr *Cpy)
- : VarAndNested(0, IsNested),
+ : VarAndNested(nullptr, IsNested),
InitExprAndCaptureKind(Cpy, Cap_This),
Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
@@ -663,10 +663,10 @@
SourceLocation PotentialThisCaptureLocation;
LambdaScopeInfo(DiagnosticsEngine &Diag)
- : CapturingScopeInfo(Diag, ImpCap_None), Lambda(0),
- CallOperator(0), NumExplicitCaptures(0), Mutable(false),
+ : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
+ CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false),
- AutoTemplateParameterDepth(0), GLTemplateParameterList(0)
+ AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr)
{
Kind = SK_Lambda;
}
@@ -787,7 +787,7 @@
};
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
- : Base(0, false), Property(0) {}
+ : Base(nullptr, false), Property(nullptr) {}
FunctionScopeInfo::WeakObjectProfileTy
FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index ea9344d..ecb405c 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -26,11 +26,11 @@
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/ExpressionTraits.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TypeTraits.h"
-#include "clang/Lex/ModuleLoader.h"
#include "clang/Sema/AnalysisBasedWarnings.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ExternalSemaSource.h"
@@ -47,6 +47,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include <deque>
#include <memory>
@@ -124,6 +125,8 @@
class LocalInstantiationScope;
class LookupResult;
class MacroInfo;
+ typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath;
+ class ModuleLoader;
class MultiLevelTemplateArgumentList;
class NamedDecl;
class NonNullAttr;
@@ -274,6 +277,15 @@
PVDK_Reset ///< #pragma vtordisp()
};
+ enum PragmaMsStackAction {
+ PSK_Reset, // #pragma ()
+ PSK_Set, // #pragma ("name")
+ PSK_Push, // #pragma (push[, id])
+ PSK_Push_Set, // #pragma (push[, id], "name")
+ PSK_Pop, // #pragma (pop[, id])
+ PSK_Pop_Set, // #pragma (pop[, id], "name")
+ };
+
/// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft
/// C++ ABI. Possible values are 0, 1, and 2, which mean:
///
@@ -289,9 +301,43 @@
/// \brief Source location for newly created implicit MSInheritanceAttrs
SourceLocation ImplicitMSInheritanceAttrLoc;
+ template<typename ValueType>
+ struct PragmaStack {
+ struct Slot {
+ llvm::StringRef StackSlotLabel;
+ ValueType Value;
+ SourceLocation PragmaLocation;
+ Slot(llvm::StringRef StackSlotLabel,
+ ValueType Value,
+ SourceLocation PragmaLocation)
+ : StackSlotLabel(StackSlotLabel), Value(Value),
+ PragmaLocation(PragmaLocation) {}
+ };
+ void Act(SourceLocation PragmaLocation,
+ PragmaMsStackAction Action,
+ llvm::StringRef StackSlotLabel,
+ ValueType Value);
+ explicit PragmaStack(const ValueType &Value)
+ : CurrentValue(Value) {}
+ SmallVector<Slot, 2> Stack;
+ ValueType CurrentValue;
+ SourceLocation CurrentPragmaLocation;
+ };
+ // FIXME: We should serialize / deserialize these if they occur in a PCH (but
+ // we shouldn't do so if they're in a module).
+ PragmaStack<StringLiteral *> DataSegStack;
+ PragmaStack<StringLiteral *> BSSSegStack;
+ PragmaStack<StringLiteral *> ConstSegStack;
+ PragmaStack<StringLiteral *> CodeSegStack;
+
/// VisContext - Manages the stack for \#pragma GCC visibility.
void *VisContext; // Really a "PragmaVisStack*"
+ /// \brief This represents the last location of a "#pragma clang optimize off"
+ /// directive if such a directive has not been closed by an "on" yet. If
+ /// optimizations are currently "on", this is set to an invalid location.
+ SourceLocation OptimizeOffPragmaLocation;
+
/// \brief Flag indicating if Sema is building a recovery call expression.
///
/// This flag is used to avoid building recovery call expressions
@@ -452,13 +498,13 @@
sema::DelayedDiagnosticPool *CurPool;
public:
- DelayedDiagnostics() : CurPool(0) {}
+ DelayedDiagnostics() : CurPool(nullptr) {}
/// Adds a delayed diagnostic.
void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h
/// Determines whether diagnostics should be delayed.
- bool shouldDelayDiagnostics() { return CurPool != 0; }
+ bool shouldDelayDiagnostics() { return CurPool != nullptr; }
/// Returns the current delayed-diagnostics pool.
sema::DelayedDiagnosticPool *getCurrentPool() const {
@@ -486,13 +532,13 @@
DelayedDiagnosticsState pushUndelayed() {
DelayedDiagnosticsState state;
state.SavedPool = CurPool;
- CurPool = 0;
+ CurPool = nullptr;
return state;
}
/// Undo a previous pushUndelayed().
void popUndelayed(DelayedDiagnosticsState state) {
- assert(CurPool == NULL);
+ assert(CurPool == nullptr);
CurPool = state.SavedPool;
}
} DelayedDiagnostics;
@@ -522,7 +568,7 @@
S.CurContext = SavedContext;
S.DelayedDiagnostics.popUndelayed(SavedContextState);
S.CXXThisTypeOverride = SavedCXXThisTypeOverride;
- SavedContext = 0;
+ SavedContext = nullptr;
}
~ContextRAII() {
@@ -800,7 +846,7 @@
/// \brief The number of SFINAE diagnostics that have been trapped.
unsigned NumSFINAEErrors;
- typedef llvm::DenseMap<ParmVarDecl *, SmallVector<ParmVarDecl *, 1> >
+ typedef llvm::DenseMap<ParmVarDecl *, llvm::TinyPtrVector<ParmVarDecl *>>
UnparsedDefaultArgInstantiationsMap;
/// \brief A mapping from parameters with unparsed default arguments to the
@@ -890,7 +936,7 @@
public:
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
TranslationUnitKind TUKind = TU_Complete,
- CodeCompleteConsumer *CompletionConsumer = 0);
+ CodeCompleteConsumer *CompletionConsumer = nullptr);
~Sema();
/// \brief Perform initialization that occurs after the parser has been
@@ -984,6 +1030,12 @@
getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const;
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const;
+ /// \brief Calls \c Lexer::getLocForEndOfToken()
+ SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
+
+ /// \brief Retrieve the module loader associated with the preprocessor.
+ ModuleLoader &getModuleLoader() const;
+
ExprResult Owned(Expr* E) { return E; }
ExprResult Owned(ExprResult R) { return R; }
StmtResult Owned(Stmt* S) { return S; }
@@ -1006,8 +1058,10 @@
void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD,
RecordDecl *RD,
CapturedRegionKind K);
- void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP =0,
- const Decl *D = 0, const BlockExpr *blkExpr = 0);
+ void
+ PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr,
+ const Decl *D = nullptr,
+ const BlockExpr *blkExpr = nullptr);
sema::FunctionScopeInfo *getCurFunction() const {
return FunctionScopes.back();
@@ -1015,14 +1069,14 @@
sema::FunctionScopeInfo *getEnclosingFunction() const {
if (FunctionScopes.empty())
- return 0;
+ return nullptr;
for (int e = FunctionScopes.size()-1; e >= 0; --e) {
if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
continue;
return FunctionScopes[e];
}
- return 0;
+ return nullptr;
}
template <typename ExprT>
@@ -1060,9 +1114,9 @@
//
QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs,
- const DeclSpec *DS = 0);
+ const DeclSpec *DS = nullptr);
QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA,
- const DeclSpec *DS = 0);
+ const DeclSpec *DS = nullptr);
QualType BuildPointerType(QualType T,
SourceLocation Loc, DeclarationName Entity);
QualType BuildReferenceType(QualType T, bool LValueRef,
@@ -1124,7 +1178,8 @@
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);
DeclarationNameInfo GetNameForDeclarator(Declarator &D);
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name);
- static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo = 0);
+ static QualType GetTypeFromParser(ParsedType Ty,
+ TypeSourceInfo **TInfo = nullptr);
CanThrowResult canThrow(const Expr *E);
const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
const FunctionProtoType *FPT);
@@ -1140,8 +1195,8 @@
const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
const FunctionProtoType *Old, SourceLocation OldLoc,
const FunctionProtoType *New, SourceLocation NewLoc,
- bool *MissingExceptionSpecification = 0,
- bool *MissingEmptyExceptionSpecification = 0,
+ bool *MissingExceptionSpecification = nullptr,
+ bool *MissingEmptyExceptionSpecification = nullptr,
bool AllowNoexceptAllMatchWithNoSpec = false,
bool IsOperatorNew = false);
bool CheckExceptionSpecSubset(
@@ -1344,20 +1399,20 @@
/// them into the FunctionDecl.
std::vector<NamedDecl*> DeclsInPrototypeScope;
- DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = 0);
+ DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
void DiagnoseUseOfUnimplementedSelectors();
bool isSimpleTypeSpecifier(tok::TokenKind Kind) const;
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, CXXScopeSpec *SS = 0,
+ Scope *S, CXXScopeSpec *SS = nullptr,
bool isClassName = false,
bool HasTrailingDot = false,
ParsedType ObjectType = ParsedType(),
bool IsCtorOrDtorName = false,
bool WantNontrivialTypeSourceInfo = false,
- IdentifierInfo **CorrectedII = 0);
+ IdentifierInfo **CorrectedII = nullptr);
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S);
bool DiagnoseUnknownTypeName(IdentifierInfo *&II,
@@ -1490,7 +1545,7 @@
SourceLocation NameLoc,
const Token &NextToken,
bool IsAddressOfOperand,
- CorrectionCandidateCallback *CCC = 0);
+ CorrectionCandidateCallback *CCC = nullptr);
Decl *ActOnDeclarator(Scope *S, Declarator &D);
@@ -1584,7 +1639,7 @@
SourceLocation LocAfterDecls);
void CheckForFunctionRedefinition(FunctionDecl *FD,
const FunctionDecl *EffectiveDefinition =
- 0);
+ nullptr);
Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D);
void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
@@ -1615,6 +1670,7 @@
Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation);
Decl *ActOnSkippedFunctionBody(Decl *Decl);
+ void ActOnFinishInlineMethodDef(CXXMethodDecl *D);
/// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an
/// attribute for which parsing is delayed.
@@ -1658,12 +1714,13 @@
void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
/// \brief Create an implicit import of the given module at the given
- /// source location.
+ /// source location, for error recovery, if possible.
///
- /// This routine is typically used for error recovery, when the entity found
- /// by name lookup is actually hidden within a module that we know about but
- /// the user has forgotten to import.
- void createImplicitModuleImport(SourceLocation Loc, Module *Mod);
+ /// This routine is typically used when an entity found by name lookup
+ /// is actually hidden within a module that we know about but the user
+ /// has forgotten to import.
+ void createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
+ Module *Mod);
/// \brief Retrieve a suitable printing policy.
PrintingPolicy getPrintingPolicy() const {
@@ -1755,7 +1812,7 @@
InClassInitStyle InitStyle,
SourceLocation TSSL,
AccessSpecifier AS, NamedDecl *PrevDecl,
- Declarator *D = 0);
+ Declarator *D = nullptr);
bool CheckNontrivialField(FieldDecl *FD);
void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM);
@@ -1875,7 +1932,7 @@
/// \param AllowInlineNamespace If \c true, allow the declaration to be in the
/// enclosing namespace set of the context, rather than contained
/// directly within it.
- bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = 0,
+ bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = nullptr,
bool AllowInlineNamespace = false);
/// Finds the scope corresponding to the given decl context, if it
@@ -2006,7 +2063,7 @@
QualType& ConvertedType);
bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
const FunctionProtoType *NewType,
- unsigned *ArgPos = 0);
+ unsigned *ArgPos = nullptr);
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
QualType FromType, QualType ToType);
@@ -2176,10 +2233,10 @@
bool PartialOverloading = false,
bool AllowExplicit = false);
void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
- TemplateArgumentListInfo *ExplicitTemplateArgs = 0);
+ ArrayRef<Expr *> Args,
+ OverloadCandidateSet &CandidateSet,
+ bool SuppressUserConversions = false,
+ TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
void AddMethodCandidate(DeclAccessPair FoundDecl,
QualType ObjectType,
Expr::Classification ObjectClassification,
@@ -2239,7 +2296,7 @@
SourceLocation OpLoc, ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet);
void AddArgumentDependentLookupCandidates(DeclarationName Name,
- bool Operator, SourceLocation Loc,
+ SourceLocation Loc,
ArrayRef<Expr *> Args,
TemplateArgumentListInfo *ExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
@@ -2270,11 +2327,12 @@
QualType TargetType,
bool Complain,
DeclAccessPair &Found,
- bool *pHadMultipleCandidates = 0);
+ bool *pHadMultipleCandidates = nullptr);
- FunctionDecl *ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
- bool Complain = false,
- DeclAccessPair* Found = 0);
+ FunctionDecl *
+ ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
+ bool Complain = false,
+ DeclAccessPair *Found = nullptr);
bool ResolveAndFixSingleFunctionTemplateSpecialization(
ExprResult &SrcExpr,
@@ -2360,7 +2418,7 @@
ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base,
SourceLocation OpLoc,
- bool *NoArrowOperatorFound = 0);
+ bool *NoArrowOperatorFound = nullptr);
/// CheckCallReturnType - Checks that a call expression's return type is
/// complete. Returns true on failure. The location passed in is the location
@@ -2526,6 +2584,9 @@
void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
QualType T1, QualType T2,
UnresolvedSetImpl &Functions);
+ void addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions,
+ DeclAccessPair Operator,
+ QualType T1, QualType T2);
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
SourceLocation GnuLabelLoc = SourceLocation());
@@ -2550,10 +2611,8 @@
bool AllowStringTemplate);
bool isKnownName(StringRef name);
- void ArgumentDependentLookup(DeclarationName Name, bool Operator,
- SourceLocation Loc,
- ArrayRef<Expr *> Args,
- ADLResult &Functions);
+ void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
+ ArrayRef<Expr *> Args, ADLResult &Functions);
void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
VisibleDeclConsumer &Consumer,
@@ -2562,13 +2621,19 @@
VisibleDeclConsumer &Consumer,
bool IncludeGlobalScope = true);
+ enum CorrectTypoKind {
+ CTK_NonError, // CorrectTypo used in a non error recovery situation.
+ CTK_ErrorRecovery // CorrectTypo used in normal error recovery.
+ };
+
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
Sema::LookupNameKind LookupKind,
Scope *S, CXXScopeSpec *SS,
CorrectionCandidateCallback &CCC,
- DeclContext *MemberContext = 0,
+ CorrectTypoKind Mode,
+ DeclContext *MemberContext = nullptr,
bool EnteringContext = false,
- const ObjCObjectPointerType *OPT = 0,
+ const ObjCObjectPointerType *OPT = nullptr,
bool RecordFailure = true);
void diagnoseTypo(const TypoCorrection &Correction,
@@ -2615,11 +2680,11 @@
bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
- const FunctionDecl *FD = 0);
+ const FunctionDecl *FD = nullptr);
bool CheckNoReturnAttr(const AttributeList &attr);
bool checkStringLiteralArgumentAttr(const AttributeList &Attr,
unsigned ArgNum, StringRef &Str,
- SourceLocation *ArgLocation = 0);
+ SourceLocation *ArgLocation = nullptr);
bool checkMSInheritanceAttrOnDefinition(
CXXRecordDecl *RD, SourceRange Range, bool BestCase,
MSInheritanceAttr::Spelling SemanticSpelling);
@@ -2733,7 +2798,7 @@
const unsigned AttributesAsWritten,
TypeSourceInfo *T,
tok::ObjCKeywordKind MethodImplKind,
- DeclContext *lexicalDC = 0);
+ DeclContext *lexicalDC = nullptr);
/// AtomicPropertySetterGetterRules - This routine enforces the rule (via
/// warning) when atomic property has one but not the other user-declared
@@ -2854,7 +2919,7 @@
public:
class FullExprArg {
public:
- FullExprArg(Sema &actions) : E(0) { }
+ FullExprArg(Sema &actions) : E(nullptr) { }
// FIXME: The const_cast here is ugly. RValue references would make this
// much nicer (or we could duplicate a bunch of the move semantics
@@ -3006,15 +3071,23 @@
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
CapturedRegionKind Kind, unsigned NumParams);
+ typedef std::pair<StringRef, QualType> CapturedParamNameType;
+ void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
+ CapturedRegionKind Kind,
+ ArrayRef<CapturedParamNameType> Params);
StmtResult ActOnCapturedRegionEnd(Stmt *S);
void ActOnCapturedRegionError();
RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD,
SourceLocation Loc,
unsigned NumParams);
- const VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E,
- bool AllowFunctionParameters);
+ VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E,
+ bool AllowFunctionParameters);
+ bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
+ bool AllowFunctionParameters);
- StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
+ StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
+ Scope *CurScope);
+ StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
@@ -3150,7 +3223,7 @@
bool CanUseDecl(NamedDecl *D);
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass=0);
+ const ObjCInterfaceDecl *UnknownObjCClass=nullptr);
void NoteDeletedFunction(FunctionDecl *FD);
std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
@@ -3160,7 +3233,7 @@
ArrayRef<Expr *> Args);
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
- Decl *LambdaContextDecl = 0,
+ Decl *LambdaContextDecl = nullptr,
bool IsDecltype = false);
enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl };
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
@@ -3251,7 +3324,7 @@
/// emitted; this may also leave the ExprResult invalid.
bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
bool ForceComplain = false,
- bool (*IsPlausibleResult)(QualType) = 0);
+ bool (*IsPlausibleResult)(QualType) = nullptr);
/// \brief Figure out if an expression could be turned into a call.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy,
@@ -3274,7 +3347,7 @@
SourceLocation TemplateKWLoc,
UnqualifiedId &Id,
bool HasTrailingLParen, bool IsAddressOfOperand,
- CorrectionCandidateCallback *CCC = 0,
+ CorrectionCandidateCallback *CCC = nullptr,
bool IsInlineAsmIdentifier = false);
void DecomposeUnqualifiedId(const UnqualifiedId &Id,
@@ -3282,10 +3355,11 @@
DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *&TemplateArgs);
- bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
- CorrectionCandidateCallback &CCC,
- TemplateArgumentListInfo *ExplicitTemplateArgs = 0,
- ArrayRef<Expr *> Args = None);
+ bool
+ DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
+ CorrectionCandidateCallback &CCC,
+ TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
+ ArrayRef<Expr *> Args = None);
ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S,
IdentifierInfo *II,
@@ -3300,18 +3374,20 @@
ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
ExprValueKind VK,
SourceLocation Loc,
- const CXXScopeSpec *SS = 0);
- ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
- const DeclarationNameInfo &NameInfo,
- const CXXScopeSpec *SS = 0, NamedDecl *FoundD = 0,
- const TemplateArgumentListInfo *TemplateArgs = 0);
+ const CXXScopeSpec *SS = nullptr);
+ ExprResult
+ BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
+ const DeclarationNameInfo &NameInfo,
+ const CXXScopeSpec *SS = nullptr,
+ NamedDecl *FoundD = nullptr,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr);
ExprResult
BuildAnonymousStructUnionMemberReference(
const CXXScopeSpec &SS,
SourceLocation nameLoc,
IndirectFieldDecl *indirectField,
- DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_none),
- Expr *baseObjectExpr = 0,
+ DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_none),
+ Expr *baseObjectExpr = nullptr,
SourceLocation opLoc = SourceLocation());
ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
@@ -3340,20 +3416,22 @@
bool NeedsADL);
ExprResult BuildDeclarationNameExpr(
const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
- NamedDecl *FoundD = 0, const TemplateArgumentListInfo *TemplateArgs = 0);
+ NamedDecl *FoundD = nullptr,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr);
ExprResult BuildLiteralOperatorCall(LookupResult &R,
- DeclarationNameInfo &SuffixInfo,
- ArrayRef<Expr*> Args,
- SourceLocation LitEndLoc,
- TemplateArgumentListInfo *ExplicitTemplateArgs = 0);
+ DeclarationNameInfo &SuffixInfo,
+ ArrayRef<Expr *> Args,
+ SourceLocation LitEndLoc,
+ TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
ExprResult BuildPredefinedExpr(SourceLocation Loc,
PredefinedExpr::IdentType IT);
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
- ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = 0);
- ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope = 0);
+ ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
+ ExprResult ActOnCharacterConstant(const Token &Tok,
+ Scope *UDLScope = nullptr);
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
ExprResult ActOnParenListExpr(SourceLocation L,
SourceLocation R,
@@ -3362,7 +3440,7 @@
/// ActOnStringLiteral - The specified tokens were lexed as pasted string
/// fragments (e.g. "foo" "bar" L"baz").
ExprResult ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks,
- Scope *UDLScope = 0);
+ Scope *UDLScope = nullptr);
ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc,
SourceLocation DefaultLoc,
@@ -3439,15 +3517,14 @@
bool HasTrailingLParen;
};
- ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
- SourceLocation OpLoc, bool IsArrow,
- const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierInScope,
- LookupResult &R,
- const TemplateArgumentListInfo *TemplateArgs,
- bool SuppressQualifierCheck = false,
- ActOnMemberAccessExtraArgs *ExtraArgs = 0);
+ ExprResult
+ BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc,
+ bool IsArrow, const CXXScopeSpec &SS,
+ SourceLocation TemplateKWLoc,
+ NamedDecl *FirstQualifierInScope, LookupResult &R,
+ const TemplateArgumentListInfo *TemplateArgs,
+ bool SuppressQualifierCheck = false,
+ ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base,
@@ -3493,12 +3570,13 @@
/// locations.
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
MultiExprArg ArgExprs, SourceLocation RParenLoc,
- Expr *ExecConfig = 0, bool IsExecConfig = false);
+ Expr *ExecConfig = nullptr,
+ bool IsExecConfig = false);
ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
SourceLocation LParenLoc,
ArrayRef<Expr *> Arg,
SourceLocation RParenLoc,
- Expr *Config = 0,
+ Expr *Config = nullptr,
bool IsExecConfig = false);
ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
@@ -3740,7 +3818,7 @@
NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
SourceLocation UsingLoc,
CXXScopeSpec &SS,
- const DeclarationNameInfo &NameInfo,
+ DeclarationNameInfo NameInfo,
AttributeList *AttrList,
bool IsInstantiation,
bool HasTypenameKeyword,
@@ -4164,7 +4242,7 @@
/// \return returns 'true' if failed, 'false' if success.
bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false,
bool BuildAndDiagnose = true,
- const unsigned *const FunctionScopeIndexToStopAt = 0);
+ const unsigned *const FunctionScopeIndexToStopAt = nullptr);
/// \brief Determine whether the given type is the type of *this that is used
/// outside of the body of a member function for a type that is currently
@@ -4386,7 +4464,8 @@
bool EnteringContext,
CXXScopeSpec &SS,
NamedDecl *ScopeLookupResult,
- bool ErrorRecoveryLookup);
+ bool ErrorRecoveryLookup,
+ bool *IsCorrectedToColon = nullptr);
/// \brief The parser has parsed a nested-name-specifier 'identifier::'.
///
@@ -4409,6 +4488,13 @@
/// output parameter (containing the full nested-name-specifier,
/// including this new type).
///
+ /// \param ErrorRecoveryLookup If true, then this method is called to improve
+ /// error recovery. In this case do not emit error message.
+ ///
+ /// \param IsCorrectedToColon If not null, suggestions to replace '::' -> ':'
+ /// are allowed. The bool value pointed by this parameter is set to 'true'
+ /// if the identifier is treated as if it was followed by ':', not '::'.
+ ///
/// \returns true if an error occurred, false otherwise.
bool ActOnCXXNestedNameSpecifier(Scope *S,
IdentifierInfo &Identifier,
@@ -4416,7 +4502,9 @@
SourceLocation CCLoc,
ParsedType ObjectType,
bool EnteringContext,
- CXXScopeSpec &SS);
+ CXXScopeSpec &SS,
+ bool ErrorRecoveryLookup = false,
+ bool *IsCorrectedToColon = nullptr);
ExprResult ActOnDecltypeExpression(Expr *E);
@@ -4685,13 +4773,13 @@
// C++ Classes
//
bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
- const CXXScopeSpec *SS = 0);
+ const CXXScopeSpec *SS = nullptr);
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS);
bool ActOnAccessSpecifier(AccessSpecifier Access,
SourceLocation ASLoc,
SourceLocation ColonLoc,
- AttributeList *Attrs = 0);
+ AttributeList *Attrs = nullptr);
NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
Declarator &D,
@@ -4829,8 +4917,7 @@
void ActOnFinishCXXMemberDecls();
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);
- void ActOnReenterTemplateScope(Scope *S, Decl *Template);
- void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D);
+ unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template);
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
@@ -4909,7 +4996,7 @@
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
SourceLocation Loc, SourceRange Range,
- CXXCastPath *BasePath = 0,
+ CXXCastPath *BasePath = nullptr,
bool IgnoreAccess = false);
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
unsigned InaccessibleBaseID,
@@ -5148,7 +5235,8 @@
TemplateParamListContext TPC);
TemplateParameterList *MatchTemplateParametersToScopeSpecifier(
SourceLocation DeclStartLoc, SourceLocation DeclLoc,
- const CXXScopeSpec &SS, ArrayRef<TemplateParameterList *> ParamLists,
+ const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
+ ArrayRef<TemplateParameterList *> ParamLists,
bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid);
DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
@@ -5230,12 +5318,7 @@
ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc,
SourceLocation ModulePrivateLoc,
- CXXScopeSpec &SS,
- TemplateTy Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc,
+ TemplateIdAnnotation &TemplateId,
AttributeList *Attr,
MultiTemplateParamsArg TemplateParameterLists);
@@ -5904,7 +5987,7 @@
unsigned NumExplicitlySpecified,
FunctionDecl *&Specialization,
sema::TemplateDeductionInfo &Info,
- SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = 0);
+ SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr);
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
@@ -6001,10 +6084,11 @@
// C++ Template Instantiation
//
- MultiLevelTemplateArgumentList getTemplateInstantiationArgs(NamedDecl *D,
- const TemplateArgumentList *Innermost = 0,
- bool RelativeToPrimary = false,
- const FunctionDecl *Pattern = 0);
+ MultiLevelTemplateArgumentList
+ getTemplateInstantiationArgs(NamedDecl *D,
+ const TemplateArgumentList *Innermost = nullptr,
+ bool RelativeToPrimary = false,
+ const FunctionDecl *Pattern = nullptr);
/// \brief A template instantiation that is currently in progress.
struct ActiveTemplateInstantiation {
@@ -6079,8 +6163,8 @@
SourceRange InstantiationRange;
ActiveTemplateInstantiation()
- : Kind(TemplateInstantiation), Template(0), Entity(0), TemplateArgs(0),
- NumTemplateArgs(0), DeductionInfo(0) {}
+ : Kind(TemplateInstantiation), Template(nullptr), Entity(nullptr),
+ TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {}
/// \brief Determines whether this template is an actual instantiation
/// that should be counted toward the maximum instantiation depth.
@@ -6507,7 +6591,7 @@
ParmVarDecl **Params, unsigned NumParams,
const MultiLevelTemplateArgumentList &TemplateArgs,
SmallVectorImpl<QualType> &ParamTypes,
- SmallVectorImpl<ParmVarDecl *> *OutParams = 0);
+ SmallVectorImpl<ParmVarDecl *> *OutParams = nullptr);
ExprResult SubstExpr(Expr *E,
const MultiLevelTemplateArgumentList &TemplateArgs);
@@ -6571,8 +6655,8 @@
void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
const Decl *Pattern, Decl *Inst,
- LateInstantiatedAttrVec *LateAttrs = 0,
- LocalInstantiationScope *OuterMostScope = 0);
+ LateInstantiatedAttrVec *LateAttrs = nullptr,
+ LocalInstantiationScope *OuterMostScope = nullptr);
bool
InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
@@ -6617,8 +6701,8 @@
const TemplateArgumentListInfo &TemplateArgsInfo,
SmallVectorImpl<TemplateArgument> &Converted,
SourceLocation PointOfInstantiation, void *InsertPos,
- LateInstantiatedAttrVec *LateAttrs = 0,
- LocalInstantiationScope *StartingScope = 0);
+ LateInstantiatedAttrVec *LateAttrs = nullptr,
+ LocalInstantiationScope *StartingScope = nullptr);
VarTemplateSpecializationDecl *CompleteVarTemplateSpecializationDecl(
VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl,
const MultiLevelTemplateArgumentList &TemplateArgs);
@@ -6752,8 +6836,8 @@
/// \param lexicalDC Container for redeclaredProperty.
void ProcessPropertyDecl(ObjCPropertyDecl *property,
ObjCContainerDecl *CD,
- ObjCPropertyDecl *redeclaredProperty = 0,
- ObjCContainerDecl *lexicalDC = 0);
+ ObjCPropertyDecl *redeclaredProperty = nullptr,
+ ObjCContainerDecl *lexicalDC = nullptr);
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
@@ -6774,7 +6858,7 @@
Selector GetterSel, Selector SetterSel,
bool *OverridingProperty,
tok::ObjCKeywordKind MethodImplKind,
- DeclContext *lexicalDC = 0);
+ DeclContext *lexicalDC = nullptr);
Decl *ActOnPropertyImplDecl(Scope *S,
SourceLocation AtLoc,
@@ -6939,6 +7023,9 @@
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr);
+ bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
+ CastKind &Kind);
+
bool checkObjCBridgeRelatedComponents(SourceLocation Loc,
QualType DestType, QualType SrcType,
ObjCInterfaceDecl *&RelatedClass,
@@ -7031,6 +7118,54 @@
void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc,
MSVtorDispAttr::Mode Value);
+ enum PragmaSectionKind {
+ PSK_DataSeg,
+ PSK_BSSSeg,
+ PSK_ConstSeg,
+ PSK_CodeSeg,
+ };
+
+ enum PragmaSectionFlag : unsigned {
+ PSF_None = 0,
+ PSF_Read = 0x1,
+ PSF_Write = 0x2,
+ PSF_Execute = 0x4,
+ PSF_Implicit = 0x8,
+ PSF_Invalid = 0x80000000U,
+ };
+
+ struct SectionInfo {
+ DeclaratorDecl *Decl;
+ SourceLocation PragmaSectionLocation;
+ int SectionFlags;
+ SectionInfo() {}
+ SectionInfo(DeclaratorDecl *Decl,
+ SourceLocation PragmaSectionLocation,
+ int SectionFlags)
+ : Decl(Decl),
+ PragmaSectionLocation(PragmaSectionLocation),
+ SectionFlags(SectionFlags) {}
+ };
+
+ llvm::StringMap<SectionInfo> SectionInfos;
+ bool UnifySection(const StringRef &SectionName,
+ int SectionFlags,
+ DeclaratorDecl *TheDecl);
+ bool UnifySection(const StringRef &SectionName,
+ int SectionFlags,
+ SourceLocation PragmaSectionLocation);
+
+ /// \brief Called on well formed \#pragma bss_seg/data_seg/const_seg/code_seg.
+ void ActOnPragmaMSSeg(SourceLocation PragmaLocation,
+ PragmaMsStackAction Action,
+ llvm::StringRef StackSlotLabel,
+ StringLiteral *SegmentName,
+ llvm::StringRef PragmaName);
+
+ /// \brief Called on well formed \#pragma section().
+ void ActOnPragmaMSSection(SourceLocation PragmaLocation,
+ int SectionFlags, StringLiteral *SegmentName);
+
/// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
@@ -7102,6 +7237,25 @@
/// the appropriate attribute.
void AddCFAuditedAttribute(Decl *D);
+ /// \brief Called on well formed \#pragma clang optimize.
+ void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);
+
+ /// \brief Get the location for the currently active "\#pragma clang optimize
+ /// off". If this location is invalid, then the state of the pragma is "on".
+ SourceLocation getOptimizeOffPragmaLocation() const {
+ return OptimizeOffPragmaLocation;
+ }
+
+ /// \brief Only called on function definitions; if there is a pragma in scope
+ /// with the effect of a range-based optnone, consider marking the function
+ /// with attribute optnone.
+ void AddRangeBasedOptnone(FunctionDecl *FD);
+
+ /// \brief Adds the 'optnone' attribute to the function declaration if there
+ /// are no conflicts; Loc represents the location causing the 'optnone'
+ /// attribute to be added (usually because of a pragma).
+ void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc);
+
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
unsigned SpellingListIndex, bool IsPackExpansion);
@@ -7140,6 +7294,9 @@
SourceLocation Loc,
ArrayRef<Expr *> VarList);
+ // brief Initialization of captured region for OpenMP parallel region.
+ void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, SourceLocation Loc,
+ Scope *CurScope);
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
@@ -7177,6 +7334,10 @@
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'collapse' clause.
+ OMPClause *ActOnOpenMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
unsigned Argument,
@@ -7190,11 +7351,19 @@
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'proc_bind' clause.
+ OMPClause *ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
ArrayRef<Expr *> Vars,
+ Expr *TailExpr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
SourceLocation EndLoc);
/// \brief Called on well-formed 'private' clause.
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
@@ -7211,6 +7380,13 @@
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'linear' clause.
+ OMPClause *ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList,
+ Expr *Step,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc);
/// \brief Called on well-formed 'copyin' clause.
OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
@@ -7234,7 +7410,7 @@
/// If isLvalue, the result of the cast is an lvalue.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK,
ExprValueKind VK = VK_RValue,
- const CXXCastPath *BasePath = 0,
+ const CXXCastPath *BasePath = nullptr,
CheckedConversionKind CCK
= CCK_ImplicitConversion);
@@ -7409,7 +7585,7 @@
SourceLocation Loc,
QualType DstType, QualType SrcType,
Expr *SrcExpr, AssignmentAction Action,
- bool *Complained = 0);
+ bool *Complained = nullptr);
/// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant
/// integer not in the range of enum values.
@@ -7480,10 +7656,10 @@
bool IsCompAssign = false);
QualType CheckAdditionOperands( // C99 6.5.6
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc,
- QualType* CompLHSTy = 0);
+ QualType* CompLHSTy = nullptr);
QualType CheckSubtractionOperands( // C99 6.5.6
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
- QualType* CompLHSTy = 0);
+ QualType* CompLHSTy = nullptr);
QualType CheckShiftOperands( // C99 6.5.7
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc,
bool IsCompAssign = false);
@@ -7516,10 +7692,10 @@
ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
- bool *NonStandardCompositeType = 0);
+ bool *NonStandardCompositeType = nullptr);
QualType FindCompositePointerType(SourceLocation Loc,
ExprResult &E1, ExprResult &E2,
- bool *NonStandardCompositeType = 0) {
+ bool *NonStandardCompositeType = nullptr) {
Expr *E1Tmp = E1.take(), *E2Tmp = E2.take();
QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp,
NonStandardCompositeType);
@@ -7729,7 +7905,8 @@
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
unsigned DiagID,
bool AllowFold = true);
- ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result=0);
+ ExprResult VerifyIntegerConstantExpression(Expr *E,
+ llvm::APSInt *Result = nullptr);
/// VerifyBitField - verifies that a bit field expression is an ICE and has
/// the correct width, and that the field type is valid.
@@ -7737,7 +7914,7 @@
/// Can optionally return whether the bit-field is of width 0
ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
QualType FieldTy, bool IsMsStruct,
- Expr *BitWidth, bool *ZeroWidth = 0);
+ Expr *BitWidth, bool *ZeroWidth = nullptr);
enum CUDAFunctionTarget {
CFT_Device,
@@ -7861,7 +8038,7 @@
void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
ArrayRef<IdentifierInfo *> SelIdents,
bool AtArgumentExpression,
- ObjCInterfaceDecl *Super = 0);
+ ObjCInterfaceDecl *Super = nullptr);
void CodeCompleteObjCForCollection(Scope *S,
DeclGroupPtrTy IterationVar);
void CodeCompleteObjCSelector(Scope *S,
@@ -7914,7 +8091,7 @@
private:
void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
- const ArraySubscriptExpr *ASE=0,
+ const ArraySubscriptExpr *ASE=nullptr,
bool AllowOnePastEnd=true, bool IndexNegated=false);
void CheckArrayAccess(const Expr *E);
// Used to grab the relevant information from a FormatAttr and a
@@ -7952,7 +8129,6 @@
bool CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckARM64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
@@ -7970,14 +8146,14 @@
private:
bool SemaBuiltinPrefetch(CallExpr *TheCall);
- bool SemaBuiltinMMPrefetch(CallExpr *TheCall);
- bool SemaBuiltinObjectSize(CallExpr *TheCall);
bool SemaBuiltinLongjmp(CallExpr *TheCall);
ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
AtomicExpr::AtomicOp Op);
bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
llvm::APSInt &Result);
+ bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,
+ int Low, int High);
public:
enum FormatStringType {
@@ -8029,8 +8205,8 @@
void CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
SourceLocation ReturnLoc,
bool isObjCMethod = false,
- const AttrVec *Attrs = 0,
- const FunctionDecl *FD = 0);
+ const AttrVec *Attrs = nullptr,
+ const FunctionDecl *FD = nullptr);
void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
@@ -8141,7 +8317,7 @@
public:
EnterExpressionEvaluationContext(Sema &Actions,
Sema::ExpressionEvaluationContext NewContext,
- Decl *LambdaContextDecl = 0,
+ Decl *LambdaContextDecl = nullptr,
bool IsDecltype = false)
: Actions(Actions) {
Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 0b3d32b..4ee1047 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -25,11 +25,23 @@
return PartialDiagnostic(DiagID, Context.getDiagAllocator());
}
+inline bool
+FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI) {
+ return FTI.NumParams == 1 && !FTI.isVariadic && FTI.Params[0].Ident == 0 &&
+ FTI.Params[0].Param &&
+ cast<ParmVarDecl>(FTI.Params[0].Param)->getType()->isVoidType();
+}
+
+inline bool
+FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI) {
+ // Assume FTI is well-formed.
+ return FTI.NumParams && !FTIHasSingleVoidParameter(FTI);
+}
// This requires the variable to be non-dependent and the initializer
// to not be value dependent.
inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) {
- const VarDecl *DefVD = 0;
+ const VarDecl *DefVD = nullptr;
return !isa<ParmVarDecl>(Var) &&
Var->isUsableInConstantExpressions(Context) &&
Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index 1af61d5..03fb523 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -246,7 +246,7 @@
LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
: SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
Exited(false), CombineWithOuterScope(CombineWithOuterScope),
- PartiallySubstitutedPack(0)
+ PartiallySubstitutedPack(nullptr)
{
SemaRef.CurrentInstantiationScope = this;
}
@@ -276,7 +276,7 @@
LocalInstantiationScope *newScope =
new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
- newScope->Outer = 0;
+ newScope->Outer = nullptr;
if (Outer)
newScope->Outer = Outer->cloneScopes(Outermost);
@@ -348,17 +348,17 @@
/// interest.
void ResetPartiallySubstitutedPack() {
assert(PartiallySubstitutedPack && "No partially-substituted pack");
- PartiallySubstitutedPack = 0;
- ArgsInPartiallySubstitutedPack = 0;
+ PartiallySubstitutedPack = nullptr;
+ ArgsInPartiallySubstitutedPack = nullptr;
NumArgsInPartiallySubstitutedPack = 0;
}
/// \brief Retrieve the partially-substitued template parameter pack.
///
/// If there is no partially-substituted parameter pack, returns NULL.
- NamedDecl *getPartiallySubstitutedPack(
- const TemplateArgument **ExplicitArgs = 0,
- unsigned *NumExplicitArgs = 0) const;
+ NamedDecl *
+ getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
+ unsigned *NumExplicitArgs = nullptr) const;
};
class TemplateDeclInstantiator
@@ -391,8 +391,8 @@
const MultiLevelTemplateArgumentList &TemplateArgs)
: SemaRef(SemaRef),
SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
- Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0)
- { }
+ Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(nullptr),
+ StartingScope(nullptr) {}
// Define all the decl visitors using DeclNodes.inc
#define DECL(DERIVED, BASE) \
@@ -436,8 +436,8 @@
// Disable late instantiation of attributes.
void disableLateAttributeInstantiation() {
- LateAttrs = 0;
- StartingScope = 0;
+ LateAttrs = nullptr;
+ StartingScope = nullptr;
}
LocalInstantiationScope *getStartingScope() const { return StartingScope; }
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index 1daa689..6a51314 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -48,7 +48,8 @@
public:
TemplateDeductionInfo(SourceLocation Loc)
- : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false), Expression(0) { }
+ : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
+ Expression(nullptr) {}
/// \brief Returns the location at which template argument is
/// occurring.
@@ -59,7 +60,7 @@
/// \brief Take ownership of the deduced template argument list.
TemplateArgumentList *take() {
TemplateArgumentList *Result = Deduced;
- Deduced = 0;
+ Deduced = nullptr;
return Result;
}
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index 16d7328..e5f8f4d 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -39,7 +39,7 @@
static const unsigned CallbackDistanceWeight = 150U;
TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl,
- NestedNameSpecifier *NNS = 0, unsigned CharDistance = 0,
+ NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0,
unsigned QualifierDistance = 0)
: CorrectionName(Name), CorrectionNameSpec(NNS),
CharDistance(CharDistance), QualifierDistance(QualifierDistance),
@@ -49,7 +49,7 @@
CorrectionDecls.push_back(NameDecl);
}
- TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = 0,
+ TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr,
unsigned CharDistance = 0)
: CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS),
CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
@@ -58,14 +58,14 @@
CorrectionDecls.push_back(Name);
}
- TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = 0,
+ TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr,
unsigned CharDistance = 0)
: CorrectionName(Name), CorrectionNameSpec(NNS),
CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
ForceSpecifierReplacement(false), RequiresImport(false) {}
TypoCorrection()
- : CorrectionNameSpec(0), CharDistance(0), QualifierDistance(0),
+ : CorrectionNameSpec(nullptr), CharDistance(0), QualifierDistance(0),
CallbackDistance(0), ForceSpecifierReplacement(false),
RequiresImport(false) {}
@@ -81,7 +81,7 @@
}
void setCorrectionSpecifier(NestedNameSpecifier* NNS) {
CorrectionNameSpec = NNS;
- ForceSpecifierReplacement = (NNS != 0);
+ ForceSpecifierReplacement = (NNS != nullptr);
}
void WillReplaceSpecifier(bool ForceReplacement) {
@@ -130,7 +130,7 @@
/// \brief Gets the pointer to the declaration of the typo correction
NamedDecl *getCorrectionDecl() const {
- return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : 0;
+ return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : nullptr;
}
template <class DeclClass>
DeclClass *getCorrectionDeclAs() const {
@@ -172,7 +172,7 @@
/// as the only element in the list to mark this TypoCorrection as a keyword.
void makeKeyword() {
CorrectionDecls.clear();
- CorrectionDecls.push_back(0);
+ CorrectionDecls.push_back(nullptr);
ForceSpecifierReplacement = true;
}
@@ -180,7 +180,7 @@
// item in CorrectionDecls is NULL.
bool isKeyword() const {
return !CorrectionDecls.empty() &&
- CorrectionDecls.front() == 0;
+ CorrectionDecls.front() == nullptr;
}
// Check if this TypoCorrection is the given keyword.
@@ -306,15 +306,15 @@
public:
FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
bool HasExplicitTemplateArgs,
- bool AllowNonStaticMethods = true);
+ MemberExpr *ME = nullptr);
bool ValidateCandidate(const TypoCorrection &candidate) override;
private:
unsigned NumArgs;
bool HasExplicitTemplateArgs;
- bool AllowNonStaticMethods;
DeclContext *CurContext;
+ MemberExpr *MemberFn;
};
// @brief Callback class that effectively disabled typo correction
diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h
index 6d1b64b..9c7212e 100644
--- a/include/clang/Sema/Weak.h
+++ b/include/clang/Sema/Weak.h
@@ -28,7 +28,7 @@
bool used; // identifier later declared?
public:
WeakInfo()
- : alias(0), loc(SourceLocation()), used(false) {}
+ : alias(nullptr), loc(SourceLocation()), used(false) {}
WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
: alias(Alias), loc(Loc), used(false) {}
inline IdentifierInfo * getAlias() const { return alias; }
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 35765b6..315c852 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -281,7 +281,14 @@
HEADER_SEARCH_OPTIONS = 11,
/// \brief Record code for the preprocessor options table.
- PREPROCESSOR_OPTIONS = 12
+ PREPROCESSOR_OPTIONS = 12,
+
+ /// \brief Record code for the module name.
+ MODULE_NAME = 13,
+
+ /// \brief Record code for the module map file that was used to build this
+ /// AST file.
+ MODULE_MAP_FILE = 14
};
/// \brief Record types that occur within the input-files block
@@ -535,7 +542,10 @@
UNDEFINED_BUT_USED = 49,
/// \brief Record code for late parsed template functions.
- LATE_PARSED_TEMPLATE = 50
+ LATE_PARSED_TEMPLATE = 50,
+
+ /// \brief Record code for \#pragma optimize options.
+ OPTIMIZE_PRAGMA_OPTIONS = 51
};
/// \brief Record types used within a source manager block.
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index 0218129..180f554 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
#define LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Serialization/ASTBitCodes.h"
namespace clang {
@@ -27,10 +28,8 @@
class Module;
class ASTDeserializationListener {
-protected:
- virtual ~ASTDeserializationListener();
-
public:
+ virtual ~ASTDeserializationListener();
/// \brief The ASTReader was initialized.
virtual void ReaderInitialized(ASTReader *Reader) { }
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index b0fde2b..be29d8f 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -34,12 +34,12 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/DataTypes.h"
#include <deque>
@@ -109,6 +109,9 @@
return FullVersion != getClangFullRepositoryVersion();
}
+ virtual void ReadModuleName(StringRef ModuleName) {}
+ virtual void ReadModuleMapFile(StringRef ModuleMapPath) {}
+
/// \brief Receives the language options.
///
/// \returns true to indicate the options are invalid or false otherwise.
@@ -130,8 +133,9 @@
///
/// \returns true to indicate the diagnostic options are invalid, or false
/// otherwise.
- virtual bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts,
- bool Complain) {
+ virtual bool
+ ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+ bool Complain) {
return false;
}
@@ -203,10 +207,12 @@
: First(First), Second(Second) { }
bool ReadFullVersionInformation(StringRef FullVersion) override;
+ void ReadModuleName(StringRef ModuleName) override;
+ void ReadModuleMapFile(StringRef ModuleMapPath) override;
bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain) override;
bool ReadTargetOptions(const TargetOptions &TargetOpts,
bool Complain) override;
- bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts,
+ bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
bool Complain) override;
bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
bool Complain) override;
@@ -239,6 +245,8 @@
bool Complain) override;
bool ReadTargetOptions(const TargetOptions &TargetOpts,
bool Complain) override;
+ bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+ bool Complain) override;
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
std::string &SuggestedPredefines) override;
void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
@@ -254,7 +262,7 @@
namespace reader {
class ASTIdentifierLookupTrait;
/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
- typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
+ typedef llvm::OnDiskIterableChainedHashTable<ASTDeclContextNameLookupTrait>
ASTDeclContextNameLookupTable;
}
@@ -332,6 +340,7 @@
/// \brief The receiver of deserialization events.
ASTDeserializationListener *DeserializationListener;
+ bool OwnsDeserializationListener;
SourceManager &SourceMgr;
FileManager &FileMgr;
@@ -409,12 +418,17 @@
/// in the chain.
DeclUpdateOffsetsMap DeclUpdateOffsets;
+ /// \brief Declaration updates for already-loaded declarations that we need
+ /// to apply once we finish processing an import.
+ llvm::SmallVector<std::pair<serialization::GlobalDeclID, Decl*>, 16>
+ PendingUpdateRecords;
+
struct ReplacedDeclInfo {
ModuleFile *Mod;
uint64_t Offset;
unsigned RawLoc;
- ReplacedDeclInfo() : Mod(0), Offset(0), RawLoc(0) {}
+ ReplacedDeclInfo() : Mod(nullptr), Offset(0), RawLoc(0) {}
ReplacedDeclInfo(ModuleFile *Mod, uint64_t Offset, unsigned RawLoc)
: Mod(Mod), Offset(Offset), RawLoc(RawLoc) {}
};
@@ -428,7 +442,7 @@
ModuleFile *Mod;
ArrayRef<serialization::LocalDeclID> Decls;
- FileDeclsInfo() : Mod(0) {}
+ FileDeclsInfo() : Mod(nullptr) {}
FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls)
: Mod(Mod), Decls(Decls) {}
};
@@ -754,6 +768,9 @@
/// \brief The floating point pragma option settings.
SmallVector<uint64_t, 1> FPPragmaOptions;
+ /// \brief The pragma clang optimize location (if the pragma state is "off").
+ SourceLocation OptimizeOffPragmaLocation;
+
/// \brief The OpenCL extension settings.
SmallVector<uint64_t, 1> OpenCLExtensions;
@@ -807,10 +824,6 @@
/// \brief Whether we have tried loading the global module index yet.
bool TriedLoadingGlobalIndex;
- /// \brief The current "generation" of the module file import stack, which
- /// indicates how many separate module file load operations have occurred.
- unsigned CurrentGeneration;
-
typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy;
/// \brief Mapping from switch-case IDs in the chain to switch-case statements
///
@@ -928,6 +941,10 @@
/// \brief Keeps track of the elements added to PendingDeclChains.
llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown;
+ /// \brief The list of canonical declarations whose redeclaration chains
+ /// need to be marked as incomplete once we're done deserializing things.
+ SmallVector<Decl *, 16> PendingIncompleteDeclChains;
+
/// \brief The Decl IDs for the Sema/Lexical DeclContext of a Decl that has
/// been loaded but its DeclContext was not set yet.
struct PendingDeclContextInfo {
@@ -951,6 +968,13 @@
/// once recursing loading has been completed.
llvm::SmallVector<NamedDecl *, 16> PendingOdrMergeChecks;
+ /// \brief Record definitions in which we found an ODR violation.
+ llvm::SmallDenseMap<CXXRecordDecl *, llvm::TinyPtrVector<CXXRecordDecl *>, 2>
+ PendingOdrMergeFailures;
+
+ /// \brief DeclContexts in which we have diagnosed an ODR violation.
+ llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;
+
/// \brief The set of Objective-C categories that have been deserialized
/// since the last time the declaration chains were linked.
llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized;
@@ -959,7 +983,14 @@
/// loaded, for which we will need to check for categories whenever a new
/// module is loaded.
SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
-
+
+ /// \brief A mapping from a primary context for a declaration chain to the
+ /// other declarations of that entity that also have name lookup tables.
+ /// Used when we merge together two class definitions that have different
+ /// sets of declared special member functions.
+ llvm::DenseMap<const DeclContext*, SmallVector<const DeclContext*, 2>>
+ MergedLookups;
+
typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> >
MergedDeclsMap;
@@ -1079,13 +1110,15 @@
unsigned ClientLoadCapabilities);
ASTReadResult ReadControlBlock(ModuleFile &F,
SmallVectorImpl<ImportedModule> &Loaded,
+ const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities);
- bool ReadASTBlock(ModuleFile &F);
+ ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);
bool ReadSourceManagerBlock(ModuleFile &F);
llvm::BitstreamCursor &SLocCursorForID(int ID);
SourceLocation getImportLocation(ModuleFile *F);
- bool ReadSubmoduleBlock(ModuleFile &F);
+ ASTReadResult ReadSubmoduleBlock(ModuleFile &F,
+ unsigned ClientLoadCapabilities);
static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener);
static bool ParseTargetOptions(const RecordData &Record, bool Complain,
@@ -1115,6 +1148,7 @@
RecordLocation TypeCursorForIndex(unsigned Index);
void LoadedDecl(unsigned Index, Decl *D);
Decl *ReadDeclRecord(serialization::DeclID ID);
+ void markIncompleteDeclChain(Decl *Canon);
RecordLocation DeclCursorForID(serialization::DeclID ID,
unsigned &RawLocation);
void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D);
@@ -1125,13 +1159,10 @@
RecordLocation getLocalBitOffset(uint64_t GlobalOffset);
uint64_t getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset);
- /// \brief Returns the first preprocessed entity ID that ends after BLoc.
+ /// \brief Returns the first preprocessed entity ID that begins or ends after
+ /// \arg Loc.
serialization::PreprocessedEntityID
- findBeginPreprocessedEntity(SourceLocation BLoc) const;
-
- /// \brief Returns the first preprocessed entity ID that begins after ELoc.
- serialization::PreprocessedEntityID
- findEndPreprocessedEntity(SourceLocation ELoc) const;
+ findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const;
/// \brief Find the next module that contains entities and return the ID
/// of the first entry.
@@ -1163,7 +1194,7 @@
typedef value_type& reference;
typedef value_type* pointer;
- ModuleDeclIterator() : Reader(0), Mod(0), Pos(0) { }
+ ModuleDeclIterator() : Reader(nullptr), Mod(nullptr), Pos(nullptr) { }
ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod,
const serialization::LocalDeclID *Pos)
@@ -1353,11 +1384,18 @@
}
/// \brief Set the AST deserialization listener.
- void setDeserializationListener(ASTDeserializationListener *Listener);
+ void setDeserializationListener(ASTDeserializationListener *Listener,
+ bool TakeOwnership = false);
/// \brief Determine whether this AST reader has a global index.
bool hasGlobalIndex() const { return (bool)GlobalIndex; }
+ /// \brief Return global module index.
+ GlobalModuleIndex *getGlobalIndex() { return GlobalIndex.get(); }
+
+ /// \brief Reset reader for a reload try.
+ void resetForReload() { TriedLoadingGlobalIndex = false; }
+
/// \brief Attempts to load the global index.
///
/// \returns true if loading the global index has failed for any reason.
@@ -1545,7 +1583,11 @@
/// \brief Retrieve the module file that owns the given declaration, or NULL
/// if the declaration is not from a module file.
ModuleFile *getOwningModuleFile(const Decl *D);
-
+
+ /// \brief Get the best name we know for the module that owns the given
+ /// declaration, or an empty string if the declaration is not from a module.
+ std::string getOwningModuleNameForDiagnostic(const Decl *D);
+
/// \brief Returns the source location for the decl \p ID.
SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
@@ -1554,6 +1596,10 @@
Decl *GetDecl(serialization::DeclID ID);
Decl *GetExternalDecl(uint32_t ID) override;
+ /// \brief Resolve a declaration ID into a declaration. Return 0 if it's not
+ /// been loaded yet.
+ Decl *GetExistingDecl(serialization::DeclID ID);
+
/// \brief Reads a declaration with the given local ID in the given module.
Decl *GetLocalDecl(ModuleFile &F, uint32_t LocalID) {
return GetDecl(getGlobalDeclID(F, LocalID));
@@ -1599,6 +1645,11 @@
return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I)));
}
+ /// \brief If any redeclarations of \p D have been imported since it was
+ /// last checked, this digs out those redeclarations and adds them to the
+ /// redeclaration chain for \p D.
+ void CompleteRedeclChain(const Decl *D) override;
+
/// \brief Read a CXXBaseSpecifiers ID form the given record and
/// return its global bit offset.
uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record,
@@ -1679,7 +1730,7 @@
void InitializeSema(Sema &S) override;
/// \brief Inform the semantic consumer that Sema is no longer available.
- void ForgetSema() override { SemaObj = 0; }
+ void ForgetSema() override { SemaObj = nullptr; }
/// \brief Retrieve the IdentifierInfo for the named identifier.
///
@@ -1746,7 +1797,7 @@
void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
void SetGloballyVisibleDecls(IdentifierInfo *II,
const SmallVectorImpl<uint32_t> &DeclIDs,
- SmallVectorImpl<Decl *> *Decls = 0);
+ SmallVectorImpl<Decl *> *Decls = nullptr);
/// \brief Report a diagnostic.
DiagnosticBuilder Diag(unsigned DiagID);
@@ -1783,7 +1834,7 @@
void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
Module *Owner);
- typedef llvm::SmallVector<DefMacroDirective*, 1> AmbiguousMacros;
+ typedef llvm::TinyPtrVector<DefMacroDirective *> AmbiguousMacros;
llvm::DenseMap<IdentifierInfo*, AmbiguousMacros> AmbiguousMacroDefs;
void
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 4d93c1e..ad6ecdd 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -295,7 +295,7 @@
};
public:
- DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(0) {}
+ DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(nullptr) {}
DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {}
DeclUpdate(unsigned Kind, QualType Type)
: Kind(Kind), Type(Type.getAsOpaquePtr()) {}
@@ -488,6 +488,7 @@
void WriteRedeclarations();
void WriteMergedDecls();
void WriteLateParsedTemplates(Sema &SemaRef);
+ void WriteOptimizePragmaOptions(Sema &SemaRef);
unsigned DeclParmVarAbbrev;
unsigned DeclContextLexicalAbbrev;
@@ -676,9 +677,7 @@
void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
/// \brief Mark a declaration context as needing an update.
- void AddUpdatedDeclContext(const DeclContext *DC) {
- UpdatedDeclContexts.insert(DC);
- }
+ void AddUpdatedDeclContext(const DeclContext *DC);
void RewriteDecl(const Decl *D) {
DeclsToRewrite.insert(D);
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index 0d9835a..1f0d752 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -186,6 +186,9 @@
/// \brief Print statistics to standard error.
void printStats();
+ /// \brief Print debugging view to standard error.
+ void dump();
+
/// \brief Write a global index into the given
///
/// \param FileMgr The file manager to use to load module files.
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 469785d..4952039 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -23,12 +23,16 @@
#include <memory>
#include <string>
+namespace llvm {
+template <typename Info> class OnDiskChainedHashTable;
+template <typename Info> class OnDiskIterableChainedHashTable;
+}
+
namespace clang {
class FileEntry;
class DeclContext;
class Module;
-template<typename Info> class OnDiskChainedHashTable;
namespace serialization {
@@ -49,7 +53,7 @@
DeclContextInfo()
: NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {}
- OnDiskChainedHashTable<reader::ASTDeclContextNameLookupTrait>
+ llvm::OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait>
*NameLookupTableData; // an ASTDeclContextNameLookupTable.
const KindDeclIDPair *LexicalDecls;
unsigned NumLexicalDecls;
@@ -115,6 +119,9 @@
/// \brief The file name of the module file.
std::string FileName;
+ /// \brief The name of the module.
+ std::string ModuleName;
+
std::string getTimestampFilename() const {
return FileName + ".timestamp";
}
@@ -136,6 +143,8 @@
/// allow resolving headers even after headers+PCH was moved to a new path.
std::string OriginalDir;
+ std::string ModuleMapPath;
+
/// \brief Whether this precompiled header is a relocatable PCH file.
bool RelocatablePCH;
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index ca643ba..08c1735 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -65,7 +65,7 @@
/// calls to visit().
struct VisitState {
explicit VisitState(unsigned N)
- : VisitNumber(N, 0), NextVisitNumber(1), NextState(0)
+ : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
{
Stack.reserve(N);
}
@@ -230,7 +230,7 @@
/// Any module that is known to both the global module index and the module
/// manager that is *not* in this set can be skipped.
void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
- llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = 0);
+ llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = nullptr);
/// \brief Visit each of the modules with a depth-first traversal.
///
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index ccbc47f..5371231 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -144,19 +144,18 @@
public:
BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
- : BT(bt), DeclWithIssue(0), Description(desc), ErrorNode(errornode),
+ : BT(bt), DeclWithIssue(nullptr), Description(desc), ErrorNode(errornode),
ConfigurationChangeToken(0), DoNotPrunePath(false) {}
BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
const ExplodedNode *errornode)
- : BT(bt), DeclWithIssue(0), ShortDescription(shortDesc), Description(desc),
- ErrorNode(errornode), ConfigurationChangeToken(0),
+ : BT(bt), DeclWithIssue(nullptr), ShortDescription(shortDesc),
+ Description(desc), ErrorNode(errornode), ConfigurationChangeToken(0),
DoNotPrunePath(false) {}
- BugReport(BugType& bt, StringRef desc, PathDiagnosticLocation l)
- : BT(bt), DeclWithIssue(0), Description(desc), Location(l), ErrorNode(0),
- ConfigurationChangeToken(0),
- DoNotPrunePath(false) {}
+ BugReport(BugType &bt, StringRef desc, PathDiagnosticLocation l)
+ : BT(bt), DeclWithIssue(nullptr), Description(desc), Location(l),
+ ErrorNode(nullptr), ConfigurationChangeToken(0), DoNotPrunePath(false) {}
/// \brief Create a BugReport with a custom uniqueing location.
///
@@ -167,7 +166,7 @@
/// the allocation site, rather then the location where the bug is reported.
BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode,
PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)
- : BT(bt), DeclWithIssue(0), Description(desc),
+ : BT(bt), DeclWithIssue(nullptr), Description(desc),
UniqueingLocation(LocationToUnique),
UniqueingDecl(DeclToUnique),
ErrorNode(errornode), ConfigurationChangeToken(0),
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index 302e0f8..f352f80 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -185,7 +185,7 @@
/// Visitor that tries to report interesting diagnostics from conditions.
class ConditionBRVisitor : public BugReporterVisitorImpl<ConditionBRVisitor> {
public:
- void Profile(llvm::FoldingSetNodeID &ID) const override{
+ void Profile(llvm::FoldingSetNodeID &ID) const override {
static int x = 0;
ID.AddPointer(&x);
}
@@ -265,7 +265,7 @@
const ExplodedNode *Prev,
BugReporterContext &BRC,
BugReport &BR) override {
- return 0;
+ return nullptr;
}
PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index cc31593..5a578d0 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -72,7 +72,9 @@
struct FilesMade : public llvm::FoldingSet<PDFileEntry> {
llvm::BumpPtrAllocator Alloc;
-
+
+ ~FilesMade();
+
void addDiagnostic(const PathDiagnostic &PD,
StringRef ConsumerName,
StringRef fileName);
@@ -136,29 +138,29 @@
PathDiagnosticLocation(SourceLocation L, const SourceManager &sm,
Kind kind)
- : K(kind), S(0), D(0), SM(&sm),
+ : K(kind), S(nullptr), D(nullptr), SM(&sm),
Loc(genLocation(L)), Range(genRange()) {
}
- FullSourceLoc
- genLocation(SourceLocation L = SourceLocation(),
- LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext*)0) const;
+ FullSourceLoc genLocation(
+ SourceLocation L = SourceLocation(),
+ LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext *)nullptr) const;
- PathDiagnosticRange
- genRange(LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext*)0) const;
+ PathDiagnosticRange genRange(
+ LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext *)nullptr) const;
public:
/// Create an invalid location.
PathDiagnosticLocation()
- : K(SingleLocK), S(0), D(0), SM(0) {}
+ : K(SingleLocK), S(nullptr), D(nullptr), SM(nullptr) {}
/// Create a location corresponding to the given statement.
PathDiagnosticLocation(const Stmt *s,
const SourceManager &sm,
LocationOrAnalysisDeclContext lac)
: K(s->getLocStart().isValid() ? StmtK : SingleLocK),
- S(K == StmtK ? s : 0),
- D(0), SM(&sm),
+ S(K == StmtK ? s : nullptr),
+ D(nullptr), SM(&sm),
Loc(genLocation(SourceLocation(), lac)),
Range(genRange(lac)) {
assert(K == SingleLocK || S);
@@ -168,7 +170,7 @@
/// Create a location corresponding to the given declaration.
PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
- : K(DeclK), S(0), D(d), SM(&sm),
+ : K(DeclK), S(nullptr), D(d), SM(&sm),
Loc(genLocation()), Range(genRange()) {
assert(D);
assert(Loc.isValid());
@@ -179,7 +181,8 @@
///
/// This should only be used if there are no more appropriate constructors.
PathDiagnosticLocation(SourceLocation loc, const SourceManager &sm)
- : K(SingleLocK), S(0), D(0), SM(&sm), Loc(loc, sm), Range(genRange()) {
+ : K(SingleLocK), S(nullptr), D(nullptr), SM(&sm), Loc(loc, sm),
+ Range(genRange()) {
assert(Loc.isValid());
assert(Range.isValid());
}
@@ -262,7 +265,7 @@
}
bool isValid() const {
- return SM != 0;
+ return SM != nullptr;
}
FullSourceLoc asLocation() const {
@@ -504,7 +507,7 @@
public:
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
StringRef s, bool addPosRange = true,
- StackHintGenerator *stackHint = 0)
+ StackHintGenerator *stackHint = nullptr)
: PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
CallStackHint(stackHint) {}
@@ -544,11 +547,11 @@
class PathDiagnosticCallPiece : public PathDiagnosticPiece {
PathDiagnosticCallPiece(const Decl *callerD,
const PathDiagnosticLocation &callReturnPos)
- : PathDiagnosticPiece(Call), Caller(callerD), Callee(0),
+ : PathDiagnosticPiece(Call), Caller(callerD), Callee(nullptr),
NoExit(false), callReturn(callReturnPos) {}
PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller)
- : PathDiagnosticPiece(Call), Caller(caller), Callee(0),
+ : PathDiagnosticPiece(Call), Caller(caller), Callee(nullptr),
NoExit(true), path(oldPath) {}
const Decl *Caller;
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index be1e9cf..b9a5b8a 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -526,7 +526,7 @@
class EventDispatcher {
CheckerManager *Mgr;
public:
- EventDispatcher() : Mgr(0) { }
+ EventDispatcher() : Mgr(nullptr) { }
template <typename CHECKER>
static void _register(CHECKER *checker, CheckerManager &mgr) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 2c799c0..08905fd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -79,9 +79,9 @@
const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
public:
- BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator& Alloc)
- : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0),
- SValListFactory(Alloc) {}
+ BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
+ : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(nullptr),
+ PersistentSValPairs(nullptr), SValListFactory(Alloc) {}
~BasicValueFactory();
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
index abb9519..0408070 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
@@ -33,7 +33,7 @@
BlockCounter(void *D) : Data(D) {}
public:
- BlockCounter() : Data(0) {}
+ BlockCounter() : Data(nullptr) {}
unsigned getNumVisited(const StackFrameContext *CallSite,
unsigned BlockID) const;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index d347be0..028875d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -86,15 +86,15 @@
const MemRegion *R;
public:
- RuntimeDefinition(): D(0), R(0) {}
- RuntimeDefinition(const Decl *InD): D(InD), R(0) {}
+ RuntimeDefinition(): D(nullptr), R(nullptr) {}
+ RuntimeDefinition(const Decl *InD): D(InD), R(nullptr) {}
RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
const Decl *getDecl() { return D; }
/// \brief Check if the definition we have is precise.
/// If not, it is possible that the call dispatches to another definition at
/// execution time.
- bool mayHaveOtherDefinitions() { return R != 0; }
+ bool mayHaveOtherDefinitions() { return R != nullptr; }
/// When other definitions are possible, returns the region whose runtime type
/// determines the method definition.
@@ -237,7 +237,7 @@
/// \brief Returns the expression associated with a given argument.
/// May be null if this expression does not appear in the source.
- virtual const Expr *getArgExpr(unsigned Index) const { return 0; }
+ virtual const Expr *getArgExpr(unsigned Index) const { return nullptr; }
/// \brief Returns the source range for errors associated with this argument.
///
@@ -293,20 +293,20 @@
const IdentifierInfo *getCalleeIdentifier() const {
const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl());
if (!ND)
- return 0;
+ return nullptr;
return ND->getIdentifier();
}
/// \brief Returns an appropriate ProgramPoint for this call.
ProgramPoint getProgramPoint(bool IsPreVisit = false,
- const ProgramPointTag *Tag = 0) const;
+ const ProgramPointTag *Tag = nullptr) const;
/// \brief Returns a new state with all argument regions invalidated.
///
/// This accepts an alternate state in case some processing has already
/// occurred.
ProgramStateRef invalidateRegions(unsigned BlockCount,
- ProgramStateRef Orig = 0) const;
+ ProgramStateRef Orig = nullptr) const;
typedef std::pair<Loc, SVal> FrameBindingTy;
typedef SmallVectorImpl<FrameBindingTy> BindingsTy;
@@ -493,7 +493,7 @@
const BlockDecl *getDecl() const override {
const BlockDataRegion *BR = getBlockRegion();
if (!BR)
- return 0;
+ return nullptr;
return BR->getDecl();
}
@@ -535,7 +535,7 @@
public:
/// \brief Returns the expression representing the implicit 'this' object.
- virtual const Expr *getCXXThisExpr() const { return 0; }
+ virtual const Expr *getCXXThisExpr() const { return nullptr; }
/// \brief Returns the value of the implicit 'this' object.
virtual SVal getCXXThisVal() const;
@@ -764,7 +764,7 @@
const Expr *getArgExpr(unsigned Index) const override {
// The first argument of an allocator call is the size of the allocation.
if (Index == 0)
- return 0;
+ return nullptr;
return getOriginExpr()->getPlacementArg(Index - 1);
}
@@ -797,7 +797,7 @@
ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
const LocationContext *LCtx)
: CallEvent(Msg, St, LCtx) {
- Data = 0;
+ Data = nullptr;
}
ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 0b9762a..143eb95 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -183,7 +183,7 @@
ProgramPoint L = N->getLocation();
if (Optional<PostStore> PSL = L.getAs<PostStore>())
return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
- return 0;
+ return nullptr;
}
/// \brief Get the value of arbitrary expressions at this point in the path.
@@ -200,9 +200,9 @@
/// tag is specified, a default tag, unique to the given checker,
/// will be used. Tags are used to prevent states generated at
/// different sites from caching out.
- ExplodedNode *addTransition(ProgramStateRef State = 0,
- const ProgramPointTag *Tag = 0) {
- return addTransitionImpl(State ? State : getState(), false, 0, Tag);
+ ExplodedNode *addTransition(ProgramStateRef State = nullptr,
+ const ProgramPointTag *Tag = nullptr) {
+ return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
}
/// \brief Generates a new transition with the given predecessor.
@@ -214,15 +214,15 @@
/// @param Tag The tag to uniquely identify the creation site.
ExplodedNode *addTransition(ProgramStateRef State,
ExplodedNode *Pred,
- const ProgramPointTag *Tag = 0) {
+ const ProgramPointTag *Tag = nullptr) {
return addTransitionImpl(State, false, Pred, Tag);
}
/// \brief Generate a sink node. Generating a sink stops exploration of the
/// given path.
- ExplodedNode *generateSink(ProgramStateRef State = 0,
- ExplodedNode *Pred = 0,
- const ProgramPointTag *Tag = 0) {
+ ExplodedNode *generateSink(ProgramStateRef State = nullptr,
+ ExplodedNode *Pred = nullptr,
+ const ProgramPointTag *Tag = nullptr) {
return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
}
@@ -244,7 +244,7 @@
if (FunDecl)
return FunDecl->getIdentifier();
else
- return 0;
+ return nullptr;
}
/// \brief Get the name of the called function (path-sensitive).
@@ -280,8 +280,8 @@
private:
ExplodedNode *addTransitionImpl(ProgramStateRef State,
bool MarkAsSink,
- ExplodedNode *P = 0,
- const ProgramPointTag *Tag = 0) {
+ ExplodedNode *P = nullptr,
+ const ProgramPointTag *Tag = nullptr) {
if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
return Pred;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 1e76ea6..51bb89b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -85,7 +85,7 @@
// does not. Is there a good equivalent there?
assert(assume(State, Cond, false) && "System is over constrained.");
#endif
- return ProgramStatePair((ProgramStateRef)NULL, State);
+ return ProgramStatePair((ProgramStateRef)nullptr, State);
}
ProgramStateRef StFalse = assume(State, Cond, false);
@@ -93,7 +93,7 @@
// We are careful to return the original state, /not/ StTrue,
// because we want to avoid having callers generate a new node
// in the ExplodedGraph.
- return ProgramStatePair(State, (ProgramStateRef)NULL);
+ return ProgramStatePair(State, (ProgramStateRef)nullptr);
}
return ProgramStatePair(StTrue, StFalse);
@@ -106,7 +106,7 @@
/// value for a symbol, even if it is perfectly constrained.
virtual const llvm::APSInt* getSymVal(ProgramStateRef state,
SymbolRef sym) const {
- return 0;
+ return nullptr;
}
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 14a0417..76ace6d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -324,13 +324,13 @@
ExplodedNode *generateNode(ProgramStateRef State,
ExplodedNode *Pred,
- const ProgramPointTag *Tag = 0) {
+ const ProgramPointTag *Tag = nullptr) {
const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
return NodeBuilder::generateNode(LocalLoc, State, Pred);
}
ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred,
- const ProgramPointTag *Tag = 0) {
+ const ProgramPointTag *Tag = nullptr) {
const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
ExplodedNode *N = NodeBuilder::generateSink(LocalLoc, State, Pred);
if (N && N->isSink())
@@ -355,14 +355,16 @@
/// nodes currently owned by another builder(with larger scope), use
/// Enclosing builder to transfer ownership.
StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
- const NodeBuilderContext &Ctx, NodeBuilder *Enclosing = 0)
+ const NodeBuilderContext &Ctx,
+ NodeBuilder *Enclosing = nullptr)
: NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
if (EnclosingBldr)
EnclosingBldr->takeNodes(SrcNode);
}
StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
- const NodeBuilderContext &Ctx, NodeBuilder *Enclosing = 0)
+ const NodeBuilderContext &Ctx,
+ NodeBuilder *Enclosing = nullptr)
: NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
if (EnclosingBldr)
for (ExplodedNodeSet::iterator I = SrcSet.begin(),
@@ -378,7 +380,7 @@
ExplodedNode *generateNode(const Stmt *S,
ExplodedNode *Pred,
ProgramStateRef St,
- const ProgramPointTag *tag = 0,
+ const ProgramPointTag *tag = nullptr,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
Pred->getLocationContext(), tag);
@@ -388,7 +390,7 @@
ExplodedNode *generateSink(const Stmt *S,
ExplodedNode *Pred,
ProgramStateRef St,
- const ProgramPointTag *tag = 0,
+ const ProgramPointTag *tag = nullptr,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
Pred->getLocationContext(), tag);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 706081e..d0a2780 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -189,7 +189,7 @@
}
ExplodedNode *getFirstPred() {
- return pred_empty() ? NULL : *(pred_begin());
+ return pred_empty() ? nullptr : *(pred_begin());
}
const ExplodedNode *getFirstPred() const {
@@ -197,7 +197,7 @@
}
const ExplodedNode *getFirstSucc() const {
- return succ_empty() ? NULL : *(succ_begin());
+ return succ_empty() ? nullptr : *(succ_begin());
}
// Iterators over successor and predecessor vertices.
@@ -295,7 +295,7 @@
/// the node was freshly created.
ExplodedNode *getNode(const ProgramPoint &L, ProgramStateRef State,
bool IsSink = false,
- bool* IsNew = 0);
+ bool* IsNew = nullptr);
ExplodedGraph* MakeEmptyGraph() const {
return new ExplodedGraph();
@@ -373,8 +373,8 @@
/// nodes in this graph.
/// \returns The trimmed graph
ExplodedGraph *trim(ArrayRef<const NodeTy *> Nodes,
- InterExplodedGraphMap *ForwardMap = 0,
- InterExplodedGraphMap *InverseMap = 0) const;
+ InterExplodedGraphMap *ForwardMap = nullptr,
+ InterExplodedGraphMap *InverseMap = nullptr) const;
/// Enable tracking of recently allocated nodes for potential reclamation
/// when calling reclaimRecentlyAllocatedNodes().
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 2fbe565..0fb4a24 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -106,7 +106,7 @@
/// Returns true if there is still simulation state on the worklist.
bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
- return Engine.ExecuteWorkList(L, Steps, 0);
+ return Engine.ExecuteWorkList(L, Steps, nullptr);
}
/// Execute the work list with an initial state. Nodes that reaches the exit
@@ -186,7 +186,7 @@
/// and \p ReferenceStmt must be valid (non-null).
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
const Stmt *ReferenceStmt, const LocationContext *LC,
- const Stmt *DiagnosticStmt = 0,
+ const Stmt *DiagnosticStmt = nullptr,
ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
/// processCFGElement - Called by CoreEngine. Used to generate new successor
@@ -477,7 +477,7 @@
/// This method is used by evalStore, VisitDeclStmt, and others.
void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
SVal location, SVal Val, bool atDeclInit = false,
- const ProgramPoint *PP = 0);
+ const ProgramPoint *PP = nullptr);
/// Call PointerEscape callback when a value escapes as a result of bind.
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
@@ -506,14 +506,14 @@
ExplodedNode *Pred,
ProgramStateRef St,
SVal location,
- const ProgramPointTag *tag = 0,
+ const ProgramPointTag *tag = nullptr,
QualType LoadTy = QualType());
// FIXME: 'tag' should be removed, and a LocationContext should be used
// instead.
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
- const ProgramPointTag *tag = 0);
+ const ProgramPointTag *tag = nullptr);
/// \brief Create a new state in which the call return value is binded to the
/// call origin expression.
@@ -586,7 +586,7 @@
ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
const LocationContext *LC,
const Expr *E,
- const Expr *ResultE = 0);
+ const Expr *ResultE = nullptr);
};
/// Traits for storing the call processing policy inside GDM.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index e3173a0..92b082d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -54,7 +54,7 @@
// Visual Studio will only create enumerations of size int, not long long.
static const int64_t Symbolic = INT64_MAX;
- RegionOffset() : R(0) {}
+ RegionOffset() : R(nullptr) {}
RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
const MemRegion *getRegion() const { return R; }
@@ -640,7 +640,7 @@
unsigned count, const MemRegion *sreg)
: TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
BlockCount(count),
- ReferencedVars(0), OriginalVars(0) {}
+ ReferencedVars(nullptr), OriginalVars(nullptr) {}
public:
const BlockTextRegion *getCodeRegion() const { return BC; }
@@ -665,11 +665,11 @@
}
bool operator==(const referenced_vars_iterator &I) const {
- assert((R == 0) == (I.R == 0));
+ assert((R == nullptr) == (I.R == nullptr));
return I.R == R;
}
bool operator!=(const referenced_vars_iterator &I) const {
- assert((R == 0) == (I.R == 0));
+ assert((R == nullptr) == (I.R == nullptr));
return I.R != R;
}
referenced_vars_iterator &operator++() {
@@ -1111,7 +1111,7 @@
if (const RegionTy* RT = dyn_cast<RegionTy>(this))
return RT;
- return NULL;
+ return nullptr;
}
//===----------------------------------------------------------------------===//
@@ -1140,9 +1140,10 @@
MemSpaceRegion *code;
public:
- MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
- : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0),
- heap(0), unknown(0), code(0) {}
+ MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a)
+ : C(c), A(a), InternalGlobals(nullptr), SystemGlobals(nullptr),
+ ImmutableGlobals(nullptr), heap(nullptr), unknown(nullptr),
+ code(nullptr) {}
~MemRegionManager();
@@ -1164,7 +1165,7 @@
/// global variables.
const GlobalsSpaceRegion *getGlobalsRegion(
MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
- const CodeTextRegion *R = 0);
+ const CodeTextRegion *R = nullptr);
/// getHeapRegion - Retrieve the memory region associated with the
/// generic "heap".
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 4d345eb..4902ef5 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -237,16 +237,16 @@
ProgramStateRef
invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
- bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
- const CallEvent *Call = 0,
- RegionAndSymbolInvalidationTraits *ITraits = 0) const;
+ bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
+ const CallEvent *Call = nullptr,
+ RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
ProgramStateRef
invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
- bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
- const CallEvent *Call = 0,
- RegionAndSymbolInvalidationTraits *ITraits = 0) const;
+ bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
+ const CallEvent *Call = nullptr,
+ RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
/// enterStackFrame - Returns the state for entry to the given stack frame,
/// preserving the current state.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index 88098ee..823bde7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -64,7 +64,8 @@
typedef const value_type* lookup_type;
static inline data_type MakeData(void *const* p) {
- return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
+ return p ? data_type((typename data_type::TreeTy*) *p)
+ : data_type(nullptr);
}
static inline void *MakeVoidPtr(data_type B) {
return B.getRoot();
@@ -112,7 +113,8 @@
typedef Key key_type;
static inline data_type MakeData(void *const* p) {
- return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
+ return p ? data_type((typename data_type::TreeTy*) *p)
+ : data_type(nullptr);
}
static inline void *MakeVoidPtr(data_type B) {
@@ -163,7 +165,7 @@
static inline data_type MakeData(void *const* p) {
return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
- : data_type(0);
+ : data_type(nullptr);
}
static inline void *MakeVoidPtr(data_type D) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 5da1dd9..29fb413 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -146,14 +146,14 @@
const LocationContext *LCtx,
QualType type,
unsigned visitCount,
- const void *symbolTag = 0) {
+ const void *symbolTag = nullptr) {
return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag);
}
const SymbolConjured* conjureSymbol(const Expr *expr,
const LocationContext *LCtx,
unsigned visitCount,
- const void *symbolTag = 0) {
+ const void *symbolTag = nullptr) {
return SymMgr.conjureSymbol(expr, LCtx, visitCount, symbolTag);
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 5a426ef..d50c3be 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -63,11 +63,11 @@
explicit SVal(const void *d, bool isLoc, unsigned ValKind)
: Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
- explicit SVal(BaseKind k, const void *D = NULL)
+ explicit SVal(BaseKind k, const void *D = nullptr)
: Data(D), Kind(k) {}
public:
- explicit SVal() : Data(0), Kind(0) {}
+ explicit SVal() : Data(nullptr), Kind(0) {}
/// \brief Convert to the specified SVal type, asserting that this SVal is of
/// the desired type.
@@ -211,7 +211,7 @@
explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
: SVal(d, isLoc, ValKind) {}
- explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
+ explicit DefinedOrUnknownSVal(BaseKind k, void *D = nullptr)
: SVal(k, D) {}
private:
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index a6da2e1..84c3166 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -220,7 +220,8 @@
bool First;
public:
- FindUniqueBinding(SymbolRef sym) : Sym(sym), Binding(0), First(true) {}
+ FindUniqueBinding(SymbolRef sym)
+ : Sym(sym), Binding(nullptr), First(true) {}
bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
SVal val) override;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index f653c70..3482e8d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -122,7 +122,7 @@
inline ProgramStateRef
processRegionChange(ProgramStateRef state,
const MemRegion* MR) {
- return processRegionChanges(state, 0, MR, MR, 0);
+ return processRegionChanges(state, nullptr, MR, MR, nullptr);
}
virtual ProgramStateRef
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index e491fb0..2b5cc18 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -498,12 +498,12 @@
const LocationContext *LCtx,
QualType T,
unsigned VisitCount,
- const void *SymbolTag = 0);
+ const void *SymbolTag = nullptr);
const SymbolConjured* conjureSymbol(const Expr *E,
const LocationContext *LCtx,
unsigned VisitCount,
- const void *SymbolTag = 0) {
+ const void *SymbolTag = nullptr) {
return conjureSymbol(E, LCtx, E->getType(), VisitCount, SymbolTag);
}
@@ -516,9 +516,9 @@
///
/// VisitCount can be used to differentiate regions corresponding to
/// different loop iterations, thus, making the symbol path-dependent.
- const SymbolMetadata* getMetadataSymbol(const MemRegion* R, const Stmt *S,
+ const SymbolMetadata *getMetadataSymbol(const MemRegion *R, const Stmt *S,
QualType T, unsigned VisitCount,
- const void *SymbolTag = 0);
+ const void *SymbolTag = nullptr);
const SymbolCast* getCastSymbol(const SymExpr *Operand,
QualType From, QualType To);
@@ -587,7 +587,7 @@
SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager& symmgr,
StoreManager &storeMgr)
: LCtx(Ctx), Loc(s), SymMgr(symmgr),
- reapedStore(0, storeMgr) {}
+ reapedStore(nullptr, storeMgr) {}
~SymbolReaper() {}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
index d12a151..3ed145d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
@@ -42,7 +42,7 @@
explicit WorkListUnit(ExplodedNode *N, BlockCounter C)
: node(N),
counter(C),
- block(NULL),
+ block(nullptr),
blockIdx(0) {}
/// Returns the node associated with the worklist unit.
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index 1f32cd8..cc4f8df 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -72,7 +72,7 @@
/// This constructor exits program in case of error.
CommonOptionsParser(int &argc, const char **argv,
llvm::cl::OptionCategory &Category,
- const char *Overview = 0);
+ const char *Overview = nullptr);
/// Returns a reference to the loaded compilations database.
CompilationDatabase &getCompilations() {
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index 097a7a8..769acd3 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -39,6 +39,7 @@
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
+#include <memory>
#include <string>
#include <vector>
@@ -96,7 +97,7 @@
/// FrontendActionFactory *Factory =
/// newFrontendActionFactory<clang::SyntaxOnlyAction>();
template <typename T>
-FrontendActionFactory *newFrontendActionFactory();
+std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
/// \brief Callbacks called before and after each source file processed by a
/// FrontendAction created by the FrontedActionFactory returned by \c
@@ -125,11 +126,11 @@
/// struct ProvidesASTConsumers {
/// clang::ASTConsumer *newASTConsumer();
/// } Factory;
-/// FrontendActionFactory *FactoryAdapter =
-/// newFrontendActionFactory(&Factory);
+/// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
+/// newFrontendActionFactory(&Factory));
template <typename FactoryT>
-inline FrontendActionFactory *newFrontendActionFactory(
- FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = NULL);
+inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
+ FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
///
@@ -160,8 +161,8 @@
/// \param FileName The file name which 'Code' will be mapped as.
///
/// \return The resulting AST or null if an error occurred.
-ASTUnit *buildASTFromCode(const Twine &Code,
- const Twine &FileName = "input.cc");
+std::unique_ptr<ASTUnit> buildASTFromCode(const Twine &Code,
+ const Twine &FileName = "input.cc");
/// \brief Builds an AST for 'Code' with additional flags.
///
@@ -170,9 +171,10 @@
/// \param FileName The file name which 'Code' will be mapped as.
///
/// \return The resulting AST or null if an error occurred.
-ASTUnit *buildASTFromCodeWithArgs(const Twine &Code,
- const std::vector<std::string> &Args,
- const Twine &FileName = "input.cc");
+std::unique_ptr<ASTUnit>
+buildASTFromCodeWithArgs(const Twine &Code,
+ const std::vector<std::string> &Args,
+ const Twine &FileName = "input.cc");
/// \brief Utility to run a FrontendAction in a single clang invocation.
class ToolInvocation {
@@ -282,7 +284,7 @@
/// \brief Create an AST for each file specified in the command line and
/// append them to ASTs.
- int buildASTs(std::vector<ASTUnit *> &ASTs);
+ int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
/// \brief Returns the file manager used in the tool.
///
@@ -303,17 +305,18 @@
};
template <typename T>
-FrontendActionFactory *newFrontendActionFactory() {
+std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
class SimpleFrontendActionFactory : public FrontendActionFactory {
public:
clang::FrontendAction *create() override { return new T; }
};
- return new SimpleFrontendActionFactory;
+ return std::unique_ptr<FrontendActionFactory>(
+ new SimpleFrontendActionFactory);
}
template <typename FactoryT>
-inline FrontendActionFactory *newFrontendActionFactory(
+inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
class FrontendActionFactoryAdapter : public FrontendActionFactory {
public:
@@ -342,12 +345,12 @@
StringRef Filename) override {
if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
return false;
- if (Callbacks != NULL)
+ if (Callbacks)
return Callbacks->handleBeginSource(CI, Filename);
return true;
}
void EndSourceFileAction() override {
- if (Callbacks != NULL)
+ if (Callbacks)
Callbacks->handleEndSource();
clang::ASTFrontendAction::EndSourceFileAction();
}
@@ -360,7 +363,8 @@
SourceFileCallbacks *Callbacks;
};
- return new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks);
+ return std::unique_ptr<FrontendActionFactory>(
+ new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
}
/// \brief Returns the absolute path of \c File, by prepending it with