Updated to Clang 3.5a.
Change-Id: I8127eb568f674c2e72635b639a3295381fe8af82
diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h
new file mode 100644
index 0000000..8212728
--- /dev/null
+++ b/include/clang-c/BuildSystem.h
@@ -0,0 +1,148 @@
+/*==-- clang-c/BuildSysetm.h - Utilities for use by build systems -*- 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 various utilities for use by build systems. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_BUILD_SYSTEM_H
+#define CLANG_C_BUILD_SYSTEM_H
+
+#include "clang-c/Platform.h"
+#include "clang-c/CXErrorCode.h"
+#include "clang-c/CXString.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup BUILD_SYSTEM Build system utilities
+ * @{
+ */
+
+/**
+ * \brief Return the timestamp for use with Clang's
+ * \c -fbuild-session-timestamp= option.
+ */
+CINDEX_LINKAGE unsigned long long clang_getBuildSessionTimestamp(void);
+
+/**
+ * \brief Object encapsulating information about overlaying virtual
+ * file/directories over the real file system.
+ */
+typedef struct CXVirtualFileOverlayImpl *CXVirtualFileOverlay;
+
+/**
+ * \brief Create a \c CXVirtualFileOverlay object.
+ * Must be disposed with \c clang_VirtualFileOverlay_dispose().
+ *
+ * \param options is reserved, always pass 0.
+ */
+CINDEX_LINKAGE CXVirtualFileOverlay
+clang_VirtualFileOverlay_create(unsigned options);
+
+/**
+ * \brief Map an absolute virtual file path to an absolute real one.
+ * The virtual path must be canonicalized (not contain "."/"..").
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay,
+ const char *virtualPath,
+ const char *realPath);
+
+/**
+ * \brief Set the case sensitivity for the \c CXVirtualFileOverlay object.
+ * The \c CXVirtualFileOverlay object is case-sensitive by default, this
+ * option can be used to override the default.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay,
+ int caseSensitive);
+
+/**
+ * \brief Write out the \c CXVirtualFileOverlay object to a char buffer.
+ *
+ * \param options is reserved, always pass 0.
+ * \param out_buffer_ptr pointer to receive the buffer pointer, which should be
+ * disposed using \c free().
+ * \param out_buffer_size pointer to receive the buffer size.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options,
+ char **out_buffer_ptr,
+ unsigned *out_buffer_size);
+
+/**
+ * \brief Dispose a \c CXVirtualFileOverlay object.
+ */
+CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay);
+
+/**
+ * \brief Object encapsulating information about a module.map file.
+ */
+typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor;
+
+/**
+ * \brief Create a \c CXModuleMapDescriptor object.
+ * Must be disposed with \c clang_ModuleMapDescriptor_dispose().
+ *
+ * \param options is reserved, always pass 0.
+ */
+CINDEX_LINKAGE CXModuleMapDescriptor
+clang_ModuleMapDescriptor_create(unsigned options);
+
+/**
+ * \brief Sets the framework module name that the module.map describes.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor,
+ const char *name);
+
+/**
+ * \brief Sets the umbrealla header name that the module.map describes.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor,
+ const char *name);
+
+/**
+ * \brief Write out the \c CXModuleMapDescriptor object to a char buffer.
+ *
+ * \param options is reserved, always pass 0.
+ * \param out_buffer_ptr pointer to receive the buffer pointer, which should be
+ * disposed using \c free().
+ * \param out_buffer_size pointer to receive the buffer size.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor, unsigned options,
+ char **out_buffer_ptr,
+ unsigned *out_buffer_size);
+
+/**
+ * \brief Dispose a \c CXModuleMapDescriptor object.
+ */
+CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLANG_C_BUILD_SYSTEM_H */
+
diff --git a/include/clang-c/CXErrorCode.h b/include/clang-c/CXErrorCode.h
new file mode 100644
index 0000000..a026c95
--- /dev/null
+++ b/include/clang-c/CXErrorCode.h
@@ -0,0 +1,64 @@
+/*===-- clang-c/CXErrorCode.h - C Index Error Codes --------------*- 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 the CXErrorCode enumerators. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_CXERRORCODE_H
+#define CLANG_C_CXERRORCODE_H
+
+#include "clang-c/Platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Error codes returned by libclang routines.
+ *
+ * Zero (\c CXError_Success) is the only error code indicating success. Other
+ * error codes, including not yet assigned non-zero values, indicate errors.
+ */
+enum CXErrorCode {
+ /**
+ * \brief No error.
+ */
+ CXError_Success = 0,
+
+ /**
+ * \brief A generic error code, no further details are available.
+ *
+ * Errors of this kind can get their own specific error codes in future
+ * libclang versions.
+ */
+ CXError_Failure = 1,
+
+ /**
+ * \brief libclang crashed while performing the requested operation.
+ */
+ CXError_Crashed = 2,
+
+ /**
+ * \brief The function detected that the arguments violate the function
+ * contract.
+ */
+ CXError_InvalidArguments = 3,
+
+ /**
+ * \brief An AST deserialization error has occurred.
+ */
+ CXError_ASTReadError = 4
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 95d54c2..7eff0a4 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -19,7 +19,9 @@
#include <time.h>
#include "clang-c/Platform.h"
+#include "clang-c/CXErrorCode.h"
#include "clang-c/CXString.h"
+#include "clang-c/BuildSystem.h"
/**
* \brief The version constants for the libclang API.
@@ -30,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 20
+#define CINDEX_VERSION_MINOR 24
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -599,6 +601,32 @@
CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range);
/**
+ * \brief Identifies an array of ranges.
+ */
+typedef struct {
+ /** \brief The number of ranges in the \c ranges array. */
+ unsigned count;
+ /**
+ * \brief An array of \c CXSourceRanges.
+ */
+ CXSourceRange *ranges;
+} CXSourceRangeList;
+
+/**
+ * \brief Retrieve all ranges that were skipped by the preprocessor.
+ *
+ * The preprocessor will skip lines when they are surrounded by an
+ * if/ifdef/ifndef directive whose condition does not evaluate to true.
+ */
+CINDEX_LINKAGE CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit tu,
+ CXFile file);
+
+/**
+ * \brief Destroy the given \c CXSourceRangeList.
+ */
+CINDEX_LINKAGE void clang_disposeSourceRangeList(CXSourceRangeList *ranges);
+
+/**
* @}
*/
@@ -625,6 +653,12 @@
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.
*/
@@ -1050,10 +1084,27 @@
struct CXUnsavedFile *unsaved_files);
/**
- * \brief Create a translation unit from an AST file (-emit-ast).
+ * \brief Same as \c clang_createTranslationUnit2, but returns
+ * the \c CXTranslationUnit instead of an error code. In case of an error this
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed
+ * error codes.
*/
-CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(CXIndex,
- const char *ast_filename);
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(
+ CXIndex CIdx,
+ const char *ast_filename);
+
+/**
+ * \brief Create a translation unit from an AST file (\c -emit-ast).
+ *
+ * \param[out] out_TU A non-NULL pointer to store the created
+ * \c CXTranslationUnit.
+ *
+ * \returns Zero on success, otherwise returns an error code.
+ */
+CINDEX_LINKAGE enum CXErrorCode clang_createTranslationUnit2(
+ CXIndex CIdx,
+ const char *ast_filename,
+ CXTranslationUnit *out_TU);
/**
* \brief Flags that control the creation of translation units.
@@ -1167,7 +1218,22 @@
* set of optimizations enabled may change from one version to the next.
*/
CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void);
-
+
+/**
+ * \brief Same as \c clang_parseTranslationUnit2, but returns
+ * the \c CXTranslationUnit instead of an error code. In case of an error this
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed
+ * error codes.
+ */
+CINDEX_LINKAGE CXTranslationUnit
+clang_parseTranslationUnit(CXIndex CIdx,
+ const char *source_filename,
+ const char *const *command_line_args,
+ int num_command_line_args,
+ struct CXUnsavedFile *unsaved_files,
+ unsigned num_unsaved_files,
+ unsigned options);
+
/**
* \brief Parse the given source file and the translation unit corresponding
* to that file.
@@ -1182,7 +1248,7 @@
* associated.
*
* \param source_filename The name of the source file to load, or NULL if the
- * source file is included in \p command_line_args.
+ * source file is included in \c command_line_args.
*
* \param command_line_args The command-line arguments that would be
* passed to the \c clang executable if it were being invoked out-of-process.
@@ -1191,7 +1257,7 @@
* '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.
*
* \param num_command_line_args The number of command-line arguments in
- * \p command_line_args.
+ * \c command_line_args.
*
* \param unsaved_files the files that have not yet been saved to disk
* but may be required for parsing, including the contents of
@@ -1206,18 +1272,22 @@
* is managed but not its compilation. This should be a bitwise OR of the
* CXTranslationUnit_XXX flags.
*
- * \returns A new translation unit describing the parsed code and containing
- * any diagnostics produced by the compiler. If there is a failure from which
- * the compiler cannot recover, returns NULL.
+ * \param[out] out_TU A non-NULL pointer to store the created
+ * \c CXTranslationUnit, describing the parsed code and containing any
+ * diagnostics produced by the compiler.
+ *
+ * \returns Zero on success, otherwise returns an error code.
*/
-CINDEX_LINKAGE CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
- const char *source_filename,
- const char * const *command_line_args,
- int num_command_line_args,
- struct CXUnsavedFile *unsaved_files,
- unsigned num_unsaved_files,
- unsigned options);
-
+CINDEX_LINKAGE enum CXErrorCode
+clang_parseTranslationUnit2(CXIndex CIdx,
+ const char *source_filename,
+ const char *const *command_line_args,
+ int num_command_line_args,
+ struct CXUnsavedFile *unsaved_files,
+ unsigned num_unsaved_files,
+ unsigned options,
+ CXTranslationUnit *out_TU);
+
/**
* \brief Flags that control how translation units are saved.
*
@@ -1369,10 +1439,11 @@
* The function \c clang_defaultReparseOptions() produces a default set of
* options recommended for most uses, based on the translation unit.
*
- * \returns 0 if the sources could be reparsed. A non-zero value will be
+ * \returns 0 if the sources could be reparsed. A non-zero error code will be
* returned if reparsing was impossible, such that the translation unit is
- * invalid. In such cases, the only valid call for \p TU is
- * \c clang_disposeTranslationUnit(TU).
+ * invalid. In such cases, the only valid call for \c TU is
+ * \c clang_disposeTranslationUnit(TU). The error codes returned by this
+ * routine are described by the \c CXErrorCode enum.
*/
CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU,
unsigned num_unsaved_files,
@@ -2070,7 +2141,11 @@
*/
CXCursor_OMPParallelDirective = 232,
- CXCursor_LastStmt = CXCursor_OMPParallelDirective,
+ /** \brief OpenMP simd directive.
+ */
+ CXCursor_OMPSimdDirective = 233,
+
+ CXCursor_LastStmt = CXCursor_OMPSimdDirective,
/**
* \brief Cursor that represents the translation unit itself.
@@ -2369,7 +2444,7 @@
/**
* \brief Describe the "language" of the entity referred to by a cursor.
*/
-CINDEX_LINKAGE enum CXLanguageKind {
+enum CXLanguageKind {
CXLanguage_Invalid = 0,
CXLanguage_C,
CXLanguage_ObjC,
@@ -2854,14 +2929,14 @@
CINDEX_LINKAGE enum CXCallingConv clang_getFunctionTypeCallingConv(CXType T);
/**
- * \brief Retrieve the result type associated with a function type.
+ * \brief Retrieve the return type associated with a function type.
*
* If a non-function type is passed in, an invalid type is returned.
*/
CINDEX_LINKAGE CXType clang_getResultType(CXType T);
/**
- * \brief Retrieve the number of non-variadic arguments associated with a
+ * \brief Retrieve the number of non-variadic parameters associated with a
* function type.
*
* If a non-function type is passed in, -1 is returned.
@@ -2869,7 +2944,7 @@
CINDEX_LINKAGE int clang_getNumArgTypes(CXType T);
/**
- * \brief Retrieve the type of an argument of a function type.
+ * \brief Retrieve the type of a parameter of a function type.
*
* If a non-function type is passed in or the function does not have enough
* parameters, an invalid type is returned.
@@ -2882,7 +2957,7 @@
CINDEX_LINKAGE unsigned clang_isFunctionTypeVariadic(CXType T);
/**
- * \brief Retrieve the result type associated with a given cursor.
+ * \brief Retrieve the return type associated with a given cursor.
*
* This only returns a valid type if the cursor refers to a function or method.
*/
@@ -3012,6 +3087,24 @@
};
/**
+ * \brief Returns the number of template arguments for given class template
+ * specialization, or -1 if type \c T is not a class template specialization.
+ *
+ * Variadic argument packs count as only one argument, and can not be inspected
+ * further.
+ */
+CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T);
+
+/**
+ * \brief Returns the type template argument of a template class specialization
+ * at given index.
+ *
+ * This function only returns template type arguments and does not handle
+ * template template arguments or variadic packs.
+ */
+CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, unsigned i);
+
+/**
* \brief Retrieve the ref-qualifier kind of a function or method.
*
* The ref-qualifier is returned for C++ functions or methods. For other types
@@ -5763,11 +5856,12 @@
* \param index_options A bitmask of options that affects how indexing is
* performed. This should be a bitwise OR of the CXIndexOpt_XXX flags.
*
- * \param out_TU [out] pointer to store a CXTranslationUnit that can be reused
- * after indexing is finished. Set to NULL if you do not require it.
+ * \param[out] out_TU pointer to store a \c CXTranslationUnit that can be
+ * reused after indexing is finished. Set to \c NULL if you do not require it.
*
- * \returns If there is a failure from which the there is no recovery, returns
- * non-zero, otherwise returns 0.
+ * \returns 0 on success or if there were errors from which the compiler could
+ * recover. If there is a failure from which the there is no recovery, returns
+ * a non-zero \c CXErrorCode.
*
* The rest of the parameters are the same as #clang_parseTranslationUnit.
*/
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index 45c8b4e..b3e74b9 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -12,14 +12,14 @@
#include "clang/ARCMigrate/FileRemapper.h"
#include "clang/Frontend/FrontendAction.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
namespace clang {
namespace arcmt {
class CheckAction : public WrapperFrontendAction {
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
+ bool BeginInvocation(CompilerInstance &CI) override;
public:
CheckAction(FrontendAction *WrappedAction);
@@ -27,7 +27,7 @@
class ModifyAction : public WrapperFrontendAction {
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
+ bool BeginInvocation(CompilerInstance &CI) override;
public:
ModifyAction(FrontendAction *WrappedAction);
@@ -36,9 +36,9 @@
class MigrateSourceAction : public ASTFrontendAction {
FileRemapper Remapper;
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ bool BeginInvocation(CompilerInstance &CI) override;
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class MigrateAction : public WrapperFrontendAction {
@@ -46,7 +46,7 @@
std::string PlistOut;
bool EmitPremigrationARCErros;
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
+ bool BeginInvocation(CompilerInstance &CI) override;
public:
MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
@@ -65,8 +65,9 @@
unsigned migrateAction);
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile);
- virtual bool BeginInvocation(CompilerInstance &CI);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+ bool BeginInvocation(CompilerInstance &CI) override;
};
}
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index f7677cc..fb2fdd3 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -12,9 +12,9 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
+#include <memory>
namespace llvm {
class MemoryBuffer;
@@ -30,7 +30,7 @@
class FileRemapper {
// FIXME: Reuse the same FileManager for multiple ASTContexts.
- OwningPtr<FileManager> FileMgr;
+ std::unique_ptr<FileManager> FileMgr;
typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target;
typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy;
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index b4fd2af..079f25e 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -108,34 +108,33 @@
};
struct MemberPointerData;
- enum {
- MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
- sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
- };
+ // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
+ typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
+ ComplexAPFloat, Vec, Arr, StructData,
+ UnionData, AddrLabelDiffData> DataType;
+ static const size_t DataSize = sizeof(DataType);
- union {
- void *Aligner;
- char Data[MaxSize];
- };
+ DataType Data;
public:
APValue() : Kind(Uninitialized) {}
- explicit APValue(const APSInt &I) : Kind(Uninitialized) {
- MakeInt(); setInt(I);
+ explicit APValue(APSInt I) : Kind(Uninitialized) {
+ MakeInt(); setInt(std::move(I));
}
- explicit APValue(const APFloat &F) : Kind(Uninitialized) {
- MakeFloat(); setFloat(F);
+ explicit APValue(APFloat F) : Kind(Uninitialized) {
+ MakeFloat(); setFloat(std::move(F));
}
explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
MakeVector(); setVector(E, N);
}
- APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
- MakeComplexInt(); setComplexInt(R, I);
+ APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
+ MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
}
- APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
- MakeComplexFloat(); setComplexFloat(R, I);
+ APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
+ MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
}
APValue(const APValue &RHS);
+ APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
: Kind(Uninitialized) {
MakeLValue(); setLValue(B, O, N, CallIndex);
@@ -200,7 +199,7 @@
APSInt &getInt() {
assert(isInt() && "Invalid accessor");
- return *(APSInt*)(char*)Data;
+ return *(APSInt*)(char*)Data.buffer;
}
const APSInt &getInt() const {
return const_cast<APValue*>(this)->getInt();
@@ -208,7 +207,7 @@
APFloat &getFloat() {
assert(isFloat() && "Invalid accessor");
- return *(APFloat*)(char*)Data;
+ return *(APFloat*)(char*)Data.buffer;
}
const APFloat &getFloat() const {
return const_cast<APValue*>(this)->getFloat();
@@ -216,7 +215,7 @@
APSInt &getComplexIntReal() {
assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data)->Real;
+ return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
}
const APSInt &getComplexIntReal() const {
return const_cast<APValue*>(this)->getComplexIntReal();
@@ -224,7 +223,7 @@
APSInt &getComplexIntImag() {
assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data)->Imag;
+ return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
}
const APSInt &getComplexIntImag() const {
return const_cast<APValue*>(this)->getComplexIntImag();
@@ -232,7 +231,7 @@
APFloat &getComplexFloatReal() {
assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data)->Real;
+ return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
}
const APFloat &getComplexFloatReal() const {
return const_cast<APValue*>(this)->getComplexFloatReal();
@@ -240,7 +239,7 @@
APFloat &getComplexFloatImag() {
assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data)->Imag;
+ return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
}
const APFloat &getComplexFloatImag() const {
return const_cast<APValue*>(this)->getComplexFloatImag();
@@ -259,20 +258,20 @@
APValue &getVectorElt(unsigned I) {
assert(isVector() && "Invalid accessor");
assert(I < getVectorLength() && "Index out of range");
- return ((Vec*)(char*)Data)->Elts[I];
+ return ((Vec*)(char*)Data.buffer)->Elts[I];
}
const APValue &getVectorElt(unsigned I) const {
return const_cast<APValue*>(this)->getVectorElt(I);
}
unsigned getVectorLength() const {
assert(isVector() && "Invalid accessor");
- return ((const Vec*)(const void *)Data)->NumElts;
+ return ((const Vec*)(const void *)Data.buffer)->NumElts;
}
APValue &getArrayInitializedElt(unsigned I) {
assert(isArray() && "Invalid accessor");
assert(I < getArrayInitializedElts() && "Index out of range");
- return ((Arr*)(char*)Data)->Elts[I];
+ return ((Arr*)(char*)Data.buffer)->Elts[I];
}
const APValue &getArrayInitializedElt(unsigned I) const {
return const_cast<APValue*>(this)->getArrayInitializedElt(I);
@@ -283,35 +282,35 @@
APValue &getArrayFiller() {
assert(isArray() && "Invalid accessor");
assert(hasArrayFiller() && "No array filler");
- return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()];
+ return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
}
const APValue &getArrayFiller() const {
return const_cast<APValue*>(this)->getArrayFiller();
}
unsigned getArrayInitializedElts() const {
assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data)->NumElts;
+ return ((const Arr*)(const void *)Data.buffer)->NumElts;
}
unsigned getArraySize() const {
assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data)->ArrSize;
+ return ((const Arr*)(const void *)Data.buffer)->ArrSize;
}
unsigned getStructNumBases() const {
assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data)->NumBases;
+ return ((const StructData*)(const char*)Data.buffer)->NumBases;
}
unsigned getStructNumFields() const {
assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data)->NumFields;
+ return ((const StructData*)(const char*)Data.buffer)->NumFields;
}
APValue &getStructBase(unsigned i) {
assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data)->Elts[i];
+ return ((StructData*)(char*)Data.buffer)->Elts[i];
}
APValue &getStructField(unsigned i) {
assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i];
+ return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
}
const APValue &getStructBase(unsigned i) const {
return const_cast<APValue*>(this)->getStructBase(i);
@@ -322,11 +321,11 @@
const FieldDecl *getUnionField() const {
assert(isUnion() && "Invalid accessor");
- return ((const UnionData*)(const char*)Data)->Field;
+ return ((const UnionData*)(const char*)Data.buffer)->Field;
}
APValue &getUnionValue() {
assert(isUnion() && "Invalid accessor");
- return *((UnionData*)(char*)Data)->Value;
+ return *((UnionData*)(char*)Data.buffer)->Value;
}
const APValue &getUnionValue() const {
return const_cast<APValue*>(this)->getUnionValue();
@@ -338,41 +337,41 @@
const AddrLabelExpr* getAddrLabelDiffLHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr;
+ return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
}
const AddrLabelExpr* getAddrLabelDiffRHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr;
+ return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
}
- void setInt(const APSInt &I) {
+ void setInt(APSInt I) {
assert(isInt() && "Invalid accessor");
- *(APSInt*)(char*)Data = I;
+ *(APSInt *)(char *)Data.buffer = std::move(I);
}
- void setFloat(const APFloat &F) {
+ void setFloat(APFloat F) {
assert(isFloat() && "Invalid accessor");
- *(APFloat*)(char*)Data = F;
+ *(APFloat *)(char *)Data.buffer = std::move(F);
}
void setVector(const APValue *E, unsigned N) {
assert(isVector() && "Invalid accessor");
- ((Vec*)(char*)Data)->Elts = new APValue[N];
- ((Vec*)(char*)Data)->NumElts = N;
+ ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
+ ((Vec*)(char*)Data.buffer)->NumElts = N;
for (unsigned i = 0; i != N; ++i)
- ((Vec*)(char*)Data)->Elts[i] = E[i];
+ ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
}
- void setComplexInt(const APSInt &R, const APSInt &I) {
+ void setComplexInt(APSInt R, APSInt I) {
assert(R.getBitWidth() == I.getBitWidth() &&
"Invalid complex int (type mismatch).");
assert(isComplexInt() && "Invalid accessor");
- ((ComplexAPSInt*)(char*)Data)->Real = R;
- ((ComplexAPSInt*)(char*)Data)->Imag = I;
+ ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
+ ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
}
- void setComplexFloat(const APFloat &R, const APFloat &I) {
+ void setComplexFloat(APFloat R, APFloat I) {
assert(&R.getSemantics() == &I.getSemantics() &&
"Invalid complex float (type mismatch).");
assert(isComplexFloat() && "Invalid accessor");
- ((ComplexAPFloat*)(char*)Data)->Real = R;
- ((ComplexAPFloat*)(char*)Data)->Imag = I;
+ ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
+ ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
}
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
unsigned CallIndex);
@@ -381,13 +380,13 @@
unsigned CallIndex);
void setUnion(const FieldDecl *Field, const APValue &Value) {
assert(isUnion() && "Invalid accessor");
- ((UnionData*)(char*)Data)->Field = Field;
- *((UnionData*)(char*)Data)->Value = Value;
+ ((UnionData*)(char*)Data.buffer)->Field = Field;
+ *((UnionData*)(char*)Data.buffer)->Value = Value;
}
void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
const AddrLabelExpr* RHSExpr) {
- ((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr;
- ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
+ ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
+ ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
}
/// Assign by swapping from a copy of the RHS.
@@ -404,46 +403,46 @@
}
void MakeInt() {
assert(isUninit() && "Bad state change");
- new ((void*)Data) APSInt(1);
+ new ((void*)Data.buffer) APSInt(1);
Kind = Int;
}
void MakeFloat() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) APFloat(0.0);
+ new ((void*)(char*)Data.buffer) APFloat(0.0);
Kind = Float;
}
void MakeVector() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) Vec();
+ new ((void*)(char*)Data.buffer) Vec();
Kind = Vector;
}
void MakeComplexInt() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) ComplexAPSInt();
+ new ((void*)(char*)Data.buffer) ComplexAPSInt();
Kind = ComplexInt;
}
void MakeComplexFloat() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) ComplexAPFloat();
+ new ((void*)(char*)Data.buffer) ComplexAPFloat();
Kind = ComplexFloat;
}
void MakeLValue();
void MakeArray(unsigned InitElts, unsigned Size);
void MakeStruct(unsigned B, unsigned M) {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) StructData(B, M);
+ new ((void*)(char*)Data.buffer) StructData(B, M);
Kind = Struct;
}
void MakeUnion() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) UnionData();
+ new ((void*)(char*)Data.buffer) UnionData();
Kind = Union;
}
void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path);
void MakeAddrLabelDiff() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) AddrLabelDiffData();
+ new ((void*)(char*)Data.buffer) AddrLabelDiffData();
Kind = AddrLabelDiff;
}
};
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 7b6fa94..45d3067 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -21,7 +21,6 @@
class CXXRecordDecl;
class Decl;
class DeclGroupRef;
- class HandleTagDeclDefinition;
class ASTMutationListener;
class ASTDeserializationListener; // layering violation because void* is ugly
class SemaConsumer; // layering violation required for safe SemaConsumer
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index f420e85..ca1a906 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -33,10 +33,10 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
+#include <memory>
#include <vector>
namespace llvm {
@@ -66,6 +66,7 @@
class UnresolvedSetIterator;
class UsingDecl;
class UsingShadowDecl;
+ class VTableContextBase;
namespace Builtin { class Context; }
@@ -82,7 +83,7 @@
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
mutable llvm::FoldingSet<ComplexType> ComplexTypes;
mutable llvm::FoldingSet<PointerType> PointerTypes;
- mutable llvm::FoldingSet<DecayedType> DecayedTypes;
+ mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
@@ -364,6 +365,7 @@
/// \brief Side-table of mangling numbers for declarations which rarely
/// need them (like static local vars).
llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
+ llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers;
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
@@ -392,7 +394,7 @@
PartialDiagnostic::StorageAllocator DiagAllocator;
/// \brief The current C++ ABI.
- OwningPtr<CXXABI> ABI;
+ std::unique_ptr<CXXABI> ABI;
CXXABI *createCXXABI(const TargetInfo &T);
/// \brief The logical -> physical address space map.
@@ -415,7 +417,7 @@
SelectorTable &Selectors;
Builtin::Context &BuiltinInfo;
mutable DeclarationNameTable DeclarationNames;
- OwningPtr<ExternalASTSource> ExternalSource;
+ IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
ASTMutationListener *Listener;
/// \brief Contains parents of a node.
@@ -624,6 +626,43 @@
private:
mutable comments::CommandTraits CommentCommandTraits;
+ /// \brief Iterator that visits import declarations.
+ class import_iterator {
+ ImportDecl *Import;
+
+ public:
+ typedef ImportDecl *value_type;
+ typedef ImportDecl *reference;
+ typedef ImportDecl *pointer;
+ typedef int difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ import_iterator() : Import() {}
+ explicit import_iterator(ImportDecl *Import) : Import(Import) {}
+
+ reference operator*() const { return Import; }
+ pointer operator->() const { return Import; }
+
+ import_iterator &operator++() {
+ Import = ASTContext::getNextLocalImport(Import);
+ return *this;
+ }
+
+ import_iterator operator++(int) {
+ import_iterator Other(*this);
+ ++(*this);
+ return Other;
+ }
+
+ friend bool operator==(import_iterator X, import_iterator Y) {
+ return X.Import == Y.Import;
+ }
+
+ friend bool operator!=(import_iterator X, import_iterator Y) {
+ return X.Import != Y.Import;
+ }
+ };
+
public:
comments::CommandTraits &getCommentCommandTraits() const {
return CommentCommandTraits;
@@ -710,47 +749,10 @@
return Import->NextLocalImport;
}
- /// \brief Iterator that visits import declarations.
- class import_iterator {
- ImportDecl *Import;
-
- public:
- typedef ImportDecl *value_type;
- typedef ImportDecl *reference;
- typedef ImportDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- import_iterator() : Import() { }
- explicit import_iterator(ImportDecl *Import) : Import(Import) { }
-
- reference operator*() const { return Import; }
- pointer operator->() const { return Import; }
-
- import_iterator &operator++() {
- Import = ASTContext::getNextLocalImport(Import);
- return *this;
- }
-
- import_iterator operator++(int) {
- import_iterator Other(*this);
- ++(*this);
- return Other;
- }
-
- friend bool operator==(import_iterator X, import_iterator Y) {
- return X.Import == Y.Import;
- }
-
- friend bool operator!=(import_iterator X, import_iterator Y) {
- return X.Import != Y.Import;
- }
- };
-
- import_iterator local_import_begin() const {
- return import_iterator(FirstLocalImport);
+ typedef llvm::iterator_range<import_iterator> import_range;
+ import_range local_imports() const {
+ return import_range(import_iterator(FirstLocalImport), import_iterator());
}
- import_iterator local_import_end() const { return import_iterator(); }
Decl *getPrimaryMergedDecl(Decl *D) {
Decl *Result = MergedDecls.lookup(D);
@@ -810,11 +812,13 @@
/// The external AST source provides the ability to load parts of
/// the abstract syntax tree as needed from some external storage,
/// e.g., a precompiled header.
- void setExternalSource(OwningPtr<ExternalASTSource> &Source);
+ void setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source);
/// \brief Retrieve a pointer to the external AST source associated
/// with this AST context, if any.
- ExternalASTSource *getExternalSource() const { return ExternalSource.get(); }
+ ExternalASTSource *getExternalSource() const {
+ return ExternalSource.getPtr();
+ }
/// \brief Attach an AST mutation listener to the AST context.
///
@@ -832,6 +836,14 @@
void PrintStats() const;
const SmallVectorImpl<Type *>& getTypes() const { return Types; }
+ /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl
+ /// declaration.
+ RecordDecl *buildImplicitRecord(StringRef Name,
+ RecordDecl::TagKind TK = TTK_Struct) const;
+
+ /// \brief Create a new implicit TU-level typedef declaration.
+ TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;
+
/// \brief Retrieve the declaration for the 128-bit signed integer type.
TypedefDecl *getInt128Decl() const;
@@ -915,6 +927,14 @@
return CanQualType::CreateUnsafe(getPointerType((QualType) T));
}
+ /// \brief Return the uniqued reference to a type adjusted from the original
+ /// type to a new type.
+ QualType getAdjustedType(QualType Orig, QualType New) const;
+ CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const {
+ return CanQualType::CreateUnsafe(
+ getAdjustedType((QualType)Orig, (QualType)New));
+ }
+
/// \brief Return the uniqued reference to the decayed version of the given
/// type. Can only be called on array and function types which decay to
/// pointer types.
@@ -1126,6 +1146,13 @@
QualType getObjCObjectType(QualType Base,
ObjCProtocolDecl * const *Protocols,
unsigned NumProtocols) const;
+
+ bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
+ /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
+ /// QT's qualified-id protocol list adopt all protocols in IDecl's list
+ /// of protocols.
+ bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
+ ObjCInterfaceDecl *IDecl);
/// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getObjCObjectPointerType(QualType OIT) const;
@@ -1382,6 +1409,10 @@
bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const;
+
+ ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
+ const ObjCPropertyDecl *PD,
+ const Decl *Container) const;
/// \brief Return the size of type \p T for Objective-C encoding purpose,
/// in characters.
@@ -1704,6 +1735,8 @@
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
+ VTableContextBase *getVTableContext();
+
MangleContext *createMangleContext();
void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
@@ -1994,9 +2027,9 @@
bool Unqualified = false, bool BlockReturnType = false);
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
bool Unqualified = false);
- QualType mergeFunctionArgumentTypes(QualType, QualType,
- bool OfBlockPointer=false,
- bool Unqualified = false);
+ QualType mergeFunctionParameterTypes(QualType, QualType,
+ bool OfBlockPointer = false,
+ bool Unqualified = false);
QualType mergeTransparentUnionType(QualType, QualType,
bool OfBlockPointer=false,
bool Unqualified = false);
@@ -2027,14 +2060,12 @@
//===--------------------------------------------------------------------===//
// Type Iterators.
//===--------------------------------------------------------------------===//
+ typedef llvm::iterator_range<SmallVectorImpl<Type *>::const_iterator>
+ type_const_range;
- typedef SmallVectorImpl<Type *>::iterator type_iterator;
- typedef SmallVectorImpl<Type *>::const_iterator const_type_iterator;
-
- type_iterator types_begin() { return Types.begin(); }
- type_iterator types_end() { return Types.end(); }
- const_type_iterator types_begin() const { return Types.begin(); }
- const_type_iterator types_end() const { return Types.end(); }
+ type_const_range types() const {
+ return type_const_range(Types.begin(), Types.end());
+ }
//===--------------------------------------------------------------------===//
// Integer Values
@@ -2125,7 +2156,7 @@
/// when it is called.
void AddDeallocation(void (*Callback)(void*), void *Data);
- GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD);
+ GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
/// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
@@ -2139,6 +2170,9 @@
void setManglingNumber(const NamedDecl *ND, unsigned Number);
unsigned getManglingNumber(const NamedDecl *ND) const;
+ void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
+ unsigned getStaticLocalNumber(const VarDecl *VD) const;
+
/// \brief Retrieve the context for computing mangling numbers in the given
/// DeclContext.
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
@@ -2238,17 +2272,17 @@
void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
const FieldDecl *Field,
bool includeVBases = true) const;
-
+public:
// Adds the encoding of a method parameter or return type.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
QualType T, std::string& S,
bool Extended) const;
-
+
+private:
const ASTRecordLayout &
getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) const;
-private:
/// \brief A set of deallocations that should be performed when the
/// ASTContext is destroyed.
typedef llvm::SmallDenseMap<void(*)(void*), llvm::SmallVector<void*, 16> >
@@ -2264,7 +2298,9 @@
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
- llvm::OwningPtr<ParentMap> AllParents;
+ std::unique_ptr<ParentMap> AllParents;
+
+ std::unique_ptr<VTableContextBase> VTContext;
};
/// \brief Utility function for constructing a nullary selector.
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
index 358ac71..9af016b 100644
--- a/include/clang/AST/ASTLambda.h
+++ b/include/clang/AST/ASTLambda.h
@@ -36,9 +36,9 @@
return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
}
-inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) {
+inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
if (!MD) return false;
- CXXRecordDecl *LambdaClass = MD->getParent();
+ const CXXRecordDecl *LambdaClass = MD->getParent();
if (LambdaClass && LambdaClass->isGenericLambda())
return isLambdaCallOperator(MD) &&
MD->isFunctionTemplateSpecialization();
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index 6d12a92..a89bfed 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -65,6 +65,10 @@
virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {}
+ /// \brief A function's exception specification has been evaluated or
+ /// instantiated.
+ virtual void ResolvedExceptionSpec(const FunctionDecl *FD) {}
+
/// \brief A function's return type has been deduced.
virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
@@ -74,6 +78,9 @@
/// \brief A static data member was implicitly instantiated.
virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
+ /// \brief A function template's definition was instantiated.
+ virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
+
/// \brief A new objc category class was added for an interface.
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {}
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index 087ad56..abc8857 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -57,11 +57,18 @@
bool isSame(ASTNodeKind Other) const;
/// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
- bool isBaseOf(ASTNodeKind Other) const;
+ /// \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;
/// \brief String representation of the kind.
StringRef asStringRef() const;
+ /// \brief Strict weak ordering for ASTNodeKind.
+ bool operator<(const ASTNodeKind &Other) const {
+ return KindId < Other.KindId;
+ }
+
private:
/// \brief Kind ids.
///
@@ -91,7 +98,9 @@
/// \brief Returns \c true if \c Base is a base kind of (or same as) \c
/// Derived.
- static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
+ /// \param Distance If non-null, used to return the distance between \c Base
+ /// and \c Derived in the class hierarchy.
+ static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
/// \brief Helper meta-function to convert a kind T to its enum value.
///
@@ -133,6 +142,11 @@
#include "clang/AST/TypeNodes.def"
#undef KIND_TO_KIND_ID
+inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
+ OS << K.asStringRef();
+ return OS;
+}
+
/// \brief A dynamically typed AST node container.
///
/// Stores an AST node in a type safe way. This allows writing code that
@@ -198,8 +212,8 @@
return getMemoizationData() < Other.getMemoizationData();
}
bool operator==(const DynTypedNode &Other) const {
- // Nodes with different types cannot be equal.
- if (!NodeKind.isSame(Other.NodeKind))
+ if (!NodeKind.isBaseOf(Other.NodeKind) &&
+ !Other.NodeKind.isBaseOf(NodeKind))
return false;
// FIXME: Implement for other types.
@@ -283,18 +297,18 @@
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename llvm::enable_if<llvm::is_base_of<
- Decl, T> >::type> : public DynCastPtrConverter<T, Decl> {};
+ T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
+ : public DynCastPtrConverter<T, Decl> {};
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename llvm::enable_if<llvm::is_base_of<
- Stmt, T> >::type> : public DynCastPtrConverter<T, Stmt> {};
+ T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
+ : public DynCastPtrConverter<T, Stmt> {};
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename llvm::enable_if<llvm::is_base_of<
- Type, T> >::type> : public DynCastPtrConverter<T, Type> {};
+ T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
+ : public DynCastPtrConverter<T, Type> {};
template <>
struct DynTypedNode::BaseConverter<
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 6db918e..d9d37b1 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -26,30 +26,6 @@
#include <cstring>
#include <memory>
-#ifdef _MSC_VER
-namespace std {
-#if _MSC_VER <= 1310
- // Work around flawed VC++ implementation of std::uninitialized_copy. Define
- // additional overloads so that elements with pointer types are recognized as
- // scalars and not objects, causing bizarre type conversion errors.
- template<class T1, class T2>
- inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
- _Scalar_ptr_iterator_tag _Cat;
- return _Cat;
- }
-
- template<class T1, class T2>
- inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
- _Scalar_ptr_iterator_tag _Cat;
- return _Cat;
- }
-#else
- // FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
- // is that the above hack won't work if it wasn't fixed.
-#endif
-}
-#endif
-
namespace clang {
class ASTContext;
@@ -77,7 +53,7 @@
}
~ASTVector() {
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
// Destroy the constructed elements in the vector.
destroy_range(Begin, End);
}
@@ -147,7 +123,7 @@
}
void clear() {
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
destroy_range(Begin, End);
}
End = Begin;
@@ -392,7 +368,7 @@
T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
// Copy the elements over.
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
std::uninitialized_copy(Begin, End, NewElts);
// Destroy the original elements.
destroy_range(Begin, End);
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 7dbf413..655bcab 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -48,10 +48,9 @@
/// An index into the spelling list of an
/// attribute defined in Attr.td file.
unsigned SpellingListIndex : 4;
-
bool Inherited : 1;
-
bool IsPackExpansion : 1;
+ bool Implicit : 1;
virtual ~Attr();
@@ -76,7 +75,7 @@
protected:
Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
: Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
- Inherited(false), IsPackExpansion(false) {}
+ Inherited(false), IsPackExpansion(false), Implicit(false) {}
public:
@@ -85,6 +84,7 @@
}
unsigned getSpellingListIndex() const { return SpellingListIndex; }
+ virtual const char *getSpelling() const = 0;
SourceLocation getLocation() const { return Range.getBegin(); }
SourceRange getRange() const { return Range; }
@@ -92,6 +92,11 @@
bool isInherited() const { return Inherited; }
+ /// \brief Returns true if the attribute has been implicitly created instead
+ /// of explicitly written by the user.
+ bool isImplicit() const { return Implicit; }
+ void setImplicit(bool I) { Implicit = I; }
+
void setPackExpansion(bool PE) { IsPackExpansion = PE; }
bool isPackExpansion() const { return IsPackExpansion; }
@@ -103,6 +108,11 @@
// Pretty print this attribute.
virtual void printPretty(raw_ostream &OS,
const PrintingPolicy &Policy) const = 0;
+
+ /// \brief By default, attributes cannot be duplicated when being merged;
+ /// however, an attribute can override this. Returns true if the attribute
+ /// can be duplicated when merging.
+ virtual bool duplicatesAllowed() const { return false; }
};
class InheritableAttr : public Attr {
@@ -121,7 +131,7 @@
};
class InheritableParamAttr : public InheritableAttr {
- virtual void anchor();
+ void anchor() override;
protected:
InheritableParamAttr(attr::Kind AK, SourceRange R,
unsigned SpellingListIndex = 0)
@@ -136,23 +146,21 @@
}
};
-class MSInheritanceAttr : public InheritableAttr {
- virtual void anchor();
-protected:
- MSInheritanceAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
- : InheritableAttr(AK, R, SpellingListIndex) {}
-
-public:
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- // Relies on relative order of enum emission with respect to param attrs.
- return (A->getKind() <= attr::LAST_MS_INHERITANCE &&
- A->getKind() > attr::LAST_INHERITABLE_PARAM);
- }
-};
-
#include "clang/AST/Attrs.inc"
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const Attr *At) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+ DiagnosticsEngine::ak_attr);
+ return DB;
+}
+
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const Attr *At) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+ DiagnosticsEngine::ak_attr);
+ return PD;
+}
} // end namespace clang
#endif
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index 8bd8fbe..4ecf98f 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -43,7 +43,7 @@
typedef SmallVector<const Attr*, 2> ConstAttrVec;
/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
-/// providing attributes that are of a specifc type.
+/// providing attributes that are of a specific type.
template <typename SpecificAttr, typename Container = AttrVec>
class specific_attr_iterator {
typedef typename Container::const_iterator Iterator;
@@ -53,7 +53,7 @@
/// specifically requested, we don't necessarily advance this all the
/// way. Instead, we advance it when an operation is requested; if the
/// operation is acting on what should be a past-the-end iterator,
- /// then we offer no guarantees, but this way we do not dererence a
+ /// then we offer no guarantees, but this way we do not dereference a
/// past-the-end iterator when we move to a past-the-end position.
mutable Iterator Current;
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index ba54fa2..260734f 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -13,6 +13,11 @@
SOURCE ../Basic/Attr.td
TARGET ClangAttrDump)
+clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE ../Basic/Attr.td
+ TARGET ClangAttrVisitor)
+
clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes
SOURCE ../Basic/StmtNodes.td
TARGET ClangStmtNodes)
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index dbe4ad0..3c7b7f0 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -190,8 +190,8 @@
CXXBasePath& front() { return Paths.front(); }
const CXXBasePath& front() const { return Paths.front(); }
- decl_iterator found_decls_begin();
- decl_iterator found_decls_end();
+ typedef llvm::iterator_range<decl_iterator> decl_range;
+ decl_range found_decls();
/// \brief Determine whether the path from the most-derived type to the
/// given base type is ambiguous (i.e., it refers to multiple subobjects of
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 9c699b7..7cccef6 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -17,7 +17,6 @@
#include "clang/AST/Type.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/type_traits.h"
#include <iterator>
namespace clang {
@@ -60,9 +59,9 @@
/// \brief Converting constructor that permits implicit upcasting of
/// canonical type pointers.
- template<typename U>
- CanQual(const CanQual<U>& Other,
- typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
+ template <typename U>
+ CanQual(const CanQual<U> &Other,
+ typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
/// \brief Retrieve the underlying type pointer, which refers to a
/// canonical type.
@@ -541,39 +540,39 @@
template<>
struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
};
template<>
struct CanProxyAdaptor<FunctionNoProtoType>
: public CanProxyBase<FunctionNoProtoType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
};
template<>
struct CanProxyAdaptor<FunctionProtoType>
: public CanProxyBase<FunctionProtoType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
- CanQualType getArgType(unsigned i) const {
- return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
+ CanQualType getParamType(unsigned i) const {
+ return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
}
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
- typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
- arg_type_iterator;
+ typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
+ param_type_iterator;
- arg_type_iterator arg_type_begin() const {
- return arg_type_iterator(this->getTypePtr()->arg_type_begin());
+ param_type_iterator param_type_begin() const {
+ return param_type_iterator(this->getTypePtr()->param_type_begin());
}
- arg_type_iterator arg_type_end() const {
- return arg_type_iterator(this->getTypePtr()->arg_type_end());
+ param_type_iterator param_type_end() const {
+ return param_type_iterator(this->getTypePtr()->param_type_end());
}
// Note: canonical function types never have exception specifications
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 09ff682..72ca9f5 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -165,7 +165,7 @@
/// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
/// greater than or equal to this quantity and is a multiple of \p Align.
/// Align must be non-zero.
- CharUnits RoundUpToAlignment(const CharUnits &Align) {
+ CharUnits RoundUpToAlignment(const CharUnits &Align) const {
return CharUnits(llvm::RoundUpToAlignment(Quantity,
Align.Quantity));
}
@@ -173,12 +173,7 @@
/// Given that this is a non-zero alignment value, what is the
/// alignment at the given offset?
CharUnits alignmentAtOffset(CharUnits offset) {
- // alignment: 0010000
- // offset: 1011100
- // lowBits: 0001011
- // result: 0000100
- QuantityType lowBits = (Quantity-1) & (offset.Quantity-1);
- return CharUnits((lowBits + 1) & ~lowBits);
+ return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
}
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 28849f5..50e9196 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -194,9 +194,9 @@
const char *getCommentKindName() const;
- LLVM_ATTRIBUTE_USED void dump() const;
- LLVM_ATTRIBUTE_USED void dumpColor() const;
- LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const;
+ void dump() const;
+ void dumpColor() const;
+ void dump(const ASTContext &Context) const;
void dump(raw_ostream &OS, const CommandTraits *Traits,
const SourceManager *SM) const;
@@ -699,7 +699,7 @@
unsigned ParamIndex;
public:
- enum LLVM_ENUM_INT_TYPE(unsigned) {
+ enum : unsigned {
InvalidParamIndex = ~0U,
VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
};
@@ -981,9 +981,9 @@
/// that we consider a "function".
ArrayRef<const ParmVarDecl *> ParamVars;
- /// Function result type if \c CommentDecl is something that we consider
+ /// Function return type if \c CommentDecl is something that we consider
/// a "function".
- QualType ResultType;
+ QualType ReturnType;
/// Template parameters that can be referenced by \\tparam if \c CommentDecl is
/// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
index ed323da..958ee03 100644
--- a/include/clang/AST/CommentCommands.td
+++ b/include/clang/AST/CommentCommands.td
@@ -146,7 +146,7 @@
def Version : BlockCommand<"version">;
def Warning : BlockCommand<"warning">;
// HeaderDoc commands
-def Abstract : BlockCommand<"abstract">;
+def Abstract : BlockCommand<"abstract"> { let IsBriefCommand = 1; }
def ClassDesign : RecordLikeDetailCommand<"classdesign">;
def CoClass : RecordLikeDetailCommand<"coclass">;
def Dependency : RecordLikeDetailCommand<"dependency">;
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index f152c77..8070615 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CLANG_AST_COMMENT_LEXER_H
#define LLVM_CLANG_AST_COMMENT_LEXER_H
-#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -293,17 +293,7 @@
StringRef resolveHTMLHexCharacterReference(StringRef Name) const;
void formTokenWithChars(Token &Result, const char *TokEnd,
- tok::TokenKind Kind) {
- const unsigned TokLen = TokEnd - BufferPtr;
- Result.setLocation(getSourceLocation(BufferPtr));
- Result.setKind(Kind);
- Result.setLength(TokLen);
-#ifndef NDEBUG
- Result.TextPtr = "<UNSET>";
- Result.IntVal = 7;
-#endif
- BufferPtr = TokEnd;
- }
+ tok::TokenKind Kind);
void formTextToken(Token &Result, const char *TokEnd) {
StringRef Text(BufferPtr, TokEnd - BufferPtr);
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
new file mode 100644
index 0000000..d10258e
--- /dev/null
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -0,0 +1,2437 @@
+//===--- DataRecursiveASTVisitor.h - Data-Recursive AST Visitor -*- 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 DataRecursiveASTVisitor interface, which recursively
+// traverses the entire AST, using data recursion for Stmts/Exprs.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+
+// The following three macros are used for meta programming. The code
+// 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)
+
+// 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)
+
+// 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)
+
+namespace clang {
+
+// 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
+// in CALL_EXPR).
+#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.
+///
+/// This class performs three distinct tasks:
+/// 1. traverse the AST (i.e. go to each node);
+/// 2. at a given node, walk up the class hierarchy, starting from
+/// the node's dynamic type, until the top-most class (e.g. Stmt,
+/// Decl, or Type) is reached.
+/// 3. given a (node, class) combination, where 'class' is some base
+/// class of the dynamic type of 'node', call a user-overridable
+/// function to actually visit the node.
+///
+/// These tasks are done by three groups of methods, respectively:
+/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
+/// for traversing an AST rooted at x. This method simply
+/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
+/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
+/// then recursively visits the child nodes of x.
+/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
+/// similarly.
+/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
+/// any child node of x. Instead, it first calls WalkUpFromBar(x)
+/// where Bar is the direct parent class of Foo (unless Foo has
+/// no parent), and then calls VisitFoo(x) (see the next list item).
+/// 3. VisitFoo(Foo *x) does task #3.
+///
+/// These three method groups are tiered (Traverse* > WalkUpFrom* >
+/// Visit*). A method (e.g. Traverse*) may call methods from the same
+/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
+/// It may not call methods from a higher tier.
+///
+/// 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
+/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
+///
+/// This scheme guarantees that all Visit*() calls for the same AST
+/// node are grouped together. In other words, Visit*() methods for
+/// different nodes are never interleaved.
+///
+/// Stmts are traversed internally using a data queue to avoid a stack overflow
+/// with hugely nested ASTs.
+///
+/// Clients of this visitor should subclass the visitor (providing
+/// themselves as the template argument, using the curiously recurring
+/// template pattern) and override any of the Traverse*, WalkUpFrom*,
+/// and Visit* methods for declarations, types, statements,
+/// expressions, or other AST nodes where the visitor should customize
+/// behavior. Most users only need to override Visit*. Advanced
+/// users may override Traverse* and WalkUpFrom* to implement custom
+/// traversal strategies. Returning false from one of these overridden
+/// functions will abort the entire traversal.
+///
+/// By default, this visitor tries to visit every part of the explicit
+/// source code exactly once. The default policy towards templates
+/// is to descend into the 'pattern' class or function body, not any
+/// explicit or implicit instantiations. Explicit specializations
+/// are still visited, and the patterns of partial specializations
+/// are visited separately. This behavior can be changed by
+/// overriding shouldVisitTemplateInstantiations() in the derived class
+/// 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 {
+public:
+ /// \brief Return a reference to the derived class.
+ Derived &getDerived() { return *static_cast<Derived*>(this); }
+
+ /// \brief Return whether this visitor should recurse into
+ /// template instantiations.
+ bool shouldVisitTemplateInstantiations() const { return false; }
+
+ /// \brief Return whether this visitor should recurse into the types of
+ /// TypeLocs.
+ bool shouldWalkTypesOfTypeLocs() const { return true; }
+
+ /// \brief Recursively visit a statement or expression, by
+ /// dispatching to Traverse*() based on the argument's dynamic type.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is NULL).
+ bool TraverseStmt(Stmt *S);
+
+ /// \brief Recursively visit a type, by dispatching to
+ /// Traverse*Type() based on the argument's getTypeClass() property.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type).
+ bool TraverseType(QualType T);
+
+ /// \brief Recursively visit a type with location, by dispatching to
+ /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type location).
+ bool TraverseTypeLoc(TypeLoc TL);
+
+ /// \brief Recursively visit an attribute, by dispatching to
+ /// Traverse*Attr() based on the argument's dynamic type.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type location).
+ bool TraverseAttr(Attr *At);
+
+ /// \brief Recursively visit a declaration, by dispatching to
+ /// Traverse*Decl() based on the argument's dynamic type.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is NULL).
+ bool TraverseDecl(Decl *D);
+
+ /// \brief Recursively visit a C++ nested-name-specifier.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+ /// \brief Recursively visit a C++ nested-name-specifier with location
+ /// information.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
+
+ /// \brief Recursively visit a name with its location information.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
+
+ /// \brief Recursively visit a template name and dispatch to the
+ /// appropriate method.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseTemplateName(TemplateName Template);
+
+ /// \brief Recursively visit a template argument and dispatch to the
+ /// appropriate method for the argument type.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ // FIXME: migrate callers to TemplateArgumentLoc instead.
+ bool TraverseTemplateArgument(const TemplateArgument &Arg);
+
+ /// \brief Recursively visit a template argument location and dispatch to the
+ /// appropriate method for the argument type.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
+
+ /// \brief Recursively visit a set of template arguments.
+ /// This can be overridden by a subclass, but it's not expected that
+ /// will be needed -- this visitor always dispatches to another.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
+ bool TraverseTemplateArguments(const TemplateArgument *Args,
+ unsigned NumArgs);
+
+ /// \brief Recursively visit a constructor initializer. This
+ /// automatically dispatches to another visitor for the initializer
+ /// expression, but not for the name of the initializer, so may
+ /// be overridden for clients that need access to the name.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
+
+ /// \brief Recursively visit a lambda capture.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseLambdaCapture(LambdaExpr::Capture C);
+
+ // ---- Methods on Attrs ----
+
+ // \brief Visit an attribute.
+ bool VisitAttr(Attr *A) { return true; }
+
+ // 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 ----
+
+ // Declare Traverse*() for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#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; \
+ } \
+ 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; \
+ } \
+ 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; \
+ } \
+ 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) \
+ 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.
+
+ // Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#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; \
+ } \
+ 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
+
+ // Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#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.
+
+ // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
+ bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
+ bool VisitTypeLoc(TypeLoc TL) { return true; }
+
+ // QualifiedTypeLoc and UnqualTypeLoc are not declared in
+ // TypeNodes.def and thus need to be handled specially.
+ bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
+ return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+ }
+ bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
+ bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
+ return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+ }
+ 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; \
+ } \
+ bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+ // ---- Methods on Decls ----
+
+ // Declare Traverse*() for all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#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; \
+ } \
+ bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
+
+private:
+ // These are helper methods used by more than one Traverse* method.
+ bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+ bool TraverseClassInstantiations(ClassTemplateDecl *D);
+ bool TraverseVariableInstantiations(VarTemplateDecl *D);
+ bool TraverseFunctionInstantiations(FunctionTemplateDecl *D) ;
+ bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
+ unsigned Count);
+ bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
+ bool TraverseRecordHelper(RecordDecl *D);
+ bool TraverseCXXRecordHelper(CXXRecordDecl *D);
+ bool TraverseDeclaratorHelper(DeclaratorDecl *D);
+ bool TraverseDeclContextHelper(DeclContext *DC);
+ bool TraverseFunctionHelper(FunctionDecl *D);
+ bool TraverseVarHelper(VarDecl *D);
+ bool TraverseOMPClause(OMPClause *C);
+ bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+#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);
+
+ typedef SmallVector<Stmt *, 16> StmtsTy;
+ typedef SmallVector<StmtsTy *, 4> QueuesTy;
+
+ QueuesTy Queues;
+
+ class NewQueueRAII {
+ DataRecursiveASTVisitor &RAV;
+ public:
+ NewQueueRAII(StmtsTy &queue, DataRecursiveASTVisitor &RAV) : RAV(RAV) {
+ RAV.Queues.push_back(&queue);
+ }
+ ~NewQueueRAII() {
+ RAV.Queues.pop_back();
+ }
+ };
+
+ StmtsTy &getCurrentQueue() {
+ assert(!Queues.empty() && "base TraverseStmt was never called?");
+ return *Queues.back();
+ }
+
+public:
+ class StmtQueueAction {
+ StmtsTy &CurrQueue;
+ public:
+ explicit StmtQueueAction(DataRecursiveASTVisitor &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))
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
+ if (!S)
+ return true;
+
+ StmtsTy Queue, StmtsToEnqueu;
+ Queue.push_back(S);
+ NewQueueRAII NQ(StmtsToEnqueu, *this);
+
+ while (!Queue.empty()) {
+ S = Queue.pop_back_val();
+ if (!S)
+ continue;
+
+ StmtsToEnqueu.clear();
+
+#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()
+#undef OPERATOR
+#undef BINOP_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()
+#undef OPERATOR
+#undef UNARYOP_LIST
+ }
+ } else {
+
+ // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
+ switch (S->getStmtClass()) {
+ case Stmt::NoStmtClass: break;
+#define ABSTRACT_STMT(STMT)
+#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)
+ Queue.push_back(*RI);
+ }
+
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<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()));
+#include "clang/AST/TypeNodes.def"
+ }
+
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+ if (TL.isNull())
+ return true;
+
+ switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) \
+ case TypeLoc::CLASS: \
+ return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
+#include "clang/AST/TypeLocNodes.def"
+ }
+
+ return true;
+}
+
+
+// Define the Traverse*Attr(Attr* A) methods
+#define VISITORCLASS DataRecursiveASTVisitor
+#include "clang/AST/AttrVisitor.inc"
+#undef VISITORCLASS
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
+ if (!D)
+ return true;
+
+ // As a syntax visitor, we want to ignore declarations for
+ // implicitly-defined declarations (ones not typed explicitly by the
+ // user).
+ if (D->isImplicit())
+ return true;
+
+ 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; \
+ break;
+#include "clang/AST/DeclNodes.inc"
+ }
+
+ // Visit any attributes attached to this declaration.
+ for (auto *I : D->attrs()) {
+ if (!getDerived().TraverseAttr(I))
+ return false;
+ }
+ return true;
+}
+
+#undef DISPATCH
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
+ NestedNameSpecifier *NNS) {
+ if (!NNS)
+ return true;
+
+ if (NNS->getPrefix())
+ TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
+
+ switch (NNS->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::Global:
+ return true;
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
+ }
+
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
+ NestedNameSpecifierLoc NNS) {
+ if (!NNS)
+ return true;
+
+ if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+ TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+
+ switch (NNS.getNestedNameSpecifier()->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::Global:
+ return true;
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
+ break;
+ }
+
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
+ DeclarationNameInfo NameInfo) {
+ switch (NameInfo.getName().getNameKind()) {
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
+ TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
+
+ break;
+
+ case DeclarationName::Identifier:
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::CXXOperatorName:
+ case DeclarationName::CXXLiteralOperatorName:
+ case DeclarationName::CXXUsingDirective:
+ break;
+ }
+
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
+ if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+ TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
+ else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+ TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
+
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseTemplateArgument(
+ const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ case TemplateArgument::NullPtr:
+ return true;
+
+ case TemplateArgument::Type:
+ return getDerived().TraverseType(Arg.getAsType());
+
+ case TemplateArgument::Template:
+ case TemplateArgument::TemplateExpansion:
+ return getDerived().TraverseTemplateName(
+ Arg.getAsTemplateOrTemplatePattern());
+
+ case TemplateArgument::Expression:
+ return getDerived().TraverseStmt(Arg.getAsExpr());
+
+ case TemplateArgument::Pack:
+ return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+ Arg.pack_size());
+ }
+
+ return true;
+}
+
+// FIXME: no template name location?
+// FIXME: no source locations for a template argument pack?
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
+ const TemplateArgumentLoc &ArgLoc) {
+ const TemplateArgument &Arg = ArgLoc.getArgument();
+
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ case TemplateArgument::NullPtr:
+ return true;
+
+ case TemplateArgument::Type: {
+ // FIXME: how can TSI ever be NULL?
+ if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
+ return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
+ else
+ return getDerived().TraverseType(Arg.getAsType());
+ }
+
+ case TemplateArgument::Template:
+ case TemplateArgument::TemplateExpansion:
+ if (ArgLoc.getTemplateQualifierLoc())
+ TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
+ ArgLoc.getTemplateQualifierLoc()));
+ return getDerived().TraverseTemplateName(
+ Arg.getAsTemplateOrTemplatePattern());
+
+ case TemplateArgument::Expression:
+ return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
+
+ case TemplateArgument::Pack:
+ return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+ Arg.pack_size());
+ }
+
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseTemplateArguments(
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ for (unsigned I = 0; I != NumArgs; ++I) {
+ TRY_TO(TraverseTemplateArgument(Args[I]));
+ }
+
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
+ CXXCtorInitializer *Init) {
+ if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+
+ if (Init->isWritten())
+ TRY_TO(TraverseStmt(Init->getInit()));
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr::Capture C){
+ 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; \
+ }
+
+DEF_TRAVERSE_TYPE(BuiltinType, { })
+
+DEF_TRAVERSE_TYPE(ComplexType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ })
+
+DEF_TRAVERSE_TYPE(PointerType, {
+ 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(RValueReferenceType, {
+ TRY_TO(TraverseType(T->getPointeeType()));
+ })
+
+DEF_TRAVERSE_TYPE(MemberPointerType, {
+ 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(ConstantArrayType, {
+ 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()));
+ })
+
+DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
+ 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()));
+ })
+
+DEF_TRAVERSE_TYPE(VectorType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ })
+
+DEF_TRAVERSE_TYPE(ExtVectorType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ })
+
+DEF_TRAVERSE_TYPE(FunctionNoProtoType,
+ { TRY_TO(TraverseType(T->getReturnType())); })
+
+DEF_TRAVERSE_TYPE(FunctionProtoType, {
+ TRY_TO(TraverseType(T->getReturnType()));
+
+ for (const auto &A : T->param_types()) {
+ TRY_TO(TraverseType(A));
+ }
+
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+})
+
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
+DEF_TRAVERSE_TYPE(TypedefType, { })
+
+DEF_TRAVERSE_TYPE(TypeOfExprType, {
+ TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
+ })
+
+DEF_TRAVERSE_TYPE(TypeOfType, {
+ TRY_TO(TraverseType(T->getUnderlyingType()));
+ })
+
+DEF_TRAVERSE_TYPE(DecltypeType, {
+ TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
+ })
+
+DEF_TRAVERSE_TYPE(UnaryTransformType, {
+ TRY_TO(TraverseType(T->getBaseType()));
+ TRY_TO(TraverseType(T->getUnderlyingType()));
+ })
+
+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(TemplateSpecializationType, {
+ TRY_TO(TraverseTemplateName(T->getTemplateName()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ })
+
+DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
+
+DEF_TRAVERSE_TYPE(AttributedType, {
+ TRY_TO(TraverseType(T->getModifiedType()));
+ })
+
+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, {
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ })
+
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ })
+
+DEF_TRAVERSE_TYPE(PackExpansionType, {
+ TRY_TO(TraverseType(T->getPattern()));
+ })
+
+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()));
+ })
+
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
+ TRY_TO(TraverseType(T->getPointeeType()));
+ })
+
+DEF_TRAVERSE_TYPE(AtomicType, {
+ TRY_TO(TraverseType(T->getValueType()));
+ })
+
+#undef DEF_TRAVERSE_TYPE
+
+// ----------------- TypeLoc traversal -----------------
+
+// This macro makes available a variable TL, the passed-in TypeLoc.
+// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
+// 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; \
+ }
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<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
+ // the normal CRTP plan of going through
+ // getDerived().TraverseTypeLoc. If we did, we'd be traversing
+ // twice for the same type (once as a QualifiedTypeLoc version of
+ // the type, once as an UnqualifiedTypeLoc version of the type),
+ // which in effect means we'd call VisitTypeLoc twice with the
+ // 'same' type. This solves that problem, at the cost of never
+ // seeing the qualified version of the type (unless the client
+ // subclasses TraverseQualifiedTypeLoc themselves). It's not a
+ // perfect solution. A perfect solution probably requires making
+ // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
+ // wrapper around Type* -- rather than being its own class in the
+ // type hierarchy.
+ return TraverseTypeLoc(TL.getUnqualifiedLoc());
+}
+
+DEF_TRAVERSE_TYPELOC(BuiltinType, { })
+
+// FIXME: ComplexTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ComplexType, {
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+ })
+
+DEF_TRAVERSE_TYPELOC(PointerType, {
+ 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(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()));
+ })
+
+DEF_TRAVERSE_TYPELOC(DecayedType, {
+ TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(AdjustedType, {
+ TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
+ })
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<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);
+ })
+
+DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+ })
+
+DEF_TRAVERSE_TYPELOC(VariableArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+ })
+
+DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
+ 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()));
+ })
+
+// FIXME: VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(VectorType, {
+ 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()));
+ })
+
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
+ TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
+ })
+
+// FIXME: location of exception specifications (attributes?)
+DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
+ TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
+
+ 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 (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+ })
+
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
+DEF_TRAVERSE_TYPELOC(TypedefType, { })
+
+DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
+ TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
+ })
+
+DEF_TRAVERSE_TYPELOC(TypeOfType, {
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+ })
+
+// FIXME: location of underlying expr
+DEF_TRAVERSE_TYPELOC(DecltypeType, {
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+ })
+
+DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(AutoType, {
+ 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, { })
+
+// 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)));
+ }
+ })
+
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
+
+DEF_TRAVERSE_TYPELOC(ParenType, {
+ TRY_TO(TraverseTypeLoc(TL.getInnerLoc()));
+ })
+
+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()));
+ })
+
+DEF_TRAVERSE_TYPELOC(DependentNameType, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
+
+ 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(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()));
+ })
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+ })
+
+DEF_TRAVERSE_TYPELOC(AtomicType, {
+ TRY_TO(TraverseTypeLoc(TL.getValueLoc()));
+ })
+
+#undef DEF_TRAVERSE_TYPELOC
+
+// ----------------- Decl traversal -----------------
+//
+// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
+// the children that come from the DeclContext associated with it.
+// Therefore each Traverse* only needs to worry about children other
+// than those.
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
+ if (!DC)
+ return true;
+
+ for (auto *Child : DC->decls()) {
+ // BlockDecls and CapturedDecls are traversed through BlockExprs and
+ // CapturedStmts respectively.
+ if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+ TRY_TO(TraverseDecl(Child));
+ }
+
+ return true;
+}
+
+// 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; \
+}
+
+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.
+})
+
+
+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()) {
+ TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
+ }
+ for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ if (D->isThisDeclarationADefinition()) {
+ TRY_TO(TraverseStmt(D->getBody()));
+ }
+ return true;
+})
+
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+ // FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(UsingDecl, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+ })
+
+DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ })
+
+DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+
+DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
+ for (auto *I : D->varlists()) {
+ TRY_TO(TraverseStmt(I));
+ }
+ })
+
+// A helper method for TemplateDecl's children.
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
+ TemplateParameterList *TPL) {
+ if (TPL) {
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ }
+ return true;
+}
+
+// A helper method for traversing the implicit instantiations of a
+// class template.
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseClassInstantiations(
+ ClassTemplateDecl *D) {
+ for (auto *SD : D->specializations()) {
+ for (auto *RD : SD->redecls()) {
+ // We don't want to visit injected-class-names in this traversal.
+ if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
+ continue;
+
+ switch (cast<ClassTemplateSpecializationDecl>(RD)->
+ getSpecializationKind()) {
+ // Visit the implicit instantiations with the requested pattern.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ TRY_TO(TraverseDecl(RD));
+ break;
+
+ // We don't need to do anything on an explicit instantiation
+ // or explicit specialization because there will be an explicit
+ // node for it elsewhere.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplateDecl, {
+ 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));
+
+ // 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(
+ VarTemplateDecl *D) {
+ for (auto *SD : D->specializations()) {
+ for (auto *RD : SD->redecls()) {
+ switch (cast<VarTemplateSpecializationDecl>(RD)->
+ getSpecializationKind()) {
+ // Visit the implicit instantiations with the requested pattern.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ TRY_TO(TraverseDecl(RD));
+ break;
+
+ // We don't need to do anything on an explicit instantiation
+ // or explicit specialization because there will be an explicit
+ // node for it elsewhere.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+DEF_TRAVERSE_DECL(
+ VarTemplateDecl,
+ {
+ VarDecl *TempDecl = D->getTemplatedDecl();
+ TRY_TO(TraverseDecl(TempDecl));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+ // By default, we do not traverse the instantiations of
+ // variable templates since they do not appear in the user code. The
+ // following code optionally traverses them.
+ //
+ // We only traverse the variable 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(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.
+})
+
+// A helper method for traversing the instantiations of a
+// function while skipping its specializations.
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
+ FunctionTemplateDecl *D) {
+ for (auto *FD : D->specializations()) {
+ for (auto *RD : FD->redecls()) {
+ switch (RD->getTemplateSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ // We don't know what kind of FunctionDecl this is.
+ TRY_TO(TraverseDecl(RD));
+ break;
+
+ // No need to visit explicit instantiations, we'll find the node
+ // eventually.
+ // FIXME: This is incorrect; there is no other node for an explicit
+ // instantiation of a function template specialization.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ break;
+
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
+ 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));
+ })
+
+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()));
+ })
+
+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()));
+ })
+
+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.
+ })
+
+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.
+ })
+
+DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
+ 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.
+ })
+
+DEF_TRAVERSE_DECL(EnumDecl, {
+ 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().
+ })
+
+
+// Helper methods for RecordDecl and its children.
+template<typename Derived>
+bool DataRecursiveASTVisitor<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.
+
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
+ CXXRecordDecl *D) {
+ if (!TraverseRecordHelper(D))
+ return false;
+ if (D->isCompleteDefinition()) {
+ for (const auto &I : D->bases()) {
+ TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
+ }
+ // We don't traverse the friends or the conversions, as they are
+ // already in decls_begin()/decls_end().
+ }
+ return true;
+}
+
+DEF_TRAVERSE_DECL(RecordDecl, {
+ TRY_TO(TraverseRecordHelper(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()));
+
+ 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(
+ const TemplateArgumentLoc *TAL, unsigned Count) {
+ for (unsigned I = 0; I < Count; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
+ }
+ return true;
+}
+
+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 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));
+
+ // Instantiations will have been visited with the primary template.
+ })
+
+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()));
+ })
+
+DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ if (D->getTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ else
+ TRY_TO(TraverseType(D->getType()));
+ 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(ObjCAtDefsFieldDecl, {
+ 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.
+ })
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+
+ // If we're an explicit template specialization, iterate over the
+ // template args that were explicitly specified. If we were doing
+ // this in typing order, we'd do it between the return type and
+ // 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()) {
+ 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) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
+ TALI->NumTemplateArgs));
+ }
+ }
+ }
+
+ // Visit the function type itself, which can be either
+ // FunctionNoProtoType or FunctionProtoType, or a typedef. This
+ // also covers the return type and the function parameters,
+ // including exception specifications.
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+
+ if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+ // Constructor initializers.
+ for (auto *I : Ctor->inits()) {
+ TRY_TO(TraverseConstructorInitializer(I));
+ }
+ }
+
+ if (D->isThisDeclarationADefinition()) {
+ 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);
+ })
+
+DEF_TRAVERSE_DECL(CXXMethodDecl, {
+ // 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);
+ })
+
+// 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);
+ })
+
+DEF_TRAVERSE_DECL(CXXDestructorDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+ })
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ // Default params are taken care of when we traverse the ParmVarDecl.
+ if (!isa<ParmVarDecl>(D))
+ TRY_TO(TraverseStmt(D->getInit()));
+ return true;
+}
+
+DEF_TRAVERSE_DECL(VarDecl, {
+ TRY_TO(TraverseVarHelper(D));
+ })
+
+DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, {
+ // For implicit instantiations, we don't want to
+ // recurse at all, since the instatiated class isn't written in
+ // the source code anywhere.
+ 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 VarTemplateSpecializationDecl
+ // (embedded in the DEF_TRAVERSE_DECL() macro).
+ return true;
+})
+
+DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl,
+ {
+ // 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));
+
+ // 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.
+})
+
+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()));
+ })
+
+DEF_TRAVERSE_DECL(ParmVarDecl, {
+ 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->getDefaultArg()));
+ })
+
+#undef DEF_TRAVERSE_DECL
+
+// ----------------- Stmt traversal -----------------
+//
+// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
+// over the children defined in children() (every stmt defines these,
+// though sometimes the range is empty). Each individual Traverse*
+// method only needs to worry about children other than those. To see
+// what children() does for a given class, see, e.g.,
+// 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; \
+}
+
+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.
+ })
+
+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.
+ })
+
+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;
+ })
+
+
+// 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(MSDependentExistsStmt, {
+ 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(CXXDependentScopeMemberExpr, {
+ 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()));
+ })
+
+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()));
+ }
+ })
+
+DEF_TRAVERSE_STMT(MemberExpr, {
+ 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(CStyleCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(CXXConstCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+ })
+
+DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
+ 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) {
+ if (InitListExpr *Syn = S->getSyntacticForm())
+ S = Syn;
+ TRY_TO(WalkUpFromInitListExpr(S));
+ StmtQueueAction StmtQueue(*this);
+ // All we need are the default actions. FIXME: use a helper function.
+ for (Stmt::child_range range = S->children(); range; ++range) {
+ StmtQueue.queue(*range);
+ }
+ return true;
+}
+
+// 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) {
+ TRY_TO(WalkUpFromGenericSelectionExpr(S));
+ StmtQueueAction StmtQueue(*this);
+ StmtQueue.queue(S->getControllingExpr());
+ for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
+ if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
+ TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
+ StmtQueue.queue(S->getAssocExpr(i));
+ }
+ return true;
+}
+
+// PseudoObjectExpr is a special case because of the wierdness with
+// syntactic expressions and opaque values.
+template<typename Derived>
+bool DataRecursiveASTVisitor<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) {
+ Expr *sub = *i;
+ if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
+ sub = OVE->getSourceExpr();
+ StmtQueue.queue(sub);
+ }
+ return true;
+}
+
+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()));
+ })
+
+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()));
+ })
+
+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()));
+ })
+
+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()));
+ })
+
+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()));
+ })
+
+DEF_TRAVERSE_STMT(TypeTraitExpr, {
+ for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+ TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
+ TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+ })
+
+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()));
+ })
+
+DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
+ // 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) {
+ TRY_TO(WalkUpFromLambdaExpr(S));
+
+ for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
+ CEnd = S->explicit_capture_end();
+ C != CEnd; ++C) {
+ TRY_TO(TraverseLambdaCapture(*C));
+ }
+
+ if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+ // Visit the whole type.
+ TRY_TO(TraverseTypeLoc(TL));
+ } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
+ if (S->hasExplicitParameters()) {
+ // Visit parameters.
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ TRY_TO(TraverseDecl(Proto.getParam(I)));
+ }
+ } else {
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+ }
+ }
+ }
+
+ StmtQueueAction StmtQueue(*this);
+ StmtQueue.queue(S->getBody());
+ 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()));
+ })
+
+// 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, { })
+
+// 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(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(CXXPseudoDestructorExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
+ TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
+ 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(ObjCEncodeExpr, {
+ if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+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(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(UnresolvedLookupExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
+
+DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
+
+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(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, { })
+
+// 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, { })
+
+// Traverse OpenCL: AsType, Convert.
+DEF_TRAVERSE_STMT(AsTypeExpr, { })
+
+// OpenMP directives.
+template<typename Derived>
+bool DataRecursiveASTVisitor<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;
+ return true;
+}
+
+DEF_TRAVERSE_STMT(OMPParallelDirective, {
+ if (!TraverseOMPExecutableDirective(S)) return false;
+})
+
+DEF_TRAVERSE_STMT(OMPSimdDirective, {
+ if (!TraverseOMPExecutableDirective(S)) return false;
+})
+
+// OpenMP clauses.
+template<typename Derived>
+bool DataRecursiveASTVisitor<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));
+#include "clang/Basic/OpenMPKinds.def"
+ default: break;
+ }
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+ TraverseStmt(C->getCondition());
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(
+ OMPNumThreadsClause *C) {
+ TraverseStmt(C->getNumThreads());
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPSafelenClause(
+ OMPSafelenClause *C) {
+ TraverseStmt(C->getSafelen());
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
+ return true;
+}
+
+template<typename Derived>
+template<typename T>
+void DataRecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+ for (auto *I : Node->varlists())
+ TraverseStmt(I);
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
+ OMPFirstprivateClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
+template<typename Derived>
+bool DataRecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
+// FIXME: look at the following tricky-seeming exprs to see if we
+// need to recurse on anything. These are ones that have methods
+// returning decls or qualtypes or nestednamespecifier -- though I'm
+// not sure if they own them -- or just seemed very complicated, or
+// had lots of sub-types to explore.
+//
+// VisitOverloadExpr and its children: recurse on template args? etc?
+
+// FIXME: go through all the stmts and exprs again, and see which of them
+// create new types, and recurse on the types (TypeLocs?) of those.
+// Candidates:
+//
+// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
+// Every class that has getQualifier.
+
+#undef DEF_TRAVERSE_STMT
+
+#undef TRY_TO
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 244a7b8..526187e 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -110,7 +110,7 @@
DeclarationName Name;
private:
- NamedDecl *getUnderlyingDeclImpl();
+ NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY;
protected:
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
@@ -161,9 +161,8 @@
void printQualifiedName(raw_ostream &OS) const;
void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
- // FIXME: Remove string versions.
+ // FIXME: Remove string version.
std::string getQualifiedNameAsString() const;
- std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const;
/// getNameForDiagnostic - Appends a human-readable name for this
/// declaration into the given stream.
@@ -259,6 +258,16 @@
/// checking. Should always return true.
bool isLinkageValid() const;
+ /// \brief True if something has required us to compute the linkage
+ /// of this declaration.
+ ///
+ /// Language features which can retroactively change linkage (like a
+ /// typedef name for linkage purposes) may need to consider this,
+ /// but hopefully only in transitory ways during parsing.
+ bool hasLinkageBeenComputed() const {
+ return hasCachedLinkage();
+ }
+
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl() {
@@ -295,7 +304,7 @@
/// location of the statement. For GNU local labels (__label__), the decl
/// location is where the __label__ is.
class LabelDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
LabelStmt *TheStmt;
/// LocStart - For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
@@ -320,7 +329,7 @@
bool isGnuLocal() const { return LocStart != getLocation(); }
void setLocStart(SourceLocation L) { LocStart = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(LocStart, getLocation());
}
@@ -333,8 +342,6 @@
class NamespaceDecl : public NamedDecl, public DeclContext,
public Redeclarable<NamespaceDecl>
{
- virtual void anchor();
-
/// LocStart - The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
SourceLocation LocStart;
@@ -350,18 +357,12 @@
NamespaceDecl(DeclContext *DC, bool Inline, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
NamespaceDecl *PrevDecl);
-
+
typedef Redeclarable<NamespaceDecl> redeclarable_base;
- virtual NamespaceDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
- }
- virtual NamespaceDecl *getPreviousDeclImpl() {
- return getPreviousDecl();
- }
- virtual NamespaceDecl *getMostRecentDeclImpl() {
- return getMostRecentDecl();
- }
-
+ NamespaceDecl *getNextRedeclaration() override;
+ NamespaceDecl *getPreviousDeclImpl() override;
+ NamespaceDecl *getMostRecentDeclImpl() override;
+
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
bool Inline, SourceLocation StartLoc,
@@ -370,9 +371,11 @@
static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -432,14 +435,14 @@
}
/// Retrieves the canonical declaration of this namespace.
- NamespaceDecl *getCanonicalDecl() {
+ NamespaceDecl *getCanonicalDecl() override {
return getOriginalNamespace();
}
const NamespaceDecl *getCanonicalDecl() const {
return getOriginalNamespace();
}
-
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(LocStart, RBraceLoc);
}
@@ -466,7 +469,7 @@
/// an lvalue) a function (in which case it is a function designator) or
/// an enum constant.
class ValueDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
QualType DeclType;
protected:
@@ -567,7 +570,7 @@
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
SourceLocation getLocStart() const LLVM_READONLY {
return getOuterLocStart();
}
@@ -769,18 +772,20 @@
TypeSourceInfo *TInfo, StorageClass SC);
typedef Redeclarable<VarDecl> redeclarable_base;
- virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
- virtual VarDecl *getPreviousDeclImpl() {
+ VarDecl *getNextRedeclaration() override { return RedeclLink.getNext(); }
+ VarDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual VarDecl *getMostRecentDeclImpl() {
+ VarDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -791,8 +796,8 @@
StorageClass S);
static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// \brief Returns the storage class as written in the source. For the
/// computed linkage of symbol, see getLinkage.
@@ -913,7 +918,7 @@
return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
}
- virtual VarDecl *getCanonicalDecl();
+ VarDecl *getCanonicalDecl() override;
const VarDecl *getCanonicalDecl() const {
return const_cast<VarDecl*>(this)->getCanonicalDecl();
}
@@ -960,7 +965,7 @@
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
- virtual bool isOutOfLine() const;
+ bool isOutOfLine() const override;
/// \brief If this is a static data member, find its out-of-line definition.
VarDecl *getOutOfLineDefinition();
@@ -1208,7 +1213,7 @@
};
class ImplicitParamDecl : public VarDecl {
- virtual void anchor();
+ void anchor() override;
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -1254,8 +1259,8 @@
StorageClass S, Expr *DefArg);
static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
void setObjCMethodScopeInfo(unsigned parameterIndex) {
ParmVarDeclBits.IsObjCMethodParam = true;
@@ -1559,18 +1564,20 @@
DNLoc(NameInfo.getInfo()) {}
typedef Redeclarable<FunctionDecl> redeclarable_base;
- virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
- virtual FunctionDecl *getPreviousDeclImpl() {
+ FunctionDecl *getNextRedeclaration() override { return RedeclLink.getNext(); }
+ FunctionDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual FunctionDecl *getMostRecentDeclImpl() {
+ FunctionDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -1605,13 +1612,12 @@
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
- virtual void getNameForDiagnostic(raw_ostream &OS,
- const PrintingPolicy &Policy,
- bool Qualified) const;
+ void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+ bool Qualified) const override;
void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// \brief Returns true if the function has a body (definition). The
/// function body might be in any of the (re-)declarations of this
@@ -1620,7 +1626,7 @@
/// containing the body (if there is one).
bool hasBody(const FunctionDecl *&Definition) const;
- virtual bool hasBody() const {
+ bool hasBody() const override {
const FunctionDecl* Definition;
return hasBody(Definition);
}
@@ -1648,7 +1654,7 @@
/// unnecessary AST de-serialization of the body.
Stmt *getBody(const FunctionDecl *&Definition) const;
- virtual Stmt *getBody() const {
+ Stmt *getBody() const override {
const FunctionDecl* Definition;
return getBody(Definition);
}
@@ -1828,7 +1834,7 @@
void setPreviousDeclaration(FunctionDecl * PrevDecl);
virtual const FunctionDecl *getCanonicalDecl() const;
- virtual FunctionDecl *getCanonicalDecl();
+ FunctionDecl *getCanonicalDecl() override;
unsigned getBuiltinID() const;
@@ -1836,12 +1842,24 @@
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
typedef ParmVarDecl * const *param_const_iterator;
+ typedef llvm::iterator_range<param_iterator> param_range;
+ typedef llvm::iterator_range<param_const_iterator> param_const_range;
- param_iterator param_begin() { return ParamInfo; }
- param_iterator param_end() { return ParamInfo+param_size(); }
+ param_iterator param_begin() { return param_iterator(ParamInfo); }
+ param_iterator param_end() {
+ return param_iterator(ParamInfo + param_size());
+ }
+ param_range params() { return param_range(param_begin(), param_end()); }
- param_const_iterator param_begin() const { return ParamInfo; }
- param_const_iterator param_end() const { return ParamInfo+param_size(); }
+ param_const_iterator param_begin() const {
+ return param_const_iterator(ParamInfo);
+ }
+ param_const_iterator param_end() const {
+ return param_const_iterator(ParamInfo + param_size());
+ }
+ param_const_range params() const {
+ return param_const_range(param_begin(), param_end());
+ }
/// getNumParams - Return the number of parameters this function must have
/// based on its FunctionType. This is the length of the ParamInfo array
@@ -1860,6 +1878,12 @@
setParams(getASTContext(), NewParamInfo);
}
+ // ArrayRef iterface to parameters.
+ // FIXME: Should one day replace iterator interface.
+ ArrayRef<ParmVarDecl*> parameters() const {
+ return llvm::makeArrayRef(ParamInfo, getNumParams());
+ }
+
const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const {
return DeclsInPrototypeScope;
}
@@ -1871,8 +1895,8 @@
/// arguments (in C++).
unsigned getMinRequiredArguments() const;
- QualType getResultType() const {
- return getType()->getAs<FunctionType>()->getResultType();
+ QualType getReturnType() const {
+ return getType()->getAs<FunctionType>()->getReturnType();
}
/// \brief Determine the type of an expression that calls this function.
@@ -1906,6 +1930,8 @@
bool isInlineDefinitionExternallyVisible() const;
+ bool isMSExternInline() const;
+
bool doesDeclarationForceExternallyVisibleDefinition() const;
/// isOverloadedOperator - Whether this function declaration
@@ -2095,7 +2121,7 @@
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a member function.
- virtual bool isOutOfLine() const;
+ bool isOutOfLine() const override;
/// \brief Identify a memory copying or setting function.
/// If the given function is a memory copy or setting function, returns
@@ -2234,10 +2260,10 @@
return cast<RecordDecl>(getDeclContext());
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// Retrieves the canonical declaration of this field.
- FieldDecl *getCanonicalDecl() { return getFirstDecl(); }
+ FieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Implement isa/cast/dyncast/etc.
@@ -2276,10 +2302,10 @@
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
void setInitVal(const llvm::APSInt &V) { Val = V; }
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// Retrieves the canonical declaration of this enumerator.
- EnumConstantDecl *getCanonicalDecl() { return getFirstDecl(); }
+ EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); }
const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Implement isa/cast/dyncast/etc.
@@ -2293,7 +2319,7 @@
/// field injected from an anonymous union/struct into the parent scope.
/// IndirectFieldDecl are always implicit.
class IndirectFieldDecl : public ValueDecl {
- virtual void anchor();
+ void anchor() override;
NamedDecl **Chaining;
unsigned ChainingSize;
@@ -2310,8 +2336,13 @@
static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
typedef NamedDecl * const *chain_iterator;
- chain_iterator chain_begin() const { return Chaining; }
- chain_iterator chain_end() const { return Chaining+ChainingSize; }
+ typedef llvm::iterator_range<chain_iterator> chain_range;
+
+ chain_range chain() const { return chain_range(chain_begin(), chain_end()); }
+ chain_iterator chain_begin() const { return chain_iterator(Chaining); }
+ chain_iterator chain_end() const {
+ return chain_iterator(Chaining + ChainingSize);
+ }
unsigned getChainingSize() const { return ChainingSize; }
@@ -2334,7 +2365,7 @@
/// TypeDecl - Represents a declaration of a type.
///
class TypeDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// TypeForDecl - This indicates the Type object that represents
/// this TypeDecl. It is a cache maintained by
/// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
@@ -2364,7 +2395,7 @@
SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
void setLocStart(SourceLocation L) { LocStart = L; }
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
if (LocStart.isValid())
return SourceRange(LocStart, getLocation());
else
@@ -2379,7 +2410,7 @@
/// Base class for declarations which introduce a typedef-name.
class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
- virtual void anchor();
+ void anchor() override;
typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
@@ -2390,20 +2421,22 @@
: TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {}
typedef Redeclarable<TypedefNameDecl> redeclarable_base;
- virtual TypedefNameDecl *getNextRedeclaration() {
+ TypedefNameDecl *getNextRedeclaration() override {
return RedeclLink.getNext();
}
- virtual TypedefNameDecl *getPreviousDeclImpl() {
+ TypedefNameDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual TypedefNameDecl *getMostRecentDeclImpl() {
+ TypedefNameDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -2428,7 +2461,7 @@
}
/// Retrieves the canonical declaration of this typedef-name.
- TypedefNameDecl *getCanonicalDecl() { return getFirstDecl(); }
+ TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); }
const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Implement isa/cast/dyncast/etc.
@@ -2450,8 +2483,8 @@
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const LLVM_READONLY;
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2471,7 +2504,7 @@
IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2572,11 +2605,11 @@
}
typedef Redeclarable<TagDecl> redeclarable_base;
- virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
- virtual TagDecl *getPreviousDeclImpl() {
+ TagDecl *getNextRedeclaration() override { return RedeclLink.getNext(); }
+ TagDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual TagDecl *getMostRecentDeclImpl() {
+ TagDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -2586,9 +2619,11 @@
void completeDefinition();
public:
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -2603,9 +2638,9 @@
/// getOuterLocStart - Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
- virtual TagDecl* getCanonicalDecl();
+ TagDecl* getCanonicalDecl() override;
const TagDecl* getCanonicalDecl() const {
return const_cast<TagDecl*>(this)->getCanonicalDecl();
}
@@ -2773,7 +2808,7 @@
/// with a fixed underlying type, and in C we allow them to be forward-declared
/// with no underlying type as an extension.
class EnumDecl : public TagDecl {
- virtual void anchor();
+ void anchor() override;
/// IntegerType - This represent the integer type that the enum corresponds
/// to for code generation purposes. Note that the enumerator constants may
/// have a different type than this does.
@@ -2819,7 +2854,7 @@
void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
TemplateSpecializationKind TSK);
public:
- EnumDecl *getCanonicalDecl() {
+ EnumDecl *getCanonicalDecl() override {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
}
const EnumDecl *getCanonicalDecl() const {
@@ -2865,6 +2900,12 @@
// enumerator_iterator - Iterates through the enumerators of this
// enumeration.
typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>
+ enumerator_range;
+
+ enumerator_range enumerators() const {
+ return enumerator_range(enumerator_begin(), enumerator_end());
+ }
enumerator_iterator enumerator_begin() const {
const EnumDecl *E = getDefinition();
@@ -2888,27 +2929,32 @@
void setPromotionType(QualType T) { PromotionType = T; }
/// getIntegerType - Return the integer type this enum decl corresponds to.
- /// This returns a null qualtype for an enum forward definition.
+ /// This returns a null QualType for an enum forward definition with no fixed
+ /// underlying type.
QualType getIntegerType() const {
if (!IntegerType)
return QualType();
- if (const Type* T = IntegerType.dyn_cast<const Type*>())
+ if (const Type *T = IntegerType.dyn_cast<const Type*>())
return QualType(T, 0);
- return IntegerType.get<TypeSourceInfo*>()->getType();
+ return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
}
/// \brief Set the underlying integer type.
void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
/// \brief Set the underlying integer type source info.
- void setIntegerTypeSourceInfo(TypeSourceInfo* TInfo) { IntegerType = TInfo; }
+ void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
/// \brief Return the type source info for the underlying integer type,
/// if no type source info exists, return 0.
- TypeSourceInfo* getIntegerTypeSourceInfo() const {
+ TypeSourceInfo *getIntegerTypeSourceInfo() const {
return IntegerType.dyn_cast<TypeSourceInfo*>();
}
+ /// \brief Retrieve the source range that covers the underlying type if
+ /// specified.
+ SourceRange getIntegerTypeRange() const LLVM_READONLY;
+
/// \brief Returns the width in bits required to store all the
/// non-negative enumerators of this enum.
unsigned getNumPositiveBits() const {
@@ -3106,7 +3152,9 @@
// the non-static data members of this class, ignoring any static
// data members, functions, constructors, destructors, etc.
typedef specific_decl_iterator<FieldDecl> field_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range;
+ field_range fields() const { return field_range(field_begin(), field_end()); }
field_iterator field_begin() const;
field_iterator field_end() const {
@@ -3155,7 +3203,7 @@
SourceLocation getAsmLoc() const { return getLocation(); }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getAsmLoc(), getRParenLoc());
}
@@ -3251,7 +3299,7 @@
void setIsVariadic(bool value) { IsVariadic = value; }
CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
- Stmt *getBody() const { return (Stmt*) Body; }
+ Stmt *getBody() const override { return (Stmt*) Body; }
void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
@@ -3261,13 +3309,31 @@
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
typedef ParmVarDecl * const *param_const_iterator;
+ typedef llvm::iterator_range<param_iterator> param_range;
+ typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+ // ArrayRef access to formal parameters.
+ // FIXME: Should eventual replace iterator access.
+ ArrayRef<ParmVarDecl*> parameters() const {
+ return llvm::makeArrayRef(ParamInfo, param_size());
+ }
bool param_empty() const { return NumParams == 0; }
- param_iterator param_begin() { return ParamInfo; }
- param_iterator param_end() { return ParamInfo+param_size(); }
+ param_range params() { return param_range(param_begin(), param_end()); }
+ param_iterator param_begin() { return param_iterator(ParamInfo); }
+ param_iterator param_end() {
+ return param_iterator(ParamInfo + param_size());
+ }
- param_const_iterator param_begin() const { return ParamInfo; }
- param_const_iterator param_end() const { return ParamInfo+param_size(); }
+ param_const_range params() const {
+ return param_const_range(param_begin(), param_end());
+ }
+ param_const_iterator param_begin() const {
+ return param_const_iterator(ParamInfo);
+ }
+ param_const_iterator param_end() const {
+ return param_const_iterator(ParamInfo + param_size());
+ }
unsigned getNumParams() const { return NumParams; }
const ParmVarDecl *getParamDecl(unsigned i) const {
@@ -3290,6 +3356,16 @@
typedef const Capture *capture_iterator;
typedef const Capture *capture_const_iterator;
+ typedef llvm::iterator_range<capture_iterator> capture_range;
+ typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+
+ capture_range captures() {
+ return capture_range(capture_begin(), capture_end());
+ }
+ capture_const_range captures() const {
+ return capture_const_range(capture_begin(), capture_end());
+ }
+
capture_iterator capture_begin() { return Captures; }
capture_iterator capture_end() { return Captures + NumCaptures; }
capture_const_iterator capture_begin() const { return Captures; }
@@ -3321,7 +3397,7 @@
ManglingContextDecl = Ctx;
}
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3357,7 +3433,7 @@
static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumParams);
- Stmt *getBody() const { return Body; }
+ Stmt *getBody() const override { return Body; }
void setBody(Stmt *B) { Body = B; }
unsigned getNumParams() const { return NumParams; }
@@ -3376,11 +3452,16 @@
void setContextParam(ImplicitParamDecl *P) { setParam(0, P); }
typedef ImplicitParamDecl **param_iterator;
+ typedef llvm::iterator_range<param_iterator> param_range;
+
/// \brief Retrieve an iterator pointing to the first parameter decl.
param_iterator param_begin() const { return getParams(); }
/// \brief Retrieve an iterator one past the last parameter decl.
param_iterator param_end() const { return getParams() + NumParams; }
+ /// \brief Retrieve an iterator range for the parameter declarations.
+ param_range params() const { return param_range(param_begin(), param_end()); }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Captured; }
@@ -3455,9 +3536,9 @@
/// This will return an empty array if the locations of the individual
/// identifiers aren't available.
ArrayRef<SourceLocation> getIdentifierLocs() const;
-
- virtual SourceRange getSourceRange() const LLVM_READONLY;
-
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Import; }
};
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 26eea64..6c31358 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -19,6 +19,7 @@
#include "clang/Basic/Linkage.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -32,6 +33,7 @@
class DependentDiagnostic;
class EnumDecl;
class FunctionDecl;
+class FunctionType;
class LinkageComputer;
class LinkageSpecDecl;
class Module;
@@ -52,20 +54,6 @@
class UsingDirectiveDecl;
}
-namespace llvm {
-// DeclContext* is only 4-byte aligned on 32-bit systems.
-template<>
- class PointerLikeTypeTraits<clang::DeclContext*> {
- typedef clang::DeclContext* PT;
-public:
- static inline void *getAsVoidPointer(PT P) { return P; }
- static inline PT getFromVoidPointer(void *P) {
- return static_cast<PT>(P);
- }
- enum { NumLowBitsAvailable = 2 };
-};
-}
-
namespace clang {
/// \brief Captures the result of checking the availability of a
@@ -302,8 +290,24 @@
template<typename decl_type> friend class Redeclarable;
+ /// \brief Allocate memory for a deserialized declaration.
+ ///
+ /// This routine must be used to allocate memory for any declaration that is
+ /// deserialized from a module file.
+ ///
+ /// \param Size The size of the allocated object.
+ /// \param Ctx The context in which we will allocate memory.
+ /// \param ID The global ID of the deserialized declaration.
+ /// \param Extra The amount of extra space to allocate after the object.
+ void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID,
+ std::size_t Extra = 0);
+
+ /// \brief Allocate memory for a non-deserialized declaration.
+ void *operator new(std::size_t Size, const ASTContext &Ctx,
+ DeclContext *Parent, std::size_t Extra = 0);
+
private:
- void CheckAccessDeclContext() const;
+ bool AccessDeclContextSanity() const;
protected:
@@ -330,18 +334,6 @@
virtual ~Decl();
- /// \brief Allocate memory for a deserialized declaration.
- ///
- /// This routine must be used to allocate memory for any declaration that is
- /// deserialized from a module file.
- ///
- /// \param Context The context in which we will allocate memory.
- /// \param ID The global ID of the deserialized declaration.
- /// \param Size The size of the allocated object.
- static void *AllocateDeserializedDecl(const ASTContext &Context,
- unsigned ID,
- unsigned Size);
-
/// \brief Update a potentially out-of-date declaration.
void updateOutOfDate(IdentifierInfo &II) const;
@@ -409,15 +401,11 @@
void setAccess(AccessSpecifier AS) {
Access = AS;
-#ifndef NDEBUG
- CheckAccessDeclContext();
-#endif
+ assert(AccessDeclContextSanity());
}
AccessSpecifier getAccess() const {
-#ifndef NDEBUG
- CheckAccessDeclContext();
-#endif
+ assert(AccessDeclContextSanity());
return AccessSpecifier(Access);
}
@@ -445,9 +433,12 @@
}
typedef AttrVec::const_iterator attr_iterator;
+ typedef llvm::iterator_range<attr_iterator> attr_range;
- // FIXME: Do not rely on iterators having comparable singular values.
- // Note that this should error out if they do not.
+ attr_range attrs() const {
+ return attr_range(attr_begin(), attr_end());
+ }
+
attr_iterator attr_begin() const {
return hasAttrs() ? getAttrs().begin() : 0;
}
@@ -467,6 +458,12 @@
}
template <typename T>
+ llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
+ return llvm::iterator_range<specific_attr_iterator<T>>(
+ specific_attr_begin<T>(), specific_attr_end<T>());
+ }
+
+ template <typename T>
specific_attr_iterator<T> specific_attr_begin() const {
return specific_attr_iterator<T>(attr_begin());
}
@@ -769,10 +766,16 @@
}
};
- /// \brief Returns iterator for all the redeclarations of the same decl.
- /// It will iterate at least once (when this decl is the only one).
+ typedef llvm::iterator_range<redecl_iterator> redecl_range;
+
+ /// \brief Returns an iterator range for all the redeclarations of the same
+ /// decl. It will iterate at least once (when this decl is the only one).
+ redecl_range redecls() const {
+ return redecl_range(redecls_begin(), redecls_end());
+ }
+
redecl_iterator redecls_begin() const {
- return redecl_iterator(const_cast<Decl*>(this));
+ return redecl_iterator(const_cast<Decl *>(this));
}
redecl_iterator redecls_end() const { return redecl_iterator(); }
@@ -836,7 +839,19 @@
bool isTemplateDecl() const;
/// \brief Whether this declaration is a function or function template.
- bool isFunctionOrFunctionTemplate() const;
+ bool isFunctionOrFunctionTemplate() const {
+ return (DeclKind >= Decl::firstFunction &&
+ DeclKind <= Decl::lastFunction) ||
+ DeclKind == FunctionTemplate;
+ }
+
+ /// \brief Returns the function itself, or the templated function if this is a
+ /// function template.
+ FunctionDecl *getAsFunction() LLVM_READONLY;
+
+ const FunctionDecl *getAsFunction() const {
+ return const_cast<Decl *>(this)->getAsFunction();
+ }
/// \brief Changes the namespace of this declaration to reflect that it's
/// a function-local extern declaration.
@@ -938,11 +953,16 @@
raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0);
// Debuggers don't usually respect default arguments.
- LLVM_ATTRIBUTE_USED void dump() const;
+ void dump() const;
// Same as dump(), but forces color printing.
- LLVM_ATTRIBUTE_USED void dumpColor() const;
+ void dumpColor() const;
void dump(raw_ostream &Out) const;
+ /// \brief Looks through the Decl's underlying type to extract a FunctionType
+ /// when possible. Will return null if the type underlying the Decl does not
+ /// have a FunctionType.
+ const FunctionType *getFunctionType(bool BlocksToo = true) const;
+
private:
void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
@@ -975,7 +995,7 @@
SourceManager &sm, const char *Msg)
: TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
- virtual void print(raw_ostream &OS) const;
+ void print(raw_ostream &OS) const override;
};
typedef llvm::MutableArrayRef<NamedDecl*> DeclContextLookupResult;
@@ -1282,8 +1302,11 @@
}
};
+ typedef llvm::iterator_range<decl_iterator> decl_range;
+
/// decls_begin/decls_end - Iterate over the declarations stored in
/// this context.
+ decl_range decls() const { return decl_range(decls_begin(), decls_end()); }
decl_iterator decls_begin() const;
decl_iterator decls_end() const { return decl_iterator(); }
bool decls_empty() const;
@@ -1291,7 +1314,10 @@
/// noload_decls_begin/end - Iterate over the declarations stored in this
/// context that are currently loaded; don't attempt to retrieve anything
/// from an external source.
- decl_iterator noload_decls_begin() const;
+ decl_range noload_decls() const {
+ return decl_range(noload_decls_begin(), noload_decls_end());
+ }
+ decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
decl_iterator noload_decls_end() const { return decl_iterator(); }
/// specific_decl_iterator - Iterates over a subrange of
@@ -1537,6 +1563,11 @@
/// of looking up every possible name.
class all_lookups_iterator;
+ typedef llvm::iterator_range<all_lookups_iterator> lookups_range;
+
+ lookups_range lookups() const;
+ lookups_range noload_lookups() const;
+
/// \brief Iterators over all possible lookups within this context.
all_lookups_iterator lookups_begin() const;
all_lookups_iterator lookups_end() const;
@@ -1547,26 +1578,15 @@
all_lookups_iterator noload_lookups_begin() const;
all_lookups_iterator noload_lookups_end() const;
- /// udir_iterator - Iterates through the using-directives stored
- /// within this context.
- typedef UsingDirectiveDecl * const * udir_iterator;
+ typedef llvm::iterator_range<UsingDirectiveDecl * const *> udir_range;
- typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
-
- udir_iterator_range getUsingDirectives() const;
-
- udir_iterator using_directives_begin() const {
- return getUsingDirectives().first;
- }
-
- udir_iterator using_directives_end() const {
- return getUsingDirectives().second;
- }
+ udir_range using_directives() const;
// These are all defined in DependentDiagnostic.h.
class ddiag_iterator;
- inline ddiag_iterator ddiag_begin() const;
- inline ddiag_iterator ddiag_end() const;
+ typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range;
+
+ inline ddiag_range ddiags() const;
// Low-level accessors
@@ -1616,12 +1636,12 @@
static bool classof(const Decl *D);
static bool classof(const DeclContext *D) { return true; }
- LLVM_ATTRIBUTE_USED void dumpDeclContext() const;
- LLVM_ATTRIBUTE_USED void dumpLookups() const;
- LLVM_ATTRIBUTE_USED void dumpLookups(llvm::raw_ostream &OS) const;
+ void dumpDeclContext() const;
+ void dumpLookups() const;
+ void dumpLookups(llvm::raw_ostream &OS) const;
private:
- void reconcileExternalVisibleStorage();
+ void reconcileExternalVisibleStorage() const;
void LoadLexicalDeclsFromExternalStorage() const;
/// @brief Makes a declaration visible within this context, but
@@ -1650,7 +1670,7 @@
// Specialization selected when ToTy is not a known subclass of DeclContext.
template <class ToTy,
- bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
+ bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value>
struct cast_convert_decl_context {
static const ToTy *doit(const DeclContext *Val) {
return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index dbc4132..f64ef8b 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -17,6 +17,7 @@
#define LLVM_CLANG_AST_DECLCXX_H
#include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -122,14 +123,14 @@
/// \brief Sets the location of the colon.
void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getAccessSpecifierLoc(), getColonLoc());
}
static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
DeclContext *DC, SourceLocation ASLoc,
SourceLocation ColonLoc) {
- return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
+ return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
}
static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -258,16 +259,6 @@
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
-/// The inheritance model to use for member pointers of a given CXXRecordDecl.
-enum MSInheritanceModel {
- MSIM_Single,
- MSIM_SinglePolymorphic,
- MSIM_Multiple,
- MSIM_MultiplePolymorphic,
- MSIM_Virtual,
- MSIM_Unspecified
-};
-
/// \brief Represents a C++ struct/union/class.
///
/// FIXME: This class will disappear once we've properly taught RecordDecl
@@ -350,10 +341,15 @@
/// \brief True if this class (or any subobject) has mutable fields.
bool HasMutableFields : 1;
+ /// \brief True if this class (or any nested anonymous struct or union)
+ /// has variant members.
+ bool HasVariantMembers : 1;
+
/// \brief True if there no non-field members declared by the user.
bool HasOnlyCMembers : 1;
- /// \brief True if any field has an in-class initializer.
+ /// \brief True if any field has an in-class initializer, including those
+ /// within anonymous unions or structs.
bool HasInClassInitializer : 1;
/// \brief True if any field is of reference type, and does not have an
@@ -621,17 +617,7 @@
/// \brief Iterator that traverses the base classes of a class.
typedef const CXXBaseSpecifier* base_class_const_iterator;
- /// \brief Iterator that traverses the base classes of a class in reverse
- /// order.
- typedef std::reverse_iterator<base_class_iterator>
- reverse_base_class_iterator;
-
- /// \brief Iterator that traverses the base classes of a class in reverse
- /// order.
- typedef std::reverse_iterator<base_class_const_iterator>
- reverse_base_class_const_iterator;
-
- virtual CXXRecordDecl *getCanonicalDecl() {
+ CXXRecordDecl *getCanonicalDecl() override {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
virtual const CXXRecordDecl *getCanonicalDecl() const {
@@ -682,46 +668,40 @@
/// \brief Retrieves the number of base classes of this class.
unsigned getNumBases() const { return data().NumBases; }
+ typedef llvm::iterator_range<base_class_iterator> base_class_range;
+ typedef llvm::iterator_range<base_class_const_iterator>
+ base_class_const_range;
+
+ base_class_range bases() {
+ return base_class_range(bases_begin(), bases_end());
+ }
+ base_class_const_range bases() const {
+ return base_class_const_range(bases_begin(), bases_end());
+ }
+
base_class_iterator bases_begin() { return data().getBases(); }
base_class_const_iterator bases_begin() const { return data().getBases(); }
base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
base_class_const_iterator bases_end() const {
return bases_begin() + data().NumBases;
}
- reverse_base_class_iterator bases_rbegin() {
- return reverse_base_class_iterator(bases_end());
- }
- reverse_base_class_const_iterator bases_rbegin() const {
- return reverse_base_class_const_iterator(bases_end());
- }
- reverse_base_class_iterator bases_rend() {
- return reverse_base_class_iterator(bases_begin());
- }
- reverse_base_class_const_iterator bases_rend() const {
- return reverse_base_class_const_iterator(bases_begin());
- }
/// \brief Retrieves the number of virtual base classes of this class.
unsigned getNumVBases() const { return data().NumVBases; }
+ base_class_range vbases() {
+ return base_class_range(vbases_begin(), vbases_end());
+ }
+ base_class_const_range vbases() const {
+ return base_class_const_range(vbases_begin(), vbases_end());
+ }
+
base_class_iterator vbases_begin() { return data().getVBases(); }
base_class_const_iterator vbases_begin() const { return data().getVBases(); }
base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
base_class_const_iterator vbases_end() const {
return vbases_begin() + data().NumVBases;
}
- reverse_base_class_iterator vbases_rbegin() {
- return reverse_base_class_iterator(vbases_end());
- }
- reverse_base_class_const_iterator vbases_rbegin() const {
- return reverse_base_class_const_iterator(vbases_end());
- }
- reverse_base_class_iterator vbases_rend() {
- return reverse_base_class_iterator(vbases_begin());
- }
- reverse_base_class_const_iterator vbases_rend() const {
- return reverse_base_class_const_iterator(vbases_begin());
- }
/// \brief Determine whether this class has any dependent base classes which
/// are not the current instantiation.
@@ -731,6 +711,12 @@
/// all method members of the class, including non-instance methods,
/// special methods, etc.
typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>
+ method_range;
+
+ method_range methods() const {
+ return method_range(method_begin(), method_end());
+ }
/// \brief Method begin iterator. Iterates in the order the methods
/// were declared.
@@ -744,6 +730,10 @@
/// Iterator access to constructor members.
typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
+ ctor_range;
+
+ ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); }
ctor_iterator ctor_begin() const {
return ctor_iterator(decls_begin());
@@ -755,6 +745,9 @@
/// An iterator over friend declarations. All of these are defined
/// in DeclFriend.h.
class friend_iterator;
+ typedef llvm::iterator_range<friend_iterator> friend_range;
+
+ friend_range friends() const;
friend_iterator friend_begin() const;
friend_iterator friend_end() const;
void pushFriendDecl(FriendDecl *FD);
@@ -1026,6 +1019,11 @@
FieldDecl *&ThisCapture) const;
typedef const LambdaExpr::Capture* 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;
}
@@ -1058,7 +1056,8 @@
bool isAggregate() const { return data().Aggregate; }
/// \brief Whether this class has any in-class initializers
- /// for non-static data members.
+ /// for non-static data members (including those in anonymous unions or
+ /// structs).
bool hasInClassInitializer() const { return data().HasInClassInitializer; }
/// \brief Whether this class or any of its subobjects has any members of
@@ -1117,6 +1116,9 @@
/// contains a mutable field.
bool hasMutableFields() const { return data().HasMutableFields; }
+ /// \brief Determine whether this class has any variant members.
+ bool hasVariantMembers() const { return data().HasVariantMembers; }
+
/// \brief Determine whether this class has a trivial default constructor
/// (C++11 [class.ctor]p5).
bool hasTrivialDefaultConstructor() const {
@@ -1144,7 +1146,7 @@
/// would be constexpr.
bool defaultedDefaultConstructorIsConstexpr() const {
return data().DefaultedDefaultConstructorIsConstexpr &&
- (!isUnion() || hasInClassInitializer());
+ (!isUnion() || hasInClassInitializer() || !hasVariantMembers());
}
/// \brief Determine whether this class has a constexpr default constructor.
@@ -1546,7 +1548,7 @@
void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
/// \brief Indicates that the definition of this class is now complete.
- virtual void completeDefinition();
+ void completeDefinition() override;
/// \brief Indicates that the definition of this class is now complete,
/// and provides a final overrider map to help determine
@@ -1599,7 +1601,25 @@
}
/// \brief Returns the inheritance model used for this record.
- MSInheritanceModel getMSInheritanceModel() const;
+ MSInheritanceAttr::Spelling getMSInheritanceModel() const;
+ /// \brief Calculate what the inheritance model would be for this class.
+ MSInheritanceAttr::Spelling calculateInheritanceModel() const;
+
+ /// In the Microsoft C++ ABI, use zero for the field offset of a null data
+ /// member pointer if we can guarantee that zero is not a valid field offset,
+ /// or if the member pointer has multiple fields. Polymorphic classes have a
+ /// vfptr at offset zero, so we can use zero for null. If there are multiple
+ /// fields, we can use zero even if it is a valid field offset because
+ /// null-ness testing will check the other fields.
+ bool nullFieldOffsetIsZero() const {
+ return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false,
+ getMSInheritanceModel()) ||
+ (hasDefinition() && isPolymorphic());
+ }
+
+ /// \brief Controls when vtordisps will be emitted if this record is used as a
+ /// virtual base.
+ MSVtorDispAttr::Mode getMSVtorDispMode() const;
/// \brief Determine whether this lambda expression was known to be dependent
/// at the time it was created, even if its context does not appear to be
@@ -1636,7 +1656,7 @@
/// In the terminology of the C++ Standard, these are the (static and
/// non-static) member functions, whether virtual or not.
class CXXMethodDecl : public FunctionDecl {
- virtual void anchor();
+ void anchor() override;
protected:
CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
@@ -1683,9 +1703,9 @@
CXXMethodDecl *CD =
cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
- // Methods declared in interfaces are automatically (pure) virtual.
- if (CD->isVirtualAsWritten() ||
- (CD->getParent()->isInterface() && CD->isUserProvided()))
+ // Member function is virtual if it is marked explicitly so, or if it is
+ // declared in __interface -- then it is automatically pure virtual.
+ if (CD->isVirtualAsWritten() || CD->isPure())
return true;
return (CD->begin_overridden_methods() != CD->end_overridden_methods());
@@ -1703,10 +1723,10 @@
/// \brief Determine whether this is a move assignment operator.
bool isMoveAssignmentOperator() const;
- CXXMethodDecl *getCanonicalDecl() {
+ CXXMethodDecl *getCanonicalDecl() override {
return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
}
- const CXXMethodDecl *getCanonicalDecl() const {
+ const CXXMethodDecl *getCanonicalDecl() const override {
return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
}
@@ -2066,7 +2086,7 @@
/// };
/// \endcode
class CXXConstructorDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief Whether this constructor declaration has the \c explicit keyword
/// specified.
bool IsExplicitSpecified : 1;
@@ -2115,6 +2135,14 @@
/// \brief Iterates through the member/base initializer list.
typedef CXXCtorInitializer * const * init_const_iterator;
+ typedef llvm::iterator_range<init_iterator> init_range;
+ typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+ init_range inits() { return init_range(init_begin(), init_end()); }
+ init_const_range inits() const {
+ return init_const_range(init_begin(), init_end());
+ }
+
/// \brief Retrieve an iterator to the first initializer.
init_iterator init_begin() { return CtorInitializers; }
/// \brief Retrieve an iterator to the first initializer.
@@ -2240,10 +2268,10 @@
/// \brief Set the constructor that this inheriting constructor is based on.
void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
- const CXXConstructorDecl *getCanonicalDecl() const {
+ const CXXConstructorDecl *getCanonicalDecl() const override {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
- CXXConstructorDecl *getCanonicalDecl() {
+ CXXConstructorDecl *getCanonicalDecl() override {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
@@ -2266,7 +2294,7 @@
/// };
/// \endcode
class CXXDestructorDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
FunctionDecl *OperatorDelete;
@@ -2289,8 +2317,12 @@
bool isImplicitlyDeclared);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
- void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
- const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+ void setOperatorDelete(FunctionDecl *OD) {
+ cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete = OD;
+ }
+ const FunctionDecl *getOperatorDelete() const {
+ return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2311,7 +2343,7 @@
/// };
/// \endcode
class CXXConversionDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
/// Whether this conversion function declaration is marked
/// "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++0x feature.
@@ -2351,7 +2383,7 @@
/// \brief Returns the type that this conversion function is converting to.
QualType getConversionType() const {
- return getType()->getAs<FunctionType>()->getResultType();
+ return getType()->getAs<FunctionType>()->getReturnType();
}
/// \brief Determine whether this conversion function is a conversion from
@@ -2440,7 +2472,7 @@
return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
}
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(ExternLoc, getLocEnd());
}
@@ -2465,7 +2497,7 @@
/// artificial names for all using-directives in order to store
/// them in DeclContext effectively.
class UsingDirectiveDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The location of the \c using keyword.
SourceLocation UsingLoc;
@@ -2546,8 +2578,8 @@
NamedDecl *Nominated,
DeclContext *CommonAncestor);
static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const LLVM_READONLY {
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(UsingLoc, getLocation());
}
@@ -2568,7 +2600,7 @@
/// namespace Foo = Bar;
/// \endcode
class NamespaceAliasDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The location of the \c namespace keyword.
SourceLocation NamespaceLoc;
@@ -2641,8 +2673,8 @@
NamedDecl *Namespace);
static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(NamespaceLoc, IdentLoc);
}
@@ -2664,7 +2696,7 @@
/// }
/// \endcode
class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
- virtual void anchor();
+ void anchor() override;
/// The referenced declaration.
NamedDecl *Underlying;
@@ -2687,13 +2719,13 @@
}
typedef Redeclarable<UsingShadowDecl> redeclarable_base;
- virtual UsingShadowDecl *getNextRedeclaration() {
+ UsingShadowDecl *getNextRedeclaration() override {
return RedeclLink.getNext();
}
- virtual UsingShadowDecl *getPreviousDeclImpl() {
+ UsingShadowDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual UsingShadowDecl *getMostRecentDeclImpl() {
+ UsingShadowDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -2701,21 +2733,23 @@
static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target) {
- return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+ return new (C, DC) UsingShadowDecl(DC, Loc, Using, Target);
}
static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
+ typedef redeclarable_base::redecl_range redecl_range;
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
- virtual UsingShadowDecl *getCanonicalDecl() {
+ UsingShadowDecl *getCanonicalDecl() override {
return getFirstDecl();
}
- virtual const UsingShadowDecl *getCanonicalDecl() const {
+ const UsingShadowDecl *getCanonicalDecl() const {
return getFirstDecl();
}
@@ -2754,7 +2788,7 @@
/// using someNameSpace::someIdentifier;
/// \endcode
class UsingDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'using' keyword itself.
SourceLocation UsingLocation;
@@ -2848,6 +2882,11 @@
}
};
+ typedef llvm::iterator_range<shadow_iterator> shadow_range;
+
+ shadow_range shadows() const {
+ return shadow_range(shadow_begin(), shadow_end());
+ }
shadow_iterator shadow_begin() const {
return shadow_iterator(FirstUsingShadow.getPointer());
}
@@ -2870,7 +2909,7 @@
static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Using; }
@@ -2891,7 +2930,7 @@
/// };
/// \endcode
class UnresolvedUsingValueDecl : public ValueDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'using' keyword
SourceLocation UsingLocation;
@@ -2944,7 +2983,7 @@
static UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
@@ -2965,7 +3004,7 @@
/// The type associated with an unresolved using typename decl is
/// currently always a typename type.
class UnresolvedUsingTypenameDecl : public TypeDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'typename' keyword
SourceLocation TypenameLocation;
@@ -3043,7 +3082,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getLocation(), getRParenLoc());
}
@@ -3083,14 +3122,17 @@
class MSPropertyDecl : public DeclaratorDecl {
IdentifierInfo *GetterId, *SetterId;
-public:
- MSPropertyDecl(DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- SourceLocation StartL, IdentifierInfo *Getter,
- IdentifierInfo *Setter):
- DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterId(Getter),
- SetterId(Setter) {}
+ MSPropertyDecl(DeclContext *DC, SourceLocation L, DeclarationName N,
+ QualType T, TypeSourceInfo *TInfo, SourceLocation StartL,
+ IdentifierInfo *Getter, IdentifierInfo *Setter)
+ : DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
+ GetterId(Getter), SetterId(Setter) {}
+public:
+ static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName N, QualType T,
+ TypeSourceInfo *TInfo, SourceLocation StartL,
+ IdentifierInfo *Getter, IdentifierInfo *Setter);
static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 9c626c8..f85cea5 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -46,10 +46,8 @@
public:
StoredDeclsList() {}
- StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
- if (DeclsTy *RHSVec = RHS.getAsVector())
- Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec),
- RHS.hasExternalDecls());
+ StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
+ RHS.Data = (NamedDecl *)0;
}
~StoredDeclsList() {
@@ -58,12 +56,11 @@
delete Vector;
}
- StoredDeclsList &operator=(const StoredDeclsList &RHS) {
+ StoredDeclsList &operator=(StoredDeclsList &&RHS) {
if (DeclsTy *Vector = getAsVector())
delete Vector;
Data = RHS.Data;
- if (DeclsTy *RHSVec = RHS.getAsVector())
- Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec), hasExternalDecls());
+ RHS.Data = (NamedDecl *)0;
return *this;
}
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index be6f2eb..bb852d0 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -132,7 +132,7 @@
}
/// Retrieves the source range for the friend declaration.
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
if (NamedDecl *ND = getFriendDecl()) {
if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
return FTD->getSourceRange();
@@ -227,6 +227,10 @@
return friend_iterator(0);
}
+inline CXXRecordDecl::friend_range CXXRecordDecl::friends() const {
+ return friend_range(friend_begin(), friend_end());
+}
+
inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
assert(!FD->NextFriend && "friend already has next friend?");
FD->NextFriend = data().FirstFriend;
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index c16975a..d2016af 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -68,38 +68,40 @@
}
};
-inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
+inline DeclContext::lookups_range DeclContext::lookups() const {
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
if (Primary->hasExternalVisibleStorage())
getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
if (StoredDeclsMap *Map = Primary->buildLookup())
- return all_lookups_iterator(Map->begin(), Map->end());
- return all_lookups_iterator();
+ return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
+ all_lookups_iterator(Map->end(), Map->end()));
+ return lookups_range();
+}
+
+inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
+ return lookups().begin();
}
inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
+ return lookups().end();
+}
+
+inline DeclContext::lookups_range DeclContext::noload_lookups() const {
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (Primary->hasExternalVisibleStorage())
- getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
- if (StoredDeclsMap *Map = Primary->buildLookup())
- return all_lookups_iterator(Map->end(), Map->end());
- return all_lookups_iterator();
+ if (StoredDeclsMap *Map = Primary->getLookupPtr())
+ return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
+ all_lookups_iterator(Map->end(), Map->end()));
+ return lookups_range();
}
inline
DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
- DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (StoredDeclsMap *Map = Primary->getLookupPtr())
- return all_lookups_iterator(Map->begin(), Map->end());
- return all_lookups_iterator();
+ return noload_lookups().begin();
}
inline
DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
- DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (StoredDeclsMap *Map = Primary->getLookupPtr())
- return all_lookups_iterator(Map->end(), Map->end());
- return all_lookups_iterator();
+ return noload_lookups().end();
}
} // end namespace clang
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 2e760d6..cdd7d26 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -162,11 +162,11 @@
/// \brief Indicates if the method was a definition but its body was skipped.
unsigned HasSkippedBody : 1;
- // Result type of this method.
+ // Return type of this method.
QualType MethodDeclType;
- // Type source information for the result type.
- TypeSourceInfo *ResultTInfo;
+ // Type source information for the return type.
+ TypeSourceInfo *ReturnTInfo;
/// \brief Array of ParmVarDecls for the formal parameters of this method
/// and optionally followed by selector locations.
@@ -224,54 +224,43 @@
ArrayRef<SourceLocation> SelLocs);
ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T,
- TypeSourceInfo *ResultTInfo,
- DeclContext *contextDecl,
- bool isInstance = true,
- bool isVariadic = false,
- bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false,
- bool isDefined = false,
+ Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+ DeclContext *contextDecl, bool isInstance = true,
+ bool isVariadic = false, bool isPropertyAccessor = false,
+ bool isImplicitlyDeclared = false, bool isDefined = false,
ImplementationControl impControl = None,
bool HasRelatedResultType = false)
- : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
- DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
- IsInstance(isInstance), IsVariadic(isVariadic),
- IsPropertyAccessor(isPropertyAccessor),
- IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0),
- DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
- RelatedResultType(HasRelatedResultType),
- SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
- MethodDeclType(T), ResultTInfo(ResultTInfo),
- ParamsAndSelLocs(0), NumParams(0),
- DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
+ : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
+ DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
+ IsInstance(isInstance), IsVariadic(isVariadic),
+ IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
+ IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
+ 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) {
setImplicit(isImplicitlyDeclared);
}
/// \brief A definition will return its interface declaration.
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
- virtual ObjCMethodDecl *getNextRedeclaration();
+ ObjCMethodDecl *getNextRedeclaration() override;
public:
- static ObjCMethodDecl *Create(ASTContext &C,
- SourceLocation beginLoc,
- SourceLocation endLoc,
- Selector SelInfo,
- QualType T,
- TypeSourceInfo *ResultTInfo,
- DeclContext *contextDecl,
- bool isInstance = true,
- bool isVariadic = false,
- bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false,
- bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false);
+ static ObjCMethodDecl *
+ Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
+ Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+ DeclContext *contextDecl, bool isInstance = true,
+ bool isVariadic = false, bool isPropertyAccessor = false,
+ bool isImplicitlyDeclared = false, bool isDefined = false,
+ ImplementationControl impControl = None,
+ bool HasRelatedResultType = false);
static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual ObjCMethodDecl *getCanonicalDecl();
+
+ ObjCMethodDecl *getCanonicalDecl() override;
const ObjCMethodDecl *getCanonicalDecl() const {
return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
}
@@ -300,7 +289,7 @@
// Location information, modeled after the Stmt API.
SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
SourceLocation getLocEnd() const LLVM_READONLY;
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getLocation(), getLocEnd());
}
@@ -314,8 +303,7 @@
if (hasStandardSelLocs())
return getStandardSelectorLoc(Index, getSelector(),
getSelLocsKind() == SelLoc_StandardWithSpace,
- llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
- NumParams),
+ parameters(),
DeclEndLoc);
return getStoredSelLocs()[Index];
}
@@ -338,32 +326,52 @@
Selector getSelector() const { return getDeclName().getObjCSelector(); }
- QualType getResultType() const { return MethodDeclType; }
- void setResultType(QualType T) { MethodDeclType = T; }
+ QualType getReturnType() const { return MethodDeclType; }
+ void setReturnType(QualType T) { MethodDeclType = T; }
/// \brief Determine the type of an expression that sends a message to this
/// function.
QualType getSendResultType() const {
- return getResultType().getNonLValueExprType(getASTContext());
+ return getReturnType().getNonLValueExprType(getASTContext());
}
- TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
- void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
+ TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
+ void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
// Iterator access to formal parameters.
unsigned param_size() const { return NumParams; }
typedef const ParmVarDecl *const *param_const_iterator;
typedef ParmVarDecl *const *param_iterator;
- param_const_iterator param_begin() const { return getParams(); }
- param_const_iterator param_end() const { return getParams() + NumParams; }
- param_iterator param_begin() { return getParams(); }
- param_iterator param_end() { return getParams() + NumParams; }
+ typedef llvm::iterator_range<param_iterator> param_range;
+ typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+ param_range params() { return param_range(param_begin(), param_end()); }
+ param_const_range params() const {
+ return param_const_range(param_begin(), param_end());
+ }
+
+ param_const_iterator param_begin() const {
+ return param_const_iterator(getParams());
+ }
+ param_const_iterator param_end() const {
+ return param_const_iterator(getParams() + NumParams);
+ }
+ param_iterator param_begin() { return param_iterator(getParams()); }
+ param_iterator param_end() { return param_iterator(getParams() + NumParams); }
+
// This method returns and of the parameters which are part of the selector
// name mangling requirements.
param_const_iterator sel_param_end() const {
return param_begin() + getSelector().getNumArgs();
}
+ // ArrayRef access to formal parameters. This should eventually
+ // replace the iterator interface above.
+ ArrayRef<ParmVarDecl*> parameters() const {
+ return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
+ NumParams);
+ }
+
/// \brief Sets the method's parameters and selector source locations.
/// If the method is implicit (not coming from source) \p SelLocs is
/// ignored.
@@ -375,12 +383,12 @@
// Iterator access to parameter types.
typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
- arg_type_iterator;
+ param_type_iterator;
- arg_type_iterator arg_type_begin() const {
+ param_type_iterator param_type_begin() const {
return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
}
- arg_type_iterator arg_type_end() const {
+ param_type_iterator param_type_end() const {
return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
}
@@ -451,11 +459,24 @@
return ImplementationControl(DeclImplementation);
}
+ /// Returns true if this specific method declaration is marked with the
+ /// designated initializer attribute.
+ bool isThisDeclarationADesignatedInitializer() const;
+
+ /// Returns true if the method selector resolves to a designated initializer
+ /// in the class's interface.
+ ///
+ /// \param InitMethod if non-null and the function returns true, it receives
+ /// the method declaration that was marked with the designated initializer
+ /// attribute.
+ bool isDesignatedInitializerForTheInterface(
+ const ObjCMethodDecl **InitMethod = 0) const;
+
/// \brief Determine whether this method has a body.
- virtual bool hasBody() const { return Body.isValid(); }
+ bool hasBody() const override { return Body.isValid(); }
/// \brief Retrieve the body of this method, if it has one.
- virtual Stmt *getBody() const;
+ Stmt *getBody() const override;
void setLazyBody(uint64_t Offset) { Body = Offset; }
@@ -484,7 +505,7 @@
/// ObjCProtocolDecl, and ObjCImplDecl.
///
class ObjCContainerDecl : public NamedDecl, public DeclContext {
- virtual void anchor();
+ void anchor() override;
SourceLocation AtStart;
@@ -500,6 +521,10 @@
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
+ prop_range;
+
+ prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
prop_iterator prop_begin() const {
return prop_iterator(decls_begin());
}
@@ -509,6 +534,12 @@
// Iterator access to instance/class methods.
typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
+ method_range;
+
+ method_range methods() const {
+ return method_range(meth_begin(), meth_end());
+ }
method_iterator meth_begin() const {
return method_iterator(decls_begin());
}
@@ -519,6 +550,11 @@
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
+ typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
+
+ instmeth_range instance_methods() const {
+ return instmeth_range(instmeth_begin(), instmeth_end());
+ }
instmeth_iterator instmeth_begin() const {
return instmeth_iterator(decls_begin());
}
@@ -529,6 +565,11 @@
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isClassMethod>
classmeth_iterator;
+ typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
+
+ classmeth_range class_methods() const {
+ return classmeth_range(classmeth_begin(), classmeth_end());
+ }
classmeth_iterator classmeth_begin() const {
return classmeth_iterator(decls_begin());
}
@@ -575,7 +616,7 @@
AtEnd = atEnd;
}
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(AtStart, getAtEndRange().getEnd());
}
@@ -621,7 +662,7 @@
///
class ObjCInterfaceDecl : public ObjCContainerDecl
, public Redeclarable<ObjCInterfaceDecl> {
- virtual void anchor();
+ void anchor() override;
/// TypeForDecl - This indicates the Type object that represents this
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
@@ -661,6 +702,22 @@
/// declared in the implementation.
mutable bool IvarListMissingImplementation : 1;
+ /// Indicates that this interface decl contains at least one initializer
+ /// marked with the 'objc_designated_initializer' attribute.
+ bool HasDesignatedInitializers : 1;
+
+ enum InheritedDesignatedInitializersState {
+ /// We didn't calculate whether the designated initializers should be
+ /// inherited or not.
+ IDI_Unknown = 0,
+ /// Designated initializers are inherited for the super class.
+ IDI_Inherited = 1,
+ /// The class does not inherit designated initializers.
+ IDI_NotInherited = 2
+ };
+ /// One of the \c InheritedDesignatedInitializersState enumeratos.
+ mutable unsigned InheritedDesignatedInitializers : 2;
+
/// \brief The location of the superclass, if any.
SourceLocation SuperClassLoc;
@@ -671,7 +728,9 @@
DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
ExternallyCompleted(),
- IvarListMissingImplementation(true) { }
+ IvarListMissingImplementation(true),
+ HasDesignatedInitializers(),
+ InheritedDesignatedInitializers(IDI_Unknown) { }
};
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
@@ -696,13 +755,13 @@
void allocateDefinitionData();
typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
- virtual ObjCInterfaceDecl *getNextRedeclaration() {
+ ObjCInterfaceDecl *getNextRedeclaration() override {
return RedeclLink.getNext();
}
- virtual ObjCInterfaceDecl *getPreviousDeclImpl() {
+ ObjCInterfaceDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual ObjCInterfaceDecl *getMostRecentDeclImpl() {
+ ObjCInterfaceDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -716,7 +775,7 @@
static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
@@ -728,6 +787,20 @@
/// when a complete class is required.
void setExternallyCompleted();
+ /// Indicate that this interface decl contains at least one initializer
+ /// marked with the 'objc_designated_initializer' attribute.
+ void setHasDesignatedInitializers();
+
+ /// Returns true if this interface decl contains at least one initializer
+ /// marked with the 'objc_designated_initializer' attribute.
+ bool hasDesignatedInitializers() const;
+
+ /// Returns true if this interface decl declares a designated initializer
+ /// or it inherites one from its super class.
+ bool declaresOrInheritsDesignatedInitializers() const {
+ return hasDesignatedInitializers() || inheritsDesignatedInitializers();
+ }
+
const ObjCProtocolList &getReferencedProtocols() const {
assert(hasDefinition() && "Caller did not check for forward reference!");
if (data().ExternallyCompleted)
@@ -750,7 +823,11 @@
}
typedef ObjCProtocolList::iterator protocol_iterator;
+ typedef llvm::iterator_range<protocol_iterator> protocol_range;
+ protocol_range protocols() const {
+ return protocol_range(protocol_begin(), protocol_end());
+ }
protocol_iterator protocol_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -773,7 +850,11 @@
}
typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+ protocol_loc_range protocol_locs() const {
+ return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+ }
protocol_loc_iterator protocol_loc_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -797,7 +878,12 @@
}
typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
+ typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
+ all_protocol_range all_referenced_protocols() const {
+ return all_protocol_range(all_referenced_protocol_begin(),
+ all_referenced_protocol_end());
+ }
all_protocol_iterator all_referenced_protocol_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -824,7 +910,9 @@
}
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+ ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
ivar_iterator ivar_begin() const {
if (const ObjCInterfaceDecl *Def = getDefinition())
return ivar_iterator(Def->decls_begin());
@@ -867,6 +955,26 @@
unsigned Num,
ASTContext &C);
+ /// Returns the designated initializers for the interface.
+ ///
+ /// If this declaration does not have methods marked as designated
+ /// initializers then the interface inherits the designated initializers of
+ /// its super class.
+ void getDesignatedInitializers(
+ llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
+
+ /// Returns true if the given selector is a designated initializer for the
+ /// interface.
+ ///
+ /// If this declaration does not have methods marked as designated
+ /// initializers then the interface inherits the designated initializers of
+ /// its super class.
+ ///
+ /// \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;
+
/// \brief Determine whether this particular declaration of this class is
/// actually also a definition.
bool isThisDeclarationADefinition() const {
@@ -984,6 +1092,14 @@
typedef filtered_category_iterator<isVisibleCategory>
visible_categories_iterator;
+ typedef llvm::iterator_range<visible_categories_iterator>
+ visible_categories_range;
+
+ visible_categories_range visible_categories() const {
+ return visible_categories_range(visible_categories_begin(),
+ visible_categories_end());
+ }
+
/// \brief Retrieve an iterator to the beginning of the visible-categories
/// list.
visible_categories_iterator visible_categories_begin() const {
@@ -1010,6 +1126,13 @@
/// \brief Iterator that walks over all of the known categories and
/// extensions, including those that are hidden.
typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
+ typedef llvm::iterator_range<known_categories_iterator>
+ known_categories_range;
+
+ known_categories_range known_categories() const {
+ return known_categories_range(known_categories_begin(),
+ known_categories_end());
+ }
/// \brief Retrieve an iterator to the beginning of the known-categories
/// list.
@@ -1039,6 +1162,14 @@
typedef filtered_category_iterator<isVisibleExtension>
visible_extensions_iterator;
+ typedef llvm::iterator_range<visible_extensions_iterator>
+ visible_extensions_range;
+
+ visible_extensions_range visible_extensions() const {
+ return visible_extensions_range(visible_extensions_begin(),
+ visible_extensions_end());
+ }
+
/// \brief Retrieve an iterator to the beginning of the visible-extensions
/// list.
visible_extensions_iterator visible_extensions_begin() const {
@@ -1065,6 +1196,13 @@
/// \brief Iterator that walks over all of the known extensions.
typedef filtered_category_iterator<isKnownExtension>
known_extensions_iterator;
+ typedef llvm::iterator_range<known_extensions_iterator>
+ known_extensions_range;
+
+ known_extensions_range known_extensions() const {
+ return known_extensions_range(known_extensions_begin(),
+ known_extensions_end());
+ }
/// \brief Retrieve an iterator to the beginning of the known-extensions
/// list.
@@ -1104,8 +1242,8 @@
ObjCPropertyDecl
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const;
+ void collectPropertiesToImplement(PropertyMap &PM,
+ PropertyDeclOrder &PO) const override;
/// isSuperClassOf - Return true if this class is the specified class or is a
/// super class of the specified interface class.
@@ -1141,15 +1279,18 @@
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
- bool shallowCategoryLookup= false,
- const ObjCCategoryDecl *C= 0) const;
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
- bool shallowCategoryLookup = false) const {
- return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
+ bool shallowCategoryLookup = false,
+ bool followSuper = true,
+ const ObjCCategoryDecl *C = 0) const;
+
+ /// Lookup an instance method for a given selector.
+ ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
+ return lookupMethod(Sel, true/*isInstance*/);
}
- ObjCMethodDecl *lookupClassMethod(Selector Sel,
- bool shallowCategoryLookup = false) const {
- return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup);
+
+ /// Lookup a class method for a given selector.
+ ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
+ return lookupMethod(Sel, false/*isInstance*/);
}
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
@@ -1167,7 +1308,9 @@
ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
const ObjCCategoryDecl *Cat) const {
return lookupMethod(Sel, true/*isInstance*/,
- false/*shallowCategoryLookup*/, Cat);
+ false/*shallowCategoryLookup*/,
+ true /* followsSuper */,
+ Cat);
}
SourceLocation getEndOfDefinitionLoc() const {
@@ -1196,15 +1339,17 @@
bool lookupCategory,
bool RHSIsQualifiedID = false);
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
/// Retrieves the canonical declaration of this Objective-C class.
- ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDecl(); }
+ ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Low-level accessor
@@ -1217,6 +1362,10 @@
friend class ASTReader;
friend class ASTDeclReader;
friend class ASTDeclWriter;
+
+private:
+ const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
+ bool inheritsDesignatedInitializers() const;
};
/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
@@ -1235,7 +1384,7 @@
/// }
///
class ObjCIvarDecl : public FieldDecl {
- virtual void anchor();
+ void anchor() override;
public:
enum AccessControl {
@@ -1246,12 +1395,10 @@
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
- bool synthesized,
- bool backingIvarReferencedInAccessor)
+ bool synthesized)
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
/*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- NextIvar(0), DeclAccess(ac), Synthesized(synthesized),
- BackingIvarReferencedInAccessor(backingIvarReferencedInAccessor) {}
+ NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
@@ -1259,8 +1406,7 @@
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW = NULL,
- bool synthesized=false,
- bool backingIvarReferencedInAccessor=false);
+ bool synthesized=false);
static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1282,13 +1428,6 @@
return DeclAccess == None ? Protected : AccessControl(DeclAccess);
}
- void setBackingIvarReferencedInAccessor(bool val) {
- BackingIvarReferencedInAccessor = val;
- }
- bool getBackingIvarReferencedInAccessor() const {
- return BackingIvarReferencedInAccessor;
- }
-
void setSynthesize(bool synth) { Synthesized = synth; }
bool getSynthesize() const { return Synthesized; }
@@ -1303,13 +1442,12 @@
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
unsigned Synthesized : 1;
- unsigned BackingIvarReferencedInAccessor : 1;
};
/// \brief Represents a field declaration created by an \@defs(...).
class ObjCAtDefsFieldDecl : public FieldDecl {
- virtual void anchor();
+ void anchor() override;
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, Expr *BW)
@@ -1362,7 +1500,7 @@
///
class ObjCProtocolDecl : public ObjCContainerDecl,
public Redeclarable<ObjCProtocolDecl> {
- virtual void anchor();
+ void anchor() override;
struct DefinitionData {
// \brief The declaration that defines this protocol.
@@ -1391,13 +1529,13 @@
void allocateDefinitionData();
typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
- virtual ObjCProtocolDecl *getNextRedeclaration() {
+ ObjCProtocolDecl *getNextRedeclaration() override {
return RedeclLink.getNext();
}
- virtual ObjCProtocolDecl *getPreviousDeclImpl() {
+ ObjCProtocolDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual ObjCProtocolDecl *getMostRecentDeclImpl() {
+ ObjCProtocolDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -1415,6 +1553,11 @@
return data().ReferencedProtocols;
}
typedef ObjCProtocolList::iterator protocol_iterator;
+ typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+ protocol_range protocols() const {
+ return protocol_range(protocol_begin(), protocol_end());
+ }
protocol_iterator protocol_begin() const {
if (!hasDefinition())
return protocol_iterator();
@@ -1428,6 +1571,11 @@
return data().ReferencedProtocols.end();
}
typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+ protocol_loc_range protocol_locs() const {
+ return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+ }
protocol_loc_iterator protocol_loc_begin() const {
if (!hasDefinition())
return protocol_loc_iterator();
@@ -1503,29 +1651,31 @@
/// \brief Starts the definition of this Objective-C protocol.
void startDefinition();
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
return SourceRange(getAtStartLoc(), getLocation());
}
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
/// Retrieves the canonical declaration of this Objective-C protocol.
- ObjCProtocolDecl *getCanonicalDecl() { return getFirstDecl(); }
+ ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const;
-
-void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
- ProtocolPropertyMap &PM) const;
+ void collectPropertiesToImplement(PropertyMap &PM,
+ PropertyDeclOrder &PO) const override;
+
+ void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
+ ProtocolPropertyMap &PM) const;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
@@ -1553,7 +1703,7 @@
/// don't support this level of dynamism, which is both powerful and dangerous.
///
class ObjCCategoryDecl : public ObjCContainerDecl {
- virtual void anchor();
+ void anchor() override;
/// Interface belonging to this category
ObjCInterfaceDecl *ClassInterface;
@@ -1613,10 +1763,22 @@
}
typedef ObjCProtocolList::iterator protocol_iterator;
- protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+ typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+ protocol_range protocols() const {
+ return protocol_range(protocol_begin(), protocol_end());
+ }
+ protocol_iterator protocol_begin() const {
+ return ReferencedProtocols.begin();
+ }
protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
unsigned protocol_size() const { return ReferencedProtocols.size(); }
typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+ protocol_loc_range protocol_locs() const {
+ return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+ }
protocol_loc_iterator protocol_loc_begin() const {
return ReferencedProtocols.loc_begin();
}
@@ -1635,6 +1797,9 @@
bool IsClassExtension() const { return getIdentifier() == 0; }
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+ ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
ivar_iterator ivar_begin() const {
return ivar_iterator(decls_begin());
}
@@ -1664,7 +1829,7 @@
};
class ObjCImplDecl : public ObjCContainerDecl {
- virtual void anchor();
+ void anchor() override;
/// Class interface for this class/category implementation
ObjCInterfaceDecl *ClassInterface;
@@ -1701,6 +1866,12 @@
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
+ propimpl_range;
+
+ propimpl_range property_impls() const {
+ return propimpl_range(propimpl_begin(), propimpl_end());
+ }
propimpl_iterator propimpl_begin() const {
return propimpl_iterator(decls_begin());
}
@@ -1728,7 +1899,7 @@
///
/// ObjCCategoryImplDecl
class ObjCCategoryImplDecl : public ObjCImplDecl {
- virtual void anchor();
+ void anchor() override;
// Category name
IdentifierInfo *Id;
@@ -1808,7 +1979,7 @@
/// specified, they need to be *identical* to the interface.
///
class ObjCImplementationDecl : public ObjCImplDecl {
- virtual void anchor();
+ void anchor() override;
/// Implementation Class's super class.
ObjCInterfaceDecl *SuperClass;
SourceLocation SuperLoc;
@@ -1859,6 +2030,14 @@
/// init_const_iterator - Iterates through the ivar initializer list.
typedef CXXCtorInitializer * const * init_const_iterator;
+ typedef llvm::iterator_range<init_iterator> init_range;
+ typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+ init_range inits() { return init_range(init_begin(), init_end()); }
+ init_const_range inits() const {
+ return init_const_range(init_begin(), init_end());
+ }
+
/// init_begin() - Retrieve an iterator to the first initializer.
init_iterator init_begin() { return IvarInitializers; }
/// begin() - Retrieve an iterator to the first initializer.
@@ -1930,6 +2109,9 @@
SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+ ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
ivar_iterator ivar_begin() const {
return ivar_iterator(decls_begin());
}
@@ -1955,7 +2137,7 @@
/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
/// declared as \@compatibility_alias alias class.
class ObjCCompatibleAliasDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// Class that this is an alias of.
ObjCInterfaceDecl *AliasedClass;
@@ -1986,7 +2168,7 @@
/// \@property (assign, readwrite) int MyProperty;
/// \endcode
class ObjCPropertyDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
public:
enum PropertyAttributeKind {
OBJC_PR_noattr = 0x00,
@@ -2145,7 +2327,7 @@
return PropertyIvarDecl;
}
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(AtLoc, getLocation());
}
@@ -2215,8 +2397,8 @@
SourceLocation ivarLoc);
static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 42fe907..76282a3 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -64,9 +64,18 @@
typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+ typedef llvm::iterator_range<varlist_iterator> varlist_range;
+ typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
unsigned varlist_size() const { return NumVars; }
bool varlist_empty() const { return NumVars == 0; }
+
+ varlist_range varlists() {
+ return varlist_range(varlist_begin(), varlist_end());
+ }
+ varlist_const_range varlists() const {
+ return varlist_const_range(varlist_begin(), varlist_end());
+ }
varlist_iterator varlist_begin() { return getVars().begin(); }
varlist_iterator varlist_end() { return getVars().end(); }
varlist_const_iterator varlist_begin() const { return getVars().begin(); }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 24bd28a..d55582a 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -227,7 +227,7 @@
/// The TemplateDecl class stores the list of template parameters and a
/// reference to the templated scoped declaration: the underlying AST node.
class TemplateDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
protected:
// This is probably never used.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -261,7 +261,7 @@
return K >= firstTemplate && K <= lastTemplate;
}
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(TemplateParams->getTemplateLoc(),
TemplatedDecl->getSourceRange().getEnd());
}
@@ -530,13 +530,13 @@
public Redeclarable<RedeclarableTemplateDecl>
{
typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
- virtual RedeclarableTemplateDecl *getNextRedeclaration() {
+ RedeclarableTemplateDecl *getNextRedeclaration() override {
return RedeclLink.getNext();
}
- virtual RedeclarableTemplateDecl *getPreviousDeclImpl() {
+ RedeclarableTemplateDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() {
+ RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -631,7 +631,9 @@
template <class decl_type> friend class RedeclarableTemplate;
/// \brief Retrieves the canonical declaration of this template.
- RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); }
+ RedeclarableTemplateDecl *getCanonicalDecl() override {
+ return getFirstDecl();
+ }
const RedeclarableTemplateDecl *getCanonicalDecl() const {
return getFirstDecl();
}
@@ -710,9 +712,11 @@
getCommonPtr()->InstantiatedFromMember.setPointer(TD);
}
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -773,7 +777,7 @@
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
- CommonBase *newCommon(ASTContext &C) const;
+ CommonBase *newCommon(ASTContext &C) const override;
Common *getCommonPtr() const {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -813,7 +817,7 @@
FunctionDecl *findSpecialization(const TemplateArgument *Args,
unsigned NumArgs, void *&InsertPos);
- FunctionTemplateDecl *getCanonicalDecl() {
+ FunctionTemplateDecl *getCanonicalDecl() override {
return cast<FunctionTemplateDecl>(
RedeclarableTemplateDecl::getCanonicalDecl());
}
@@ -842,7 +846,11 @@
}
typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
+ typedef llvm::iterator_range<spec_iterator> spec_range;
+ spec_range specializations() const {
+ return spec_range(spec_begin(), spec_end());
+ }
spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
}
@@ -892,12 +900,9 @@
/// This class is inheritedly privately by different kinds of template
/// parameters and is not part of the Decl hierarchy. Just a facility.
class TemplateParmPosition {
-protected:
- // FIXME: This should probably never be called, but it's here as
- TemplateParmPosition()
- : Depth(0), Position(0)
- { /* llvm_unreachable("Cannot create positionless template parameter"); */ }
+ TemplateParmPosition() LLVM_DELETED_FUNCTION;
+protected:
TemplateParmPosition(unsigned D, unsigned P)
: Depth(D), Position(P)
{ }
@@ -1009,7 +1014,7 @@
/// \brief Returns whether this is a parameter pack.
bool isParameterPack() const;
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1086,7 +1091,7 @@
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// \brief Determine whether this template parameter has a default
/// argument.
@@ -1206,7 +1211,7 @@
class TemplateTemplateParmDecl : public TemplateDecl,
protected TemplateParmPosition
{
- virtual void anchor();
+ void anchor() override;
/// DefaultArgument - The default template argument, if any.
TemplateArgumentLoc DefaultArgument;
@@ -1347,7 +1352,7 @@
DefaultArgumentWasInherited = false;
}
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
SourceLocation End = getLocation();
if (hasDefaultArgument() && !defaultArgumentWasInherited())
End = getDefaultArgument().getSourceRange().getEnd();
@@ -1444,10 +1449,14 @@
static ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
- virtual void getNameForDiagnostic(raw_ostream &OS,
- const PrintingPolicy &Policy,
- bool Qualified) const;
+ void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+ bool Qualified) const override;
+ // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
+ // different "most recent" declaration from this function for the same
+ // declaration, because we don't override getMostRecentDeclImpl(). But
+ // it's not clear that we should override that, because the most recent
+ // declaration as a CXXRecordDecl sometimes is the injected-class-name.
ClassTemplateSpecializationDecl *getMostRecentDecl() {
CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
this)->getMostRecentDecl();
@@ -1516,17 +1525,11 @@
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *>
getInstantiatedFrom() const {
- if (getSpecializationKind() != TSK_ImplicitInstantiation &&
- getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
- getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
+ if (!isTemplateInstantiation(getSpecializationKind()))
return llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *>();
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<ClassTemplateDecl*>();
+ return getSpecializedTemplateOrPartial();
}
/// \brief Retrieve the class template or class template partial
@@ -1617,7 +1620,7 @@
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
@@ -1643,7 +1646,7 @@
class ClassTemplatePartialSpecializationDecl
: public ClassTemplateSpecializationDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The list of template parameters
TemplateParameterList* TemplateParams;
@@ -1840,7 +1843,7 @@
: RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
DeclarationName(), 0, 0) { }
- CommonBase *newCommon(ASTContext &C) const;
+ CommonBase *newCommon(ASTContext &C) const override;
Common *getCommonPtr() const {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -1879,7 +1882,7 @@
/// in. InsertPos must be obtained from findSpecialization.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
- ClassTemplateDecl *getCanonicalDecl() {
+ ClassTemplateDecl *getCanonicalDecl() override {
return cast<ClassTemplateDecl>(
RedeclarableTemplateDecl::getCanonicalDecl());
}
@@ -1970,6 +1973,11 @@
QualType getInjectedClassNameSpecialization();
typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
+ typedef llvm::iterator_range<spec_iterator> spec_range;
+
+ spec_range specializations() const {
+ return spec_range(spec_begin(), spec_end());
+ }
spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
@@ -1979,17 +1987,6 @@
return makeSpecIterator(getSpecializations(), true);
}
- typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
- partial_spec_iterator;
-
- partial_spec_iterator partial_spec_begin() {
- return makeSpecIterator(getPartialSpecializations(), false);
- }
-
- partial_spec_iterator partial_spec_end() {
- return makeSpecIterator(getPartialSpecializations(), true);
- }
-
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ClassTemplate; }
@@ -2109,7 +2106,7 @@
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
- CommonBase *newCommon(ASTContext &C) const;
+ CommonBase *newCommon(ASTContext &C) const override;
Common *getCommonPtr() {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -2122,7 +2119,7 @@
}
- TypeAliasTemplateDecl *getCanonicalDecl() {
+ TypeAliasTemplateDecl *getCanonicalDecl() override {
return cast<TypeAliasTemplateDecl>(
RedeclarableTemplateDecl::getCanonicalDecl());
}
@@ -2172,7 +2169,7 @@
/// \brief Declaration of a function specialization at template class scope.
///
-/// This is a non standard extension needed to support MSVC.
+/// This is a non-standard extension needed to support MSVC.
///
/// For example:
/// \code
@@ -2214,9 +2211,8 @@
CXXMethodDecl *FD,
bool HasExplicitTemplateArgs,
TemplateArgumentListInfo TemplateArgs) {
- return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD,
- HasExplicitTemplateArgs,
- TemplateArgs);
+ return new (C, DC) ClassScopeFunctionSpecializationDecl(
+ DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
}
static ClassScopeFunctionSpecializationDecl *
@@ -2316,9 +2312,8 @@
static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
unsigned ID);
- virtual void getNameForDiagnostic(raw_ostream &OS,
- const PrintingPolicy &Policy,
- bool Qualified) const;
+ void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+ bool Qualified) const override;
VarTemplateSpecializationDecl *getMostRecentDecl() {
VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
@@ -2510,7 +2505,7 @@
class VarTemplatePartialSpecializationDecl
: public VarTemplateSpecializationDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The list of template parameters
TemplateParameterList *TemplateParams;
@@ -2685,7 +2680,7 @@
: RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(),
DeclarationName(), 0, 0) {}
- CommonBase *newCommon(ASTContext &C) const;
+ CommonBase *newCommon(ASTContext &C) const override;
Common *getCommonPtr() const {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -2708,8 +2703,8 @@
/// \brief Create a variable template node.
static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl,
- VarTemplateDecl *PrevDecl);
+ TemplateParameterList *Params,
+ VarDecl *Decl);
/// \brief Create an empty variable template node.
static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2724,7 +2719,7 @@
/// in. InsertPos must be obtained from findSpecialization.
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
- VarTemplateDecl *getCanonicalDecl() {
+ VarTemplateDecl *getCanonicalDecl() override {
return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
}
const VarTemplateDecl *getCanonicalDecl() const {
@@ -2780,6 +2775,11 @@
VarTemplatePartialSpecializationDecl *D);
typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
+ typedef llvm::iterator_range<spec_iterator> spec_range;
+
+ spec_range specializations() const {
+ return spec_range(spec_begin(), spec_end());
+ }
spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
@@ -2789,17 +2789,6 @@
return makeSpecIterator(getSpecializations(), true);
}
- typedef SpecIterator<VarTemplatePartialSpecializationDecl>
- partial_spec_iterator;
-
- partial_spec_iterator partial_spec_begin() {
- return makeSpecIterator(getPartialSpecializations(), false);
- }
-
- partial_spec_iterator partial_spec_end() {
- return makeSpecIterator(getPartialSpecializations(), true);
- }
-
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == VarTemplate; }
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 004b45d..0c783d2 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -171,18 +171,16 @@
DependentDiagnostic *Ptr;
};
-inline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const {
+inline DeclContext::ddiag_range DeclContext::ddiags() const {
assert(isDependentContext()
&& "cannot iterate dependent diagnostics of non-dependent context");
const DependentStoredDeclsMap *Map
= static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
- if (!Map) return ddiag_iterator();
- return ddiag_iterator(Map->FirstDiagnostic);
-}
+ if (!Map)
+ return ddiag_range();
-inline DeclContext::ddiag_iterator DeclContext::ddiag_end() const {
- return ddiag_iterator();
+ return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
}
}
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index f2648b9..adc8308 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -508,6 +508,16 @@
SmallVectorImpl<
PartialDiagnosticAt> &Diags);
+ /// isPotentialConstantExprUnevaluted - Return true if this expression might
+ /// be usable in a constant expression in C++11 in an unevaluated context, if
+ /// it were in function FD marked constexpr. Return false if the function can
+ /// never produce a constant expression, along with diagnostics describing
+ /// why not.
+ static bool isPotentialConstantExprUnevaluated(Expr *E,
+ const FunctionDecl *FD,
+ SmallVectorImpl<
+ PartialDiagnosticAt> &Diags);
+
/// 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;
@@ -600,6 +610,14 @@
const VarDecl *VD,
SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+ /// EvaluateWithSubstitution - Evaluate an expression as if from the context
+ /// of a call to the given function with the given arguments, inside an
+ /// unevaluated context. Returns true if the expression could be folded to a
+ /// constant.
+ bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
+ const FunctionDecl *Callee,
+ llvm::ArrayRef<const Expr*> Args) const;
+
/// \brief Enumeration used to describe the kind of Null pointer constant
/// returned from \c isNullPointerConstant().
enum NullPointerConstantKind {
@@ -764,11 +782,6 @@
SmallVectorImpl<const Expr *> &CommaLHS,
SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
- /// Skip irrelevant expressions to find what should be materialize for
- /// binding with a reference.
- const Expr *
- findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const;
-
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
T->getStmtClass() <= lastExprConstant;
@@ -2238,9 +2251,9 @@
/// this function call.
unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
- /// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
- /// not, return 0.
- unsigned isBuiltinCall() const;
+ /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
+ /// of the callee. If not, return 0.
+ unsigned getBuiltinCallee() const;
/// \brief Returns \c true if this is a call to a builtin which does not
/// evaluate side-effects within its arguments.
@@ -2633,7 +2646,7 @@
private:
Stmt *Op;
- void CheckCastConsistency() const;
+ bool CastConsistency() const;
const CXXBaseSpecifier * const *path_buffer() const {
return const_cast<CastExpr*>(this)->path_buffer();
@@ -2664,9 +2677,7 @@
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
setBasePathSize(BasePathSize);
-#ifndef NDEBUG
- CheckCastConsistency();
-#endif
+ assert(CastConsistency());
}
/// \brief Construct an empty cast.
@@ -3774,6 +3785,14 @@
void setInit(unsigned Init, Expr *expr) {
assert(Init < getNumInits() && "Initializer access out of range!");
InitExprs[Init] = expr;
+
+ if (expr) {
+ ExprBits.TypeDependent |= expr->isTypeDependent();
+ ExprBits.ValueDependent |= expr->isValueDependent();
+ ExprBits.InstantiationDependent |= expr->isInstantiationDependent();
+ ExprBits.ContainsUnexpandedParameterPack |=
+ expr->containsUnexpandedParameterPack();
+ }
}
/// \brief Reserve space for some number of initializers.
@@ -4186,18 +4205,14 @@
/// and array-range designators.
unsigned getNumSubExprs() const { return NumSubExprs; }
- Expr *getSubExpr(unsigned Idx) {
+ Expr *getSubExpr(unsigned Idx) const {
assert(Idx < NumSubExprs && "Subscript out of range");
- char* Ptr = static_cast<char*>(static_cast<void *>(this));
- Ptr += sizeof(DesignatedInitExpr);
- return reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx];
+ return cast<Expr>(reinterpret_cast<Stmt *const *>(this + 1)[Idx]);
}
void setSubExpr(unsigned Idx, Expr *E) {
assert(Idx < NumSubExprs && "Subscript out of range");
- char* Ptr = static_cast<char*>(static_cast<void *>(this));
- Ptr += sizeof(DesignatedInitExpr);
- reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx] = E;
+ reinterpret_cast<Stmt **>(this + 1)[Idx] = E;
}
/// \brief Replaces the designator at index @p Idx with the series
@@ -4621,7 +4636,7 @@
public:
/// NoResult - A value for the result index indicating that there is
/// no semantic result.
- enum LLVM_ENUM_INT_TYPE(unsigned) { NoResult = ~0U };
+ enum : unsigned { NoResult = ~0U };
static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic,
ArrayRef<Expr*> semantic,
@@ -4713,6 +4728,16 @@
BI_First = 0
};
+ // The ABI values for various atomic memory orderings.
+ enum AtomicOrderingKind {
+ AO_ABI_memory_order_relaxed = 0,
+ AO_ABI_memory_order_consume = 1,
+ AO_ABI_memory_order_acquire = 2,
+ AO_ABI_memory_order_release = 3,
+ AO_ABI_memory_order_acq_rel = 4,
+ AO_ABI_memory_order_seq_cst = 5
+ };
+
private:
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
Stmt* SubExprs[END_EXPR];
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6356ee7..6ed55ca 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1161,7 +1161,10 @@
const_arg_iterator arg_begin() const { return Args; }
const_arg_iterator arg_end() const { return Args + NumArgs; }
- Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); }
+ Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
+ const Expr *const *getArgs() const {
+ return const_cast<CXXConstructExpr *>(this)->getArgs();
+ }
unsigned getNumArgs() const { return NumArgs; }
/// \brief Return the specified argument.
@@ -2110,138 +2113,12 @@
child_range children() { return child_range(&Base, &Base + 1); }
};
-/// \brief Represents a GCC or MS unary type trait, as used in the
-/// implementation of TR1/C++11 type trait templates.
-///
-/// Example:
-/// \code
-/// __is_pod(int) == true
-/// __is_enum(std::string) == false
-/// \endcode
-class UnaryTypeTraitExpr : public Expr {
- /// \brief The trait. A UnaryTypeTrait enum in MSVC compatible unsigned.
- unsigned UTT : 31;
- /// The value of the type trait. Unspecified if dependent.
- bool Value : 1;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The type being queried.
- TypeSourceInfo *QueriedType;
-
-public:
- UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt,
- TypeSourceInfo *queried, bool value,
- SourceLocation rparen, QualType ty)
- : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
- false, queried->getType()->isDependentType(),
- queried->getType()->isInstantiationDependentType(),
- queried->getType()->containsUnexpandedParameterPack()),
- UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { }
-
- explicit UnaryTypeTraitExpr(EmptyShell Empty)
- : Expr(UnaryTypeTraitExprClass, Empty), UTT(0), Value(false),
- QueriedType() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- UnaryTypeTrait getTrait() const { return static_cast<UnaryTypeTrait>(UTT); }
-
- QualType getQueriedType() const { return QueriedType->getType(); }
-
- TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnaryTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(); }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Represents a GCC or MS binary type trait, as used in the
-/// implementation of TR1/C++11 type trait templates.
-///
-/// Example:
-/// \code
-/// __is_base_of(Base, Derived) == true
-/// \endcode
-class BinaryTypeTraitExpr : public Expr {
- /// \brief The trait. A BinaryTypeTrait enum in MSVC compatible unsigned.
- unsigned BTT : 8;
-
- /// The value of the type trait. Unspecified if dependent.
- bool Value : 1;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The lhs type being queried.
- TypeSourceInfo *LhsType;
-
- /// \brief The rhs type being queried.
- TypeSourceInfo *RhsType;
-
-public:
- BinaryTypeTraitExpr(SourceLocation loc, BinaryTypeTrait btt,
- TypeSourceInfo *lhsType, TypeSourceInfo *rhsType,
- bool value, SourceLocation rparen, QualType ty)
- : Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false,
- lhsType->getType()->isDependentType() ||
- rhsType->getType()->isDependentType(),
- (lhsType->getType()->isInstantiationDependentType() ||
- rhsType->getType()->isInstantiationDependentType()),
- (lhsType->getType()->containsUnexpandedParameterPack() ||
- rhsType->getType()->containsUnexpandedParameterPack())),
- BTT(btt), Value(value), Loc(loc), RParen(rparen),
- LhsType(lhsType), RhsType(rhsType) { }
-
-
- explicit BinaryTypeTraitExpr(EmptyShell Empty)
- : Expr(BinaryTypeTraitExprClass, Empty), BTT(0), Value(false),
- LhsType(), RhsType() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- BinaryTypeTrait getTrait() const {
- return static_cast<BinaryTypeTrait>(BTT);
- }
-
- QualType getLhsType() const { return LhsType->getType(); }
- QualType getRhsType() const { return RhsType->getType(); }
-
- TypeSourceInfo *getLhsTypeSourceInfo() const { return LhsType; }
- TypeSourceInfo *getRhsTypeSourceInfo() const { return RhsType; }
-
- bool getValue() const { assert(!isTypeDependent()); return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BinaryTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(); }
-
- friend class ASTStmtReader;
-};
-
/// \brief A type trait used in the implementation of various C++11 and
/// Library TR1 trait templates.
///
/// \code
+/// __is_pod(int) == true
+/// __is_enum(std::string) == false
/// __is_trivially_constructible(vector<int>, int*, int*)
/// \endcode
class TypeTraitExpr : public Expr {
@@ -2334,7 +2211,7 @@
friend class ASTStmtWriter;
};
-
+
/// \brief An Embarcadero array type trait, as used in the implementation of
/// __array_rank and __array_extent.
///
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index aeb55da..fc78e89 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -215,7 +215,7 @@
} // end namespace clang
namespace llvm {
-template <> struct isPodLike<clang::ObjCDictionaryElement> : llvm::true_type {};
+template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
}
namespace clang {
@@ -683,13 +683,13 @@
if (isExplicitProperty()) {
const ObjCPropertyDecl *PDecl = getExplicitProperty();
if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
- ResultType = Getter->getResultType();
+ ResultType = Getter->getReturnType();
else
ResultType = PDecl->getType();
} else {
const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
if (Getter)
- ResultType = Getter->getResultType(); // with reference!
+ ResultType = Getter->getReturnType(); // with reference!
}
return ResultType;
}
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index b077426..54e96d9 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -53,7 +53,7 @@
/// sources can resolve types and declarations from abstract IDs into
/// actual type and declaration nodes, and read parts of declaration
/// contexts.
-class ExternalASTSource {
+class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
/// \brief Whether this AST source also provides information for
/// semantic analysis.
bool SemaSource;
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
index ae84bcf..85e6449 100644
--- a/include/clang/AST/Makefile
+++ b/include/clang/AST/Makefile
@@ -1,6 +1,6 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc \
+BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc AttrVisitor.inc \
StmtNodes.inc DeclNodes.inc \
CommentNodes.inc CommentHTMLTags.inc \
CommentHTMLTagsProperties.inc \
@@ -30,6 +30,12 @@
$(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
+$(ObjDir)/AttrVisitor.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute AST visitor with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-attr-ast-visitor -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
+
$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang statement node tables with tblgen"
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index c4d0d22..28bcd8b 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -31,9 +31,10 @@
class FunctionDecl;
class NamedDecl;
class ObjCMethodDecl;
- class VarDecl;
+ class StringLiteral;
struct ThisAdjustment;
struct ThunkInfo;
+ class VarDecl;
/// MangleBuffer - a convenient class for storing a name which is
/// either the result of a mangling or is a constant string with
@@ -80,6 +81,7 @@
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
+ llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
public:
ManglerKind getKind() const { return Kind; }
@@ -104,12 +106,19 @@
Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
return Result.first->second;
}
-
+
+ uint64_t getAnonymousStructId(const TagDecl *TD) {
+ std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
+ Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
+ return Result.first->second;
+ }
+
/// @name Mangler Entry Points
/// @{
bool shouldMangleDeclName(const NamedDecl *D);
virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
+ virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
// FIXME: consider replacing raw_ostream & with something like SmallString &.
void mangleName(const NamedDecl *D, raw_ostream &);
@@ -128,6 +137,7 @@
raw_ostream &) = 0;
virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
raw_ostream &) = 0;
+ virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
void mangleGlobalBlock(const BlockDecl *BD,
const NamedDecl *ID,
@@ -200,7 +210,6 @@
raw_ostream &Out) = 0;
virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
- uint64_t OffsetInVFTable,
raw_ostream &) = 0;
static bool classof(const MangleContext *C) {
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
index 5a227f2..56c9952 100644
--- a/include/clang/AST/MangleNumberingContext.h
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -33,7 +33,6 @@
class MangleNumberingContext
: public RefCountedBase<MangleNumberingContext> {
llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
- llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers;
public:
virtual ~MangleNumberingContext() {}
@@ -46,13 +45,18 @@
/// context.
unsigned getManglingNumber(const BlockDecl *BD);
- /// \brief Retrieve the mangling number of a static local variable within
- /// this context.
- virtual unsigned getManglingNumber(const VarDecl *VD) = 0;
+ /// Static locals are numbered by source order.
+ unsigned getStaticLocalNumber(const VarDecl *VD);
/// \brief Retrieve the mangling number of a static local variable within
/// this context.
- unsigned getManglingNumber(const TagDecl *TD);
+ virtual unsigned getManglingNumber(const VarDecl *VD,
+ unsigned MSLocalManglingNumber) = 0;
+
+ /// \brief Retrieve the mangling number of a static local variable within
+ /// this context.
+ virtual unsigned getManglingNumber(const TagDecl *TD,
+ unsigned MSLocalManglingNumber) = 0;
};
} // end namespace clang
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
new file mode 100644
index 0000000..64b5ce4
--- /dev/null
+++ b/include/clang/AST/OpenMPClause.h
@@ -0,0 +1,617 @@
+//===- OpenMPClause.h - Classes for OpenMP clauses --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file defines OpenMP AST classes for clauses.
+/// There are clauses for executable directives, clauses for declarative
+/// directives and clauses which can be used in both kinds of directives.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
+#define LLVM_CLANG_AST_OPENMPCLAUSE_H
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// AST classes for clauses.
+//===----------------------------------------------------------------------===//
+
+/// \brief This is a basic class for representing single OpenMP clause.
+///
+class OMPClause {
+ /// \brief Starting location of the clause (the clause keyword).
+ SourceLocation StartLoc;
+ /// \brief Ending location of the clause.
+ SourceLocation EndLoc;
+ /// \brief Kind of the clause.
+ OpenMPClauseKind Kind;
+
+protected:
+ OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
+ : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
+
+public:
+ /// \brief Returns the starting location of the clause.
+ SourceLocation getLocStart() const { return StartLoc; }
+ /// \brief Returns the ending location of the clause.
+ SourceLocation getLocEnd() const { return EndLoc; }
+
+ /// \brief Sets the starting location of the clause.
+ void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
+ /// \brief Sets the ending location of the clause.
+ void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
+
+ /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
+ OpenMPClauseKind getClauseKind() const { return Kind; }
+
+ bool isImplicit() const { return StartLoc.isInvalid(); }
+
+ StmtRange children();
+ ConstStmtRange children() const {
+ return const_cast<OMPClause *>(this)->children();
+ }
+ static bool classof(const OMPClause *T) { return true; }
+};
+
+/// \brief This represents clauses with the list of variables like 'private',
+/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
+/// '#pragma omp ...' directives.
+template <class T> class OMPVarListClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Number of variables in the list.
+ unsigned NumVars;
+
+protected:
+ /// \brief Fetches list of variables associated with this clause.
+ llvm::MutableArrayRef<Expr *> getVarRefs() {
+ return llvm::MutableArrayRef<Expr *>(
+ reinterpret_cast<Expr **>(
+ reinterpret_cast<char *>(this) +
+ llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+ NumVars);
+ }
+
+ /// \brief Sets the list of variables for this clause.
+ void setVarRefs(ArrayRef<Expr *> VL) {
+ assert(VL.size() == NumVars &&
+ "Number of variables is not the same as the preallocated buffer");
+ std::copy(
+ VL.begin(), VL.end(),
+ reinterpret_cast<Expr **>(
+ reinterpret_cast<char *>(this) +
+ llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())));
+ }
+
+ /// \brief Build a clause with \a N variables
+ ///
+ /// \param K Kind of the clause.
+ /// \param StartLoc Starting location of the clause (the clause keyword).
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
+ : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
+
+public:
+ typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
+ typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+ typedef llvm::iterator_range<varlist_iterator> varlist_range;
+ typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
+
+ unsigned varlist_size() const { return NumVars; }
+ bool varlist_empty() const { return NumVars == 0; }
+
+ varlist_range varlists() {
+ return varlist_range(varlist_begin(), varlist_end());
+ }
+ varlist_const_range varlists() const {
+ return varlist_const_range(varlist_begin(), varlist_end());
+ }
+
+ varlist_iterator varlist_begin() { return getVarRefs().begin(); }
+ varlist_iterator varlist_end() { return getVarRefs().end(); }
+ varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
+ varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Fetches list of all variables in the clause.
+ ArrayRef<const Expr *> getVarRefs() const {
+ return ArrayRef<const Expr *>(
+ reinterpret_cast<const Expr *const *>(
+ reinterpret_cast<const char *>(this) +
+ llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+ NumVars);
+ }
+};
+
+/// \brief This represents 'if' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel if(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'if'
+/// clause with condition 'a > 5'.
+///
+class OMPIfClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Condition of the 'if' clause.
+ Stmt *Condition;
+
+ /// \brief Set condition.
+ ///
+ void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+ /// \brief Build 'if' clause with condition \a Cond.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param Cond Condition of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPIfClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Condition(Cond) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPIfClause()
+ : OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Condition(0) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns condition.
+ Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_if;
+ }
+
+ StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
+/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp parallel num_threads(6)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'num_threads'
+/// clause with number of threads '6'.
+///
+class OMPNumThreadsClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Condition of the 'num_threads' clause.
+ Stmt *NumThreads;
+
+ /// \brief Set condition.
+ ///
+ void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
+
+public:
+ /// \brief Build 'num_threads' clause with condition \a NumThreads.
+ ///
+ /// \param NumThreads Number of threads for the construct.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ NumThreads(NumThreads) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPNumThreadsClause()
+ : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), NumThreads(0) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns number of threads.
+ Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_num_threads;
+ }
+
+ StmtRange children() { return StmtRange(&NumThreads, &NumThreads + 1); }
+};
+
+/// \brief This represents 'safelen' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp simd safelen(4)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'safelen'
+/// with single expression '4'.
+/// If the safelen clause is used then no two iterations executed
+/// concurrently with SIMD instructions can have a greater distance
+/// in the logical iteration space than its value. The parameter of
+/// the safelen clause must be a constant positive integer expression.
+///
+class OMPSafelenClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Safe iteration space distance.
+ Stmt *Safelen;
+
+ /// \brief Set safelen.
+ void setSafelen(Expr *Len) { Safelen = Len; }
+
+public:
+ /// \brief Build 'safelen' clause.
+ ///
+ /// \param Len Expression associated with this clause.
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Safelen(Len) {}
+
+ /// \brief Build an empty clause.
+ ///
+ explicit OMPSafelenClause()
+ : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Safelen(0) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Return safe iteration space distance.
+ Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_safelen;
+ }
+
+ StmtRange children() { return StmtRange(&Safelen, &Safelen + 1); }
+};
+
+/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel default(shared)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'default'
+/// clause with kind 'shared'.
+///
+class OMPDefaultClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief A kind of the 'default' clause.
+ OpenMPDefaultClauseKind Kind;
+ /// \brief Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// \brief Set kind of the clauses.
+ ///
+ /// \param K Argument of clause.
+ ///
+ void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
+
+ /// \brief Set argument location.
+ ///
+ /// \param KLoc Argument location.
+ ///
+ void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+ /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
+ ///
+ /// \param A Argument of the clause ('none' or 'shared').
+ /// \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.
+ ///
+ OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Kind(A), KindKwLoc(ALoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPDefaultClause()
+ : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_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.
+ OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
+
+ /// \brief Returns location of clause kind.
+ SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_default;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel private(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'private'
+/// with the variables 'a' and 'b'.
+///
+class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPPrivateClause(unsigned N)
+ : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_private;
+ }
+};
+
+/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp parallel firstprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
+ LParenLoc, EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPFirstprivateClause(unsigned N)
+ : OMPVarListClause<OMPFirstprivateClause>(
+ OMPC_firstprivate, SourceLocation(), SourceLocation(),
+ SourceLocation(), N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPFirstprivateClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_firstprivate;
+ }
+};
+
+/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel shared(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'shared'
+/// with the variables 'a' and 'b'.
+///
+class OMPSharedClause : public OMPVarListClause<OMPSharedClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPSharedClause(unsigned N)
+ : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_shared;
+ }
+};
+
+/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel copyin(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'copyin'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyinClause : public OMPVarListClause<OMPCopyinClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPCopyinClause(unsigned N)
+ : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPCopyinClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_copyin;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index 5e41d95..aba88d6 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -295,7 +295,10 @@
CK_BuiltinFnToFnPtr,
// Convert a zero value for OpenCL event_t initialization.
- CK_ZeroToOCLEvent
+ CK_ZeroToOCLEvent,
+
+ // Convert a pointer to a different address space.
+ CK_AddressSpaceConversion
};
static const CastKind CK_Invalid = static_cast<CastKind>(-1);
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 7642699..349f4c4 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -41,7 +41,8 @@
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false),
- MSWChar(LO.MicrosoftExt && !LO.WChar) { }
+ Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
+ IncludeNewlines(true) { }
/// \brief What language we're printing.
LangOptions LangOpts;
@@ -125,7 +126,7 @@
/// \brief When printing an anonymous tag name, also print the location of
/// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just
- /// prints "<anonymous>" for the name.
+ /// prints "(anonymous)" for the name.
bool AnonymousTagLocations : 1;
/// \brief When true, suppress printing of the __strong lifetime qualifier in
@@ -152,9 +153,16 @@
///
unsigned PolishForDeclaration : 1;
+ /// \brief When true, print the half-precision floating-point type as 'half'
+ /// instead of '__fp16'
+ unsigned Half : 1;
+
/// \brief When true, print the built-in wchar_t type as __wchar_t. For use in
/// Microsoft mode when wchar_t is not available.
unsigned MSWChar : 1;
+
+ /// \brief When true, include newlines after statements like "break", etc.
+ unsigned IncludeNewlines : 1;
};
} // end namespace clang
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index a4fcc10..8ba85c4 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -193,9 +193,7 @@
SourceManager &SourceMgr;
std::vector<RawComment *> Comments;
- void addCommentsToFront(const std::vector<RawComment *> &C) {
- Comments.insert(Comments.begin(), C.begin(), C.end());
- }
+ void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
friend class ASTReader;
};
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 7268b3a..4befb45 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -66,6 +66,10 @@
// Alignment - Alignment of record in characters.
CharUnits Alignment;
+ /// RequiredAlignment - The required alignment of the object. In the MS-ABI
+ /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
+ CharUnits RequiredAlignment;
+
/// FieldOffsets - Array of field offsets in bits.
uint64_t *FieldOffsets;
@@ -78,9 +82,9 @@
/// the size of the object without virtual bases.
CharUnits NonVirtualSize;
- /// NonVirtualAlign - The non-virtual alignment (in chars) of an object,
+ /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
/// which is the alignment of the object without virtual bases.
- CharUnits NonVirtualAlign;
+ CharUnits NonVirtualAlignment;
/// SizeOfLargestEmptySubobject - The size of the largest empty subobject
/// (either a base or a member). Will be zero if the class doesn't contain
@@ -100,10 +104,15 @@
/// a primary base class.
bool HasExtendableVFPtr : 1;
- /// AlignAfterVBases - Force appropriate alignment after virtual bases are
- /// laid out in MS-C++-ABI.
- bool AlignAfterVBases : 1;
-
+ /// HasZeroSizedSubObject - True if this class contains a zero sized member
+ /// or base or a base with a zero sized member or base. Only used for
+ /// MS-ABI.
+ bool HasZeroSizedSubObject : 1;
+
+ /// \brief True if this class is zero sized or first base is zero sized or
+ /// has this property. Only used for MS-ABI.
+ bool LeadsWithZeroSizedBase : 1;
+
/// PrimaryBase - The primary base info for this record.
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
@@ -127,6 +136,7 @@
friend class ASTContext;
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
+ CharUnits requiredAlignment,
CharUnits datasize, const uint64_t *fieldoffsets,
unsigned fieldcount);
@@ -134,16 +144,18 @@
typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
ASTRecordLayout(const ASTContext &Ctx,
CharUnits size, CharUnits alignment,
+ CharUnits requiredAlignment,
bool hasOwnVFPtr, bool hasExtendableVFPtr,
CharUnits vbptroffset,
CharUnits datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
- CharUnits nonvirtualsize, CharUnits nonvirtualalign,
+ CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
CharUnits SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool IsPrimaryBaseVirtual,
const CXXRecordDecl *BaseSharingVBPtr,
- bool ForceAlign,
+ bool HasZeroSizedSubObject,
+ bool LeadsWithZeroSizedBase,
const BaseOffsetsMapTy& BaseOffsets,
const VBaseOffsetsMapTy& VBaseOffsets);
@@ -187,10 +199,10 @@
/// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
/// which is the alignment of the object without virtual bases.
- CharUnits getNonVirtualAlign() const {
+ CharUnits getNonVirtualAlignment() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->NonVirtualAlign;
+ return CXXInfo->NonVirtualAlignment;
}
/// getPrimaryBase - Get the primary base for this record.
@@ -267,9 +279,17 @@
return !CXXInfo->VBPtrOffset.isNegative();
}
- bool getAlignAfterVBases() const {
+ CharUnits getRequiredAlignment() const {
+ return RequiredAlignment;
+ }
+
+ bool hasZeroSizedSubObject() const {
+ return CXXInfo && CXXInfo->HasZeroSizedSubObject;
+ }
+
+ bool leadsWithZeroSizedBase() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->AlignAfterVBases;
+ return CXXInfo->LeadsWithZeroSizedBase;
}
/// getVBPtrOffset - Get the offset for virtual base table pointer.
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index d09550f..1a2ce44 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
@@ -182,6 +183,13 @@
/// otherwise (including when the argument is a Null type location).
bool TraverseTypeLoc(TypeLoc TL);
+ /// \brief Recursively visit an attribute, by dispatching to
+ /// Traverse*Attr() based on the argument's dynamic type.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type location).
+ bool TraverseAttr(Attr *At);
+
/// \brief Recursively visit a declaration, by dispatching to
/// Traverse*Decl() based on the argument's dynamic type.
///
@@ -254,6 +262,16 @@
/// \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.
+#define ATTR_VISITOR_DECLS_ONLY
+#include "clang/AST/AttrVisitor.inc"
+#undef ATTR_VISITOR_DECLS_ONLY
+
// ---- Methods on Stmts ----
// Declare Traverse*() for all concrete Stmt classes.
@@ -423,6 +441,7 @@
bool TraverseFunctionHelper(FunctionDecl *D);
bool TraverseVarHelper(VarDecl *D);
bool TraverseOMPClause(OMPClause *C);
+ bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
#define OPENMP_CLAUSE(Name, Class) \
bool Visit##Class(Class *C);
#include "clang/Basic/OpenMPKinds.def"
@@ -623,6 +642,12 @@
}
+// Define the Traverse*Attr(Attr* A) methods
+#define VISITORCLASS RecursiveASTVisitor
+#include "clang/AST/AttrVisitor.inc"
+#undef VISITORCLASS
+
+
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
if (!D)
@@ -636,10 +661,18 @@
switch (D->getKind()) {
#define ABSTRACT_DECL(DECL)
#define DECL(CLASS, BASE) \
- case Decl::CLASS: DISPATCH(CLASS##Decl, CLASS##Decl, D);
+ case Decl::CLASS: \
+ if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl*>(D))) \
+ return false; \
+ break;
#include "clang/AST/DeclNodes.inc"
- }
+ }
+ // Visit any attributes attached to this declaration.
+ for (auto *I : D->attrs()) {
+ if (!getDerived().TraverseAttr(I))
+ return false;
+ }
return true;
}
@@ -874,6 +907,10 @@
TRY_TO(TraverseType(T->getPointeeType()));
})
+DEF_TRAVERSE_TYPE(AdjustedType, {
+ TRY_TO(TraverseType(T->getOriginalType()));
+ })
+
DEF_TRAVERSE_TYPE(DecayedType, {
TRY_TO(TraverseType(T->getOriginalType()));
})
@@ -911,25 +948,20 @@
TRY_TO(TraverseType(T->getElementType()));
})
-DEF_TRAVERSE_TYPE(FunctionNoProtoType, {
- TRY_TO(TraverseType(T->getResultType()));
- })
+DEF_TRAVERSE_TYPE(FunctionNoProtoType,
+ { TRY_TO(TraverseType(T->getReturnType())); })
DEF_TRAVERSE_TYPE(FunctionProtoType, {
- TRY_TO(TraverseType(T->getResultType()));
+ TRY_TO(TraverseType(T->getReturnType()));
- for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
- AEnd = T->arg_type_end();
- A != AEnd; ++A) {
- TRY_TO(TraverseType(*A));
- }
+ for (const auto &A : T->param_types()) {
+ TRY_TO(TraverseType(A));
+ }
- for (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- TRY_TO(TraverseType(*E));
- }
- })
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+})
DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
DEF_TRAVERSE_TYPE(TypedefType, { })
@@ -1084,6 +1116,10 @@
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
})
+DEF_TRAVERSE_TYPELOC(AdjustedType, {
+ TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
+ })
+
DEF_TRAVERSE_TYPELOC(DecayedType, {
TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
})
@@ -1135,27 +1171,25 @@
})
DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
+ TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
})
// FIXME: location of exception specifications (attributes?)
DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
+ TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
const FunctionProtoType *T = TL.getTypePtr();
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- if (TL.getArg(I)) {
- TRY_TO(TraverseDecl(TL.getArg(I)));
- } else if (I < T->getNumArgs()) {
- TRY_TO(TraverseType(T->getArgType(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 (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- TRY_TO(TraverseType(*E));
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
}
})
@@ -1263,13 +1297,11 @@
if (!DC)
return true;
- for (DeclContext::decl_iterator Child = DC->decls_begin(),
- ChildEnd = DC->decls_end();
- Child != ChildEnd; ++Child) {
+ for (auto *Child : DC->decls()) {
// BlockDecls and CapturedDecls are traversed through BlockExprs and
// CapturedStmts respectively.
- if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child))
- TRY_TO(TraverseDecl(*Child));
+ if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+ TRY_TO(TraverseDecl(Child));
}
return true;
@@ -1409,18 +1441,18 @@
})
DEF_TRAVERSE_DECL(ObjCMethodDecl, {
- if (D->getResultTypeSourceInfo()) {
- TRY_TO(TraverseTypeLoc(D->getResultTypeSourceInfo()->getTypeLoc()));
- }
- for (ObjCMethodDecl::param_iterator
- I = D->param_begin(), E = D->param_end(); I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody()));
- }
- return true;
- })
+ if (D->getReturnTypeSourceInfo()) {
+ TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
+ }
+ for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ if (D->isThisDeclarationADefinition()) {
+ TRY_TO(TraverseStmt(D->getBody()));
+ }
+ return true;
+})
DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
// FIXME: implement
@@ -1438,10 +1470,8 @@
DEF_TRAVERSE_DECL(UsingShadowDecl, { })
DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
- for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
- E = D->varlist_end();
- I != E; ++I) {
- TRY_TO(TraverseStmt(*I));
+ for (auto *I : D->varlists()) {
+ TRY_TO(TraverseStmt(I));
}
})
@@ -1458,65 +1488,84 @@
return true;
}
-#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
-/* A helper method for traversing the implicit instantiations of a
- class or variable template. */ \
-template<typename Derived> \
-bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations( \
- TMPLDECLKIND##TemplateDecl *D) { \
- TMPLDECLKIND##TemplateDecl::spec_iterator end = D->spec_end(); \
- for (TMPLDECLKIND##TemplateDecl::spec_iterator it = D->spec_begin(); \
- it != end; ++it) { \
- TMPLDECLKIND##TemplateSpecializationDecl* SD = *it; \
- \
- switch (SD->getSpecializationKind()) { \
- /* Visit the implicit instantiations with the requested pattern. */ \
- case TSK_Undeclared: \
- case TSK_ImplicitInstantiation: \
- TRY_TO(TraverseDecl(SD)); \
- break; \
- \
- /* We don't need to do anything on an explicit instantiation
- or explicit specialization because there will be an explicit
- node for it elsewhere. */ \
- case TSK_ExplicitInstantiationDeclaration: \
- case TSK_ExplicitInstantiationDefinition: \
- case TSK_ExplicitSpecialization: \
- break; \
- } \
- } \
- \
- return true; \
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
+ ClassTemplateDecl *D) {
+ for (auto *SD : D->specializations()) {
+ for (auto *RD : SD->redecls()) {
+ // We don't want to visit injected-class-names in this traversal.
+ if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
+ continue;
+
+ switch (cast<ClassTemplateSpecializationDecl>(RD)->
+ getSpecializationKind()) {
+ // Visit the implicit instantiations with the requested pattern.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ TRY_TO(TraverseDecl(RD));
+ break;
+
+ // We don't need to do anything on an explicit instantiation
+ // or explicit specialization because there will be an explicit
+ // node for it elsewhere.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+ }
+
+ return true;
}
-
-DEF_TRAVERSE_TMPL_INST(Class)
-DEF_TRAVERSE_TMPL_INST(Var)
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
+ VarTemplateDecl *D) {
+ for (auto *SD : D->specializations()) {
+ for (auto *RD : SD->redecls()) {
+ switch (cast<VarTemplateSpecializationDecl>(RD)->
+ getSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ TRY_TO(TraverseDecl(RD));
+ break;
+
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
// A helper method for traversing the instantiations of a
// function while skipping its specializations.
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
FunctionTemplateDecl *D) {
- FunctionTemplateDecl::spec_iterator end = D->spec_end();
- for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end;
- ++it) {
- FunctionDecl* FD = *it;
- switch (FD->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- // We don't know what kind of FunctionDecl this is.
- TRY_TO(TraverseDecl(FD));
- break;
+ for (auto *FD : D->specializations()) {
+ for (auto *RD : FD->redecls()) {
+ switch (RD->getTemplateSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ // We don't know what kind of FunctionDecl this is.
+ TRY_TO(TraverseDecl(RD));
+ break;
- // FIXME: For now traverse explicit instantiations here. Change that
- // once they are represented as dedicated nodes in the AST.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- TRY_TO(TraverseDecl(FD));
- break;
+ // FIXME: For now traverse explicit instantiations here. Change that
+ // once they are represented as dedicated nodes in the AST.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ TRY_TO(TraverseDecl(RD));
+ break;
- case TSK_ExplicitSpecialization:
- break;
+ case TSK_ExplicitSpecialization:
+ break;
+ }
}
}
@@ -1622,10 +1671,8 @@
if (!TraverseRecordHelper(D))
return false;
if (D->isCompleteDefinition()) {
- for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
- E = D->bases_end();
- I != E; ++I) {
- TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc()));
+ for (const auto &I : D->bases()) {
+ TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
}
// We don't traverse the friends or the conversions, as they are
// already in decls_begin()/decls_end().
@@ -1791,10 +1838,8 @@
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
// Constructor initializers.
- for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
- E = Ctor->init_end();
- I != E; ++I) {
- TRY_TO(TraverseConstructorInitializer(*I));
+ for (auto *I : Ctor->inits()) {
+ TRY_TO(TraverseConstructorInitializer(I));
}
}
@@ -1923,9 +1968,8 @@
})
DEF_TRAVERSE_STMT(DeclStmt, {
- for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
+ 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 [=
@@ -2133,15 +2177,6 @@
TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
})
-DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
- })
-
-DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getLhsTypeSourceInfo()->getTypeLoc()));
- TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
- })
-
DEF_TRAVERSE_STMT(TypeTraitExpr, {
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
@@ -2184,11 +2219,11 @@
} else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
if (S->hasExplicitParameters()) {
// Visit parameters.
- for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) {
- TRY_TO(TraverseDecl(Proto.getArg(I)));
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ TRY_TO(TraverseDecl(Proto.getParam(I)));
}
} else {
- TRY_TO(TraverseTypeLoc(Proto.getResultLoc()));
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
}
}
}
@@ -2325,11 +2360,22 @@
DEF_TRAVERSE_STMT(AsTypeExpr, { })
// OpenMP directives.
-DEF_TRAVERSE_STMT(OMPParallelDirective, {
+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;
+ return true;
+}
+
+DEF_TRAVERSE_STMT(OMPParallelDirective, {
+ if (!TraverseOMPExecutableDirective(S)) return false;
+})
+
+DEF_TRAVERSE_STMT(OMPSimdDirective, {
+ if (!TraverseOMPExecutableDirective(S)) return false;
})
// OpenMP clauses.
@@ -2347,6 +2393,25 @@
}
template<typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+ TraverseStmt(C->getCondition());
+ return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(
+ OMPNumThreadsClause *C) {
+ TraverseStmt(C->getNumThreads());
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
+ TraverseStmt(C->getSafelen());
+ return true;
+}
+
+template<typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
return true;
}
@@ -2354,10 +2419,8 @@
template<typename Derived>
template<typename T>
void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
- for (typename T::varlist_iterator I = Node->varlist_begin(),
- E = Node->varlist_end();
- I != E; ++I)
- TraverseStmt(*I);
+ for (auto *I : Node->varlists())
+ TraverseStmt(I);
}
template<typename Derived>
@@ -2379,6 +2442,12 @@
return true;
}
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index cfe5a90..1170eda 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -161,13 +161,18 @@
}
};
- /// \brief Returns iterator for all the redeclarations of the same decl.
- /// It will iterate at least once (when this decl is the only one).
- redecl_iterator redecls_begin() const {
- return redecl_iterator(const_cast<decl_type*>(
- static_cast<const decl_type*>(this)));
+ typedef llvm::iterator_range<redecl_iterator> redecl_range;
+
+ /// \brief Returns an iterator range for all the redeclarations of the same
+ /// decl. It will iterate at least once (when this decl is the only one).
+ redecl_range redecls() const {
+ return redecl_range(redecl_iterator(const_cast<decl_type *>(
+ static_cast<const decl_type *>(this))),
+ redecl_iterator());
}
- redecl_iterator redecls_end() const { return redecl_iterator(); }
+
+ redecl_iterator redecls_begin() const { return redecls().begin(); }
+ redecl_iterator redecls_end() const { return redecls().end(); }
friend class ASTDeclReader;
friend class ASTDeclWriter;
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index ace53d8..ae34f42 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -371,12 +371,12 @@
/// \brief Dumps the specified AST fragment and all subtrees to
/// \c llvm::errs().
- LLVM_ATTRIBUTE_USED void dump() const;
- LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const;
+ void dump() const;
+ void dump(SourceManager &SM) const;
void dump(raw_ostream &OS, SourceManager &SM) const;
/// dumpColor - same as dump(), but forces color highlighting.
- LLVM_ATTRIBUTE_USED void dumpColor() const;
+ void dumpColor() const;
/// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
/// back to its original source language syntax.
@@ -485,7 +485,13 @@
typedef DeclGroupRef::iterator decl_iterator;
typedef DeclGroupRef::const_iterator const_decl_iterator;
+ typedef llvm::iterator_range<decl_iterator> decl_range;
+ typedef llvm::iterator_range<const_decl_iterator> decl_const_range;
+ decl_range decls() { return decl_range(decl_begin(), decl_end()); }
+ decl_const_range decls() const {
+ return decl_const_range(decl_begin(), decl_end());
+ }
decl_iterator decl_begin() { return DG.begin(); }
decl_iterator decl_end() { return DG.end(); }
const_decl_iterator decl_begin() const { return DG.begin(); }
@@ -565,6 +571,9 @@
unsigned size() const { return CompoundStmtBits.NumStmts; }
typedef Stmt** body_iterator;
+ typedef llvm::iterator_range<body_iterator> body_range;
+
+ 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; }
@@ -575,6 +584,11 @@
}
typedef Stmt* const * const_body_iterator;
+ typedef llvm::iterator_range<const_body_iterator> body_const_range;
+
+ body_const_range body() const {
+ return body_const_range(body_begin(), body_end());
+ }
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; }
@@ -612,11 +626,11 @@
// Iterators
child_range children() {
- return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts);
+ return child_range(Body, Body + CompoundStmtBits.NumStmts);
}
const_child_range children() const {
- return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts);
+ return child_range(Body, Body + CompoundStmtBits.NumStmts);
}
};
@@ -1767,7 +1781,7 @@
}
child_range children() {
- return child_range(&Exprs[0], &Exprs[0]);
+ return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
}
};
@@ -2042,6 +2056,15 @@
/// \brief An iterator that walks over the captures.
typedef Capture *capture_iterator;
typedef const Capture *const_capture_iterator;
+ typedef llvm::iterator_range<capture_iterator> capture_range;
+ typedef llvm::iterator_range<const_capture_iterator> capture_const_range;
+
+ capture_range captures() {
+ return capture_range(capture_begin(), capture_end());
+ }
+ capture_const_range captures() const {
+ return capture_const_range(capture_begin(), capture_end());
+ }
/// \brief Retrieve an iterator pointing to the first capture.
capture_iterator capture_begin() { return getStoredCaptures(); }
@@ -2058,6 +2081,11 @@
/// \brief Iterator that walks over the capture initialization arguments.
typedef Expr **capture_init_iterator;
+ typedef llvm::iterator_range<capture_init_iterator> capture_init_range;
+
+ capture_init_range capture_inits() const {
+ return capture_init_range(capture_init_begin(), capture_init_end());
+ }
/// \brief Retrieve the first initialization argument.
capture_init_iterator capture_init_begin() const {
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index fbc8e5d..a31632f 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CLANG_AST_STMT_ITR_H
#define LLVM_CLANG_AST_STMT_ITR_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <cstddef>
#include <iterator>
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 8570d88..023720a 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -1,4 +1,4 @@
-//===- StmtOpenMP.h - Classes for OpenMP directives and clauses --*- C++ -*-===//
+//===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,359 +15,15 @@
#ifndef LLVM_CLANG_AST_STMTOPENMP_H
#define LLVM_CLANG_AST_STMTOPENMP_H
+#include "clang/AST/Expr.h"
+#include "clang/AST/OpenMPClause.h"
+#include "clang/AST/Stmt.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Stmt.h"
namespace clang {
//===----------------------------------------------------------------------===//
-// AST classes for clauses.
-//===----------------------------------------------------------------------===//
-
-/// \brief This is a basic class for representing single OpenMP clause.
-///
-class OMPClause {
- /// \brief Starting location of the clause (the clause keyword).
- SourceLocation StartLoc;
- /// \brief Ending location of the clause.
- SourceLocation EndLoc;
- /// \brief Kind of the clause.
- OpenMPClauseKind Kind;
-protected:
- OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
- : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
-
-public:
-
- /// \brief Returns the starting location of the clause.
- SourceLocation getLocStart() const { return StartLoc; }
- /// \brief Returns the ending location of the clause.
- SourceLocation getLocEnd() const { return EndLoc; }
-
- /// \brief Sets the starting location of the clause.
- void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
- /// \brief Sets the ending location of the clause.
- void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
-
- /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
- OpenMPClauseKind getClauseKind() const { return Kind; }
-
- bool isImplicit() const { return StartLoc.isInvalid();}
-
- StmtRange children();
- ConstStmtRange children() const {
- return const_cast<OMPClause *>(this)->children();
- }
- static bool classof(const OMPClause *T) {
- return true;
- }
-};
-
-/// \brief This represents clauses with the list of variables like 'private',
-/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
-/// '#pragma omp ...' directives.
-template <class T>
-class OMPVarList {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Number of variables in the list.
- unsigned NumVars;
-protected:
- /// \brief Fetches list of variables associated with this clause.
- llvm::MutableArrayRef<Expr *> getVarRefs() {
- return llvm::MutableArrayRef<Expr *>(
- reinterpret_cast<Expr **>(static_cast<T *>(this) + 1),
- NumVars);
- }
-
- /// \brief Sets the list of variables for this clause.
- void setVarRefs(ArrayRef<Expr *> VL) {
- assert(VL.size() == NumVars &&
- "Number of variables is not the same as the preallocated buffer");
- std::copy(VL.begin(), VL.end(),
- reinterpret_cast<Expr **>(static_cast<T *>(this) + 1));
- }
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param N Number of the variables in the clause.
- ///
- OMPVarList(SourceLocation LParenLoc, unsigned N)
- : LParenLoc(LParenLoc), NumVars(N) { }
-public:
- typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
- typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
-
- unsigned varlist_size() const { return NumVars; }
- bool varlist_empty() const { return NumVars == 0; }
- varlist_iterator varlist_begin() { return getVarRefs().begin(); }
- varlist_iterator varlist_end() { return getVarRefs().end(); }
- varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
- varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Fetches list of all variables in the clause.
- ArrayRef<const Expr *> getVarRefs() const {
- return ArrayRef<const Expr *>(
- reinterpret_cast<const Expr *const *>(static_cast<const T *>(this) + 1),
- NumVars);
- }
-};
-
-/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp parallel default(shared)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'default'
-/// clause with kind 'shared'.
-///
-class OMPDefaultClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief A kind of the 'default' clause.
- OpenMPDefaultClauseKind Kind;
- /// \brief Start location of the kind in source code.
- SourceLocation KindKwLoc;
-
- /// \brief Set kind of the clauses.
- ///
- /// \param K Argument of clause.
- ///
- void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
-
- /// \brief Set argument location.
- ///
- /// \param KLoc Argument location.
- ///
- void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
-public:
- /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
- ///
- /// \param A Argument of the clause ('none' or 'shared').
- /// \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.
- ///
- OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(A), KindKwLoc(ALoc) { }
-
- /// \brief Build an empty clause.
- ///
- OMPDefaultClause()
- : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_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.
- OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
-
- /// \brief Returns location of clause kind.
- SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_default;
- }
-
- StmtRange children() {
- return StmtRange();
- }
-};
-
-/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel private(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'private'
-/// with the variables 'a' and 'b'.
-///
-class OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> {
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPClause(OMPC_private, StartLoc, EndLoc),
- OMPVarList<OMPPrivateClause>(LParenLoc, N) { }
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPPrivateClause(unsigned N)
- : OMPClause(OMPC_private, SourceLocation(), SourceLocation()),
- OMPVarList<OMPPrivateClause>(SourceLocation(), N) { }
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- ///
- static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc,
- ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- StmtRange children() {
- return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_private;
- }
-};
-
-/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp parallel firstprivate(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
-/// with the variables 'a' and 'b'.
-///
-class OMPFirstprivateClause : public OMPClause,
- public OMPVarList<OMPFirstprivateClause> {
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPClause(OMPC_firstprivate, StartLoc, EndLoc),
- OMPVarList<OMPFirstprivateClause>(LParenLoc, N) { }
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPFirstprivateClause(unsigned N)
- : OMPClause(OMPC_firstprivate, SourceLocation(), SourceLocation()),
- OMPVarList<OMPFirstprivateClause>(SourceLocation(), N) { }
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- ///
- static OMPFirstprivateClause *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc,
- ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- StmtRange children() {
- return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_firstprivate;
- }
-};
-
-/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel shared(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'shared'
-/// with the variables 'a' and 'b'.
-///
-class OMPSharedClause : public OMPClause, public OMPVarList<OMPSharedClause> {
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPClause(OMPC_shared, StartLoc, EndLoc),
- OMPVarList<OMPSharedClause>(LParenLoc, N) { }
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPSharedClause(unsigned N)
- : OMPClause(OMPC_shared, SourceLocation(), SourceLocation()),
- OMPVarList<OMPSharedClause>(SourceLocation(), N) { }
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- ///
- static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- StmtRange children() {
- return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_shared;
- }
-};
-
-//===----------------------------------------------------------------------===//
// AST classes for directives.
//===----------------------------------------------------------------------===//
@@ -382,10 +38,23 @@
SourceLocation StartLoc;
/// \brief Ending location of the directive.
SourceLocation EndLoc;
- /// \brief Pointer to the list of clauses.
- llvm::MutableArrayRef<OMPClause *> Clauses;
- /// \brief Associated statement (if any) and expressions.
- llvm::MutableArrayRef<Stmt *> StmtAndExpressions;
+ /// \brief Numbers of clauses.
+ const unsigned NumClauses;
+ /// \brief Number of child expressions/stmts.
+ const unsigned NumChildren;
+ /// \brief Offset from this to the start of clauses.
+ /// There are NumClauses pointers to clauses, they are followed by
+ /// NumChildren pointers to child stmts/exprs (if the directive type
+ /// requires an associated stmt, then it has to be the first of them).
+ const unsigned ClausesOffset;
+
+ /// \brief Get the clauses storage.
+ llvm::MutableArrayRef<OMPClause *> getClauses() {
+ OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
+ reinterpret_cast<char *>(this) + ClausesOffset);
+ return llvm::MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
+ }
+
protected:
/// \brief Build instance of directive of class \a K.
///
@@ -397,12 +66,11 @@
template <typename T>
OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses, unsigned NumberOfExpressions)
- : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc),
- Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1),
- NumClauses),
- StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()),
- NumberOfExpressions) { }
+ unsigned NumClauses, unsigned NumChildren)
+ : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc),
+ NumClauses(NumClauses), NumChildren(NumChildren),
+ ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
+ llvm::alignOf<OMPClause *>())) {}
/// \brief Sets the list of variables for this clause.
///
@@ -414,9 +82,7 @@
///
/// /param S Associated statement.
///
- void setAssociatedStmt(Stmt *S) {
- StmtAndExpressions[0] = S;
- }
+ void setAssociatedStmt(Stmt *S) { *child_begin() = S; }
public:
/// \brief Returns starting location of directive kind.
@@ -436,21 +102,16 @@
void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
/// \brief Get number of clauses.
- unsigned getNumClauses() const { return Clauses.size(); }
+ unsigned getNumClauses() const { return NumClauses; }
/// \brief Returns specified clause.
///
/// \param i Number of clause.
///
- OMPClause *getClause(unsigned i) const {
- assert(i < Clauses.size() && "index out of bound!");
- return Clauses[i];
- }
+ OMPClause *getClause(unsigned i) const { return clauses()[i]; }
/// \brief Returns statement associated with the directive.
- Stmt *getAssociatedStmt() const {
- return StmtAndExpressions[0];
- }
+ Stmt *getAssociatedStmt() const { return const_cast<Stmt *>(*child_begin()); }
OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
@@ -460,12 +121,15 @@
}
child_range children() {
- return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end());
+ Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
+ return child_range(ChildStorage, ChildStorage + NumChildren);
}
- ArrayRef<OMPClause *> clauses() { return Clauses; }
+ ArrayRef<OMPClause *> clauses() { return getClauses(); }
- ArrayRef<OMPClause *> clauses() const { return Clauses; }
+ ArrayRef<OMPClause *> clauses() const {
+ return const_cast<OMPExecutableDirective *>(this)->getClauses();
+ }
};
/// \brief This represents '#pragma omp parallel' directive.
@@ -484,17 +148,19 @@
/// \param EndLoc Ending Location of the directive.
///
OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned N)
- : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
- StartLoc, EndLoc, N, 1) { }
+ unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
+ StartLoc, EndLoc, NumClauses, 1) {}
/// \brief Build an empty directive.
///
- /// \param N Number of clauses.
+ /// \param NumClauses Number of clauses.
///
- explicit OMPParallelDirective(unsigned N)
- : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
- SourceLocation(), SourceLocation(), N, 1) { }
+ explicit OMPParallelDirective(unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
+
public:
/// \brief Creates directive with a list of \a Clauses.
///
@@ -504,25 +170,91 @@
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement associated with the directive.
///
- static OMPParallelDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
+ static OMPParallelDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
/// \brief Creates an empty directive with the place for \a N clauses.
///
/// \param C AST context.
- /// \param N The number of clauses.
+ /// \param NumClauses Number of clauses.
///
- static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned N,
- EmptyShell);
+ static OMPParallelDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelDirectiveClass;
}
};
-} // end namespace clang
+/// \brief This represents '#pragma omp simd' directive.
+///
+/// \code
+/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clauses 'private'
+/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
+/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
+///
+class OMPSimdDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief Number of collapsed loops as specified by 'collapse' clause.
+ unsigned CollapsedNum;
+ /// \brief Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
+ EndLoc, NumClauses, 1),
+ CollapsedNum(CollapsedNum) {}
+
+ /// \brief Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
+ : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd,
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1),
+ CollapsedNum(CollapsedNum) {}
+
+public:
+ /// \brief Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt);
+
+ /// \brief Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ unsigned CollapsedNum, EmptyShell);
+
+ unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPSimdDirectiveClass;
+ }
+};
+
+} // end namespace clang
#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 6c40eb1..abe106c 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -34,8 +34,7 @@
class TypeSourceInfo;
class ValueDecl;
-/// \brief Represents a template argument within a class template
-/// specialization.
+/// \brief Represents a template argument.
class TemplateArgument {
public:
/// \brief The kind of template argument we're storing.
@@ -52,16 +51,19 @@
/// was provided for a non-type template parameter.
NullPtr,
/// The template argument is an integral value stored in an llvm::APSInt
- /// that was provided for an integral non-type template parameter.
+ /// that was provided for an integral non-type template parameter.
Integral,
- /// The template argument is a template name that was provided for a
+ /// The template argument is a template name that was provided for a
/// template template parameter.
Template,
- /// The template argument is a pack expansion of a template name that was
+ /// The template argument is a pack expansion of a template name that was
/// provided for a template template parameter.
TemplateExpansion,
- /// The template argument is a value- or type-dependent expression or a
- /// non-dependent __uuidof expression stored in an Expr*.
+ /// The template argument is an expression, and we've not resolved it to one
+ /// of the other forms yet, either because it's dependent or because we're
+ /// representing a non-canonical template argument (for instance, in a
+ /// TemplateSpecializationType). Also used to represent a non-dependent
+ /// __uuidof expression (a Microsoft extension).
Expression,
/// The template argument is actually a parameter pack. Arguments are stored
/// in the Args struct.
@@ -565,7 +567,8 @@
/// Force ASTTemplateArgumentListInfo to the right alignment
/// for the following array of TemplateArgumentLocs.
- void *Aligner;
+ llvm::AlignedCharArray<
+ llvm::AlignOf<TemplateArgumentLoc>::Alignment, 1> Aligner;
};
/// \brief Retrieve the template arguments
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 7995e21..7be6fcd 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -26,12 +26,12 @@
#include "clang/Basic/Visibility.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/type_traits.h"
namespace clang {
enum {
@@ -505,9 +505,9 @@
SplitQualType getSingleStepDesugaredType() const; // end of this file
- // Make llvm::tie work.
- operator std::pair<const Type *,Qualifiers>() const {
- return std::pair<const Type *,Qualifiers>(Ty, Quals);
+ // Make std::tie work.
+ std::pair<const Type *,Qualifiers> asPair() const {
+ return std::pair<const Type *, Qualifiers>(Ty, Quals);
}
friend bool operator==(SplitQualType a, SplitQualType b) {
@@ -1797,7 +1797,7 @@
return CanonicalType;
}
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
- LLVM_ATTRIBUTE_USED void dump() const;
+ void dump() const;
friend class ASTReader;
friend class ASTWriter;
@@ -1996,39 +1996,59 @@
static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
};
-/// \brief Represents a pointer type decayed from an array or function type.
-class DecayedType : public Type, public llvm::FoldingSetNode {
- QualType OriginalType;
- QualType DecayedPointer;
+/// \brief Represents a type which was implicitly adjusted by the semantic
+/// engine for arbitrary reasons. For example, array and function types can
+/// decay, and function types can have their calling conventions adjusted.
+class AdjustedType : public Type, public llvm::FoldingSetNode {
+ QualType OriginalTy;
+ QualType AdjustedTy;
- DecayedType(QualType OriginalType, QualType DecayedPointer,
- QualType CanonicalPtr)
- : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(),
- OriginalType->isInstantiationDependentType(),
- OriginalType->isVariablyModifiedType(),
- OriginalType->containsUnexpandedParameterPack()),
- OriginalType(OriginalType), DecayedPointer(DecayedPointer) {
- assert(isa<PointerType>(DecayedPointer));
+protected:
+ AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
+ QualType CanonicalPtr)
+ : Type(TC, CanonicalPtr, OriginalTy->isDependentType(),
+ OriginalTy->isInstantiationDependentType(),
+ OriginalTy->isVariablyModifiedType(),
+ OriginalTy->containsUnexpandedParameterPack()),
+ OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
+
+ friend class ASTContext; // ASTContext creates these.
+
+public:
+ QualType getOriginalType() const { return OriginalTy; }
+ QualType getAdjustedType() const { return AdjustedTy; }
+
+ bool isSugared() const { return true; }
+ QualType desugar() const { return AdjustedTy; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, OriginalTy, AdjustedTy);
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
+ ID.AddPointer(Orig.getAsOpaquePtr());
+ ID.AddPointer(New.getAsOpaquePtr());
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed;
+ }
+};
+
+/// \brief Represents a pointer type decayed from an array or function type.
+class DecayedType : public AdjustedType {
+
+ DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr)
+ : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
+ assert(isa<PointerType>(getAdjustedType()));
}
friend class ASTContext; // ASTContext creates these.
public:
- QualType getDecayedType() const { return DecayedPointer; }
- QualType getOriginalType() const { return OriginalType; }
+ QualType getDecayedType() const { return getAdjustedType(); }
QualType getPointeeType() const {
- return cast<PointerType>(DecayedPointer)->getPointeeType();
- }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return DecayedPointer; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, OriginalType);
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) {
- ID.AddPointer(OriginalType.getAsOpaquePtr());
+ return cast<PointerType>(getDecayedType())->getPointeeType();
}
static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
@@ -2185,6 +2205,7 @@
}
const Type *getClass() const { return Class; }
+ CXXRecordDecl *getMostRecentCXXRecordDecl() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2758,8 +2779,7 @@
unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
public:
-
- QualType getResultType() const { return ResultType; }
+ QualType getReturnType() const { return ResultType; }
bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
@@ -2776,7 +2796,7 @@
/// \brief Determine the type of an expression that calls a function of
/// this type.
QualType getCallResultType(ASTContext &Context) const {
- return getResultType().getNonLValueExprType(Context);
+ return getReturnType().getNonLValueExprType(Context);
}
static StringRef getNameForCallConv(CallingConv CC);
@@ -2805,7 +2825,7 @@
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getResultType(), getExtInfo());
+ Profile(ID, getReturnType(), getExtInfo());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
ExtInfo Info) {
@@ -2818,27 +2838,26 @@
}
};
-/// FunctionProtoType - Represents a prototype with argument type info, e.g.
+/// FunctionProtoType - Represents a prototype with parameter type info, e.g.
/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
-/// arguments, not as having a single void argument. Such a type can have an
+/// parameters, not as having a single void parameter. Such a type can have an
/// exception specification, but this specification is not part of the canonical
/// type.
class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
public:
/// ExtProtoInfo - Extra information about a function prototype.
struct ExtProtoInfo {
- ExtProtoInfo() :
- Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- ExceptionSpecType(EST_None), RefQualifier(RQ_None),
- NumExceptions(0), Exceptions(0), NoexceptExpr(0),
- ExceptionSpecDecl(0), ExceptionSpecTemplate(0),
- ConsumedArguments(0) {}
+ 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) {}
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), ConsumedArguments(0) {}
+ ExceptionSpecTemplate(0), ConsumedParameters(0) {}
FunctionType::ExtInfo ExtInfo;
bool Variadic : 1;
@@ -2851,7 +2870,7 @@
Expr *NoexceptExpr;
FunctionDecl *ExceptionSpecDecl;
FunctionDecl *ExceptionSpecTemplate;
- const bool *ConsumedArguments;
+ const bool *ConsumedParameters;
};
private:
@@ -2866,11 +2885,11 @@
return false;
}
- FunctionProtoType(QualType result, ArrayRef<QualType> args,
+ FunctionProtoType(QualType result, ArrayRef<QualType> params,
QualType canonical, const ExtProtoInfo &epi);
- /// NumArgs - The number of arguments this function has, not counting '...'.
- unsigned NumArgs : 15;
+ /// The number of parameters this function has, not counting '...'.
+ unsigned NumParams : 15;
/// NumExceptions - The number of types in the exception spec, if any.
unsigned NumExceptions : 9;
@@ -2878,8 +2897,8 @@
/// ExceptionSpecType - The type of exception specification this function has.
unsigned ExceptionSpecType : 3;
- /// HasAnyConsumedArgs - Whether this function has any consumed arguments.
- unsigned HasAnyConsumedArgs : 1;
+ /// HasAnyConsumedParams - Whether this function has any consumed parameters.
+ unsigned HasAnyConsumedParams : 1;
/// Variadic - Whether the function is variadic.
unsigned Variadic : 1;
@@ -2892,8 +2911,8 @@
/// This is a value of type \c RefQualifierKind.
unsigned RefQualifier : 2;
- // ArgInfo - There is an variable size array after the class in memory that
- // holds the argument types.
+ // ParamInfo - There is an variable size array after the class in memory that
+ // holds the parameter types.
// Exceptions - There is another variable size array after ArgInfo that
// holds the exception types.
@@ -2906,17 +2925,17 @@
// instantiate this function type's exception specification, and the function
// from which it should be instantiated.
- // ConsumedArgs - A variable size array, following Exceptions
- // and of length NumArgs, holding flags indicating which arguments
- // are consumed. This only appears if HasAnyConsumedArgs is true.
+ // ConsumedParameters - A variable size array, following Exceptions
+ // and of length NumParams, holding flags indicating which parameters
+ // are consumed. This only appears if HasAnyConsumedParams is true.
friend class ASTContext; // ASTContext creates these.
- const bool *getConsumedArgsBuffer() const {
- assert(hasAnyConsumedArgs());
+ const bool *getConsumedParamsBuffer() const {
+ assert(hasAnyConsumedParams());
// Find the end of the exceptions.
- Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end());
+ Expr *const *eh_end = reinterpret_cast<Expr *const *>(param_type_end());
if (getExceptionSpecType() != EST_ComputedNoexcept)
eh_end += NumExceptions;
else
@@ -2926,13 +2945,13 @@
}
public:
- unsigned getNumArgs() const { return NumArgs; }
- QualType getArgType(unsigned i) const {
- assert(i < NumArgs && "Invalid argument number!");
- return arg_type_begin()[i];
+ unsigned getNumParams() const { return NumParams; }
+ QualType getParamType(unsigned i) const {
+ assert(i < NumParams && "invalid parameter index");
+ return param_type_begin()[i];
}
- ArrayRef<QualType> getArgTypes() const {
- return ArrayRef<QualType>(arg_type_begin(), arg_type_end());
+ ArrayRef<QualType> getParamTypes() const {
+ return ArrayRef<QualType>(param_type_begin(), param_type_end());
}
ExtProtoInfo getExtProtoInfo() const {
@@ -2954,8 +2973,8 @@
} else if (EPI.ExceptionSpecType == EST_Unevaluated) {
EPI.ExceptionSpecDecl = getExceptionSpecDecl();
}
- if (hasAnyConsumedArgs())
- EPI.ConsumedArguments = getConsumedArgsBuffer();
+ if (hasAnyConsumedParams())
+ EPI.ConsumedParameters = getConsumedParamsBuffer();
return EPI;
}
@@ -2994,7 +3013,7 @@
if (getExceptionSpecType() != EST_ComputedNoexcept)
return 0;
// NoexceptExpr sits where the arguments end.
- return *reinterpret_cast<Expr *const *>(arg_type_end());
+ return *reinterpret_cast<Expr *const *>(param_type_end());
}
/// \brief If this function type has an exception specification which hasn't
/// been determined yet (either because it has not been evaluated or because
@@ -3004,7 +3023,7 @@
if (getExceptionSpecType() != EST_Uninstantiated &&
getExceptionSpecType() != EST_Unevaluated)
return 0;
- return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0];
+ return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
}
/// \brief If this function type has an uninstantiated exception
/// specification, this is the function whose exception specification
@@ -3013,17 +3032,12 @@
FunctionDecl *getExceptionSpecTemplate() const {
if (getExceptionSpecType() != EST_Uninstantiated)
return 0;
- return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[1];
+ return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
}
- bool isNothrow(const ASTContext &Ctx) const {
- ExceptionSpecificationType EST = getExceptionSpecType();
- assert(EST != EST_Unevaluated && EST != EST_Uninstantiated);
- if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
- return true;
- if (EST != EST_ComputedNoexcept)
- return false;
- return getNoexceptSpec(Ctx) == NR_Nothrow;
- }
+ /// \brief Determine whether this function type has a non-throwing exception
+ /// specification. If this depends on template arguments, returns
+ /// \c ResultIfDependent.
+ bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const;
bool isVariadic() const { return Variadic; }
@@ -3045,16 +3059,28 @@
return static_cast<RefQualifierKind>(RefQualifier);
}
- typedef const QualType *arg_type_iterator;
- arg_type_iterator arg_type_begin() const {
+ typedef const QualType *param_type_iterator;
+ typedef llvm::iterator_range<param_type_iterator> param_type_range;
+
+ param_type_range param_types() const {
+ return param_type_range(param_type_begin(), param_type_end());
+ }
+ param_type_iterator param_type_begin() const {
return reinterpret_cast<const QualType *>(this+1);
}
- arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
+ param_type_iterator param_type_end() const {
+ return param_type_begin() + NumParams;
+ }
typedef const QualType *exception_iterator;
+ typedef llvm::iterator_range<exception_iterator> exception_range;
+
+ exception_range exceptions() const {
+ return exception_range(exception_begin(), exception_end());
+ }
exception_iterator exception_begin() const {
// exceptions begin where arguments end
- return arg_type_end();
+ return param_type_end();
}
exception_iterator exception_end() const {
if (getExceptionSpecType() != EST_Dynamic)
@@ -3062,13 +3088,11 @@
return exception_begin() + NumExceptions;
}
- bool hasAnyConsumedArgs() const {
- return HasAnyConsumedArgs;
- }
- bool isArgConsumed(unsigned I) const {
- assert(I < getNumArgs() && "argument index out of range!");
- if (hasAnyConsumedArgs())
- return getConsumedArgsBuffer()[I];
+ bool hasAnyConsumedParams() const { return HasAnyConsumedParams; }
+ bool isParamConsumed(unsigned I) const {
+ assert(I < getNumParams() && "parameter index out of range");
+ if (hasAnyConsumedParams())
+ return getConsumedParamsBuffer()[I];
return false;
}
@@ -3084,7 +3108,7 @@
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
- arg_type_iterator ArgTys, unsigned NumArgs,
+ param_type_iterator ArgTys, unsigned NumArgs,
const ExtProtoInfo &EPI, const ASTContext &Context);
};
@@ -4326,7 +4350,9 @@
ObjCInterfaceDecl *getInterface() const;
typedef ObjCProtocolDecl * const *qual_iterator;
+ typedef llvm::iterator_range<qual_iterator> qual_range;
+ qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
qual_iterator qual_begin() const { return getProtocolStorage(); }
qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
@@ -4528,7 +4554,9 @@
/// for convenience. This will always iterate over the full set of
/// protocols on a type, not just those provided directly.
typedef ObjCObjectType::qual_iterator qual_iterator;
+ typedef llvm::iterator_range<qual_iterator> qual_range;
+ qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
qual_iterator qual_begin() const {
return getObjectType()->qual_begin();
}
@@ -5159,10 +5187,9 @@
// Helper class template that is used by Type::getAs to ensure that one does
// not try to look through a qualified type to get to an array type.
-template<typename T,
- bool isArrayType = (llvm::is_same<T, ArrayType>::value ||
- llvm::is_base_of<ArrayType, T>::value)>
-struct ArrayType_cannot_be_used_with_getAs { };
+template <typename T, bool isArrayType = (std::is_same<T, ArrayType>::value ||
+ std::is_base_of<ArrayType, T>::value)>
+struct ArrayType_cannot_be_used_with_getAs {};
template<typename T>
struct ArrayType_cannot_be_used_with_getAs<T, true>;
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 8ddfac7..a54aee8 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -978,12 +978,10 @@
}
-struct DecayedLocInfo { }; // Nothing.
+struct AdjustedLocInfo { }; // Nothing.
-/// \brief Wrapper for source info for pointers decayed from arrays and
-/// functions.
-class DecayedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, DecayedTypeLoc,
- DecayedType, DecayedLocInfo> {
+class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
+ AdjustedType, AdjustedLocInfo> {
public:
TypeLoc getOriginalLoc() const {
return getInnerTypeLoc();
@@ -1004,12 +1002,17 @@
}
unsigned getLocalDataSize() const {
- // sizeof(DecayedLocInfo) is 1, but we don't need its address to be unique
+ // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
// anyway. TypeLocBuilder can't handle data sizes of 1.
return 0; // No data.
}
};
+/// \brief Wrapper for source info for pointers decayed from arrays and
+/// functions.
+class DecayedTypeLoc : public InheritingConcreteTypeLoc<
+ AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
+};
struct PointerLikeLocInfo {
SourceLocation StarLoc;
@@ -1205,23 +1208,23 @@
}
ArrayRef<ParmVarDecl *> getParams() const {
- return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
+ return ArrayRef<ParmVarDecl *>(getParmArray(), getNumParams());
}
- // ParmVarDecls* are stored after Info, one for each argument.
+ // ParmVarDecls* are stored after Info, one for each parameter.
ParmVarDecl **getParmArray() const {
return (ParmVarDecl**) getExtraLocalData();
}
- unsigned getNumArgs() const {
+ unsigned getNumParams() const {
if (isa<FunctionNoProtoType>(getTypePtr()))
return 0;
- return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
+ return cast<FunctionProtoType>(getTypePtr())->getNumParams();
}
- ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
- void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
+ ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
+ void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
- TypeLoc getResultLoc() const {
+ TypeLoc getReturnLoc() const {
return getInnerTypeLoc();
}
@@ -1234,21 +1237,21 @@
setLParenLoc(Loc);
setRParenLoc(Loc);
setLocalRangeEnd(Loc);
- for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
- setArg(i, NULL);
+ for (unsigned i = 0, e = getNumParams(); i != e; ++i)
+ setParam(i, NULL);
}
/// \brief Returns the size of the type source info data block that is
/// specific to this type.
unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(ParmVarDecl*);
+ return getNumParams() * sizeof(ParmVarDecl *);
}
unsigned getExtraLocalDataAlignment() const {
return llvm::alignOf<ParmVarDecl*>();
}
- QualType getInnerType() const { return getTypePtr()->getResultType(); }
+ QualType getInnerType() const { return getTypePtr()->getReturnType(); }
};
class FunctionProtoTypeLoc :
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 3126f48..3b2665b 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -81,7 +81,8 @@
DEPENDENT_TYPE(UnresolvedUsing, Type)
NON_CANONICAL_TYPE(Paren, Type)
NON_CANONICAL_TYPE(Typedef, Type)
-NON_CANONICAL_TYPE(Decayed, Type)
+NON_CANONICAL_TYPE(Adjusted, Type)
+NON_CANONICAL_TYPE(Decayed, AdjustedType)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index 4e45132..02132d8 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -19,8 +19,9 @@
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/ABI.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/DenseSet.h"
+#include <memory>
#include <utility>
namespace clang {
@@ -208,11 +209,11 @@
typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
private:
uint64_t NumVTableComponents;
- llvm::OwningArrayPtr<VTableComponent> VTableComponents;
+ std::unique_ptr<VTableComponent[]> VTableComponents;
/// \brief Contains thunks needed by vtables, sorted by indices.
uint64_t NumVTableThunks;
- llvm::OwningArrayPtr<VTableThunkTy> VTableThunks;
+ std::unique_ptr<VTableThunkTy[]> VTableThunks;
/// \brief Address points for all vtables.
AddressPointsMapTy AddressPoints;
@@ -270,6 +271,10 @@
public:
typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
+ bool isMicrosoft() const { return IsMicrosoftABI; }
+
+ virtual ~VTableContextBase() {}
+
protected:
typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
@@ -280,7 +285,7 @@
/// offset offsets, thunks etc) for the given record decl.
virtual void computeVTableRelatedInformation(const CXXRecordDecl *RD) = 0;
- virtual ~VTableContextBase() {}
+ VTableContextBase(bool MS) : IsMicrosoftABI(MS) {}
public:
virtual const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
@@ -297,11 +302,12 @@
return &I->second;
}
+
+ bool IsMicrosoftABI;
};
class ItaniumVTableContext : public VTableContextBase {
private:
- bool IsMicrosoftABI;
/// \brief Contains the index (relative to the vtable address point)
/// where the function pointer for a virtual function is stored.
@@ -323,7 +329,7 @@
VirtualBaseClassOffsetOffsetsMapTy;
VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
- void computeVTableRelatedInformation(const CXXRecordDecl *RD);
+ void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
public:
ItaniumVTableContext(ASTContext &Context);
@@ -355,49 +361,83 @@
/// Base must be a virtual base class or an unambiguous base.
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
const CXXRecordDecl *VBase);
+
+ static bool classof(const VTableContextBase *VT) {
+ return !VT->isMicrosoft();
+ }
};
-struct VFPtrInfo {
+/// Holds information about the inheritance path to a virtual base or function
+/// table pointer. A record may contain as many vfptrs or vbptrs as there are
+/// base subobjects.
+struct VPtrInfo {
typedef SmallVector<const CXXRecordDecl *, 1> BasePath;
- // Don't pass the PathToMangle as it should be calculated later.
- VFPtrInfo(CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr)
- : VBTableIndex(0), LastVBase(0), VFPtrOffset(VFPtrOffset),
- PathToBaseWithVFPtr(PathToBaseWithVFPtr), VFPtrFullOffset(VFPtrOffset) {
- }
+ VPtrInfo(const CXXRecordDecl *RD)
+ : ReusingBase(RD), BaseWithVPtr(RD), NextBaseToMangle(RD) {}
- // Don't pass the PathToMangle as it should be calculated later.
- VFPtrInfo(uint64_t VBTableIndex, const CXXRecordDecl *LastVBase,
- CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr,
- CharUnits VFPtrFullOffset)
- : VBTableIndex(VBTableIndex), LastVBase(LastVBase),
- VFPtrOffset(VFPtrOffset), PathToBaseWithVFPtr(PathToBaseWithVFPtr),
- VFPtrFullOffset(VFPtrFullOffset) {
- assert(VBTableIndex && "The full constructor should only be used "
- "for vfptrs in virtual bases");
- assert(LastVBase);
- }
+ // Copy constructor.
+ // FIXME: Uncomment when we've moved to C++11.
+ // VPtrInfo(const VPtrInfo &) = default;
- /// If nonzero, holds the vbtable index of the virtual base with the vfptr.
- uint64_t VBTableIndex;
+ /// The vtable will hold all of the virtual bases or virtual methods of
+ /// ReusingBase. This may or may not be the same class as VPtrSubobject.Base.
+ /// A derived class will reuse the vptr of the first non-virtual base
+ /// subobject that has one.
+ const CXXRecordDecl *ReusingBase;
- /// Stores the last vbase on the path from the complete type to the vfptr.
- const CXXRecordDecl *LastVBase;
+ /// BaseWithVPtr is at this offset from its containing complete object or
+ /// virtual base.
+ CharUnits NonVirtualOffset;
- /// This is the offset of the vfptr from the start of the last vbase,
- /// or the complete type if there are no virtual bases.
- CharUnits VFPtrOffset;
+ /// The vptr is stored inside this subobject.
+ const CXXRecordDecl *BaseWithVPtr;
+
+ /// The bases from the inheritance path that got used to mangle the vbtable
+ /// name. This is not really a full path like a CXXBasePath. It holds the
+ /// subset of records that need to be mangled into the vbtable symbol name in
+ /// order to get a unique name.
+ BasePath MangledPath;
+
+ /// The next base to push onto the mangled path if this path is ambiguous in a
+ /// derived class. If it's null, then it's already been pushed onto the path.
+ const CXXRecordDecl *NextBaseToMangle;
+
+ /// The set of possibly indirect vbases that contain this vbtable. When a
+ /// derived class indirectly inherits from the same vbase twice, we only keep
+ /// vtables and their paths from the first instance.
+ BasePath ContainingVBases;
/// This holds the base classes path from the complete type to the first base
- /// with the given vfptr offset, in the base-to-derived order.
- BasePath PathToBaseWithVFPtr;
+ /// with the given vfptr offset, in the base-to-derived order. Only used for
+ /// vftables.
+ BasePath PathToBaseWithVPtr;
- /// This holds the subset of records that need to be mangled into the vftable
- /// symbol name in order to get a unique name, in the derived-to-base order.
- BasePath PathToMangle;
+ /// Static offset from the top of the most derived class to this vfptr,
+ /// including any virtual base offset. Only used for vftables.
+ CharUnits FullOffsetInMDC;
- /// This is the full offset of the vfptr from the start of the complete type.
- CharUnits VFPtrFullOffset;
+ /// The vptr is stored inside the non-virtual component of this virtual base.
+ const CXXRecordDecl *getVBaseWithVPtr() const {
+ return ContainingVBases.empty() ? 0 : ContainingVBases.front();
+ }
+};
+
+typedef SmallVector<VPtrInfo *, 2> VPtrInfoVector;
+
+/// All virtual base related information about a given record decl. Includes
+/// information on all virtual base tables and the path components that are used
+/// to mangle them.
+struct VirtualBaseInfo {
+ ~VirtualBaseInfo() { llvm::DeleteContainerPointers(VBPtrPaths); }
+
+ /// A map from virtual base to vbtable index for doing a conversion from the
+ /// the derived class to the a base.
+ llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
+
+ /// Information on all virtual base tables used when this record is the most
+ /// derived class.
+ VPtrInfoVector VBPtrPaths;
};
class MicrosoftVTableContext : public VTableContextBase {
@@ -431,16 +471,11 @@
assert(VBase != other.VBase);
return VBTableIndex < other.VBTableIndex;
}
- if (VFPtrOffset != other.VFPtrOffset)
- return VFPtrOffset < other.VFPtrOffset;
- if (Index != other.Index)
- return Index < other.Index;
- return false;
+ return std::tie(VFPtrOffset, Index) <
+ std::tie(other.VFPtrOffset, other.Index);
}
};
- typedef SmallVector<VFPtrInfo, 1> VFPtrListTy;
-
private:
ASTContext &Context;
@@ -448,7 +483,7 @@
MethodVFTableLocationsTy;
MethodVFTableLocationsTy MethodVFTableLocations;
- typedef llvm::DenseMap<const CXXRecordDecl *, VFPtrListTy>
+ typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector *>
VFPtrLocationsMapTy;
VFPtrLocationsMapTy VFPtrLocations;
@@ -456,43 +491,36 @@
typedef llvm::DenseMap<VFTableIdTy, const VTableLayout *> VFTableLayoutMapTy;
VFTableLayoutMapTy VFTableLayouts;
- typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> BasesSetVectorTy;
- void enumerateVFPtrs(const CXXRecordDecl *MostDerivedClass,
- const ASTRecordLayout &MostDerivedClassLayout,
- BaseSubobject Base, const CXXRecordDecl *LastVBase,
- const VFPtrInfo::BasePath &PathFromCompleteClass,
- BasesSetVectorTy &VisitedVBases,
- MicrosoftVTableContext::VFPtrListTy &Result);
+ llvm::DenseMap<const CXXRecordDecl *, VirtualBaseInfo *> VBaseInfo;
- void enumerateVFPtrs(const CXXRecordDecl *ForClass,
- MicrosoftVTableContext::VFPtrListTy &Result);
+ void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
- void computeVTableRelatedInformation(const CXXRecordDecl *RD);
+ void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
void dumpMethodLocations(const CXXRecordDecl *RD,
const MethodVFTableLocationsTy &NewMethods,
raw_ostream &);
- typedef std::pair<const CXXRecordDecl *, const CXXRecordDecl *> ClassPairTy;
- typedef llvm::DenseMap<ClassPairTy, unsigned> VBTableIndicesTy;
- VBTableIndicesTy VBTableIndices;
- llvm::DenseSet<const CXXRecordDecl *> ComputedVBTableIndices;
+ const VirtualBaseInfo *
+ computeVBTableRelatedInformation(const CXXRecordDecl *RD);
- void computeVBTableRelatedInformation(const CXXRecordDecl *RD);
+ void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,
+ VPtrInfoVector &Paths);
public:
- MicrosoftVTableContext(ASTContext &Context) : Context(Context) {}
+ MicrosoftVTableContext(ASTContext &Context)
+ : VTableContextBase(/*MS=*/true), Context(Context) {}
- ~MicrosoftVTableContext() { llvm::DeleteContainerSeconds(VFTableLayouts); }
+ ~MicrosoftVTableContext();
- const VFPtrListTy &getVFPtrOffsets(const CXXRecordDecl *RD);
+ const VPtrInfoVector &getVFPtrOffsets(const CXXRecordDecl *RD);
const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD,
CharUnits VFPtrOffset);
const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD);
- const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
+ const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) override {
// Complete destructors don't have a slot in a vftable, so no thunks needed.
if (isa<CXXDestructorDecl>(GD.getDecl()) &&
GD.getDtorType() == Dtor_Complete)
@@ -505,14 +533,13 @@
/// The vbtable is an array of i32 offsets. The first entry is a self entry,
/// and the rest are offsets from the vbptr to virtual bases.
unsigned getVBTableIndex(const CXXRecordDecl *Derived,
- const CXXRecordDecl *VBase) {
- computeVBTableRelatedInformation(Derived);
- ClassPairTy Pair(Derived, VBase);
- assert(VBTableIndices.count(Pair) == 1 &&
- "VBase must be a vbase of Derived");
- return VBTableIndices[Pair];
- }
+ const CXXRecordDecl *VBase);
+
+ const VPtrInfoVector &enumerateVBTables(const CXXRecordDecl *RD);
+
+ static bool classof(const VTableContextBase *VT) { return VT->isMicrosoft(); }
};
-}
+
+} // namespace clang
#endif
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index db0a83d..8c8a509 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -228,7 +228,7 @@
namespace internal {
class CollectMatchesCallback : public MatchFinder::MatchCallback {
public:
- virtual void run(const MatchFinder::MatchResult &Result) {
+ void run(const MatchFinder::MatchResult &Result) override {
Nodes.push_back(Result.Nodes);
}
SmallVector<BoundNodes, 1> Nodes;
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 0a3157d..15621b7 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -323,9 +323,13 @@
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
/// refersToType(asString("int"))))
/// matches the specialization \c A<int>
-AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument,
- internal::Matcher<TemplateArgument>, InnerMatcher) {
- llvm::ArrayRef<TemplateArgument> List = Node.getTemplateArgs().asArray();
+AST_POLYMORPHIC_MATCHER_P(
+ hasAnyTemplateArgument,
+ AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
+ TemplateSpecializationType),
+ internal::Matcher<TemplateArgument>, InnerMatcher) {
+ llvm::ArrayRef<TemplateArgument> List =
+ internal::getTemplateSpecializationArgs(Node);
return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
Builder);
}
@@ -419,12 +423,16 @@
/// classTemplateSpecializationDecl(hasTemplateArgument(
/// 1, refersToType(asString("int"))))
/// matches the specialization \c A<bool, int>
-AST_MATCHER_P2(ClassTemplateSpecializationDecl, hasTemplateArgument,
- unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
- const TemplateArgumentList &List = Node.getTemplateArgs();
+AST_POLYMORPHIC_MATCHER_P2(
+ hasTemplateArgument,
+ AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
+ TemplateSpecializationType),
+ unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
+ llvm::ArrayRef<TemplateArgument> List =
+ internal::getTemplateSpecializationArgs(Node);
if (List.size() <= N)
return false;
- return InnerMatcher.matches(List.get(N), Finder, Builder);
+ return InnerMatcher.matches(List[N], Finder, Builder);
}
/// \brief Matches a TemplateArgument that refers to a certain type.
@@ -445,7 +453,8 @@
return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
}
-/// \brief Matches a TemplateArgument that refers to a certain declaration.
+/// \brief Matches a canonical TemplateArgument that refers to a certain
+/// declaration.
///
/// Given
/// \code
@@ -464,6 +473,24 @@
return false;
}
+/// \brief Matches a sugar TemplateArgument that refers to a certain expression.
+///
+/// Given
+/// \code
+/// template<typename T> struct A {};
+/// struct B { B* next; };
+/// A<&B::next> a;
+/// \endcode
+/// templateSpecializationType(hasAnyTemplateArgument(
+/// isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
+/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
+/// \c B::next
+AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher) {
+ if (Node.getKind() == TemplateArgument::Expression)
+ return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
+ return false;
+}
+
/// \brief Matches C++ constructor declarations.
///
/// Example matches Foo::Foo() and Foo::Foo(int)
@@ -518,7 +545,7 @@
///
/// Example matches y
/// \code
-/// class X { void y() };
+/// class X { void y(); };
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl;
@@ -635,6 +662,16 @@
Stmt,
CXXMemberCallExpr> memberCallExpr;
+/// \brief Matches expressions that introduce cleanups to be run at the end
+/// of the sub-expression's evaluation.
+///
+/// Example matches std::string()
+/// \code
+/// const std::string str = std::string();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
+exprWithCleanups;
+
/// \brief Matches init list expressions.
///
/// Given
@@ -842,15 +879,6 @@
/// \endcode
const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
-/// \brief Matches range-based for statements.
-///
-/// forRangeStmt() matches 'for (auto a : i)'
-/// \code
-/// int i[] = {1, 2, 3}; for (auto a : i);
-/// for(int j = 0; j < 5; ++j);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt;
-
/// \brief Matches the increment statement of a for loop.
///
/// Example:
@@ -880,6 +908,29 @@
return (Init != NULL && InnerMatcher.matches(*Init, Finder, Builder));
}
+/// \brief Matches range-based for statements.
+///
+/// forRangeStmt() matches 'for (auto a : i)'
+/// \code
+/// int i[] = {1, 2, 3}; for (auto a : i);
+/// for(int j = 0; j < 5; ++j);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt;
+
+/// \brief Matches the initialization statement of a for loop.
+///
+/// Example:
+/// forStmt(hasLoopVariable(anything()))
+/// matches 'int x' in
+/// \code
+/// for (int x : a) { }
+/// \endcode
+AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>,
+ InnerMatcher) {
+ const VarDecl *const Var = Node.getLoopVariable();
+ return (Var != NULL && InnerMatcher.matches(*Var, Finder, Builder));
+}
+
/// \brief Matches while statements.
///
/// Given
@@ -1317,21 +1368,21 @@
/// \c b.
///
/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc eachOf = {
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
internal::EachOfVariadicOperator
};
/// \brief Matches if any of the given matchers matches.
///
/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc anyOf = {
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
internal::AnyOfVariadicOperator
};
/// \brief Matches if all given matchers match.
///
/// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc allOf = {
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
internal::AllOfVariadicOperator
};
@@ -1671,12 +1722,9 @@
/// \endcode
///
/// Usable as: Any Matcher
-template <typename M>
-internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M>
-unless(const M &InnerMatcher) {
- return internal::PolymorphicMatcherWithParam1<
- internal::NotMatcher, M>(InnerMatcher);
-}
+const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
+ internal::NotUnaryOperator
+};
/// \brief Matches a node if the declaration associated with that node
/// matches the given matcher.
@@ -2175,6 +2223,11 @@
return false;
}
+/// \brief Matches a constructor call expression which uses list initialization.
+AST_MATCHER(CXXConstructExpr, isListInitialization) {
+ return Node.isListInitialization();
+}
+
/// \brief Matches the n'th parameter of a function declaration.
///
/// Given
@@ -2234,7 +2287,7 @@
/// matches int f() { return 1; }
AST_MATCHER_P(FunctionDecl, returns,
internal::Matcher<QualType>, InnerMatcher) {
- return InnerMatcher.matches(Node.getResultType(), Finder, Builder);
+ return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
}
/// \brief Matches extern "C" function declarations.
@@ -2267,16 +2320,6 @@
InnerMatcher.matches(*Condition, Finder, Builder));
}
-namespace internal {
-struct NotEqualsBoundNodePredicate {
- bool operator()(const internal::BoundNodesMap &Nodes) const {
- return Nodes.getNode(ID) != Node;
- }
- std::string ID;
- ast_type_traits::DynTypedNode Node;
-};
-} // namespace internal
-
/// \brief Matches if a node equals a previously bound node.
///
/// Matches a node if it equals the node previously bound to \p ID.
@@ -2603,6 +2646,20 @@
return Node.isVirtual();
}
+/// \brief Matches if the given method declaration is pure.
+///
+/// Given
+/// \code
+/// class A {
+/// public:
+/// virtual void x() = 0;
+/// };
+/// \endcode
+/// matches A::x
+AST_MATCHER(CXXMethodDecl, isPure) {
+ return Node.isPure();
+}
+
/// \brief Matches if the given method declaration is const.
///
/// Given
@@ -2822,8 +2879,8 @@
/// \brief Matches \c TypeLocs for which the given inner
/// QualType-matcher matches.
-inline internal::BindableMatcher<TypeLoc> loc(
- const internal::Matcher<QualType> &InnerMatcher) {
+AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc,
+ internal::Matcher<QualType>, InnerMatcher, 0) {
return internal::BindableMatcher<TypeLoc>(
new internal::TypeLocTypeMatcher(InnerMatcher));
}
@@ -3306,8 +3363,9 @@
/// \brief Matches \c NestedNameSpecifierLocs for which the given inner
/// NestedNameSpecifier-matcher matches.
-inline internal::BindableMatcher<NestedNameSpecifierLoc> loc(
- const internal::Matcher<NestedNameSpecifier> &InnerMatcher) {
+AST_MATCHER_FUNCTION_P_OVERLOAD(
+ internal::BindableMatcher<NestedNameSpecifierLoc>, loc,
+ internal::Matcher<NestedNameSpecifier>, InnerMatcher, 1) {
return internal::BindableMatcher<NestedNameSpecifierLoc>(
new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>(
InnerMatcher));
@@ -3343,7 +3401,7 @@
/// matches "A::"
AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
internal::Matcher<TypeLoc>, InnerMatcher) {
- return InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
+ return Node && InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
}
/// \brief Matches on the prefix of a \c NestedNameSpecifier.
@@ -3463,11 +3521,9 @@
internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
BoundNodesTreeBuilder Result;
bool Matched = false;
- for (CXXConstructorDecl::init_const_iterator I = Node.init_begin(),
- E = Node.init_end();
- I != E; ++I) {
+ for (const auto *I : Node.inits()) {
BoundNodesTreeBuilder InitBuilder(*Builder);
- if (InnerMatcher.matches(**I, Finder, &InitBuilder)) {
+ if (InnerMatcher.matches(*I, Finder, &InitBuilder)) {
Matched = true;
Result.addMatch(InitBuilder);
}
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 69cee2e..23885a1 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -44,7 +44,6 @@
#include "clang/AST/Type.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/VariadicFunction.h"
-#include "llvm/Support/type_traits.h"
#include <map>
#include <string>
#include <vector>
@@ -52,11 +51,6 @@
namespace clang {
namespace ast_matchers {
-/// FIXME: Move into the llvm support library.
-template <bool> struct CompileAssert {};
-#define TOOLING_COMPILE_ASSERT(Expr, Msg) \
- typedef CompileAssert<(bool(Expr))> Msg[bool(Expr) ? 1 : -1]
-
class BoundNodes;
namespace internal {
@@ -198,9 +192,9 @@
private:
/// Implements MatcherInterface::Matches.
- virtual bool matches(const T &Node,
- ASTMatchFinder * /* Finder */,
- BoundNodesTreeBuilder * /* Builder */) const {
+ bool matches(const T &Node,
+ ASTMatchFinder * /* Finder */,
+ BoundNodesTreeBuilder * /* Builder */) const override {
return matchesNode(Node);
}
};
@@ -225,9 +219,8 @@
/// Requires \c T to be derived from \c From.
template <typename From>
Matcher(const Matcher<From> &Other,
- typename llvm::enable_if_c<
- llvm::is_base_of<From, T>::value &&
- !llvm::is_same<From, T>::value >::type* = 0)
+ typename std::enable_if<std::is_base_of<From, T>::value &&
+ !std::is_same<From, T>::value>::type * = 0)
: Implementation(new ImplicitCastMatcher<From>(Other)) {}
/// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
@@ -235,9 +228,9 @@
/// The resulting matcher is not strict, i.e. ignores qualifiers.
template <typename TypeT>
Matcher(const Matcher<TypeT> &Other,
- typename llvm::enable_if_c<
- llvm::is_same<T, QualType>::value &&
- llvm::is_same<TypeT, Type>::value >::type* = 0)
+ typename std::enable_if<
+ std::is_same<T, QualType>::value &&
+ std::is_same<TypeT, Type>::value>::type* = 0)
: Implementation(new TypeToQualType<TypeT>(Other)) {}
/// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
@@ -272,9 +265,8 @@
TypeToQualType(const Matcher<TypeT> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- virtual bool matches(const QualType &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const QualType &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
if (Node.isNull())
return false;
return InnerMatcher.matches(*Node, Finder, Builder);
@@ -292,9 +284,8 @@
explicit ImplicitCastMatcher(const Matcher<Base> &From)
: From(From) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return From.matches(Node, Finder, Builder);
}
@@ -379,9 +370,7 @@
/// matcher can handle a value of T.
///
/// If it is not compatible, then this matcher will never match anything.
- template <typename T> Matcher<T> unconditionalConvertTo() const {
- return Matcher<T>(new WrappedMatcher<T>(*this));
- }
+ template <typename T> Matcher<T> unconditionalConvertTo() const;
private:
class MatcherStorage : public RefCountedBaseVPTR {
@@ -410,9 +399,6 @@
/// \brief Typed implementation of \c MatcherStorage.
template <typename T> class TypedMatcherStorage;
- /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher.
- template <typename T> class WrappedMatcher;
-
IntrusiveRefCntPtr<const MatcherStorage> Storage;
};
@@ -425,15 +411,15 @@
InnerMatcher(Other), AllowBind(AllowBind) {}
bool matches(const ast_type_traits::DynTypedNode DynNode,
- ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const
- LLVM_OVERRIDE {
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
if (const T *Node = DynNode.get<T>()) {
return InnerMatcher.matches(*Node, Finder, Builder);
}
return false;
}
- llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const LLVM_OVERRIDE {
+ llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const override {
if (!AllowBind)
return llvm::Optional<DynTypedMatcher>();
return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID));
@@ -452,22 +438,6 @@
inline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M)
: Storage(new TypedMatcherStorage<T>(M, true)) {}
-template <typename T>
-class DynTypedMatcher::WrappedMatcher : public MatcherInterface<T> {
-public:
- explicit WrappedMatcher(const DynTypedMatcher &Matcher) : Inner(Matcher) {}
- virtual ~WrappedMatcher() {}
-
- bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- return Inner.matches(ast_type_traits::DynTypedNode::create(Node), Finder,
- Builder);
- }
-
-private:
- const DynTypedMatcher Inner;
-};
-
/// \brief Specialization of the conversion functions for QualType.
///
/// These specializations provide the Matcher<Type>->Matcher<QualType>
@@ -546,16 +516,17 @@
/// PolymorphicMatcherWithParam1 and should be StringRef.
template <typename T, typename ArgT>
class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
- TOOLING_COMPILE_ASSERT((llvm::is_same<T, CXXOperatorCallExpr>::value ||
- llvm::is_same<T, CXXMethodDecl>::value),
- unsupported_class_for_matcher);
- TOOLING_COMPILE_ASSERT((llvm::is_same<ArgT, StringRef>::value),
- argument_type_must_be_StringRef);
+ static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
+ std::is_same<T, CXXMethodDecl>::value,
+ "unsupported class for matcher");
+ static_assert(std::is_same<ArgT, StringRef>::value,
+ "argument type must be StringRef");
+
public:
explicit HasOverloadedOperatorNameMatcher(const StringRef Name)
: SingleNodeMatcherInterface<T>(), Name(Name) {}
- virtual bool matchesNode(const T &Node) const LLVM_OVERRIDE {
+ bool matchesNode(const T &Node) const override {
return matchesSpecialized(Node);
}
@@ -584,16 +555,15 @@
/// not actually used.
template <typename T, typename DeclMatcherT>
class HasDeclarationMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT((llvm::is_same< DeclMatcherT,
- Matcher<Decl> >::value),
- instantiated_with_wrong_types);
+ static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
+ "instantiated with wrong types");
+
public:
explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return matchesSpecialized(Node, Finder, Builder);
}
@@ -603,7 +573,7 @@
template <typename U>
bool matchesSpecialized(
const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
- typename llvm::enable_if<has_getDecl<U>, int>::type = 0) const {
+ typename std::enable_if<has_getDecl<U>::value, int>::type = 0) const {
return matchesDecl(Node.getDecl(), Finder, Builder);
}
@@ -667,14 +637,14 @@
template <typename T>
struct IsBaseType {
static const bool value =
- (llvm::is_same<T, Decl>::value ||
- llvm::is_same<T, Stmt>::value ||
- llvm::is_same<T, QualType>::value ||
- llvm::is_same<T, Type>::value ||
- llvm::is_same<T, TypeLoc>::value ||
- llvm::is_same<T, NestedNameSpecifier>::value ||
- llvm::is_same<T, NestedNameSpecifierLoc>::value ||
- llvm::is_same<T, CXXCtorInitializer>::value);
+ std::is_same<T, Decl>::value ||
+ std::is_same<T, Stmt>::value ||
+ std::is_same<T, QualType>::value ||
+ std::is_same<T, Type>::value ||
+ std::is_same<T, TypeLoc>::value ||
+ std::is_same<T, NestedNameSpecifier>::value ||
+ std::is_same<T, NestedNameSpecifierLoc>::value ||
+ std::is_same<T, CXXCtorInitializer>::value;
};
template <typename T>
const bool IsBaseType<T>::value;
@@ -740,14 +710,13 @@
BoundNodesTreeBuilder *Builder,
TraversalKind Traverse,
BindKind Bind) {
- TOOLING_COMPILE_ASSERT(
- (llvm::is_base_of<Decl, T>::value ||
- llvm::is_base_of<Stmt, T>::value ||
- llvm::is_base_of<NestedNameSpecifier, T>::value ||
- llvm::is_base_of<NestedNameSpecifierLoc, T>::value ||
- llvm::is_base_of<TypeLoc, T>::value ||
- llvm::is_base_of<QualType, T>::value),
- unsupported_type_for_recursive_matching);
+ static_assert(std::is_base_of<Decl, T>::value ||
+ std::is_base_of<Stmt, T>::value ||
+ std::is_base_of<NestedNameSpecifier, T>::value ||
+ std::is_base_of<NestedNameSpecifierLoc, T>::value ||
+ std::is_base_of<TypeLoc, T>::value ||
+ std::is_base_of<QualType, T>::value,
+ "unsupported type for recursive matching");
return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, Traverse, Bind);
}
@@ -757,14 +726,13 @@
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
BindKind Bind) {
- TOOLING_COMPILE_ASSERT(
- (llvm::is_base_of<Decl, T>::value ||
- llvm::is_base_of<Stmt, T>::value ||
- llvm::is_base_of<NestedNameSpecifier, T>::value ||
- llvm::is_base_of<NestedNameSpecifierLoc, T>::value ||
- llvm::is_base_of<TypeLoc, T>::value ||
- llvm::is_base_of<QualType, T>::value),
- unsupported_type_for_recursive_matching);
+ static_assert(std::is_base_of<Decl, T>::value ||
+ std::is_base_of<Stmt, T>::value ||
+ std::is_base_of<NestedNameSpecifier, T>::value ||
+ std::is_base_of<NestedNameSpecifierLoc, T>::value ||
+ std::is_base_of<TypeLoc, T>::value ||
+ std::is_base_of<QualType, T>::value,
+ "unsupported type for recursive matching");
return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, Bind);
}
@@ -775,9 +743,9 @@
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) {
- TOOLING_COMPILE_ASSERT((llvm::is_base_of<Decl, T>::value ||
- llvm::is_base_of<Stmt, T>::value),
- only_Decl_or_Stmt_allowed_for_recursive_matching);
+ static_assert(std::is_base_of<Decl, T>::value ||
+ std::is_base_of<Stmt, T>::value,
+ "only Decl or Stmt allowed for recursive matching");
return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
Matcher, Builder, MatchMode);
}
@@ -820,7 +788,7 @@
/// \brief The first type on the list.
typedef T1 head;
- /// \brief A sub list with the tail. ie everything but the head.
+ /// \brief A sublist with the tail. ie everything but the head.
///
/// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
/// end of the list.
@@ -852,7 +820,7 @@
template <typename AnyTypeList, typename T>
struct TypeListContainsSuperOf {
static const bool value =
- llvm::is_base_of<typename AnyTypeList::head, T>::value ||
+ std::is_base_of<typename AnyTypeList::head, T>::value ||
TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
};
template <typename T>
@@ -952,8 +920,8 @@
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
template <typename T>
operator Matcher<T>() const {
- TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
- right_polymorphic_conversion);
+ static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+ "right polymorphic conversion");
return Matcher<T>(new MatcherT<T>());
}
};
@@ -970,8 +938,8 @@
template <typename T>
operator Matcher<T>() const {
- TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
- right_polymorphic_conversion);
+ static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+ "right polymorphic conversion");
return Matcher<T>(new MatcherT<T, P1>(Param1));
}
@@ -991,8 +959,8 @@
template <typename T>
operator Matcher<T>() const {
- TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
- right_polymorphic_conversion);
+ static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+ "right polymorphic conversion");
return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
}
@@ -1018,7 +986,7 @@
template <typename T>
class TrueMatcher : public SingleNodeMatcherInterface<T> {
public:
- virtual bool matchesNode(const T &Node) const {
+ bool matchesNode(const T &Node) const override {
return true;
}
};
@@ -1033,9 +1001,8 @@
IdMatcher(StringRef ID, const Matcher<T> &InnerMatcher)
: ID(ID), InnerMatcher(InnerMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
bool Result = InnerMatcher.matches(Node, Finder, Builder);
if (Result) {
Builder->setBinding(ID, &Node);
@@ -1074,15 +1041,15 @@
/// ChildT must be an AST base type.
template <typename T, typename ChildT>
class HasMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<ChildT>::value,
- has_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<ChildT>::value,
+ "has only accepts base type matcher");
+
public:
explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
: ChildMatcher(ChildMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesChildOf(
Node, ChildMatcher, Builder,
ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
@@ -1100,15 +1067,15 @@
/// for each child that matches.
template <typename T, typename ChildT>
class ForEachMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<ChildT>::value,
- for_each_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<ChildT>::value,
+ "for each only accepts base type matcher");
+
public:
explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher)
: ChildMatcher(ChildMatcher) {}
- virtual bool matches(const T& Node,
- ASTMatchFinder* Finder,
- BoundNodesTreeBuilder* Builder) const {
+ bool matches(const T& Node, ASTMatchFinder* Finder,
+ BoundNodesTreeBuilder* Builder) const override {
return Finder->matchesChildOf(
Node, ChildMatcher, Builder,
ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
@@ -1119,38 +1086,6 @@
const Matcher<ChildT> ChildMatcher;
};
-/// \brief Matches nodes of type T if the given Matcher<T> does not match.
-///
-/// Type argument MatcherT is required by PolymorphicMatcherWithParam1
-/// but not actually used. It will always be instantiated with a type
-/// convertible to Matcher<T>.
-template <typename T, typename MatcherT>
-class NotMatcher : public MatcherInterface<T> {
-public:
- explicit NotMatcher(const Matcher<T> &InnerMatcher)
- : InnerMatcher(InnerMatcher) {}
-
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
- // The 'unless' matcher will always discard the result:
- // If the inner matcher doesn't match, unless returns true,
- // but the inner matcher cannot have bound anything.
- // If the inner matcher matches, the result is false, and
- // any possible binding will be discarded.
- // We still need to hand in all the bound nodes up to this
- // point so the inner matcher can depend on bound nodes,
- // and we need to actively discard the bound nodes, otherwise
- // the inner matcher will reset the bound nodes if it doesn't
- // match, but this would be inversed by 'unless'.
- BoundNodesTreeBuilder Discard(*Builder);
- return !InnerMatcher.matches(Node, Finder, &Discard);
- }
-
-private:
- const Matcher<T> InnerMatcher;
-};
-
/// \brief VariadicOperatorMatcher related types.
/// @{
@@ -1165,22 +1100,18 @@
class VariadicOperatorMatcherInterface : public MatcherInterface<T> {
public:
VariadicOperatorMatcherInterface(VariadicOperatorFunction Func,
- ArrayRef<const Matcher<T> *> InputMatchers)
- : Func(Func) {
- for (size_t i = 0, e = InputMatchers.size(); i != e; ++i) {
- InnerMatchers.push_back(*InputMatchers[i]);
- }
- }
+ std::vector<DynTypedMatcher> InnerMatchers)
+ : Func(Func), InnerMatchers(std::move(InnerMatchers)) {}
- virtual bool matches(const T &Node, ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder,
InnerMatchers);
}
private:
const VariadicOperatorFunction Func;
- std::vector<DynTypedMatcher> InnerMatchers;
+ const std::vector<DynTypedMatcher> InnerMatchers;
};
/// \brief "No argument" placeholder to use as template paratemers.
@@ -1192,14 +1123,14 @@
/// Input matchers can have any type (including other polymorphic matcher
/// types), and the actual Matcher<T> is generated on demand with an implicit
/// coversion operator.
-template <typename P1, typename P2,
+template <typename P1, typename P2 = VariadicOperatorNoArg,
typename P3 = VariadicOperatorNoArg,
typename P4 = VariadicOperatorNoArg,
typename P5 = VariadicOperatorNoArg>
class VariadicOperatorMatcher {
public:
VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1,
- const P2 &Param2,
+ const P2 &Param2 = VariadicOperatorNoArg(),
const P3 &Param3 = VariadicOperatorNoArg(),
const P4 &Param4 = VariadicOperatorNoArg(),
const P5 &Param5 = VariadicOperatorNoArg())
@@ -1207,31 +1138,27 @@
Param4(Param4), Param5(Param5) {}
template <typename T> operator Matcher<T>() const {
- Matcher<T> *Array[5];
- size_t Size = 0;
-
- addMatcher<T>(Param1, Array, Size);
- addMatcher<T>(Param2, Array, Size);
- addMatcher<T>(Param3, Array, Size);
- addMatcher<T>(Param4, Array, Size);
- addMatcher<T>(Param5, Array, Size);
- Matcher<T> Result(new VariadicOperatorMatcherInterface<T>(
- Func, ArrayRef<const Matcher<T> *>(Array, Size)));
- for (size_t i = 0, e = Size; i != e; ++i) delete Array[i];
- return Result;
+ std::vector<DynTypedMatcher> Matchers;
+ addMatcher<T>(Param1, Matchers);
+ addMatcher<T>(Param2, Matchers);
+ addMatcher<T>(Param3, Matchers);
+ addMatcher<T>(Param4, Matchers);
+ addMatcher<T>(Param5, Matchers);
+ return Matcher<T>(
+ new VariadicOperatorMatcherInterface<T>(Func, std::move(Matchers)));
}
private:
template <typename T>
- static void addMatcher(const Matcher<T> &M, Matcher<T> **Array,
- size_t &Size) {
- Array[Size++] = new Matcher<T>(M);
+ static void addMatcher(const Matcher<T> &M,
+ std::vector<DynTypedMatcher> &Matchers) {
+ Matchers.push_back(M);
}
/// \brief Overload to ignore \c VariadicOperatorNoArg arguments.
template <typename T>
- static void addMatcher(VariadicOperatorNoArg, Matcher<T> **Array,
- size_t &Size) {}
+ static void addMatcher(VariadicOperatorNoArg,
+ std::vector<DynTypedMatcher> &Matchers) {}
const VariadicOperatorFunction Func;
const P1 Param1;
@@ -1244,26 +1171,38 @@
/// \brief Overloaded function object to generate VariadicOperatorMatcher
/// objects from arbitrary matchers.
///
-/// It supports 2-5 argument overloaded operator(). More can be added if needed.
+/// It supports 1-5 argument overloaded operator(). More can be added if needed.
+template <unsigned MinCount, unsigned MaxCount>
struct VariadicOperatorMatcherFunc {
VariadicOperatorFunction Func;
+ template <unsigned Count, typename T>
+ struct EnableIfValidArity
+ : public std::enable_if<MinCount <= Count && Count <= MaxCount, T> {};
+
+ template <typename M1>
+ typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type
+ operator()(const M1 &P1) const {
+ return VariadicOperatorMatcher<M1>(Func, P1);
+ }
template <typename M1, typename M2>
- VariadicOperatorMatcher<M1, M2> operator()(const M1 &P1, const M2 &P2) const {
+ typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type
+ operator()(const M1 &P1, const M2 &P2) const {
return VariadicOperatorMatcher<M1, M2>(Func, P1, P2);
}
template <typename M1, typename M2, typename M3>
- VariadicOperatorMatcher<M1, M2, M3> operator()(const M1 &P1, const M2 &P2,
- const M3 &P3) const {
+ typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type
+ operator()(const M1 &P1, const M2 &P2, const M3 &P3) const {
return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3);
}
template <typename M1, typename M2, typename M3, typename M4>
- VariadicOperatorMatcher<M1, M2, M3, M4>
+ typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const {
return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4);
}
template <typename M1, typename M2, typename M3, typename M4, typename M5>
- VariadicOperatorMatcher<M1, M2, M3, M4, M5>
+ typename EnableIfValidArity<
+ 5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type
operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
const M5 &P5) const {
return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4,
@@ -1273,6 +1212,13 @@
/// @}
+/// \brief Matches nodes that do not match the provided matcher.
+///
+/// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1.
+bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+ ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ ArrayRef<DynTypedMatcher> InnerMatchers);
+
/// \brief Matches nodes for which all provided matchers match.
bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
ASTMatchFinder *Finder,
@@ -1293,12 +1239,22 @@
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
+template <typename T>
+inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
+ return Matcher<T>(new VariadicOperatorMatcherInterface<T>(
+ AllOfVariadicOperator, llvm::makeArrayRef(*this)));
+}
+
/// \brief Creates a Matcher<T> that matches if all inner matchers match.
template<typename T>
BindableMatcher<T> makeAllOfComposite(
ArrayRef<const Matcher<T> *> InnerMatchers) {
+ std::vector<DynTypedMatcher> DynMatchers;
+ for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
+ DynMatchers.push_back(*InnerMatchers[i]);
+ }
return BindableMatcher<T>(new VariadicOperatorMatcherInterface<T>(
- AllOfVariadicOperator, InnerMatchers));
+ AllOfVariadicOperator, std::move(DynMatchers)));
}
/// \brief Creates a Matcher<T> that matches if
@@ -1320,15 +1276,15 @@
/// DescendantT must be an AST base type.
template <typename T, typename DescendantT>
class HasDescendantMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<DescendantT>::value,
- has_descendant_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<DescendantT>::value,
+ "has descendant only accepts base type matcher");
+
public:
explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
: DescendantMatcher(DescendantMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesDescendantOf(
Node, DescendantMatcher, Builder, ASTMatchFinder::BK_First);
}
@@ -1343,15 +1299,15 @@
/// \c ParentT must be an AST base type.
template <typename T, typename ParentT>
class HasParentMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<ParentT>::value,
- has_parent_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<ParentT>::value,
+ "has parent only accepts base type matcher");
+
public:
explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
: ParentMatcher(ParentMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesAncestorOf(
Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly);
}
@@ -1366,15 +1322,15 @@
/// \c AncestorT must be an AST base type.
template <typename T, typename AncestorT>
class HasAncestorMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<AncestorT>::value,
- has_ancestor_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<AncestorT>::value,
+ "has ancestor only accepts base type matcher");
+
public:
explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
: AncestorMatcher(AncestorMatcher) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesAncestorOf(
Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All);
}
@@ -1391,16 +1347,16 @@
/// for each descendant node that matches instead of only for the first.
template <typename T, typename DescendantT>
class ForEachDescendantMatcher : public MatcherInterface<T> {
- TOOLING_COMPILE_ASSERT(IsBaseType<DescendantT>::value,
- for_each_descendant_only_accepts_base_type_matcher);
+ static_assert(IsBaseType<DescendantT>::value,
+ "for each descendant only accepts base type matcher");
+
public:
explicit ForEachDescendantMatcher(
const Matcher<DescendantT>& DescendantMatcher)
: DescendantMatcher(DescendantMatcher) {}
- virtual bool matches(const T& Node,
- ASTMatchFinder* Finder,
- BoundNodesTreeBuilder* Builder) const {
+ bool matches(const T& Node, ASTMatchFinder* Finder,
+ BoundNodesTreeBuilder* Builder) const override {
return Finder->matchesDescendantOf(Node, DescendantMatcher, Builder,
ASTMatchFinder::BK_All);
}
@@ -1413,17 +1369,17 @@
/// the value the ValueEqualsMatcher was constructed with.
template <typename T, typename ValueT>
class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
- TOOLING_COMPILE_ASSERT((llvm::is_base_of<CharacterLiteral, T>::value ||
- llvm::is_base_of<CXXBoolLiteralExpr,
- T>::value ||
- llvm::is_base_of<FloatingLiteral, T>::value ||
- llvm::is_base_of<IntegerLiteral, T>::value),
- the_node_must_have_a_getValue_method);
+ static_assert(std::is_base_of<CharacterLiteral, T>::value ||
+ std::is_base_of<CXXBoolLiteralExpr, T>::value ||
+ std::is_base_of<FloatingLiteral, T>::value ||
+ std::is_base_of<IntegerLiteral, T>::value,
+ "the node must have a getValue method");
+
public:
explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
: ExpectedValue(ExpectedValue) {}
- virtual bool matchesNode(const T &Node) const {
+ bool matchesNode(const T &Node) const override {
return Node.getValue() == ExpectedValue;
}
@@ -1478,9 +1434,8 @@
explicit LocMatcher(const Matcher<T> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- virtual bool matches(const TLoc &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const TLoc &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
if (!Node)
return false;
return InnerMatcher.matches(*extract(Node), Finder, Builder);
@@ -1503,9 +1458,8 @@
explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
: InnerMatcher(InnerMatcher) {}
- virtual bool matches(const TypeLoc &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
if (!Node)
return false;
return InnerMatcher.matches(Node.getType(), Finder, Builder);
@@ -1525,9 +1479,8 @@
QualType (T::*TraverseFunction)() const)
: InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
QualType NextNode = (Node.*TraverseFunction)();
if (NextNode.isNull())
return false;
@@ -1549,9 +1502,8 @@
TypeLoc (T::*TraverseFunction)() const)
: InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
- virtual bool matches(const T &Node,
- ASTMatchFinder *Finder,
- BoundNodesTreeBuilder *Builder) const {
+ bool matches(const T &Node, ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const override {
TypeLoc NextNode = (Node.*TraverseFunction)();
if (!NextNode)
return false;
@@ -1612,6 +1564,26 @@
return Self(InnerMatchers);
}
+// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
+// APIs for accessing the template argument list.
+inline llvm::ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
+ return D.getTemplateArgs().asArray();
+}
+
+inline llvm::ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
+ return llvm::ArrayRef<TemplateArgument>(T.getArgs(), T.getNumArgs());
+}
+
+struct NotEqualsBoundNodePredicate {
+ bool operator()(const internal::BoundNodesMap &Nodes) const {
+ return Nodes.getNode(ID) != Node;
+ }
+ std::string ID;
+ ast_type_traits::DynTypedNode Node;
+};
+
} // end namespace internal
} // end namespace ast_matchers
} // end namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index b5d5303..418e577 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -37,6 +37,25 @@
#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
+/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
+/// defines a single-parameter function named DefineMatcher() that returns a
+/// ReturnType object.
+///
+/// The code between the curly braces has access to the following variables:
+///
+/// Param: the parameter passed to the function; its type
+/// is ParamType.
+///
+/// The code should return an instance of ReturnType.
+#define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) \
+ AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
+ 0)
+#define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \
+ Param, OverloadId) \
+ inline ReturnType DefineMatcher(const ParamType &Param); \
+ typedef ReturnType (&DefineMatcher##_Type##OverloadId)(const ParamType &); \
+ inline ReturnType DefineMatcher(const ParamType &Param)
+
/// \brief AST_MATCHER(Type, DefineMatcher) { ... }
/// defines a zero parameter function named DefineMatcher() that returns a
/// Matcher<Type> object.
@@ -53,8 +72,8 @@
class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> { \
public: \
explicit matcher_##DefineMatcher##Matcher() {} \
- virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
+ bool matches(const Type &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const override; \
}; \
} \
inline internal::Matcher<Type> DefineMatcher() { \
@@ -90,8 +109,8 @@
explicit matcher_##DefineMatcher##OverloadId##Matcher( \
const ParamType &A##Param) \
: Param(A##Param) {} \
- virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
+ bool matches(const Type &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const override; \
\
private: \
const ParamType Param; \
@@ -135,8 +154,8 @@
matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \
const ParamType2 &A##Param2) \
: Param1(A##Param1), Param2(A##Param2) {} \
- virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
+ bool matches(const Type &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const override; \
\
private: \
const ParamType1 Param1; \
@@ -184,8 +203,8 @@
template <typename NodeType> \
class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
public: \
- virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
+ bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const override; \
}; \
} \
inline internal::PolymorphicMatcherWithParam0< \
@@ -223,8 +242,8 @@
explicit matcher_##DefineMatcher##OverloadId##Matcher( \
const ParamType &A##Param) \
: Param(A##Param) {} \
- virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
+ bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const override; \
\
private: \
const ParamType Param; \
@@ -270,8 +289,8 @@
matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \
const ParamType2 &A##Param2) \
: Param1(A##Param1), Param2(A##Param2) {} \
- virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
- BoundNodesTreeBuilder *Builder) const; \
+ bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
+ BoundNodesTreeBuilder *Builder) const override; \
\
private: \
const ParamType1 Param1; \
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
index aec0c0e..53629bf 100644
--- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -15,15 +15,14 @@
#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
-#include <string>
-#include <vector>
-
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/raw_ostream.h"
+#include <string>
+#include <vector>
namespace clang {
namespace ast_matchers {
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
index bb6ac76..5901495 100644
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -34,6 +34,7 @@
#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+#include "clang/ASTMatchers/Dynamic/Registry.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
@@ -65,7 +66,7 @@
///
/// All the arguments passed here have already been processed.
///
- /// \param MatcherName The matcher name found by the parser.
+ /// \param Ctor A matcher constructor looked up by lookupMatcherCtor.
///
/// \param NameRange The location of the name in the matcher source.
/// Useful for error reporting.
@@ -78,11 +79,25 @@
/// \return The matcher objects constructed by the processor, or a null
/// matcher if an error occurred. In that case, \c Error will contain a
/// description of the error.
- virtual VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+ virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
const SourceRange &NameRange,
StringRef BindID,
ArrayRef<ParserValue> Args,
Diagnostics *Error) = 0;
+
+ /// \brief Look up a matcher by name.
+ ///
+ /// \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.
+ virtual llvm::Optional<MatcherCtor>
+ lookupMatcherCtor(StringRef MatcherName, const SourceRange &NameRange,
+ Diagnostics *Error) = 0;
};
/// \brief Parse a matcher expression, creating matchers from the registry.
@@ -129,8 +144,16 @@
static bool parseExpression(StringRef Code, Sema *S,
VariantValue *Value, Diagnostics *Error);
+ /// \brief Complete an expression at the given offset.
+ ///
+ /// \return The list of completions, which may be empty if there are no
+ /// available completions or if an error occurred.
+ static std::vector<MatcherCompletion>
+ completeExpression(StringRef Code, unsigned CompletionOffset);
+
private:
class CodeTokenizer;
+ struct ScopedContextEntry;
struct TokenInfo;
Parser(CodeTokenizer *Tokenizer, Sema *S,
@@ -139,9 +162,17 @@
bool parseExpressionImpl(VariantValue *Value);
bool parseMatcherExpressionImpl(VariantValue *Value);
+ void addCompletion(const TokenInfo &CompToken, StringRef TypedText,
+ StringRef Decl);
+ void addExpressionCompletions();
+
CodeTokenizer *const Tokenizer;
Sema *const S;
Diagnostics *const Error;
+
+ typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy;
+ ContextStackTy ContextStack;
+ std::vector<MatcherCompletion> Completions;
};
} // namespace dynamic
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index c113c14..d7df698 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -21,20 +21,72 @@
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
namespace ast_matchers {
namespace dynamic {
+namespace internal {
+class MatcherDescriptor;
+}
+
+typedef const internal::MatcherDescriptor *MatcherCtor;
+
+struct MatcherCompletion {
+ MatcherCompletion() {}
+ MatcherCompletion(StringRef TypedText, StringRef MatcherDecl)
+ : TypedText(TypedText), MatcherDecl(MatcherDecl) {}
+
+ /// \brief The text to type to select this matcher.
+ std::string TypedText;
+
+ /// \brief The "declaration" of the matcher, with type information.
+ std::string MatcherDecl;
+
+ bool operator==(const MatcherCompletion &Other) const {
+ return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
+ }
+};
+
class Registry {
public:
- /// \brief Construct a matcher from the registry by name.
+ /// \brief Look up a matcher in the registry by name,
///
- /// Consult the registry of known matchers and construct the appropriate
- /// matcher 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);
+
+ /// \brief Compute the list of completions for \p Context.
///
- /// \param MatcherName The name of the matcher to instantiate.
+ /// Each element of \p Context represents a matcher invocation, going from
+ /// outermost to innermost. Elements are pairs consisting of a reference to the
+ /// matcher constructor and the index of the next element in the argument list
+ /// of that matcher (or for the last element, the index of the completion
+ /// point in the argument list). An empty list requests completion for the
+ /// root matcher.
+ ///
+ /// The completions are ordered first by decreasing relevance, then
+ /// alphabetically. Relevance is determined by how closely the matcher's
+ /// type matches that of the context. For example, if the innermost matcher
+ /// takes a FunctionDecl matcher, the FunctionDecl matchers are returned
+ /// first, followed by the ValueDecl matchers, then NamedDecl, then Decl, then
+ /// polymorphic matchers.
+ ///
+ /// Matchers which are technically convertible to the innermost context but
+ /// which would match either all or no nodes are excluded. For example,
+ /// namedDecl and varDecl are excluded in a FunctionDecl context, because
+ /// those matchers would match respectively all or no nodes in such a context.
+ static std::vector<MatcherCompletion>
+ getCompletions(llvm::ArrayRef<std::pair<MatcherCtor, unsigned> > Context);
+
+ /// \brief Construct a matcher from the registry.
+ ///
+ /// \param Ctor The matcher constructor to instantiate.
///
/// \param NameRange The location of the name in the matcher source.
/// Useful for error reporting.
@@ -44,10 +96,10 @@
/// will return an error.
///
/// \return The matcher object constructed if no error was found.
- /// A null matcher if the matcher is not found, or if the number of
- /// arguments or argument types do not match the signature.
- /// In that case \c Error will contain the description of the error.
- static VariantMatcher constructMatcher(StringRef MatcherName,
+ /// A null matcher if the number of arguments or argument types do not match
+ /// the signature. In that case \c Error will contain the description of
+ /// the error.
+ static VariantMatcher constructMatcher(MatcherCtor Ctor,
const SourceRange &NameRange,
ArrayRef<ParserValue> Args,
Diagnostics *Error);
@@ -58,7 +110,7 @@
/// matcher to the specified \c BindID.
/// If the matcher is not bindable, it sets an error in \c Error and returns
/// a null matcher.
- static VariantMatcher constructBoundMatcher(StringRef MatcherName,
+ static VariantMatcher constructBoundMatcher(MatcherCtor Ctor,
const SourceRange &NameRange,
StringRef BindID,
ArrayRef<ParserValue> Args,
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
index b9bc017..c685357 100644
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -17,14 +17,13 @@
#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
-#include <vector>
-
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Support/type_traits.h"
+#include <memory>
+#include <vector>
namespace clang {
namespace ast_matchers {
@@ -50,7 +49,8 @@
class MatcherOps {
public:
virtual ~MatcherOps();
- virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const = 0;
+ virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const = 0;
virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
virtual void constructVariadicOperator(
ast_matchers::internal::VariadicOperatorFunction Func,
@@ -78,14 +78,14 @@
/// \brief Clones the provided matchers.
///
/// They should be the result of a polymorphic matcher.
- static VariantMatcher PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers);
+ static VariantMatcher PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
/// \brief Creates a 'variadic' operator matcher.
///
/// It will bind to the appropriate type on getTypedMatcher<T>().
static VariantMatcher VariadicOperatorMatcher(
ast_matchers::internal::VariadicOperatorFunction Func,
- ArrayRef<VariantMatcher> Args);
+ std::vector<VariantMatcher> Args);
/// \brief Makes the matcher the "null" matcher.
void reset();
@@ -145,7 +145,10 @@
public:
typedef ast_matchers::internal::Matcher<T> MatcherT;
- virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const {
+ virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const {
+ IsExactMatch = Matcher.getSupportedKind().isSame(
+ ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
return Matcher.canConvertTo<T>();
}
@@ -156,34 +159,25 @@
virtual void constructVariadicOperator(
ast_matchers::internal::VariadicOperatorFunction Func,
ArrayRef<VariantMatcher> InnerMatchers) {
- const size_t NumArgs = InnerMatchers.size();
- MatcherT **InnerArgs = new MatcherT *[NumArgs]();
- bool HasError = false;
- for (size_t i = 0; i != NumArgs; ++i) {
+ std::vector<DynTypedMatcher> DynMatchers;
+ for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
// Abort if any of the inner matchers can't be converted to
// Matcher<T>.
if (!InnerMatchers[i].hasTypedMatcher<T>()) {
- HasError = true;
- break;
+ return;
}
- InnerArgs[i] = new MatcherT(InnerMatchers[i].getTypedMatcher<T>());
+ DynMatchers.push_back(InnerMatchers[i].getTypedMatcher<T>());
}
- if (!HasError) {
- Out.reset(new MatcherT(
- new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
- Func, ArrayRef<const MatcherT *>(InnerArgs, NumArgs))));
- }
- for (size_t i = 0; i != NumArgs; ++i) {
- delete InnerArgs[i];
- }
- delete[] InnerArgs;
+ Out.reset(new MatcherT(
+ new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
+ Func, DynMatchers)));
}
bool hasMatcher() const { return Out.get() != NULL; }
const MatcherT &matcher() const { return *Out; }
private:
- OwningPtr<MatcherT> Out;
+ std::unique_ptr<MatcherT> Out;
};
IntrusiveRefCntPtr<const Payload> Value;
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index 23a094a..7de4b59 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -18,8 +18,8 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h"
-#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/SourceLocation.h"
namespace clang {
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 2a806c8..1bfd05d 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -17,9 +17,15 @@
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/Analysis/DominatorInternals.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/IR/Module.h"
+#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/GenericDomTreeConstruction.h"
+
+// FIXME: There is no good reason for the domtree to require a print method
+// which accepts an LLVM Module, so remove this (and the method's argument that
+// needs it) when that is fixed.
+namespace llvm {
+class Module;
+}
namespace clang {
@@ -155,11 +161,6 @@
CFG *cfg;
};
-inline void WriteAsOperand(raw_ostream &OS, const CFGBlock *BB,
- bool t) {
- OS << "BB#" << BB->getBlockID();
-}
-
} // end namespace clang
//===-------------------------------------
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index c9516b5..3bffcd3 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -572,7 +572,8 @@
ArgType getArgType(ASTContext &Ctx) const;
- bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx);
+ bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt,
+ ASTContext &Ctx);
void toString(raw_ostream &os) const;
diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h
index 30c5b2d..90a6d01 100644
--- a/include/clang/Analysis/Analyses/ReachableCode.h
+++ b/include/clang/Analysis/Analyses/ReachableCode.h
@@ -27,6 +27,7 @@
namespace clang {
class AnalysisDeclContext;
class CFGBlock;
+ class Preprocessor;
}
//===----------------------------------------------------------------------===//
@@ -36,11 +37,22 @@
namespace clang {
namespace reachable_code {
+/// Classifications of unreachable code.
+enum UnreachableKind {
+ UK_Return,
+ UK_Break,
+ UK_Loop_Increment,
+ UK_Other
+};
+
class Callback {
virtual void anchor();
public:
virtual ~Callback() {}
- virtual void HandleUnreachable(SourceLocation L, SourceRange R1,
+ virtual void HandleUnreachable(UnreachableKind UK,
+ SourceLocation L,
+ SourceRange ConditionVal,
+ SourceRange R1,
SourceRange R2) = 0;
};
@@ -49,7 +61,8 @@
unsigned ScanReachableFromBlock(const CFGBlock *Start,
llvm::BitVector &Reachable);
-void FindUnreachableCode(AnalysisDeclContext &AC, Callback &CB);
+void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP,
+ Callback &CB);
}} // end namespace clang::reachable_code
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index 5def3dd..d8c0801 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -39,7 +39,8 @@
/// mutex.
enum LockKind {
LK_Shared, ///< Shared/reader lock of a mutex.
- LK_Exclusive ///< Exclusive/writer lock of a mutex.
+ LK_Exclusive, ///< Exclusive/writer lock of a mutex.
+ LK_Generic ///< Can be either Shared or Exclusive
};
/// This enum distinguishes between different ways to access (read or write) a
@@ -72,27 +73,46 @@
virtual ~ThreadSafetyHandler();
/// Warn about lock expressions which fail to resolve to lockable objects.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param Loc -- the SourceLocation of the unresolved expression.
- virtual void handleInvalidLockExp(SourceLocation Loc) {}
+ virtual void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) {}
/// Warn about unlock function calls that do not have a prior matching lock
/// expression.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc -- The SourceLocation of the Unlock
- virtual void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {}
+ virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
+ SourceLocation Loc) {}
+
+ /// Warn about an unlock function call that attempts to unlock a lock with
+ /// the incorrect lock kind. For instance, a shared lock being unlocked
+ /// exclusively, or vice versa.
+ /// \param LockName -- A StringRef name for the lock expression, to be printed
+ /// in the error message.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
+ /// \param Expected -- the kind of lock expected.
+ /// \param Received -- the kind of lock received.
+ /// \param Loc -- The SourceLocation of the Unlock.
+ virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
+ LockKind Expected, LockKind Received,
+ SourceLocation Loc) {}
/// Warn about lock function calls for locks which are already held.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc -- The location of the second lock expression.
- virtual void handleDoubleLock(Name LockName, SourceLocation Loc) {}
+ virtual void handleDoubleLock(StringRef Kind, Name LockName,
+ SourceLocation Loc) {}
/// Warn about situations where a mutex is sometimes held and sometimes not.
/// The three situations are:
/// 1. a mutex is locked on an "if" branch but not the "else" branch,
/// 2, or a mutex is only held at the start of some loop iterations,
/// 3. or when a mutex is locked but not unlocked inside a function.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param LocLocked -- The location of the lock expression where the mutex is
@@ -100,50 +120,56 @@
/// \param LocEndOfScope -- The location of the end of the scope where the
/// mutex is no longer held
/// \param LEK -- which of the three above cases we should warn for
- virtual void handleMutexHeldEndOfScope(Name LockName,
+ virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
SourceLocation LocLocked,
SourceLocation LocEndOfScope,
- LockErrorKind LEK){}
+ LockErrorKind LEK) {}
/// Warn when a mutex is held exclusively and shared at the same point. For
/// example, if a mutex is locked exclusively during an if branch and shared
/// during the else branch.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc1 -- The location of the first lock expression.
/// \param Loc2 -- The location of the second lock expression.
- virtual void handleExclusiveAndShared(Name LockName, SourceLocation Loc1,
+ virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
+ SourceLocation Loc1,
SourceLocation Loc2) {}
/// Warn when a protected operation occurs while no locks are held.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param D -- The decl for the protected variable or function
/// \param POK -- The kind of protected operation (e.g. variable access)
/// \param AK -- The kind of access (i.e. read or write) that occurred
/// \param Loc -- The location of the protected operation.
- virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
- AccessKind AK, SourceLocation Loc) {}
+ virtual void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
+ ProtectedOperationKind POK, AccessKind AK,
+ SourceLocation Loc) {}
/// Warn when a protected operation occurs while the specific mutex protecting
/// the operation is not locked.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param D -- The decl for the protected variable or function
/// \param POK -- The kind of protected operation (e.g. variable access)
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param LK -- The kind of access (i.e. read or write) that occurred
/// \param Loc -- The location of the protected operation.
- virtual void handleMutexNotHeld(const NamedDecl *D,
+ virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
ProtectedOperationKind POK, Name LockName,
LockKind LK, SourceLocation Loc,
- Name *PossibleMatch=0) {}
+ Name *PossibleMatch = 0) {}
/// Warn when a function is called while an excluded mutex is locked. For
/// example, the mutex may be locked inside the function.
+ /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param FunName -- The name of the function
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc -- The location of the function call.
- virtual void handleFunExcludesLock(Name FunName, Name LockName,
- SourceLocation Loc) {}
+ virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
+ Name LockName, SourceLocation Loc) {}
bool issueBetaWarnings() { return IssueBetaWarnings; }
void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index b6f183d..73b38b7 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -19,8 +19,8 @@
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Allocator.h"
+#include <memory>
namespace clang {
@@ -69,16 +69,16 @@
const Decl * const D;
- OwningPtr<CFG> cfg, completeCFG;
- OwningPtr<CFGStmtMap> cfgStmtMap;
+ std::unique_ptr<CFG> cfg, completeCFG;
+ std::unique_ptr<CFGStmtMap> cfgStmtMap;
CFG::BuildOptions cfgBuildOptions;
CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
bool builtCFG, builtCompleteCFG;
- OwningPtr<ParentMap> PM;
- OwningPtr<PseudoConstantAnalysis> PCA;
- OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA;
+ std::unique_ptr<ParentMap> PM;
+ std::unique_ptr<PseudoConstantAnalysis> PCA;
+ std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
llvm::BumpPtrAllocator A;
@@ -252,7 +252,7 @@
virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
- LLVM_ATTRIBUTE_USED void dumpStack() const;
+ void dumpStack() const;
public:
static void ProfileCommon(llvm::FoldingSetNodeID &ID,
@@ -287,11 +287,11 @@
const CFGBlock *getCallSiteBlock() const { return Block; }
/// Return true if the current LocationContext has no caller context.
- virtual bool inTopFrame() const { return getParent() == 0; }
+ bool inTopFrame() const override { return getParent() == 0; }
unsigned getIndex() const { return Index; }
- void Profile(llvm::FoldingSetNodeID &ID);
+ void Profile(llvm::FoldingSetNodeID &ID) override;
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
const LocationContext *parent, const Stmt *s,
@@ -317,7 +317,7 @@
public:
~ScopeContext() {}
- void Profile(llvm::FoldingSetNodeID &ID);
+ void Profile(llvm::FoldingSetNodeID &ID) override;
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
const LocationContext *parent, const Stmt *s) {
@@ -349,7 +349,7 @@
const void *getContextData() const { return ContextData; }
- void Profile(llvm::FoldingSetNodeID &ID);
+ void Profile(llvm::FoldingSetNodeID &ID) override;
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
const LocationContext *parent, const BlockDecl *bd,
@@ -409,7 +409,8 @@
bool addInitializers = false,
bool addTemporaryDtors = false,
bool synthesizeBodies = false,
- bool addStaticInitBranches = false);
+ bool addStaticInitBranches = false,
+ bool addCXXNewAllocator = true);
~AnalysisDeclContextManager();
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 14b7ab8..123d144 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -21,13 +21,14 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
#include <bitset>
#include <cassert>
#include <iterator>
+#include <memory>
namespace clang {
class CXXDestructorDecl;
@@ -45,6 +46,7 @@
class ASTContext;
class CXXRecordDecl;
class CXXDeleteExpr;
+ class CXXNewExpr;
/// CFGElement - Represents a top-level expression in a basic block.
class CFGElement {
@@ -53,6 +55,7 @@
// main kind
Statement,
Initializer,
+ NewAllocator,
// dtor kind
AutomaticObjectDtor,
DeleteDtor,
@@ -70,7 +73,9 @@
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = 0)
: Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
- Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {}
+ Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
+ assert(getKind() == kind);
+ }
CFGElement() {}
public:
@@ -141,6 +146,25 @@
}
};
+/// CFGNewAllocator - Represents C++ allocator call.
+class CFGNewAllocator : public CFGElement {
+public:
+ explicit CFGNewAllocator(const CXXNewExpr *S)
+ : CFGElement(NewAllocator, S) {}
+
+ // Get the new expression.
+ const CXXNewExpr *getAllocatorExpr() const {
+ return static_cast<CXXNewExpr *>(Data1.getPointer());
+ }
+
+private:
+ friend class CFGElement;
+ CFGNewAllocator() {}
+ static bool isKind(const CFGElement &elem) {
+ return elem.getKind() == NewAllocator;
+ }
+};
+
/// CFGImplicitDtor - Represents C++ object destructor implicitly generated
/// by compiler on various occasions.
class CFGImplicitDtor : public CFGElement {
@@ -388,9 +412,64 @@
/// of the CFG.
unsigned BlockID;
+public:
+ /// This class represents a potential adjacent block in the CFG. It encodes
+ /// whether or not the block is actually reachable, or can be proved to be
+ /// trivially unreachable. For some cases it allows one to encode scenarios
+ /// where a block was substituted because the original (now alternate) block
+ /// is unreachable.
+ class AdjacentBlock {
+ enum Kind {
+ AB_Normal,
+ AB_Unreachable,
+ AB_Alternate
+ };
+
+ CFGBlock *ReachableBlock;
+ llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
+
+ public:
+ /// Construct an AdjacentBlock with a possibly unreachable block.
+ AdjacentBlock(CFGBlock *B, bool IsReachable);
+
+ /// Construct an AdjacentBlock with a reachable block and an alternate
+ /// unreachable block.
+ AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock);
+
+ /// Get the reachable block, if one exists.
+ CFGBlock *getReachableBlock() const {
+ return ReachableBlock;
+ }
+
+ /// Get the potentially unreachable block.
+ CFGBlock *getPossiblyUnreachableBlock() const {
+ return UnreachableBlock.getPointer();
+ }
+
+ /// Provide an implicit conversion to CFGBlock* so that
+ /// AdjacentBlock can be substituted for CFGBlock*.
+ operator CFGBlock*() const {
+ return getReachableBlock();
+ }
+
+ CFGBlock& operator *() const {
+ return *getReachableBlock();
+ }
+
+ CFGBlock* operator ->() const {
+ return getReachableBlock();
+ }
+
+ bool isReachable() const {
+ Kind K = (Kind) UnreachableBlock.getInt();
+ return K == AB_Normal || K == AB_Alternate;
+ }
+ };
+
+private:
/// Predecessors/Successors - Keep track of the predecessor / successor
/// CFG blocks.
- typedef BumpVector<CFGBlock*> AdjacentBlocks;
+ typedef BumpVector<AdjacentBlock> AdjacentBlocks;
AdjacentBlocks Preds;
AdjacentBlocks Succs;
@@ -480,9 +559,11 @@
class FilterOptions {
public:
FilterOptions() {
+ IgnoreNullPredecessors = 1;
IgnoreDefaultsWithCoveredEnums = 0;
}
+ unsigned IgnoreNullPredecessors : 1;
unsigned IgnoreDefaultsWithCoveredEnums : 1;
};
@@ -495,11 +576,14 @@
IMPL I, E;
const FilterOptions F;
const CFGBlock *From;
- public:
+ public:
explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
- const CFGBlock *from,
- const FilterOptions &f)
- : I(i), E(e), F(f), From(from) {}
+ const CFGBlock *from,
+ const FilterOptions &f)
+ : I(i), E(e), F(f), From(from) {
+ while (hasMore() && Filter(*I))
+ ++I;
+ }
bool hasMore() const { return I != E; }
@@ -531,7 +615,7 @@
// Manipulation of block contents
- void setTerminator(Stmt *Statement) { Terminator = Statement; }
+ void setTerminator(CFGTerminator Term) { Terminator = Term; }
void setLabel(Stmt *Statement) { Label = Statement; }
void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
void setHasNoReturnElement() { HasNoReturnElement = true; }
@@ -539,10 +623,10 @@
CFGTerminator getTerminator() { return Terminator; }
const CFGTerminator getTerminator() const { return Terminator; }
- Stmt *getTerminatorCondition();
+ Stmt *getTerminatorCondition(bool StripParens = true);
- const Stmt *getTerminatorCondition() const {
- return const_cast<CFGBlock*>(this)->getTerminatorCondition();
+ const Stmt *getTerminatorCondition(bool StripParens = true) const {
+ return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens);
}
const Stmt *getLoopTarget() const { return LoopTarget; }
@@ -560,13 +644,13 @@
void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
bool ShowColors) const;
void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
-
- void addSuccessor(CFGBlock *Block, BumpVectorContext &C) {
- if (Block)
- Block->Preds.push_back(this, C);
- Succs.push_back(Block, C);
+ void printAsOperand(raw_ostream &OS, bool /*PrintType*/) {
+ OS << "BB#" << getBlockID();
}
+ /// Adds a (potentially unreachable) successor block to the current block.
+ void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C);
+
void appendStmt(Stmt *statement, BumpVectorContext &C) {
Elements.push_back(CFGStmt(statement), C);
}
@@ -576,6 +660,11 @@
Elements.push_back(CFGInitializer(initializer), C);
}
+ void appendNewAllocator(CXXNewExpr *NE,
+ BumpVectorContext &C) {
+ Elements.push_back(CFGNewAllocator(NE), C);
+ }
+
void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) {
Elements.push_back(CFGBaseDtor(BS), C);
}
@@ -634,6 +723,7 @@
bool AddImplicitDtors;
bool AddTemporaryDtors;
bool AddStaticInitBranches;
+ bool AddCXXNewAllocator;
bool alwaysAdd(const Stmt *stmt) const {
return alwaysAddMask[stmt->getStmtClass()];
@@ -655,7 +745,8 @@
,AddInitializers(false)
,AddImplicitDtors(false)
,AddTemporaryDtors(false)
- ,AddStaticInitBranches(false) {}
+ ,AddStaticInitBranches(false)
+ ,AddCXXNewAllocator(false) {}
};
/// \brief Provides a custom implementation of the iterator class to have the
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
index c611ea2..5b99f1d 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -14,12 +14,12 @@
#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
#define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
-#include "functional" // STL
#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 {
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 333329d..1423e01 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -658,12 +658,12 @@
private:
const void *TagKind;
};
-
+
class SimpleProgramPointTag : public ProgramPointTag {
- std::string desc;
+ std::string Desc;
public:
- SimpleProgramPointTag(StringRef description);
- StringRef getTagDescription() const;
+ SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg);
+ StringRef getTagDescription() const override;
};
} // end namespace clang
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index 387e779..e246712 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -60,7 +60,7 @@
}
~BumpVector() {
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
// Destroy the constructed elements in the vector.
destroy_range(Begin, End);
}
@@ -130,7 +130,7 @@
}
void clear() {
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
destroy_range(Begin, End);
}
End = Begin;
@@ -223,7 +223,7 @@
T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity);
// Copy the elements over.
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
std::uninitialized_copy(Begin, End, NewElts);
// Destroy the original elements.
destroy_range(Begin, End);
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 3da2e2b..7360683 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -7,6 +7,54 @@
//
//===----------------------------------------------------------------------===//
+// The documentation is organized by category. Attributes can have category-
+// specific documentation that is collated within the larger document.
+class DocumentationCategory<string name> {
+ string Name = name;
+ code Content = [{}];
+}
+def DocCatFunction : DocumentationCategory<"Function Attributes">;
+def DocCatVariable : DocumentationCategory<"Variable Attributes">;
+def DocCatType : DocumentationCategory<"Type Attributes">;
+def DocCatStmt : DocumentationCategory<"Statement Attributes">;
+// Attributes listed under the Undocumented category do not generate any public
+// documentation. Ideally, this category should be used for internal-only
+// attributes which contain no spellings.
+def DocCatUndocumented : DocumentationCategory<"Undocumented">;
+
+class DocDeprecated<string replacement = ""> {
+ // If the Replacement field is empty, no replacement will be listed with the
+ // documentation. Otherwise, the documentation will specify the attribute has
+ // been superseded by this replacement.
+ string Replacement = replacement;
+}
+
+// Specifies the documentation to be associated with the given category.
+class Documentation {
+ DocumentationCategory Category;
+ code Content;
+
+ // If the heading is empty, one may be picked automatically. If the attribute
+ // only has one spelling, no heading is required as the attribute's sole
+ // spelling is sufficient. If all spellings are semantically common, the
+ // heading will be the semantic spelling. If the spellings are not
+ // semantically common and no heading is provided, an error will be emitted.
+ string Heading = "";
+
+ // When set, specifies that the attribute is deprecated and can optionally
+ // specify a replacement attribute.
+ DocDeprecated Deprecated;
+}
+
+// Specifies that the attribute is explicitly undocumented. This can be a
+// helpful placeholder for the attribute while working on the implementation,
+// but should not be used once feature work has been completed.
+def Undocumented : Documentation {
+ let Category = DocCatUndocumented;
+}
+
+include "clang/Basic/AttrDocs.td"
+
// An attribute's subject is whatever it appertains to. In this file, it is
// more accurately a list of things that an attribute can appertain to. All
// Decls and Stmts are possibly AttrSubjects (even though the syntax may not
@@ -19,29 +67,63 @@
// A subset-subject is an AttrSubject constrained to operate only on some subset
// of that subject.
//
-// The description is used in output messages to specify what the subject
-// represents. FIXME: Deal with translation issues.
-//
// The code fragment is a boolean expression that will confirm that the subject
// meets the requirements; the subject will have the name S, and will have the
// type specified by the base. It should be a simple boolean expression.
-class SubsetSubject<AttrSubject base, string description, code check>
- : AttrSubject {
+class SubsetSubject<AttrSubject base, code check> : AttrSubject {
AttrSubject Base = base;
- string Description = description;
code CheckCode = check;
}
// This is the type of a variable which C++11 allows alignas(...) to appertain
// to.
-def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
+def NormalVar : SubsetSubject<Var,
[{S->getStorageClass() != VarDecl::Register &&
S->getKind() != Decl::ImplicitParam &&
S->getKind() != Decl::ParmVar &&
S->getKind() != Decl::NonTypeTemplateParm}]>;
-def NonBitField : SubsetSubject<Field, "non-bit field",
+def NonBitField : SubsetSubject<Field,
[{!S->isBitField()}]>;
+def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
+ [{S->isInstanceMethod()}]>;
+
+def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
+ [{S->getMethodFamily() == OMF_init &&
+ (isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
+ (isa<ObjCCategoryDecl>(S->getDeclContext()) &&
+ cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}]>;
+
+def Struct : SubsetSubject<Record,
+ [{!S->isUnion()}]>;
+
+def TLSVar : SubsetSubject<Var,
+ [{S->getTLSKind() != 0}]>;
+
+def SharedVar : SubsetSubject<Var,
+ [{S->hasGlobalStorage() && !S->getTLSKind()}]>;
+
+def GlobalVar : SubsetSubject<Var,
+ [{S->hasGlobalStorage()}]>;
+
+// FIXME: this hack is needed because DeclNodes.td defines the base Decl node
+// type to be a class, not a definition. This makes it impossible to create an
+// attribute subject which accepts a Decl. Normally, this is not a problem,
+// because the attribute can have no Subjects clause to accomplish this. But in
+// the case of a SubsetSubject, there's no way to express it without this hack.
+def DeclBase : AttrSubject;
+def FunctionLike : SubsetSubject<DeclBase,
+ [{S->getFunctionType(false) != NULL}]>;
+
+// HasFunctionProto is a more strict version of FunctionLike, so it should
+// never be specified in a Subjects list along with FunctionLike (due to the
+// inclusive nature of subject testing).
+def HasFunctionProto : SubsetSubject<DeclBase,
+ [{(S->getFunctionType(true) != NULL &&
+ isa<FunctionProtoType>(S->getFunctionType())) ||
+ isa<ObjCMethodDecl>(S) ||
+ isa<BlockDecl>(S)}]>;
+
// A single argument to an attribute
class Argument<string name, bit optional> {
string Name = name;
@@ -56,7 +138,6 @@
class FunctionArgument<string name, bit opt = 0> : Argument<name, opt>;
class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
-class SourceLocArgument<string name, bit opt = 0> : Argument<name, opt>;
class VariadicUnsignedArgument<string name> : Argument<name, 1>;
class VariadicExprArgument<string name> : Argument<name, 1>;
@@ -68,6 +149,11 @@
// be dependent.
class AlignedArgument<string name, bit opt = 0> : Argument<name, opt>;
+// A bool argument with a default value
+class DefaultBoolArgument<string name, bit default> : BoolArgument<name, 1> {
+ bit Default = default;
+}
+
// An integer argument with a default value
class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
int Default = default;
@@ -95,6 +181,7 @@
class Spelling<string name, string variety> {
string Name = name;
string Variety = variety;
+ bit KnownToGCC;
}
class GNU<string name> : Spelling<name, "GNU">;
@@ -104,16 +191,58 @@
}
class Keyword<string name> : Spelling<name, "Keyword">;
+// The GCC spelling implies GNU<name, "GNU"> and CXX11<"gnu", name> and also
+// sets KnownToGCC to 1. This spelling should be used for any GCC-compatible
+// attributes.
+class GCC<string name> : Spelling<name, "GCC"> {
+ let KnownToGCC = 1;
+}
+
class Accessor<string name, list<Spelling> spellings> {
string Name = name;
list<Spelling> Spellings = spellings;
}
+class SubjectDiag<bit warn> {
+ bit Warn = warn;
+}
+def WarnDiag : SubjectDiag<1>;
+def ErrorDiag : SubjectDiag<0>;
+
+class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag,
+ string customDiag = ""> {
+ list<AttrSubject> Subjects = subjects;
+ SubjectDiag Diag = diag;
+ string CustomDiag = customDiag;
+}
+
+class LangOpt<string name> {
+ string Name = name;
+}
+def MicrosoftExt : LangOpt<"MicrosoftExt">;
+def Borland : LangOpt<"Borland">;
+def CUDA : LangOpt<"CUDA">;
+
+// Defines targets for target-specific attributes. The list of strings should
+// specify architectures for which the target applies, based off the ArchType
+// enumeration in Triple.h.
+class TargetArch<list<string> arches> {
+ list<string> Arches = arches;
+ list<string> OSes;
+}
+def TargetARM : TargetArch<["arm", "thumb"]>;
+def TargetMSP430 : TargetArch<["msp430"]>;
+def TargetX86 : TargetArch<["x86"]>;
+def TargetX86Win : TargetArch<["x86", "x86_64"]> {
+ let OSes = ["Win32"];
+}
+def TargetMips : TargetArch<["mips", "mipsel"]>;
+
class Attr {
// The various ways in which an attribute can be spelled in source
list<Spelling> Spellings;
// The things to which an attribute can appertain
- list<AttrSubject> Subjects;
+ SubjectList Subjects;
// The arguments allowed on an attribute
list<Argument> Args = [];
// Accessors which should be generated for the attribute.
@@ -131,28 +260,55 @@
bit SemaHandler = 1;
// Set to true for attributes that are completely ignored.
bit Ignored = 0;
- // Set to true if each of the spellings is a distinct attribute.
- bit DistinctSpellings = 0;
// Set to true if the attribute's parsing does not match its semantic
// content. Eg) It parses 3 args, but semantically takes 4 args. Opts out of
// common attribute error checking.
bit HasCustomParsing = 0;
+ // Set to true if all of the attribute's arguments should be parsed in an
+ // unevaluated context.
+ bit ParseArgumentsAsUnevaluated = 0;
+ // Set to true if this attribute can be duplicated on a subject when merging
+ // attributes. By default, attributes are not merged.
+ bit DuplicatesAllowedWhileMerging = 0;
+ // Lists language options, one of which is required to be true for the
+ // attribute to be applicable. If empty, no language options are required.
+ list<LangOpt> LangOpts = [];
// Any additional text that should be included verbatim in the class.
code AdditionalMembers = [{}];
+ // Any documentation that should be associated with the attribute. Since an
+ // attribute may be documented under multiple categories, more than one
+ // Documentation entry may be listed.
+ list<Documentation> Documentation;
}
/// A type attribute is not processed on a declaration or a statement.
class TypeAttr : Attr {
+ // By default, type attributes do not get an AST node.
let ASTNode = 0;
}
/// An inheritable attribute is inherited by later redeclarations.
class InheritableAttr : Attr;
-/// A target-specific attribute that is meant to be processed via
-/// TargetAttributesSema::ProcessDeclAttribute. This class is meant to be used
-/// as a mixin with InheritableAttr or Attr depending on the attribute's needs.
-class TargetSpecificAttr;
+/// A target-specific attribute. This class is meant to be used as a mixin
+/// with InheritableAttr or Attr depending on the attribute's needs.
+class TargetSpecificAttr<TargetArch target> {
+ TargetArch Target = target;
+ // Attributes are generally required to have unique spellings for their names
+ // so that the parser can determine what kind of attribute it has parsed.
+ // However, target-specific attributes are special in that the attribute only
+ // "exists" for a given target. So two target-specific attributes can share
+ // the same name when they exist in different targets. To support this, a
+ // Kind can be explicitly specified for a target-specific attribute. This
+ // corresponds to the AttributeList::AT_* enum that is generated and it
+ // should contain a shared value between the attributes.
+ //
+ // Target-specific attributes which use this feature should ensure that the
+ // spellings match exactly betweeen the attributes, and if the arguments or
+ // subjects differ, should specify HasCustomParsing = 1 and implement their
+ // own parsing and semantic handling requirements as-needed.
+ string ParseKind;
+}
/// An inheritable parameter attribute is inherited by later
/// redeclarations, even when it's written on a parameter.
@@ -163,6 +319,7 @@
let Ignored = 1;
let ASTNode = 0;
let SemaHandler = 0;
+ let Documentation = [Undocumented];
}
//
@@ -172,66 +329,77 @@
def AddressSpace : TypeAttr {
let Spellings = [GNU<"address_space">];
let Args = [IntArgument<"AddressSpace">];
+ let Documentation = [Undocumented];
}
def Alias : Attr {
- let Spellings = [GNU<"alias">, CXX11<"gnu", "alias">];
+ let Spellings = [GCC<"alias">];
let Args = [StringArgument<"Aliasee">];
+ let Documentation = [Undocumented];
}
def Aligned : InheritableAttr {
- let Spellings = [GNU<"aligned">, Declspec<"align">, CXX11<"gnu", "aligned">,
- Keyword<"alignas">, Keyword<"_Alignas">];
- let Subjects = [NonBitField, NormalVar, Tag];
+ let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
+ Keyword<"_Alignas">];
+// let Subjects = SubjectList<[NonBitField, NormalVar, Tag]>;
let Args = [AlignedArgument<"Alignment", 1>];
- let Accessors = [Accessor<"isGNU", [GNU<"aligned">, CXX11<"gnu","aligned">]>,
+ let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
Accessor<"isC11", [Keyword<"_Alignas">]>,
Accessor<"isAlignas", [Keyword<"alignas">,
Keyword<"_Alignas">]>,
Accessor<"isDeclspec",[Declspec<"align">]>];
+ let Documentation = [Undocumented];
}
def AlignMac68k : InheritableAttr {
+ // This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let SemaHandler = 0;
-}
-
-def AllocSize : InheritableAttr {
- let Spellings = [GNU<"alloc_size">, CXX11<"gnu", "alloc_size">];
- let Args = [VariadicUnsignedArgument<"Args">];
+ let Documentation = [Undocumented];
}
def AlwaysInline : InheritableAttr {
- let Spellings = [GNU<"always_inline">, CXX11<"gnu", "always_inline">];
+ let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
}
def TLSModel : InheritableAttr {
- let Spellings = [GNU<"tls_model">, CXX11<"gnu", "tls_model">];
- let Subjects = [Var];
+ let Spellings = [GCC<"tls_model">];
+ let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
let Args = [StringArgument<"Model">];
+ let Documentation = [TLSModelDocs];
}
def AnalyzerNoReturn : InheritableAttr {
let Spellings = [GNU<"analyzer_noreturn">];
+ let Documentation = [Undocumented];
}
def Annotate : InheritableParamAttr {
let Spellings = [GNU<"annotate">];
let Args = [StringArgument<"Annotation">];
+ let Documentation = [Undocumented];
}
-def ARMInterrupt : InheritableAttr, TargetSpecificAttr {
+def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
+ // NOTE: If you add any additional spellings, MSP430Interrupt's spellings
+ // must match.
let Spellings = [GNU<"interrupt">];
let Args = [EnumArgument<"Interrupt", "InterruptType",
["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
1>];
+ let ParseKind = "Interrupt";
+ let HasCustomParsing = 1;
+ let Documentation = [ARMInterruptDocs];
}
def AsmLabel : InheritableAttr {
- let Spellings = [];
+ let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
let Args = [StringArgument<"Label">];
let SemaHandler = 0;
+ let Documentation = [Undocumented];
}
def Availability : InheritableAttr {
@@ -247,11 +415,15 @@
.Default(llvm::StringRef());
} }];
let HasCustomParsing = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+// let Subjects = SubjectList<[Named]>;
+ let Documentation = [AvailabilityDocs];
}
def Blocks : InheritableAttr {
let Spellings = [GNU<"blocks">];
let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
+ let Documentation = [Undocumented];
}
def Bounded : IgnoredAttr {
@@ -259,14 +431,15 @@
}
def CarriesDependency : InheritableParamAttr {
- let Spellings = [GNU<"carries_dependency">, CXX11<"","carries_dependency">,
- CXX11<"std","carries_dependency">];
- let Subjects = [ParmVar, Function];
+ let Spellings = [GNU<"carries_dependency">, CXX11<"","carries_dependency">];
+ let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>;
+ let Documentation = [CarriesDependencyDocs];
}
def CDecl : InheritableAttr {
- let Spellings = [GNU<"cdecl">, CXX11<"gnu", "cdecl">, Keyword<"__cdecl">,
- Keyword<"_cdecl">];
+ let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
// cf_audited_transfer indicates that the given function has been
@@ -275,7 +448,8 @@
// '#pragma clang arc_cf_code_audited' rather than explicitly.
def CFAuditedTransfer : InheritableAttr {
let Spellings = [GNU<"cf_audited_transfer">];
- let Subjects = [Function];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
// cf_unknown_transfer is an explicit opt-out of cf_audited_transfer.
@@ -283,237 +457,381 @@
// transfer semantics.
def CFUnknownTransfer : InheritableAttr {
let Spellings = [GNU<"cf_unknown_transfer">];
- let Subjects = [Function];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def CFReturnsRetained : InheritableAttr {
let Spellings = [GNU<"cf_returns_retained">];
- let Subjects = [ObjCMethod, Function];
+// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+ let Documentation = [Undocumented];
}
def CFReturnsNotRetained : InheritableAttr {
let Spellings = [GNU<"cf_returns_not_retained">];
- let Subjects = [ObjCMethod, Function];
+// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+ let Documentation = [Undocumented];
}
def CFConsumed : InheritableParamAttr {
let Spellings = [GNU<"cf_consumed">];
- let Subjects = [ParmVar];
+ let Subjects = SubjectList<[ParmVar]>;
+ let Documentation = [Undocumented];
}
def Cleanup : InheritableAttr {
- let Spellings = [GNU<"cleanup">, CXX11<"gnu", "cleanup">];
+ let Spellings = [GCC<"cleanup">];
let Args = [FunctionArgument<"FunctionDecl">];
+ let Subjects = SubjectList<[Var]>;
+ let Documentation = [Undocumented];
}
def Cold : InheritableAttr {
- let Spellings = [GNU<"cold">, CXX11<"gnu", "cold">];
+ let Spellings = [GCC<"cold">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
}
def Common : InheritableAttr {
- let Spellings = [GNU<"common">, CXX11<"gnu", "common">];
+ let Spellings = [GCC<"common">];
+ let Subjects = SubjectList<[Var]>;
+ let Documentation = [Undocumented];
}
def Const : InheritableAttr {
- let Spellings = [GNU<"const">, GNU<"__const">,
- CXX11<"gnu", "const">, CXX11<"gnu", "__const">];
+ let Spellings = [GCC<"const">, GCC<"__const">];
+ let Documentation = [Undocumented];
}
def Constructor : InheritableAttr {
- let Spellings = [GNU<"constructor">, CXX11<"gnu", "constructor">];
- let Args = [IntArgument<"Priority", 1>];
+ let Spellings = [GCC<"constructor">];
+ let Args = [DefaultIntArgument<"Priority", 65535>];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
}
def CUDAConstant : InheritableAttr {
let Spellings = [GNU<"constant">];
+ let Subjects = SubjectList<[Var]>;
+ let LangOpts = [CUDA];
+ let Documentation = [Undocumented];
}
def CUDADevice : InheritableAttr {
let Spellings = [GNU<"device">];
+ let Subjects = SubjectList<[Function, Var]>;
+ let LangOpts = [CUDA];
+ let Documentation = [Undocumented];
}
def CUDAGlobal : InheritableAttr {
let Spellings = [GNU<"global">];
+ let Subjects = SubjectList<[Function]>;
+ let LangOpts = [CUDA];
+ let Documentation = [Undocumented];
}
def CUDAHost : InheritableAttr {
let Spellings = [GNU<"host">];
+ let Subjects = SubjectList<[Function]>;
+ let LangOpts = [CUDA];
+ let Documentation = [Undocumented];
}
def CUDALaunchBounds : InheritableAttr {
let Spellings = [GNU<"launch_bounds">];
let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>];
+ let LangOpts = [CUDA];
+ let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag,
+ "ExpectedFunctionOrMethod">;
+ // An AST node is created for this attribute, but is not used by other parts
+ // of the compiler. However, this node needs to exist in the AST because
+ // non-LLVM backends may be relying on the attribute's presence.
+ let Documentation = [Undocumented];
}
def CUDAShared : InheritableAttr {
let Spellings = [GNU<"shared">];
+ let Subjects = SubjectList<[Var]>;
+ let LangOpts = [CUDA];
+ let Documentation = [Undocumented];
}
def C11NoReturn : InheritableAttr {
let Spellings = [Keyword<"_Noreturn">];
- let Subjects = [Function];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
let SemaHandler = 0;
+ let Documentation = [C11NoReturnDocs];
}
def CXX11NoReturn : InheritableAttr {
- let Spellings = [CXX11<"","noreturn">, CXX11<"std","noreturn">];
- let Subjects = [Function];
+ let Spellings = [CXX11<"","noreturn">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [CXX11NoReturnDocs];
}
def OpenCLKernel : InheritableAttr {
let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
+// This attribute is both a type attribute, and a declaration attribute (for
+// parameter variables).
def OpenCLImageAccess : Attr {
- let Spellings = [GNU<"opencl_image_access">];
- let Args = [IntArgument<"Access">];
+ let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
+ Keyword<"__write_only">, Keyword<"write_only">,
+ Keyword<"__read_write">, Keyword<"read_write">];
+ let Subjects = SubjectList<[ParmVar], ErrorDiag>;
+ let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
+ Keyword<"read_only">]>,
+ Accessor<"isReadWrite", [Keyword<"__read_write">,
+ Keyword<"read_write">]>,
+ Accessor<"isWriteOnly", [Keyword<"__write_only">,
+ Keyword<"write_only">]>];
+ let Documentation = [Undocumented];
+}
+
+def OpenCLPrivateAddressSpace : TypeAttr {
+ let Spellings = [Keyword<"__private">, Keyword<"private">];
+ let Documentation = [Undocumented];
+}
+
+def OpenCLGlobalAddressSpace : TypeAttr {
+ let Spellings = [Keyword<"__global">, Keyword<"global">];
+ let Documentation = [Undocumented];
+}
+
+def OpenCLLocalAddressSpace : TypeAttr {
+ let Spellings = [Keyword<"__local">, Keyword<"local">];
+ let Documentation = [Undocumented];
+}
+
+def OpenCLConstantAddressSpace : TypeAttr {
+ let Spellings = [Keyword<"__constant">, Keyword<"constant">];
+ let Documentation = [Undocumented];
}
def Kernel : Attr {
let Spellings = [GNU<"kernel">];
+ let Documentation = [Undocumented];
}
def Deprecated : InheritableAttr {
- let Spellings = [GNU<"deprecated">,
- CXX11<"gnu", "deprecated">, CXX11<"","deprecated">];
+ let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
+ CXX11<"","deprecated">];
let Args = [StringArgument<"Message", 1>];
+ let Documentation = [Undocumented];
}
def Destructor : InheritableAttr {
- let Spellings = [GNU<"destructor">, CXX11<"gnu", "destructor">];
- let Args = [IntArgument<"Priority", 1>];
+ let Spellings = [GCC<"destructor">];
+ let Args = [DefaultIntArgument<"Priority", 65535>];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
+}
+
+def EnableIf : InheritableAttr {
+ let Spellings = [GNU<"enable_if">];
+ let Subjects = SubjectList<[Function]>;
+ let Args = [ExprArgument<"Cond">, StringArgument<"Message">];
+ let TemplateDependent = 1;
+ let Documentation = [EnableIfDocs];
}
def ExtVectorType : Attr {
let Spellings = [GNU<"ext_vector_type">];
+ let Subjects = SubjectList<[TypedefName], ErrorDiag>;
let Args = [ExprArgument<"NumElements">];
let ASTNode = 0;
+ let Documentation = [Undocumented];
}
def FallThrough : Attr {
let Spellings = [CXX11<"clang", "fallthrough">];
- let Subjects = [NullStmt];
+// let Subjects = [NullStmt];
+ let Documentation = [FallthroughDocs];
}
def FastCall : InheritableAttr {
- let Spellings = [GNU<"fastcall">, CXX11<"gnu", "fastcall">,
- Keyword<"__fastcall">, Keyword<"_fastcall">];
+ let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">,
+ Keyword<"_fastcall">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
def Final : InheritableAttr {
let Spellings = [Keyword<"final">, Keyword<"sealed">];
let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>];
let SemaHandler = 0;
+ let Documentation = [Undocumented];
}
def MinSize : InheritableAttr {
let Spellings = [GNU<"minsize">];
- let Subjects = [Function];
+ let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def Format : InheritableAttr {
- let Spellings = [GNU<"format">, CXX11<"gnu", "format">];
+ let Spellings = [GCC<"format">];
let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
IntArgument<"FirstArg">];
+ let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto], WarnDiag,
+ "ExpectedFunction">;
+ let Documentation = [FormatDocs];
}
def FormatArg : InheritableAttr {
- let Spellings = [GNU<"format_arg">, CXX11<"gnu", "format_arg">];
+ let Spellings = [GCC<"format_arg">];
let Args = [IntArgument<"FormatIdx">];
+ let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag,
+ "ExpectedFunction">;
+ let Documentation = [Undocumented];
}
def GNUInline : InheritableAttr {
- let Spellings = [GNU<"gnu_inline">, CXX11<"gnu", "gnu_inline">];
+ let Spellings = [GCC<"gnu_inline">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
}
def Hot : InheritableAttr {
- let Spellings = [GNU<"hot">, CXX11<"gnu", "hot">];
+ let Spellings = [GCC<"hot">];
+ let Subjects = SubjectList<[Function]>;
+ // An AST node is created for this attribute, but not actually used beyond
+ // semantic checking for mutual exclusion with the Cold attribute.
+ let Documentation = [Undocumented];
}
def IBAction : InheritableAttr {
let Spellings = [GNU<"ibaction">];
+ let Subjects = SubjectList<[ObjCInstanceMethod], WarnDiag,
+ "ExpectedObjCInstanceMethod">;
+ // An AST node is created for this attribute, but is not used by other parts
+ // of the compiler. However, this node needs to exist in the AST because
+ // external tools rely on it.
+ let Documentation = [Undocumented];
}
def IBOutlet : InheritableAttr {
let Spellings = [GNU<"iboutlet">];
+// let Subjects = [ObjCIvar, ObjCProperty];
+ let Documentation = [Undocumented];
}
def IBOutletCollection : InheritableAttr {
let Spellings = [GNU<"iboutletcollection">];
let Args = [TypeArgument<"Interface", 1>];
+// let Subjects = [ObjCIvar, ObjCProperty];
+ let Documentation = [Undocumented];
}
def Malloc : InheritableAttr {
- let Spellings = [GNU<"malloc">, CXX11<"gnu", "malloc">];
+ let Spellings = [GCC<"malloc">];
+// let Subjects = [Function];
+ let Documentation = [Undocumented];
}
def MaxFieldAlignment : InheritableAttr {
+ // This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let Args = [UnsignedArgument<"Alignment">];
let SemaHandler = 0;
+ let Documentation = [Undocumented];
}
def MayAlias : InheritableAttr {
- let Spellings = [GNU<"may_alias">, CXX11<"gnu", "may_alias">];
+ // FIXME: this is a type attribute in GCC, but a declaration attribute here.
+ let Spellings = [GCC<"may_alias">];
+ let Documentation = [Undocumented];
}
def MSABI : InheritableAttr {
- let Spellings = [GNU<"ms_abi">, CXX11<"gnu", "ms_abi">];
+ let Spellings = [GCC<"ms_abi">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
-def MSP430Interrupt : InheritableAttr, TargetSpecificAttr {
- let Spellings = [];
+def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> {
+ // NOTE: If you add any additional spellings, ARMInterrupt's spellings must
+ // match.
+ let Spellings = [GNU<"interrupt">];
let Args = [UnsignedArgument<"Number">];
- let SemaHandler = 0;
+ let ParseKind = "Interrupt";
+ let HasCustomParsing = 1;
+ let Documentation = [Undocumented];
}
-def Mips16 : InheritableAttr, TargetSpecificAttr {
- let Spellings = [GNU<"mips16">, CXX11<"gnu", "mips16">];
- let Subjects = [Function];
+def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
+ let Spellings = [GCC<"mips16">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def Mode : Attr {
- let Spellings = [GNU<"mode">, CXX11<"gnu", "mode">];
+ let Spellings = [GCC<"mode">];
let Args = [IdentifierArgument<"Mode">];
+ let Documentation = [Undocumented];
}
def Naked : InheritableAttr {
- let Spellings = [GNU<"naked">, CXX11<"gnu", "naked">];
+ let Spellings = [GCC<"naked">, Declspec<"naked">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
}
def NeonPolyVectorType : TypeAttr {
let Spellings = [GNU<"neon_polyvector_type">];
let Args = [IntArgument<"NumElements">];
+ let Documentation = [Undocumented];
}
def NeonVectorType : TypeAttr {
let Spellings = [GNU<"neon_vector_type">];
let Args = [IntArgument<"NumElements">];
+ let Documentation = [Undocumented];
}
def ReturnsTwice : InheritableAttr {
- let Spellings = [GNU<"returns_twice">, CXX11<"gnu", "returns_twice">];
+ let Spellings = [GCC<"returns_twice">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
}
def NoCommon : InheritableAttr {
- let Spellings = [GNU<"nocommon">, CXX11<"gnu", "nocommon">];
+ let Spellings = [GCC<"nocommon">];
+ let Subjects = SubjectList<[Var]>;
+ let Documentation = [Undocumented];
}
def NoDebug : InheritableAttr {
let Spellings = [GNU<"nodebug">];
+ let Documentation = [Undocumented];
+}
+
+def NoDuplicate : InheritableAttr {
+ let Spellings = [GNU<"noduplicate">, CXX11<"clang", "noduplicate">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [NoDuplicateDocs];
}
def NoInline : InheritableAttr {
- let Spellings = [GNU<"noinline">, CXX11<"gnu", "noinline">];
+ let Spellings = [GCC<"noinline">, Declspec<"noinline">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
}
-def NoMips16 : InheritableAttr, TargetSpecificAttr {
- let Spellings = [GNU<"nomips16">, CXX11<"gnu", "nomips16">];
- let Subjects = [Function];
+def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
+ let Spellings = [GCC<"nomips16">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def NonNull : InheritableAttr {
- let Spellings = [GNU<"nonnull">, CXX11<"gnu", "nonnull">];
+ let Spellings = [GCC<"nonnull">];
+ let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
+ "ExpectedFunctionMethodOrParameter">;
let Args = [VariadicUnsignedArgument<"Args">];
let AdditionalMembers =
[{bool isNonNull(unsigned idx) const {
@@ -523,150 +841,226 @@
return true;
return false;
} }];
+ let Documentation = [Undocumented];
+}
+
+def ReturnsNonNull : InheritableAttr {
+ let Spellings = [GCC<"returns_nonnull">];
+ let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag,
+ "ExpectedFunctionOrMethod">;
+ let Documentation = [Undocumented];
}
def NoReturn : InheritableAttr {
- let Spellings = [GNU<"noreturn">, CXX11<"gnu", "noreturn">];
+ let Spellings = [GCC<"noreturn">, Declspec<"noreturn">];
// FIXME: Does GCC allow this on the function instead?
- let Subjects = [Function];
+ let Documentation = [Undocumented];
}
def NoInstrumentFunction : InheritableAttr {
- let Spellings = [GNU<"no_instrument_function">,
- CXX11<"gnu", "no_instrument_function">];
- let Subjects = [Function];
+ let Spellings = [GCC<"no_instrument_function">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
}
def NoThrow : InheritableAttr {
- let Spellings = [GNU<"nothrow">, CXX11<"gnu", "nothrow">];
-}
-
-def NSBridged : InheritableAttr {
- let Spellings = [GNU<"ns_bridged">];
- let Subjects = [Record];
- let Args = [IdentifierArgument<"BridgedType", 1>];
+ let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
+ let Documentation = [Undocumented];
}
def ObjCBridge : InheritableAttr {
let Spellings = [GNU<"objc_bridge">];
- let Subjects = [Record];
- let Args = [IdentifierArgument<"BridgedType", 1>];
+ let Subjects = SubjectList<[Record], ErrorDiag>;
+ let Args = [IdentifierArgument<"BridgedType">];
+ let Documentation = [Undocumented];
+}
+
+def ObjCBridgeMutable : InheritableAttr {
+ let Spellings = [GNU<"objc_bridge_mutable">];
+ let Subjects = SubjectList<[Record], ErrorDiag>;
+ let Args = [IdentifierArgument<"BridgedType">];
+ let Documentation = [Undocumented];
+}
+
+def ObjCBridgeRelated : InheritableAttr {
+ let Spellings = [GNU<"objc_bridge_related">];
+ let Subjects = SubjectList<[Record], ErrorDiag>;
+ let Args = [IdentifierArgument<"RelatedClass">,
+ IdentifierArgument<"ClassMethod">,
+ IdentifierArgument<"InstanceMethod">];
+ let HasCustomParsing = 1;
+ let Documentation = [Undocumented];
}
def NSReturnsRetained : InheritableAttr {
let Spellings = [GNU<"ns_returns_retained">];
- let Subjects = [ObjCMethod, Function];
+// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+ let Documentation = [Undocumented];
}
def NSReturnsNotRetained : InheritableAttr {
let Spellings = [GNU<"ns_returns_not_retained">];
- let Subjects = [ObjCMethod, Function];
+// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+ let Documentation = [Undocumented];
}
def NSReturnsAutoreleased : InheritableAttr {
let Spellings = [GNU<"ns_returns_autoreleased">];
- let Subjects = [ObjCMethod, Function];
+// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+ let Documentation = [Undocumented];
}
def NSConsumesSelf : InheritableAttr {
let Spellings = [GNU<"ns_consumes_self">];
- let Subjects = [ObjCMethod];
+ let Subjects = SubjectList<[ObjCMethod]>;
+ let Documentation = [Undocumented];
}
def NSConsumed : InheritableParamAttr {
let Spellings = [GNU<"ns_consumed">];
- let Subjects = [ParmVar];
+ let Subjects = SubjectList<[ParmVar]>;
+ let Documentation = [Undocumented];
}
def ObjCException : InheritableAttr {
let Spellings = [GNU<"objc_exception">];
+ let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def ObjCMethodFamily : InheritableAttr {
let Spellings = [GNU<"objc_method_family">];
- let Subjects = [ObjCMethod];
+ let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
let Args = [EnumArgument<"Family", "FamilyKind",
["none", "alloc", "copy", "init", "mutableCopy", "new"],
["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init",
"OMF_mutableCopy", "OMF_new"]>];
+ let Documentation = [ObjCMethodFamilyDocs];
}
def ObjCNSObject : InheritableAttr {
let Spellings = [GNU<"NSObject">];
+ let Documentation = [Undocumented];
}
def ObjCPreciseLifetime : InheritableAttr {
let Spellings = [GNU<"objc_precise_lifetime">];
- let Subjects = [Var];
+ let Subjects = SubjectList<[Var], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def ObjCReturnsInnerPointer : InheritableAttr {
let Spellings = [GNU<"objc_returns_inner_pointer">];
- let Subjects = [ObjCMethod, ObjCProperty];
+ let Subjects = SubjectList<[ObjCMethod, ObjCProperty], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def ObjCRequiresSuper : InheritableAttr {
let Spellings = [GNU<"objc_requires_super">];
- let Subjects = [ObjCMethod];
+ let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
+ let Documentation = [ObjCRequiresSuperDocs];
}
def ObjCRootClass : InheritableAttr {
let Spellings = [GNU<"objc_root_class">];
- let Subjects = [ObjCInterface];
+ let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+ let Documentation = [Undocumented];
+}
+
+def ObjCExplicitProtocolImpl : InheritableAttr {
+ let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">];
+ let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
+ let Documentation = [Undocumented];
+}
+
+def ObjCDesignatedInitializer : Attr {
+ let Spellings = [GNU<"objc_designated_initializer">];
+ let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag,
+ "ExpectedObjCInterfaceDeclInitMethod">;
+ let Documentation = [Undocumented];
+}
+
+def OptimizeNone : InheritableAttr {
+ let Spellings = [GNU<"optnone">, CXX11<"clang", "optnone">];
+ let Subjects = SubjectList<[Function, ObjCMethod]>;
+ let Documentation = [OptnoneDocs];
}
def Overloadable : Attr {
let Spellings = [GNU<"overloadable">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [OverloadableDocs];
}
def Override : InheritableAttr {
- let Spellings = [];
+ let Spellings = [Keyword<"override">];
let SemaHandler = 0;
+ let Documentation = [Undocumented];
}
def Ownership : InheritableAttr {
let Spellings = [GNU<"ownership_holds">, GNU<"ownership_returns">,
GNU<"ownership_takes">];
- let DistinctSpellings = 1;
- let Args = [EnumArgument<"OwnKind", "OwnershipKind",
- ["ownership_holds", "ownership_returns", "ownership_takes"],
- ["Holds", "Returns", "Takes"]>,
- StringArgument<"Module">, VariadicUnsignedArgument<"Args">];
- let HasCustomParsing = 1;
+ let Accessors = [Accessor<"isHolds", [GNU<"ownership_holds">]>,
+ Accessor<"isReturns", [GNU<"ownership_returns">]>,
+ Accessor<"isTakes", [GNU<"ownership_takes">]>];
+ let AdditionalMembers = [{
+ enum OwnershipKind { Holds, Returns, Takes };
+ OwnershipKind getOwnKind() const {
+ return isHolds() ? Holds :
+ isTakes() ? Takes :
+ Returns;
+ }
+ }];
+ let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">];
+ let Subjects = SubjectList<[HasFunctionProto], WarnDiag, "ExpectedFunction">;
+ let Documentation = [Undocumented];
}
def Packed : InheritableAttr {
- let Spellings = [GNU<"packed">, CXX11<"gnu", "packed">];
+ let Spellings = [GCC<"packed">];
+// let Subjects = [Tag, Field];
+ let Documentation = [Undocumented];
}
def PnaclCall : InheritableAttr {
let Spellings = [GNU<"pnaclcall">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
def IntelOclBicc : InheritableAttr {
let Spellings = [GNU<"intel_ocl_bicc">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
def Pcs : InheritableAttr {
- let Spellings = [GNU<"pcs">, CXX11<"gnu", "pcs">];
+ let Spellings = [GCC<"pcs">];
let Args = [EnumArgument<"PCS", "PCSType",
["aapcs", "aapcs-vfp"],
["AAPCS", "AAPCS_VFP"]>];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [PcsDocs];
}
def Pure : InheritableAttr {
- let Spellings = [GNU<"pure">, CXX11<"gnu", "pure">];
+ let Spellings = [GCC<"pure">];
+ let Documentation = [Undocumented];
}
-def Regparm : InheritableAttr {
- let Spellings = [GNU<"regparm">, CXX11<"gnu", "regparm">];
+def Regparm : TypeAttr {
+ let Spellings = [GCC<"regparm">];
let Args = [UnsignedArgument<"NumParams">];
+ let Documentation = [Undocumented];
}
def ReqdWorkGroupSize : InheritableAttr {
let Spellings = [GNU<"reqd_work_group_size">];
let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
UnsignedArgument<"ZDim">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def WorkGroupSizeHint : InheritableAttr {
@@ -674,102 +1068,137 @@
let Args = [UnsignedArgument<"XDim">,
UnsignedArgument<"YDim">,
UnsignedArgument<"ZDim">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def InitPriority : InheritableAttr {
let Spellings = [GNU<"init_priority">];
let Args = [UnsignedArgument<"Priority">];
+ let Subjects = SubjectList<[Var], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def Section : InheritableAttr {
- let Spellings = [GNU<"section">, CXX11<"gnu", "section">];
+ let Spellings = [GCC<"section">];
let Args = [StringArgument<"Name">];
+ let Subjects = SubjectList<[Function, GlobalVar,
+ ObjCMethod, ObjCProperty], ErrorDiag,
+ "ExpectedFunctionGlobalVarMethodOrProperty">;
+ let Documentation = [Undocumented];
}
def Sentinel : InheritableAttr {
- let Spellings = [GNU<"sentinel">, CXX11<"gnu", "sentinel">];
+ let Spellings = [GCC<"sentinel">];
let Args = [DefaultIntArgument<"Sentinel", 0>,
DefaultIntArgument<"NullPos", 0>];
+// let Subjects = SubjectList<[Function, ObjCMethod, Block, Var]>;
+ let Documentation = [Undocumented];
}
def StdCall : InheritableAttr {
- let Spellings = [GNU<"stdcall">, CXX11<"gnu", "stdcall">,
- Keyword<"__stdcall">, Keyword<"_stdcall">];
+ let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
def SysVABI : InheritableAttr {
- let Spellings = [GNU<"sysv_abi">, CXX11<"gnu", "sysv_abi">];
+ let Spellings = [GCC<"sysv_abi">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
def ThisCall : InheritableAttr {
- let Spellings = [GNU<"thiscall">, CXX11<"gnu", "thiscall">,
- Keyword<"__thiscall">, Keyword<"_thiscall">];
+ let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">,
+ Keyword<"_thiscall">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
def Pascal : InheritableAttr {
let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
+// let Subjects = [Function, ObjCMethod];
+ let Documentation = [Undocumented];
}
def TransparentUnion : InheritableAttr {
- let Spellings = [GNU<"transparent_union">, CXX11<"gnu", "transparent_union">];
+ let Spellings = [GCC<"transparent_union">];
+// let Subjects = SubjectList<[Record, TypedefName]>;
+ let Documentation = [Undocumented];
}
def Unavailable : InheritableAttr {
let Spellings = [GNU<"unavailable">];
let Args = [StringArgument<"Message", 1>];
+ let Documentation = [Undocumented];
}
def ArcWeakrefUnavailable : InheritableAttr {
let Spellings = [GNU<"objc_arc_weak_reference_unavailable">];
- let Subjects = [ObjCInterface];
+ let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def ObjCGC : TypeAttr {
let Spellings = [GNU<"objc_gc">];
let Args = [IdentifierArgument<"Kind">];
+ let Documentation = [Undocumented];
}
def ObjCOwnership : InheritableAttr {
let Spellings = [GNU<"objc_ownership">];
let Args = [IdentifierArgument<"Kind">];
let ASTNode = 0;
+ let Documentation = [Undocumented];
}
def ObjCRequiresPropertyDefs : InheritableAttr {
let Spellings = [GNU<"objc_requires_property_definitions">];
- let Subjects = [ObjCInterface];
+ let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def Unused : InheritableAttr {
- let Spellings = [GNU<"unused">, CXX11<"gnu", "unused">];
+ let Spellings = [GCC<"unused">];
+ let Subjects = SubjectList<[Var, ObjCIvar, Type, Label, Field, ObjCMethod,
+ FunctionLike], WarnDiag,
+ "ExpectedVariableFunctionOrLabel">;
+ let Documentation = [Undocumented];
}
def Used : InheritableAttr {
- let Spellings = [GNU<"used">, CXX11<"gnu", "used">];
+ let Spellings = [GCC<"used">];
+ let Documentation = [Undocumented];
}
def Uuid : InheritableAttr {
- let Spellings = [GNU<"uuid">];
+ let Spellings = [Declspec<"uuid">];
let Args = [StringArgument<"Guid">];
- let Subjects = [CXXRecord];
+// let Subjects = SubjectList<[CXXRecord]>;
+ let LangOpts = [MicrosoftExt, Borland];
+ let Documentation = [Undocumented];
}
def VectorSize : TypeAttr {
- let Spellings = [GNU<"vector_size">, CXX11<"gnu", "vector_size">];
+ let Spellings = [GCC<"vector_size">];
let Args = [ExprArgument<"NumBytes">];
+ let Documentation = [Undocumented];
}
def VecTypeHint : InheritableAttr {
let Spellings = [GNU<"vec_type_hint">];
let Args = [TypeArgument<"TypeHint">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def Visibility : InheritableAttr {
let Clone = 0;
- let Spellings = [GNU<"visibility">, CXX11<"gnu", "visibility">];
+ let Spellings = [GCC<"visibility">];
let Args = [EnumArgument<"Visibility", "VisibilityType",
["default", "hidden", "internal", "protected"],
["Default", "Hidden", "Hidden", "Protected"]>];
+ let Documentation = [Undocumented];
}
def TypeVisibility : InheritableAttr {
@@ -778,80 +1207,227 @@
let Args = [EnumArgument<"Visibility", "VisibilityType",
["default", "hidden", "internal", "protected"],
["Default", "Hidden", "Hidden", "Protected"]>];
+// let Subjects = [Tag, ObjCInterface, Namespace];
+ let Documentation = [Undocumented];
}
def VecReturn : InheritableAttr {
let Spellings = [GNU<"vecreturn">];
- let Subjects = [CXXRecord];
+ let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
+ let Documentation = [Undocumented];
}
def WarnUnused : InheritableAttr {
let Spellings = [GNU<"warn_unused">];
- let Subjects = [Record];
+ let Subjects = SubjectList<[Record]>;
+ let Documentation = [Undocumented];
}
def WarnUnusedResult : InheritableAttr {
- let Spellings = [GNU<"warn_unused_result">,
- CXX11<"clang", "warn_unused_result">,
- CXX11<"gnu", "warn_unused_result">];
+ let Spellings = [GCC<"warn_unused_result">,
+ CXX11<"clang", "warn_unused_result">];
+ let Subjects = SubjectList<[ObjCMethod, CXXRecord, FunctionLike], WarnDiag,
+ "ExpectedFunctionMethodOrClass">;
+ let Documentation = [Undocumented];
}
def Weak : InheritableAttr {
- let Spellings = [GNU<"weak">, CXX11<"gnu", "weak">];
+ let Spellings = [GCC<"weak">];
+ let Subjects = SubjectList<[Var, Function, CXXRecord]>;
+ let Documentation = [Undocumented];
}
def WeakImport : InheritableAttr {
let Spellings = [GNU<"weak_import">];
+ let Documentation = [Undocumented];
}
def WeakRef : InheritableAttr {
- let Spellings = [GNU<"weakref">, CXX11<"gnu", "weakref">];
+ let Spellings = [GCC<"weakref">];
// A WeakRef that has an argument is treated as being an AliasAttr
let Args = [StringArgument<"Aliasee", 1>];
+ let Subjects = SubjectList<[Var, Function], ErrorDiag>;
+ let Documentation = [Undocumented];
}
-def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr {
- let Spellings = [];
+def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> {
+ let Spellings = [GNU<"force_align_arg_pointer">];
+ // Technically, this appertains to a FunctionDecl, but the target-specific
+ // code silently allows anything function-like (such as typedefs or function
+ // pointers), but does not apply the attribute to them.
+ let Documentation = [Undocumented];
}
// Attribute to disable AddressSanitizer (or equivalent) checks.
def NoSanitizeAddress : InheritableAttr {
- let Spellings = [GNU<"no_address_safety_analysis">,
- GNU<"no_sanitize_address">,
- CXX11<"gnu", "no_address_safety_analysis">,
- CXX11<"gnu", "no_sanitize_address">];
+ let Spellings = [GCC<"no_address_safety_analysis">,
+ GCC<"no_sanitize_address">];
+ let Subjects = SubjectList<[Function, FunctionTemplate], 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 Documentation = [NoSanitizeThreadDocs];
}
// Attribute to disable MemorySanitizer checks.
def NoSanitizeMemory : InheritableAttr {
let Spellings = [GNU<"no_sanitize_memory">];
+ let Subjects = SubjectList<[Function, FunctionTemplate], ErrorDiag>;
+ let Documentation = [NoSanitizeMemoryDocs];
}
// C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
def GuardedVar : InheritableAttr {
let Spellings = [GNU<"guarded_var">];
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
+ let Documentation = [Undocumented];
}
def PtGuardedVar : InheritableAttr {
let Spellings = [GNU<"pt_guarded_var">];
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
+ let Documentation = [Undocumented];
}
def Lockable : InheritableAttr {
let Spellings = [GNU<"lockable">];
+ let Subjects = SubjectList<[Record]>;
+ let Documentation = [Undocumented];
+ let ASTNode = 0; // Replaced by Capability
}
def ScopedLockable : InheritableAttr {
let Spellings = [GNU<"scoped_lockable">];
+ let Subjects = SubjectList<[Record]>;
+ let Documentation = [Undocumented];
+}
+
+def Capability : InheritableAttr {
+ let Spellings = [GNU<"capability">, CXX11<"clang", "capability">,
+ GNU<"shared_capability">,
+ CXX11<"clang", "shared_capability">];
+ let Subjects = SubjectList<[Struct, TypedefName], ErrorDiag,
+ "ExpectedStructOrTypedef">;
+ let Args = [StringArgument<"Name">];
+ let Accessors = [Accessor<"isShared",
+ [GNU<"shared_capability">,
+ CXX11<"clang","shared_capability">]>];
+ let Documentation = [Undocumented];
+ let AdditionalMembers = [{
+ bool isMutex() const { return getName().equals_lower("mutex"); }
+ bool isRole() const { return getName().equals_lower("role"); }
+ }];
+}
+
+def AssertCapability : InheritableAttr {
+ let Spellings = [GNU<"assert_capability">,
+ CXX11<"clang", "assert_capability">,
+ GNU<"assert_shared_capability">,
+ CXX11<"clang", "assert_shared_capability">];
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let LateParsed = 1;
+ let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Args = [ExprArgument<"Expr">];
+ let Accessors = [Accessor<"isShared",
+ [GNU<"assert_shared_capability">,
+ CXX11<"clang", "assert_shared_capability">]>];
+ let Documentation = [AssertCapabilityDocs];
+}
+
+def AcquireCapability : InheritableAttr {
+ let Spellings = [GNU<"acquire_capability">,
+ CXX11<"clang", "acquire_capability">,
+ GNU<"acquire_shared_capability">,
+ CXX11<"clang", "acquire_shared_capability">,
+ GNU<"exclusive_lock_function">,
+ GNU<"shared_lock_function">];
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let LateParsed = 1;
+ let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Args = [VariadicExprArgument<"Args">];
+ let Accessors = [Accessor<"isShared",
+ [GNU<"acquire_shared_capability">,
+ CXX11<"clang", "acquire_shared_capability">,
+ GNU<"shared_lock_function">]>];
+ let Documentation = [AcquireCapabilityDocs];
+}
+
+def TryAcquireCapability : InheritableAttr {
+ let Spellings = [GNU<"try_acquire_capability">,
+ CXX11<"clang", "try_acquire_capability">,
+ GNU<"try_acquire_shared_capability">,
+ CXX11<"clang", "try_acquire_shared_capability">];
+ let Subjects = SubjectList<[Function, FunctionTemplate],
+ ErrorDiag>;
+ let LateParsed = 1;
+ let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
+ let Accessors = [Accessor<"isShared",
+ [GNU<"try_acquire_shared_capability">,
+ CXX11<"clang", "try_acquire_shared_capability">]>];
+ let Documentation = [TryAcquireCapabilityDocs];
+}
+
+def ReleaseCapability : InheritableAttr {
+ let Spellings = [GNU<"release_capability">,
+ CXX11<"clang", "release_capability">,
+ GNU<"release_shared_capability">,
+ CXX11<"clang", "release_shared_capability">,
+ GNU<"release_generic_capability">,
+ CXX11<"clang", "release_generic_capability">,
+ GNU<"unlock_function">];
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let LateParsed = 1;
+ let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Args = [VariadicExprArgument<"Args">];
+ let Accessors = [Accessor<"isShared",
+ [GNU<"release_shared_capability">,
+ CXX11<"clang", "release_shared_capability">]>,
+ Accessor<"isGeneric",
+ [GNU<"release_generic_capability">,
+ CXX11<"clang", "release_generic_capability">,
+ GNU<"unlock_function">]>];
+ let Documentation = [ReleaseCapabilityDocs];
+}
+
+def RequiresCapability : InheritableAttr {
+ let Spellings = [GNU<"requires_capability">,
+ CXX11<"clang", "requires_capability">,
+ GNU<"exclusive_locks_required">,
+ GNU<"requires_shared_capability">,
+ CXX11<"clang", "requires_shared_capability">,
+ GNU<"shared_locks_required">];
+ let Args = [VariadicExprArgument<"Args">];
+ let LateParsed = 1;
+ let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Accessors = [Accessor<"isShared", [GNU<"requires_shared_capability">,
+ GNU<"shared_locks_required">,
+ CXX11<"clang","requires_shared_capability">]>];
+ let Documentation = [Undocumented];
}
def NoThreadSafetyAnalysis : InheritableAttr {
let Spellings = [GNU<"no_thread_safety_analysis">];
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Documentation = [Undocumented];
}
def GuardedBy : InheritableAttr {
@@ -859,6 +1435,11 @@
let Args = [ExprArgument<"Arg">];
let LateParsed = 1;
let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
+ let Documentation = [Undocumented];
}
def PtGuardedBy : InheritableAttr {
@@ -866,6 +1447,11 @@
let Args = [ExprArgument<"Arg">];
let LateParsed = 1;
let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
+ let Documentation = [Undocumented];
}
def AcquiredAfter : InheritableAttr {
@@ -873,6 +1459,11 @@
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
+ let Documentation = [Undocumented];
}
def AcquiredBefore : InheritableAttr {
@@ -880,20 +1471,11 @@
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
-}
-
-def ExclusiveLockFunction : InheritableAttr {
- let Spellings = [GNU<"exclusive_lock_function">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
-}
-
-def SharedLockFunction : InheritableAttr {
- let Spellings = [GNU<"shared_lock_function">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
+ let Documentation = [Undocumented];
}
def AssertExclusiveLock : InheritableAttr {
@@ -901,6 +1483,10 @@
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Documentation = [Undocumented];
}
def AssertSharedLock : InheritableAttr {
@@ -908,6 +1494,10 @@
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Documentation = [Undocumented];
}
// The first argument is an integer or boolean value specifying the return value
@@ -917,6 +1507,10 @@
let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Documentation = [Undocumented];
}
// The first argument is an integer or boolean value specifying the return value
@@ -926,13 +1520,10 @@
let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
-}
-
-def UnlockFunction : InheritableAttr {
- let Spellings = [GNU<"unlock_function">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Documentation = [Undocumented];
}
def LockReturned : InheritableAttr {
@@ -940,6 +1531,9 @@
let Args = [ExprArgument<"Arg">];
let LateParsed = 1;
let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Documentation = [Undocumented];
}
def LocksExcluded : InheritableAttr {
@@ -947,70 +1541,78 @@
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
-}
-
-def ExclusiveLocksRequired : InheritableAttr {
- let Spellings = [GNU<"exclusive_locks_required">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
-}
-
-def SharedLocksRequired : InheritableAttr {
- let Spellings = [GNU<"shared_locks_required">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
+ let ParseArgumentsAsUnevaluated = 1;
+ let DuplicatesAllowedWhileMerging = 1;
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
+ let Documentation = [Undocumented];
}
// C/C++ consumed attributes.
def Consumable : InheritableAttr {
let Spellings = [GNU<"consumable">];
- let Subjects = [CXXRecord];
+ let Subjects = SubjectList<[CXXRecord]>;
let Args = [EnumArgument<"DefaultState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
+ let Documentation = [ConsumableDocs];
+}
+
+def ConsumableAutoCast : InheritableAttr {
+ let Spellings = [GNU<"consumable_auto_cast_state">];
+ let Subjects = SubjectList<[CXXRecord]>;
+ let Documentation = [Undocumented];
+}
+
+def ConsumableSetOnRead : InheritableAttr {
+ let Spellings = [GNU<"consumable_set_state_on_read">];
+ let Subjects = SubjectList<[CXXRecord]>;
+ let Documentation = [Undocumented];
}
def CallableWhen : InheritableAttr {
let Spellings = [GNU<"callable_when">];
- let Subjects = [CXXMethod];
+ let Subjects = SubjectList<[CXXMethod]>;
let Args = [VariadicEnumArgument<"CallableState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
+ let Documentation = [CallableWhenDocs];
}
def ParamTypestate : InheritableAttr {
let Spellings = [GNU<"param_typestate">];
- let Subjects = [ParmVar];
+ let Subjects = SubjectList<[ParmVar]>;
let Args = [EnumArgument<"ParamState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
+ let Documentation = [ParamTypestateDocs];
}
def ReturnTypestate : InheritableAttr {
let Spellings = [GNU<"return_typestate">];
- let Subjects = [Function, ParmVar];
+ let Subjects = SubjectList<[Function, ParmVar]>;
let Args = [EnumArgument<"State", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
+ let Documentation = [ReturnTypestateDocs];
}
def SetTypestate : InheritableAttr {
let Spellings = [GNU<"set_typestate">];
- let Subjects = [CXXMethod];
+ let Subjects = SubjectList<[CXXMethod]>;
let Args = [EnumArgument<"NewState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
["Unknown", "Consumed", "Unconsumed"]>];
+ let Documentation = [SetTypestateDocs];
}
def TestTypestate : InheritableAttr {
let Spellings = [GNU<"test_typestate">];
- let Subjects = [CXXMethod];
+ let Subjects = SubjectList<[CXXMethod]>;
let Args = [EnumArgument<"TestState", "ConsumedState",
["consumed", "unconsumed"],
["Consumed", "Unconsumed"]>];
+ let Documentation = [TestTypestateDocs];
}
// Type safety attributes for `void *' pointers and type tags.
@@ -1022,8 +1624,8 @@
UnsignedArgument<"ArgumentIdx">,
UnsignedArgument<"TypeTagIdx">,
BoolArgument<"IsPointer">];
- let Subjects = [Function];
let HasCustomParsing = 1;
+ let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs];
}
def TypeTagForDatatype : InheritableAttr {
@@ -1032,8 +1634,9 @@
TypeArgument<"MatchingCType">,
BoolArgument<"LayoutCompatible">,
BoolArgument<"MustBeNull">];
- let Subjects = [Var];
+// let Subjects = SubjectList<[Var], ErrorDiag>;
let HasCustomParsing = 1;
+ let Documentation = [TypeTagForDatatypeDocs];
}
// Microsoft-related attributes
@@ -1043,63 +1646,103 @@
}
def MsStruct : InheritableAttr {
- let Spellings = [Declspec<"ms_struct">];
+ let Spellings = [GCC<"ms_struct">];
+ let Subjects = SubjectList<[Record]>;
+ let Documentation = [Undocumented];
}
-def DLLExport : InheritableAttr, TargetSpecificAttr {
- let Spellings = [Declspec<"dllexport">];
+def DLLExport : InheritableAttr, TargetSpecificAttr<TargetX86Win> {
+ let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
+ let Subjects = SubjectList<[Function, Var]>;
+ let Documentation = [Undocumented];
}
-def DLLImport : InheritableAttr, TargetSpecificAttr {
- let Spellings = [Declspec<"dllimport">];
-}
-
-def ForceInline : InheritableAttr {
- let Spellings = [Keyword<"__forceinline">];
+def DLLImport : InheritableAttr, TargetSpecificAttr<TargetX86Win> {
+ 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 Documentation = [Undocumented];
}
def SelectAny : InheritableAttr {
let Spellings = [Declspec<"selectany">];
+ let LangOpts = [MicrosoftExt];
+ let Documentation = [Undocumented];
}
-def Win64 : InheritableAttr {
+def Win64 : IgnoredAttr {
let Spellings = [Keyword<"__w64">];
+ let LangOpts = [MicrosoftExt];
}
def Ptr32 : TypeAttr {
let Spellings = [Keyword<"__ptr32">];
+ let Documentation = [Undocumented];
}
def Ptr64 : TypeAttr {
let Spellings = [Keyword<"__ptr64">];
+ let Documentation = [Undocumented];
}
def SPtr : TypeAttr {
let Spellings = [Keyword<"__sptr">];
+ let Documentation = [Undocumented];
}
def UPtr : TypeAttr {
let Spellings = [Keyword<"__uptr">];
+ let Documentation = [Undocumented];
}
-class MSInheritanceAttr : InheritableAttr;
+def MSInheritance : InheritableAttr {
+ let LangOpts = [MicrosoftExt];
+ let Args = [DefaultBoolArgument<"BestCase", 1>];
+ let Spellings = [Keyword<"__single_inheritance">,
+ Keyword<"__multiple_inheritance">,
+ Keyword<"__virtual_inheritance">,
+ Keyword<"__unspecified_inheritance">];
+ let AdditionalMembers = [{
+ static bool hasVBPtrOffsetField(Spelling Inheritance) {
+ return Inheritance == Keyword_unspecified_inheritance;
+ }
-def SingleInheritance : MSInheritanceAttr {
- let Spellings = [Keyword<"__single_inheritance">];
+ // Only member pointers to functions need a this adjustment, since it can be
+ // combined with the field offset for data pointers.
+ static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) {
+ return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance;
+ }
+
+ static bool hasVBTableOffsetField(Spelling Inheritance) {
+ return Inheritance >= Keyword_virtual_inheritance;
+ }
+
+ static bool hasOnlyOneField(bool IsMemberFunction,
+ Spelling Inheritance) {
+ if (IsMemberFunction)
+ return Inheritance <= Keyword_single_inheritance;
+ return Inheritance <= Keyword_multiple_inheritance;
+ }
+ }];
+ let Documentation = [MSInheritanceDocs];
}
-def MultipleInheritance : MSInheritanceAttr {
- let Spellings = [Keyword<"__multiple_inheritance">];
-}
-
-def VirtualInheritance : MSInheritanceAttr {
- let Spellings = [Keyword<"__virtual_inheritance">];
-}
-
-// This attribute doesn't have any spellings, but we can apply it implicitly to
-// incomplete types that lack any of the other attributes.
-def UnspecifiedInheritance : MSInheritanceAttr {
+def MSVtorDisp : InheritableAttr {
+ // This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
+ let Args = [UnsignedArgument<"vdm">];
+ let SemaHandler = 0;
+
+ let AdditionalMembers = [{
+ enum Mode {
+ Never,
+ ForVBaseOverride,
+ ForVFTable
+ };
+
+ Mode getVtorDispMode() const { return Mode(vdm); }
+ }];
+ let Documentation = [Undocumented];
}
def Unaligned : IgnoredAttr {
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
new file mode 100644
index 0000000..2f62175
--- /dev/null
+++ b/include/clang/Basic/AttrDocs.td
@@ -0,0 +1,970 @@
+//==--- AttrDocs.td - Attribute documentation ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+def GlobalDocumentation {
+ code Intro =[{..
+ -------------------------------------------------------------------
+ NOTE: This file is automatically generated by running clang-tblgen
+ -gen-attr-docs. Do not edit this file by hand!!
+ -------------------------------------------------------------------
+
+===================
+Attributes in Clang
+===================
+.. contents::
+ :local:
+
+Introduction
+============
+
+This page lists the attributes currently supported by Clang.
+}];
+}
+
+def TLSModelDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``tls_model`` attribute allows you to specify which thread-local storage
+model to use. It accepts the following strings:
+
+* global-dynamic
+* local-dynamic
+* initial-exec
+* local-exec
+
+TLS models are mutually exclusive.
+ }];
+}
+
+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``
+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.
+ }];
+}
+
+def C11NoReturnDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+A function declared as ``_Noreturn`` shall not return to its caller. The
+compiler will generate a diagnostic for a function declared as ``_Noreturn``
+that appears to be capable of returning to its caller.
+ }];
+}
+
+def CXX11NoReturnDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+A function declared as ``[[noreturn]]`` shall not return to its caller. The
+compiler will generate a diagnostic for a function declared as ``[[noreturn]]``
+that appears to be capable of returning to its caller.
+ }];
+}
+
+def AssertCapabilityDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability)";
+ let Content = [{
+Marks a function that dynamically tests whether a capability is held, and halts
+the program if it is not held.
+ }];
+}
+
+def AcquireCapabilityDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability)";
+ let Content = [{
+Marks a function as acquiring a capability.
+ }];
+}
+
+def TryAcquireCapabilityDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability)";
+ let Content = [{
+Marks a function that attempts to acquire a capability. This function may fail to
+actually acquire the capability; they accept a Boolean value determining
+whether acquiring the capability means success (true), or failing to acquire
+the capability means success (false).
+ }];
+}
+
+def ReleaseCapabilityDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability)";
+ let Content = [{
+Marks a function as releasing a capability.
+ }];
+}
+def EnableIfDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``enable_if`` attribute can be placed on function declarations to control
+which overload is selected based on the values of the function's arguments.
+When combined with the ``overloadable`` attribute, this feature is also
+available in C.
+
+.. code-block:: c++
+
+ int isdigit(int c);
+ int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
+
+ void foo(char c) {
+ isdigit(c);
+ isdigit(10);
+ isdigit(-10); // results in a compile-time error.
+ }
+
+The enable_if attribute takes two arguments, the first is an expression written
+in terms of the function parameters, the second is a string explaining why this
+overload candidate could not be selected to be displayed in diagnostics. The
+expression is part of the function signature for the purposes of determining
+whether it is a redeclaration (following the rules used when determining
+whether a C++ template specialization is ODR-equivalent), but is not part of
+the type.
+
+The enable_if expression is evaluated as if it were the body of a
+bool-returning constexpr function declared with the arguments of the function
+it is being applied to, then called with the parameters at the callsite. If the
+result is false or could not be determined through constant expression
+evaluation, then this overload will not be chosen and the provided string may
+be used in a diagnostic if the compile fails as a result.
+
+Because the enable_if expression is an unevaluated context, there are no global
+state changes, nor the ability to pass information from the enable_if
+expression to the function body. For example, suppose we want calls to
+strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of
+strbuf) only if the size of strbuf can be determined:
+
+.. code-block:: c++
+
+ __attribute__((always_inline))
+ static inline size_t strnlen(const char *s, size_t maxlen)
+ __attribute__((overloadable))
+ __attribute__((enable_if(__builtin_object_size(s, 0) != -1))),
+ "chosen when the buffer size is known but 'maxlen' is not")))
+ {
+ return strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
+ }
+
+Multiple enable_if attributes may be applied to a single declaration. In this
+case, the enable_if expressions are evaluated from left to right in the
+following manner. First, the candidates whose enable_if expressions evaluate to
+false or cannot be evaluated are discarded. If the remaining candidates do not
+share ODR-equivalent enable_if expressions, the overload resolution is
+ambiguous. Otherwise, enable_if overload resolution continues with the next
+enable_if attribute on the candidates that have not been discarded and have
+remaining enable_if attributes. In this way, we pick the most specific
+overload out of a number of viable overloads using enable_if.
+
+.. code-block:: c++
+
+ void f() __attribute__((enable_if(true, ""))); // #1
+ void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2
+
+ void g(int i, int j) __attribute__((enable_if(i, ""))); // #1
+ void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2
+
+In this example, a call to f() is always resolved to #2, as the first enable_if
+expression is ODR-equivalent for both declarations, but #1 does not have another
+enable_if expression to continue evaluating, so the next round of evaluation has
+only a single candidate. In a call to g(1, 1), the call is ambiguous even though
+#2 has more enable_if attributes, because the first enable_if expressions are
+not ODR-equivalent.
+
+Query for this feature with ``__has_attribute(enable_if)``.
+ }];
+}
+
+def OverloadableDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang provides support for C++ function overloading in C. Function overloading
+in C is introduced using the ``overloadable`` attribute. For example, one
+might provide several overloaded versions of a ``tgsin`` function that invokes
+the appropriate standard function computing the sine of a value with ``float``,
+``double``, or ``long double`` precision:
+
+.. code-block:: c
+
+ #include <math.h>
+ float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
+ double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
+ long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }
+
+Given these declarations, one can call ``tgsin`` with a ``float`` value to
+receive a ``float`` result, with a ``double`` to receive a ``double`` result,
+etc. Function overloading in C follows the rules of C++ function overloading
+to pick the best overload given the call arguments, with a few C-specific
+semantics:
+
+* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a
+ floating-point promotion (per C99) rather than as a floating-point conversion
+ (as in C++).
+
+* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is
+ considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are
+ compatible types.
+
+* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
+ and ``U`` are compatible types. This conversion is given "conversion" rank.
+
+The declaration of ``overloadable`` functions is restricted to function
+declarations and definitions. Most importantly, if any function with a given
+name is given the ``overloadable`` attribute, then all function declarations
+and definitions with that name (and in that scope) must have the
+``overloadable`` attribute. This rule even applies to redeclarations of
+functions whose original declaration had the ``overloadable`` attribute, e.g.,
+
+.. code-block:: c
+
+ int f(int) __attribute__((overloadable));
+ float f(float); // error: declaration of "f" must have the "overloadable" attribute
+
+ int g(int) __attribute__((overloadable));
+ int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute
+
+Functions marked ``overloadable`` must have prototypes. Therefore, the
+following code is ill-formed:
+
+.. code-block:: c
+
+ int h() __attribute__((overloadable)); // error: h does not have a prototype
+
+However, ``overloadable`` functions are allowed to use a ellipsis even if there
+are no named parameters (as is permitted in C++). This feature is particularly
+useful when combined with the ``unavailable`` attribute:
+
+.. code-block:: c++
+
+ void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error
+
+Functions declared with the ``overloadable`` attribute have their names mangled
+according to the same rules as C++ function names. For example, the three
+``tgsin`` functions in our motivating example get the mangled names
+``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two
+caveats to this use of name mangling:
+
+* Future versions of Clang may change the name mangling of functions overloaded
+ in C, so you should not depend on an specific mangling. To be completely
+ safe, we strongly urge the use of ``static inline`` with ``overloadable``
+ functions.
+
+* The ``overloadable`` attribute has almost no meaning when used in C++,
+ because names will already be mangled and functions are already overloadable.
+ However, when an ``overloadable`` function occurs within an ``extern "C"``
+ linkage specification, it's name *will* be mangled in the same way as it
+ would in C.
+
+Query for this feature with ``__has_extension(attribute_overloadable)``.
+ }];
+}
+
+def ObjCMethodFamilyDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Many methods in Objective-C have conventional meanings determined by their
+selectors. It is sometimes useful to be able to mark a method as having a
+particular conventional meaning despite not having the right selector, or as
+not having the conventional meaning that its selector would suggest. For these
+use cases, we provide an attribute to specifically describe the "method family"
+that a method belongs to.
+
+**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of
+``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This
+attribute can only be placed at the end of a method declaration:
+
+.. code-block:: objc
+
+ - (NSString *)initMyStringValue __attribute__((objc_method_family(none)));
+
+Users who do not wish to change the conventional meaning of a method, and who
+merely want to document its non-standard retain and release semantics, should
+use the retaining behavior attributes (``ns_returns_retained``,
+``ns_returns_not_retained``, etc).
+
+Query for this feature with ``__has_attribute(objc_method_family)``.
+ }];
+}
+
+def NoDuplicateDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``noduplicate`` attribute can be placed on function declarations to control
+whether function calls to this function can be duplicated or not as a result of
+optimizations. This is required for the implementation of functions with
+certain special requirements, like the OpenCL "barrier" function, that might
+need to be run concurrently by all the threads that are executing in lockstep
+on the hardware. For example this attribute applied on the function
+"nodupfunc" in the code below avoids that:
+
+.. code-block:: c
+
+ void nodupfunc() __attribute__((noduplicate));
+ // Setting it as a C++11 attribute is also valid
+ // void nodupfunc() [[clang::noduplicate]];
+ void foo();
+ void bar();
+
+ nodupfunc();
+ if (a > n) {
+ foo();
+ } else {
+ bar();
+ }
+
+gets possibly modified by some optimizations into code similar to this:
+
+.. code-block:: c
+
+ if (a > n) {
+ nodupfunc();
+ foo();
+ } else {
+ nodupfunc();
+ bar();
+ }
+
+where the call to "nodupfunc" is duplicated and sunk into the two branches
+of the condition.
+ }];
+}
+
+def ObjCRequiresSuperDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Some Objective-C classes allow a subclass to override a particular method in a
+parent class but expect that the overriding method also calls the overridden
+method in the parent class. For these cases, we provide an attribute to
+designate that a method requires a "call to ``super``" in the overriding
+method in the subclass.
+
+**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only
+be placed at the end of a method declaration:
+
+.. code-block:: objc
+
+ - (void)foo __attribute__((objc_requires_super));
+
+This attribute can only be applied the method declarations within a class, and
+not a protocol. Currently this attribute does not enforce any placement of
+where the call occurs in the overriding method (such as in the case of
+``-dealloc`` where the call must appear at the end). It checks only that it
+exists.
+
+Note that on both OS X and iOS that the Foundation framework provides a
+convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this
+attribute:
+
+.. code-block:: objc
+
+ - (void)foo NS_REQUIRES_SUPER;
+
+This macro is conditionally defined depending on the compiler's support for
+this attribute. If the compiler does not support the attribute the macro
+expands to nothing.
+
+Operationally, when a method has this annotation the compiler will warn if the
+implementation of an override in a subclass does not call super. For example:
+
+.. code-block:: objc
+
+ warning: method possibly missing a [super AnnotMeth] call
+ - (void) AnnotMeth{};
+ ^
+ }];
+}
+
+def AvailabilityDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``availability`` attribute can be placed on declarations to describe the
+lifecycle of that declaration relative to operating system versions. Consider
+the function declaration for a hypothetical function ``f``:
+
+.. code-block:: c++
+
+ void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
+
+The availability attribute states that ``f`` was introduced in Mac OS X 10.4,
+deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information
+is used by Clang to determine when it is safe to use ``f``: for example, if
+Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()``
+succeeds. If Clang is instructed to compile code for Mac OS X 10.6, the call
+succeeds but Clang emits a warning specifying that the function is deprecated.
+Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call
+fails because ``f()`` is no longer available.
+
+The availability attribute is a comma-separated list starting with the
+platform name and then including clauses specifying important milestones in the
+declaration's lifetime (in any order) along with additional information. Those
+clauses can be:
+
+introduced=\ *version*
+ The first version in which this declaration was introduced.
+
+deprecated=\ *version*
+ The first version in which this declaration was deprecated, meaning that
+ users should migrate away from this API.
+
+obsoleted=\ *version*
+ The first version in which this declaration was obsoleted, meaning that it
+ was removed completely and can no longer be used.
+
+unavailable
+ This declaration is never available on this platform.
+
+message=\ *string-literal*
+ Additional message text that Clang will provide when emitting a warning or
+ error about use of a deprecated or obsoleted declaration. Useful to direct
+ users to replacement APIs.
+
+Multiple availability attributes can be placed on a declaration, which may
+correspond to different platforms. Only the availability attribute with the
+platform corresponding to the target platform will be used; any others will be
+ignored. If no availability attribute specifies availability for the current
+target platform, the availability attributes are ignored. Supported platforms
+are:
+
+``ios``
+ Apple's iOS operating system. The minimum deployment target is specified by
+ the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*``
+ command-line arguments.
+
+``macosx``
+ Apple's Mac OS X operating system. The minimum deployment target is
+ specified by the ``-mmacosx-version-min=*version*`` command-line argument.
+
+A declaration can be used even when deploying back to a platform version prior
+to when the declaration was introduced. When this happens, the declaration is
+`weakly linked
+<https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_,
+as if the ``weak_import`` attribute were added to the declaration. A
+weakly-linked declaration may or may not be present a run-time, and a program
+can determine whether the declaration is present by checking whether the
+address of that declaration is non-NULL.
+
+If there are multiple declarations of the same entity, the availability
+attributes must either match on a per-platform basis or later
+declarations must not have availability attributes for that
+platform. For example:
+
+.. code-block:: c
+
+ void g(void) __attribute__((availability(macosx,introduced=10.4)));
+ void g(void) __attribute__((availability(macosx,introduced=10.4))); // okay, matches
+ void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform
+ void g(void); // okay, inherits both macosx and ios availability from above.
+ void g(void) __attribute__((availability(macosx,introduced=10.5))); // error: mismatch
+
+When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,:
+
+.. code-block:: objc
+
+ @interface A
+ - (id)method __attribute__((availability(macosx,introduced=10.4)));
+ - (id)method2 __attribute__((availability(macosx,introduced=10.4)));
+ @end
+
+ @interface B : A
+ - (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later
+ - (id)method __attribute__((availability(macosx,introduced=10.5))); // error: this method was available via the base class in 10.4
+ @end
+ }];
+}
+
+def FallthroughDocs : Documentation {
+ let Category = DocCatStmt;
+ let Content = [{
+The ``clang::fallthrough`` attribute is used along with the
+``-Wimplicit-fallthrough`` argument to annotate intentional fall-through
+between switch labels. It can only be applied to a null statement placed at a
+point of execution between any statement and the next switch label. It is
+common to mark these places with a specific comment, but this attribute is
+meant to replace comments with a more strict annotation, which can be checked
+by the compiler. This attribute doesn't change semantics of the code and can
+be used wherever an intended fall-through occurs. It is designed to mimic
+control-flow statements like ``break;``, so it can be placed in most places
+where ``break;`` can, but only if there are no statements on the execution path
+between it and the next switch label.
+
+Here is an example:
+
+.. code-block:: c++
+
+ // compile with -Wimplicit-fallthrough
+ switch (n) {
+ case 22:
+ case 33: // no warning: no statements between case labels
+ f();
+ case 44: // warning: unannotated fall-through
+ g();
+ [[clang::fallthrough]];
+ case 55: // no warning
+ if (x) {
+ h();
+ break;
+ }
+ else {
+ i();
+ [[clang::fallthrough]];
+ }
+ case 66: // no warning
+ p();
+ [[clang::fallthrough]]; // warning: fallthrough annotation does not
+ // directly precede case label
+ q();
+ case 77: // warning: unannotated fall-through
+ r();
+ }
+ }];
+}
+
+def ARMInterruptDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on
+ARM targets. This attribute may be attached to a function definition and
+instructs the backend to generate appropriate function entry/exit code so that
+it can be used directly as an interrupt service routine.
+
+The parameter passed to the interrupt attribute is optional, but if
+provided it must be a string literal with one of the following values: "IRQ",
+"FIQ", "SWI", "ABORT", "UNDEF".
+
+The semantics are as follows:
+
+- If the function is AAPCS, Clang instructs the backend to realign the stack to
+ 8 bytes on entry. This is a general requirement of the AAPCS at public
+ interfaces, but may not hold when an exception is taken. Doing this allows
+ other AAPCS functions to be called.
+- If the CPU is M-class this is all that needs to be done since the architecture
+ itself is designed in such a way that functions obeying the normal AAPCS ABI
+ constraints are valid exception handlers.
+- If the CPU is not M-class, the prologue and epilogue are modified to save all
+ non-banked registers that are used, so that upon return the user-mode state
+ will not be corrupted. Note that to avoid unnecessary overhead, only
+ general-purpose (integer) registers are saved in this way. If VFP operations
+ are needed, that state must be saved manually.
+
+ Specifically, interrupt kinds other than "FIQ" will save all core registers
+ except "lr" and "sp". "FIQ" interrupts will save r0-r7.
+- If the CPU is not M-class, the return instruction is changed to one of the
+ canonical sequences permitted by the architecture for exception return. Where
+ possible the function itself will make the necessary "lr" adjustments so that
+ the "preferred return address" is selected.
+
+ Unfortunately the compiler is unable to make this guarantee for an "UNDEF"
+ handler, where the offset from "lr" to the preferred return address depends on
+ the execution state of the code which generated the exception. In this case
+ a sequence equivalent to "movs pc, lr" will be used.
+ }];
+}
+
+def PcsDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+On ARM targets, this can attribute can be used to select calling conventions,
+similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
+"aapcs-vfp".
+ }];
+}
+
+def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> {
+ let Content = [{
+Clang supports additional attributes for checking basic resource management
+properties, specifically for unique objects that have a single owning reference.
+The following attributes are currently supported, although **the implementation
+for these annotations is currently in development and are subject to change.**
+ }];
+}
+
+def SetTypestateDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+Annotate methods that transition an object into a new state with
+``__attribute__((set_typestate(new_state)))``. The new new state must be
+unconsumed, consumed, or unknown.
+ }];
+}
+
+def CallableWhenDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+Use ``__attribute__((callable_when(...)))`` to indicate what states a method
+may be called in. Valid states are unconsumed, consumed, or unknown. Each
+argument to this attribute must be a quoted string. E.g.:
+
+``__attribute__((callable_when("unconsumed", "unknown")))``
+ }];
+}
+
+def TestTypestateDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method
+returns true if the object is in the specified state..
+ }];
+}
+
+def ParamTypestateDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+This attribute specifies expectations about function parameters. Calls to an
+function with annotated parameters will issue a warning if the corresponding
+argument isn't in the expected state. The attribute is also used to set the
+initial state of the parameter when analyzing the function's body.
+ }];
+}
+
+def ReturnTypestateDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+The ``return_typestate`` attribute can be applied to functions or parameters.
+When applied to a function the attribute specifies the state of the returned
+value. The function's body is checked to ensure that it always returns a value
+in the specified state. On the caller side, values returned by the annotated
+function are initialized to the given state.
+
+When applied to a function parameter it modifies the state of an argument after
+a call to the function returns. The function's body is checked to ensure that
+the parameter is in the expected state before returning.
+ }];
+}
+
+def ConsumableDocs : Documentation {
+ let Category = DocCatConsumed;
+ let Content = [{
+Each ``class`` that uses any of the typestate annotations must first be marked
+using the ``consumable`` attribute. Failure to do so will result in a warning.
+
+This attribute accepts a single parameter that must be one of the following:
+``unknown``, ``consumed``, or ``unconsumed``.
+ }];
+}
+
+def NoSanitizeAddressDocs : Documentation {
+ let Category = DocCatFunction;
+ // This function has multiple distinct spellings, and so it requires a custom
+ // heading to be specified. The most common spelling is sufficient.
+ let Heading = "no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address)";
+ let Content = [{
+.. _langext-address_sanitizer:
+
+Use ``__attribute__((no_sanitize_address))`` on a function declaration to
+specify that address safety instrumentation (e.g. AddressSanitizer) should
+not be applied to that function.
+ }];
+}
+
+def NoSanitizeThreadDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+.. _langext-thread_sanitizer:
+
+Use ``__attribute__((no_sanitize_thread))`` on a function declaration to
+specify that checks for data races on plain (non-atomic) memory accesses should
+not be inserted by ThreadSanitizer. The function is still instrumented by the
+tool to avoid false positives and provide meaningful stack traces.
+ }];
+}
+
+def NoSanitizeMemoryDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+.. _langext-memory_sanitizer:
+
+Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
+specify that checks for uninitialized memory should not be inserted
+(e.g. by MemorySanitizer). The function may still be instrumented by the tool
+to avoid false positives in other places.
+ }];
+}
+
+def DocCatTypeSafety : DocumentationCategory<"Type Safety Checking"> {
+ let Content = [{
+Clang supports additional attributes to enable checking type safety properties
+that can't be enforced by the C type system. Use cases include:
+
+* MPI library implementations, where these attributes enable checking that
+ the buffer type matches the passed ``MPI_Datatype``;
+* for HDF5 library there is a similar use case to MPI;
+* checking types of variadic functions' arguments for functions like
+ ``fcntl()`` and ``ioctl()``.
+
+You can detect support for these attributes with ``__has_attribute()``. For
+example:
+
+.. code-block:: c++
+
+ #if defined(__has_attribute)
+ # if __has_attribute(argument_with_type_tag) && \
+ __has_attribute(pointer_with_type_tag) && \
+ __has_attribute(type_tag_for_datatype)
+ # define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx)))
+ /* ... other macros ... */
+ # endif
+ #endif
+
+ #if !defined(ATTR_MPI_PWT)
+ # define ATTR_MPI_PWT(buffer_idx, type_idx)
+ #endif
+
+ int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
+ ATTR_MPI_PWT(1,3);
+ }];
+}
+
+def ArgumentWithTypeTagDocs : Documentation {
+ let Category = DocCatTypeSafety;
+ let Heading = "argument_with_type_tag";
+ let Content = [{
+Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,
+type_tag_idx)))`` on a function declaration to specify that the function
+accepts a type tag that determines the type of some other argument.
+``arg_kind`` is an identifier that should be used when annotating all
+applicable type tags.
+
+This attribute is primarily useful for checking arguments of variadic functions
+(``pointer_with_type_tag`` can be used in most non-variadic cases).
+
+For example:
+
+.. code-block:: c++
+
+ int fcntl(int fd, int cmd, ...)
+ __attribute__(( argument_with_type_tag(fcntl,3,2) ));
+ }];
+}
+
+def PointerWithTypeTagDocs : Documentation {
+ let Category = DocCatTypeSafety;
+ let Heading = "pointer_with_type_tag";
+ let Content = [{
+Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``
+on a function declaration to specify that the function accepts a type tag that
+determines the pointee type of some other pointer argument.
+
+For example:
+
+.. code-block:: c++
+
+ int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
+ __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+ }];
+}
+
+def TypeTagForDatatypeDocs : Documentation {
+ let Category = DocCatTypeSafety;
+ let Content = [{
+Clang supports annotating type tags of two forms.
+
+* **Type tag that is an expression containing a reference to some declared
+ identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a
+ declaration with that identifier:
+
+ .. code-block:: c++
+
+ extern struct mpi_datatype mpi_datatype_int
+ __attribute__(( type_tag_for_datatype(mpi,int) ));
+ #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
+
+* **Type tag that is an integral literal.** Introduce a ``static const``
+ variable with a corresponding initializer value and attach
+ ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration,
+ for example:
+
+ .. code-block:: c++
+
+ #define MPI_INT ((MPI_Datatype) 42)
+ static const MPI_Datatype mpi_datatype_int
+ __attribute__(( type_tag_for_datatype(mpi,int) )) = 42
+
+The attribute also accepts an optional third argument that determines how the
+expression is compared to the type tag. There are two supported flags:
+
+* ``layout_compatible`` will cause types to be compared according to
+ layout-compatibility rules (C++11 [class.mem] p 17, 18). This is
+ implemented to support annotating types like ``MPI_DOUBLE_INT``.
+
+ For example:
+
+ .. code-block:: c++
+
+ /* In mpi.h */
+ struct internal_mpi_double_int { double d; int i; };
+ extern struct mpi_datatype mpi_datatype_double_int
+ __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) ));
+
+ #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
+
+ /* In user code */
+ struct my_pair { double a; int b; };
+ struct my_pair *buffer;
+ MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning
+
+ struct my_int_pair { int a; int b; }
+ struct my_int_pair *buffer2;
+ MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element
+ // type 'struct my_int_pair'
+ // doesn't match specified MPI_Datatype
+
+* ``must_be_null`` specifies that the expression should be a null pointer
+ constant, for example:
+
+ .. code-block:: c++
+
+ /* In mpi.h */
+ extern struct mpi_datatype mpi_datatype_null
+ __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
+
+ #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
+
+ /* In user code */
+ MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL
+ // was specified but buffer
+ // is not a null pointer
+ }];
+}
+
+def FormatDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+
+Clang supports the ``format`` attribute, which indicates that the function
+accepts a ``printf`` or ``scanf``-like format string and corresponding
+arguments or a ``va_list`` that contains these arguments.
+
+Please see `GCC documentation about format attribute
+<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details
+about attribute syntax.
+
+Clang implements two kinds of checks with this attribute.
+
+#. Clang checks that the function with the ``format`` attribute is called with
+ a format string that uses format specifiers that are allowed, and that
+ arguments match the format string. This is the ``-Wformat`` warning, it is
+ on by default.
+
+#. Clang checks that the format string argument is a literal string. This is
+ the ``-Wformat-nonliteral`` warning, it is off by default.
+
+ Clang implements this mostly the same way as GCC, but there is a difference
+ for functions that accept a ``va_list`` argument (for example, ``vprintf``).
+ GCC does not emit ``-Wformat-nonliteral`` warning for calls to such
+ fuctions. Clang does not warn if the format string comes from a function
+ parameter, where the function is annotated with a compatible attribute,
+ otherwise it warns. For example:
+
+ .. code-block:: c
+
+ __attribute__((__format__ (__scanf__, 1, 3)))
+ void foo(const char* s, char *buf, ...) {
+ va_list ap;
+ va_start(ap, buf);
+
+ vprintf(s, ap); // warning: format string is not a string literal
+ }
+
+ In this case we warn because ``s`` contains a format string for a
+ ``scanf``-like function, but it is passed to a ``printf``-like function.
+
+ If the attribute is removed, clang still warns, because the format string is
+ not a string literal.
+
+ Another example:
+
+ .. code-block:: c
+
+ __attribute__((__format__ (__printf__, 1, 3)))
+ void foo(const char* s, char *buf, ...) {
+ va_list ap;
+ va_start(ap, buf);
+
+ vprintf(s, ap); // warning
+ }
+
+ In this case Clang does not warn because the format string ``s`` and
+ the corresponding arguments are annotated. If the arguments are
+ incorrect, the caller of ``foo`` will receive a warning.
+ }];
+}
+
+def MSInheritanceDocs : Documentation {
+ let Category = DocCatType;
+ let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
+ let Content = [{
+This collection of keywords is enabled under ``-fms-extensions`` and controls
+the pointer-to-member representation used on ``*-*-win32`` targets.
+
+The ``*-*-win32`` targets utilize a pointer-to-member representation which
+varies in size and alignment depending on the definition of the underlying
+class.
+
+However, this is problematic when a forward declaration is only available and
+no definition has been made yet. In such cases, Clang is forced to utilize the
+most general representation that is available to it.
+
+These keywords make it possible to use a pointer-to-member representation other
+than the most general one regardless of whether or not the definition will ever
+be present in the current translation unit.
+
+This family of keywords belong between the ``class-key`` and ``class-name``:
+
+.. code-block:: c++
+
+ struct __single_inheritance S;
+ int S::*i;
+ struct S {};
+
+This keyword can be applied to class templates but only has an effect when used
+on full specializations:
+
+.. code-block:: c++
+
+ template <typename T, typename U> struct __single_inheritance A; // warning: inheritance model ignored on primary template
+ template <typename T> struct __multiple_inheritance A<T, T>; // warning: inheritance model ignored on partial specialization
+ template <> struct __single_inheritance A<int, float>;
+
+Note that choosing an inheritance model less general than strictly necessary is
+an error:
+
+.. code-block:: c++
+
+ struct __multiple_inheritance S; // error: inheritance model does not match definition
+ int S::*i;
+ struct S {};
+}];
+}
+
+def OptnoneDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``optnone`` attribute suppresses essentially all optimizations
+on a function or method, regardless of the optimization level applied to
+the compilation unit as a whole. This is particularly useful when you
+need to debug a particular function, but it is infeasible to build the
+entire application without optimization. Avoiding optimization on the
+specified function can improve the quality of the debugging information
+for that function.
+
+This attribute is incompatible with the ``always_inline`` attribute.
+ }];
+}
+
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
index 7c4e2c7..150a30e 100644
--- a/include/clang/Basic/AttrKinds.h
+++ b/include/clang/Basic/AttrKinds.h
@@ -24,7 +24,6 @@
#define ATTR(X) X,
#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
-#define LAST_MS_INHERITANCE_ATTR(X) X, LAST_MS_INHERITANCE = X,
#include "clang/Basic/AttrList.inc"
NUM_ATTRS
};
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
new file mode 100644
index 0000000..4a7e462
--- /dev/null
+++ b/include/clang/Basic/Attributes.h
@@ -0,0 +1,39 @@
+//===--- Attributes.h - Attributes header -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ATTRIBUTES_H
+#define LLVM_CLANG_BASIC_ATTRIBUTES_H
+
+#include "llvm/ADT/Triple.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+class IdentifierInfo;
+
+enum class AttrSyntax {
+ /// Is the attribute identifier generally known for any syntax?
+ Generic,
+ /// Is the identifier known as a GNU-style attribute?
+ GNU,
+ /// Is the identifier known as a __declspec-style attribute?
+ Declspec,
+ // Is the identifier known as a C++-style attribute?
+ CXX
+};
+
+/// \brief Return true if we recognize and implement the attribute specified by
+/// the given information.
+bool hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
+ const IdentifierInfo *Attr, const llvm::Triple &T,
+ const LangOptions &LangOpts);
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_ATTRIBUTES_H
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 55c6ed7..540ec25 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -50,6 +50,7 @@
// L -> long (e.g. Li for 'long int')
// LL -> long long
// LLL -> __int128_t (e.g. LLLi)
+// W -> int64_t
// S -> signed
// U -> unsigned
// I -> Required to constant fold to an integer constant expression.
@@ -444,6 +445,7 @@
BUILTIN(__builtin_return_address, "v*IUi", "n")
BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
BUILTIN(__builtin_frame_address, "v*IUi", "n")
+BUILTIN(__builtin___clear_cache, "vc*c*", "n")
BUILTIN(__builtin_flt_rounds, "i", "nc")
BUILTIN(__builtin_setjmp, "iv**", "j")
BUILTIN(__builtin_longjmp, "vv**i", "r")
@@ -679,6 +681,11 @@
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "v.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
// C99 library functions
// C99 stdlib.h
@@ -1137,6 +1144,21 @@
LIBBUILTIN(ctanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ctanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+// __sinpi and friends are OS X specific library functions, but otherwise much
+// like the standard (non-complex) sin (etc).
+LIBBUILTIN(__sinpi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__sinpif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(__cospi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__cospif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(__tanpi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__tanpif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+// Similarly, __exp10 is OS X only
+LIBBUILTIN(__exp10, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__exp10f, "ff", "fne", "math.h", ALL_LANGUAGES)
+
// Blocks runtime Builtin math library functions
LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 9756f21..fd8fd42 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -177,6 +177,10 @@
/// \brief Is this builtin supported according to the given language options?
bool BuiltinIsSupported(const Builtin::Info &BuiltinInfo,
const LangOptions &LangOpts);
+
+ /// \brief Helper function for isPrintfLike and isScanfLike.
+ bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
+ const char *Fmt) const;
};
}
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index aafd202..a0a0a5d 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -16,10 +16,5 @@
// In libgcc
BUILTIN(__clear_cache, "vv*v*", "i")
-// NEON
-#define GET_NEON_AARCH64_BUILTINS
-#include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_AARCH64_BUILTINS
-#undef GET_NEON_BUILTINS
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 21bb892..aab9255 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -65,9 +65,4 @@
BUILTIN(__builtin_arm_dmb, "vUi", "nc")
BUILTIN(__builtin_arm_dsb, "vUi", "nc")
-// NEON
-#define GET_NEON_BUILTINS
-#include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_BUILTINS
-
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsARM64.def b/include/clang/Basic/BuiltinsARM64.def
new file mode 100644
index 0000000..dcc1b51
--- /dev/null
+++ b/include/clang/Basic/BuiltinsARM64.def
@@ -0,0 +1,34 @@
+//===--- 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/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def
index e435d52..2d217f7 100644
--- a/include/clang/Basic/BuiltinsMips.def
+++ b/include/clang/Basic/BuiltinsMips.def
@@ -783,15 +783,15 @@
BUILTIN(__builtin_msa_shf_h, "V8sV8sIUi", "nc")
BUILTIN(__builtin_msa_shf_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_sld_b, "V16cV16cUi", "nc")
-BUILTIN(__builtin_msa_sld_h, "V8sV8sUi", "nc")
-BUILTIN(__builtin_msa_sld_w, "V4iV4iUi", "nc")
-BUILTIN(__builtin_msa_sld_d, "V2LLiV2LLiUi", "nc")
+BUILTIN(__builtin_msa_sld_b, "V16cV16cV16cUi", "nc")
+BUILTIN(__builtin_msa_sld_h, "V8sV8sV8sUi", "nc")
+BUILTIN(__builtin_msa_sld_w, "V4iV4iV4iUi", "nc")
+BUILTIN(__builtin_msa_sld_d, "V2LLiV2LLiV2LLiUi", "nc")
-BUILTIN(__builtin_msa_sldi_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_sldi_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_sldi_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_sldi_d, "V2LLiV2LLiIUi", "nc")
+BUILTIN(__builtin_msa_sldi_b, "V16cV16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_sldi_h, "V8sV8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_sldi_w, "V4iV4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_sldi_d, "V2LLiV2LLiV2LLiIUi", "nc")
BUILTIN(__builtin_msa_sll_b, "V16cV16cV16c", "nc")
BUILTIN(__builtin_msa_sll_h, "V8sV8sV8s", "nc")
diff --git a/include/clang/Basic/BuiltinsNEON.def b/include/clang/Basic/BuiltinsNEON.def
new file mode 100644
index 0000000..7800ae6
--- /dev/null
+++ b/include/clang/Basic/BuiltinsNEON.def
@@ -0,0 +1,21 @@
+//===--- BuiltinsNEON.def - NEON 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 NEON-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.
+
+#define GET_NEON_BUILTINS
+#include "clang/Basic/arm_neon.inc"
+#undef GET_NEON_BUILTINS
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 51397fa..4a67fc1 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -59,6 +59,7 @@
// All MMX instructions will be generated via builtins. Any MMX vector
// types (<1 x i64>, <2 x i32>, etc.) that aren't used by these builtins will be
// expanded by the back-end.
+BUILTIN(_mm_prefetch, "vcC*i", "nc")
BUILTIN(__builtin_ia32_emms, "v", "")
BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "")
BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "")
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index 274b94d..e4929b5 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -28,7 +28,14 @@
SOURCE Attr.td
TARGET ClangAttrList)
+clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE Attr.td
+ TARGET ClangAttrHasAttributeImpl
+ )
+
# ARM NEON
clang_tablegen(arm_neon.inc -gen-arm-neon-sema
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE arm_neon.td
TARGET ClangARMNeon)
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index c057bdf..6082ec8 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -21,7 +21,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/Support/type_traits.h"
#include <list>
#include <vector>
@@ -35,6 +34,9 @@
class Preprocessor;
class DiagnosticErrorTrap;
class StoredDiagnostic;
+ namespace tok {
+ enum TokenKind : unsigned short;
+ }
/// \brief Annotates a diagnostic with some code that should be
/// inserted, removed, or replaced to fix the problem.
@@ -134,6 +136,7 @@
enum Level {
Ignored = DiagnosticIDs::Ignored,
Note = DiagnosticIDs::Note,
+ Remark = DiagnosticIDs::Remark,
Warning = DiagnosticIDs::Warning,
Error = DiagnosticIDs::Error,
Fatal = DiagnosticIDs::Fatal
@@ -151,13 +154,15 @@
ak_c_string, ///< const char *
ak_sint, ///< int
ak_uint, ///< unsigned
+ ak_tokenkind, ///< enum TokenKind : unsigned
ak_identifierinfo, ///< IdentifierInfo
ak_qualtype, ///< QualType
ak_declarationname, ///< DeclarationName
ak_nameddecl, ///< NamedDecl *
ak_nestednamespec, ///< NestedNameSpecifier *
ak_declcontext, ///< DeclContext *
- ak_qualtype_pair ///< pair<QualType, QualType>
+ ak_qualtype_pair, ///< pair<QualType, QualType>
+ ak_attr ///< Attr *
};
/// \brief Represents on argument value, which is a union discriminated
@@ -536,11 +541,6 @@
bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map,
SourceLocation Loc = SourceLocation());
- /// \brief Set the warning-as-error flag for the given diagnostic.
- ///
- /// This function always only operates on the current diagnostic state.
- void setDiagnosticWarningAsError(diag::kind Diag, bool Enabled);
-
/// \brief Set the warning-as-error flag for the given diagnostic group.
///
/// This function always only operates on the current diagnostic state.
@@ -548,11 +548,6 @@
/// \returns True if the given group is unknown, false otherwise.
bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
- /// \brief Set the error-as-fatal flag for the given diagnostic.
- ///
- /// This function always only operates on the current diagnostic state.
- void setDiagnosticErrorAsFatal(diag::kind Diag, bool Enabled);
-
/// \brief Set the error-as-fatal flag for the given diagnostic group.
///
/// This function always only operates on the current diagnostic state.
@@ -587,12 +582,18 @@
this->NumWarnings = NumWarnings;
}
- /// \brief Return an ID for a diagnostic with the specified message and level.
+ /// \brief Return an ID for a diagnostic with the specified format string and
+ /// level.
///
/// If this is the first request for this diagnostic, it is registered and
/// created, otherwise the existing ID is returned.
- unsigned getCustomDiagID(Level L, StringRef Message) {
- return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message);
+ ///
+ /// \param FormatString A fixed diagnostic format string that will be hashed
+ /// and mapped to a unique DiagID.
+ template <unsigned N>
+ unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
+ return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
+ StringRef(FormatString, N - 1));
}
/// \brief Converts a diagnostic argument (as an intptr_t) into the string
@@ -1013,7 +1014,13 @@
return DB;
}
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) {
+// We use enable_if here to prevent that this overload is selected for
+// pointers or other arguments that are implicitly convertible to bool.
+template <typename T>
+inline
+typename std::enable_if<std::is_same<T, bool>::value,
+ const DiagnosticBuilder &>::type
+operator<<(const DiagnosticBuilder &DB, T I) {
DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
return DB;
}
@@ -1025,6 +1032,12 @@
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ tok::TokenKind I) {
+ DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const IdentifierInfo *II) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
DiagnosticsEngine::ak_identifierinfo);
@@ -1037,14 +1050,14 @@
// match.
template<typename T>
inline
-typename llvm::enable_if<llvm::is_same<T, DeclContext>,
- const DiagnosticBuilder &>::type
+typename std::enable_if<std::is_same<T, DeclContext>::value,
+ const DiagnosticBuilder &>::type
operator<<(const DiagnosticBuilder &DB, T *DC) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
DiagnosticsEngine::ak_declcontext);
return DB;
}
-
+
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const SourceRange &R) {
DB.AddSourceRange(CharSourceRange::getTokenRange(R));
@@ -1052,11 +1065,18 @@
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ ArrayRef<SourceRange> Ranges) {
+ for (const SourceRange &R: Ranges)
+ DB.AddSourceRange(CharSourceRange::getTokenRange(R));
+ return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const CharSourceRange &R) {
DB.AddSourceRange(R);
return DB;
}
-
+
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const FixItHint &Hint) {
if (!Hint.isNull())
@@ -1065,7 +1085,7 @@
}
inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
- unsigned DiagID){
+ unsigned DiagID) {
assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
CurDiagLoc = Loc;
CurDiagID = DiagID;
@@ -1312,7 +1332,7 @@
class IgnoringDiagConsumer : public DiagnosticConsumer {
virtual void anchor();
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) {
+ const Diagnostic &Info) override {
// Just ignore it.
}
};
@@ -1328,11 +1348,11 @@
virtual ~ForwardingDiagnosticConsumer();
- virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info);
- virtual void clear();
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) override;
+ void clear() override;
- virtual bool IncludeInDiagnosticCounts() const;
+ bool IncludeInDiagnosticCounts() const override;
};
// Struct used for sending info about how a type should be printed.
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index 2616548..61a4508 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -15,6 +15,7 @@
// Define the diagnostic mappings.
class DiagMapping;
def MAP_IGNORE : DiagMapping;
+def MAP_REMARK : DiagMapping;
def MAP_WARNING : DiagMapping;
def MAP_ERROR : DiagMapping;
def MAP_FATAL : DiagMapping;
@@ -22,6 +23,7 @@
// Define the diagnostic classes.
class DiagClass;
def CLASS_NOTE : DiagClass;
+def CLASS_REMARK : DiagClass;
def CLASS_WARNING : DiagClass;
def CLASS_EXTENSION : DiagClass;
def CLASS_ERROR : DiagClass;
@@ -84,6 +86,7 @@
// FIXME: ExtWarn and Extension should also be SFINAEFailure by default.
class Error<string str> : Diagnostic<str, CLASS_ERROR, MAP_ERROR>, SFINAEFailure;
class Warning<string str> : Diagnostic<str, CLASS_WARNING, MAP_WARNING>;
+class Remark<string str> : Diagnostic<str, CLASS_REMARK, MAP_IGNORE>;
class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_IGNORE>;
class ExtWarn<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_WARNING>;
class Note<string str> : Diagnostic<str, CLASS_NOTE, MAP_FATAL/*ignored*/>;
diff --git a/include/clang/Basic/DiagnosticCategories.td b/include/clang/Basic/DiagnosticCategories.td
index a02fbdf..37b8569 100644
--- a/include/clang/Basic/DiagnosticCategories.td
+++ b/include/clang/Basic/DiagnosticCategories.td
@@ -8,3 +8,4 @@
//===----------------------------------------------------------------------===//
class CatInlineAsm : DiagCategory<"Inline Assembly Issue">;
+class CatBackend : DiagCategory<"Backend Issue">;
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index c54bafc..0430b1d 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -30,7 +30,7 @@
"definition of %0 is not complete until the closing '}'">;
/// note_matching - this is used as a continuation of a previous diagnostic,
/// e.g. to specify the '(' when we expected a ')'.
-def note_matching : Note<"to match this '%0'">;
+def note_matching : Note<"to match this %0">;
def note_using : Note<"using">;
def note_possibility : Note<"one possibility">;
@@ -40,7 +40,6 @@
let CategoryName = "Lexical or Preprocessor Issue" in {
-def err_expected_colon : Error<"expected ':'">;
def err_expected_colon_after_setter_name : Error<
"method name referenced in property setter attribute "
"must end with ':'">;
@@ -60,6 +59,10 @@
let CategoryName = "Parse Issue" in {
+def err_expected : Error<"expected %0">;
+def err_expected_either : Error<"expected %0 or %1">;
+def err_expected_after : Error<"expected %1 after %0">;
+
def err_param_redefinition : Error<"redefinition of parameter %0">;
def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">;
def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">,
@@ -101,8 +104,9 @@
InGroup<CXX98CompatPedantic>, DefaultIgnore;
def err_integer_too_large : Error<
"integer constant is larger than the largest unsigned integer type">;
-def warn_integer_too_large_for_signed : Warning<
- "integer constant is larger than the largest signed integer type">;
+def ext_integer_too_large_for_signed : ExtWarn<
+ "integer constant is larger than the largest signed integer type">,
+ InGroup<DiagGroup<"implicitly-unsigned-literal">>;
// Sema && AST
def note_invalid_subexpr_in_const_expr : Note<
@@ -114,7 +118,6 @@
"unknown target triple '%0', please use -triple or -arch">;
def err_target_unknown_cpu : Error<"unknown target CPU '%0'">;
def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
-def err_target_unknown_cxxabi : Error<"unknown C++ ABI '%0'">;
def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">;
def err_target_unsupported_fpmath : Error<
"the '%0' unit is not supported with this instruction set">;
@@ -133,4 +136,14 @@
// Modules
def err_module_file_conflict : Error<"module '%0' found in both '%1' and '%2'">;
+// TransformActions
+// TODO: Use a custom category name to distinguish rewriter errors.
+def err_mt_message : Error<"[rewriter] %0">;
+def warn_mt_message : Warning<"[rewriter] %0">;
+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 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 b489807..71080ba 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -17,6 +17,8 @@
"unsupported argument '%1' to option '%0'">;
def err_drv_unknown_stdin_type : Error<
"-E or -x required when input is from standard input">;
+def err_drv_unknown_stdin_type_clang_cl : Error<
+ "use /Tc or /Tp to set input type for standard input">;
def err_drv_unknown_language : Error<"language not recognized: '%0'">;
def err_drv_invalid_arch_name : Error<
"invalid arch name '%0'">;
@@ -109,8 +111,6 @@
"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_unknown_toolchain : Error<
- "cannot recognize the type of the toolchain">;
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">,
@@ -136,8 +136,6 @@
InGroup<UnusedSanitizeArgument>;
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
-def warn_drv_deprecated_arg : Warning<
- "argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
def warn_drv_assuming_mfloat_abi_is : Warning<
"unknown platform, assuming -mfloat-abi=%0">;
def warn_ignoring_ftabstop_value : Warning<
@@ -154,6 +152,8 @@
"precompiled header '%0' was ignored because '%1' is not first '-include'">;
def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
InGroup<DiagGroup<"missing-sysroot">>;
+def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">,
+ InGroup<DiagGroup<"debug-compression-unavailable">>;
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
@@ -164,4 +164,11 @@
"analyzer-config option '%0' has a key but no value">;
def err_analyzer_config_multiple_values : Error<
"analyzer-config option '%0' should contain only one '='">;
+
+def err_drv_modules_validate_once_requires_timestamp : Error<
+ "option '-fmodules-validate-once-per-build-session' requires "
+ "'-fbuild-session-timestamp=<seconds since Epoch>'">;
+
+def warn_drv_invoking_fallback : Warning<"falling back to %0">,
+ InGroup<DiagGroup<"fallback">>;
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index bcf3c41..32c824a 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -16,11 +16,21 @@
// Error generated by the backend.
def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
+def warn_fe_inline_asm : Warning<"%0">, CatInlineAsm, InGroup<BackendInlineAsm>;
+def note_fe_inline_asm : Note<"%0">, CatInlineAsm;
def note_fe_inline_asm_here : Note<"instantiated into assembly here">;
def err_fe_cannot_link_module : Error<"cannot link module '%0': %1">,
DefaultFatal;
+def warn_fe_backend_frame_larger_than: Warning<"stack size exceeded (%0) in %1">,
+ CatBackend, InGroup<BackendFrameLargerThan>;
+def err_fe_backend_frame_larger_than: Error<"%0">, CatBackend;
+def note_fe_backend_frame_larger_than: Note<"%0">, CatBackend;
+def warn_fe_backend_plugin: Warning<"%0">, CatBackend, InGroup<BackendPlugin>;
+def err_fe_backend_plugin: Error<"%0">, CatBackend;
+def remark_fe_backend_plugin: Remark<"%0">, CatBackend, InGroup<RemarkBackendPlugin>;
+def note_fe_backend_plugin: Note<"%0">, CatBackend;
def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
@@ -77,6 +87,8 @@
"cannot find end ('}}') of expected %0">;
def err_verify_invalid_content : Error<
"invalid expected %0: %1">;
+def err_verify_missing_regex : Error<
+ "cannot find start of regex ('{{') in %0">;
def err_verify_inconsistent_diags : Error<
"'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: "
"%2">;
@@ -138,6 +150,10 @@
InGroup<IncompleteUmbrella>;
def err_module_unavailable : Error<
"module '%0' %select{is incompatible with|requires}1 feature '%2'">;
+def err_module_header_missing : Error<
+ "%select{|umbrella }0header '%1' not found">;
+def err_module_cannot_create_includes : Error<
+ "cannot create includes file for module %0: %1">;
def warn_module_config_macro_undef : Warning<
"%select{definition|#undef}0 of configuration macro '%1' has no effect on "
"the import of '%2'; pass '%select{-D%1=...|-U%1}0' on the command line "
@@ -145,4 +161,9 @@
InGroup<ConfigMacros>;
def note_module_def_undef_here : Note<
"macro was %select{defined|#undef'd}0 here">;
+
+def err_missing_vfs_overlay_file : Error<
+ "virtual filesystem overlay file '%0' not found">, DefaultFatal;
+def err_invalid_vfs_overlay : Error<
+ "invalid virtual filesystem overlay file '%0'">, DefaultFatal;
}
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index b0d0216..5df740f 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -18,7 +18,7 @@
// Empty DiagGroups are recognized by clang but ignored.
def : DiagGroup<"abi">;
-def : DiagGroup<"address">;
+def AbsoluteValue : DiagGroup<"absolute-value">;
def AddressOfTemporary : DiagGroup<"address-of-temporary">;
def : DiagGroup<"aggregate-return">;
def GNUAlignofExpression : DiagGroup<"gnu-alignof-expression">;
@@ -37,13 +37,16 @@
def LiteralConversion : DiagGroup<"literal-conversion">;
def StringConversion : DiagGroup<"string-conversion">;
def SignConversion : DiagGroup<"sign-conversion">;
-def BoolConversion : DiagGroup<"bool-conversion">;
+def PointerBoolConversion : DiagGroup<"pointer-bool-conversion">;
+def BoolConversion : DiagGroup<"bool-conversion", [ PointerBoolConversion ] >;
def IntConversion : DiagGroup<"int-conversion">;
def EnumConversion : DiagGroup<"enum-conversion">;
+def EnumTooLarge : DiagGroup<"enum-too-large">;
def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">;
def NullConversion : DiagGroup<"null-conversion">;
def ImplicitConversionFloatingPointToBool :
DiagGroup<"implicit-conversion-floating-point-to-bool">;
+def ObjCLiteralConversion : DiagGroup<"objc-literal-conversion">;
def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
@@ -71,6 +74,7 @@
DiagGroup<"c++11-compat-deprecated-writable-strings">;
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
+def UnavailableDeclarations : DiagGroup<"unavailable-declarations">;
def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
def DeprecatedRegister : DiagGroup<"deprecated-register">;
@@ -168,9 +172,11 @@
def DanglingElse: DiagGroup<"dangling-else">;
def DanglingField : DiagGroup<"dangling-field">;
def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
+def InfiniteRecursion : DiagGroup<"infinite-recursion">;
def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">;
def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
def : DiagGroup<"import">;
+def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">;
def IncompatiblePointerTypesDiscardsQualifiers
: DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
def IncompatiblePointerTypes
@@ -214,16 +220,18 @@
def InitializerOverrides : DiagGroup<"initializer-overrides">;
def NonNull : DiagGroup<"nonnull">;
def NonPODVarargs : DiagGroup<"non-pod-varargs">;
+def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
def : DiagGroup<"nonportable-cfstrings">;
def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
def OveralignedType : DiagGroup<"over-aligned">;
-def : DiagGroup<"old-style-cast">;
+def OldStyleCast : DiagGroup<"old-style-cast">;
def : DiagGroup<"old-style-definition">;
def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">;
def : DiagGroup<"overflow">;
def ForwardClassReceiver : DiagGroup<"receiver-forward-class">;
def MethodAccess : DiagGroup<"objc-method-access">;
def ObjCReceiver : DiagGroup<"receiver-expr">;
+def OperatorNewReturnsNull : DiagGroup<"new-returns-null">;
def OverlengthStrings : DiagGroup<"overlength-strings">;
def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
def PrivateExtern : DiagGroup<"private-extern">;
@@ -232,6 +240,7 @@
def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
+def ObjCDesignatedInit : DiagGroup<"objc-designated-initializers">;
def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">;
def ObjCReadonlyPropertyHasSetter : DiagGroup<"objc-readonly-with-setter-property">;
def ObjCInvalidIBOutletProperty : DiagGroup<"invalid-iboutlet">;
@@ -275,12 +284,15 @@
def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">;
def StaticFloatInit : DiagGroup<"static-float-init", [GNUStaticFloatInit]>;
def GNUStatementExpression : DiagGroup<"gnu-statement-expression">;
+def StringCompare : DiagGroup<"string-compare">;
def StringPlusInt : DiagGroup<"string-plus-int">;
def StringPlusChar : DiagGroup<"string-plus-char">;
def StrncatSize : DiagGroup<"strncat-size">;
def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
+def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
def TautologicalCompare : DiagGroup<"tautological-compare",
- [TautologicalOutOfRangeCompare]>;
+ [TautologicalOutOfRangeCompare,
+ TautologicalPointerCompare]>;
def HeaderHygiene : DiagGroup<"header-hygiene">;
def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
@@ -315,6 +327,7 @@
def StrictSelector : DiagGroup<"strict-selector-match">;
def MethodDuplicate : DiagGroup<"duplicate-method-match">;
def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
+def SwitchBool : DiagGroup<"switch-bool">;
def SwitchEnum : DiagGroup<"switch-enum">;
def Switch : DiagGroup<"switch">;
def ImplicitFallthroughPerFunction :
@@ -334,10 +347,14 @@
def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes,
UninitializedStaticSelfInit]>;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def IgnoredPragmas : DiagGroup<"ignored-pragmas">;
+def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>;
def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
-def UnknownAttributes : DiagGroup<"attributes">;
+def UnknownAttributes : DiagGroup<"unknown-attributes">;
def IgnoredAttributes : DiagGroup<"ignored-attributes">;
+def Attributes : DiagGroup<"attributes", [UnknownAttributes,
+ IgnoredAttributes]>;
def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
[CXX98CompatUnnamedTypeTemplateArgs]>;
def UnsupportedFriend : DiagGroup<"unsupported-friend">;
@@ -364,7 +381,6 @@
def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">;
def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
-def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
@@ -385,6 +401,7 @@
[ARCRepeatedUseOfWeakMaybe]>;
def ObjCBridge : DiagGroup<"bridge-cast">;
+def DeallocInCategory:DiagGroup<"dealloc-in-category">;
def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">;
def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>;
def Protocol : DiagGroup<"protocol">;
@@ -408,8 +425,29 @@
def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
+// Unreachable code warning groups.
+//
+// The goal is make -Wunreachable-code on by default, in -Wall, or at
+// least actively used, with more noisy versions of the warning covered
+// under separate flags.
+//
+def UnreachableCodeLoopIncrement : DiagGroup<"unreachable-code-loop-increment">;
+def UnreachableCode : DiagGroup<"unreachable-code",
+ [UnreachableCodeLoopIncrement]>;
+def UnreachableCodeBreak : DiagGroup<"unreachable-code-break">;
+def UnreachableCodeReturn : DiagGroup<"unreachable-code-return">;
+def UnreachableCodeAggressive : DiagGroup<"unreachable-code-aggressive",
+ [UnreachableCode,
+ UnreachableCodeBreak,
+ UnreachableCodeReturn]>;
+
// Aggregation warning settings.
+// Populate -Waddress with warnings from other groups.
+def : DiagGroup<"address", [PointerBoolConversion,
+ StringCompare,
+ TautologicalPointerCompare]>;
+
// -Widiomatic-parentheses contains warnings about 'idiomatic'
// missing parentheses; it is off by default. We do not include it
// in -Wparentheses because most users who use -Wparentheses explicitly
@@ -440,6 +478,7 @@
LiteralConversion,
NonLiteralNullConversion, // (1-1)->pointer (etc)
NullConversion, // NULL->non-pointer
+ ObjCLiteralConversion,
SignConversion,
StringConversion]>,
DiagCategory<"Value Conversion Issue">;
@@ -461,7 +500,7 @@
[FormatExtraArgs, FormatZeroLength, NonNull,
FormatSecurity, FormatY2K, FormatInvalidSpecifier]>,
DiagCategory<"Format String Issue">;
-def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
+def FormatNonLiteral : DiagGroup<"format-nonliteral">;
def Format2 : DiagGroup<"format=2",
[FormatNonLiteral, FormatSecurity, FormatY2K]>;
@@ -502,6 +541,7 @@
Unused,
VolatileRegisterVar,
ObjCMissingSuperCalls,
+ ObjCDesignatedInit,
OverloadedVirtual,
PrivateExtern,
SelTypeCast,
@@ -524,7 +564,7 @@
// Note that putting warnings in -Wall will not disable them by default. If a
// warning should be active _only_ when -Wall is passed in, mark it as
// DefaultIgnore in addition to putting it here.
-def : DiagGroup<"all", [Most, Parentheses, Switch]>;
+def : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool]>;
// Warnings enabled by -pedantic. This is magically filled in by TableGen.
def Pedantic : DiagGroup<"pedantic">;
@@ -608,8 +648,6 @@
ObjCStringComparison
]>;
-def ObjCLiteralMissingAtSign : DiagGroup<"objc-literal-missing-atsign">;
-
// Inline ASM warnings.
def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
def ASM : DiagGroup<"asm", [
@@ -618,3 +656,9 @@
// OpenMP warnings.
def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
+
+// Backend warnings.
+def BackendInlineAsm : DiagGroup<"inline-asm">;
+def BackendFrameLargerThan : DiagGroup<"frame-larger-than">;
+def BackendPlugin : DiagGroup<"backend-plugin">;
+def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 56e30fb..f9b8456 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -56,16 +56,17 @@
};
/// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
- /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
- /// (emit as an error). It allows clients to map errors to
- /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
- /// one).
+ /// to either MAP_IGNORE (nothing), MAP_REMARK (emit a remark), MAP_WARNING
+ /// (emit a warning), MAP_ERROR (emit as an error). It allows clients to
+ /// map errors to MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting
+ /// diagnostics after this one).
enum Mapping {
// NOTE: 0 means "uncomputed".
MAP_IGNORE = 1, ///< Map this diagnostic to nothing, ignore it.
- MAP_WARNING = 2, ///< Map this diagnostic to a warning.
- MAP_ERROR = 3, ///< Map this diagnostic to an error.
- MAP_FATAL = 4 ///< Map this diagnostic to a fatal error.
+ MAP_REMARK = 2, ///< Map this diagnostic to a remark.
+ MAP_WARNING = 3, ///< Map this diagnostic to a warning.
+ MAP_ERROR = 4, ///< Map this diagnostic to an error.
+ MAP_FATAL = 5 ///< Map this diagnostic to a fatal error.
};
}
@@ -113,7 +114,7 @@
public:
/// \brief The level of the diagnostic, after it has been through mapping.
enum Level {
- Ignored, Note, Warning, Error, Fatal
+ Ignored, Note, Remark, Warning, Error, Fatal
};
private:
@@ -124,11 +125,16 @@
DiagnosticIDs();
~DiagnosticIDs();
- /// \brief Return an ID for a diagnostic with the specified message and level.
+ /// \brief Return an ID for a diagnostic with the specified format string and
+ /// level.
///
/// If this is the first request for this diagnostic, it is registered and
/// created, otherwise the existing ID is returned.
- unsigned getCustomDiagID(Level L, StringRef Message);
+
+ // FIXME: Replace this function with a create-only facilty like
+ // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
+ // writing, nearly all callers of this function were invalid.
+ unsigned getCustomDiagID(Level L, StringRef FormatString);
//===--------------------------------------------------------------------===//
// Diagnostic classification and reporting interfaces.
@@ -247,15 +253,15 @@
///
/// \param Loc The source location for which we are interested in finding out
/// the diagnostic state. Can be null in order to query the latest state.
- DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
- const DiagnosticsEngine &Diag) const;
+ DiagnosticIDs::Level
+ getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
+ const DiagnosticsEngine &Diag) const LLVM_READONLY;
/// \brief An internal implementation helper used when \p DiagClass is
/// already known.
- DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
- unsigned DiagClass,
- SourceLocation Loc,
- const DiagnosticsEngine &Diag) const;
+ DiagnosticIDs::Level
+ getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, SourceLocation Loc,
+ const DiagnosticsEngine &Diag) const LLVM_READONLY;
/// \brief Used to report a diagnostic that is finally fully formed.
///
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 871f5f6..e1fc72f 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -151,7 +151,8 @@
// Literal
def ext_nonstandard_escape : Extension<
"use of non-standard escape character '\\%0'">;
-def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">;
+def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">,
+ InGroup<DiagGroup<"unknown-escape-sequence">>;
def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">;
def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">;
def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">;
@@ -300,6 +301,9 @@
InGroup<DiagGroup<"import-preprocessor-directive-pedantic">>;
def err_pp_import_directive_ms : Error<
"#import of type library is an unsupported Microsoft feature">;
+def ext_pp_include_search_ms : ExtWarn<
+ "#include resolved using non-portable MSVC search rules as: %0">,
+ InGroup<DiagGroup<"msvc-include">>;
def ext_pp_ident_directive : Extension<"#ident is a language extension">;
def ext_pp_include_next_directive : Extension<
@@ -377,8 +381,7 @@
"expected end of line in preprocessor expression">;
def err_pp_defined_requires_identifier : Error<
"operator 'defined' requires an identifier">;
-def err_pp_missing_lparen : Error<"missing '(' after '%0'">;
-def err_pp_missing_rparen : Error<"missing ')' after '%0'">;
+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<
"division by zero in preprocessor expression">;
@@ -400,6 +403,9 @@
ExtWarn<"__has_warning expected option name (e.g. \"-Wundef\")">,
InGroup<MalformedWarningCheck>;
+def err_pp_identifier_arg_not_identifier : Error<
+ "cannot convert %0 token to an identifier">;
+
def warn_pragma_include_alias_mismatch_angle :
ExtWarn<"angle-bracketed include <%0> cannot be aliased to double-quoted "
"include \"%1\"">, InGroup<UnknownPragmas>;
@@ -435,7 +441,8 @@
def err_pragma_push_pop_macro_malformed : Error<
"pragma %0 requires a parenthesized string">;
def warn_pragma_pop_macro_no_push : Warning<
- "pragma pop_macro could not pop '%0', no matching push_macro">;
+ "pragma pop_macro could not pop '%0', no matching push_macro">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_message : Warning<"%0">,
InGroup<PoundPragmaMessage>, DefaultWarnNoWerror;
def err_pragma_message : Error<"%0">;
@@ -470,7 +477,7 @@
InGroup<UnknownPragmas>;
// - #pragma __debug
def warn_pragma_debug_unexpected_command : Warning<
- "unexpected debug command '%0'">;
+ "unexpected debug command '%0'">, InGroup<IgnoredPragmas>;
def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
def err_paste_at_start : Error<
@@ -491,7 +498,7 @@
"too few arguments provided to function-like macro invocation">;
def err_pp_bad_paste : Error<
"pasting formed '%0', an invalid preprocessing token">;
-def err_pp_bad_paste_ms : Warning<
+def ext_pp_bad_paste_ms : ExtWarn<
"pasting formed '%0', an invalid preprocessing token">, DefaultError,
InGroup<DiagGroup<"invalid-token-paste">>;
def err_pp_operator_used_as_macro_name : Error<
@@ -551,8 +558,6 @@
def err_mmap_module_redefinition : Error<
"redefinition of module '%0'">;
def note_mmap_prev_definition : Note<"previously defined here">;
-def err_mmap_header_not_found : Error<
- "%select{|umbrella }0header '%1' not found">;
def err_mmap_umbrella_dir_not_found : Error<
"umbrella directory '%0' not found">;
def err_mmap_umbrella_clash : Error<
@@ -605,7 +610,7 @@
"import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
def warn_uncovered_module_header : Warning<
"umbrella header for module '%0' does not include header '%1'">,
- InGroup<IncompleteUmbrella>, DefaultIgnore;
+ InGroup<IncompleteUmbrella>;
def warn_forgotten_module_header : Warning<
"header '%0' is included in module '%1' but not listed in module map">,
InGroup<IncompleteModule>, DefaultIgnore;
@@ -614,7 +619,7 @@
def error_use_of_private_header_outside_module : Error<
"use of private header from outside its module: '%0'">;
def error_undeclared_use_of_module : Error<
- "use of a module not declared used: '%0'">;
+ "module %0 does not depend on a module exporting '%1'">;
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/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 2feab52..40fab75 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -59,7 +59,8 @@
"complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;
def ext_thread_before : Extension<"'__thread' before '%0'">;
def ext_keyword_as_ident : ExtWarn<
- "keyword '%0' will be treated as an identifier %select{here|for the remainder of the translation unit}1">,
+ "keyword '%0' will be made available as an identifier "
+ "%select{here|for the remainder of the translation unit}1">,
InGroup<KeywordCompat>;
def error_empty_enum : Error<"use of empty enum">;
@@ -148,18 +149,6 @@
def err_expected_type : Error<"expected a type">;
def err_expected_external_declaration : Error<"expected external declaration">;
def err_extraneous_closing_brace : Error<"extraneous closing brace ('}')">;
-def err_expected_ident : Error<"expected identifier">;
-def err_expected_ident_lparen : Error<"expected identifier or '('">;
-def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
-def err_expected_lbrace : Error<"expected '{'">;
-def err_expected_lparen : Error<"expected '('">;
-def err_expected_lparen_or_lbrace : Error<"expected '(' or '{'">;
-def err_expected_rparen : Error<"expected ')'">;
-def err_expected_lsquare : Error<"expected '['">;
-def err_expected_rsquare : Error<"expected ']'">;
-def err_expected_rbrace : Error<"expected '}'">;
-def err_expected_greater : Error<"expected '>'">;
-def err_expected_ggg : Error<"expected '>>>'">;
def err_expected_semi_declaration : Error<
"expected ';' at end of declaration">;
def err_expected_semi_decl_list : Error<
@@ -185,18 +174,16 @@
def err_invalid_token_after_toplevel_declarator : Error<
"expected ';' after top level declarator">;
def err_invalid_token_after_declarator_suggest_equal : Error<
- "invalid '%0' at end of declaration; did you mean '='?">;
+ "invalid %0 at end of declaration; did you mean '='?">;
def err_expected_statement : Error<"expected statement">;
def err_expected_lparen_after : Error<"expected '(' after '%0'">;
-def err_expected_lparen_after_id : Error<"expected '(' after %0">;
+def err_expected_rparen_after : Error<"expected ')' after '%0'">;
+def err_expected_punc : Error<"expected ')' or ',' after '%0'">;
def err_expected_less_after : Error<"expected '<' after '%0'">;
-def err_expected_equal_after : Error<"expected '=' after %0">;
-def err_expected_comma : Error<"expected ','">;
def err_expected_lbrace_in_compound_literal : Error<
"expected '{' in compound literal">;
def err_expected_while : Error<"expected 'while' in do/while loop">;
-def err_expected_semi_after : Error<"expected ';' after %0">;
def err_expected_semi_after_stmt : Error<"expected ';' after %0 statement">;
def err_expected_semi_after_expr : Error<"expected ';' after expression">;
def err_extraneous_token_before_semi : Error<"extraneous '%0' before ';'">;
@@ -206,7 +193,7 @@
def err_expected_semi_after_namespace_name : Error<
"expected ';' after namespace name">;
def err_unexpected_namespace_attributes_alias : Error<
- "attributes can not be specified on namespace alias">;
+ "attributes cannot be specified on namespace alias">;
def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
def err_namespace_nonnamespace_scope : Error<
"namespaces can only be defined in global or namespace scope">;
@@ -217,7 +204,6 @@
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_expected_colon_after : Error<"expected ':' after %0">;
def warn_missing_selector_name : Warning<
"%0 used as the name of the previous parameter rather than as part "
"of the selector">,
@@ -238,6 +224,8 @@
def err_expected_property_name : Error<"expected property name">;
def err_unexpected_at : Error<"unexpected '@' in program">;
+def err_atimport : Error<
+"use of '@import' when modules are disabled, add -fmodules">;
def err_invalid_reference_qualifier_application : Error<
"'%0' qualifier may not be applied to a reference">;
@@ -364,6 +352,8 @@
"unexpected parenthesis after '::'">;
def err_function_definition_not_allowed : Error<
"function definition is not allowed here">;
+def err_expected_end_of_enumerator : Error<
+ "expected '= constant-expression' or end of enumerator definition">;
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
@@ -424,7 +414,7 @@
def err_expected_objc_container : Error<
"'@end' must appear in an Objective-C context">;
def err_unexpected_protocol_qualifier : Error<
- "@implementation declaration can not be protocol qualified">;
+ "@implementation declaration cannot be protocol qualified">;
def err_objc_unexpected_atend : Error<
"'@end' appears where closing brace '}' is expected">;
def error_property_ivar_decl : Error<
@@ -480,9 +470,6 @@
"noexcept specifications are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_expected_catch : Error<"expected catch">;
-def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
-def err_expected_rbrace_or_comma : Error<"expected '}' or ','">;
-def err_expected_rsquare_or_comma : Error<"expected ']' or ','">;
def err_using_namespace_in_class : Error<
"'using namespace' is not allowed in classes">;
def err_constructor_bad_name : Error<
@@ -504,8 +491,7 @@
"ISO C++11 requires a parenthesized pack declaration to have a name">,
InGroup<DiagGroup<"anonymous-pack-parens">>;
def err_function_is_not_record : Error<
- "unexpected '%select{.|->}0' in function call; perhaps remove the "
- "'%select{.|->}0'?">;
+ "unexpected %0 in function call; perhaps remove the %0?">;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -535,7 +521,7 @@
def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_attribute : Warning<
- "attributes are incompatible with C++98">,
+ "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">;
@@ -549,8 +535,6 @@
"introducing an attribute">;
def err_ms_declspec_type : Error<
"__declspec attributes must be an identifier or string literal">;
-def warn_ms_declspec_unknown : Warning<
- "unknown __declspec attribute %0 ignored">, InGroup<UnknownAttributes>;
def err_ms_property_no_getter_or_putter : Error<
"property does not specify a getter or a putter">;
def err_ms_property_unknown_accessor : Error<
@@ -578,8 +562,8 @@
"template template parameter requires 'class' after the parameter list">;
def err_template_spec_syntax_non_template : Error<
"identifier followed by '<' indicates a class template specialization but "
- "%0 %select{does not refer to a template|refers to a function "
- "template|<unused>|refers to a template template parameter}1">;
+ "%0 %select{does not refer to a template|refers to a function template|"
+ "<unused>|refers to a variable template|<unused>}1">;
def err_id_after_template_in_nested_name_spec : Error<
"expected template name after 'template' keyword in nested name specifier">;
def err_two_right_angle_brackets_need_space : Error<
@@ -639,16 +623,13 @@
"expected a qualified name after 'typename'">;
def warn_expected_qualified_after_typename : ExtWarn<
"expected a qualified name after 'typename'">;
-def err_expected_semi_after_tagdecl : Error<
- "expected ';' after %0">;
def err_typename_refers_to_non_type_template : Error<
- "typename specifier refers to a non-template">;
+ "typename specifier refers to a non-type template">;
def err_expected_type_name_after_typename : Error<
"expected an identifier or template-id after '::'">;
def err_explicit_spec_non_template : Error<
- "explicit %select{specialization|instantiation}0 of non-template "
- "%select{class|struct|union|interface}1 %2">;
+ "explicit %select{specialization|instantiation}0 of non-template %1 %2">;
def err_default_template_template_parameter_not_template : Error<
"default template argument for a template template parameter must be a class "
@@ -744,7 +725,8 @@
"lambda expressions are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_lambda_missing_parens : Error<
- "lambda requires '()' before %select{'mutable'|return type}0">;
+ "lambda requires '()' before %select{'mutable'|return type|"
+ "attribute specifier}0">;
// Availability attribute
def err_expected_version : Error<
@@ -753,6 +735,13 @@
"version number must have non-zero major, minor, or sub-minor version">;
def err_availability_expected_platform : Error<
"expected a platform name, e.g., 'macosx'">;
+
+// objc_bridge_related attribute
+def err_objcbridge_related_expected_related_class : Error<
+ "expected a related ObjectiveC class name, e.g., 'NSColor'">;
+def err_objcbridge_related_selector_name : Error<
+ "expected a class method selector with single argument, e.g., 'colorWithCGColor:'">;
+
def err_availability_expected_change : Error<
"expected 'introduced', 'deprecated', or 'obsoleted'">;
def err_availability_unknown_change : Error<
@@ -769,35 +758,51 @@
def err_type_safety_unknown_flag : Error<
"invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">;
+// Type traits
+def err_type_trait_arity : Error<
+ "type trait requires %0%select{| or more}1 argument%select{|s}2; have "
+ "%3 argument%s3">;
+
// Language specific pragmas
// - Generic warnings
def warn_pragma_expected_lparen : Warning<
- "missing '(' after '#pragma %0' - ignoring">;
+ "missing '(' after '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_rparen : Warning<
- "missing ')' after '#pragma %0' - ignoring">;
+ "missing ')' after '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_identifier : Warning<
- "expected identifier in '#pragma %0' - ignored">;
+ "expected identifier 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>;
def warn_pragma_ms_struct : Warning<
- "incorrect use of '#pragma ms_struct on|off' - ignored">;
+ "incorrect use of '#pragma ms_struct on|off' - ignored">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_extra_tokens_at_eol : Warning<
- "extra tokens at end of '#pragma %0' - ignored">;
+ "extra tokens at end of '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
+def warn_pragma_expected_punc : Warning<
+ "expected ')' or ',' in '#pragma %0'">, InGroup<IgnoredPragmas>;
// - #pragma options
def warn_pragma_options_expected_align : Warning<
- "expected 'align' following '#pragma options' - ignored">;
+ "expected 'align' following '#pragma options' - ignored">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_align_expected_equal : Warning<
- "expected '=' following '#pragma %select{align|options align}0' - ignored">;
+ "expected '=' following '#pragma %select{align|options align}0' - ignored">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_align_invalid_option : Warning<
- "invalid alignment option in '#pragma %select{align|options align}0' - ignored">;
+ "invalid alignment option in '#pragma %select{align|options align}0' - ignored">,
+ InGroup<IgnoredPragmas>;
// - #pragma pack
-def warn_pragma_pack_invalid_action : Warning<
- "unknown action for '#pragma pack' - ignored">;
+def warn_pragma_invalid_action : Warning<
+ "unknown action for '#pragma %0' - ignored">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_pack_malformed : Warning<
- "expected integer or identifier in '#pragma pack' - ignored">;
+ "expected integer or identifier in '#pragma pack' - ignored">,
+ InGroup<IgnoredPragmas>;
// - #pragma unused
def warn_pragma_unused_expected_var : Warning<
- "expected '#pragma unused' argument to be a variable name">;
-def warn_pragma_unused_expected_punc : Warning<
- "expected ')' or ',' in '#pragma unused'">;
+ "expected '#pragma unused' argument to be a variable name">,
+ InGroup<IgnoredPragmas>;
// - #pragma fp_contract
def err_pragma_fp_contract_scope : Error<
"'#pragma fp_contract' can only appear at file scope or at the start of a "
@@ -810,6 +815,10 @@
def err_pragma_detect_mismatch_malformed : Error<
"pragma detect_mismatch is malformed; it requires two comma-separated "
"string literals">;
+// - #pragma pointers_to_members
+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'">;
// OpenCL Section 6.8.g
def err_not_opencl_storage_class_specifier : Error<
@@ -817,11 +826,11 @@
// OpenCL EXTENSION pragma (OpenCL 1.1 [9.1])
def warn_pragma_expected_colon : Warning<
- "missing ':' after %0 - ignoring">;
+ "missing ':' after %0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_enable_disable : Warning<
- "expected 'enable' or 'disable' - ignoring">;
+ "expected 'enable' or 'disable' - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unknown_extension : Warning<
- "unknown OpenCL extension %0 - ignoring">;
+ "unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
def err_seh_expected_handler : Error<
"expected '__except' or '__finally' block">;
@@ -836,20 +845,20 @@
"%0 only allowed in __finally block">;
// OpenMP support.
-def warn_pragma_omp_ignored : Warning <
+def warn_pragma_omp_ignored : Warning<
"unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;
-def warn_omp_extra_tokens_at_eol : Warning <
+def warn_omp_extra_tokens_at_eol : Warning<
"extra tokens at the end of '#pragma omp %0' are ignored">,
InGroup<ExtraTokens>;
-def err_omp_unknown_directive : Error <
+def err_omp_unknown_directive : Error<
"expected an OpenMP directive">;
-def err_omp_unexpected_directive : Error <
+def err_omp_unexpected_directive : Error<
"unexpected OpenMP directive '#pragma omp %0'">;
-def err_omp_expected_punc : Error <
- "expected ',' or ')' in %select{'#pragma omp %1'|'%1' clause}0">;
-def err_omp_unexpected_clause : Error <
+def err_omp_expected_punc : Error<
+ "expected ',' or ')' in '%0' clause">;
+def err_omp_unexpected_clause : Error<
"unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
-def err_omp_more_one_clause : Error <
+def err_omp_more_one_clause : Error<
"directive '#pragma omp %0' cannot contain more than one '%1' clause">;
} // end of Parse Issue category.
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 6c7cb00..b138619 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -30,6 +30,25 @@
"been assigned">, InGroup<DiagGroup<"duplicate-enum">>, DefaultIgnore;
def note_duplicate_element : Note<"element %0 also has value %1">;
+// Absolute value functions
+def warn_unsigned_abs : Warning<
+ "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">;
+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>;
+def warn_wrong_absolute_value_type : Warning<
+ "using %select{integer|floating point|complex}1 absolute value function %0 "
+ "when argument is of %select{integer|floating point|complex}2 type">,
+ InGroup<AbsoluteValue>;
+def note_replace_abs_function : Note<"use function '%0' instead">;
+
+def warn_infinite_recursive_function : Warning<
+ "all paths through this function will call itself">,
+ InGroup<InfiniteRecursion>, DefaultIgnore;
+
// Constant expressions
def err_expr_not_ice : Error<
"expression is not an %select{integer|integral}0 constant expression">;
@@ -87,9 +106,9 @@
def err_vla_decl_in_file_scope : Error<
"variable length array declaration not allowed at file scope">;
def err_vla_decl_has_static_storage : Error<
- "variable length array declaration can not have 'static' storage duration">;
+ "variable length array declaration cannot have 'static' storage duration">;
def err_vla_decl_has_extern_linkage : Error<
- "variable length array declaration can not have 'extern' linkage">;
+ "variable length array declaration cannot have 'extern' linkage">;
def ext_vla_folded_to_constant : Extension<
"variable length array folded to constant array as an extension">, InGroup<GNUFoldingConstant>;
@@ -142,7 +161,7 @@
def err_bad_variable_name : Error<
"%0 cannot be the name of a variable or data member">;
def err_bad_parameter_name : Error<
- "'%0' cannot be the name of a parameter">;
+ "%0 cannot be the name of a parameter">;
def err_parameter_name_omitted : Error<"parameter name omitted">;
def warn_unused_parameter : Warning<"unused parameter %0">,
InGroup<UnusedParameter>, DefaultIgnore;
@@ -218,7 +237,10 @@
def err_ellipsis_first_arg : Error<
"ISO C requires a named argument before '...'">;
def err_declarator_need_ident : Error<"declarator requires an identifier">;
-def err_bad_language : Error<"unknown linkage language">;
+def err_language_linkage_spec_unknown : Error<"unknown linkage language">;
+def err_language_linkage_spec_not_ascii : Error<
+ "string literal in language linkage specifier cannot have an "
+ "encoding-prefix">;
def warn_use_out_of_scope_declaration : Warning<
"use of out-of-scope declaration of %0">;
def err_inline_non_function : Error<
@@ -251,9 +273,9 @@
def err_using_decl_nested_name_specifier_is_not_base_class : Error<
"using declaration refers into '%0', which is not a base class of %1">;
def err_using_decl_constructor_not_in_direct_base : Error<
- "%0 is not a direct base of %1, can not inherit constructors">;
+ "%0 is not a direct base of %1, cannot inherit constructors">;
def err_using_decl_constructor_conflict : Error<
- "can not inherit constructor, already inherited constructor with "
+ "cannot inherit constructor, already inherited constructor with "
"the same signature">;
def note_using_decl_constructor_conflict_current_ctor : Note<
"conflicting constructor">;
@@ -267,18 +289,21 @@
def note_using_decl_constructor_ellipsis : Note<
"constructor declared with ellipsis here">;
def err_using_decl_can_not_refer_to_class_member : Error<
- "using declaration can not refer to class member">;
+ "using declaration cannot refer to class member">;
+def note_using_decl_class_member_workaround : Note<
+ "use %select{an alias declaration|a typedef declaration|a reference}0 "
+ "instead">;
def err_using_decl_can_not_refer_to_namespace : Error<
- "using declaration can not refer to namespace">;
+ "using declaration cannot refer to namespace">;
def err_using_decl_constructor : Error<
- "using declaration can not refer to a constructor">;
+ "using declaration cannot refer to a constructor">;
def warn_cxx98_compat_using_decl_constructor : Warning<
"inheriting constructors are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_using_decl_destructor : Error<
- "using declaration can not refer to a destructor">;
+ "using declaration cannot refer to a destructor">;
def err_using_decl_template_id : Error<
- "using declaration can not refer to a template specialization">;
+ "using declaration cannot refer to a template specialization">;
def note_using_decl_target : Note<"target of using declaration">;
def note_using_decl_conflict : Note<"conflicting declaration">;
def err_using_decl_redeclaration : Error<"redeclaration of using decl">;
@@ -337,8 +362,22 @@
def warn_suggest_noreturn_block : Warning<
"block could be declared with attribute 'noreturn'">,
InGroup<MissingNoreturn>, DefaultIgnore;
-def warn_unreachable : Warning<"will never be executed">,
- InGroup<DiagGroup<"unreachable-code">>, DefaultIgnore;
+
+// Unreachable code.
+def warn_unreachable : Warning<
+ "code will never be executed">,
+ InGroup<UnreachableCode>, DefaultIgnore;
+def warn_unreachable_break : Warning<
+ "'break' will never be executed">,
+ InGroup<UnreachableCodeBreak>, DefaultIgnore;
+def warn_unreachable_return : Warning<
+ "'return' will never be executed">,
+ InGroup<UnreachableCodeReturn>, DefaultIgnore;
+def warn_unreachable_loop_increment : Warning<
+ "loop will run at most once (loop increment never executed)">,
+ InGroup<UnreachableCodeLoopIncrement>, DefaultIgnore;
+def note_unreachable_silence : Note<
+ "silence by adding parentheses to mark code as explicitly dead">;
/// Built-in functions.
def ext_implicit_lib_function_decl : ExtWarn<
@@ -363,8 +402,6 @@
"incompatible redeclaration of library function %0">,
InGroup<DiagGroup<"incompatible-library-redeclaration">>;
def err_builtin_definition : Error<"definition of builtin function %0">;
-def err_types_compatible_p_in_cplusplus : Error<
- "__builtin_types_compatible_p is not valid in C++">;
def warn_builtin_unknown : Warning<"use of unknown builtin %0">,
InGroup<ImplicitFunctionDeclare>, DefaultError;
def warn_dyn_class_memaccess : Warning<
@@ -388,11 +425,18 @@
"%select{destination|source}2; expected %3 or an explicit length">,
InGroup<SizeofPointerMemaccess>;
def warn_strlcpycat_wrong_size : Warning<
- "size argument in %0 call appears to be size of the source; expected the size of "
- "the destination">,
+ "size argument in %0 call appears to be size of the source; "
+ "expected the size of the destination">,
InGroup<DiagGroup<"strlcpy-strlcat-size">>;
def note_strlcpycat_wrong_size : Note<
"change size argument to be the size of the destination">;
+def warn_memsize_comparison : Warning<
+ "size argument in %0 call is a comparison">,
+ InGroup<DiagGroup<"memsize-comparison">>;
+def warn_memsize_comparison_paren_note : Note<
+ "did you mean to compare the result of %0 instead?">;
+def warn_memsize_comparison_cast_note : Note<
+ "explicitly cast the argument to size_t to silence this warning">;
def warn_strncat_large_size : Warning<
"the value of the size argument in 'strncat' is too large, might lead to a "
@@ -416,7 +460,8 @@
def note_main_remove_noreturn : Note<"remove '_Noreturn'">;
def err_constexpr_main : Error<
"'main' is not allowed to be declared constexpr">;
-def err_mainlike_template_decl : Error<"'%0' cannot be a template">;
+def err_deleted_main : Error<"'main' is not allowed to be deleted">;
+def err_mainlike_template_decl : Error<"%0 cannot be a template">;
def err_main_returns_nonint : Error<"'main' must return 'int'">;
def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,
InGroup<MainReturnType>;
@@ -428,6 +473,8 @@
def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
"parameter of 'main' (%select{argument count|argument array|environment|"
"platform-specific data}0) must be of type %1">;
+def ext_main_used : Extension<
+ "ISO C++ does not allow 'main' to be used by a program">, InGroup<Main>;
/// parser diagnostics
def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
@@ -435,6 +482,10 @@
def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">,
InGroup<MissingDeclarations>;
def err_typedef_not_identifier : Error<"typedef name must be an identifier">;
+def err_typedef_changes_linkage : Error<"unsupported: typedef changes linkage"
+ " of anonymous type, but linkage was already computed">;
+def note_typedef_changes_linkage : Note<"use a tag name here to establish "
+ "linkage prior to definition">;
def err_statically_allocated_object : Error<
"interface type cannot be statically allocated">;
def err_object_cannot_be_passed_returned_by_value : Error<
@@ -453,22 +504,30 @@
"declaring function return value of type %0 is not allowed; did you forget * ?">;
def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
def warn_pragma_options_align_reset_failed : Warning<
- "#pragma options align=reset failed: %0">;
+ "#pragma options align=reset failed: %0">,
+ InGroup<IgnoredPragmas>;
def err_pragma_options_align_mac68k_target_unsupported : Error<
"mac68k alignment pragma is not supported on this target">;
def warn_pragma_pack_invalid_alignment : Warning<
- "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">;
+ "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">,
+ InGroup<IgnoredPragmas>;
// Follow the MSVC implementation.
def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">;
def warn_pragma_pack_pop_identifer_and_alignment : Warning<
"specifying both a name and alignment to 'pop' is undefined">;
-def warn_pragma_pack_pop_failed : Warning<"#pragma pack(pop, ...) failed: %0">;
-def warn_pragma_ms_struct_failed : Warning<"#pramga ms_struct can not be used with dynamic classes or structures">, InGroup<IgnoredAttributes>;
+def warn_pragma_pop_failed : Warning<"#pragma %0(pop, ...) failed: %1">,
+ InGroup<IgnoredPragmas>;
+def warn_cxx_ms_struct :
+ Warning<"ms_struct may not produce MSVC-compatible layouts for classes "
+ "with base classes or virtual functions">,
+ DefaultError, InGroup<IncompatibleMSStruct>;
def warn_pragma_unused_undeclared_var : Warning<
- "undeclared variable %0 used as an argument for '#pragma unused'">;
+ "undeclared variable %0 used as an argument for '#pragma unused'">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_unused_expected_var_arg : Warning<
- "only variables can be arguments to '#pragma unused'">;
+ "only variables can be arguments to '#pragma unused'">,
+ InGroup<IgnoredPragmas>;
def err_pragma_push_visibility_mismatch : Error<
"#pragma visibility push with no matching #pragma visibility pop">;
def note_surrounding_namespace_ends_here : Note<
@@ -547,12 +606,10 @@
"instance variable %0 has conflicting bit-field width">;
def err_conflicting_ivar_name : Error<
"conflicting instance variable names: %0 vs %1">;
-def err_inconsistant_ivar_count : Error<
+def err_inconsistent_ivar_count : Error<
"inconsistent number of instance variables specified">;
def warn_undef_method_impl : Warning<"method definition for %0 not found">,
InGroup<DiagGroup<"incomplete-implementation">>;
-def note_required_for_protocol_at :
- Note<"required for direct or indirect protocol %0">;
def warn_conflicting_overriding_ret_types : Warning<
"conflicting return type in "
@@ -696,21 +753,21 @@
def err_atomic_property_nontrivial_assign_op : Error<
"atomic property of reference type %0 cannot have non-trivial assignment"
" operator">;
-def warn_owning_getter_rule : Warning<
- "property's synthesized getter follows Cocoa naming"
+def warn_cocoa_naming_owned_rule : Warning<
+ "property follows Cocoa naming"
" convention for returning 'owned' objects">,
InGroup<DiagGroup<"objc-property-matches-cocoa-ownership-rule">>;
def warn_auto_synthesizing_protocol_property :Warning<
- "auto property synthesis will not synthesize property"
- " declared in a protocol">,
+ "auto property synthesis will not synthesize property %0"
+ " declared in protocol %1">,
InGroup<DiagGroup<"objc-protocol-property-synthesis">>;
def warn_no_autosynthesis_shared_ivar_property : Warning <
"auto property synthesis will not synthesize property "
- "'%0' because it cannot share an ivar with another synthesized property">,
+ "%0 because it cannot share an ivar with another synthesized property">,
InGroup<ObjCNoPropertyAutoSynthesis>;
def warn_no_autosynthesis_property : Warning<
"auto property synthesis will not synthesize property "
- "'%0' because it is 'readwrite' but it will be synthesized 'readonly' "
+ "%0 because it is 'readwrite' but it will be synthesized 'readonly' "
"via another property">,
InGroup<ObjCNoPropertyAutoSynthesis>;
def warn_autosynthesis_property_ivar_match :Warning<
@@ -724,10 +781,10 @@
"property declared as returning non-retained objects"
"; getter returning retained objects">;
def error_property_setter_ambiguous_use : Error<
- "synthesized properties '%0' and '%1' both claim setter %2 -"
+ "synthesized properties %0 and %1 both claim setter %2 -"
" use of this setter will cause unexpected behavior">;
-def err_ownin_getter_rule : Error<
- "property's synthesized getter follows Cocoa naming"
+def err_cocoa_naming_owned_rule : Error<
+ "property follows Cocoa naming"
" convention for returning 'owned' objects">;
def warn_default_atomic_custom_getter_setter : Warning<
"atomic by default property %0 has a user defined %select{getter|setter}1 "
@@ -778,6 +835,9 @@
def warn_arc_perform_selector_leaks : Warning<
"performSelector may cause a leak because its selector is unknown">,
InGroup<DiagGroup<"arc-performSelector-leaks">>;
+def warn_dealloc_in_category : Warning<
+"-dealloc is being overridden in a category">,
+InGroup<DeallocInCategory>;
def err_gc_weak_property_strong_type : Error<
"weak attribute declared on a __strong type property in GC mode">;
def warn_receiver_is_weak : Warning <
@@ -818,13 +878,10 @@
def error_strong_property : Error<
"existing instance variable %1 for strong property %0 may not be __weak">;
def error_dynamic_property_ivar_decl : Error<
- "dynamic property can not have instance variable specification">;
+ "dynamic property cannot have instance variable specification">;
def error_duplicate_ivar_use : Error<
"synthesized properties %0 and %1 both claim instance variable %2">;
def error_property_implemented : Error<"property %0 is already implemented">;
-def warn_objc_property_attr_mutually_exclusive : Warning<
- "property attributes '%0' and '%1' are mutually exclusive">,
- InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
def warn_objc_missing_super_call : Warning<
"method possibly missing a [super %0] call">,
InGroup<ObjCMissingSuperCalls>;
@@ -841,19 +898,21 @@
def note_auto_readonly_iboutlet_fixup_suggest : Note<
"property should be changed to be readwrite">;
def warn_auto_readonly_iboutlet_property : Warning<
- "readonly IBOutlet property '%0' when auto-synthesized may "
+ "readonly IBOutlet property %0 when auto-synthesized may "
"not work correctly with 'nib' loader">,
InGroup<DiagGroup<"readonly-iboutlet-property">>;
def warn_auto_implicit_atomic_property : Warning<
"property is assumed atomic when auto-synthesizing the property">,
InGroup<ImplicitAtomic>, DefaultIgnore;
def warn_unimplemented_selector: Warning<
- "creating selector for nonexistent method %0">, InGroup<Selector>, DefaultIgnore;
-def warning_multiple_selectors: Warning<
- "multiple selectors named %0 found">, InGroup<SelectorTypeMismatch>, DefaultIgnore;
+ "no method with selector %0 is implemented in this translation unit">,
+ InGroup<Selector>, DefaultIgnore;
def warn_unimplemented_protocol_method : Warning<
- "method %0 in protocol not implemented">, InGroup<Protocol>;
-
+ "method %0 in protocol %1 not implemented">, InGroup<Protocol>;
+def warning_multiple_selectors: Warning<
+ "several methods with selector %0 of mismatched types are found "
+ "for the @selector expression">,
+ InGroup<SelectorTypeMismatch>, DefaultIgnore;
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
"static_assert expression is not an integral constant expression">;
@@ -937,19 +996,23 @@
def err_array_of_abstract_type : Error<"array of abstract class type %0">;
def err_capture_of_abstract_type : Error<
"by-copy capture of value of abstract type %0">;
+def err_capture_of_incomplete_type : Error<
+ "by-copy capture of variable %0 with incomplete type %1">;
+def err_capture_default_non_local : Error<
+ "non-local lambda expression cannot have a capture-default">;
def err_multiple_final_overriders : Error<
"virtual function %q0 has more than one final overrider in %1">;
def note_final_overrider : Note<"final overrider of %q0 in %1">;
def err_type_defined_in_type_specifier : Error<
- "%0 can not be defined in a type specifier">;
+ "%0 cannot be defined in a type specifier">;
def err_type_defined_in_result_type : Error<
- "%0 can not be defined in the result type of a function">;
+ "%0 cannot be defined in the result type of a function">;
def err_type_defined_in_param_type : Error<
- "%0 can not be defined in a parameter type">;
+ "%0 cannot be defined in a parameter type">;
def err_type_defined_in_alias_template : Error<
- "%0 can not be defined in a type alias template">;
+ "%0 cannot be defined in a type alias template">;
def note_pure_virtual_function : Note<
"unimplemented pure virtual method %0 in %1">;
@@ -1119,7 +1182,7 @@
def err_virtual_out_of_class : Error<
"'virtual' can only be specified inside the class definition">;
def err_virtual_member_function_template : Error<
- "'virtual' can not be specified on member function templates">;
+ "'virtual' cannot be specified on member function templates">;
def err_static_overrides_virtual : Error<
"'static' member function %0 overrides a virtual function in a base class">;
def err_explicit_non_function : Error<
@@ -1495,16 +1558,22 @@
"declaration of variable %0 with type %1 requires an initializer">;
def err_auto_new_requires_ctor_arg : Error<
"new expression for type %0 requires a constructor argument">;
-def err_auto_new_requires_parens : Error<
+def err_auto_new_list_init : Error<
"new expression for type %0 cannot use list-initialization">;
def err_auto_var_init_no_expression : Error<
"initializer for variable %0 with type %1 is empty">;
def err_auto_var_init_multiple_expressions : Error<
"initializer for variable %0 with type %1 contains multiple expressions">;
+def err_auto_var_init_paren_braces : Error<
+ "cannot deduce type for variable %0 with type %1 from "
+ "parenthesized initializer list">;
def err_auto_new_ctor_multiple_expressions : Error<
"new expression for type %0 contains multiple constructor arguments">;
def err_auto_missing_trailing_return : Error<
- "'auto' return without trailing return type">;
+ "'auto' return without trailing return type; deduced return types are a "
+ "C++1y extension">;
+def err_deduced_return_type : Error<
+ "deduced return types are a C++1y extension">;
def err_trailing_return_without_auto : Error<
"function with trailing return type must specify return type 'auto', not %0">;
def err_trailing_return_in_parens : Error<
@@ -1570,7 +1639,7 @@
"abstract class is marked '%select{final|sealed}0'">, InGroup<AbstractFinalClass>;
// C++11 attributes
-def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
+def err_repeat_attribute : Error<"%0 attribute cannot be repeated">;
// C++11 final
def err_final_function_overridden : Error<
@@ -1730,6 +1799,8 @@
def ext_constexpr_function_never_constant_expr : ExtWarn<
"constexpr %select{function|constructor}0 never produces a "
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
+def err_enable_if_never_constant_expr : Error<
+ "'enable_if' attribute expression never produces a constant expression">;
def err_constexpr_body_no_return : Error<
"no return statement in constexpr function">;
def warn_cxx11_compat_constexpr_body_no_return : Warning<
@@ -1786,7 +1857,7 @@
// Attributes
def err_nsobject_attribute : Error<
- "__attribute ((NSObject)) is for pointer types only">;
+ "'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<
@@ -1795,12 +1866,9 @@
"%0 attribute %plural{0:takes no arguments|1:takes one argument|"
":requires exactly %1 arguments}1">;
def err_attribute_too_many_arguments : Error<
- "attribute takes no more than %0 argument%s0">;
-def err_suppress_autosynthesis : Error<
- "objc_requires_property_definitions attribute may only be specified on a class"
- "to a class declaration">;
+ "%0 attribute takes no more than %1 argument%s1">;
def err_attribute_too_few_arguments : Error<
- "attribute takes at least %0 argument%s0">;
+ "%0 attribute takes at least %1 argument%s1">;
def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
def err_attribute_bad_neon_vector_size : Error<
"Neon vector size must be 64 or 128 bits">;
@@ -1809,14 +1877,11 @@
def err_aligned_attribute_argument_not_int : Error<
"'aligned' attribute requires integer constant">;
def err_alignas_attribute_wrong_decl_type : Error<
- "'%select{alignas|_Alignas}0' attribute cannot be applied to a %select{"
- "function parameter|variable with 'register' storage class|"
- "'catch' variable|bit-field}1">;
+ "%0 attribute cannot be applied to a %select{function parameter|"
+ "variable with 'register' storage class|'catch' variable|bit-field}1">;
def err_alignas_missing_on_definition : Error<
- "'%select{alignas|_Alignas}0' must be specified on definition if it is "
- "specified on any declaration">;
-def note_alignas_on_declaration : Note<
- "declared with '%select{alignas|_Alignas}0' attribute here">;
+ "%0 must be specified on definition if it is specified on any declaration">;
+def note_alignas_on_declaration : Note<"declared with %0 attribute here">;
def err_alignas_mismatch : Error<
"redeclaration has different alignment requirement (%1 vs %0)">;
def err_alignas_underaligned : Error<
@@ -1836,17 +1901,20 @@
def err_attribute_argument_vec_type_hint : Error<
"invalid attribute argument %0 - expecting a vector or vectorizable scalar type">;
def err_attribute_argument_out_of_bounds : Error<
- "'%0' attribute parameter %1 is out of bounds">;
+ "%0 attribute parameter %1 is out of bounds">;
def err_attribute_uuid_malformed_guid : Error<
"uuid attribute contains a malformed GUID">;
-def warn_nonnull_pointers_only : Warning<
- "nonnull attribute only applies to pointer arguments">;
-def err_attribute_pointers_only : Error<
- "%0 attribute only applies to pointer arguments">;
+def warn_attribute_pointers_only : Warning<
+ "%0 attribute only applies to pointer arguments">,
+ InGroup<IgnoredAttributes>;
+def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Text>;
+def warn_attribute_return_pointers_only : Warning<
+ "%0 attribute only applies to return values that are pointers">,
+ InGroup<IgnoredAttributes>;
def err_attribute_no_member_pointers : Error<
"%0 attribute cannot be used with pointers to members">;
def err_attribute_invalid_implicit_this_argument : Error<
- "'%0' attribute is invalid for the implicit this argument">;
+ "%0 attribute is invalid for the implicit this argument">;
def err_ownership_type : Error<
"%0 attribute only applies to %select{pointer|integer}1 arguments">;
def err_format_strftime_third_parameter : Error<
@@ -1858,8 +1926,6 @@
def err_format_attribute_implicit_this_format_string : Error<
"format attribute cannot specify the implicit this argument as the format "
"string">;
-def err_common_not_supported_cplusplus : Error<
- "common attribute is not supported in C++">;
def err_init_method_bad_return_type : Error<
"init methods must return an object pointer type, not %0">;
def err_attribute_invalid_size : Error<
@@ -1868,8 +1934,8 @@
def err_attribute_size_too_large : Error<"vector size too large">;
def err_typecheck_vector_not_convertable : Error<
"can't convert between vector values of different size (%0 and %1)">;
-def err_typecheck_ext_vector_not_typedef : Error<
- "ext_vector_type only applies to types, not variables">;
+def err_typecheck_vector_not_convertable_non_scalar : Error<
+ "can't convert between vector and non-scalar values (%0 and %1)">;
def err_ext_vector_component_exceeds_length : Error<
"vector component access exceeds type %0">;
def err_ext_vector_component_name_illegal : Error<
@@ -1923,8 +1989,8 @@
"direct comparison of %select{an array literal|a dictionary literal|"
"a numeric literal|a boxed expression|}0 has undefined behavior">,
InGroup<ObjCLiteralComparison>;
-def warn_missing_atsign_prefix : Warning<
- "string literal must be prefixed by '@' ">, InGroup<ObjCLiteralMissingAtSign>;
+def err_missing_atsign_prefix : Error<
+ "string literal must be prefixed by '@' ">;
def warn_objc_string_literal_comparison : Warning<
"direct comparison of a string literal has undefined behavior">,
InGroup<ObjCStringComparison>;
@@ -1948,30 +2014,24 @@
def err_attribute_section_invalid_for_target : Error<
"argument to 'section' attribute is not valid for this target: %0">;
-def err_attribute_section_local_variable : Error<
- "'section' attribute is not valid on local variables">;
def warn_mismatched_section : Warning<
"section does not match previous declaration">, InGroup<Section>;
def err_anonymous_property: Error<
"anonymous property is not supported">;
-def err_property_is_variably_modified: Error<
- "property '%0' has a variably modified type">;
-def err_no_getter_for_property : Error<
- "no getter defined for property '%0'">;
-def err_no_setter_for_property : Error<
- "no setter defined for property '%0'">;
-def error_cannot_find_suitable_getter : Error<
- "cannot find suitable getter for property '%0'">;
-def error_cannot_find_suitable_setter : Error<
- "cannot find suitable setter for property '%0'">;
+def err_property_is_variably_modified : Error<
+ "property %0 has a variably modified type">;
+def err_no_accessor_for_property : Error<
+ "no %select{getter|setter}0 defined for property %1">;
+def error_cannot_find_suitable_accessor : Error<
+ "cannot find suitable %select{getter|setter}0 for property %1">;
def err_attribute_aligned_not_power_of_two : Error<
"requested alignment is not a power of 2">;
-def err_attribute_aligned_greater_than_8192 : Error<
- "requested alignment must be 8192 bytes or smaller">;
+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">;
+ "%0 redeclared without %1 attribute: previous %1 ignored">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">,
InGroup<IgnoredAttributes>;
def warn_attribute_after_definition_ignored : Warning<
@@ -2005,8 +2065,8 @@
"Objective-C GC does not allow weak variables on the stack">,
InGroup<IgnoredAttributes>;
def warn_nsobject_attribute : Warning<
- "__attribute ((NSObject)) may be put on a typedef only, "
- "attribute is ignored">, InGroup<NSobjectAttribute>;
+ "'NSObject' attribute may be put on a typedef only; attribute is ignored">,
+ InGroup<NSobjectAttribute>;
def warn_attribute_weak_on_local : Warning<
"__weak attribute cannot be specified on an automatic variable when ARC "
"is not enabled">,
@@ -2017,19 +2077,28 @@
"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_attribute_dll_not_extern : Error<
+ "%q0 must have external linkage when declared %q1">;
def warn_attribute_invalid_on_definition : Warning<
"'%0' attribute cannot be specified on a definition">,
InGroup<IgnoredAttributes>;
+def err_attribute_dll_redeclaration : Error<
+ "redeclaration of %q0 cannot add %q1 attribute">;
+def err_attribute_dllimport_data_definition : Error<
+ "definition of dllimport data">;
def err_attribute_weakref_not_static : Error<
"weakref declaration must have internal linkage">;
def err_attribute_weakref_not_global_context : Error<
- "weakref declaration of '%0' must be in a global context">;
+ "weakref declaration of %0 must be in a global context">;
def err_attribute_weakref_without_alias : Error<
- "weakref declaration of '%0' must also have an alias attribute">;
+ "weakref declaration of %0 must also have an alias attribute">;
def err_alias_not_supported_on_darwin : Error <
"only weak aliases are supported on darwin">;
def err_alias_to_undefined : Error<
"alias must point to a defined variable or function">;
+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 err_duplicate_mangled_name : Error<
"definition with same mangled name as another definition">;
def err_cyclic_alias : Error<
@@ -2042,18 +2111,13 @@
"variables, functions and labels|fields and global variables|structs|"
"variables, functions and tag types|thread-local variables|"
"variables and fields|variables, data members and tag types|"
- "types and namespaces|Objective-C interfaces}1">,
+ "types and namespaces|Objective-C interfaces|methods and properties|"
+ "struct or union|struct, union or class|types|"
+ "Objective-C instance methods|init methods of interface or class extension declarations|"
+ "variables, functions and classes|Objective-C protocols|"
+ "functions and global variables|structs or typedefs}1">,
InGroup<IgnoredAttributes>;
-def err_attribute_wrong_decl_type : Error<
- "%0 attribute only applies to %select{functions|unions|"
- "variables and functions|functions and methods|parameters|"
- "functions, methods and blocks|functions, methods, and classes|"
- "functions, methods, and parameters|classes|variables|methods|"
- "variables, functions and labels|fields and global variables|structs|"
- "variables, functions and tag types|thread-local variables|"
- "variables and fields|variables, data members and tag types|"
- "types and namespaces|Objective-C interfaces|"
- "methods and properties|struct or union|struct, union or class}1">;
+def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
def warn_type_attribute_wrong_type : Warning<
"'%0' only applies to %select{function|pointer|"
"Objective-C object or block pointer}1 types; type here is %2">,
@@ -2093,8 +2157,6 @@
"objc_precise_lifetime is not meaningful for "
"%select{__unsafe_unretained|__autoreleasing}0 objects">;
def err_invalid_pcs : Error<"invalid PCS type">;
-def err_attribute_can_be_applied_only_to_value_decl : Error<
- "%0 attribute can only be applied to value declarations">;
def warn_attribute_not_on_decl : Warning<
"%0 attribute ignored when parsing type">, InGroup<IgnoredAttributes>;
def err_base_specifier_attribute : Error<
@@ -2121,29 +2183,23 @@
"overridden method is here">;
// Thread Safety Attributes
+def warn_invalid_capability_name : Warning<
+ "invalid capability name '%0'; capability name must be 'mutex' or 'role'">,
+ InGroup<ThreadSafetyAttributes>, DefaultIgnore;
def warn_thread_attribute_ignored : Warning<
"ignoring %0 attribute because its argument is invalid">,
InGroup<ThreadSafetyAttributes>, DefaultIgnore;
def warn_thread_attribute_argument_not_lockable : Warning<
"%0 attribute requires arguments whose type is annotated "
- "with 'lockable' attribute; type here is '%1'">,
+ "with 'capability' attribute; type here is %1">,
InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_argument_not_class : Warning<
- "%0 attribute requires arguments that are class type or point to"
- " class type; type here is '%1'">,
- InGroup<ThreadSafetyAttributes>, DefaultIgnore;
def warn_thread_attribute_decl_not_lockable : Warning<
"%0 attribute can only be applied in a context annotated "
- "with 'lockable' attribute">,
+ "with 'capability(\"mutex\")' attribute">,
InGroup<ThreadSafetyAttributes>, DefaultIgnore;
def warn_thread_attribute_decl_not_pointer : Warning<
- "'%0' only applies to pointer types; type here is %1">,
+ "%0 only applies to pointer types; type here is %1">,
InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_wrong_decl_type : Warning<
- "%0 attribute only applies to %select{"
- "fields and global variables|functions and methods|"
- "classes and structs}1">,
- InGroup<ThreadSafetyAttributes>, DefaultIgnore;
def err_attribute_argument_out_of_range : Error<
"%0 attribute parameter %1 is out of bounds: "
"%plural{0:no parameters to index into|"
@@ -2151,41 +2207,43 @@
":must be between 1 and %2}2">;
// Thread Safety Analysis
-def warn_unlock_but_no_lock : Warning<
- "unlocking '%0' that was not locked">,
+def warn_unlock_but_no_lock : Warning<"releasing %0 '%1' that was not held">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_double_lock : Warning<
- "locking '%0' that is already locked">,
+def warn_unlock_kind_mismatch : Warning<
+ "releasing %0 '%1' using %select{shared|exclusive}2 access, expected "
+ "%select{shared|exclusive}3 access">,
+ InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def warn_double_lock : Warning<"acquiring %0 '%1' that is already held">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_no_unlock : Warning<
- "mutex '%0' is still locked at the end of function">,
+ "%0 '%1' is still held at the end of function">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_expecting_locked : Warning<
- "expecting mutex '%0' to be locked at the end of function">,
+ "expecting %0 '%1' to be held at the end of function">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
// FIXME: improve the error message about locks not in scope
def warn_lock_some_predecessors : Warning<
- "mutex '%0' is not locked on every path through here">,
+ "%0 '%1' is not held on every path through here">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_expecting_lock_held_on_loop : Warning<
- "expecting mutex '%0' to be locked at start of each loop">,
+ "expecting %0 '%1' to be held at start of each loop">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def note_locked_here : Note<"mutex acquired here">;
+def note_locked_here : Note<"%0 acquired here">;
def warn_lock_exclusive_and_shared : Warning<
- "mutex '%0' is locked exclusively and shared in the same scope">,
+ "%0 '%1' is acquired exclusively and shared in the same scope">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def note_lock_exclusive_and_shared : Note<
- "the other lock of mutex '%0' is here">;
+ "the other acquisition of %0 '%1' is here">;
def warn_variable_requires_any_lock : Warning<
- "%select{reading|writing}1 variable '%0' requires locking "
+ "%select{reading|writing}1 variable '%0' requires holding "
"%select{any mutex|any mutex exclusively}1">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_var_deref_requires_any_lock : Warning<
- "%select{reading|writing}1 the value pointed to by '%0' requires locking "
+ "%select{reading|writing}1 the value pointed to by '%0' requires holding "
"%select{any mutex|any mutex exclusively}1">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_fun_excludes_mutex : Warning<
- "cannot call function '%0' while mutex '%1' is locked">,
+ "cannot call function '%1' while %0 '%2' is held">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_cannot_resolve_lock : Warning<
"cannot resolve lock expression">,
@@ -2193,28 +2251,26 @@
// Imprecise thread safety warnings
def warn_variable_requires_lock : Warning<
- "%select{reading|writing}2 variable '%0' requires locking "
- "%select{'%1'|'%1' exclusively}2">,
+ "%select{reading|writing}3 variable '%1' requires holding %0 "
+ "%select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_var_deref_requires_lock : Warning<
- "%select{reading|writing}2 the value pointed to by '%0' requires locking "
- "%select{'%1'|'%1' exclusively}2">,
+ "%select{reading|writing}3 the value pointed to by '%1' requires "
+ "holding %0 %select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_fun_requires_lock : Warning<
- "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">,
+ "calling function '%1' requires holding %0 %select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
// Precise thread safety warnings
-def warn_variable_requires_lock_precise : Warning<
- "%select{reading|writing}2 variable '%0' requires locking "
- "%select{'%1'|'%1' exclusively}2">,
+def warn_variable_requires_lock_precise :
+ Warning<warn_variable_requires_lock.Text>,
InGroup<ThreadSafetyPrecise>, DefaultIgnore;
-def warn_var_deref_requires_lock_precise : Warning<
- "%select{reading|writing}2 the value pointed to by '%0' requires locking "
- "%select{'%1'|'%1' exclusively}2">,
+def warn_var_deref_requires_lock_precise :
+ Warning<warn_var_deref_requires_lock.Text>,
InGroup<ThreadSafetyPrecise>, DefaultIgnore;
-def warn_fun_requires_lock_precise : Warning<
- "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">,
+def warn_fun_requires_lock_precise :
+ Warning<warn_fun_requires_lock.Text>,
InGroup<ThreadSafetyPrecise>, DefaultIgnore;
def note_found_mutex_near_match : Note<"found near match '%0'">;
@@ -2299,17 +2355,30 @@
def warn_impcast_floating_point_to_bool : Warning<
"implicit conversion turns floating-point number into bool: %0 to %1">,
InGroup<ImplicitConversionFloatingPointToBool>;
-def warn_impcast_function_to_bool : Warning<
- "address of function %q0 will always evaluate to 'true'">,
- InGroup<BoolConversion>;
-def note_function_to_bool_silence : Note<
+
+def warn_impcast_pointer_to_bool : Warning<
+ "address of%select{| function| array}0 '%1' will always evaluate to "
+ "'true'">,
+ InGroup<PointerBoolConversion>;
+def warn_null_pointer_compare : Warning<
+ "comparison of %select{address of|function|array}0 '%1' %select{not |}2"
+ "equal to a null pointer is always %select{true|false}2">,
+ InGroup<TautologicalPointerCompare>;
+
+def note_function_warning_silence : Note<
"prefix with the address-of operator to silence this warning">;
-def note_function_to_bool_call : Note<
+def note_function_to_function_call : Note<
"suffix with parentheses to turn this into a function call">;
+def warn_impcast_objective_c_literal_to_bool : Warning<
+ "implicit boolean conversion of Objective-C object literal always "
+ "evaluates to true">,
+ InGroup<ObjCLiteralConversion>;
def warn_cast_align : Warning<
"cast from %0 to %1 increases required alignment from %2 to %3">,
InGroup<CastAlign>, DefaultIgnore;
+def warn_old_style_cast : Warning<
+ "use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore;
// Separate between casts to void* and non-void* pointers.
// Some APIs use (abuse) void* for something like a user context,
@@ -2355,17 +2424,26 @@
InGroup<DiagGroup<"unsupported-visibility">>;
def err_mismatched_visibility: Error<"visibility does not match previous declaration">;
def note_previous_attribute : Note<"previous attribute is here">;
-def err_unknown_machine_mode : Error<"unknown machine mode %0">;
-def err_unsupported_machine_mode : Error<"unsupported machine mode %0">;
+def err_mismatched_ms_inheritance : Error<
+ "inheritance model does not match %select{definition|previous declaration}0">;
+def warn_ignored_ms_inheritance : Warning<
+ "inheritance model ignored on %select{primary template|partial specialization}0">,
+ InGroup<IgnoredAttributes>;
+def note_previous_ms_inheritance : Note<
+ "previous inheritance model specified here">;
+def err_machine_mode : Error<"%select{unknown|unsupported}0 machine mode %1">;
def err_mode_not_primitive : Error<
"mode attribute only supported for integer and floating-point types">;
def err_mode_wrong_type : Error<
"type of machine mode does not match type of base type">;
def err_attr_wrong_decl : Error<
- "'%0' attribute invalid on this declaration, requires typedef or value">;
+ "%0 attribute invalid on this declaration, requires typedef or value">;
def warn_attribute_nonnull_no_pointers : Warning<
"'nonnull' attribute applied to function with no pointer arguments">,
InGroup<IgnoredAttributes>;
+def warn_attribute_nonnull_parm_no_args : Warning<
+ "'nonnull' attribute when used on parameters takes no arguments">,
+ InGroup<IgnoredAttributes>;
def warn_attribute_malloc_pointer_only : Warning<
"'malloc' attribute only applies to functions returning a pointer type">,
InGroup<IgnoredAttributes>;
@@ -2394,15 +2472,14 @@
"'regparm' is not valid on this platform">;
def err_attribute_regparm_invalid_number : Error<
"'regparm' parameter must be between 0 and %0 inclusive">;
+def err_attribute_not_supported_in_lang : Error<
+ "%0 attribute is not supported in %select{C|C++|Objective-C}1">;
// Clang-Specific Attributes
def warn_attribute_iboutlet : Warning<
"%0 attribute can only be applied to instance variables or properties">,
InGroup<IgnoredAttributes>;
-def warn_attribute_ibaction: Warning<
- "ibaction attribute can only be applied to Objective-C instance methods">,
- InGroup<IgnoredAttributes>;
def err_iboutletcollection_type : Error<
"invalid type %0 as argument of iboutletcollection attribute">;
def err_iboutletcollection_builtintype : Error<
@@ -2414,8 +2491,6 @@
"IBOutletCollection properties should be copy/strong and not assign">,
InGroup<ObjCInvalidIBOutletProperty>;
-def err_attribute_overloadable_not_function : Error<
- "'overloadable' attribute can only be applied to a function">;
def err_attribute_overloadable_missing : Error<
"%select{overloaded function|redeclaration of}0 %1 must have the "
"'overloadable' attribute">;
@@ -2436,15 +2511,36 @@
InGroup<DiagGroup<"requires-super-attribute">>;
def note_protocol_decl : Note<
"protocol is declared here">;
+def note_protocol_decl_undefined : Note<
+ "protocol %0 has no definition">;
-def err_ns_bridged_not_interface : Error<
- "parameter of 'ns_bridged' attribute does not name an Objective-C class">;
-
+// objc_designated_initializer attribute diagnostics.
+def warn_objc_designated_init_missing_super_call : Warning<
+ "designated initializer missing a 'super' call to a designated initializer of the super class">,
+ InGroup<ObjCDesignatedInit>;
+def note_objc_designated_init_marked_here : Note<
+ "method marked as designated initializer of the class here">;
+def warn_objc_designated_init_non_super_designated_init_call : Warning<
+ "designated initializer should only invoke a designated initializer on 'super'">,
+ InGroup<ObjCDesignatedInit>;
+def warn_objc_designated_init_non_designated_init_call : Warning<
+ "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'">,
+ InGroup<ObjCDesignatedInit>;
+def warn_objc_secondary_init_missing_init_call : Warning<
+ "secondary 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">,
+ InGroup<ObjCDesignatedInit>;
+
// objc_bridge attribute diagnostics.
-def err_objc_bridge_not_id : Error<
- "parameter of 'objc_bridge' attribute must be a single name of an Objective-C class">;
+def err_objc_attr_not_id : Error<
+ "parameter of %0 attribute must be a single name of an Objective-C %select{class|protocol}1">;
def err_objc_cf_bridged_not_interface : Error<
- "CF object of type %0 is bridged to '%1', which is not an Objective-C class">;
+ "CF object of type %0 is bridged to %1, which is not an Objective-C class">;
def err_objc_ns_bridged_invalid_cfobject : Error<
"ObjectiveC object of type %0 is bridged to %1, which is not valid CF object">;
def warn_objc_invalid_bridge : Warning<
@@ -2452,6 +2548,18 @@
def warn_objc_invalid_bridge_to_cf : Warning<
"%0 cannot bridge to %1">, InGroup<ObjCBridge>;
+// objc_bridge_related attribute diagnostics.
+def err_objc_bridged_related_invalid_class : Error<
+ "could not find Objective-C class %0 to convert %1 to %2">;
+def err_objc_bridged_related_invalid_class_name : Error<
+ "%0 must be name of an Objective-C class to be able to convert %1 to %2">;
+def err_objc_bridged_related_known_method : Error<
+ "%0 must be explicitly converted to %1; use %select{%objcclass2|%objcinstance2}3 "
+ "method for this conversion">;
+
+def err_objc_attr_protocol_requires_definition : Error<
+ "attribute %0 can only be applied to @protocol definitions, not forward declarations">;
+
// Function Parameter Semantic Analysis.
def err_param_with_void_type : Error<"argument may not have 'void' type">;
def err_void_only_param : Error<
@@ -2462,8 +2570,6 @@
"a parameter list without types is only allowed in a function definition">;
def ext_param_not_declared : Extension<
"parameter %0 was not declared, defaulting to type 'int'">;
-def err_param_typedef_of_void : Error<
- "empty parameter list defined with a %select{typedef|type alias}0 of 'void' not allowed%select{ in C++|}0">;
def err_param_default_argument : Error<
"C does not support default arguments">;
def err_param_default_argument_redefinition : Error<
@@ -2579,6 +2685,8 @@
"candidate template ignored: substitution failure%0%1">;
def note_ovl_candidate_disabled_by_enable_if : Note<
"candidate template ignored: disabled by %0%1">;
+def note_ovl_candidate_disabled_by_enable_if_attr : Note<
+ "candidate disabled: %0">;
def note_ovl_candidate_failed_overload_resolution : Note<
"candidate template ignored: couldn't resolve reference to overloaded "
"function %0">;
@@ -3164,6 +3272,8 @@
def err_dependent_non_type_arg_in_partial_spec : Error<
"non-type template argument depends on a template parameter of the "
"partial specialization">;
+def note_dependent_non_type_default_arg_in_partial_spec : Note<
+ "template parameter is used in default argument declared here">;
def err_dependent_typed_non_type_arg_in_partial_spec : Error<
"non-type template argument specializes a template parameter with "
"dependent type %0">;
@@ -3173,7 +3283,7 @@
"primary template, remove the template argument list">;
def warn_partial_specs_not_deducible : Warning<
"%select{class|variable}0 template partial specialization contains "
- "%select{a template parameter|template parameters}1 that can not be "
+ "%select{a template parameter|template parameters}1 that cannot be "
"deduced; this partial specialization will never be used">;
def note_partial_spec_unused_parameter : Note<
"non-deducible template parameter %0">;
@@ -3383,11 +3493,11 @@
"add 'typename' to treat this using declaration as a type">;
def err_template_kw_refers_to_non_template : Error<
- "%0 following the 'template' keyword does not refer to a template">;
+ "%0 following the 'template' keyword does not refer to a template">;
def err_template_kw_refers_to_class_template : Error<
- "'%0%1' instantiated to a class template, not a function template">;
+ "'%0%1' instantiated to a class template, not a function template">;
def note_referenced_class_template : Error<
- "class template declared here">;
+ "class template declared here">;
def err_template_kw_missing : Error<
"missing 'template' keyword prior to dependent template name '%0%1'">;
def ext_template_outside_of_template : ExtWarn<
@@ -3397,13 +3507,16 @@
InGroup<CXX98Compat>, DefaultIgnore;
def err_non_type_template_in_nested_name_specifier : Error<
- "qualified name refers into a specialization of function template %0">;
+ "qualified name refers into a specialization of %select{function|variable}0 "
+ "template %1">;
def err_template_id_not_a_type : Error<
"template name refers to non-type template %0">;
def note_template_declared_here : Note<
"%select{function template|class template|variable template"
"|type alias template|template template parameter}0 "
"%1 declared here">;
+def err_alias_template_expansion_into_fixed_list : Error<
+ "pack expansion used as argument for non-pack parameter of alias template">;
def note_parameter_type : Note<
"parameter of type %0 is declared here">;
@@ -3494,7 +3607,7 @@
def warn_deprecated_message : Warning<"%0 is deprecated: %1">,
InGroup<DeprecatedDeclarations>;
def warn_deprecated_fwdclass_message : Warning<
- "%0 maybe deprecated because receiver type is unknown">,
+ "%0 may be deprecated because the receiver type is unknown">,
InGroup<DeprecatedDeclarations>;
def warn_deprecated_def : Warning<
"Implementing deprecated %select{method|class|category}0">,
@@ -3502,9 +3615,10 @@
def err_unavailable : Error<"%0 is unavailable">;
def err_unavailable_message : Error<"%0 is unavailable: %1">;
def warn_unavailable_fwdclass_message : Warning<
- "%0 maybe unavailable because receiver type is unknown">;
-def note_unavailable_here : Note<
- "%select{declaration|function}0 has been explicitly marked "
+ "%0 may be unavailable because the receiver type is unknown">,
+ InGroup<UnavailableDeclarations>;
+def note_availability_specified_here : Note<
+ "%0 has been explicitly marked "
"%select{unavailable|deleted|deprecated}1 here">;
def note_implicitly_deleted : Note<
"explicitly defaulted function was implicitly deleted here">;
@@ -3528,6 +3642,8 @@
def warn_missing_variable_declarations : Warning<
"no previous extern declaration for non-static variable %0">,
InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
+def err_static_data_member_reinitialization :
+ Error<"static data member %0 already has an initializer">;
def err_redefinition : Error<"redefinition of %0">;
def err_alias_after_tentative :
Error<"alias definition of %0 after tentative definition">;
@@ -3544,9 +3660,6 @@
def err_redefinition_extern_inline : Error<
"redefinition of a 'extern inline' function %0 is not supported in "
"%select{C99 mode|C++}1">;
-def warn_cxx98_compat_friend_redefinition : Warning<
- "friend function %0 would be implicitly redefined in C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def note_deleted_dtor_no_operator_delete : Note<
"virtual destructor requires an unambiguous, accessible 'operator delete'">;
@@ -3604,6 +3717,8 @@
def err_redefinition_variably_modified_typedef : Error<
"redefinition of %select{typedef|type alias}0 for variably-modified type %1">;
+def err_inline_decl_follows_def : Error<
+ "inline declaration of %0 follows non-inline definition">;
def err_inline_declaration_block_scope : Error<
"inline declaration of %0 not allowed in block scope">;
def err_static_non_static : Error<
@@ -3689,17 +3804,18 @@
def ext_enum_value_not_int : Extension<
"ISO C restricts enumerator values to range of 'int' (%0 is too "
"%select{small|large}1)">;
-def warn_enum_too_large : Warning<
- "enumeration values exceed range of largest integer">;
-def warn_enumerator_too_large : Warning<
- "enumerator value %0 is not representable in the largest integer type">;
+def ext_enum_too_large : ExtWarn<
+ "enumeration values exceed range of largest integer">, InGroup<EnumTooLarge>;
+def ext_enumerator_increment_too_large : ExtWarn<
+ "incremented enumerator value %0 is not representable in the "
+ "largest integer type">, InGroup<EnumTooLarge>;
def warn_illegal_constant_array_size : Extension<
"size of static array must be an integer constant expression">;
def err_vm_decl_in_file_scope : Error<
"variably modified type declaration not allowed at file scope">;
def err_vm_decl_has_extern_linkage : Error<
- "variably modified type declaration can not have 'extern' linkage">;
+ "variably modified type declaration cannot have 'extern' linkage">;
def err_typecheck_field_variable_size : Error<
"fields must have a constant size: 'variable length array in structure' "
"extension will never be supported">;
@@ -3732,6 +3848,9 @@
InGroup<BadArrayNewLength>;
def warn_typecheck_function_qualifiers : Warning<
"qualifier on function type %0 has unspecified behavior">;
+def warn_typecheck_reference_qualifiers : Warning<
+ "'%0' qualifier on reference type %1 has no effect">,
+ InGroup<IgnoredQualifiers>;
def err_typecheck_invalid_restrict_not_pointer : Error<
"restrict requires a pointer or reference (%0 is invalid)">;
def err_typecheck_invalid_restrict_not_pointer_noarg : Error<
@@ -3771,11 +3890,11 @@
def warn_initializer_string_for_char_array_too_long : ExtWarn<
"initializer-string for char array is too long">;
def warn_missing_field_initializers : Warning<
- "missing field '%0' initializer">,
+ "missing field %0 initializer">,
InGroup<MissingFieldInitializers>, DefaultIgnore;
def warn_braces_around_scalar_init : Warning<
"braces around scalar initializer">;
-def warn_many_braces_around_scalar_init : ExtWarn<
+def ext_many_braces_around_scalar_init : ExtWarn<
"too many braces around scalar initializer">;
def ext_complex_component_init : Extension<
"complex initialization specifying real and imaginary components "
@@ -3913,6 +4032,9 @@
"jump exits scope of variable with __attribute__((cleanup))">;
def note_exits_dtor : Note<
"jump exits scope of variable with non-trivial destructor">;
+def note_exits_temporary_dtor : Note<
+ "jump exits scope of lifetime-extended temporary with non-trivial "
+ "destructor">;
def note_exits___block : Note<
"jump exits scope of __block variable">;
def note_exits_objc_try : Note<
@@ -3954,8 +4076,8 @@
def err_flexible_array_empty_aggregate : Error<
"flexible array member %0 not allowed in otherwise empty "
"%select{struct|interface|union|class|enum}1">;
-def err_flexible_array_has_nonpod_type : Error<
- "flexible array member %0 of non-POD element type %1">;
+def err_flexible_array_has_nontrivial_dtor : Error<
+ "flexible array member %0 of type %1 with non-trivial destruction">;
def ext_flexible_array_in_struct : Extension<
"%0 may not be nested in a struct due to flexible array member">,
InGroup<FlexibleArrayExtensions>;
@@ -4224,6 +4346,8 @@
def ext_sizeof_alignof_void_type : Extension<
"invalid application of '%select{sizeof|alignof|vec_step}0' to a void "
"type">, InGroup<PointerArith>;
+def err_opencl_sizeof_alignof_type : Error<
+ "invalid application of '%select{sizeof|alignof|vec_step}0' to a void type">;
def err_sizeof_alignof_incomplete_type : Error<
"invalid application of '%select{sizeof|alignof|vec_step}0' to an "
"incomplete type %1">;
@@ -4439,6 +4563,9 @@
"extra qualification on member %0">, InGroup<Microsoft>;
def err_member_extra_qualification : Error<
"extra qualification on member %0">;
+def warn_namespace_member_extra_qualification : Warning<
+ "extra qualification on member %0">,
+ InGroup<DiagGroup<"extra-qualification">>;
def err_member_qualification : Error<
"non-friend class member %0 cannot have a qualified name">;
def note_member_def_close_match : Note<"member declaration nearly matches">;
@@ -4505,8 +4632,9 @@
def warn_deprecated_string_literal_conversion : Warning<
"conversion from string literal to %0 is deprecated">,
InGroup<CXX11CompatDeprecatedWritableStr>;
-def warn_deprecated_string_literal_conversion_c : Warning<
- "dummy warning to enable -fconst-strings">, InGroup<DeprecatedWritableStr>, DefaultIgnore;
+def ext_deprecated_string_literal_conversion : ExtWarn<
+ "ISO C++11 does not allow conversion from string literal to %0">,
+ InGroup<CXX11CompatDeprecatedWritableStr>, 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">;
@@ -4812,7 +4940,7 @@
def err_qualified_objc_catch_parm : Error<
"@catch parameter declarator cannot be qualified">;
def warn_objc_pointer_cxx_catch_fragile : Warning<
- "can not catch an exception thrown with @throw in C++ in the non-unified "
+ "cannot catch an exception thrown with @throw in C++ in the non-unified "
"exception model">, InGroup<ObjCNonUnifiedException>;
def err_objc_object_catch : Error<
"can't catch an Objective-C object by value">;
@@ -5013,7 +5141,7 @@
"exception declarator cannot be qualified">;
def err_early_catch_all : Error<"catch-all handler must come last">;
def err_bad_memptr_rhs : Error<
- "right hand operand to %0 has non pointer-to-member type %1">;
+ "right hand operand to %0 has non-pointer-to-member type %1">;
def err_bad_memptr_lhs : Error<
"left hand operand to %0 must be a %select{|pointer to }1class "
"compatible with the right hand operand, but is %2">;
@@ -5139,6 +5267,9 @@
"initializer missing for lambda capture %0">;
def err_init_capture_multiple_expressions : Error<
"initializer for lambda capture %0 contains multiple expressions">;
+ def err_init_capture_paren_braces : Error<
+ "cannot deduce type for lambda capture %0 from "
+ "parenthesized initializer list">;
def err_init_capture_deduction_failure : Error<
"cannot deduce type for lambda capture %0 from initializer of type %2">;
def err_init_capture_deduction_failure_from_init_list : Error<
@@ -5199,9 +5330,10 @@
"conversion function %diff{from $ to $|between types}0,1 "
"invokes a deleted function">;
-def err_expected_class_or_namespace : Error<"expected a class or namespace">;
-def err_expected_class : Error<"%0 is not a class%select{ or namespace|, "
- "namespace, or scoped enumeration}1">;
+def err_expected_class_or_namespace : Error<"%0 is not a class"
+ "%select{ or namespace|, namespace, or scoped enumeration}1">;
+def note_expected_class_or_namespace_declared_here : Note<
+ "%0 declared here">;
def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here "
"because namespace %1 does not enclose namespace %2">;
def err_invalid_declarator_global_scope : Error<
@@ -5590,7 +5722,10 @@
def err_atomic_op_bitwise_needs_atomic_int : Error<
"address argument to bitwise atomic operation must be a pointer to "
"%select{|atomic }0integer (%1 invalid)">;
-
+def warn_atomic_op_has_invalid_memory_order : Warning<
+ "memory order argument to atomic operation is invalid">,
+ InGroup<DiagGroup<"atomic-memory-ordering">>;
+
def err_atomic_load_store_uses_lib : Error<
"atomic %select{load|store}0 requires runtime support that is not "
"available for this target">;
@@ -5630,6 +5765,11 @@
"passing object of trivial but non-POD type %0 through variadic"
" %select{function|block|method|constructor}1 is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def warn_pass_class_arg_to_vararg : Warning<
+ "passing object of class type %0 through variadic "
+ "%select{function|block|method|constructor}1"
+ "%select{|; did you mean to call '%3'?}2">,
+ InGroup<ClassVarargs>, DefaultIgnore;
def err_cannot_pass_to_vararg : Error<
"cannot pass %select{expression of type %1|initializer list}0 to variadic "
"%select{function|block|method|constructor}2">;
@@ -5709,20 +5849,16 @@
InGroup<DiagGroup<"unused-volatile-lvalue">>;
def warn_unused_comparison : Warning<
- "%select{equality|inequality}0 comparison result unused">,
+ "%select{%select{|in}1equality|relational}0 comparison result unused">,
InGroup<UnusedComparison>;
def note_inequality_comparison_to_or_assign : Note<
"use '|=' to turn this inequality comparison into an or-assignment">;
def err_incomplete_type_used_in_type_trait_expr : Error<
"incomplete type %0 used in type trait expression">;
-def err_type_trait_arity : Error<
- "type trait requires %0%select{| or more}1 argument%select{|s}2; have "
- "%3 argument%s3">;
def err_dimension_expr_not_constant_integer : Error<
"dimension expression does not evaluate to a constant unsigned int">;
-def err_expected_ident_or_lparen : Error<"expected identifier or '('">;
def err_typecheck_cond_incompatible_operands_null : Error<
"non-pointer operand type %0 incompatible with %select{NULL|nullptr}1">;
@@ -5782,6 +5918,12 @@
"invalid conversion between vector type %0 and integer type %1 "
"of different size">;
+def err_opencl_function_pointer_variable : Error<
+ "pointers to functions are not allowed">;
+
+def err_opencl_taking_function_address : Error<
+ "taking address of function is not allowed">;
+
def err_invalid_conversion_between_vector_and_scalar : Error<
"invalid conversion between vector type %0 and scalar type %1">;
@@ -5974,6 +6116,9 @@
"%0 must have at least one parameter">;
def err_operator_new_delete_template_too_few_parameters : Error<
"%0 template must have at least two parameters">;
+def warn_operator_new_returns_null : Warning<
+ "%0 should not return a null pointer unless it is declared 'throw()'"
+ "%select{| or 'noexcept'}1">, InGroup<OperatorNewReturnsNull>;
def err_operator_new_dependent_param_type : Error<
"%0 cannot take a dependent type as first parameter; "
@@ -5990,6 +6135,8 @@
// C++ literal operators
def err_literal_operator_outside_namespace : Error<
"literal operator %0 must be in a namespace or global scope">;
+def err_literal_operator_id_outside_namespace : Error<
+ "non-namespace scope '%0' cannot have a literal operator member">;
def err_literal_operator_default_argument : Error<
"literal operator cannot have a default argument">;
// FIXME: This diagnostic sucks
@@ -6150,6 +6297,8 @@
"format string should not be a wide string">, InGroup<Format>;
def warn_printf_format_string_contains_null_char : Warning<
"format string contains '\\0' within the string body">, InGroup<Format>;
+def warn_printf_format_string_not_null_terminated : Warning<
+ "format string is not null-terminated">, InGroup<Format>;
def warn_printf_asterisk_missing_arg : Warning<
"'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">,
InGroup<Format>;
@@ -6186,6 +6335,9 @@
def warn_null_arg : Warning<
"null passed to a callee which requires a non-null argument">,
InGroup<NonNull>;
+def warn_null_ret : Warning<
+ "null returned from %select{function|method}0 that requires a non-null return value">,
+ InGroup<NonNull>;
// CHECK: returning address/reference of stack memory
def warn_ret_stack_addr : Warning<
@@ -6234,7 +6386,7 @@
def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
"unspecified (use strncmp instead)">,
- InGroup<DiagGroup<"string-compare">>;
+ InGroup<StringCompare>;
def warn_identity_field_assign : Warning<
"assigning %select{field|instance variable}0 to itself">,
@@ -6252,7 +6404,7 @@
"this type tag was not designed to be used with this function">,
InGroup<TypeSafety>;
def warn_type_safety_type_mismatch : Warning<
- "argument type %0 doesn't match specified '%1' type tag "
+ "argument type %0 doesn't match specified %1 type tag "
"%select{that requires %3|}2">, InGroup<TypeSafety>;
def warn_type_safety_null_pointer_required : Warning<
"specified %0 type tag requires a null pointer">, InGroup<TypeSafety>;
@@ -6299,11 +6451,17 @@
"'continue' statement not in loop statement">;
def err_break_not_in_loop_or_switch : Error<
"'break' statement not in loop or switch statement">;
+def warn_loop_ctrl_binds_to_inner : Warning<
+ "'%0' is bound to current loop, GCC binds it to the enclosing loop">,
+ InGroup<GccCompat>;
+def warn_break_binds_to_switch : Warning<
+ "'break' is bound to loop, GCC binds it to switch">,
+ InGroup<GccCompat>;
def err_default_not_in_switch : Error<
"'default' statement not in switch statement">;
def err_case_not_in_switch : Error<"'case' statement not in switch statement">;
def warn_bool_switch_condition : Warning<
- "switch condition has boolean value">;
+ "switch condition has boolean value">, InGroup<SwitchBool>;
def warn_case_value_overflow : Warning<
"overflow converting case value to switch condition type (%0 to %1)">,
InGroup<Switch>;
@@ -6434,6 +6592,8 @@
def err_return_init_list : Error<
"%select{void function|void method|constructor|destructor}1 %0 "
"must not return a value">;
+def err_ctor_dtor_returns_void : Error<
+ "%select{constructor|destructor}1 %0 must not return void expression">;
def warn_noreturn_function_has_return_expr : Warning<
"function %0 declared 'noreturn' should not return">,
InGroup<InvalidNoreturn>;
@@ -6572,9 +6732,6 @@
def error_protected_ivar_access : Error<"instance variable %0 is protected">,
AccessControl;
def warn_maynot_respond : Warning<"%0 may not respond to %1">;
-def warn_attribute_method_def : Warning<
- "attributes on method implementation and its declaration must match">,
- InGroup<DiagGroup<"mismatched-method-attributes">>;
def ext_typecheck_base_super : Warning<
"method parameter type "
"%diff{$ does not match super class method parameter type $|"
@@ -6667,6 +6824,8 @@
"kernel functions cannot be declared static">;
def err_opencl_ptrptr_kernel_param : Error<
"kernel parameter cannot be declared as a pointer to a pointer">;
+def err_opencl_private_ptr_kernel_param : Error<
+ "kernel parameter cannot be declared as a pointer to the __private address space">;
def err_static_function_scope : Error<
"variables in function scope cannot be declared static">;
def err_opencl_bitfields : Error<
@@ -6696,6 +6855,12 @@
def err_opencl_global_invalid_addr_space : Error<
"global variables must have a constant address space qualifier">;
def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">;
+def err_opencl_kernel_attr :
+ Error<"attribute %0 can only be applied to a kernel function">;
+def err_opencl_return_value_with_address_space : Error<
+ "return value cannot be qualified with address space">;
+def err_opencl_constant_no_init : Error<
+ "variable in constant address space must be initialized">;
} // end of sema category
let CategoryName = "OpenMP Issue" in {
@@ -6719,24 +6884,42 @@
"a private variable with incomplete type %0">;
def err_omp_firstprivate_incomplete_type : Error<
"a firstprivate variable with incomplete type %0">;
-def err_omp_unexpected_clause_value : Error <
+def err_omp_unexpected_clause_value : Error<
"expected %0 in OpenMP clause '%1'">;
-def err_omp_expected_var_name : Error <
+def err_omp_expected_var_name : Error<
"expected variable name">;
-def err_omp_required_method : Error <
+def err_omp_required_method : Error<
"%0 variable must have an accessible, unambiguous %select{default constructor|copy constructor|copy assignment operator|'%2'|destructor}1">;
def err_omp_clause_ref_type_arg : Error<
"arguments of OpenMP clause '%0' cannot be of reference type %1">;
def err_omp_threadprivate_incomplete_type : Error<
"threadprivate variable with incomplete type %0">;
-def err_omp_no_dsa_for_variable : Error <
+def err_omp_no_dsa_for_variable : Error<
"variable %0 must have explicitly specified data sharing attributes">;
def err_omp_wrong_dsa : Error<
"%0 variable cannot be %1">;
-def note_omp_explicit_dsa : Note <
+def note_omp_explicit_dsa : Note<
"defined as %0">;
-def note_omp_predetermined_dsa : Note <
+def note_omp_predetermined_dsa : Note<
"predetermined as %0">;
+def err_omp_not_for : Error<
+ "statement after '#pragma omp %0' must be a for loop">;
+def err_omp_negative_expression_in_clause : Error<
+ "argument to '%0' clause must be a positive integer value">;
+def err_omp_not_integral : Error<
+ "expression must have integral or unscoped enumeration "
+ "type, not %0">;
+def err_omp_incomplete_type : Error<
+ "expression has incomplete class type %0">;
+def err_omp_explicit_conversion : Error<
+ "expression requires explicit conversion from %0 to %1">;
+def note_omp_conversion_here : Note<
+ "conversion to %select{integral|enumeration}0 type %1 declared here">;
+def err_omp_ambiguous_conversion : Error<
+ "ambiguous conversion from type %0 to an integral or unscoped "
+ "enumeration type">;
+def err_omp_required_access : Error<
+ "%0 variable must be %1">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -6778,6 +6961,14 @@
"declaration of %0 must be imported from module '%1' before it is required">;
def err_module_private_definition : Error<
"definition of %0 must be imported from module '%1' before it is required">;
+def err_module_import_in_extern_c : Error<
+ "import of C++ module '%0' appears within extern \"C\" language linkage "
+ "specification">;
+def note_module_import_in_extern_c : Note<
+ "extern \"C\" language linkage specification begins here">;
+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">;
}
let CategoryName = "Documentation Issue" in {
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 81509cc..57ba0a4 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
let Component = "Serialization" in {
+let CategoryName = "AST Deserialization Issue" in {
def err_fe_unable_to_read_pch_file : Error<
"unable to read PCH file %0: '%1'">;
@@ -22,6 +23,8 @@
DefaultFatal;
def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
+def note_pch_required_by : Note<"'%0' required by '%1'">;
+def note_pch_rebuild_required : Note<"please rebuild precompiled header '%0'">;
def note_module_cache_path : Note<
"after modifying system headers, please delete the module cache at '%0'">;
@@ -37,11 +40,11 @@
def err_pch_langopt_value_mismatch : Error<
"%0 differs in PCH file vs. current file">;
-def warn_pch_version_too_old : Error<
+def err_pch_version_too_old : Error<
"PCH file uses an older PCH format that is no longer supported">;
-def warn_pch_version_too_new : Error<
+def err_pch_version_too_new : Error<
"PCH file uses a newer PCH format that cannot be read">;
-def warn_pch_different_branch : Error<
+def err_pch_different_branch : Error<
"PCH file built from a different branch (%0) than the compiler (%1)">;
def err_pch_with_compiler_errors : Error<
"PCH file contains compiler errors">;
@@ -76,4 +79,6 @@
def note_module_odr_violation_possible_decl : Note<
"declaration of %0 does not match">;
-}
+} // let CategoryName
+} // let Component
+
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index 255eee3..cc9e4e4 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -17,16 +17,17 @@
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/VirtualFileSystem.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/FileSystem.h"
+#include <memory>
// FIXME: Enhance libsystem to support inode and other fields in stat.
#include <sys/types.h>
+#include <map>
#ifdef _MSC_VER
typedef unsigned short mode_t;
@@ -55,10 +56,10 @@
/// \brief Cached information about one file (either on disk
/// or in the virtual file system).
///
-/// If the 'FD' member is valid, then this FileEntry has an open file
+/// If the 'File' member is valid, then this FileEntry has an open file
/// descriptor for the file.
class FileEntry {
- const char *Name; // Name of the file.
+ std::string Name; // Name of the file.
off_t Size; // File size in bytes.
time_t ModTime; // Modification time of file.
const DirectoryEntry *Dir; // Directory file lives in.
@@ -66,33 +67,34 @@
llvm::sys::fs::UniqueID UniqueID;
bool IsNamedPipe;
bool InPCH;
+ bool IsValid; // Is this \c FileEntry initialized and valid?
- /// FD - The file descriptor for the file entry if it is opened and owned
- /// by the FileEntry. If not, this is set to -1.
- mutable int FD;
+ /// \brief The open file, if it is owned by the \p FileEntry.
+ mutable std::unique_ptr<vfs::File> File;
friend class FileManager;
+ void closeFile() const {
+ File.reset(0); // rely on destructor to close File
+ }
+
+ void operator=(const FileEntry &) LLVM_DELETED_FUNCTION;
+
public:
- FileEntry(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe, bool InPCH)
- : Name(0), UniqueID(UniqueID), IsNamedPipe(IsNamedPipe), InPCH(InPCH),
- FD(-1) {}
- // Add a default constructor for use with llvm::StringMap
FileEntry()
- : Name(0), UniqueID(0, 0), IsNamedPipe(false), InPCH(false), FD(-1) {}
+ : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
+ {}
- FileEntry(const FileEntry &FE) {
- memcpy(this, &FE, sizeof(FE));
- assert(FD == -1 && "Cannot copy a file-owning FileEntry");
+ // FIXME: this is here to allow putting FileEntry in std::map. Once we have
+ // emplace, we shouldn't need a copy constructor anymore.
+ /// Intentionally does not copy fields that are not set in an uninitialized
+ /// \c FileEntry.
+ FileEntry(const FileEntry &FE) : UniqueID(FE.UniqueID),
+ IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid) {
+ assert(!isValid() && "Cannot copy an initialized FileEntry");
}
- void operator=(const FileEntry &FE) {
- memcpy(this, &FE, sizeof(FE));
- assert(FD == -1 && "Cannot assign a file-owning FileEntry");
- }
-
- ~FileEntry();
-
- const char *getName() const { return Name; }
+ const char *getName() const { return Name.c_str(); }
+ bool isValid() const { return IsValid; }
off_t getSize() const { return Size; }
unsigned getUID() const { return UID; }
const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
@@ -119,16 +121,14 @@
/// as a single file.
///
class FileManager : public RefCountedBase<FileManager> {
+ IntrusiveRefCntPtr<vfs::FileSystem> FS;
FileSystemOptions FileSystemOpts;
- class UniqueDirContainer;
- class UniqueFileContainer;
-
/// \brief Cache for existing real directories.
- UniqueDirContainer &UniqueRealDirs;
+ std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueRealDirs;
/// \brief Cache for existing real files.
- UniqueFileContainer &UniqueRealFiles;
+ std::map<llvm::sys::fs::UniqueID, FileEntry> UniqueRealFiles;
/// \brief The virtual directories that we have allocated.
///
@@ -169,17 +169,18 @@
unsigned NumDirCacheMisses, NumFileCacheMisses;
// Caching.
- OwningPtr<FileSystemStatCache> StatCache;
+ std::unique_ptr<FileSystemStatCache> StatCache;
bool getStatValue(const char *Path, FileData &Data, bool isFile,
- int *FileDescriptor);
+ vfs::File **F);
/// Add all ancestors of the given path (pointing to either a file
/// or a directory) as virtual directories.
void addAncestorsAsVirtualDirs(StringRef Path);
public:
- FileManager(const FileSystemOptions &FileSystemOpts);
+ FileManager(const FileSystemOptions &FileSystemOpts,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS = 0);
~FileManager();
/// \brief Installs the provided FileSystemStatCache object within
@@ -226,6 +227,10 @@
/// \brief Returns the current file system options
const FileSystemOptions &getFileSystemOptions() { return FileSystemOpts; }
+ IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystem() const {
+ return FS;
+ }
+
/// \brief Retrieve a file entry for a "virtual" file that acts as
/// if there were a file with the given name on disk.
///
@@ -245,8 +250,10 @@
///
/// If the path is relative, it will be resolved against the WorkingDir of the
/// FileManager's FileSystemOptions.
+ ///
+ /// \returns false on success, true on error.
bool getNoncachedStatValue(StringRef Path,
- llvm::sys::fs::file_status &Result);
+ vfs::Status &Result);
/// \brief Remove the real file \p Entry from the cache.
void invalidateCache(const FileEntry *Entry);
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index 23d8256..c4a89b3 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -16,15 +16,22 @@
#define LLVM_CLANG_FILESYSTEMSTATCACHE_H
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/FileSystem.h"
+#include <memory>
#include <sys/stat.h>
#include <sys/types.h>
namespace clang {
+namespace vfs {
+class File;
+class FileSystem;
+}
+
+// FIXME: should probably replace this with vfs::Status
struct FileData {
+ std::string Name;
uint64_t Size;
time_t ModTime;
llvm::sys::fs::UniqueID UniqueID;
@@ -39,8 +46,8 @@
class FileSystemStatCache {
virtual void anchor();
protected:
- OwningPtr<FileSystemStatCache> NextStatCache;
-
+ std::unique_ptr<FileSystemStatCache> NextStatCache;
+
public:
virtual ~FileSystemStatCache() {}
@@ -57,10 +64,11 @@
/// If isFile is true, then this lookup should only return success for files
/// (not directories). If it is false this lookup should only return
/// success for directories (not files). On a successful file lookup, the
- /// implementation can optionally fill in FileDescriptor with a valid
- /// descriptor and the client guarantees that it will close it.
+ /// implementation can optionally fill in \p F with a valid \p File object and
+ /// the client guarantees that it will close it.
static bool get(const char *Path, FileData &Data, bool isFile,
- int *FileDescriptor, FileSystemStatCache *Cache);
+ vfs::File **F, FileSystemStatCache *Cache,
+ vfs::FileSystem &FS);
/// \brief Sets the next stat call cache in the chain of stat caches.
/// Takes ownership of the given stat cache.
@@ -74,21 +82,20 @@
/// \brief Retrieve the next stat call cache in the chain, transferring
/// ownership of this cache (and, transitively, all of the remaining caches)
/// to the caller.
- FileSystemStatCache *takeNextStatCache() { return NextStatCache.take(); }
-
+ FileSystemStatCache *takeNextStatCache() { return NextStatCache.release(); }
+
protected:
virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
- int *FileDescriptor) = 0;
+ vfs::File **F, vfs::FileSystem &FS) = 0;
LookupResult statChained(const char *Path, FileData &Data, bool isFile,
- int *FileDescriptor) {
+ vfs::File **F, vfs::FileSystem &FS) {
if (FileSystemStatCache *Next = getNextStatCache())
- return Next->getStat(Path, Data, isFile, FileDescriptor);
+ return Next->getStat(Path, Data, isFile, F, FS);
// 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, FileDescriptor, 0) ? CacheMissing
- : CacheExists;
+ return get(Path, Data, isFile, F, 0, FS) ? CacheMissing : CacheExists;
}
};
@@ -106,8 +113,8 @@
iterator begin() const { return StatCalls.begin(); }
iterator end() const { return StatCalls.end(); }
- virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
- int *FileDescriptor);
+ LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+ vfs::File **F, vfs::FileSystem &FS) override;
};
} // end namespace clang
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 304ff36..abf5b93 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -697,9 +697,11 @@
/// \brief Derive the full selector name (e.g. "foo:bar:") and return
/// it as an std::string.
- // FIXME: Add a print method that uses a raw_ostream.
std::string getAsString() const;
+ /// \brief Prints the full selector name (e.g. "foo:bar:").
+ void print(llvm::raw_ostream &OS) const;
+
/// \brief Derive the conventional family of this method.
ObjCMethodFamily getMethodFamily() const {
return getMethodFamilyImpl(*this);
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index 306c75e..01898f4 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -29,7 +29,6 @@
class StringRef;
class Twine;
template<typename T> class ArrayRef;
- template<typename T> class OwningPtr;
template<unsigned InternalLen> class SmallString;
template<typename T, unsigned N> class SmallVector;
template<typename T> class SmallVectorImpl;
@@ -63,7 +62,6 @@
using llvm::StringRef;
using llvm::Twine;
using llvm::ArrayRef;
- using llvm::OwningPtr;
using llvm::SmallString;
using llvm::SmallVector;
using llvm::SmallVectorImpl;
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index c6a2c78..7b21482 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -43,12 +43,12 @@
LANGOPT(C99 , 1, 0, "C99")
LANGOPT(C11 , 1, 0, "C11")
-LANGOPT(MicrosoftExt , 1, 0, "Microsoft extensions")
-LANGOPT(MicrosoftMode , 1, 0, "Microsoft compatibility mode")
+LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
+LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions")
LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
LANGOPT(Borland , 1, 0, "Borland extensions")
LANGOPT(CPlusPlus , 1, 0, "C++")
-LANGOPT(CPlusPlus11 , 1, 0, "C++0x")
+LANGOPT(CPlusPlus11 , 1, 0, "C++11")
LANGOPT(CPlusPlus1y , 1, 0, "C++1y")
LANGOPT(ObjC1 , 1, 0, "Objective-C 1")
LANGOPT(ObjC2 , 1, 0, "Objective-C 2")
@@ -61,6 +61,7 @@
LANGOPT(Trigraphs , 1, 0,"trigraphs")
LANGOPT(LineComment , 1, 0, "'//' comments")
LANGOPT(Bool , 1, 0, "bool, true, and false keywords")
+LANGOPT(Half , 1, 0, "half keyword")
LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword")
BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers")
BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
@@ -113,6 +114,7 @@
BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control")
LANGOPT(CharIsSigned , 1, 1, "signed char")
LANGOPT(ShortWChar , 1, 0, "unsigned short wchar_t")
+ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method")
LANGOPT(ShortEnums , 1, 0, "short enum types")
@@ -121,7 +123,7 @@
LANGOPT(NativeHalfType , 1, 0, "Native half type support")
LANGOPT(CUDA , 1, 0, "CUDA")
LANGOPT(OpenMP , 1, 0, "OpenMP support")
-LANGOPT(Renderscript , 1, 0, "Renderscript")
+LANGOPT(Renderscript , 1, 0, "RenderScript")
LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators")
LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions")
@@ -176,10 +178,11 @@
"if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
VALUE_LANGOPT(MSCVersion, 32, 0,
"version of Microsoft Visual C/C++")
+VALUE_LANGOPT(VtorDispMode, 2, 1, "How many vtordisps to insert")
LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
-BENIGN_LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
#undef LANGOPT
#undef VALUE_LANGOPT
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index d4e8b4e..e969161 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -58,7 +58,7 @@
typedef clang::Visibility Visibility;
enum GCMode { NonGC, GCOnly, HybridGC };
- enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
+ enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
enum SignedOverflowBehaviorTy {
SOB_Undefined, // Default C standard behavior.
@@ -66,6 +66,13 @@
SOB_Trapping // -ftrapv
};
+ enum PragmaMSPointersToMembersKind {
+ PPTMK_BestCase,
+ PPTMK_FullGeneralitySingleInheritance,
+ PPTMK_FullGeneralityMultipleInheritance,
+ PPTMK_FullGeneralityVirtualInheritance
+ };
+
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
public:
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
index 6996207..247c6e7 100644
--- a/include/clang/Basic/Linkage.h
+++ b/include/clang/Basic/Linkage.h
@@ -63,7 +63,7 @@
GVA_CXXInline,
GVA_StrongExternal,
GVA_TemplateInstantiation,
- GVA_ExplicitTemplateInstantiation
+ GVA_StrongODR
};
inline bool isExternallyVisible(Linkage L) {
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
index 6a33133..5579a99 100644
--- a/include/clang/Basic/Makefile
+++ b/include/clang/Basic/Makefile
@@ -6,6 +6,7 @@
DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
DiagnosticSerializationKinds.inc \
+ AttrHasAttributeImpl.inc \
DiagnosticIndexName.inc DiagnosticGroups.inc AttrList.inc arm_neon.inc \
Version.inc
@@ -48,9 +49,16 @@
$(Verb) $(ClangTableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../.. $<
+$(ObjDir)/AttrHasAttributeImpl.inc.tmp : Attr.td $(CLANG_TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang __has_attribute implementation with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-attr-has-attribute-impl -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
+
$(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(CLANG_TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang arm_neon.inc with tblgen"
- $(Verb) $(ClangTableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) $<
+ $(Verb) $(ClangTableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../.. $<
$(ObjDir)/Version.inc.tmp : Version.inc.in Makefile $(LLVM_OBJ_ROOT)/Makefile.config $(ObjDir)/.dir
$(Echo) "Updating Clang version info."
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index e8d774e..1f7f71d 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -88,7 +88,19 @@
SmallVector<const FileEntry *, 2> ExcludedHeaders;
/// \brief The headers that are private to this module.
- llvm::SmallVector<const FileEntry *, 2> PrivateHeaders;
+ SmallVector<const FileEntry *, 2> PrivateHeaders;
+
+ /// \brief Information about a header directive as found in the module map
+ /// file.
+ struct HeaderDirective {
+ SourceLocation FileNameLoc;
+ std::string FileName;
+ bool IsUmbrella;
+ };
+
+ /// \brief Headers that are mentioned in the module map file but could not be
+ /// found on the file system.
+ SmallVector<HeaderDirective, 1> MissingHeaders;
/// \brief An individual requirement: a feature name and a flag indicating
/// the required state of that feature.
@@ -116,7 +128,12 @@
/// \brief Whether this is a "system" module (which assumes that all
/// headers in it are system headers).
unsigned IsSystem : 1;
-
+
+ /// \brief Whether this is an 'extern "C"' module (which implicitly puts all
+ /// headers in it within an 'extern "C"' block, and allows the module to be
+ /// imported within such a block).
+ unsigned IsExternC : 1;
+
/// \brief Whether we should infer submodules for this module based on
/// the headers.
///
@@ -148,11 +165,14 @@
MacrosVisible,
/// \brief All of the names in this module are visible.
AllVisible
- };
-
- ///\ brief The visibility of names within this particular module.
+ };
+
+ /// \brief The visibility of names within this particular module.
NameVisibilityKind NameVisibility;
+ /// \brief The location at which macros within this module became visible.
+ SourceLocation MacroVisibilityLoc;
+
/// \brief The location of the inferred submodule.
SourceLocation InferredSubmoduleLoc;
@@ -243,16 +263,6 @@
/// \brief The list of conflicts.
std::vector<Conflict> Conflicts;
- /// \brief Construct a top-level module.
- explicit Module(StringRef Name, SourceLocation DefinitionLoc,
- bool IsFramework)
- : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0),Umbrella(),ASTFile(0),
- IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
- IsExplicit(false), IsSystem(false),
- InferSubmodules(false), InferExplicitSubmodules(false),
- InferExportWildcard(false), ConfigMacrosExhaustive(false),
- NameVisibility(Hidden) { }
-
/// \brief Construct a new module or submodule.
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
bool IsFramework, bool IsExplicit);
@@ -276,7 +286,8 @@
/// this module.
bool isAvailable(const LangOptions &LangOpts,
const TargetInfo &Target,
- Requirement &Req) const;
+ Requirement &Req,
+ HeaderDirective &MissingHeader) const;
/// \brief Determine whether this module is a submodule.
bool isSubModule() const { return Parent != 0; }
@@ -330,7 +341,8 @@
/// \brief Set the serialized AST file for the top-level module of this module.
void setASTFile(const FileEntry *File) {
- assert((getASTFile() == 0 || getASTFile() == File) && "file path changed");
+ assert((File == 0 || getASTFile() == 0 || getASTFile() == File) &&
+ "file path changed");
getTopLevelModule()->ASTFile = File;
}
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index 4c64497..fa375f4 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -99,6 +99,11 @@
Arch == llvm::Triple::x86_64)
return false;
}
+ else if ((getKind() == MacOSX) && isNonFragile() &&
+ (getVersion() >= VersionTuple(10, 0)) &&
+ (getVersion() < VersionTuple(10, 6)))
+ return Arch != llvm::Triple::x86_64;
+ // Except for deployment target of 10.5 or less,
// Mac runtimes use legacy dispatch everywhere now.
return true;
}
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index ee30123..8c2cd8d 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -17,6 +17,7 @@
#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"
@@ -29,84 +30,11 @@
typedef uint32_t Offset;
-inline void Emit8(raw_ostream& Out, uint32_t V) {
- Out << (unsigned char)(V);
-}
-
-inline void Emit16(raw_ostream& Out, uint32_t V) {
- Out << (unsigned char)(V);
- Out << (unsigned char)(V >> 8);
- assert((V >> 16) == 0);
-}
-
-inline void Emit24(raw_ostream& Out, uint32_t V) {
- Out << (unsigned char)(V);
- Out << (unsigned char)(V >> 8);
- Out << (unsigned char)(V >> 16);
- assert((V >> 24) == 0);
-}
-
-inline void Emit32(raw_ostream& Out, uint32_t V) {
- Out << (unsigned char)(V);
- Out << (unsigned char)(V >> 8);
- Out << (unsigned char)(V >> 16);
- Out << (unsigned char)(V >> 24);
-}
-
-inline void Emit64(raw_ostream& Out, uint64_t V) {
- Out << (unsigned char)(V);
- Out << (unsigned char)(V >> 8);
- Out << (unsigned char)(V >> 16);
- Out << (unsigned char)(V >> 24);
- Out << (unsigned char)(V >> 32);
- Out << (unsigned char)(V >> 40);
- Out << (unsigned char)(V >> 48);
- Out << (unsigned char)(V >> 56);
-}
-
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)
- Emit8(Out, 0);
-}
-
-inline uint16_t ReadUnalignedLE16(const unsigned char *&Data) {
- uint16_t V = ((uint16_t)Data[0]) |
- ((uint16_t)Data[1] << 8);
- Data += 2;
- return V;
-}
-
-inline uint32_t ReadUnalignedLE32(const unsigned char *&Data) {
- uint32_t V = ((uint32_t)Data[0]) |
- ((uint32_t)Data[1] << 8) |
- ((uint32_t)Data[2] << 16) |
- ((uint32_t)Data[3] << 24);
- Data += 4;
- return V;
-}
-
-inline uint64_t ReadUnalignedLE64(const unsigned char *&Data) {
- uint64_t V = ((uint64_t)Data[0]) |
- ((uint64_t)Data[1] << 8) |
- ((uint64_t)Data[2] << 16) |
- ((uint64_t)Data[3] << 24) |
- ((uint64_t)Data[4] << 32) |
- ((uint64_t)Data[5] << 40) |
- ((uint64_t)Data[6] << 48) |
- ((uint64_t)Data[7] << 56);
- Data += 8;
- return V;
-}
-
-inline uint32_t ReadLE32(const unsigned char *&Data) {
- // Hosts that directly support little-endian 32-bit loads can just
- // use them. Big-endian hosts need a bswap.
- uint32_t V = *((const uint32_t*)Data);
- if (llvm::sys::IsBigEndianHost)
- V = llvm::ByteSwap_32(V);
- Data += 4;
- return V;
+ endian::Writer<little>(Out).write<uint8_t>(0);
}
} // end namespace io
@@ -188,7 +116,8 @@
}
io::Offset Emit(raw_ostream &out, Info &InfoObj) {
- using namespace clang::io;
+ using namespace llvm::support;
+ endian::Writer<little> LE(out);
// Emit the payload of the table.
for (unsigned i = 0; i < NumBuckets; ++i) {
@@ -200,12 +129,12 @@
assert(B.off && "Cannot write a bucket at offset 0. Please add padding.");
// Write out the number of items in the bucket.
- Emit16(out, B.length);
+ 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) {
- Emit32(out, I->hash);
+ 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);
@@ -214,11 +143,12 @@
}
// Emit the hashtable itself.
- Pad(out, 4);
+ io::Pad(out, 4);
io::Offset TableOff = out.tell();
- Emit32(out, NumBuckets);
- Emit32(out, NumEntries);
- for (unsigned i = 0; i < NumBuckets; ++i) Emit32(out, Buckets[i].off);
+ 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;
}
@@ -286,7 +216,7 @@
if (!InfoPtr)
InfoPtr = &InfoObj;
- using namespace io;
+ using namespace llvm::support;
const internal_key_type& iKey = InfoObj.GetInternalKey(eKey);
unsigned key_hash = InfoObj.ComputeHash(iKey);
@@ -294,17 +224,17 @@
unsigned idx = key_hash & (NumBuckets - 1);
const unsigned char* Bucket = Buckets + sizeof(uint32_t)*idx;
- unsigned offset = ReadLE32(Bucket);
+ 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 = ReadUnalignedLE16(Items);
+ unsigned len = endian::readNext<uint16_t, little, unaligned>(Items);
for (unsigned i = 0; i < len; ++i) {
// Read the hash.
- uint32_t item_hash = ReadUnalignedLE32(Items);
+ 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);
@@ -359,10 +289,12 @@
}
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 = io::ReadUnalignedLE16(Ptr);
+ NumItemsInBucketLeft =
+ endian::readNext<uint16_t, little, unaligned>(Ptr);
}
Ptr += 4; // Skip the hash.
// Determine the length of the key and the data.
@@ -423,10 +355,12 @@
}
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 = io::ReadUnalignedLE16(Ptr);
+ NumItemsInBucketLeft =
+ endian::readNext<uint16_t, little, unaligned>(Ptr);
}
Ptr += 4; // Skip the hash.
// Determine the length of the key and the data.
@@ -468,13 +402,13 @@
static OnDiskChainedHashTable* Create(const unsigned char* buckets,
const unsigned char* const base,
const Info &InfoObj = Info()) {
- using namespace io;
+ using namespace llvm::support;
assert(buckets > base);
assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
"buckets should be 4-byte aligned.");
- unsigned numBuckets = ReadLE32(buckets);
- unsigned numEntries = ReadLE32(buckets);
+ 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);
}
diff --git a/include/clang/Basic/OpenCL.h b/include/clang/Basic/OpenCL.h
deleted file mode 100644
index 3b3f259..0000000
--- a/include/clang/Basic/OpenCL.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===--- OpenCL.h - OpenCL enums --------------------------------*- 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 some OpenCL-specific enums.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_OPENCL_H
-#define LLVM_CLANG_BASIC_OPENCL_H
-
-namespace clang {
-
-/// \brief Names for the OpenCL image access qualifiers (OpenCL 1.1 6.6).
-enum OpenCLImageAccess {
- CLIA_read_only = 1,
- CLIA_write_only = 2,
- CLIA_read_write = 3
-};
-
-}
-
-#endif
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 6d1a7b2..348f40f 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -21,6 +21,9 @@
#ifndef OPENMP_PARALLEL_CLAUSE
# define OPENMP_PARALLEL_CLAUSE(Name)
#endif
+#ifndef OPENMP_SIMD_CLAUSE
+# define OPENMP_SIMD_CLAUSE(Name)
+#endif
#ifndef OPENMP_DEFAULT_KIND
# define OPENMP_DEFAULT_KIND(Name)
#endif
@@ -29,18 +32,30 @@
OPENMP_DIRECTIVE(threadprivate)
OPENMP_DIRECTIVE(parallel)
OPENMP_DIRECTIVE(task)
+OPENMP_DIRECTIVE(simd)
// OpenMP clauses.
+OPENMP_CLAUSE(if, OMPIfClause)
+OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
+OPENMP_CLAUSE(safelen, OMPSafelenClause)
OPENMP_CLAUSE(default, OMPDefaultClause)
OPENMP_CLAUSE(private, OMPPrivateClause)
OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
OPENMP_CLAUSE(shared, OMPSharedClause)
+OPENMP_CLAUSE(copyin, OMPCopyinClause)
-// Clauses allowed for OpenMP directives.
+// Clauses allowed for OpenMP directive 'parallel'.
+OPENMP_PARALLEL_CLAUSE(if)
+OPENMP_PARALLEL_CLAUSE(num_threads)
OPENMP_PARALLEL_CLAUSE(default)
OPENMP_PARALLEL_CLAUSE(private)
OPENMP_PARALLEL_CLAUSE(firstprivate)
OPENMP_PARALLEL_CLAUSE(shared)
+OPENMP_PARALLEL_CLAUSE(copyin)
+
+// FIXME: more clauses allowed for directive 'omp simd'.
+OPENMP_SIMD_CLAUSE(private)
+OPENMP_SIMD_CLAUSE(safelen)
// Static attributes for 'default' clause.
OPENMP_DEFAULT_KIND(none)
@@ -50,3 +65,5 @@
#undef OPENMP_DIRECTIVE
#undef OPENMP_CLAUSE
#undef OPENMP_PARALLEL_CLAUSE
+#undef OPENMP_SIMD_CLAUSE
+
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index dd29926..314b9ef 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -201,13 +201,11 @@
}
}
-#if LLVM_HAS_RVALUE_REFERENCES
PartialDiagnostic(PartialDiagnostic &&Other)
: DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
Allocator(Other.Allocator) {
Other.DiagStorage = 0;
}
-#endif
PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
: DiagID(Other.DiagID), DiagStorage(DiagStorage),
@@ -251,7 +249,6 @@
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
PartialDiagnostic &operator=(PartialDiagnostic &&Other) {
freeStorage();
@@ -262,7 +259,6 @@
Other.DiagStorage = 0;
return *this;
}
-#endif
~PartialDiagnostic() {
freeStorage();
@@ -380,8 +376,8 @@
// match.
template<typename T>
friend inline
- typename llvm::enable_if<llvm::is_same<T, DeclContext>,
- const PartialDiagnostic &>::type
+ typename std::enable_if<std::is_same<T, DeclContext>::value,
+ const PartialDiagnostic &>::type
operator<<(const PartialDiagnostic &PD, T *DC) {
PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
DiagnosticsEngine::ak_declcontext);
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
new file mode 100644
index 0000000..64853f9
--- /dev/null
+++ b/include/clang/Basic/PlistSupport.h
@@ -0,0 +1,113 @@
+//===---------- PlistSupport.h - Plist Output Utilities ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PLISTSUPPORT_H
+#define LLVM_CLANG_PLISTSUPPORT_H
+
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace markup {
+typedef llvm::DenseMap<FileID, unsigned> FIDMap;
+
+static const char *PlistHeader =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
+ "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+ "<plist version=\"1.0\">\n";
+
+static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
+ const SourceManager &SM, SourceLocation L) {
+ FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+ FIDMap::iterator I = FIDs.find(FID);
+ if (I != FIDs.end())
+ return;
+ FIDs[FID] = V.size();
+ V.push_back(FID);
+}
+
+static unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
+ SourceLocation L) {
+ FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+ FIDMap::const_iterator I = FIDs.find(FID);
+ assert(I != FIDs.end());
+ return I->second;
+}
+
+static raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
+ for (unsigned i = 0; i < indent; ++i)
+ o << ' ';
+ return o;
+}
+
+static void EmitLocation(raw_ostream &o, const SourceManager &SM,
+ const LangOptions &LangOpts, SourceLocation L,
+ const FIDMap &FM, unsigned indent,
+ bool extend = false) {
+ FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM));
+
+ // Add in the length of the token, so that we cover multi-char tokens.
+ unsigned offset =
+ extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
+
+ Indent(o, indent) << "<dict>\n";
+ Indent(o, indent) << " <key>line</key><integer>"
+ << Loc.getExpansionLineNumber() << "</integer>\n";
+ Indent(o, indent) << " <key>col</key><integer>"
+ << Loc.getExpansionColumnNumber() + offset
+ << "</integer>\n";
+ Indent(o, indent) << " <key>file</key><integer>" << GetFID(FM, SM, Loc)
+ << "</integer>\n";
+ Indent(o, indent) << "</dict>\n";
+}
+
+static inline void EmitRange(raw_ostream &o, const SourceManager &SM,
+ const LangOptions &LangOpts, CharSourceRange R,
+ const FIDMap &FM, unsigned indent) {
+ Indent(o, indent) << "<array>\n";
+ EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1);
+ EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange());
+ Indent(o, indent) << "</array>\n";
+}
+
+static raw_ostream &EmitString(raw_ostream &o, StringRef s) {
+ o << "<string>";
+ for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
+ char c = *I;
+ switch (c) {
+ default:
+ o << c;
+ break;
+ case '&':
+ o << "&";
+ break;
+ case '<':
+ o << "<";
+ break;
+ case '>':
+ o << ">";
+ break;
+ case '\'':
+ o << "'";
+ break;
+ case '\"':
+ o << """;
+ break;
+ }
+ }
+ o << "</string>";
+ return o;
+}
+}
+}
+
+#endif
diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h
index 967d0d1..0e49295 100644
--- a/include/clang/Basic/PrettyStackTrace.h
+++ b/include/clang/Basic/PrettyStackTrace.h
@@ -31,7 +31,7 @@
public:
PrettyStackTraceLoc(SourceManager &sm, SourceLocation L, const char *Msg)
: SM(sm), Loc(L), Message(Msg) {}
- virtual void print(raw_ostream &OS) const;
+ void print(raw_ostream &OS) const override;
};
}
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index c9b31a3..94c4616 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -89,7 +89,7 @@
ObjectSize | Return | Shift | SignedIntegerOverflow |
Unreachable | VLABound | Vptr)
-// -fsanitize=undefined-trap (and its alias -fcatch-undefined-behavior) includes
+// -fsanitize=undefined-trap includes
// all sanitizers included by -fsanitize=undefined, except those that require
// runtime support. This group is generally used in conjunction with the
// -fsanitize-undefined-trap-on-error flag.
@@ -103,7 +103,6 @@
SignedIntegerOverflow | UnsignedIntegerOverflow | Shift |
IntegerDivideByZero)
-// -fbounds-checking
SANITIZER("local-bounds", LocalBounds)
SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 10ae07b..01ca9a5 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -89,7 +89,7 @@
friend class SourceManager;
friend class ASTReader;
friend class ASTWriter;
- enum LLVM_ENUM_INT_TYPE(unsigned) {
+ enum : unsigned {
MacroIDBit = 1U << 31
};
public:
@@ -172,7 +172,7 @@
}
void print(raw_ostream &OS, const SourceManager &SM) const;
- LLVM_ATTRIBUTE_USED std::string printToString(const SourceManager &SM) const;
+ std::string printToString(const SourceManager &SM) const;
void dump(const SourceManager &SM) const;
};
@@ -188,7 +188,7 @@
return LHS.getRawEncoding() < RHS.getRawEncoding();
}
-/// \brief A trival tuple used to represent a source range.
+/// \brief A trivial tuple used to represent a source range.
class SourceRange {
SourceLocation B;
SourceLocation E;
@@ -331,7 +331,7 @@
/// \brief Prints information about this FullSourceLoc to stderr.
///
/// This is useful for debugging.
- LLVM_ATTRIBUTE_USED void dump() const;
+ void dump() const;
friend inline bool
operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 6aab998..c2130ac 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -42,7 +42,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Allocator.h"
@@ -50,6 +49,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include <cassert>
#include <map>
+#include <memory>
#include <vector>
namespace clang {
@@ -569,7 +569,7 @@
/// \brief Lazily create the object keeping overridden files info, since
/// it is uncommonly used.
- OwningPtr<OverriddenFilesInfoTy> OverriddenFilesInfo;
+ std::unique_ptr<OverriddenFilesInfoTy> OverriddenFilesInfo;
OverriddenFilesInfoTy &getOverriddenFilesInfo() {
if (!OverriddenFilesInfo)
@@ -1332,7 +1332,7 @@
return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
}
- /// \brief The size of the SLocEnty that \p FID represents.
+ /// \brief The size of the SLocEntry that \p FID represents.
unsigned getFileIDSize(FileID FID) const;
/// \brief Given a specific FileID, returns true if \p Loc is inside that
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 0b80939..f895673 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -63,21 +63,13 @@
TST_decltype_auto, // C++1y decltype(auto)
TST_unknown_anytype, // __unknown_anytype extension
TST_atomic, // C11 _Atomic
- TST_image1d_t, // OpenCL image1d_t
- TST_image1d_array_t, // OpenCL image1d_array_t
- TST_image1d_buffer_t, // OpenCL image1d_buffer_t
- TST_image2d_t, // OpenCL image2d_t
- TST_image2d_array_t, // OpenCL image2d_array_t
- TST_image3d_t, // OpenCL image3d_t
- TST_sampler_t, // OpenCL sampler_t
- TST_event_t, // OpenCL event_t
TST_error // erroneous type
};
/// \brief Structure that packs information about the type specifiers that
/// were written in a particular type specifier sequence.
struct WrittenBuiltinSpecs {
- /*DeclSpec::TST*/ unsigned Type : 6;
+ /*DeclSpec::TST*/ unsigned Type : 5;
/*DeclSpec::TSS*/ unsigned Sign : 2;
/*DeclSpec::TSW*/ unsigned Width : 2;
bool ModeAttr : 1;
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 69851a9..0f0f284 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -115,8 +115,6 @@
def CXXDeleteExpr : DStmt<Expr>;
def CXXPseudoDestructorExpr : DStmt<Expr>;
def TypeTraitExpr : DStmt<Expr>;
-def UnaryTypeTraitExpr : DStmt<Expr>;
-def BinaryTypeTraitExpr : DStmt<Expr>;
def ArrayTypeTraitExpr : DStmt<Expr>;
def ExpressionTraitExpr : DStmt<Expr>;
def DependentScopeDeclRefExpr : DStmt<Expr>;
@@ -180,3 +178,4 @@
// OpenMP Directives.
def OMPExecutableDirective : Stmt<1>;
def OMPParallelDirective : DStmt<OMPExecutableDirective>;
+def OMPSimdDirective : DStmt<OMPExecutableDirective>;
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index ed3cc49..e6cc9ab 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -21,10 +21,20 @@
namespace clang {
+ namespace NEON {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsNEON.def"
+ FirstTSBuiltin
+ };
+ }
+
/// \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
@@ -33,13 +43,25 @@
/// \brief ARM builtins
namespace ARM {
enum {
- LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+ LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsARM.def"
- LastTSBuiltin
+ LastTSBuiltin
};
}
+ /// \brief ARM64 builtins
+ namespace ARM64 {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+ LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
+ #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+ #include "clang/Basic/BuiltinsARM64.def"
+ LastTSBuiltin
+ };
+ }
+
/// \brief PPC builtins
namespace PPC {
enum {
@@ -91,6 +113,7 @@
Poly8,
Poly16,
Poly64,
+ Poly128,
Float16,
Float32,
Float64
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
index 1590cca..f9e37c3 100644
--- a/include/clang/Basic/TargetCXXABI.h
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -63,6 +63,14 @@
/// - constructor/destructor signatures.
iOS,
+ /// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more
+ /// closely, but we don't guarantee to follow it perfectly.
+ ///
+ /// It is documented here:
+ /// http://infocenter.arm.com
+ /// /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf
+ iOS64,
+
/// The generic AArch64 ABI is also a modified version of the Itanium ABI,
/// but it has fewer divergences than the 32-bit ARM ABI.
///
@@ -105,6 +113,7 @@
case GenericItanium:
case GenericARM:
case iOS:
+ case iOS64:
return true;
case Microsoft:
@@ -120,6 +129,7 @@
case GenericItanium:
case GenericARM:
case iOS:
+ case iOS64:
return false;
case Microsoft:
@@ -135,14 +145,14 @@
return !isMicrosoft();
}
- /// Are temporary objects passed by value to a call destroyed by the callee?
+ /// Are arguments to a call destroyed left to right in the callee?
/// This is a fundamental language change, since it implies that objects
/// passed by value do *not* live to the end of the full expression.
/// Temporaries passed to a function taking a const reference live to the end
/// of the full expression as usual. Both the caller and the callee must
/// have access to the destructor, while only the caller needs the
/// destructor if this is false.
- bool isArgumentDestroyedByCallee() const {
+ bool areArgsDestroyedLeftToRightInCallee() const {
return isMicrosoft();
}
@@ -195,6 +205,7 @@
bool canKeyFunctionBeInline() const {
switch (getKind()) {
case GenericARM:
+ case iOS64:
return false;
case GenericAArch64:
@@ -230,7 +241,7 @@
/// Only allocate objects in the tail padding of a base class if
/// the base class is not POD according to the rules of C++ TR1.
- /// This is non strictly conforming in C++11 mode.
+ /// This is non-strictly conforming in C++11 mode.
UseTailPaddingUnlessPOD03,
/// Only allocate objects in the tail padding of a base class if
@@ -248,6 +259,11 @@
case iOS:
return UseTailPaddingUnlessPOD03;
+ // iOS on ARM64 uses the C++11 POD rules. It does not honor the
+ // Itanium exception about classes with over-large bitfields.
+ case iOS64:
+ return UseTailPaddingUnlessPOD11;
+
// MSVC always allocates fields in the tail-padding of a base class
// subobject, even if they're POD.
case Microsoft:
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 047872d..24a6fa6 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -16,9 +16,9 @@
#define LLVM_CLANG_BASIC_TARGETINFO_H
#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -579,6 +579,7 @@
}
const char *getTargetDescription() const {
+ assert(DescriptionString);
return DescriptionString;
}
@@ -604,24 +605,6 @@
/// either; the entire thing is pretty badly mangled.
virtual bool hasProtectedVisibility() const { return true; }
- /// \brief Return the section to use for CFString literals, or 0 if no
- /// special section is used.
- virtual const char *getCFStringSection() const {
- return "__DATA,__cfstring";
- }
-
- /// \brief Return the section to use for NSString literals, or 0 if no
- /// special section is used.
- virtual const char *getNSStringSection() const {
- return "__OBJC,__cstring_object,regular,no_dead_strip";
- }
-
- /// \brief Return the section to use for NSString literals, or 0 if no
- /// special section is used (NonFragile ABI).
- virtual const char *getNSStringNonFragileABISection() const {
- return "__DATA, __objc_stringobj, regular, no_dead_strip";
- }
-
/// \brief An optional hook that targets can implement to perform semantic
/// checking on attribute((section("foo"))) specifiers.
///
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 9909182..d8a10a5 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -38,10 +38,6 @@
/// If given, the name of the target ABI to use.
std::string ABI;
- /// If given, the name of the target C++ ABI to use. If not given, defaults
- /// to "itanium".
- std::string CXXABI;
-
/// If given, the version string of the linker in use.
std::string LinkerVersion;
diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h
index c521893..b730143 100644
--- a/include/clang/Basic/TemplateKinds.h
+++ b/include/clang/Basic/TemplateKinds.h
@@ -17,6 +17,7 @@
namespace clang {
/// \brief Specifies the kind of template name that an identifier refers to.
+/// Be careful when changing this: this enumeration is used in diagnostics.
enum TemplateNameKind {
/// The name does not refer to a template.
TNK_Non_template = 0,
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 6812cce..42ebcf8 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -23,6 +23,18 @@
#ifndef KEYWORD
#define KEYWORD(X,Y) TOK(kw_ ## X)
#endif
+#ifndef TYPE_TRAIT
+#define TYPE_TRAIT(N,I,K) KEYWORD(I,K)
+#endif
+#ifndef TYPE_TRAIT_1
+#define TYPE_TRAIT_1(I,E,K) TYPE_TRAIT(1,I,K)
+#endif
+#ifndef TYPE_TRAIT_2
+#define TYPE_TRAIT_2(I,E,K) TYPE_TRAIT(2,I,K)
+#endif
+#ifndef TYPE_TRAIT_N
+#define TYPE_TRAIT_N(I,E,K) TYPE_TRAIT(0,I,K)
+#endif
#ifndef ALIAS
#define ALIAS(X,Y,Z)
#endif
@@ -217,6 +229,7 @@
// KEYALTIVEC - This is a keyword in AltiVec
// KEYBORLAND - This is a keyword if Borland extensions are enabled
// BOOLSUPPORT - This is a keyword if 'bool' is a built-in type
+// HALFSUPPORT - This is a keyword if 'half' is a built-in type
// WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type
//
KEYWORD(auto , KEYALL)
@@ -255,7 +268,7 @@
KEYWORD(while , KEYALL)
KEYWORD(_Alignas , KEYALL)
KEYWORD(_Alignof , KEYALL)
-KEYWORD(_Atomic , KEYALL)
+KEYWORD(_Atomic , KEYALL|KEYNOMS)
KEYWORD(_Bool , KEYNOCXX)
KEYWORD(_Complex , KEYALL)
KEYWORD(_Generic , KEYALL)
@@ -284,7 +297,7 @@
KEYWORD(namespace , KEYCXX)
KEYWORD(new , KEYCXX)
KEYWORD(operator , KEYCXX)
-KEYWORD(private , KEYCXX|KEYOPENCL)
+KEYWORD(private , KEYCXX)
KEYWORD(protected , KEYCXX)
KEYWORD(public , KEYCXX)
KEYWORD(reinterpret_cast , KEYCXX)
@@ -334,7 +347,9 @@
KEYWORD(__attribute , KEYALL)
KEYWORD(__builtin_choose_expr , KEYALL)
KEYWORD(__builtin_offsetof , KEYALL)
-KEYWORD(__builtin_types_compatible_p, KEYALL)
+// __builtin_types_compatible_p is a GNU C extension that we handle like a C++
+// type trait.
+TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
KEYWORD(__builtin_va_arg , KEYALL)
KEYWORD(__extension__ , KEYALL)
KEYWORD(__imag , KEYALL)
@@ -351,42 +366,49 @@
// MS Extensions
KEYWORD(__FUNCDNAME__ , KEYMS)
KEYWORD(L__FUNCTION__ , KEYMS)
-KEYWORD(__is_interface_class , KEYMS)
-KEYWORD(__is_sealed , KEYMS)
+TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS)
+TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
+
+// MSVC12.0 / VS2013 Type Traits
+TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS)
+TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS)
+TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX)
+TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX)
// GNU and MS Type Traits
-KEYWORD(__has_nothrow_assign , KEYCXX)
-KEYWORD(__has_nothrow_move_assign , KEYCXX)
-KEYWORD(__has_nothrow_copy , KEYCXX)
-KEYWORD(__has_nothrow_constructor , KEYCXX)
-KEYWORD(__has_trivial_assign , KEYCXX)
-KEYWORD(__has_trivial_move_assign , KEYCXX)
-KEYWORD(__has_trivial_copy , KEYCXX)
-KEYWORD(__has_trivial_constructor , KEYCXX)
-KEYWORD(__has_trivial_move_constructor, KEYCXX)
-KEYWORD(__has_trivial_destructor , KEYCXX)
-KEYWORD(__has_virtual_destructor , KEYCXX)
-KEYWORD(__is_abstract , KEYCXX)
-KEYWORD(__is_base_of , KEYCXX)
-KEYWORD(__is_class , KEYCXX)
-KEYWORD(__is_convertible_to , KEYCXX)
-KEYWORD(__is_empty , KEYCXX)
-KEYWORD(__is_enum , KEYCXX)
-KEYWORD(__is_final , KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_move_assign, HasNothrowMoveAssign, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_copy, HasNothrowCopy, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_constructor, HasNothrowConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_assign, HasTrivialAssign, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_move_assign, HasTrivialMoveAssign, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_copy, HasTrivialCopy, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_constructor, HasTrivialDefaultConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_destructor, HasTrivialDestructor, KEYCXX)
+TYPE_TRAIT_1(__has_virtual_destructor, HasVirtualDestructor, KEYCXX)
+TYPE_TRAIT_1(__is_abstract, IsAbstract, KEYCXX)
+TYPE_TRAIT_2(__is_base_of, IsBaseOf, KEYCXX)
+TYPE_TRAIT_1(__is_class, IsClass, KEYCXX)
+TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEYCXX)
+TYPE_TRAIT_1(__is_empty, IsEmpty, KEYCXX)
+TYPE_TRAIT_1(__is_enum, IsEnum, KEYCXX)
+TYPE_TRAIT_1(__is_final, IsFinal, KEYCXX)
// Tentative name - there's no implementation of std::is_literal_type yet.
-KEYWORD(__is_literal , KEYCXX)
+TYPE_TRAIT_1(__is_literal, IsLiteral, KEYCXX)
// Name for GCC 4.6 compatibility - people have already written libraries using
// this name unfortunately.
-KEYWORD(__is_literal_type , KEYCXX)
-KEYWORD(__is_pod , KEYCXX)
-KEYWORD(__is_polymorphic , KEYCXX)
-KEYWORD(__is_trivial , KEYCXX)
-KEYWORD(__is_union , KEYCXX)
+ALIAS("__is_literal_type", __is_literal, KEYCXX)
+TYPE_TRAIT_1(__is_pod, IsPOD, KEYCXX)
+TYPE_TRAIT_1(__is_polymorphic, IsPolymorphic, KEYCXX)
+TYPE_TRAIT_1(__is_trivial, IsTrivial, KEYCXX)
+TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX)
// Clang-only C++ Type Traits
-KEYWORD(__is_trivially_constructible, KEYCXX)
-KEYWORD(__is_trivially_copyable , KEYCXX)
-KEYWORD(__is_trivially_assignable , KEYCXX)
+TYPE_TRAIT_N(__is_trivially_constructible, IsTriviallyConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_trivially_copyable, IsTriviallyCopyable, KEYCXX)
+TYPE_TRAIT_2(__is_trivially_assignable, IsTriviallyAssignable, KEYCXX)
KEYWORD(__underlying_type , KEYCXX)
// Embarcadero Expression Traits
@@ -394,33 +416,33 @@
KEYWORD(__is_rvalue_expr , KEYCXX)
// Embarcadero Unary Type Traits
-KEYWORD(__is_arithmetic , KEYCXX)
-KEYWORD(__is_floating_point , KEYCXX)
-KEYWORD(__is_integral , KEYCXX)
-KEYWORD(__is_complete_type , KEYCXX)
-KEYWORD(__is_void , KEYCXX)
-KEYWORD(__is_array , KEYCXX)
-KEYWORD(__is_function , KEYCXX)
-KEYWORD(__is_reference , KEYCXX)
-KEYWORD(__is_lvalue_reference , KEYCXX)
-KEYWORD(__is_rvalue_reference , KEYCXX)
-KEYWORD(__is_fundamental , KEYCXX)
-KEYWORD(__is_object , KEYCXX)
-KEYWORD(__is_scalar , KEYCXX)
-KEYWORD(__is_compound , KEYCXX)
-KEYWORD(__is_pointer , KEYCXX)
-KEYWORD(__is_member_object_pointer , KEYCXX)
-KEYWORD(__is_member_function_pointer, KEYCXX)
-KEYWORD(__is_member_pointer , KEYCXX)
-KEYWORD(__is_const , KEYCXX)
-KEYWORD(__is_volatile , KEYCXX)
-KEYWORD(__is_standard_layout , KEYCXX)
-KEYWORD(__is_signed , KEYCXX)
-KEYWORD(__is_unsigned , KEYCXX)
+TYPE_TRAIT_1(__is_arithmetic, IsArithmetic, KEYCXX)
+TYPE_TRAIT_1(__is_floating_point, IsFloatingPoint, KEYCXX)
+TYPE_TRAIT_1(__is_integral, IsIntegral, KEYCXX)
+TYPE_TRAIT_1(__is_complete_type, IsCompleteType, KEYCXX)
+TYPE_TRAIT_1(__is_void, IsVoid, KEYCXX)
+TYPE_TRAIT_1(__is_array, IsArray, KEYCXX)
+TYPE_TRAIT_1(__is_function, IsFunction, KEYCXX)
+TYPE_TRAIT_1(__is_reference, IsReference, KEYCXX)
+TYPE_TRAIT_1(__is_lvalue_reference, IsLvalueReference, KEYCXX)
+TYPE_TRAIT_1(__is_rvalue_reference, IsRvalueReference, KEYCXX)
+TYPE_TRAIT_1(__is_fundamental, IsFundamental, KEYCXX)
+TYPE_TRAIT_1(__is_object, IsObject, KEYCXX)
+TYPE_TRAIT_1(__is_scalar, IsScalar, KEYCXX)
+TYPE_TRAIT_1(__is_compound, IsCompound, KEYCXX)
+TYPE_TRAIT_1(__is_pointer, IsPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_object_pointer, IsMemberObjectPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_function_pointer, IsMemberFunctionPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_pointer, IsMemberPointer, KEYCXX)
+TYPE_TRAIT_1(__is_const, IsConst, KEYCXX)
+TYPE_TRAIT_1(__is_volatile, IsVolatile, KEYCXX)
+TYPE_TRAIT_1(__is_standard_layout, IsStandardLayout, KEYCXX)
+TYPE_TRAIT_1(__is_signed, IsSigned, KEYCXX)
+TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX)
// Embarcadero Binary Type Traits
-KEYWORD(__is_same , KEYCXX)
-KEYWORD(__is_convertible , KEYCXX)
+TYPE_TRAIT_2(__is_same, IsSame, KEYCXX)
+TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX)
KEYWORD(__array_rank , KEYCXX)
KEYWORD(__array_extent , KEYCXX)
@@ -434,35 +456,31 @@
KEYWORD(__stdcall , KEYALL)
KEYWORD(__fastcall , KEYALL)
KEYWORD(__thiscall , KEYALL)
-KEYWORD(__forceinline , KEYALL)
+KEYWORD(__forceinline , KEYMS)
KEYWORD(__unaligned , KEYMS)
-// OpenCL-specific keywords
-KEYWORD(__kernel , KEYOPENCL)
-ALIAS("kernel", __kernel , KEYOPENCL)
-KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC)
-KEYWORD(__private , KEYOPENCL)
+// OpenCL address space qualifiers
KEYWORD(__global , KEYOPENCL)
KEYWORD(__local , KEYOPENCL)
KEYWORD(__constant , KEYOPENCL)
+KEYWORD(__private , KEYOPENCL)
ALIAS("global", __global , KEYOPENCL)
ALIAS("local", __local , KEYOPENCL)
ALIAS("constant", __constant , KEYOPENCL)
+ALIAS("private", __private , KEYOPENCL)
+// OpenCL function qualifiers
+KEYWORD(__kernel , KEYOPENCL)
+ALIAS("kernel", __kernel , KEYOPENCL)
+// OpenCL access qualifiers
KEYWORD(__read_only , KEYOPENCL)
KEYWORD(__write_only , KEYOPENCL)
KEYWORD(__read_write , KEYOPENCL)
ALIAS("read_only", __read_only , KEYOPENCL)
ALIAS("write_only", __write_only , KEYOPENCL)
ALIAS("read_write", __read_write , KEYOPENCL)
+// OpenCL builtins
KEYWORD(__builtin_astype , KEYOPENCL)
-KEYWORD(image1d_t , KEYOPENCL)
-KEYWORD(image1d_array_t , KEYOPENCL)
-KEYWORD(image1d_buffer_t , KEYOPENCL)
-KEYWORD(image2d_t , KEYOPENCL)
-KEYWORD(image2d_array_t , KEYOPENCL)
-KEYWORD(image3d_t , KEYOPENCL)
-KEYWORD(sampler_t , KEYOPENCL)
-KEYWORD(event_t , KEYOPENCL)
+KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC)
// Borland Extensions.
KEYWORD(__pascal , KEYALL)
@@ -475,7 +493,7 @@
ALIAS("__fp16", half , KEYALL)
// OpenCL Extension.
-KEYWORD(half , KEYOPENCL)
+KEYWORD(half , HALFSUPPORT)
// Objective-C ARC keywords.
KEYWORD(__bridge , KEYARC)
@@ -656,6 +674,16 @@
// handles them.
ANNOTATION(pragma_fp_contract)
+// Annotation for #pragma pointers_to_members...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_pointers_to_members)
+
+// Annotation for #pragma vtordisp...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_vtordisp)
+
// Annotation for #pragma OPENCL EXTENSION...
// The lexer produces these so that they only take effect when the parser
// handles them.
@@ -667,8 +695,10 @@
ANNOTATION(pragma_openmp)
ANNOTATION(pragma_openmp_end)
-// Annotation for module import translated from #include etc.
+// Annotations for module import translated from #include etc.
ANNOTATION(module_include)
+ANNOTATION(module_begin)
+ANNOTATION(module_end)
#undef ANNOTATION
#undef TESTING_KEYWORD
@@ -677,6 +707,10 @@
#undef CXX_KEYWORD_OPERATOR
#undef PPKEYWORD
#undef ALIAS
+#undef TYPE_TRAIT_N
+#undef TYPE_TRAIT_2
+#undef TYPE_TRAIT_1
+#undef TYPE_TRAIT
#undef KEYWORD
#undef PUNCTUATOR
#undef TOK
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
index dcbe1da..794625c 100644
--- a/include/clang/Basic/TokenKinds.h
+++ b/include/clang/Basic/TokenKinds.h
@@ -15,12 +15,14 @@
#ifndef LLVM_CLANG_TOKENKINDS_H
#define LLVM_CLANG_TOKENKINDS_H
+#include "llvm/Support/Compiler.h"
+
namespace clang {
namespace tok {
/// \brief Provides a simple uniform namespace for tokens from all C languages.
-enum TokenKind {
+enum TokenKind : unsigned short {
#define TOK(X) X,
#include "clang/Basic/TokenKinds.def"
NUM_TOKENS
@@ -52,7 +54,7 @@
///
/// The name of a token will be an internal name (such as "l_square")
/// and should not be used as part of diagnostic messages.
-const char *getTokenName(enum TokenKind Kind);
+const char *getTokenName(TokenKind Kind) LLVM_READNONE;
/// \brief Determines the spelling of simple punctuation tokens like
/// '!' or '%', and returns NULL for literal and annotation tokens.
@@ -61,7 +63,11 @@
/// and will not produce any alternative spellings (e.g., a
/// digraph). For the actual spelling of a given Token, use
/// Preprocessor::getSpelling().
-const char *getTokenSimpleSpelling(enum TokenKind Kind);
+const char *getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE;
+
+/// \brief Determines the spelling of simple keyword and contextual keyword
+/// tokens like 'int' and 'dynamic_cast'. Returns NULL for other token kinds.
+const char *getKeywordSpelling(TokenKind Kind) LLVM_READNONE;
/// \brief Return true if this is a raw identifier or an identifier kind.
inline bool isAnyIdentifier(TokenKind K) {
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index fc53527..d7d2b18 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -17,8 +17,8 @@
namespace clang {
- /// \brief Names for the unary type traits.
- enum UnaryTypeTrait {
+ /// \brief Names for traits that operate specifically on types.
+ enum TypeTrait {
UTT_HasNothrowAssign,
UTT_HasNothrowMoveAssign,
UTT_HasNothrowCopy,
@@ -37,6 +37,7 @@
UTT_IsCompleteType,
UTT_IsCompound,
UTT_IsConst,
+ UTT_IsDestructible,
UTT_IsEmpty,
UTT_IsEnum,
UTT_IsFinal,
@@ -50,6 +51,7 @@
UTT_IsMemberFunctionPointer,
UTT_IsMemberObjectPointer,
UTT_IsMemberPointer,
+ UTT_IsNothrowDestructible,
UTT_IsObject,
UTT_IsPOD,
UTT_IsPointer,
@@ -65,17 +67,19 @@
UTT_IsUnion,
UTT_IsUnsigned,
UTT_IsVoid,
- UTT_IsVolatile
- };
-
- /// \brief Names for the binary type traits.
- enum BinaryTypeTrait {
+ UTT_IsVolatile,
+ UTT_Last = UTT_IsVolatile,
BTT_IsBaseOf,
BTT_IsConvertible,
BTT_IsConvertibleTo,
BTT_IsSame,
BTT_TypeCompatible,
- BTT_IsTriviallyAssignable
+ BTT_IsNothrowAssignable,
+ BTT_IsTriviallyAssignable,
+ BTT_Last = BTT_IsTriviallyAssignable,
+ TT_IsConstructible,
+ TT_IsNothrowConstructible,
+ TT_IsTriviallyConstructible
};
/// \brief Names for the array type traits.
@@ -90,12 +94,6 @@
UETT_AlignOf,
UETT_VecStep
};
-
- /// \brief Names for type traits that operate specifically on types.
- enum TypeTrait {
- TT_IsTriviallyConstructible
- };
-
}
#endif
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 7db8a2e..02da432 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -70,6 +70,9 @@
/// and the vendor tag.
std::string getClangFullVersion();
+ /// \brief Like getClangFullVersion(), but with a custom tool name.
+ std::string getClangToolFullVersion(llvm::StringRef ToolName);
+
/// \brief Retrieves a string representing the complete clang version suitable
/// for use in the CPP __VERSION__ macro, which includes the clang version
/// number, the repository version, and the vendor tag.
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
index ff06a5c..54d06e0 100644
--- a/include/clang/Basic/VersionTuple.h
+++ b/include/clang/Basic/VersionTuple.h
@@ -18,6 +18,7 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/Optional.h"
#include <string>
+#include <tuple>
namespace clang {
@@ -87,13 +88,8 @@
/// If not provided, minor and subminor version numbers are considered to be
/// zero.
friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
- if (X.Major != Y.Major)
- return X.Major < Y.Major;
-
- if (X.Minor != Y.Minor)
- return X.Minor < Y.Minor;
-
- return X.Subminor < Y.Subminor;
+ return std::tie(X.Major, X.Minor, X.Subminor) <
+ std::tie(Y.Major, Y.Minor, Y.Subminor);
}
/// \brief Determine whether one version number follows another.
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
new file mode 100644
index 0000000..5595e14
--- /dev/null
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -0,0 +1,169 @@
+//===- VirtualFileSystem.h - Virtual File System Layer ----------*- 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 virtual file system interface vfs::FileSystem.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+#define LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/SourceMgr.h"
+
+namespace llvm {
+class MemoryBuffer;
+}
+
+namespace clang {
+namespace vfs {
+
+/// \brief The result of a \p status operation.
+class Status {
+ std::string Name;
+ llvm::sys::fs::UniqueID UID;
+ llvm::sys::TimeValue MTime;
+ uint32_t User;
+ uint32_t Group;
+ uint64_t Size;
+ llvm::sys::fs::file_type Type;
+ llvm::sys::fs::perms Perms;
+
+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,
+ llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group,
+ uint64_t Size, llvm::sys::fs::file_type Type,
+ llvm::sys::fs::perms Perms);
+
+ /// \brief Returns the name that should be used for this file or directory.
+ StringRef getName() const { return Name; }
+ void setName(StringRef N) { Name = N; }
+
+ /// @name Status interface from llvm::sys::fs
+ /// @{
+ llvm::sys::fs::file_type getType() const { return Type; }
+ llvm::sys::fs::perms getPermissions() const { return Perms; }
+ llvm::sys::TimeValue getLastModificationTime() const { return MTime; }
+ llvm::sys::fs::UniqueID getUniqueID() const { return UID; }
+ uint32_t getUser() const { return User; }
+ uint32_t getGroup() const { return Group; }
+ uint64_t getSize() const { return Size; }
+ void setType(llvm::sys::fs::file_type v) { Type = v; }
+ void setPermissions(llvm::sys::fs::perms p) { Perms = p; }
+ /// @}
+ /// @name Status queries
+ /// These are static queries in llvm::sys::fs.
+ /// @{
+ bool equivalent(const Status &Other) const;
+ bool isDirectory() const;
+ bool isRegularFile() const;
+ bool isOther() const;
+ bool isSymlink() const;
+ bool isStatusKnown() const;
+ bool exists() const;
+ /// @}
+};
+
+/// \brief Represents an open file.
+class File {
+public:
+ /// \brief Destroy the file after closing it (if open).
+ /// Sub-classes should generally call close() inside their destructors. We
+ /// cannot do that from the base class, since close is virtual.
+ virtual ~File();
+ /// \brief Get the status of the file.
+ virtual llvm::ErrorOr<Status> status() = 0;
+ /// \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;
+ /// \brief Closes the file.
+ virtual llvm::error_code close() = 0;
+ /// \brief Sets the name to use for this file.
+ virtual void setName(StringRef Name) = 0;
+};
+
+/// \brief The virtual file system interface.
+class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem> {
+public:
+ virtual ~FileSystem();
+
+ /// \brief Get the status of the entry at \p Path, if one exists.
+ virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
+ /// \brief Get a \p File object for the file at \p Path, if one exists.
+ virtual llvm::error_code openFileForRead(const Twine &Path,
+ std::unique_ptr<File> &Result) = 0;
+
+ /// This is a convenience method that opens a file, gets its content and then
+ /// closes the file.
+ llvm::error_code getBufferForFile(const Twine &Name,
+ std::unique_ptr<llvm::MemoryBuffer> &Result,
+ int64_t FileSize = -1,
+ bool RequiresNullTerminator = true);
+};
+
+/// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by
+/// the operating system.
+IntrusiveRefCntPtr<FileSystem> getRealFileSystem();
+
+/// \brief A file system that allows overlaying one \p AbstractFileSystem on top
+/// of another.
+///
+/// Consists of a stack of >=1 \p FileSystem objects, which are treated as being
+/// one merged file system. When there is a directory that exists in more than
+/// one file system, the \p OverlayFileSystem contains a directory containing
+/// the union of their contents. The attributes (permissions, etc.) of the
+/// top-most (most recently added) directory are used. When there is a file
+/// that exists in more than one file system, the file in the top-most file
+/// system overrides the other(s).
+class OverlayFileSystem : public FileSystem {
+ typedef SmallVector<IntrusiveRefCntPtr<FileSystem>, 1> FileSystemList;
+ typedef FileSystemList::reverse_iterator iterator;
+
+ /// \brief The stack of file systems, implemented as a list in order of
+ /// their addition.
+ FileSystemList FSList;
+
+ /// \brief Get an iterator pointing to the most recently added file system.
+ iterator overlays_begin() { return FSList.rbegin(); }
+
+ /// \brief Get an iterator pointing one-past the least recently added file
+ /// system.
+ iterator overlays_end() { return FSList.rend(); }
+
+public:
+ OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base);
+ /// \brief Pushes a file system on top of the stack.
+ void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
+
+ llvm::ErrorOr<Status> status(const Twine &Path) override;
+ llvm::error_code openFileForRead(const Twine &Path,
+ std::unique_ptr<File> &Result) override;
+};
+
+/// \brief Get a globally unique ID for a virtual file or directory.
+llvm::sys::fs::UniqueID getNextVirtualUniqueID();
+
+/// \brief Gets a \p FileSystem for a virtual file system described in YAML
+/// format.
+///
+/// Takes ownership of \p Buffer.
+IntrusiveRefCntPtr<FileSystem>
+getVFSFromYAML(llvm::MemoryBuffer *Buffer,
+ llvm::SourceMgr::DiagHandlerTy DiagHandler,
+ void *DiagContext = 0,
+ IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
+
+} // end namespace vfs
+} // end namespace clang
+#endif // LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
index b918459..8f7ae57 100644
--- a/include/clang/Basic/arm_neon.td
+++ b/include/clang/Basic/arm_neon.td
@@ -30,6 +30,7 @@
def OP_MLA : Op;
def OP_MLAL : Op;
def OP_MULLHi : Op;
+def OP_MULLHi_P64 : Op;
def OP_MULLHi_N : Op;
def OP_MLALHi : Op;
def OP_MLALHi_N : Op;
@@ -140,13 +141,17 @@
string Name = n;
string Prototype = p;
string Types = t;
+ string ArchGuard = "";
+
Op Operand = o;
bit isShift = 0;
bit isScalarShift = 0;
bit isScalarNarrowShift = 0;
bit isVCVT_N = 0;
- bit isA64 = 0;
- bit isCrypto = 0;
+ // For immediate checks: the immediate will be assumed to specify the lane of
+ // a Q register. Only used for intrinsics which end up calling polymorphic
+ // builtins.
+ bit isLaneQ = 0;
// Certain intrinsics have different names than their representative
// instructions. This field allows us to handle this correctly when we
@@ -224,6 +229,7 @@
// s: short
// i: int
// l: long
+// k: 128-bit long
// f: float
// h: half-float
// d: double
@@ -404,9 +410,11 @@
// E.3.19 Set all lanes to same value
let InstName = "vmov" in {
def VDUP_N : WOpInst<"vdup_n", "ds",
- "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
+ "UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
+ OP_DUP>;
def VMOV_N : WOpInst<"vmov_n", "ds",
- "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
+ "UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
+ OP_DUP>;
}
let InstName = "" in
def VDUP_LANE: WOpInst<"vdup_lane", "dgi",
@@ -540,87 +548,66 @@
////////////////////////////////////////////////////////////////////////////////
// AArch64 Intrinsics
-let isA64 = 1 in {
+let ArchGuard = "defined(__aarch64__)" in {
////////////////////////////////////////////////////////////////////////////////
// Load/Store
-// With additional QUl, Ql, d, Qd, Pl, QPl type.
-def LD1 : WInst<"vld1", "dc",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def LD2 : WInst<"vld2", "2c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def LD3 : WInst<"vld3", "3c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def LD4 : WInst<"vld4", "4c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def ST1 : WInst<"vst1", "vpd",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def ST2 : WInst<"vst2", "vp2",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def ST3 : WInst<"vst3", "vp3",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def ST4 : WInst<"vst4", "vp4",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
+def LD1 : WInst<"vld1", "dc", "dQdPlQPl">;
+def LD2 : WInst<"vld2", "2c", "QUlQldQdPlQPl">;
+def LD3 : WInst<"vld3", "3c", "QUlQldQdPlQPl">;
+def LD4 : WInst<"vld4", "4c", "QUlQldQdPlQPl">;
+def ST1 : WInst<"vst1", "vpd", "dQdPlQPl">;
+def ST2 : WInst<"vst2", "vp2", "QUlQldQdPlQPl">;
+def ST3 : WInst<"vst3", "vp3", "QUlQldQdPlQPl">;
+def ST4 : WInst<"vst4", "vp4", "QUlQldQdPlQPl">;
def LD1_X2 : WInst<"vld1_x2", "2c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
def LD3_x3 : WInst<"vld1_x3", "3c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
def LD4_x4 : WInst<"vld1_x4", "4c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
def ST1_X2 : WInst<"vst1_x2", "vp2",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
def ST1_X3 : WInst<"vst1_x3", "vp3",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
def ST1_X4 : WInst<"vst1_x4", "vp4",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
-// With additional QUl, Ql, d, Qd, Pl, QPl type.
-def LD1_LANE : WInst<"vld1_lane", "dcdi",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def LD2_LANE : WInst<"vld2_lane", "2c2i",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def LD3_LANE : WInst<"vld3_lane", "3c3i",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def LD4_LANE : WInst<"vld4_lane", "4c4i",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def ST1_LANE : WInst<"vst1_lane", "vpdi",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def ST2_LANE : WInst<"vst2_lane", "vp2i",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def ST3_LANE : WInst<"vst3_lane", "vp3i",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def ST4_LANE : WInst<"vst4_lane", "vp4i",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+def LD1_LANE : WInst<"vld1_lane", "dcdi", "dQdPlQPl">;
+def LD2_LANE : WInst<"vld2_lane", "2c2i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def LD3_LANE : WInst<"vld3_lane", "3c3i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def LD4_LANE : WInst<"vld4_lane", "4c4i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def ST1_LANE : WInst<"vst1_lane", "vpdi", "dQdPlQPl">;
+def ST2_LANE : WInst<"vst2_lane", "vp2i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def ST3_LANE : WInst<"vst3_lane", "vp3i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def ST4_LANE : WInst<"vst4_lane", "vp4i", "lUlQcQUcQPcQlQUldQdPlQPl">;
-def LD1_DUP : WInst<"vld1_dup", "dc",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+def LD1_DUP : WInst<"vld1_dup", "dc", "dQdPlQPl">;
def LD2_DUP : WInst<"vld2_dup", "2c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
def LD3_DUP : WInst<"vld3_dup", "3c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
def LD4_DUP : WInst<"vld4_dup", "4c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+ "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
+
+def VLDRQ : WInst<"vldrq", "sc", "Pk">;
+def VSTRQ : WInst<"vstrq", "vps", "Pk">;
////////////////////////////////////////////////////////////////////////////////
// Addition
-// With additional d, Qd type.
-def ADD : IOpInst<"vadd", "ddd", "csilfdUcUsUiUlQcQsQiQlQfQUcQUsQUiQUlQd",
- OP_ADD>;
+def ADD : IOpInst<"vadd", "ddd", "dQd", OP_ADD>;
////////////////////////////////////////////////////////////////////////////////
// Subtraction
-// With additional Qd type.
-def SUB : IOpInst<"vsub", "ddd", "csildfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUlQd",
- OP_SUB>;
+def SUB : IOpInst<"vsub", "ddd", "dQd", OP_SUB>;
////////////////////////////////////////////////////////////////////////////////
// Multiplication
-// With additional Qd type.
-def MUL : IOpInst<"vmul", "ddd", "csifdUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MUL>;
-def MLA : IOpInst<"vmla", "dddd", "csifdUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MLA>;
-def MLS : IOpInst<"vmls", "dddd", "csifdUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MLS>;
+def MUL : IOpInst<"vmul", "ddd", "dQd", OP_MUL>;
+def MLA : IOpInst<"vmla", "dddd", "dQd", OP_MLA>;
+def MLS : IOpInst<"vmls", "dddd", "dQd", OP_MLS>;
////////////////////////////////////////////////////////////////////////////////
// Multiplication Extended
@@ -632,34 +619,33 @@
////////////////////////////////////////////////////////////////////////////////
// Vector fused multiply-add operations
-// With additional d, Qd type.
-def FMLA : SInst<"vfma", "dddd", "fdQfQd">;
+def FMLA : SInst<"vfma", "dddd", "dQd">;
def FMLS : SInst<"vfms", "dddd", "fdQfQd">;
////////////////////////////////////////////////////////////////////////////////
-// MUL, FMA, FMS definitions with scalar argument
+// MUL, MLA, MLS, FMA, FMS definitions with scalar argument
def VMUL_N_A64 : IOpInst<"vmul_n", "dds", "Qd", OP_MUL_N>;
-def FMLA_N : SOpInst<"vfma_n", "ddds", "fQf", OP_FMLA_N>;
-def FMLS_N : SOpInst<"vfms_n", "ddds", "fQf", OP_FMLS_N>;
+
+def FMLA_N : SOpInst<"vfma_n", "ddds", "fQfQd", OP_FMLA_N>;
+def FMLS_N : SOpInst<"vfms_n", "ddds", "fQfQd", OP_FMLS_N>;
+
+def MLA_N : SOpInst<"vmla_n", "ddds", "Qd", OP_MLA_N>;
+def MLS_N : SOpInst<"vmls_n", "ddds", "Qd", OP_MLS_N>;
////////////////////////////////////////////////////////////////////////////////
// Logical operations
-// With additional Qd, Ql, QPl type.
-def BSL : SInst<"vbsl", "dudd",
- "csilUcUsUiUlfdPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPsQdPlQPl">;
+def BSL : SInst<"vbsl", "dudd", "dPlQdQPl">;
////////////////////////////////////////////////////////////////////////////////
// Absolute Difference
-// With additional Qd type.
-def ABD : SInst<"vabd", "ddd", "csiUcUsUifdQcQsQiQUcQUsQUiQfQd">;
+def ABD : SInst<"vabd", "ddd", "dQd">;
////////////////////////////////////////////////////////////////////////////////
// saturating absolute/negate
-// With additional Qd/Ql type.
-def ABS : SInst<"vabs", "dd", "csilfdQcQsQiQfQlQd">;
-def QABS : SInst<"vqabs", "dd", "csilQcQsQiQl">;
-def NEG : SOpInst<"vneg", "dd", "csilfdQcQsQiQfQdQl", OP_NEG>;
-def QNEG : SInst<"vqneg", "dd", "csilQcQsQiQl">;
+def ABS : SInst<"vabs", "dd", "dQdlQl">;
+def QABS : SInst<"vqabs", "dd", "lQl">;
+def NEG : SOpInst<"vneg", "dd", "dlQdQl", OP_NEG>;
+def QNEG : SInst<"vqneg", "dd", "lQl">;
////////////////////////////////////////////////////////////////////////////////
// Signed Saturating Accumulated of Unsigned Value
@@ -671,9 +657,8 @@
////////////////////////////////////////////////////////////////////////////////
// Reciprocal/Sqrt
-// With additional d, Qd type.
-def FRECPS : IInst<"vrecps", "ddd", "fdQfQd">;
-def FRSQRTS : IInst<"vrsqrts", "ddd", "fdQfQd">;
+def FRECPS : IInst<"vrecps", "ddd", "dQd">;
+def FRSQRTS : IInst<"vrsqrts", "ddd", "dQd">;
////////////////////////////////////////////////////////////////////////////////
// bitwise reverse
@@ -695,7 +680,7 @@
// Converting vectors
def VCVT_HIGH_F16 : SOpInst<"vcvt_high_f16", "qhj", "f", OP_VCVT_NA_HI>;
def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI>;
-def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "fj", "d">;
+def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "mj", "d">;
def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI>;
def VCVT_F64_F32 : SInst<"vcvt_f64_f32", "wd", "f">;
def VCVT_F64 : SInst<"vcvt_f64", "Fd", "lUlQlQUl">;
@@ -711,47 +696,22 @@
def FRINTI : SInst<"vrndi", "dd", "fdQfQd">;
def VCVT_S64 : SInst<"vcvt_s64", "xd", "dQd">;
def VCVT_U64 : SInst<"vcvt_u64", "ud", "dQd">;
-def FCVTNS_S32 : SInst<"vcvtn_s32", "xd", "fQf">;
-def FCVTNS_S64 : SInst<"vcvtn_s64", "xd", "dQd">;
-def FCVTNU_S32 : SInst<"vcvtn_u32", "ud", "fQf">;
-def FCVTNU_S64 : SInst<"vcvtn_u64", "ud", "dQd">;
-def FCVTPS_S32 : SInst<"vcvtp_s32", "xd", "fQf">;
-def FCVTPS_S64 : SInst<"vcvtp_s64", "xd", "dQd">;
-def FCVTPU_S32 : SInst<"vcvtp_u32", "ud", "fQf">;
-def FCVTPU_S64 : SInst<"vcvtp_u64", "ud", "dQd">;
-def FCVTMS_S32 : SInst<"vcvtm_s32", "xd", "fQf">;
-def FCVTMS_S64 : SInst<"vcvtm_s64", "xd", "dQd">;
-def FCVTMU_S32 : SInst<"vcvtm_u32", "ud", "fQf">;
-def FCVTMU_S64 : SInst<"vcvtm_u64", "ud", "dQd">;
-def FCVTAS_S32 : SInst<"vcvta_s32", "xd", "fQf">;
-def FCVTAS_S64 : SInst<"vcvta_s64", "xd", "dQd">;
-def FCVTAU_S32 : SInst<"vcvta_u32", "ud", "fQf">;
-def FCVTAU_S64 : SInst<"vcvta_u64", "ud", "dQd">;
-def FRECPE : SInst<"vrecpe", "dd", "fdUiQfQUiQd">;
-def FRSQRTE : SInst<"vrsqrte", "dd", "fdUiQfQUiQd">;
+def FRECPE : SInst<"vrecpe", "dd", "dQd">;
+def FRSQRTE : SInst<"vrsqrte", "dd", "dQd">;
def FSQRT : SInst<"vsqrt", "dd", "fdQfQd">;
////////////////////////////////////////////////////////////////////////////////
// Comparison
-// With additional Qd, Ql, QPl type.
-def FCAGE : IInst<"vcage", "udd", "fdQfQd">;
-def FCAGT : IInst<"vcagt", "udd", "fdQfQd">;
-def FCALE : IInst<"vcale", "udd", "fdQfQd">;
-def FCALT : IInst<"vcalt", "udd", "fdQfQd">;
-// With additional Ql, QUl, Qd types.
-def CMTST : WInst<"vtst", "udd",
- "csiUcUsUiPcPsQcQsQiQUcQUsQUiQPcQPslUlQlQUlPlQPl">;
-// With additional l, Ul,d, Qd, Ql, QUl, Qd types.
-def CFMEQ : SOpInst<"vceq", "udd",
- "csilfUcUsUiUlPcQcdQdQsQiQfQUcQUsQUiQUlQlQPcPlQPl", OP_EQ>;
-def CFMGE : SOpInst<"vcge", "udd",
- "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUldQd", OP_GE>;
-def CFMLE : SOpInst<"vcle", "udd",
- "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUldQd", OP_LE>;
-def CFMGT : SOpInst<"vcgt", "udd",
- "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUldQd", OP_GT>;
-def CFMLT : SOpInst<"vclt", "udd",
- "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUldQd", OP_LT>;
+def FCAGE : IInst<"vcage", "udd", "dQd">;
+def FCAGT : IInst<"vcagt", "udd", "dQd">;
+def FCALE : IInst<"vcale", "udd", "dQd">;
+def FCALT : IInst<"vcalt", "udd", "dQd">;
+def CMTST : WInst<"vtst", "udd", "lUlPlQlQUlQPl">;
+def CFMEQ : SOpInst<"vceq", "udd", "lUldQdQlQUlPlQPl", OP_EQ>;
+def CFMGE : SOpInst<"vcge", "udd", "lUldQdQlQUl", OP_GE>;
+def CFMLE : SOpInst<"vcle", "udd", "lUldQdQlQUl", OP_LE>;
+def CFMGT : SOpInst<"vcgt", "udd", "lUldQdQlQUl", OP_GT>;
+def CFMLT : SOpInst<"vclt", "udd", "lUldQdQlQUl", OP_LT>;
def CMEQ : SInst<"vceqz", "ud",
"csilfUcUsUiUlPcPsPlQcQsQiQlQfQUcQUsQUiQUlQPcQPsdQdQPl">;
@@ -762,9 +722,8 @@
////////////////////////////////////////////////////////////////////////////////
// Max/Min Integer
-// With additional Qd type.
-def MAX : SInst<"vmax", "ddd", "csiUcUsUifdQcQsQiQUcQUsQUiQfQd">;
-def MIN : SInst<"vmin", "ddd", "csiUcUsUifdQcQsQiQUcQUsQUiQfQd">;
+def MAX : SInst<"vmax", "ddd", "dQd">;
+def MIN : SInst<"vmin", "ddd", "dQd">;
////////////////////////////////////////////////////////////////////////////////
// MaxNum/MinNum Floating Point
@@ -773,9 +732,8 @@
////////////////////////////////////////////////////////////////////////////////
// Pairwise Max/Min
-// With additional Qc Qs Qi QUc QUs QUi Qf Qd types.
-def MAXP : SInst<"vpmax", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">;
-def MINP : SInst<"vpmin", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">;
+def MAXP : SInst<"vpmax", "ddd", "QcQsQiQUcQUsQUiQfQd">;
+def MINP : SInst<"vpmin", "ddd", "QcQsQiQUcQUsQUiQfQd">;
////////////////////////////////////////////////////////////////////////////////
// Pairwise MaxNum/MinNum Floating Point
@@ -784,8 +742,7 @@
////////////////////////////////////////////////////////////////////////////////
// Pairwise Addition
-// With additional Qc Qs Qi QUc QUs QUi Qf Qd types.
-def ADDP : IInst<"vpadd", "ddd", "csiUcUsUifQcQsQiQlQUcQUsQUiQUlQfQd">;
+def ADDP : IInst<"vpadd", "ddd", "QcQsQiQlQUcQUsQUiQUlQfQd">;
////////////////////////////////////////////////////////////////////////////////
// Shifts by constant
@@ -795,11 +752,8 @@
OP_LONG_HI>;
////////////////////////////////////////////////////////////////////////////////
-// Shifts with insert, with additional Ql, QPl type.
-def SRI_N : WInst<"vsri_n", "dddi",
- "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPsPlQPl">;
-def SLI_N : WInst<"vsli_n", "dddi",
- "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPsPlQPl">;
+def SRI_N : WInst<"vsri_n", "dddi", "PlQPl">;
+def SLI_N : WInst<"vsli_n", "dddi", "PlQPl">;
// Right shift narrow high
def SHRN_HIGH_N : IOpInst<"vshrn_high_n", "hmdi",
@@ -854,15 +808,16 @@
def VQDMLAL_HIGH_N : SOpInst<"vqdmlal_high_n", "wwks", "si", OP_QDMLALHi_N>;
def VQDMLSL_HIGH : SOpInst<"vqdmlsl_high", "wwkk", "si", OP_QDMLSLHi>;
def VQDMLSL_HIGH_N : SOpInst<"vqdmlsl_high_n", "wwks", "si", OP_QDMLSLHi_N>;
+def VMULL_P64 : SInst<"vmull", "rss", "Pl">;
+def VMULL_HIGH_P64 : SOpInst<"vmull_high", "rdd", "HPl", OP_MULLHi_P64>;
+
////////////////////////////////////////////////////////////////////////////////
// Extract or insert element from vector
-def GET_LANE : IInst<"vget_lane", "sdi",
- "csilPcPsUcUsUiUlQcQsQiQlQUcQUsQUiQUlPcPsQPcQPsfdQfQdPlQPl">;
-def SET_LANE : IInst<"vset_lane", "dsdi",
- "csilPcPsUcUsUiUlQcQsQiQlQUcQUsQUiQUlPcPsQPcQPsfdQfQdPlQPl">;
+def GET_LANE : IInst<"vget_lane", "sdi", "dQdPlQPl">;
+def SET_LANE : IInst<"vset_lane", "dsdi", "dQdPlQPl">;
def COPY_LANE : IOpInst<"vcopy_lane", "ddidi",
- "csilPcPsUcUsUiUlPcPsPlfd", OP_COPY_LN>;
+ "csilUcUsUiUlPcPsPlfd", OP_COPY_LN>;
def COPYQ_LANE : IOpInst<"vcopy_lane", "ddigi",
"QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPYQ_LN>;
def COPY_LANEQ : IOpInst<"vcopy_laneq", "ddiki",
@@ -872,26 +827,19 @@
////////////////////////////////////////////////////////////////////////////////
// Set all lanes to same value
-def VDUP_LANE1: WOpInst<"vdup_lane", "dgi",
- "csilPcPsUcUsUiUlhfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
- OP_DUP_LN>;
+def VDUP_LANE1: WOpInst<"vdup_lane", "dgi", "hdQhQdPlQPl", OP_DUP_LN>;
def VDUP_LANE2: WOpInst<"vdup_laneq", "dki",
- "csilPcPsUcUsUiUlhfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
+ "csilUcUsUiUlPcPshfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
OP_DUP_LN>;
-def DUP_N : WOpInst<"vdup_n", "ds",
- "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUldQdPlQPl",
- OP_DUP>;
-def MOV_N : WOpInst<"vmov_n", "ds",
- "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUldQd",
- OP_DUP>;
+def DUP_N : WOpInst<"vdup_n", "ds", "dQdPlQPl", OP_DUP>;
+def MOV_N : WOpInst<"vmov_n", "ds", "dQd", OP_DUP>;
////////////////////////////////////////////////////////////////////////////////
-// Combining vectors, with additional Pl
-def COMBINE : NoTestOpInst<"vcombine", "kdd", "csilhfdUcUsUiUlPcPsPl", OP_CONC>;
+def COMBINE : NoTestOpInst<"vcombine", "kdd", "dPl", OP_CONC>;
////////////////////////////////////////////////////////////////////////////////
-//Initialize a vector from bit pattern, with additional Pl
-def CREATE : NoTestOpInst<"vcreate", "dl", "csihfdUcUsUiUlPcPslPl", OP_CAST>;
+//Initialize a vector from bit pattern
+def CREATE : NoTestOpInst<"vcreate", "dl", "dPl", OP_CAST>;
////////////////////////////////////////////////////////////////////////////////
@@ -901,7 +849,9 @@
"siUsUifQsQiQUsQUiQf", OP_MLS_LN>;
def VFMA_LANE : IInst<"vfma_lane", "dddgi", "fdQfQd">;
-def VFMA_LANEQ : IInst<"vfma_laneq", "dddji", "fdQfQd">;
+def VFMA_LANEQ : IInst<"vfma_laneq", "dddji", "fdQfQd"> {
+ let isLaneQ = 1;
+}
def VFMS_LANE : IOpInst<"vfms_lane", "dddgi", "fdQfQd", OP_FMS_LN>;
def VFMS_LANEQ : IOpInst<"vfms_laneq", "dddji", "fdQfQd", OP_FMS_LNQ>;
@@ -933,7 +883,7 @@
// Note: d type is handled by SCALAR_VMUL_LANEQ
def VMUL_LANEQ : IOpInst<"vmul_laneq", "ddji",
- "sifUsUiQsQiQfQUsQUiQfQd", OP_MUL_LN>;
+ "sifUsUiQsQiQUsQUiQfQd", OP_MUL_LN>;
def VMULL_LANEQ : SOpInst<"vmull_laneq", "wdki", "siUsUi", OP_MULL_LN>;
def VMULL_HIGH_LANE : SOpInst<"vmull_high_lane", "wkdi", "siUsUi",
OP_MULLHi_LN>;
@@ -965,12 +915,11 @@
////////////////////////////////////////////////////////////////////////////////
// Newly added Vector Extract for f64
-def VEXT_A64 : WInst<"vext", "dddi",
- "cUcPcsUsPsiUilUlfdQcQUcQPcQsQUsQPsQiQUiQlQUlQfQdPlQPl">;
+def VEXT_A64 : WInst<"vext", "dddi", "dQdPlQPl">;
////////////////////////////////////////////////////////////////////////////////
// Crypto
-let isCrypto = 1 in {
+let ArchGuard = "__ARM_FEATURE_CRYPTO" in {
def AESE : SInst<"vaese", "ddd", "QUc">;
def AESD : SInst<"vaesd", "ddd", "QUc">;
def AESMC : SInst<"vaesmc", "dd", "QUc">;
@@ -990,6 +939,31 @@
}
////////////////////////////////////////////////////////////////////////////////
+// Float -> Int conversions with explicit rounding mode
+
+let ArchGuard = "__ARM_ARCH >= 8" in {
+def FCVTNS_S32 : SInst<"vcvtn_s32", "xd", "fQf">;
+def FCVTNU_S32 : SInst<"vcvtn_u32", "ud", "fQf">;
+def FCVTPS_S32 : SInst<"vcvtp_s32", "xd", "fQf">;
+def FCVTPU_S32 : SInst<"vcvtp_u32", "ud", "fQf">;
+def FCVTMS_S32 : SInst<"vcvtm_s32", "xd", "fQf">;
+def FCVTMU_S32 : SInst<"vcvtm_u32", "ud", "fQf">;
+def FCVTAS_S32 : SInst<"vcvta_s32", "xd", "fQf">;
+def FCVTAU_S32 : SInst<"vcvta_u32", "ud", "fQf">;
+}
+
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)" in {
+def FCVTNS_S64 : SInst<"vcvtn_s64", "xd", "dQd">;
+def FCVTNU_S64 : SInst<"vcvtn_u64", "ud", "dQd">;
+def FCVTPS_S64 : SInst<"vcvtp_s64", "xd", "dQd">;
+def FCVTPU_S64 : SInst<"vcvtp_u64", "ud", "dQd">;
+def FCVTMS_S64 : SInst<"vcvtm_s64", "xd", "dQd">;
+def FCVTMU_S64 : SInst<"vcvtm_u64", "ud", "dQd">;
+def FCVTAS_S64 : SInst<"vcvta_s64", "xd", "dQd">;
+def FCVTAU_S64 : SInst<"vcvta_u64", "ud", "dQd">;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Permutation
def VTRN1 : SOpInst<"vtrn1", "ddd",
"csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_TRN1>;
@@ -1021,10 +995,17 @@
////////////////////////////////////////////////////////////////////////////////
// Vector reinterpret cast operations
-// With additional d, Qd, pl, Qpl types
-def REINTERPRET
+
+// NeonEmitter implicitly takes the cartesian product of the type string with
+// itself during generation so, unlike all other intrinsics, this one should
+// include *all* types, not just additional ones.
+//
+// We also rely on NeonEmitter handling the 32-bit vreinterpret before the
+// 64-bit one so that the common casts don't get guarded as AArch64-only
+// (FIXME).
+def VVREINTERPRET
: NoTestOpInst<"vreinterpret", "dd",
- "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPl", OP_REINT>;
+ "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", OP_REINT>;
////////////////////////////////////////////////////////////////////////////////
@@ -1042,10 +1023,8 @@
def SCALAR_QSUB : SInst<"vqsub", "sss", "ScSsSiSlSUcSUsSUiSUl">;
let InstName = "vmov" in {
-def VGET_HIGH_A64 : NoTestOpInst<"vget_high", "dk", "csilhfdUcUsUiUlPcPsPl",
- OP_HI>;
-def VGET_LOW_A64 : NoTestOpInst<"vget_low", "dk", "csilhfdUcUsUiUlPcPsPl",
- OP_LO>;
+def VGET_HIGH_A64 : NoTestOpInst<"vget_high", "dk", "dPl", OP_HI>;
+def VGET_LOW_A64 : NoTestOpInst<"vget_low", "dk", "dPl", OP_LO>;
}
////////////////////////////////////////////////////////////////////////////////
@@ -1294,7 +1273,9 @@
def SCALAR_VMUL_LANE : IInst<"vmul_lane", "ddgi", "d">;
// VMUL_LANEQ d type implemented using scalar mul lane
-def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "ddji", "d">;
+def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "ddji", "d"> {
+ let isLaneQ = 1;
+}
// VMULX_LANE d type implemented using scalar vmulx_lane
def SCALAR_VMULX_LANE : IOpInst<"vmulx_lane", "ddgi", "d", OP_SCALAR_VMULX_LN>;
diff --git a/include/clang/CMakeLists.txt b/include/clang/CMakeLists.txt
index 71c37fd..1d8aecd 100644
--- a/include/clang/CMakeLists.txt
+++ b/include/clang/CMakeLists.txt
@@ -1,7 +1,6 @@
add_subdirectory(AST)
add_subdirectory(Basic)
add_subdirectory(Driver)
-add_subdirectory(Lex)
add_subdirectory(Parse)
add_subdirectory(Sema)
add_subdirectory(Serialization)
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
index 135b6a9..f8b90b3 100644
--- a/include/clang/CodeGen/BackendUtil.h
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -21,7 +21,7 @@
class CodeGenOptions;
class TargetOptions;
class LangOptions;
-
+
enum BackendAction {
Backend_EmitAssembly, ///< Emit native assembly files
Backend_EmitBC, ///< Emit LLVM bitcode files
@@ -30,11 +30,11 @@
Backend_EmitMCNull, ///< Run CodeGen, but don't emit anything
Backend_EmitObj ///< Emit native object files
};
-
+
void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
const TargetOptions &TOpts, const LangOptions &LOpts,
- llvm::Module *M,
- BackendAction Action, raw_ostream *OS);
+ StringRef TDesc, llvm::Module *M, BackendAction Action,
+ raw_ostream *OS);
}
#endif
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index 96da0e9..e4a9272 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -19,14 +19,16 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/FoldingSet.h"
-
#include <cassert>
namespace llvm {
class Type;
+ class StructType;
}
namespace clang {
+class Decl;
+
namespace CodeGen {
/// ABIArgInfo - Helper class to encapsulate information about how a
@@ -60,7 +62,15 @@
/// are all scalar types or are themselves expandable types.
Expand,
- KindFirst=Direct, KindLast=Expand
+ /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
+ /// This is similar to 'direct', except it only applies to arguments stored
+ /// in memory and forbids any implicit copies. When applied to a return
+ /// type, it means the value is returned indirectly via an implicit sret
+ /// parameter stored in the argument struct.
+ InAlloca,
+
+ KindFirst = Direct,
+ KindLast = InAlloca
};
private:
@@ -103,6 +113,9 @@
return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false,
Padding);
}
+ 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);
@@ -118,6 +131,7 @@
Kind getKind() const { return TheKind; }
bool isDirect() const { return TheKind == Direct; }
+ bool isInAlloca() const { return TheKind == InAlloca; }
bool isExtend() const { return TheKind == Extend; }
bool isIgnore() const { return TheKind == Ignore; }
bool isIndirect() const { return TheKind == Indirect; }
@@ -172,6 +186,23 @@
return BoolData1;
}
+ unsigned getInAllocaFieldIndex() const {
+ assert(TheKind == InAlloca && "Invalid kind!");
+ return UIntData;
+ }
+
+ /// \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;
+ }
+
+ void setInAllocaSRet(bool SRet) {
+ assert(TheKind == InAlloca && "Invalid kind!");
+ BoolData0 = SRet;
+ }
+
void dump() const;
};
@@ -195,7 +226,7 @@
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
unsigned additional) {
if (!prototype->isVariadic()) return All;
- return RequiredArgs(prototype->getNumArgs() + additional);
+ return RequiredArgs(prototype->getNumParams() + additional);
}
static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
@@ -243,6 +274,9 @@
/// The clang::CallingConv that this was originally created with.
unsigned ASTCallingConvention : 8;
+ /// Whether this is an instance method.
+ unsigned InstanceMethod : 1;
+
/// Whether this function is noreturn.
unsigned NoReturn : 1;
@@ -255,6 +289,10 @@
RequiredArgs Required;
+ /// The struct representing all arguments passed in memory. Only used when
+ /// passing non-trivial types with inalloca. Not part of the profile.
+ llvm::StructType *ArgStruct;
+
unsigned NumArgs;
ArgInfo *getArgsBuffer() {
return reinterpret_cast<ArgInfo*>(this+1);
@@ -267,6 +305,7 @@
public:
static CGFunctionInfo *create(unsigned llvmCC,
+ bool InstanceMethod,
const FunctionType::ExtInfo &extInfo,
CanQualType resultType,
ArrayRef<CanQualType> argTypes,
@@ -275,6 +314,14 @@
typedef const ArgInfo *const_arg_iterator;
typedef ArgInfo *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());
+ }
+
const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
arg_iterator arg_begin() { return getArgsBuffer() + 1; }
@@ -285,6 +332,8 @@
bool isVariadic() const { return Required.allowsOptionalArgs(); }
RequiredArgs getRequiredArgs() const { return Required; }
+ bool isInstanceMethod() const { return InstanceMethod; }
+
bool isNoReturn() const { return NoReturn; }
/// In ARC, whether this function retains its return value. This
@@ -325,23 +374,33 @@
ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
+ /// \brief Return true if this function uses inalloca arguments.
+ bool usesInAlloca() const { return ArgStruct; }
+
+ /// \brief Get the struct type used to represent all the arguments in memory.
+ llvm::StructType *getArgStruct() const { return ArgStruct; }
+ void setArgStruct(llvm::StructType *Ty) { ArgStruct = Ty; }
+
void Profile(llvm::FoldingSetNodeID &ID) {
ID.AddInteger(getASTCallingConvention());
+ ID.AddBoolean(InstanceMethod);
ID.AddBoolean(NoReturn);
ID.AddBoolean(ReturnsRetained);
ID.AddBoolean(HasRegParm);
ID.AddInteger(RegParm);
ID.AddInteger(Required.getOpaqueData());
getReturnType().Profile(ID);
- for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it)
- it->type.Profile(ID);
+ for (const auto &I : arguments())
+ I.type.Profile(ID);
}
static void Profile(llvm::FoldingSetNodeID &ID,
+ bool InstanceMethod,
const FunctionType::ExtInfo &info,
RequiredArgs required,
CanQualType resultType,
ArrayRef<CanQualType> argTypes) {
ID.AddInteger(info.getCC());
+ ID.AddBoolean(InstanceMethod);
ID.AddBoolean(info.getNoReturn());
ID.AddBoolean(info.getProducesResult());
ID.AddBoolean(info.getHasRegParm());
diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h
index 81e2cdc..90c7494 100644
--- a/include/clang/CodeGen/CodeGenABITypes.h
+++ b/include/clang/CodeGen/CodeGenABITypes.h
@@ -47,10 +47,7 @@
class CodeGenABITypes
{
public:
- CodeGenABITypes(ASTContext &C, const CodeGenOptions &CodeGenOpts,
- llvm::Module &M, const llvm::DataLayout &TD,
- DiagnosticsEngine &Diags);
-
+ CodeGenABITypes(ASTContext &C, llvm::Module &M, const llvm::DataLayout &TD);
~CodeGenABITypes();
/// These methods all forward to methods in the private implementation class
@@ -65,12 +62,18 @@
CanQual<FunctionNoProtoType> Ty);
const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,
const FunctionProtoType *FTP);
- const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType,
+ const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType,
llvm::ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args);
private:
+ /// Default CodeGenOptions object used to initialize the
+ /// CodeGenModule and otherwise not used. More specifically, it is
+ /// not used in ABI type generation, so none of the options matter.
+ CodeGenOptions *CGO;
+
+ /// The CodeGenModule we use get to the CodeGenTypes object.
CodeGen::CodeGenModule *CGM;
};
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
index 912ef01..2300d29 100644
--- a/include/clang/CodeGen/CodeGenAction.h
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -11,7 +11,7 @@
#define LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
#include "clang/Frontend/FrontendAction.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
namespace llvm {
class LLVMContext;
@@ -24,7 +24,7 @@
class CodeGenAction : public ASTFrontendAction {
private:
unsigned Act;
- OwningPtr<llvm::Module> TheModule;
+ std::unique_ptr<llvm::Module> TheModule;
llvm::Module *LinkModule;
llvm::LLVMContext *VMContext;
bool OwnsVMContext;
@@ -35,14 +35,14 @@
/// otherwise it creates a fresh LLVM context and takes ownership.
CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = 0);
- virtual bool hasIRSupport() const;
+ bool hasIRSupport() const override;
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
- virtual void ExecuteAction();
+ void ExecuteAction() override;
- virtual void EndSourceFileAction();
+ void EndSourceFileAction() override;
public:
~CodeGenAction();
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index 289dbe3..2cdb581 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -50,10 +50,11 @@
LinkJobClass,
LipoJobClass,
DsymutilJobClass,
- VerifyJobClass,
+ VerifyDebugInfoJobClass,
+ VerifyPCHJobClass,
JobClassFirst=PreprocessJobClass,
- JobClassLast=VerifyJobClass
+ JobClassLast=VerifyPCHJobClass
};
static const char *getClassName(ActionClass AC);
@@ -141,7 +142,7 @@
};
class PreprocessJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
PreprocessJobAction(Action *Input, types::ID OutputType);
@@ -151,7 +152,7 @@
};
class PrecompileJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
PrecompileJobAction(Action *Input, types::ID OutputType);
@@ -161,7 +162,7 @@
};
class AnalyzeJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
AnalyzeJobAction(Action *Input, types::ID OutputType);
@@ -171,7 +172,7 @@
};
class MigrateJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
MigrateJobAction(Action *Input, types::ID OutputType);
@@ -181,7 +182,7 @@
};
class CompileJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
CompileJobAction(Action *Input, types::ID OutputType);
@@ -191,7 +192,7 @@
};
class AssembleJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
AssembleJobAction(Action *Input, types::ID OutputType);
@@ -201,7 +202,7 @@
};
class LinkJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
LinkJobAction(ActionList &Inputs, types::ID Type);
@@ -211,7 +212,7 @@
};
class LipoJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
LipoJobAction(ActionList &Inputs, types::ID Type);
@@ -221,7 +222,7 @@
};
class DsymutilJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
DsymutilJobAction(ActionList &Inputs, types::ID Type);
@@ -231,11 +232,31 @@
};
class VerifyJobAction : public JobAction {
- virtual void anchor();
+ void anchor() override;
public:
- VerifyJobAction(ActionList &Inputs, types::ID Type);
+ VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
+ VerifyJobAction(ActionClass Kind, ActionList &Inputs, types::ID Type);
static bool classof(const Action *A) {
- return A->getKind() == VerifyJobClass;
+ return A->getKind() == VerifyDebugInfoJobClass ||
+ A->getKind() == VerifyPCHJobClass;
+ }
+};
+
+class VerifyDebugInfoJobAction : public VerifyJobAction {
+ void anchor() override;
+public:
+ VerifyDebugInfoJobAction(Action *Input, types::ID Type);
+ static bool classof(const Action *A) {
+ return A->getKind() == VerifyDebugInfoJobClass;
+ }
+};
+
+class VerifyPCHJobAction : public VerifyJobAction {
+ void anchor() override;
+public:
+ VerifyPCHJobAction(Action *Input, types::ID Type);
+ static bool classof(const Action *A) {
+ return A->getKind() == VerifyPCHJobClass;
}
};
diff --git a/include/clang/Driver/CC1AsOptions.td b/include/clang/Driver/CC1AsOptions.td
index b536724..3e130d0 100644
--- a/include/clang/Driver/CC1AsOptions.td
+++ b/include/clang/Driver/CC1AsOptions.td
@@ -83,6 +83,9 @@
def mno_exec_stack : Flag<["-"], "mnoexecstack">,
HelpText<"Mark the file as not needing an executable stack">;
+def compress_debug_sections : Flag<["-"], "compress-debug-sections">,
+ HelpText<"Compress DWARF debug sections using zlib">;
+
def g : Flag<["-"], "g">, HelpText<"Generate source level debug information">;
def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
diff --git a/include/clang/Driver/CC1Options.h b/include/clang/Driver/CC1Options.h
deleted file mode 100644
index e69de29..0000000
--- a/include/clang/Driver/CC1Options.h
+++ /dev/null
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 85cfdcf..e84a20b 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -17,8 +17,6 @@
// Target Options
//===----------------------------------------------------------------------===//
-def cxx_abi : Separate<["-"], "cxx-abi">,
- HelpText<"Target a particular C++ ABI type">;
def target_abi : Separate<["-"], "target-abi">,
HelpText<"Target a particular ABI type">;
def target_cpu : Separate<["-"], "target-cpu">,
@@ -140,6 +138,8 @@
HelpText<"Split out the dwarf .dwo sections">;
def gnu_pubnames : Flag<["-"], "gnu-pubnames">,
HelpText<"Emit newer GNU style pubnames">;
+def arange_sections : Flag<["-"], "arange_sections">,
+ HelpText<"Emit DWARF .debug_arange sections">;
def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">,
HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
def no_implicit_float : Flag<["-"], "no-implicit-float">,
@@ -190,6 +190,8 @@
HelpText<"Limit float precision to the given value">;
def mno_exec_stack : Flag<["-"], "mnoexecstack">,
HelpText<"Mark the file as not needing an executable stack">;
+def compress_debug_sections : Flag<["-"], "compress-debug-sections">,
+ HelpText<"Compress DWARF debug sections using zlib">;
def split_stacks : Flag<["-"], "split-stacks">,
HelpText<"Try to use a split stack if possible.">;
def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">,
@@ -223,6 +225,8 @@
def sys_header_deps : Flag<["-"], "sys-header-deps">,
HelpText<"Include system headers in dependency output">;
+def module_file_deps : Flag<["-"], "module-file-deps">,
+ HelpText<"Include module files in dependency output">;
def header_include_file : Separate<["-"], "header-include-file">,
HelpText<"Filename (or -) to write header include output to">;
def show_includes : Flag<["--"], "show-includes">,
@@ -256,6 +260,8 @@
HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">;
def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">,
HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
+def verify : Flag<["-"], "verify">,
+ HelpText<"Verify diagnostic output using comment directives">;
def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">,
HelpText<"Silence ObjC rewriting warnings">;
@@ -397,8 +403,6 @@
HelpText<"Weakly link in the blocks runtime">;
def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">,
HelpText<"Use SjLj style exceptions">;
-def fhidden_weak_vtables : Flag<["-"], "fhidden-weak-vtables">,
- HelpText<"Generate weak vtables and RTTI with hidden visibility">;
def main_file_name : Separate<["-"], "main-file-name">,
HelpText<"Main file name to use for debug info">;
def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
@@ -476,6 +480,8 @@
HelpText<"Enable C++1y sized global deallocation functions">;
def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">,
HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">;
+def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
+ HelpText<"Control vtordisp placement on win32 targets">;
//===----------------------------------------------------------------------===//
// Header Search Options
@@ -504,14 +510,6 @@
"implicit extern \"C\" semantics; these are assumed to not be "
"user-provided and are used to model system and standard headers' "
"paths.">;
-def isystem_prefix : JoinedOrSeparate<["-"], "isystem-prefix">,
- MetaVarName<"<prefix>">,
- HelpText<"Treat all #include paths starting with <prefix> as including a "
- "system header.">;
-def ino_system_prefix : JoinedOrSeparate<["-"], "ino-system-prefix">,
- MetaVarName<"<prefix>">,
- HelpText<"Treat all #include paths starting with <prefix> as not including a "
- "system header.">;
//===----------------------------------------------------------------------===//
// Preprocessor Options
@@ -539,6 +537,8 @@
HelpText<"OpenCL only. Treat double precision floating-point constant as single precision constant.">;
def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">,
HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">;
+def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">,
+ HelpText<"OpenCL only. Generate kernel argument metadata.">;
def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">,
HelpText<"OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable">;
def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">,
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index d17a63c..d33e6b6 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -57,10 +57,15 @@
def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>;
def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">,
MetaVarName<"<macro[=value]>">, Alias<D>;
+def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>;
def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable RTTI">, Alias<frtti>;
def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable RTTI">, Alias<fno_rtti>;
def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">,
Alias<fwritable_strings>;
+def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">,
+ Alias<ffunction_sections>;
+def _SLASH_Gy_ : CLFlag<"Gy-">, HelpText<"Don't put each function in its own section">,
+ Alias<fno_function_sections>;
def _SLASH_help : CLFlag<"help">, Alias<help>,
HelpText<"Display available options">;
def _SLASH_HELP : CLFlag<"HELP">, Alias<help>;
@@ -88,7 +93,6 @@
Alias<fomit_frame_pointer>;
def _SLASH_Oy_ : CLFlag<"Oy-">, HelpText<"Disable frame pointer omission">,
Alias<fno_omit_frame_pointer>;
-def _SLASH_P : CLFlag<"P">, HelpText<"Only run the preprocessor">, Alias<E>;
def _SLASH_QUESTION : CLFlag<"?">, Alias<help>,
HelpText<"Display available options">;
def _SLASH_showIncludes : CLFlag<"showIncludes">,
@@ -96,6 +100,16 @@
Alias<show_includes>;
def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">,
MetaVarName<"<macro>">, Alias<U>;
+def _SLASH_vmb : CLFlag<"vmb">,
+ HelpText<"Use a best-case representation method for member pointers">;
+def _SLASH_vmg : CLFlag<"vmg">,
+ HelpText<"Use a most-general representation for member pointers">;
+def _SLASH_vms : CLFlag<"vms">,
+ HelpText<"Set the default most-general representation to single inheritance">;
+def _SLASH_vmm : CLFlag<"vmm">,
+ HelpText<"Set the default most-general representation to multiple inheritance">;
+def _SLASH_vmv : CLFlag<"vmv">,
+ HelpText<"Set the default most-general representation to virtual inheritance">;
def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>;
def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>;
def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>;
@@ -107,6 +121,11 @@
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_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">,
+ Alias<vtordisp_mode_EQ>;
+def _SLASH_Z7 : CLFlag<"Z7">, Alias<gline_tables_only>;
+def _SLASH_Zi : CLFlag<"Zi">, HelpText<"Enable debug information">,
+ Alias<gline_tables_only>;
def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">,
Alias<fsyntax_only>;
@@ -142,6 +161,7 @@
Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">;
def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>,
Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">;
+def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">;
def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">,
HelpText<"Specify a C source file">, MetaVarName<"<filename>">;
def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">;
@@ -164,7 +184,6 @@
def _SLASH_RTC : CLIgnoredJoined<"RTC">;
def _SLASH_sdl : CLIgnoredFlag<"sdl">;
def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
-def _SLASH_vmg : CLIgnoredFlag<"vmg">;
def _SLASH_w : CLIgnoredJoined<"w">;
def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
@@ -177,8 +196,8 @@
def _SLASH_arch : CLJoined<"arch:">;
def _SLASH_bigobj : CLFlag<"bigobj">;
def _SLASH_clr : CLJoined<"clr">;
+def _SLASH_d2Zi_PLUS : CLFlag<"d2Zi+">;
def _SLASH_doc : CLJoined<"doc">;
-def _SLASH_E : CLFlag<"E">;
def _SLASH_EH : CLJoined<"EH">;
def _SLASH_EP : CLFlag<"EP">;
def _SLASH_FA_joined : CLJoined<"FA">;
@@ -210,8 +229,6 @@
def _SLASH_Gs : CLJoined<"Gs">;
def _SLASH_GT : CLFlag<"GT">;
def _SLASH_GX : CLFlag<"GX">;
-def _SLASH_Gy : CLFlag<"Gy">;
-def _SLASH_Gy_ : CLFlag<"Gy-">;
def _SLASH_Gz : CLFlag<"Gz">;
def _SLASH_GZ : CLFlag<"GZ">;
def _SLASH_H : CLFlag<"H">;
@@ -229,11 +246,6 @@
def _SLASH_Qvec_report : CLJoined<"Qvec-report">;
def _SLASH_u : CLFlag<"u">;
def _SLASH_V : CLFlag<"V">;
-def _SLASH_vd : CLJoined<"vd">;
-def _SLASH_vmb : CLFlag<"vmb">;
-def _SLASH_vmm : CLFlag<"vmm">;
-def _SLASH_vms : CLFlag<"vms">;
-def _SLASH_vmv : CLFlag<"vmv">;
def _SLASH_volatile : CLFlag<"volatile">;
def _SLASH_WL : CLFlag<"WL">;
def _SLASH_Wp64 : CLFlag<"Wp64">;
@@ -243,13 +255,11 @@
def _SLASH_Yd : CLFlag<"Yd">;
def _SLASH_Yl : CLJoined<"Yl">;
def _SLASH_Yu : CLJoined<"Yu">;
-def _SLASH_Z7 : CLFlag<"Z7">;
def _SLASH_Za : CLFlag<"Za">;
def _SLASH_Zc : CLJoined<"Zc:">;
def _SLASH_Ze : CLFlag<"Ze">;
def _SLASH_Zg : CLFlag<"Zg">;
-def _SLASH_Zi : CLFlag<"Zi">;
def _SLASH_ZI : CLFlag<"ZI">;
def _SLASH_Zl : CLFlag<"Zl">;
-def _SLASH_Zp : CLFlag<"Zp">;
+def _SLASH_Zp : CLJoined<"Zp">;
def _SLASH_ZW : CLJoined<"ZW">;
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 867444e..0448725 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -15,11 +15,11 @@
#include "clang/Driver/Phases.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Path.h" // FIXME: Kill when CompilationInfo
+#include <memory>
// lands.
#include <list>
#include <set>
@@ -415,6 +415,10 @@
bool &HadExtra);
};
+/// \return True if the last defined optimization level is -Ofast.
+/// And False otherwise.
+bool isOptimizationLevelFast(const llvm::opt::ArgList &Args);
+
} // end namespace driver
} // end namespace clang
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 1dd49a7..5b19efe 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -11,9 +11,9 @@
#define CLANG_DRIVER_JOB_H_
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Option/Option.h"
+#include <memory>
namespace llvm {
class raw_ostream;
@@ -76,8 +76,8 @@
Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
const llvm::opt::ArgStringList &_Arguments);
- virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
- bool Quote, bool CrashReport = false) const;
+ void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+ bool CrashReport = false) const override;
virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const;
@@ -88,6 +88,8 @@
/// getCreator - Return the Tool which caused the creation of this job.
const Tool &getCreator() const { return Creator; }
+ const char *getExecutable() const { return Executable; }
+
const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
static bool classof(const Job *J) {
@@ -104,18 +106,18 @@
const char *Executable_, const ArgStringList &Arguments_,
Command *Fallback_);
- virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
- bool Quote, bool CrashReport = false) const;
+ void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+ bool CrashReport = false) const override;
- virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
- bool *ExecutionFailed) const;
+ int Execute(const StringRef **Redirects, std::string *ErrMsg,
+ bool *ExecutionFailed) const override;
static bool classof(const Job *J) {
return J->getKind() == FallbackCommandClass;
}
private:
- OwningPtr<Command> Fallback;
+ std::unique_ptr<Command> Fallback;
};
/// JobList - A sequence of jobs to perform.
@@ -133,8 +135,8 @@
JobList();
virtual ~JobList();
- virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
- bool Quote, bool CrashReport = false) const;
+ void Print(llvm::raw_ostream &OS, const char *Terminator,
+ bool Quote, bool CrashReport = false) const override;
/// Add a job to the list (taking ownership).
void addJob(Job *J) { Jobs.push_back(J); }
diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h
new file mode 100644
index 0000000..6c3738a
--- /dev/null
+++ b/include/clang/Driver/Multilib.h
@@ -0,0 +1,167 @@
+//===--- Multilib.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_DRIVER_MULTILIB_H_
+#define CLANG_LIB_DRIVER_MULTILIB_H_
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+
+/// This corresponds to a single GCC Multilib, or a segment of one controlled
+/// by a command line flag
+class Multilib {
+public:
+ typedef std::vector<std::string> flags_list;
+
+private:
+ std::string GCCSuffix;
+ std::string OSSuffix;
+ std::string IncludeSuffix;
+ flags_list Flags;
+
+public:
+ Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "",
+ StringRef IncludeSuffix = "");
+
+ /// \brief Get the detected GCC installation path suffix for the multi-arch
+ /// target variant. Always starts with a '/', unless empty
+ const std::string &gccSuffix() const {
+ assert(GCCSuffix.empty() ||
+ (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
+ return GCCSuffix;
+ }
+ /// Set the GCC installation path suffix.
+ Multilib &gccSuffix(StringRef S);
+
+ /// \brief Get the detected os path suffix for the multi-arch
+ /// target variant. Always starts with a '/', unless empty
+ const std::string &osSuffix() const {
+ assert(OSSuffix.empty() ||
+ (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
+ return OSSuffix;
+ }
+ /// Set the os path suffix.
+ Multilib &osSuffix(StringRef S);
+
+ /// \brief Get the include directory suffix. Always starts with a '/', unless
+ /// empty
+ const std::string &includeSuffix() const {
+ assert(IncludeSuffix.empty() ||
+ (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
+ return IncludeSuffix;
+ }
+ /// Set the include directory suffix
+ Multilib &includeSuffix(StringRef S);
+
+ /// \brief Get the flags that indicate or contraindicate this multilib's use
+ /// All elements begin with either '+' or '-'
+ const flags_list &flags() const { return Flags; }
+ flags_list &flags() { return Flags; }
+ /// Add a flag to the flags list
+ Multilib &flag(StringRef F) {
+ assert(F.front() == '+' || F.front() == '-');
+ Flags.push_back(F);
+ return *this;
+ }
+
+ /// \brief print summary of the Multilib
+ void print(raw_ostream &OS) const;
+
+ /// Check whether any of the 'against' flags contradict the 'for' flags.
+ bool isValid() const;
+
+ /// Check whether the default is selected
+ bool isDefault() const
+ { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
+
+ bool operator==(const Multilib &Other) const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
+
+class MultilibSet {
+public:
+ typedef std::vector<Multilib> multilib_list;
+ typedef multilib_list::iterator iterator;
+ typedef multilib_list::const_iterator const_iterator;
+
+ struct FilterCallback {
+ virtual ~FilterCallback() {};
+ /// \return true iff the filter should remove the Multilib from the set
+ virtual bool operator()(const Multilib &M) const = 0;
+ };
+
+private:
+ multilib_list Multilibs;
+
+public:
+ MultilibSet() {}
+
+ /// Add an optional Multilib segment
+ MultilibSet &Maybe(const Multilib &M);
+
+ /// Add a set of mutually incompatible Multilib segments
+ MultilibSet &Either(const Multilib &M1, const Multilib &M2);
+ MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+ const Multilib &M3);
+ MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+ const Multilib &M3, const Multilib &M4);
+ MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+ const Multilib &M3, const Multilib &M4,
+ const Multilib &M5);
+ MultilibSet &Either(const std::vector<Multilib> &Ms);
+
+ /// Filter out some subset of the Multilibs using a user defined callback
+ MultilibSet &FilterOut(const FilterCallback &F);
+ /// Filter out those Multilibs whose gccSuffix matches the given expression
+ MultilibSet &FilterOut(std::string Regex);
+
+ /// Add a completed Multilib to the set
+ void push_back(const Multilib &M);
+
+ /// Union this set of multilibs with another
+ void combineWith(const MultilibSet &MS);
+
+ /// Remove all of thie multilibs from the set
+ void clear() { Multilibs.clear(); }
+
+ iterator begin() { return Multilibs.begin(); }
+ const_iterator begin() const { return Multilibs.begin(); }
+
+ iterator end() { return Multilibs.end(); }
+ const_iterator end() const { return Multilibs.end(); }
+
+ /// Pick the best multilib in the set, \returns false if none are compatible
+ bool select(const Multilib::flags_list &Flags, Multilib &M) const;
+
+ unsigned size() const { return Multilibs.size(); }
+
+ void print(raw_ostream &OS) const;
+
+private:
+ /// Apply the filter to Multilibs and return the subset that remains
+ static multilib_list filterCopy(const FilterCallback &F,
+ const multilib_list &Ms);
+
+ /// Apply the filter to the multilib_list, removing those that don't match
+ static void filterInPlace(const FilterCallback &F, multilib_list &Ms);
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
+}
+}
+
+#endif
+
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 9e7dc78..33e058f 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -72,8 +72,8 @@
def m_x86_Features_Group : OptionGroup<"<m x86 features group>">, Group<m_Group>;
def m_hexagon_Features_Group : OptionGroup<"<m hexagon features group>">, Group<m_Group>;
def m_arm_Features_Group : OptionGroup<"<m arm features group>">, Group<m_Group>;
+def m_aarch64_Features_Group : OptionGroup<"<m aarch64 features group>">, Group<m_Group>;
def m_ppc_Features_Group : OptionGroup<"<m ppc features group>">, Group<m_Group>;
-def opencl_Group : OptionGroup<"<opencl group>">;
def u_Group : OptionGroup<"<u group>">;
def pedantic_Group : OptionGroup<"<pedantic group>">,
@@ -184,8 +184,13 @@
HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">;
def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>,
HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">;
-def objcmt_white_list_dir_path: Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>,
+def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, Flags<[CC1Option]>,
+ HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">;
+def objcmt_whitelist_dir_path: Joined<["-"], "objcmt-whitelist-dir-path=">, Flags<[CC1Option]>,
HelpText<"Only modify files with a filename contained in the provided directory path">;
+// The misspelt "white-list" [sic] alias is due for removal.
+def : Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>,
+ Alias<objcmt_whitelist_dir_path>;
// Make sure all other -ccc- options are rejected.
def ccc_ : Joined<["-"], "ccc-">, Group<internal_Group>, Flags<[Unsupported]>;
@@ -193,7 +198,7 @@
// Standard Options
def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[DriverOption, CoreOption]>,
- HelpText<"Print the commands to run for this compilation">;
+ HelpText<"Print (but do not run) the commands to run for this compilation">;
def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>,
Flags<[DriverOption, CoreOption]>;
def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>;
@@ -213,20 +218,26 @@
def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option]>,
HelpText<"Add directory to include search path">;
def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>;
-def MD : Flag<["-"], "MD">, Group<M_Group>;
-def MF : JoinedOrSeparate<["-"], "MF">, Group<M_Group>;
+def MD : Flag<["-"], "MD">, Group<M_Group>,
+ HelpText<"Write a depfile containing user and system headers">;
+def MMD : Flag<["-"], "MMD">, Group<M_Group>,
+ HelpText<"Write a depfile containing user headers">;
+def M : Flag<["-"], "M">, Group<M_Group>,
+ HelpText<"Like -MD, but also implies -E and writes to stdout by default">;
+def MM : Flag<["-"], "MM">, Group<M_Group>,
+ HelpText<"Like -MMD, but also implies -E and writes to stdout by default">;
+def MF : JoinedOrSeparate<["-"], "MF">, Group<M_Group>,
+ HelpText<"Write depfile output from -MMD, -MD, -MM, or -M to <file>">,
+ MetaVarName<"<file>">;
def MG : Flag<["-"], "MG">, Group<M_Group>, Flags<[CC1Option]>,
- HelpText<"Add missing headers to dependency list">;
-def MMD : Flag<["-"], "MMD">, Group<M_Group>;
-def MM : Flag<["-"], "MM">, Group<M_Group>;
+ HelpText<"Add missing headers to depfile">;
def MP : Flag<["-"], "MP">, Group<M_Group>, Flags<[CC1Option]>,
HelpText<"Create phony target for each dependency (other than main file)">;
def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>, Flags<[CC1Option]>,
- HelpText<"Specify target to quote for dependency">;
+ HelpText<"Specify name of main file output to quote in depfile">;
def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>,
- HelpText<"Specify target for dependency">;
+ HelpText<"Specify name of main file output in depfile">;
def Mach : Flag<["-"], "Mach">;
-def M : Flag<["-"], "M">, Group<M_Group>;
def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>;
def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>;
def ObjCXX : Flag<["-"], "ObjC++">, Flags<[DriverOption]>,
@@ -268,6 +279,8 @@
def Wp_COMMA : CommaJoined<["-"], "Wp,">,
HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
MetaVarName<"<arg>">;
+def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option]>;
+def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option]>;
def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
def Xanalyzer : Separate<["-"], "Xanalyzer">,
@@ -297,8 +310,6 @@
def bundle__loader : Separate<["-"], "bundle_loader">;
def bundle : Flag<["-"], "bundle">;
def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>;
-def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Flags<[CC1Option]>, Group<opencl_Group>,
-HelpText<"OpenCL only. This option allows the compiler to store information about the arguments of a kernel(s)"> ;
def client__name : JoinedOrSeparate<["-"], "client_name">;
def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>;
def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
@@ -346,10 +357,7 @@
HelpText<"Use Apple's kernel extensions ABI">;
def fapple_pragma_pack : Flag<["-"], "fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable Apple gcc-compatible #pragma pack handling">;
-def faddress_sanitizer : Flag<["-"], "faddress-sanitizer">, Group<f_Group>;
-def fno_address_sanitizer : Flag<["-"], "fno-address-sanitizer">, Group<f_Group>;
-def fthread_sanitizer : Flag<["-"], "fthread-sanitizer">, Group<f_Group>;
-def fno_thread_sanitizer : Flag<["-"], "fno-thread-sanitizer">, Group<f_Group>;
+def shared_libasan : Flag<["-"], "shared-libasan">;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]>;
@@ -369,19 +377,23 @@
def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">,
Group<f_Group>, Flags<[DriverOption, CC1Option]>,
HelpText<"Enable sample-based profile guided optimizations">;
+def fauto_profile_EQ : Joined<["-"], "fauto-profile=">,
+ Alias<fprofile_sample_use_EQ>;
+def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Generate instrumented code to collect execution counts">;
+def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>;
+def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Use instrumentation data for profile-guided optimization">;
def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable the 'blocks' language feature">;
def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
def fborland_extensions : Flag<["-"], "fborland-extensions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Accept non-standard constructs supported by the Borland compiler">;
-def fbounds_checking : Flag<["-"], "fbounds-checking">, Group<f_Group>,
- HelpText<"Enable run-time bounds checks">;
-def fbounds_checking_EQ : Joined<["-"], "fbounds-checking=">, Flags<[CC1Option]>,
- Group<f_Group>;
def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>;
def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
-def fcatch_undefined_behavior : Flag<["-"], "fcatch-undefined-behavior">, Group<f_Group>;
def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use colors in diagnostics">;
@@ -417,8 +429,6 @@
HelpText<"Print source range spans in numeric form">;
def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">;
-def fdiagnostics_show_name : Flag<["-"], "fdiagnostics-show-name">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Print diagnostic name">;
def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">,
Group<f_Group>, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">;
def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group<f_clang_Group>;
@@ -440,18 +450,14 @@
def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Emit all declarations, even if unused">;
def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
-def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>;
+def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable support for exception handling">;
-def fexpensive_optimizations : Flag<["-"], "fexpensive-optimizations">,
- Group<clang_ignored_f_Group>;
-def fno_expensive_optimizations : Flag<["-"], "fno-expensive-optimizations">,
- Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fno-expensive-optimizations">, Group<clang_ignored_f_Group>;
def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>;
-def fextended_identifiers : Flag<["-"], "fextended-identifiers">,
- Group<clang_ignored_f_Group>;
-def fno_extended_identifiers : Flag<["-"], "fno-extended-identifiers">,
- Group<f_Group>, Flags<[Unsupported]>;
+def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable the *frontend*'s 'fast-math' mode. This has no effect on "
@@ -470,23 +476,21 @@
"address (memory errors) | thread (race detection) | "
"undefined (miscellaneous undefined behavior)">;
def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>;
-def fsanitize_address_zero_base_shadow : Flag<["-"], "fsanitize-address-zero-base-shadow">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Make AddressSanitizer map shadow memory "
- "at zero offset">;
-def fno_sanitize_address_zero_base_shadow : Flag<["-"], "fno-sanitize-address-zero-base-shadow">,
- Group<f_clang_Group>;
def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Path to blacklist file for sanitizers">;
def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
Group<f_clang_Group>,
HelpText<"Don't use blacklist file for sanitizers">;
+def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable origins tracking in MemorySanitizer">;
def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Enable origins tracking in MemorySanitizer">;
def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
- Group<f_clang_Group>;
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Disable origins tracking in MemorySanitizer">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">,
Group<f_clang_Group>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
@@ -512,9 +516,9 @@
def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Group<f_Group>;
def fhonor_infinities : Flag<["-"], "fhonor-infinities">, Group<f_Group>;
def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<f_Group>;
-// Sic. This option was misspelled originally.
-def fhonor_infinites : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>;
-def fno_honor_infinites : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>;
+// This option was originally misspelt "infinites" [sic].
+def : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>;
+def : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>;
def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>;
def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>;
def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>,
@@ -539,16 +543,14 @@
HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>;
def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>;
-def findirect_virtual_calls : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
+def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_f_Group>;
def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Generate calls to instrument function entry and exit">;
-def fkeep_inline_functions : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>;
def flat__namespace : Flag<["-"], "flat_namespace">;
def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
-def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Limit debug information produced to reduce size of debug binary">;
def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
def flto : Flag<["-"], "flto">, Group<f_Group>;
def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>;
@@ -559,21 +561,35 @@
def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">;
def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Enable Microsoft compatibility mode">;
+ HelpText<"Enable full Microsoft Visual C++ compatibility">;
def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
- HelpText<"Version of the Microsoft C/C++ compiler to report in _MSC_VER (0 = don't define it (default))">;
+ HelpText<"Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))">;
def fdelayed_template_parsing : Flag<["-"], "fdelayed-template-parsing">, Group<f_Group>,
HelpText<"Parse templated function definitions at the end of the "
- "translation unit ">, Flags<[CC1Option]>;
+ "translation unit">, Flags<[CC1Option]>;
+def fms_memptr_rep_EQ : Joined<["-"], "fms-memptr-rep=">, Group<f_Group>, Flags<[CC1Option]>;
def fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group<i_Group>,
Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
HelpText<"Specify the module cache path">;
+def fmodules_user_build_path : Separate<["-"], "fmodules-user-build-path">, Group<i_Group>,
+ Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
+ HelpText<"Specify the module user build path">;
def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
Flags<[CC1Option]>, MetaVarName<"<seconds>">,
HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">;
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 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">;
+def fmodules_validate_once_per_build_session : Flag<["-"], "fmodules-validate-once-per-build-session">,
+ Group<i_Group>, Flags<[CC1Option]>,
+ HelpText<"Don't verify input files for the modules if the module has been "
+ "successfully validate or loaded during this build session">;
+def fmodules_validate_system_headers : Flag<["-"], "fmodules-validate-system-headers">,
+ Group<i_Group>, Flags<[CC1Option]>,
+ HelpText<"Validate the system headers that a module depends on when loading the module">;
def fmodules : Flag <["-"], "fmodules">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
HelpText<"Enable the 'modules' language feature">;
@@ -627,7 +643,6 @@
Flags<[DriverOption]>;
def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">;
-def fno_diagnostics_show_name : Flag<["-"], "fno-diagnostics-show-name">, Group<f_Group>;
def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>;
def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">,
Flags<[CC1Option]>, Group<f_Group>;
@@ -640,11 +655,9 @@
def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>;
def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>;
-def fno_keep_inline_functions : Flag<["-"], "fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">, Flags<[CC1Option]>;
-def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Do not limit debug information produced to reduce size of debug binary">;
def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Disallow merging of constants">;
def fno_modules : Flag <["-"], "fno-modules">, Group<f_Group>,
@@ -672,7 +685,8 @@
Flags<[CC1Option]>, HelpText<"Do not include source location information with diagnostics">;
def fno_spell_checking : Flag<["-"], "fno-spell-checking">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Disable spell-checking">;
-def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>;
+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 fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
@@ -726,7 +740,8 @@
def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
-def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option]>;
+def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
+def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>, Flags<[CC1Option]>;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
@@ -753,12 +768,14 @@
def freg_struct_return : Flag<["-"], "freg-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Override the default ABI to return small structs in registers">;
def frtti : Flag<["-"], "frtti">, Group<f_Group>;
-def fsched_interblock : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Allocate to an enum type only as many bytes as it needs for the declared range of possible values">;
-def freorder_blocks : Flag<["-"], "freorder-blocks">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "freorder-blocks">, Group<clang_ignored_f_Group>;
def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Force wchar_t to be a short unsigned int">;
+def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Force wchar_t to be an unsigned int">;
def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Which overload candidates to show when overload resolution fails: "
"best|all; defaults to all">;
@@ -770,8 +787,18 @@
def fno_signed_char : Flag<["-"], "fno-signed-char">, Flags<[CC1Option]>,
Group<clang_ignored_f_Group>, HelpText<"Char is unsigned">;
def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>;
-def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>;
-def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>;
+def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>,
+ HelpText<"Force the usage of stack protectors for all functions">;
+def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group<f_Group>,
+ HelpText<"Use a strong heuristic to apply stack protectors to functions">;
+def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>,
+ HelpText<"Enable stack protectors for functions potentially vulnerable to stack smashing">;
+def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Emit full debug info for all types used by the program">;
+def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CC1Option]>,
+ 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_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable optimizations based on the strict definition of an enum's "
@@ -789,16 +816,16 @@
def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
HelpText<"Enable the loop vectorization passes">;
def fno_vectorize : Flag<["-"], "fno-vectorize">, Group<f_Group>;
-def ftree_vectorize : Flag<["-"], "ftree-vectorize">, Alias<fvectorize>;
-def fno_tree_vectorize : Flag<["-"], "fno-tree-vectorize">, Alias<fno_vectorize>;
+def : Flag<["-"], "ftree-vectorize">, Alias<fvectorize>;
+def : Flag<["-"], "fno-tree-vectorize">, Alias<fno_vectorize>;
def fslp_vectorize : Flag<["-"], "fslp-vectorize">, Group<f_Group>,
HelpText<"Enable the superword-level parallelism vectorization passes">;
def fno_slp_vectorize : Flag<["-"], "fno-slp-vectorize">, Group<f_Group>;
def fslp_vectorize_aggressive : Flag<["-"], "fslp-vectorize-aggressive">, Group<f_Group>,
HelpText<"Enable the BB vectorization passes">;
def fno_slp_vectorize_aggressive : Flag<["-"], "fno-slp-vectorize-aggressive">, Group<f_Group>;
-def ftree_slp_vectorize : Flag<["-"], "ftree-slp-vectorize">, Alias<fslp_vectorize>;
-def fno_tree_slp_vectorize : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>;
+def : Flag<["-"], "ftree-slp-vectorize">, Alias<fslp_vectorize>;
+def : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>;
def Wlarge_by_value_copy_def : Flag<["-"], "Wlarge-by-value-copy">,
HelpText<"Warn if a function definition returns or accepts an object larger "
"in bytes than a given value">, Flags<[HelpHidden]>;
@@ -811,7 +838,7 @@
def Wframe_larger_than : Separate<["-"], "Wframe-larger-than">, Group<clang_ignored_f_Group>;
def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Alias<Wframe_larger_than>;
-def fterminated_vtables : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>;
+def : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>;
def fthreadsafe_statics : Flag<["-"], "fthreadsafe-statics">, Group<f_Group>;
def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>, Flags<[CC1Option]>;
def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group<f_Group>, Flags<[CC1Option]>;
@@ -866,10 +893,13 @@
Flags<[CC1Option]>;
def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
+def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
+ Flags<[CC1Option]>;
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
HelpText<"Generate source level debug information">, Flags<[CC1Option]>;
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<g_Group>,
HelpText<"Emit debug line number tables only">, Flags<[CC1Option]>;
+def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>;
def g0 : Flag<["-"], "g0">, Group<g_Group>;
def g1 : Flag<["-"], "g1">, Group<g_Group>;
def g2 : Flag<["-"], "g2">, Group<g_Group>;
@@ -900,6 +930,7 @@
def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>;
def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>;
+def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
def help : Flag<["-", "--"], "help">, Flags<[CC1Option]>,
HelpText<"Display available options">;
@@ -918,9 +949,10 @@
HelpText<"Include precompiled header file">, MetaVarName<"<file>">;
def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, Flags<[CC1Option]>,
HelpText<"Whether to build a relocatable precompiled header">;
+def verify_pch : Flag<["-"], "verify-pch">, Group<Action_Group>, Flags<[CC1Option]>,
+ HelpText<"Load and verify that a pre-compiled header file is not stale">;
def init : Separate<["-"], "init">;
def install__name : Separate<["-"], "install_name">;
-def integrated_as : Flag<["-"], "integrated-as">, Flags<[DriverOption]>;
def iprefix : JoinedOrSeparate<["-"], "iprefix">, Group<clang_i_Group>, Flags<[CC1Option]>,
HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">, MetaVarName<"<dir>">;
def iquote : JoinedOrSeparate<["-"], "iquote">, Group<clang_i_Group>, Flags<[CC1Option]>,
@@ -938,6 +970,8 @@
HelpText<"Add directory to SYSTEM include search path, "
"absolute paths are relative to -isysroot">, MetaVarName<"<directory>">,
Flags<[CC1Option]>;
+def ivfsoverlay : JoinedOrSeparate<["-"], "ivfsoverlay">, Group<clang_i_Group>, Flags<[CC1Option]>,
+ HelpText<"Overlay the virtual filesystem described by file over the real file system">;
def i : Joined<["-"], "i">, Group<i_Group>;
def keep__private__externs : Flag<["-"], "keep_private_externs">;
def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>;
@@ -945,6 +979,7 @@
def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>;
def EL : Flag<["-"], "EL">, Flags<[DriverOption]>;
def EB : Flag<["-"], "EB">, Flags<[DriverOption]>;
+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]>,
HelpText<"Enable hexagon-qdsp6 backward compatibility">;
@@ -1046,6 +1081,9 @@
def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
HelpText<"Disallow use of CRC instructions (ARM only)">;
+def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
+ HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
+
def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
def mfprnd : Flag<["-"], "mfprnd">, Group<m_ppc_Features_Group>;
@@ -1056,6 +1094,8 @@
def mno_popcntd : Flag<["-"], "mno-popcntd">, Group<m_ppc_Features_Group>;
def mqpx : Flag<["-"], "mqpx">, Group<m_ppc_Features_Group>;
def mno_qpx : Flag<["-"], "mno-qpx">, Group<m_ppc_Features_Group>;
+def mcrbits : Flag<["-"], "mcrbits">, Group<m_ppc_Features_Group>;
+def mno_crbits : Flag<["-"], "mno-crbits">, Group<m_ppc_Features_Group>;
def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable AltiVec vector initializer syntax">;
@@ -1160,7 +1200,6 @@
def no_canonical_prefixes : Flag<["-"], "no-canonical-prefixes">, Flags<[HelpHidden]>,
HelpText<"Use relative instead of canonical paths">;
def no_cpp_precomp : Flag<["-"], "no-cpp-precomp">, Group<clang_ignored_f_Group>;
-def no_integrated_as : Flag<["-"], "no-integrated-as">, Flags<[DriverOption]>;
def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">, Flags<[DriverOption]>;
def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>;
def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">;
@@ -1228,6 +1267,8 @@
def r : Flag<["-"], "r">;
def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>,
HelpText<"Save intermediate compilation results">;
+def via_file_asm : Flag<["-", "--"], "via-file-asm">, InternalDebugOpt,
+ HelpText<"Write assembly to file for input to assemble jobs">;
def sectalign : MultiArg<["-"], "sectalign", 3>;
def sectcreate : MultiArg<["-"], "sectcreate", 3>;
def sectobjectsymbols : MultiArg<["-"], "sectobjectsymbols", 2>;
@@ -1257,6 +1298,16 @@
HelpText<"C++ standard library to use">;
def sub__library : JoinedOrSeparate<["-"], "sub_library">;
def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
+def system_header_prefix : Joined<["--"], "system-header-prefix=">,
+ Group<clang_i_Group>, Flags<[CC1Option]>, MetaVarName<"<prefix>">,
+ HelpText<"Treat all #include paths starting with <prefix> as including a "
+ "system header.">;
+def : Separate<["--"], "system-header-prefix">, Alias<system_header_prefix>;
+def no_system_header_prefix : Joined<["--"], "no-system-header-prefix=">,
+ Group<clang_i_Group>, Flags<[CC1Option]>, MetaVarName<"<prefix>">,
+ HelpText<"Treat all #include paths starting with <prefix> as not including a "
+ "system header.">;
+def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix>;
def s : Flag<["-"], "s">;
def target : Joined<["--"], "target=">, Flags<[DriverOption]>,
HelpText<"Generate code for the given target">;
@@ -1278,10 +1329,10 @@
HelpText<"undef all system defines">;
def unexported__symbols__list : Separate<["-"], "unexported_symbols_list">;
def u : JoinedOrSeparate<["-"], "u">, Group<u_Group>;
-def v : Flag<["-"], "v">, Flags<[CC1Option]>,
+def v : Flag<["-"], "v">, Flags<[CC1Option, CoreOption]>,
HelpText<"Show commands to run and use verbose output">;
-def verify : Flag<["-"], "verify">, Flags<[DriverOption,CC1Option]>,
- HelpText<"Verify output using a verifier">;
+def verify_debug_info : Flag<["--"], "verify-debug-info">, Flags<[DriverOption]>,
+ HelpText<"Verify the binary representation of debug output">;
def weak_l : Joined<["-"], "weak-l">, Flags<[LinkerInput]>;
def weak__framework : Separate<["-"], "weak_framework">, Flags<[LinkerInput]>;
def weak__library : Separate<["-"], "weak_library">, Flags<[LinkerInput]>;
@@ -1294,6 +1345,15 @@
MetaVarName<"<language>">;
def y : Joined<["-"], "y">;
+def fintegrated_as : Flag<["-"], "fintegrated-as">, Flags<[DriverOption]>,
+ Group<f_Group>, HelpText<"Enable the integrated assembler">;
+def fno_integrated_as : Flag<["-"], "fno-integrated-as">,
+ Flags<[CC1Option, DriverOption]>, Group<f_Group>,
+ HelpText<"Disable the integrated assembler">;
+def : Flag<["-"], "integrated-as">, Alias<fintegrated_as>, Flags<[DriverOption]>;
+def : Flag<["-"], "no-integrated-as">, Alias<fno_integrated_as>,
+ Flags<[CC1Option, DriverOption]>;
+
def working_directory : JoinedOrSeparate<["-"], "working-directory">, Flags<[CC1Option]>,
HelpText<"Resolve file paths relative to the specified directory">;
def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option]>,
@@ -1302,7 +1362,8 @@
// Double dash options, which are usually an alias for one of the previous
// options.
-def _mhwdiv_EQ : Separate<["--"], "mhwdiv">, Alias<mhwdiv_EQ>;
+def _mhwdiv_EQ : Joined<["--"], "mhwdiv=">, Alias<mhwdiv_EQ>;
+def _mhwdiv : Separate<["--"], "mhwdiv">, Alias<mhwdiv_EQ>;
def _CLASSPATH_EQ : Joined<["--"], "CLASSPATH=">, Alias<fclasspath_EQ>;
def _CLASSPATH : Separate<["--"], "CLASSPATH">, Alias<fclasspath_EQ>;
def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>;
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index 35b8f89..c79c471 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -9,10 +9,9 @@
#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
#define CLANG_LIB_DRIVER_SANITIZERARGS_H_
-#include <string>
-
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
+#include <string>
namespace clang {
namespace driver {
@@ -43,14 +42,16 @@
NeedsLeakDetection = Leak,
NeedsUbsanRt = Undefined | Integer,
NotAllowedWithTrap = Vptr,
- HasZeroBaseShadow = Thread | Memory | DataFlow
+ HasZeroBaseShadow = Thread | Memory | DataFlow,
+ NeedsUnwindTables = Address | Thread | Memory | DataFlow
};
unsigned Kind;
std::string BlacklistFile;
- bool MsanTrackOrigins;
+ int MsanTrackOrigins;
bool AsanZeroBaseShadow;
bool UbsanTrapOnError;
+ bool AsanSharedRuntime;
public:
SanitizerArgs();
@@ -58,6 +59,7 @@
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
bool needsAsanRt() const { return Kind & NeedsAsanRt; }
+ bool needsSharedAsanRt() const { return AsanSharedRuntime; }
bool needsTsanRt() const { return Kind & NeedsTsanRt; }
bool needsMsanRt() const { return Kind & NeedsMsanRt; }
bool needsLeakDetection() const { return Kind & NeedsLeakDetection; }
@@ -74,6 +76,7 @@
bool hasZeroBaseShadow() const {
return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow;
}
+ bool needsUnwindTables() const { return Kind & NeedsUnwindTables; }
void addArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
@@ -99,7 +102,7 @@
/// Produce an argument string from ArgList \p Args, which shows how it
/// provides a sanitizer kind in \p Mask. For example, the argument list
- /// "-fsanitize=thread,vptr -faddress-sanitizer" with mask \c NeedsUbsanRt
+ /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
/// would produce "-fsanitize=vptr".
static std::string lastArgumentForKind(const Driver &D,
const llvm::opt::ArgList &Args,
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 84e0b55..953229c 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -11,12 +11,13 @@
#define CLANG_DRIVER_TOOLCHAIN_H_
#include "clang/Driver/Action.h"
+#include "clang/Driver/Multilib.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Path.h"
+#include <memory>
#include <string>
namespace llvm {
@@ -65,17 +66,19 @@
/// programs.
path_list ProgramPaths;
- mutable OwningPtr<Tool> Clang;
- mutable OwningPtr<Tool> Assemble;
- mutable OwningPtr<Tool> Link;
+ mutable std::unique_ptr<Tool> Clang;
+ mutable std::unique_ptr<Tool> Assemble;
+ mutable std::unique_ptr<Tool> Link;
Tool *getClang() const;
Tool *getAssemble() const;
Tool *getLink() const;
Tool *getClangAs() const;
- mutable OwningPtr<SanitizerArgs> SanitizerArguments;
+ mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
protected:
+ MultilibSet Multilibs;
+
ToolChain(const Driver &D, const llvm::Triple &T,
const llvm::opt::ArgList &Args);
@@ -113,6 +116,9 @@
StringRef getPlatform() const { return Triple.getVendorName(); }
StringRef getOS() const { return Triple.getOSName(); }
+ /// \brief Returns true if the toolchain is targeting a non-native architecture.
+ bool isCrossCompiling() const;
+
/// \brief Provide the default architecture name (as expected by -arch) for
/// this toolchain. Note t
std::string getDefaultUniversalArchName() const;
@@ -127,6 +133,8 @@
path_list &getProgramPaths() { return ProgramPaths; }
const path_list &getProgramPaths() const { return ProgramPaths; }
+ const MultilibSet &getMultilibs() const { return Multilibs; }
+
const SanitizerArgs& getSanitizerArgs() const;
// Tool access.
@@ -193,7 +201,7 @@
virtual bool UseObjCMixedDispatch() const { return false; }
/// GetDefaultStackProtectorLevel - Get the default stack protector level for
- /// this tool chain (0=off, 1=on, 2=all).
+ /// this tool chain (0=off, 1=on, 2=strong, 3=all).
virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
return 0;
}
@@ -275,6 +283,9 @@
virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
+ /// \brief Add warning options that need to be passed to cc1 for this target.
+ virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const;
+
// GetRuntimeLibType - Determine the runtime library type to use with the
// given compilation arguments.
virtual RuntimeLibType
@@ -303,7 +314,7 @@
/// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets
/// global flags for unsafe floating point math, add it and return true.
///
- /// This checks for presence of the -ffast-math or -funsafe-math flags.
+ /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
virtual bool
AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
index 3ad5a6b..f95b797 100644
--- a/include/clang/Edit/EditedSource.h
+++ b/include/clang/Edit/EditedSource.h
@@ -50,7 +50,7 @@
const bool FCommitInSystemHeader = true)
: SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
ForceCommitInSystemHeader(FCommitInSystemHeader),
- StrAlloc(/*size=*/512) { }
+ StrAlloc() { }
const SourceManager &getSourceManager() const { return SourceMgr; }
const LangOptions &getLangOpts() const { return LangOpts; }
diff --git a/include/clang/Edit/FileOffset.h b/include/clang/Edit/FileOffset.h
index 675ad18..0c1e72b 100644
--- a/include/clang/Edit/FileOffset.h
+++ b/include/clang/Edit/FileOffset.h
@@ -41,20 +41,16 @@
return !(LHS == RHS);
}
friend bool operator<(FileOffset LHS, FileOffset RHS) {
- if (LHS.FID != RHS.FID)
- return LHS.FID < RHS.FID;
- return LHS.Offs < RHS.Offs;
+ return std::tie(LHS.FID, LHS.Offs) < std::tie(RHS.FID, RHS.Offs);
}
friend bool operator>(FileOffset LHS, FileOffset RHS) {
- if (LHS.FID != RHS.FID)
- return LHS.FID > RHS.FID;
- return LHS.Offs > RHS.Offs;
+ return RHS < LHS;
}
friend bool operator>=(FileOffset LHS, FileOffset RHS) {
- return LHS > RHS || LHS == RHS;
+ return !(LHS < RHS);
}
friend bool operator<=(FileOffset LHS, FileOffset RHS) {
- return LHS < RHS || LHS == RHS;
+ return !(RHS < LHS);
}
};
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 0f27467..cded911 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -30,16 +30,37 @@
/// \brief The \c FormatStyle is used to configure the formatting to follow
/// specific guidelines.
struct FormatStyle {
+ /// \brief Supported languages. When stored in a configuration file, specifies
+ /// the language, that the configuration targets. When passed to the
+ /// reformat() function, enables syntax features specific to the language.
+ enum LanguageKind {
+ /// Do not use.
+ LK_None,
+ /// Should be used for C, C++, ObjectiveC, ObjectiveC++.
+ LK_Cpp,
+ /// Should be used for JavaScript.
+ LK_JavaScript,
+ /// Should be used for Protocol Buffers
+ /// (https://developers.google.com/protocol-buffers/).
+ LK_Proto
+ };
+
+ /// \brief Language, this format style is targeted at.
+ LanguageKind Language;
+
/// \brief The column limit.
///
/// A column limit of \c 0 means that there is no column limit. In this case,
/// clang-format will respect the input's line breaking decisions within
- /// statements.
+ /// statements unless they contradict other rules.
unsigned ColumnLimit;
/// \brief The maximum number of consecutive empty lines to keep.
unsigned MaxEmptyLinesToKeep;
+ /// \brief If true, empty lines at the start of blocks are kept.
+ bool KeepEmptyLinesAtTheStartOfBlocks;
+
/// \brief The penalty for each line break introduced inside a comment.
unsigned PenaltyBreakComment;
@@ -58,7 +79,8 @@
/// \brief Set whether & and * bind to the type as opposed to the variable.
bool PointerBindsToType;
- /// \brief If \c true, analyze the formatted file for the most common binding.
+ /// \brief If \c true, analyze the formatted file for the most common binding
+ /// and use \c PointerBindsToType only as fallback.
bool DerivePointerBinding;
/// \brief The extra indent or outdent of access modifiers, e.g. \c public:.
@@ -141,6 +163,14 @@
/// single line.
bool AllowShortLoopsOnASingleLine;
+ /// \brief If \c true, <tt>int f() { return 0; }</tt> can be put on a single
+ /// line.
+ bool AllowShortFunctionsOnASingleLine;
+
+ /// \brief Add a space after \c @property in Objective-C, i.e. use
+ /// <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
/// <tt>Foo <Protocol></tt> instead of \c Foo<Protocol>.
bool ObjCSpaceBeforeProtocolList;
@@ -199,7 +229,11 @@
/// Like \c Attach, but break before function definitions.
BS_Stroustrup,
/// Always break before braces.
- BS_Allman
+ BS_Allman,
+ /// Always break before braces and add an extra level of indentation to
+ /// braces of control statements, not to those of class, function
+ /// or other definitions.
+ BS_GNU
};
/// \brief The brace breaking style to use.
@@ -231,15 +265,32 @@
/// template argument lists
bool SpacesInAngles;
- /// \brief If \c false, spaces may be inserted into '()'.
+ /// \brief If \c true, spaces may be inserted into '()'.
bool SpaceInEmptyParentheses;
- /// \brief If \c false, spaces may be inserted into C style casts.
+ /// \brief If \c true, spaces are inserted inside container literals (e.g.
+ /// ObjC and Javascript array and dict literals).
+ bool SpacesInContainerLiterals;
+
+ /// \brief If \c true, spaces may be inserted into C style casts.
bool SpacesInCStyleCastParentheses;
- /// \brief If \c true, spaces will be inserted between 'for'/'if'/'while'/...
- /// and '('.
- bool SpaceAfterControlStatementKeyword;
+ /// \brief Different ways to put a space before opening parentheses.
+ enum SpaceBeforeParensOptions {
+ /// Never put a space before opening parentheses.
+ SBPO_Never,
+ /// Put a space before opening parentheses only after control statement
+ /// keywords (<tt>for/if/while...</tt>).
+ SBPO_ControlStatements,
+ /// Always put a space before opening parentheses, except when it's
+ /// prohibited by the syntax rules (in function-like macro definitions) or
+ /// when determined by other style rules (after unary operators, opening
+ /// parentheses, etc.)
+ SBPO_Always
+ };
+
+ /// \brief Defines in which cases to put a space before opening parentheses.
+ SpaceBeforeParensOptions SpaceBeforeParens;
/// \brief If \c false, spaces will be removed before assignment operators.
bool SpaceBeforeAssignmentOperators;
@@ -247,6 +298,22 @@
/// \brief Indent width for line continuations.
unsigned ContinuationIndentWidth;
+ /// \brief A regular expression that describes comments with special meaning,
+ /// which should not be split into lines or otherwise changed.
+ std::string CommentPragmas;
+
+ /// \brief A vector of macros that should be interpreted as foreach loops
+ /// instead of as function calls.
+ ///
+ /// These are expected to be macros of the form:
+ /// \code
+ /// FOREACH(<variable-declaration>, ...)
+ /// <loop-body>
+ /// \endcode
+ ///
+ /// For example: BOOST_FOREACH.
+ std::vector<std::string> ForEachMacros;
+
bool operator==(const FormatStyle &R) const {
return AccessModifierOffset == R.AccessModifierOffset &&
ConstructorInitializerIndentWidth ==
@@ -255,6 +322,8 @@
AlignTrailingComments == R.AlignTrailingComments &&
AllowAllParametersOfDeclarationOnNextLine ==
R.AllowAllParametersOfDeclarationOnNextLine &&
+ AllowShortFunctionsOnASingleLine ==
+ R.AllowShortFunctionsOnASingleLine &&
AllowShortIfStatementsOnASingleLine ==
R.AllowShortIfStatementsOnASingleLine &&
AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
@@ -277,9 +346,12 @@
IndentCaseLabels == R.IndentCaseLabels &&
IndentFunctionDeclarationAfterType ==
R.IndentFunctionDeclarationAfterType &&
- IndentWidth == R.IndentWidth &&
+ IndentWidth == R.IndentWidth && Language == R.Language &&
MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
+ KeepEmptyLinesAtTheStartOfBlocks ==
+ R.KeepEmptyLinesAtTheStartOfBlocks &&
NamespaceIndentation == R.NamespaceIndentation &&
+ ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
PenaltyBreakComment == R.PenaltyBreakComment &&
PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess &&
@@ -293,11 +365,13 @@
UseTab == R.UseTab && SpacesInParentheses == R.SpacesInParentheses &&
SpacesInAngles == R.SpacesInAngles &&
SpaceInEmptyParentheses == R.SpaceInEmptyParentheses &&
+ SpacesInContainerLiterals == R.SpacesInContainerLiterals &&
SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
- SpaceAfterControlStatementKeyword ==
- R.SpaceAfterControlStatementKeyword &&
+ SpaceBeforeParens == R.SpaceBeforeParens &&
SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
- ContinuationIndentWidth == R.ContinuationIndentWidth;
+ ContinuationIndentWidth == R.ContinuationIndentWidth &&
+ CommentPragmas == R.CommentPragmas &&
+ ForEachMacros == R.ForEachMacros;
}
};
@@ -305,13 +379,15 @@
/// http://llvm.org/docs/CodingStandards.html.
FormatStyle getLLVMStyle();
-/// \brief Returns a format style complying with Google's C++ style guide:
+/// \brief Returns a format style complying with one of Google's style guides:
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml.
-FormatStyle getGoogleStyle();
+/// http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml.
+/// https://developers.google.com/protocol-buffers/docs/style.
+FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language);
/// \brief Returns a format style complying with Chromium's style guide:
/// http://www.chromium.org/developers/coding-style.
-FormatStyle getChromiumStyle();
+FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language);
/// \brief Returns a format style complying with Mozilla's style guide:
/// https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style.
@@ -321,15 +397,26 @@
/// http://www.webkit.org/coding/coding-style.html
FormatStyle getWebKitStyle();
-/// \brief Gets a predefined style by name.
+/// \brief Returns a format style complying with GNU Coding Standards:
+/// http://www.gnu.org/prep/standards/standards.html
+FormatStyle getGNUStyle();
+
+/// \brief Gets a predefined style for the specified language by name.
///
/// Currently supported names: LLVM, Google, Chromium, Mozilla. Names are
/// compared case-insensitively.
///
/// Returns \c true if the Style has been set.
-bool getPredefinedStyle(StringRef Name, FormatStyle *Style);
+bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
+ FormatStyle *Style);
/// \brief Parse configuration from YAML-formatted text.
+///
+/// Style->Language is used to get the base style, if the \c BasedOnStyle
+/// option is present.
+///
+/// When \c BasedOnStyle is not present, options not present in the YAML
+/// document, are retained in \p Style.
llvm::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
/// \brief Gets configuration in a YAML string.
@@ -381,10 +468,13 @@
/// above.
/// \param[in] FileName Path to start search for .clang-format if \c StyleName
/// == "file".
+/// \param[in] FallbackStyle The name of a predefined style used to fallback to
+/// in case the style can't be determined from \p StyleName.
///
/// \returns FormatStyle as specified by \c StyleName. If no style could be
/// determined, the default is LLVM Style (see getLLVMStyle()).
-FormatStyle getStyle(StringRef StyleName, StringRef FileName);
+FormatStyle getStyle(StringRef StyleName, StringRef FileName,
+ StringRef FallbackStyle);
} // end namespace format
} // end namespace clang
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 43d77f0..3a26df3 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -27,12 +27,13 @@
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MD5.h"
#include "llvm/Support/Path.h"
#include <cassert>
#include <map>
+#include <memory>
#include <string>
#include <sys/types.h>
#include <utility>
@@ -63,33 +64,51 @@
/// \brief Utility class for loading a ASTContext from an AST file.
///
class ASTUnit : public ModuleLoader {
+public:
+ struct StandaloneFixIt {
+ std::pair<unsigned, unsigned> RemoveRange;
+ std::pair<unsigned, unsigned> InsertFromRange;
+ std::string CodeToInsert;
+ bool BeforePreviousInsertions;
+ };
+
+ struct StandaloneDiagnostic {
+ unsigned ID;
+ DiagnosticsEngine::Level Level;
+ std::string Message;
+ std::string Filename;
+ unsigned LocOffset;
+ std::vector<std::pair<unsigned, unsigned> > Ranges;
+ std::vector<StandaloneFixIt> FixIts;
+ };
+
private:
IntrusiveRefCntPtr<LangOptions> LangOpts;
IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
IntrusiveRefCntPtr<FileManager> FileMgr;
IntrusiveRefCntPtr<SourceManager> SourceMgr;
- OwningPtr<HeaderSearch> HeaderInfo;
+ std::unique_ptr<HeaderSearch> HeaderInfo;
IntrusiveRefCntPtr<TargetInfo> Target;
IntrusiveRefCntPtr<Preprocessor> PP;
IntrusiveRefCntPtr<ASTContext> Ctx;
IntrusiveRefCntPtr<TargetOptions> TargetOpts;
IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
- ASTReader *Reader;
+ IntrusiveRefCntPtr<ASTReader> Reader;
bool HadModuleLoaderFatalFailure;
struct ASTWriterData;
- OwningPtr<ASTWriterData> WriterData;
+ std::unique_ptr<ASTWriterData> WriterData;
FileSystemOptions FileSystemOpts;
/// \brief The AST consumer that received information about the translation
/// unit as it was parsed or loaded.
- OwningPtr<ASTConsumer> Consumer;
-
+ std::unique_ptr<ASTConsumer> Consumer;
+
/// \brief The semantic analysis object used to type-check the translation
/// unit.
- OwningPtr<Sema> TheSema;
-
+ std::unique_ptr<Sema> TheSema;
+
/// Optional owned invocation, just used to make the invocation used in
/// LoadFromCommandLine available.
IntrusiveRefCntPtr<CompilerInvocation> Invocation;
@@ -135,7 +154,7 @@
std::string OriginalSourceFile;
/// \brief The set of diagnostics produced when creating the preamble.
- SmallVector<StoredDiagnostic, 4> PreambleDiagnostics;
+ SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics;
/// \brief The set of diagnostics produced when creating this
/// translation unit.
@@ -205,8 +224,34 @@
return Preamble;
}
-private:
+ /// Data used to determine if a file used in the preamble has been changed.
+ struct PreambleFileHash {
+ /// All files have size set.
+ off_t Size;
+ /// Modification time is set for files that are on disk. For memory
+ /// buffers it is zero.
+ time_t ModTime;
+
+ /// Memory buffers have MD5 instead of modification time. We don't
+ /// compute MD5 for on-disk files because we hope that modification time is
+ /// enough to tell if the file was changed.
+ llvm::MD5::MD5Result MD5;
+
+ static PreambleFileHash createForFile(off_t Size, time_t ModTime);
+ static PreambleFileHash
+ createForMemoryBuffer(const llvm::MemoryBuffer *Buffer);
+
+ friend bool operator==(const PreambleFileHash &LHS,
+ const PreambleFileHash &RHS);
+
+ friend bool operator!=(const PreambleFileHash &LHS,
+ const PreambleFileHash &RHS) {
+ return !(LHS == RHS);
+ }
+ };
+
+private:
/// \brief The contents of the preamble that has been precompiled to
/// \c PreambleFile.
PreambleData Preamble;
@@ -216,17 +261,13 @@
/// Used to inform the lexer as to whether it's starting at the beginning of
/// a line after skipping the preamble.
bool PreambleEndsAtStartOfLine;
-
- /// \brief The size of the source buffer that we've reserved for the main
- /// file within the precompiled preamble.
- unsigned PreambleReservedSize;
/// \brief Keeps track of the files that were used when computing the
/// preamble, with both their buffer size and their modification time.
///
/// If any of the files have changed from one compile to the next,
/// the preamble must be thrown away.
- llvm::StringMap<std::pair<off_t, time_t> > FilesInPreamble;
+ llvm::StringMap<PreambleFileHash> FilesInPreamble;
/// \brief When non-NULL, this is the buffer used to store the contents of
/// the main file when it has been padded for use with the precompiled
@@ -268,9 +309,9 @@
const char **ArgBegin, const char **ArgEnd,
ASTUnit &AST, bool CaptureDiagnostics);
- void TranslateStoredDiagnostics(ASTReader *MMan, StringRef ModName,
+ void TranslateStoredDiagnostics(FileManager &FileMgr,
SourceManager &SrcMan,
- const SmallVectorImpl<StoredDiagnostic> &Diags,
+ const SmallVectorImpl<StandaloneDiagnostic> &Diags,
SmallVectorImpl<StoredDiagnostic> &Out);
void clearFileLevelDecls();
@@ -337,8 +378,8 @@
/// \brief Allocator used to store cached code completions.
IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
CachedCompletionAllocator;
-
- OwningPtr<CodeCompletionTUInfo> CCTUInfo;
+
+ std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
/// \brief The set of cached code-completion results.
std::vector<CachedCodeCompletionResult> CachedCompletionResults;
@@ -406,9 +447,7 @@
/// just about any usage.
/// Becomes a noop in release mode; only useful for debug mode checking.
class ConcurrencyState {
-#ifndef NDEBUG
void *Mutex; // a llvm::sys::MutexImpl in debug;
-#endif
public:
ConcurrencyState();
@@ -457,7 +496,7 @@
void setASTContext(ASTContext *ctx) { Ctx = ctx; }
void setPreprocessor(Preprocessor *pp);
- bool hasSema() const { return TheSema.isValid(); }
+ bool hasSema() const { return (bool)TheSema; }
Sema &getSema() const {
assert(TheSema && "ASTUnit does not have a Sema object!");
return *TheSema;
@@ -646,11 +685,9 @@
/// \brief Determine what kind of translation unit this AST represents.
TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
- typedef llvm::PointerUnion<const char *, const llvm::MemoryBuffer *>
- FilenameOrMemBuf;
/// \brief A mapping from a file name to the memory buffer that stores the
/// remapped contents of that file.
- typedef std::pair<std::string, FilenameOrMemBuf> RemappedFile;
+ typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile;
/// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
static ASTUnit *create(CompilerInvocation *CI,
@@ -670,8 +707,7 @@
IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
const FileSystemOptions &FileSystemOpts,
bool OnlyLocalDecls = false,
- RemappedFile *RemappedFiles = 0,
- unsigned NumRemappedFiles = 0,
+ ArrayRef<RemappedFile> RemappedFiles = None,
bool CaptureDiagnostics = false,
bool AllowPCHWithCompilerErrors = false,
bool UserFilesAreVolatile = false);
@@ -714,19 +750,14 @@
/// This will only receive an ASTUnit if a new one was created. If an already
/// created ASTUnit was passed in \p Unit then the caller can check that.
///
- 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,
- bool IncludeBriefCommentsInCodeCompletion = false,
- bool UserFilesAreVolatile = false,
- OwningPtr<ASTUnit> *ErrAST = 0);
+ 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,
+ bool IncludeBriefCommentsInCodeCompletion = false,
+ bool UserFilesAreVolatile = false, std::unique_ptr<ASTUnit> *ErrAST = 0);
/// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
/// CompilerInvocation object.
@@ -767,32 +798,25 @@
///
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
// shouldn't need to specify them at construction time.
- static ASTUnit *LoadFromCommandLine(const char **ArgBegin,
- const char **ArgEnd,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- StringRef ResourceFilesPath,
- bool OnlyLocalDecls = false,
- bool CaptureDiagnostics = false,
- RemappedFile *RemappedFiles = 0,
- unsigned NumRemappedFiles = 0,
- bool RemappedFilesKeepOriginalName = true,
- bool PrecompilePreamble = false,
- TranslationUnitKind TUKind = TU_Complete,
- bool CacheCodeCompletionResults = false,
- bool IncludeBriefCommentsInCodeCompletion = false,
- bool AllowPCHWithCompilerErrors = false,
- bool SkipFunctionBodies = false,
- bool UserFilesAreVolatile = false,
- bool ForSerialization = false,
- OwningPtr<ASTUnit> *ErrAST = 0);
-
+ static ASTUnit *LoadFromCommandLine(
+ const char **ArgBegin, const char **ArgEnd,
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
+ bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+ ArrayRef<RemappedFile> RemappedFiles = None,
+ bool RemappedFilesKeepOriginalName = true,
+ bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+ bool CacheCodeCompletionResults = false,
+ bool IncludeBriefCommentsInCodeCompletion = false,
+ bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false,
+ bool UserFilesAreVolatile = false, bool ForSerialization = false,
+ std::unique_ptr<ASTUnit> *ErrAST = 0);
+
/// \brief Reparse the source files using the same command-line options that
/// were originally used to produce this translation unit.
///
/// \returns True if a failure occurred that causes the ASTUnit not to
/// contain any translation-unit information, false otherwise.
- bool Reparse(RemappedFile *RemappedFiles = 0,
- unsigned NumRemappedFiles = 0);
+ bool Reparse(ArrayRef<RemappedFile> RemappedFiles = None);
/// \brief Perform code completion at the given file, line, and
/// column within this translation unit.
@@ -815,7 +839,7 @@
/// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
/// OwnedBuffers parameters are all disgusting hacks. They will go away.
void CodeComplete(StringRef File, unsigned Line, unsigned Column,
- RemappedFile *RemappedFiles, unsigned NumRemappedFiles,
+ ArrayRef<RemappedFile> RemappedFiles,
bool IncludeMacros, bool IncludeCodePatterns,
bool IncludeBriefComments,
CodeCompleteConsumer &Consumer,
@@ -834,19 +858,16 @@
///
/// \returns True if an error occurred, false otherwise.
bool serialize(raw_ostream &OS);
-
- virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) {
+
+ ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) override {
// ASTUnit doesn't know how to load modules (not that this matters).
return ModuleLoadResult();
}
- virtual void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc,
- bool Complain) { }
+ void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc, bool Complain) override {}
};
diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h
index b7dc7c7..11762a9 100644
--- a/include/clang/Frontend/ChainedDiagnosticConsumer.h
+++ b/include/clang/Frontend/ChainedDiagnosticConsumer.h
@@ -11,7 +11,7 @@
#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H
#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
namespace clang {
class LangOptions;
@@ -22,8 +22,8 @@
/// diagnostics should be included in counts.
class ChainedDiagnosticConsumer : public DiagnosticConsumer {
virtual void anchor();
- OwningPtr<DiagnosticConsumer> Primary;
- OwningPtr<DiagnosticConsumer> Secondary;
+ std::unique_ptr<DiagnosticConsumer> Primary;
+ std::unique_ptr<DiagnosticConsumer> Secondary;
public:
ChainedDiagnosticConsumer(DiagnosticConsumer *_Primary,
@@ -32,28 +32,28 @@
Secondary.reset(_Secondary);
}
- virtual void BeginSourceFile(const LangOptions &LO,
- const Preprocessor *PP) {
+ void BeginSourceFile(const LangOptions &LO,
+ const Preprocessor *PP) override {
Primary->BeginSourceFile(LO, PP);
Secondary->BeginSourceFile(LO, PP);
}
- virtual void EndSourceFile() {
+ void EndSourceFile() override {
Secondary->EndSourceFile();
Primary->EndSourceFile();
}
- virtual void finish() {
+ void finish() override {
Secondary->finish();
Primary->finish();
}
- virtual bool IncludeInDiagnosticCounts() const {
+ bool IncludeInDiagnosticCounts() const override {
return Primary->IncludeInDiagnosticCounts();
}
- virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info) {
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) override {
// Default implementation (Warnings/errors count).
DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
diff --git a/include/clang/Frontend/ChainedIncludesSource.h b/include/clang/Frontend/ChainedIncludesSource.h
index aa30460..676e749 100644
--- a/include/clang/Frontend/ChainedIncludesSource.h
+++ b/include/clang/Frontend/ChainedIncludesSource.h
@@ -24,13 +24,13 @@
public:
virtual ~ChainedIncludesSource();
- static ChainedIncludesSource *create(CompilerInstance &CI);
+ static IntrusiveRefCntPtr<ChainedIncludesSource> create(CompilerInstance &CI);
ExternalSemaSource &getFinalReader() const { return *FinalReader; }
private:
std::vector<CompilerInstance *> CIs;
- OwningPtr<ExternalSemaSource> FinalReader;
+ IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
protected:
@@ -39,35 +39,35 @@
// ExternalASTSource interface.
//===----------------------------------------------------------------------===//
- virtual Decl *GetExternalDecl(uint32_t ID);
- virtual Selector GetExternalSelector(uint32_t ID);
- virtual uint32_t GetNumExternalSelectors();
- virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
- virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
- virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC,
- DeclarationName Name);
- virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
- bool (*isKindWeWant)(Decl::Kind),
- SmallVectorImpl<Decl*> &Result);
- virtual void CompleteType(TagDecl *Tag);
- virtual void CompleteType(ObjCInterfaceDecl *Class);
- virtual void StartedDeserializing();
- virtual void FinishedDeserializing();
- virtual void StartTranslationUnit(ASTConsumer *Consumer);
- virtual void PrintStats();
+ Decl *GetExternalDecl(uint32_t ID) override;
+ Selector GetExternalSelector(uint32_t ID) override;
+ uint32_t GetNumExternalSelectors() override;
+ Stmt *GetExternalDeclStmt(uint64_t Offset) override;
+ CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
+ bool FindExternalVisibleDeclsByName(const DeclContext *DC,
+ DeclarationName Name) override;
+ ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+ bool (*isKindWeWant)(Decl::Kind),
+ SmallVectorImpl<Decl*> &Result) override;
+ void CompleteType(TagDecl *Tag) override;
+ void CompleteType(ObjCInterfaceDecl *Class) override;
+ void StartedDeserializing() override;
+ void FinishedDeserializing() override;
+ void StartTranslationUnit(ASTConsumer *Consumer) override;
+ void PrintStats() override;
/// Return the amount of memory used by memory buffers, breaking down
/// by heap-backed versus mmap'ed memory.
- virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
+ void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
//===----------------------------------------------------------------------===//
// ExternalSemaSource interface.
//===----------------------------------------------------------------------===//
- virtual void InitializeSema(Sema &S);
- virtual void ForgetSema();
- virtual void ReadMethodPool(Selector Sel);
- virtual bool LookupUnqualified(LookupResult &R, Scope *S);
+ void InitializeSema(Sema &S) override;
+ void ForgetSema() override;
+ void ReadMethodPool(Selector Sel) override;
+ bool LookupUnqualified(LookupResult &R, Scope *S) override;
};
}
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 78b825d..753b641 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -28,6 +28,8 @@
CODEGENOPT(Name, Bits, Default)
#endif
+CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
+CODEGENOPT(CompressDebugSections, 1, 0) ///< -Wa,-compress-debug-sections
CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
@@ -59,8 +61,6 @@
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
///< are required.
CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
-CODEGENOPT(HiddenWeakVTables , 1, 0) ///< Emit weak vtables, RTTI, and thunks with
- ///< hidden visibility.
CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
///< enabled.
CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
@@ -87,6 +87,9 @@
VALUE_CODEGENOPT(OptimizationLevel, 3, 0) ///< The -O[0-4] option specified.
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
+CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate
+ ///< execution counts to use with PGO.
+
/// If -fpcc-struct-return or -freg-struct-return is specified.
ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
@@ -96,7 +99,7 @@
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
///< offset in AddressSanitizer.
-CODEGENOPT(SanitizeMemoryTrackOrigins, 1, 0) ///< Enable tracking origins in
+CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
///< MemorySanitizer
CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on
/// -fsanitize-undefined-trap-on-error
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 86aabf7..da97e5c 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -50,12 +50,20 @@
};
enum DebugInfoKind {
- NoDebugInfo, // Don't generate debug info.
- DebugLineTablesOnly, // Emit only debug info necessary for generating
- // line number tables (-gline-tables-only).
- LimitedDebugInfo, // Limit generated debug info to reduce size
- // (-flimit-debug-info).
- FullDebugInfo // Generate complete debug info.
+ NoDebugInfo, /// Don't generate debug info.
+
+ DebugLineTablesOnly, /// Emit only debug info necessary for generating
+ /// line number tables (-gline-tables-only).
+
+ LimitedDebugInfo, /// Limit generated debug info to reduce size
+ /// (-fno-standalone-debug). This emits
+ /// forward decls for types that could be
+ /// replaced with forward decls in the source
+ /// code. For dynamic C++ classes type info
+ /// is only emitted int the module that
+ /// contains the classe's vtable.
+
+ FullDebugInfo /// Generate complete debug info.
};
enum TLSModel {
@@ -134,6 +142,9 @@
/// Name of the profile file to use with -fprofile-sample-use.
std::string SampleProfileFile;
+ /// Name of the profile file to use as input for -fprofile-instr-use
+ std::string InstrProfileInput;
+
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 5673c59..ee97d9b 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -13,14 +13,15 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/Utils.h"
#include "clang/Lex/ModuleLoader.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <list>
+#include <memory>
#include <string>
#include <utility>
@@ -74,6 +75,9 @@
/// The target being compiled for.
IntrusiveRefCntPtr<TargetInfo> Target;
+ /// The virtual file system.
+ IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem;
+
/// The file manager.
IntrusiveRefCntPtr<FileManager> FileMgr;
@@ -87,19 +91,22 @@
IntrusiveRefCntPtr<ASTContext> Context;
/// The AST consumer.
- OwningPtr<ASTConsumer> Consumer;
+ std::unique_ptr<ASTConsumer> Consumer;
/// The code completion consumer.
- OwningPtr<CodeCompleteConsumer> CompletionConsumer;
+ std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
/// \brief The semantic analysis object.
- OwningPtr<Sema> TheSema;
+ std::unique_ptr<Sema> TheSema;
/// \brief The frontend timer
- OwningPtr<llvm::Timer> FrontendTimer;
+ std::unique_ptr<llvm::Timer> FrontendTimer;
- /// \brief Non-owning reference to the ASTReader, if one exists.
- ASTReader *ModuleManager;
+ /// \brief The ASTReader, if one exists.
+ IntrusiveRefCntPtr<ASTReader> ModuleManager;
+
+ /// \brief The dependency file generator.
+ std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator;
/// \brief The set of top-level modules that has already been loaded,
/// along with the module map
@@ -123,7 +130,7 @@
/// \brief Holds information about the output file.
///
/// If TempFilename is not empty we must rename it to Filename at the end.
- /// TempFilename may be empty and Filename non empty if creating the temporary
+ /// TempFilename may be empty and Filename non-empty if creating the temporary
/// failed.
struct OutputFile {
std::string Filename;
@@ -313,6 +320,26 @@
void setTarget(TargetInfo *Value);
/// }
+ /// @name Virtual File System
+ /// {
+
+ bool hasVirtualFileSystem() const { return VirtualFileSystem != 0; }
+
+ vfs::FileSystem &getVirtualFileSystem() const {
+ assert(hasVirtualFileSystem() &&
+ "Compiler instance has no virtual file system");
+ return *VirtualFileSystem;
+ }
+
+ /// \brief Replace the current virtual file system.
+ ///
+ /// \note Most clients should use setFileManager, which will implicitly reset
+ /// the virtual file system to the one contained in the file manager.
+ void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+ VirtualFileSystem = FS;
+ }
+
+ /// }
/// @name File Manager
/// {
@@ -325,10 +352,11 @@
}
void resetAndLeakFileManager() {
+ BuryPointer(FileMgr.getPtr());
FileMgr.resetWithoutRelease();
}
- /// setFileManager - Replace the current file manager.
+ /// \brief Replace the current file manager and virtual file system.
void setFileManager(FileManager *Value);
/// }
@@ -344,6 +372,7 @@
}
void resetAndLeakSourceManager() {
+ BuryPointer(SourceMgr.getPtr());
SourceMgr.resetWithoutRelease();
}
@@ -363,6 +392,7 @@
}
void resetAndLeakPreprocessor() {
+ BuryPointer(PP.getPtr());
PP.resetWithoutRelease();
}
@@ -381,6 +411,7 @@
}
void resetAndLeakASTContext() {
+ BuryPointer(Context.getPtr());
Context.resetWithoutRelease();
}
@@ -395,7 +426,7 @@
/// @name ASTConsumer
/// {
- bool hasASTConsumer() const { return Consumer.isValid(); }
+ bool hasASTConsumer() const { return (bool)Consumer; }
ASTConsumer &getASTConsumer() const {
assert(Consumer && "Compiler instance has no AST consumer!");
@@ -404,7 +435,7 @@
/// takeASTConsumer - Remove the current AST consumer and give ownership to
/// the caller.
- ASTConsumer *takeASTConsumer() { return Consumer.take(); }
+ ASTConsumer *takeASTConsumer() { return Consumer.release(); }
/// setASTConsumer - Replace the current AST consumer; the compiler instance
/// takes ownership of \p Value.
@@ -413,29 +444,27 @@
/// }
/// @name Semantic analysis
/// {
- bool hasSema() const { return TheSema.isValid(); }
-
+ bool hasSema() const { return (bool)TheSema; }
+
Sema &getSema() const {
assert(TheSema && "Compiler instance has no Sema object!");
return *TheSema;
}
-
- Sema *takeSema() { return TheSema.take(); }
-
+
+ Sema *takeSema() { return TheSema.release(); }
+
/// }
/// @name Module Management
/// {
- ASTReader *getModuleManager() const { return ModuleManager; }
- void setModuleManager(ASTReader *Reader) { ModuleManager = Reader; }
+ IntrusiveRefCntPtr<ASTReader> getModuleManager() const;
+ void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader);
/// }
/// @name Code Completion
/// {
- bool hasCodeCompletionConsumer() const {
- return CompletionConsumer.isValid();
- }
+ bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
CodeCompleteConsumer &getCodeCompletionConsumer() const {
assert(CompletionConsumer &&
@@ -446,7 +475,7 @@
/// takeCodeCompletionConsumer - Remove the current code completion consumer
/// and give ownership to the caller.
CodeCompleteConsumer *takeCodeCompletionConsumer() {
- return CompletionConsumer.take();
+ return CompletionConsumer.release();
}
/// setCodeCompletionConsumer - Replace the current code completion consumer;
@@ -457,7 +486,7 @@
/// @name Frontend timer
/// {
- bool hasFrontendTimer() const { return FrontendTimer.isValid(); }
+ bool hasFrontendTimer() const { return (bool)FrontendTimer; }
llvm::Timer &getFrontendTimer() const {
assert(FrontendTimer && "Compiler instance has no frontend timer!");
@@ -530,7 +559,7 @@
/// Create the preprocessor, using the invocation, file, and source managers,
/// and replace any existing one with it.
- void createPreprocessor();
+ void createPreprocessor(TranslationUnitKind TUKind);
/// Create the AST context.
void createASTContext();
@@ -653,16 +682,13 @@
const FrontendOptions &Opts);
/// }
-
- virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective);
- virtual void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc,
- bool Complain);
+ ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) override;
+
+ void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc, bool Complain) override;
bool hadModuleLoaderFatalFailure() const {
return ModuleLoader::HadFatalFailure;
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
index fefb6f3..d275249 100644
--- a/include/clang/Frontend/DependencyOutputOptions.h
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -26,6 +26,7 @@
/// problems.
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
+ unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
/// The file to write dependency output to.
std::string OutputFile;
@@ -50,6 +51,7 @@
UsePhonyTargets = 0;
AddMissingHeaderDeps = 0;
PrintShowIncludes = 0;
+ IncludeModuleFiles = 0;
}
};
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index f3cd054..f554b88 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -158,20 +158,19 @@
: DiagnosticRenderer(LangOpts, DiagOpts) {}
virtual ~DiagnosticNoteRenderer();
-
- virtual void emitBasicNote(StringRef Message);
-
- virtual void emitIncludeLocation(SourceLocation Loc,
- PresumedLoc PLoc,
- const SourceManager &SM);
- virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+ void emitBasicNote(StringRef Message) override;
+
+ void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+ const SourceManager &SM) override;
+
+ void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM) override;
+
+ void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
- const SourceManager &SM);
-
- virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
- StringRef ModuleName,
- const SourceManager &SM);
+ const SourceManager &SM) override;
virtual void emitNote(SourceLocation Loc, StringRef Message,
const SourceManager *SM) = 0;
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index a568ba0..8c24513 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -21,8 +21,8 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Frontend/FrontendOptions.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
+#include <memory>
#include <string>
#include <vector>
@@ -35,7 +35,7 @@
/// Abstract base class for actions which can be performed by the frontend.
class FrontendAction {
FrontendInputFile CurrentInput;
- OwningPtr<ASTUnit> CurrentASTUnit;
+ std::unique_ptr<ASTUnit> CurrentASTUnit;
CompilerInstance *Instance;
friend class ASTMergeAction;
friend class WrapperFrontendAction;
@@ -124,7 +124,7 @@
bool isCurrentFileAST() const {
assert(!CurrentInput.isEmpty() && "No current file!");
- return CurrentASTUnit.isValid();
+ return (bool)CurrentASTUnit;
}
const FrontendInputFile &getCurrentInput() const {
@@ -146,9 +146,7 @@
return *CurrentASTUnit;
}
- ASTUnit *takeCurrentASTUnit() {
- return CurrentASTUnit.take();
- }
+ ASTUnit *takeCurrentASTUnit() { return CurrentASTUnit.release(); }
void setCurrentInput(const FrontendInputFile &CurrentInput, ASTUnit *AST = 0);
@@ -220,17 +218,17 @@
///
/// This will also take care of instantiating a code completion consumer if
/// the user requested it and the action supports it.
- virtual void ExecuteAction();
+ void ExecuteAction() override;
public:
- virtual bool usesPreprocessorOnly() const { return false; }
+ bool usesPreprocessorOnly() const override { return false; }
};
class PluginASTAction : public ASTFrontendAction {
virtual void anchor();
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) = 0;
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override = 0;
public:
/// \brief Parse the given plugin command line arguments.
@@ -248,11 +246,11 @@
protected:
/// \brief Provide a default implementation which returns aborts;
/// this method should never be called by FrontendAction clients.
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
public:
- virtual bool usesPreprocessorOnly() const { return true; }
+ bool usesPreprocessorOnly() const override { return true; }
};
/// \brief A frontend action which simply wraps some other runtime-specified
@@ -262,28 +260,27 @@
/// some existing action's behavior. It implements every virtual method in
/// the FrontendAction interface by forwarding to the wrapped action.
class WrapperFrontendAction : public FrontendAction {
- OwningPtr<FrontendAction> WrappedAction;
+ std::unique_ptr<FrontendAction> WrappedAction;
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
- virtual bool BeginInvocation(CompilerInstance &CI);
- virtual bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename);
- virtual void ExecuteAction();
- virtual void EndSourceFileAction();
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+ bool BeginInvocation(CompilerInstance &CI) override;
+ bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
+ void ExecuteAction() override;
+ void EndSourceFileAction() override;
public:
/// Construct a WrapperFrontendAction from an existing action, taking
/// ownership of it.
WrapperFrontendAction(FrontendAction *WrappedAction);
- virtual bool usesPreprocessorOnly() const;
- virtual TranslationUnitKind getTranslationUnitKind();
- virtual bool hasPCHSupport() const;
- virtual bool hasASTFileSupport() const;
- virtual bool hasIRSupport() const;
- virtual bool hasCodeCompletionSupport() const;
+ bool usesPreprocessorOnly() const override;
+ TranslationUnitKind getTranslationUnitKind() override;
+ bool hasPCHSupport() const override;
+ bool hasASTFileSupport() const override;
+ bool hasIRSupport() const override;
+ bool hasCodeCompletionSupport() const override;
};
} // end namespace clang
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index f3d1276..a5db252 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -23,15 +23,15 @@
//===----------------------------------------------------------------------===//
class InitOnlyAction : public FrontendAction {
- virtual void ExecuteAction();
+ void ExecuteAction() override;
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
public:
// Don't claim to only use the preprocessor, we want to follow the AST path,
// but do nothing.
- virtual bool usesPreprocessorOnly() const { return false; }
+ bool usesPreprocessorOnly() const override { return false; }
};
//===----------------------------------------------------------------------===//
@@ -40,44 +40,44 @@
class ASTPrintAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class ASTDumpAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class ASTDeclListAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class ASTViewAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class DeclContextPrintAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class GeneratePCHAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
- virtual TranslationUnitKind getTranslationUnitKind() {
+ TranslationUnitKind getTranslationUnitKind() override {
return TU_Prefix;
}
- virtual bool hasASTFileSupport() const { return false; }
+ bool hasASTFileSupport() const override { return false; }
public:
/// \brief Compute the AST consumer arguments that will be used to
@@ -96,21 +96,21 @@
bool IsSystem;
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
-
- virtual TranslationUnitKind getTranslationUnitKind() {
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
+ TranslationUnitKind getTranslationUnitKind() override {
return TU_Module;
}
-
- virtual bool hasASTFileSupport() const { return false; }
-
+
+ bool hasASTFileSupport() const override { return false; }
+
public:
explicit GenerateModuleAction(bool IsSystem = false)
: ASTFrontendAction(), IsSystem(IsSystem) { }
- virtual bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename);
-
+ bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
+
/// \brief Compute the AST consumer arguments that will be used to
/// create the PCHGenerator instance returned by CreateASTConsumer.
///
@@ -124,26 +124,37 @@
class SyntaxOnlyAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
public:
- virtual bool hasCodeCompletionSupport() const { return true; }
+ bool hasCodeCompletionSupport() const override { return true; }
};
/// \brief Dump information about the given module file, to be used for
/// basic debugging and discovery.
class DumpModuleInfoAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
- virtual void ExecuteAction();
-
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+ void ExecuteAction() override;
+
public:
- virtual bool hasPCHSupport() const { return false; }
- virtual bool hasASTFileSupport() const { return true; }
- virtual bool hasIRSupport() const { return false; }
- virtual bool hasCodeCompletionSupport() const { return false; }
+ bool hasPCHSupport() const override { return false; }
+ bool hasASTFileSupport() const override { return true; }
+ bool hasIRSupport() const override { return false; }
+ bool hasCodeCompletionSupport() const override { return false; }
+};
+
+class VerifyPCHAction : public ASTFrontendAction {
+protected:
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
+ void ExecuteAction() override;
+
+public:
+ bool hasCodeCompletionSupport() const override { return false; }
};
/**
@@ -162,34 +173,34 @@
std::vector<std::string> ASTFiles;
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
- virtual bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename);
+ bool BeginSourceFileAction(CompilerInstance &CI,
+ StringRef Filename) override;
- virtual void ExecuteAction();
- virtual void EndSourceFileAction();
+ void ExecuteAction() override;
+ void EndSourceFileAction() override;
public:
ASTMergeAction(FrontendAction *AdaptedAction, ArrayRef<std::string> ASTFiles);
virtual ~ASTMergeAction();
- virtual bool usesPreprocessorOnly() const;
- virtual TranslationUnitKind getTranslationUnitKind();
- virtual bool hasPCHSupport() const;
- virtual bool hasASTFileSupport() const;
- virtual bool hasCodeCompletionSupport() const;
+ bool usesPreprocessorOnly() const override;
+ TranslationUnitKind getTranslationUnitKind() override;
+ bool hasPCHSupport() const override;
+ bool hasASTFileSupport() const override;
+ bool hasCodeCompletionSupport() const override;
};
class PrintPreambleAction : public FrontendAction {
protected:
- void ExecuteAction();
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) {
- return 0;
+ void ExecuteAction() override;
+ ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) override {
+ return 0;
}
-
- virtual bool usesPreprocessorOnly() const { return true; }
+
+ bool usesPreprocessorOnly() const override { return true; }
};
//===----------------------------------------------------------------------===//
@@ -198,29 +209,29 @@
class DumpRawTokensAction : public PreprocessorFrontendAction {
protected:
- void ExecuteAction();
+ void ExecuteAction() override;
};
class DumpTokensAction : public PreprocessorFrontendAction {
protected:
- void ExecuteAction();
+ void ExecuteAction() override;
};
class GeneratePTHAction : public PreprocessorFrontendAction {
protected:
- void ExecuteAction();
+ void ExecuteAction() override;
};
class PreprocessOnlyAction : public PreprocessorFrontendAction {
protected:
- void ExecuteAction();
+ void ExecuteAction() override;
};
class PrintPreprocessedAction : public PreprocessorFrontendAction {
protected:
- void ExecuteAction();
+ void ExecuteAction() override;
- virtual bool hasPCHSupport() const { return true; }
+ bool hasPCHSupport() const override { return true; }
};
} // end namespace clang
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 4b321e8..fc13b19 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -43,6 +43,7 @@
GeneratePTH, ///< Generate pre-tokenized header.
InitOnly, ///< Only execute frontend initialization.
ModuleFileInfo, ///< Dump information about a module file.
+ VerifyPCH, ///< Load and verify that a PCH file is usable.
ParseSyntaxOnly, ///< Parse and perform semantic analysis.
PluginAction, ///< Run a plugin action, \see ActionName.
PrintDeclContext, ///< Print DeclContext and their Decls.
@@ -179,10 +180,13 @@
ObjCMT_ReturnsInnerPointerProperty = 0x200,
/// \brief use NS_NONATOMIC_IOSONLY for property 'atomic' attribute
ObjCMT_NsAtomicIOSOnlyProperty = 0x400,
+ /// \brief Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
+ ObjCMT_DesignatedInitializer = 0x800,
ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty |
ObjCMT_Annotation | ObjCMT_Instancetype |
ObjCMT_NsMacros | ObjCMT_ProtocolConformance |
- ObjCMT_NsAtomicIOSOnlyProperty),
+ ObjCMT_NsAtomicIOSOnlyProperty |
+ ObjCMT_DesignatedInitializer),
ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls)
};
unsigned ObjCMTAction;
diff --git a/include/clang/Frontend/LayoutOverrideSource.h b/include/clang/Frontend/LayoutOverrideSource.h
index ec34e14..16d032b 100644
--- a/include/clang/Frontend/LayoutOverrideSource.h
+++ b/include/clang/Frontend/LayoutOverrideSource.h
@@ -47,12 +47,13 @@
/// \brief If this particular record type has an overridden layout,
/// return that layout.
- virtual bool
+ 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);
+ llvm::DenseMap<const CXXRecordDecl *,
+ CharUnits> &VirtualBaseOffsets) override;
/// \brief Dump the overridden layouts.
void dump();
diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h
index e8a6bb3..4ef643e 100644
--- a/include/clang/Frontend/LogDiagnosticPrinter.h
+++ b/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -62,14 +62,14 @@
DwarfDebugFlags = Value;
}
- void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) {
+ void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override {
LangOpts = &LO;
}
- void EndSourceFile();
+ void EndSourceFile() override;
- virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info);
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) override;
};
} // end namespace clang
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
index 6ea7547..6ea1d73 100644
--- a/include/clang/Frontend/MultiplexConsumer.h
+++ b/include/clang/Frontend/MultiplexConsumer.h
@@ -17,7 +17,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Sema/SemaConsumer.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
#include <vector>
namespace clang {
@@ -33,28 +33,28 @@
~MultiplexConsumer();
// ASTConsumer
- virtual void Initialize(ASTContext &Context);
- virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);
- virtual bool HandleTopLevelDecl(DeclGroupRef D);
- virtual void HandleInterestingDecl(DeclGroupRef D);
- virtual void HandleTranslationUnit(ASTContext &Ctx);
- virtual void HandleTagDeclDefinition(TagDecl *D);
- virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D);
- virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
- virtual void CompleteTentativeDefinition(VarDecl *D);
- virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired);
- virtual ASTMutationListener *GetASTMutationListener();
- virtual ASTDeserializationListener *GetASTDeserializationListener();
- virtual void PrintStats();
+ void Initialize(ASTContext &Context) override;
+ void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override;
+ bool HandleTopLevelDecl(DeclGroupRef D) override;
+ void HandleInterestingDecl(DeclGroupRef D) override;
+ void HandleTranslationUnit(ASTContext &Ctx) override;
+ void HandleTagDeclDefinition(TagDecl *D) override;
+ void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override;
+ void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
+ void CompleteTentativeDefinition(VarDecl *D) override;
+ void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override;
+ ASTMutationListener *GetASTMutationListener() override;
+ ASTDeserializationListener *GetASTDeserializationListener() override;
+ void PrintStats() override;
// SemaConsumer
- virtual void InitializeSema(Sema &S);
- virtual void ForgetSema();
+ void InitializeSema(Sema &S) override;
+ void ForgetSema() override;
private:
std::vector<ASTConsumer*> Consumers; // Owns these.
- OwningPtr<MultiplexASTMutationListener> MutationListener;
- OwningPtr<MultiplexASTDeserializationListener> DeserializationListener;
+ std::unique_ptr<MultiplexASTMutationListener> MutationListener;
+ std::unique_ptr<MultiplexASTDeserializationListener> DeserializationListener;
};
} // end namespace clang
diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h
index 117771d..4dda1fa 100644
--- a/include/clang/Frontend/SerializedDiagnosticPrinter.h
+++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h
@@ -46,6 +46,19 @@
RECORD_LAST = RECORD_FIXIT
};
+/// A stable version of DiagnosticIDs::Level.
+///
+/// Do not change the order of values in this enum, and please increment the
+/// serialized diagnostics version number when you add to it.
+enum Level {
+ Ignored = 0,
+ Note,
+ Warning,
+ Error,
+ Fatal,
+ Remark
+};
+
/// \brief Returns a DiagnosticConsumer that serializes diagnostics to
/// a bitcode file.
///
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
index c8d01b0..2aa9576 100644
--- a/include/clang/Frontend/TextDiagnostic.h
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -77,38 +77,38 @@
bool ShowColors);
protected:
- virtual void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
- DiagnosticsEngine::Level Level,
- StringRef Message,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager *SM,
- DiagOrStoredDiag D);
+ void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ StringRef Message,
+ ArrayRef<CharSourceRange> Ranges,
+ const SourceManager *SM,
+ DiagOrStoredDiag D) override;
- virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
- DiagnosticsEngine::Level Level,
- ArrayRef<CharSourceRange> Ranges,
- const SourceManager &SM);
-
- virtual void emitCodeContext(SourceLocation Loc,
- DiagnosticsEngine::Level Level,
- SmallVectorImpl<CharSourceRange>& Ranges,
- ArrayRef<FixItHint> Hints,
- const SourceManager &SM) {
+ void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges,
+ const SourceManager &SM) override;
+
+ void emitCodeContext(SourceLocation Loc,
+ DiagnosticsEngine::Level Level,
+ SmallVectorImpl<CharSourceRange>& Ranges,
+ ArrayRef<FixItHint> Hints,
+ const SourceManager &SM) override {
emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM);
}
-
- virtual void emitBasicNote(StringRef Message);
-
- virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
- const SourceManager &SM);
- virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+ void emitBasicNote(StringRef Message) override;
+
+ void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+ const SourceManager &SM) override;
+
+ void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM) override;
+
+ void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
- const SourceManager &SM);
-
- virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
- StringRef ModuleName,
- const SourceManager &SM);
+ const SourceManager &SM) override;
private:
void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
index 93ac299..feff798 100644
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -39,8 +39,8 @@
const_iterator note_begin() const { return Notes.begin(); }
const_iterator note_end() const { return Notes.end(); }
- virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info);
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) override;
/// FlushDiagnostics - Flush the buffered diagnostics to an given
/// diagnostic engine.
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index dc80470..9f6d5ff 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -18,7 +18,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
namespace clang {
class DiagnosticOptions;
@@ -30,7 +30,7 @@
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
/// \brief Handle to the currently active text diagnostic emitter.
- OwningPtr<TextDiagnostic> TextDiag;
+ std::unique_ptr<TextDiagnostic> TextDiag;
/// A string to prefix to error messages.
std::string Prefix;
@@ -47,9 +47,10 @@
/// used.
void setPrefix(std::string Value) { Prefix = Value; }
- void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP);
- void EndSourceFile();
- void HandleDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
+ void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override;
+ void EndSourceFile() override;
+ void HandleDiagnostic(DiagnosticsEngine::Level Level,
+ const Diagnostic &Info) override;
};
} // end namespace clang
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index dff56c3..63eecb1 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -30,6 +30,7 @@
namespace clang {
class ASTConsumer;
+class ASTReader;
class CompilerInstance;
class CompilerInvocation;
class Decl;
@@ -72,10 +73,18 @@
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
const PreprocessorOutputOptions &Opts);
-/// AttachDependencyFileGen - Create a dependency file generator, and attach
-/// it to the given preprocessor. This takes ownership of the output stream.
-void AttachDependencyFileGen(Preprocessor &PP,
- const DependencyOutputOptions &Opts);
+/// Builds a depdenency file when attached to a Preprocessor (for includes) and
+/// ASTReader (for module imports), and writes it out at the end of processing
+/// a source file. Users should attach to the ast reader whenever a module is
+/// loaded.
+class DependencyFileGenerator {
+ void *Impl; // Opaque implementation
+ DependencyFileGenerator(void *Impl);
+public:
+ static DependencyFileGenerator *CreateAndAttachToPreprocessor(
+ Preprocessor &PP, const DependencyOutputOptions &Opts);
+ void AttachToASTReader(ASTReader &R);
+};
/// AttachDependencyGraphGen - Create a dependency graph generator, and attach
/// it to the given preprocessor.
@@ -123,6 +132,22 @@
return getLastArgIntValue(Args, Id, Default, &Diags);
}
+uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
+ llvm::opt::OptSpecifier Id, uint64_t Default,
+ DiagnosticsEngine *Diags = 0);
+
+inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
+ llvm::opt::OptSpecifier Id,
+ uint64_t Default,
+ DiagnosticsEngine &Diags) {
+ return getLastArgUInt64Value(Args, Id, Default, &Diags);
+}
+
+// When Clang->getFrontendOpts().DisableFree is set we don't delete some of the
+// global objects, but we don't want LeakDetectors to complain, so we bury them
+// in a globally visible array.
+void BuryPointer(const void *Ptr);
+
} // end namespace clang
#endif
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index 95d7752..39678ef 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -13,10 +13,10 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include <climits>
+#include <memory>
namespace clang {
@@ -108,10 +108,11 @@
///
/// In this example, the diagnostic may appear only once, if at all.
///
-/// Regex matching mode may be selected by appending '-re' to type, such as:
+/// Regex matching mode may be selected by appending '-re' to type and
+/// including regexes wrapped in double curly braces in the directive, such as:
///
/// \code
-/// expected-error-re
+/// expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}}
/// \endcode
///
/// Examples matching error: "variable has incomplete type 'struct s'"
@@ -120,10 +121,10 @@
/// // expected-error {{variable has incomplete type 'struct s'}}
/// // expected-error {{variable has incomplete type}}
///
-/// // expected-error-re {{variable has has type 'struct .'}}
-/// // expected-error-re {{variable has has type 'struct .*'}}
-/// // expected-error-re {{variable has has type 'struct (.*)'}}
-/// // expected-error-re {{variable has has type 'struct[[:space:]](.*)'}}
+/// // expected-error-re {{variable has type 'struct {{.}}'}}
+/// // expected-error-re {{variable has type 'struct {{.*}}'}}
+/// // expected-error-re {{variable has type 'struct {{(.*)}}'}}
+/// // expected-error-re {{variable has type 'struct{{[[:space:]](.*)}}'}}
/// \endcode
///
/// VerifyDiagnosticConsumer expects at least one expected-* directive to
@@ -203,7 +204,7 @@
DiagnosticsEngine &Diags;
DiagnosticConsumer *PrimaryClient;
bool OwnsPrimaryClient;
- OwningPtr<TextDiagnosticBuffer> Buffer;
+ std::unique_ptr<TextDiagnosticBuffer> Buffer;
const Preprocessor *CurrentPreprocessor;
const LangOptions *LangOpts;
SourceManager *SrcManager;
@@ -217,24 +218,19 @@
SrcManager = &SM;
}
-#ifndef NDEBUG
+ // These facilities are used for validation in debug builds.
class UnparsedFileStatus {
llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
-
public:
UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
: Data(File, FoundDirectives) {}
-
const FileEntry *getFile() const { return Data.getPointer(); }
bool foundDirectives() const { return Data.getInt(); }
};
-
typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap;
typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap;
-
ParsedFilesMap ParsedFiles;
UnparsedFilesMap UnparsedFiles;
-#endif
public:
/// Create a new verifying diagnostic client, which will issue errors to
@@ -243,10 +239,10 @@
VerifyDiagnosticConsumer(DiagnosticsEngine &Diags);
~VerifyDiagnosticConsumer();
- virtual void BeginSourceFile(const LangOptions &LangOpts,
- const Preprocessor *PP);
+ void BeginSourceFile(const LangOptions &LangOpts,
+ const Preprocessor *PP) override;
- virtual void EndSourceFile();
+ void EndSourceFile() override;
enum ParsedStatus {
/// File has been processed via HandleComment.
@@ -262,10 +258,10 @@
/// \brief Update lists of parsed and unparsed files.
void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
- virtual bool HandleComment(Preprocessor &PP, SourceRange Comment);
+ bool HandleComment(Preprocessor &PP, SourceRange Comment) override;
- virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info);
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) override;
};
} // end namspace clang
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
index 7b0fd50..3195dee 100644
--- a/include/clang/Index/USRGeneration.h
+++ b/include/clang/Index/USRGeneration.h
@@ -14,7 +14,9 @@
#include "llvm/ADT/StringRef.h"
namespace clang {
- class Decl;
+class Decl;
+class MacroDefinition;
+class SourceManager;
namespace index {
@@ -22,7 +24,7 @@
return "c:";
}
-/// \brief Generate a USR for a Decl, including the prefix.
+/// \brief Generate a USR for a Decl, including the USR prefix.
/// \returns true if the results should be ignored, false otherwise.
bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
@@ -47,6 +49,12 @@
/// \brief Generate a USR fragment for an Objective-C protocol.
void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
+/// \brief Generate a USR for a macro, including the USR prefix.
+///
+/// \returns true on error, false on success.
+bool generateUSRForMacro(const MacroDefinition *MD, const SourceManager &SM,
+ SmallVectorImpl<char> &Buf);
+
} // namespace index
} // namespace clang
diff --git a/include/clang/Lex/CMakeLists.txt b/include/clang/Lex/CMakeLists.txt
deleted file mode 100644
index 38055eb..0000000
--- a/include/clang/Lex/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-clang_tablegen(AttrSpellings.inc -gen-clang-attr-spelling-list
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrSpellings
- DEPENDS AttrSpellings.inc)
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index dff3e8c..16899a0 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -161,11 +161,17 @@
/// \param [out] InUserSpecifiedSystemFramework If the file is found,
/// set to true if the file is located in a framework that has been
/// user-specified to be treated as a system framework.
- const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
+ ///
+ /// \param [out] MappedName if this is a headermap which maps the filename to
+ /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
+ /// vector and point Filename to it.
+ const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
ModuleMap::KnownHeader *SuggestedModule,
- bool &InUserSpecifiedSystemFramework) const;
+ bool &InUserSpecifiedSystemFramework,
+ bool &HasBeenMapped,
+ SmallVectorImpl<char> &MappedName) const;
private:
const FileEntry *DoFrameworkLookup(
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 8473a6a..8e78b5a 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -55,6 +55,11 @@
/// "../../file.h".
const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
+ /// If the specified relative filename is located in this HeaderMap return
+ /// the filename it is mapped to, otherwise return an empty StringRef.
+ StringRef lookupFilename(StringRef Filename,
+ SmallVectorImpl<char> &DestPath) const;
+
/// getFileName - Return the filename of the headermap.
const char *getFileName() const;
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index fb1a862..c3af633 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -18,10 +18,10 @@
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Allocator.h"
+#include <memory>
#include <vector>
namespace clang {
@@ -73,6 +73,9 @@
/// provided via a header map. This bit indicates when this is one of
/// those framework headers.
unsigned IndexHeaderMapHeader : 1;
+
+ /// \brief Whether this file had been looked up as a header.
+ unsigned IsValid : 1;
/// \brief The number of times the file has been included already.
unsigned short NumIncludes;
@@ -102,7 +105,7 @@
: isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
External(false), isModuleHeader(false), isCompilingModuleHeader(false),
HeaderRole(ModuleMap::NormalHeader),
- Resolved(false), IndexHeaderMapHeader(false),
+ Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {}
/// \brief Retrieve the controlling macro for this header file, if
@@ -158,6 +161,7 @@
/// \brief Header-search options used to initialize this header search.
IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
+ DiagnosticsEngine &Diags;
FileManager &FileMgr;
/// \#include search path information. Requests for \#include "x" search the
/// directory of the \#including file first, then each directory in SearchDirs
@@ -185,15 +189,27 @@
/// included, indexed by the FileEntry's UID.
std::vector<HeaderFileInfo> FileInfo;
- /// \brief Keeps track of each lookup performed by LookupFile.
- ///
- /// The first part of the value is the starting index in SearchDirs
- /// that the cached search was performed from. If there is a hit and
- /// this value doesn't match the current query, the cache has to be
- /// ignored. The second value is the entry in SearchDirs that satisfied
- /// the query.
- llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
- LookupFileCache;
+ /// Keeps track of each lookup performed by LookupFile.
+ struct LookupFileCacheInfo {
+ /// Starting index in SearchDirs that the cached search was performed from.
+ /// If there is a hit and this value doesn't match the current query, the
+ /// cache has to be ignored.
+ unsigned StartIdx;
+ /// The entry in SearchDirs that satisfied the query.
+ unsigned HitIdx;
+ /// This is non-null if the original filename was mapped to a framework
+ /// include via a headermap.
+ const char *MappedName;
+
+ /// Default constructor -- Initialize all members with zero.
+ LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {}
+
+ void reset(unsigned StartIdx) {
+ this->StartIdx = StartIdx;
+ this->MappedName = nullptr;
+ }
+ };
+ llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
/// \brief Collection mapping a framework or subframework
/// name like "Carbon" to the Carbon.framework directory.
@@ -204,7 +220,7 @@
/// include_alias pragma for Microsoft compatibility.
typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
IncludeAliasMap;
- OwningPtr<IncludeAliasMap> IncludeAliases;
+ std::unique_ptr<IncludeAliasMap> IncludeAliases;
/// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
/// headermaps. This vector owns the headermap.
@@ -232,6 +248,8 @@
unsigned NumMultiIncludeFileOptzn;
unsigned NumFrameworkLookups, NumSubFrameworkLookups;
+ bool EnabledModules;
+
// HeaderSearch doesn't support default or copy construction.
HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION;
void operator=(const HeaderSearch&) LLVM_DELETED_FUNCTION;
@@ -278,9 +296,7 @@
}
/// \brief Checks whether the map exists or not.
- bool HasIncludeAliasMap() const {
- return IncludeAliases.isValid();
- }
+ bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
/// \brief Map the source include name to the dest include name.
///
@@ -347,13 +363,15 @@
/// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
/// the file was found in, or null if not applicable.
///
+ /// \param IncludeLoc Used for diagnostics if valid.
+ ///
/// \param isAngled indicates whether the file reference is a <> reference.
///
/// \param CurDir If non-null, the file was found in the specified directory
/// search location. This is used to implement \#include_next.
///
- /// \param CurFileEnt If non-null, indicates where the \#including file is, in
- /// case a relative search is needed.
+ /// \param Includers Indicates where the \#including file(s) are, in case
+ /// relative searches are needed. In reverse order of inclusion.
///
/// \param SearchPath If non-null, will be set to the search path relative
/// to which the file was found. If the include path is absolute, SearchPath
@@ -366,10 +384,10 @@
/// \param SuggestedModule If non-null, and the file found is semantically
/// part of a known module, this will be set to the module that should
/// be imported instead of preprocessing/parsing the file found.
- const FileEntry *LookupFile(StringRef Filename, bool isAngled,
- const DirectoryLookup *FromDir,
+ const FileEntry *LookupFile(StringRef Filename, SourceLocation IncludeLoc,
+ bool isAngled, const DirectoryLookup *FromDir,
const DirectoryLookup *&CurDir,
- const FileEntry *CurFileEnt,
+ ArrayRef<const FileEntry *> Includers,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
ModuleMap::KnownHeader *SuggestedModule,
@@ -458,6 +476,9 @@
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
+ /// Returns true if modules are enabled.
+ bool enabledModules() const { return EnabledModules; }
+
/// \brief Retrieve the name of the module file that should be used to
/// load the given module.
///
@@ -486,11 +507,18 @@
///
/// \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,
+ bool IsFramework);
void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
/// \brief Determine whether there is a module map that may map the header
/// with the given file name to a (sub)module.
+ /// Always returns false if modules are disabled.
///
/// \param Filename The name of the file.
///
@@ -543,16 +571,20 @@
/// of the given search directory.
void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
+ /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
+ const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
+ return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
+ }
+
public:
/// \brief Retrieve the module map.
ModuleMap &getModuleMap() { return ModMap; }
unsigned header_file_size() const { return FileInfo.size(); }
- /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
- const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
- return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
- }
+ /// \brief Get a \c HeaderFileInfo structure for the specified \c FileEntry,
+ /// if one exists.
+ bool tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const;
// Used by external tools
typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
@@ -602,26 +634,32 @@
/// invalid.
LMM_InvalidModuleMap
};
-
+
+ LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File,
+ bool IsSystem);
+
/// \brief Try to load the module map file in the given directory.
///
/// \param DirName The name of the directory where we will look for a module
/// map file.
/// \param IsSystem Whether this is a system header directory.
+ /// \param IsFramework Whether this is a framework directory.
///
/// \returns The result of attempting to load the module map file from the
/// named directory.
- LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem);
+ LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
+ bool IsFramework);
/// \brief Try to load the module map file in the given directory.
///
/// \param Dir The directory where we will look for a module map file.
/// \param IsSystem Whether this is a system header directory.
+ /// \param IsFramework Whether this is a framework directory.
///
/// \returns The result of attempting to load the module map file from the
/// named directory.
LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir,
- bool IsSystem);
+ bool IsSystem, bool IsFramework);
/// \brief Return the HeaderFileInfo structure for the specified FileEntry.
HeaderFileInfo &getFileInfo(const FileEntry *FE);
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index b563b38..06024b2 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -58,20 +58,6 @@
bool ignoreSysRoot)
: Path(path), Group(group), IsFramework(isFramework),
IgnoreSysRoot(ignoreSysRoot) {}
-
- Entry(const Entry& rhs)
- : Path(rhs.Path), Group(rhs.Group), IsFramework(rhs.IsFramework),
- IgnoreSysRoot(rhs.IgnoreSysRoot) {}
-
- Entry& operator=(const Entry& rhs)
- {
- if (this == &rhs)
- return *this;
- Path = rhs.Path;
- Group = rhs.Group;
- IsFramework = rhs.IsFramework;
- IgnoreSysRoot = rhs.IgnoreSysRoot;
- }
};
struct SystemHeaderPrefix {
@@ -103,6 +89,9 @@
/// \brief The directory used for the module cache.
std::string ModuleCachePath;
+ /// \brief The directory used for a user build.
+ std::string ModuleUserBuildPath;
+
/// \brief Whether we should disable the use of the hash string within the
/// module cache.
///
@@ -130,6 +119,12 @@
/// regenerated often.
unsigned ModuleCachePruneAfter;
+ /// \brief The time in seconds when the build session started.
+ ///
+ /// This time is used by other optimizations in header search and module
+ /// loading.
+ uint64_t BuildSessionTimestamp;
+
/// \brief The set of macro names that should be ignored for the purposes
/// of computing the module hash.
llvm::SetVector<std::string> ModulesIgnoreMacros;
@@ -137,6 +132,9 @@
/// \brief The set of user-provided module-map-files.
llvm::SetVector<std::string> ModuleMapFiles;
+ /// \brief The set of user-provided virtual filesystem overlay files.
+ std::vector<std::string> VFSOverlayFiles;
+
/// Include the compiler builtin includes.
unsigned UseBuiltinIncludes : 1;
@@ -152,14 +150,25 @@
/// Whether header search information should be output as for -v.
unsigned Verbose : 1;
+ /// \brief If true, skip verifying input files used by modules if the
+ /// module was already verified during this build session (see
+ /// \c BuildSessionTimestamp).
+ unsigned ModulesValidateOncePerBuildSession : 1;
+
+ /// \brief Whether to validate system input files when a module is loaded.
+ unsigned ModulesValidateSystemHeaders : 1;
+
public:
HeaderSearchOptions(StringRef _Sysroot = "/")
: Sysroot(_Sysroot), DisableModuleHash(0), ModuleMaps(0),
ModuleCachePruneInterval(7*24*60*60),
ModuleCachePruneAfter(31*24*60*60),
+ BuildSessionTimestamp(0),
UseBuiltinIncludes(true),
UseStandardSystemIncludes(true), UseStandardCXXIncludes(true),
- UseLibcxx(false), Verbose(false) {}
+ UseLibcxx(false), Verbose(false),
+ ModulesValidateOncePerBuildSession(false),
+ ModulesValidateSystemHeaders(false) {}
/// AddPath - Add the \p Path path to the specified \p Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
@@ -173,6 +182,10 @@
void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
SystemHeaderPrefixes.push_back(SystemHeaderPrefix(Prefix, IsSystemHeader));
}
+
+ void AddVFSOverlayFile(StringRef Name) {
+ VFSOverlayFiles.push_back(Name);
+ }
};
} // end namespace clang
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index f456fa9..513eb88 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -44,7 +44,7 @@
/// or buffering/seeking of tokens, only forward lexing is supported. It relies
/// on the specified Preprocessor object to handle preprocessor directives, etc.
class Lexer : public PreprocessorLexer {
- virtual void anchor();
+ void anchor() override;
//===--------------------------------------------------------------------===//
// Constant configuration values for this lexer.
@@ -145,7 +145,7 @@
private:
/// IndirectLex - An indirect call to 'Lex' that can be invoked via
/// the PreprocessorLexer interface.
- void IndirectLex(Token &Result) { Lex(Result); }
+ void IndirectLex(Token &Result) override { Lex(Result); }
public:
/// LexFromRawLexer - Lex a token from a designated raw lexer (one with no
@@ -218,7 +218,9 @@
/// getSourceLocation - Return a source location for the next character in
/// the current file.
- SourceLocation getSourceLocation() { return getSourceLocation(BufferPtr); }
+ SourceLocation getSourceLocation() override {
+ return getSourceLocation(BufferPtr);
+ }
/// \brief Return the current location in the buffer.
const char *getBufferLocation() const { return BufferPtr; }
@@ -614,8 +616,28 @@
/// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is
/// invalid.
uint32_t tryReadUCN(const char *&CurPtr, const char *SlashLoc, Token *Tok);
-};
+ /// \brief Try to consume a UCN as part of an identifier at the current
+ /// location.
+ /// \param CurPtr Initially points to the range of characters in the source
+ /// buffer containing the '\'. Updated to point past the end of
+ /// the UCN on success.
+ /// \param Size The number of characters occupied by the '\' (including
+ /// trigraphs and escaped newlines).
+ /// \param Result The token being produced. Marked as containing a UCN on
+ /// success.
+ /// \return \c true if a UCN was lexed and it produced an acceptable
+ /// identifier character, \c false otherwise.
+ bool tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size,
+ Token &Result);
+
+ /// \brief Try to consume an identifier character encoded in UTF-8.
+ /// \param CurPtr Points to the start of the (potential) UTF-8 code unit
+ /// sequence. On success, updated to point past the end of it.
+ /// \return \c true if a UTF-8 sequence mapping to an acceptable identifier
+ /// character was lexed, \c false otherwise.
+ bool tryConsumeIdentifierUTF8Char(const char *&CurPtr);
+};
} // end namespace clang
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 64d5aa2..3e52418 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -33,6 +33,9 @@
class SourceManager;
class LangOptions;
+/// Copy characters from Input to Buf, expanding any UCNs.
+void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input);
+
/// NumericLiteralParser - This performs strict semantic analysis of the content
/// of a ppnumber, classifying it as either integer, floating, or erroneous,
/// determines the radix of the value and can convert it to a useful value.
@@ -48,6 +51,8 @@
bool saw_exponent, saw_period, saw_ud_suffix;
+ SmallString<32> UDSuffixBuf;
+
public:
NumericLiteralParser(StringRef TokSpelling,
SourceLocation TokLoc,
@@ -72,7 +77,7 @@
}
StringRef getUDSuffix() const {
assert(saw_ud_suffix);
- return StringRef(SuffixBegin, ThisTokEnd - SuffixBegin);
+ return UDSuffixBuf;
}
unsigned getUDSuffixOffset() const {
assert(saw_ud_suffix);
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 8cb370e..1580d1b 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -21,7 +21,7 @@
#include <cassert>
namespace clang {
- class Preprocessor;
+class Preprocessor;
/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
///
@@ -338,12 +338,6 @@
/// \brief True if the macro directive was loaded from a PCH file.
bool IsFromPCH : 1;
- /// \brief Whether the macro directive is currently "hidden".
- ///
- /// Note that this is transient state that is never serialized to the AST
- /// file.
- bool IsHidden : 1;
-
// Used by DefMacroDirective -----------------------------------------------//
/// \brief True if this macro was imported from a module.
@@ -360,10 +354,10 @@
bool IsPublic : 1;
MacroDirective(Kind K, SourceLocation Loc)
- : Previous(0), Loc(Loc), MDKind(K), IsFromPCH(false), IsHidden(false),
+ : Previous(0), Loc(Loc), MDKind(K), IsFromPCH(false),
IsImported(false), IsAmbiguous(false),
IsPublic(true) {
- }
+ }
public:
Kind getKind() const { return Kind(MDKind); }
@@ -386,12 +380,6 @@
void setIsFromPCH() { IsFromPCH = true; }
- /// \brief Determine whether this macro directive is hidden.
- bool isHidden() const { return IsHidden; }
-
- /// \brief Set whether this macro directive is hidden.
- void setHidden(bool Val) { IsHidden = Val; }
-
class DefInfo {
DefMacroDirective *DefDirective;
SourceLocation UndefLoc;
@@ -423,31 +411,31 @@
LLVM_EXPLICIT operator bool() const { return isValid(); }
- inline DefInfo getPreviousDefinition(bool AllowHidden = false);
- const DefInfo getPreviousDefinition(bool AllowHidden = false) const {
- return const_cast<DefInfo*>(this)->getPreviousDefinition(AllowHidden);
+ inline DefInfo getPreviousDefinition();
+ const DefInfo getPreviousDefinition() const {
+ return const_cast<DefInfo*>(this)->getPreviousDefinition();
}
};
/// \brief Traverses the macro directives history and returns the next
/// macro definition directive along with info about its undefined location
/// (if there is one) and if it is public or private.
- DefInfo getDefinition(bool AllowHidden = false);
- const DefInfo getDefinition(bool AllowHidden = false) const {
- return const_cast<MacroDirective*>(this)->getDefinition(AllowHidden);
+ DefInfo getDefinition();
+ const DefInfo getDefinition() const {
+ return const_cast<MacroDirective*>(this)->getDefinition();
}
- bool isDefined(bool AllowHidden = false) const {
- if (const DefInfo Def = getDefinition(AllowHidden))
+ bool isDefined() const {
+ if (const DefInfo Def = getDefinition())
return !Def.isUndefined();
return false;
}
- const MacroInfo *getMacroInfo(bool AllowHidden = false) const {
- return getDefinition(AllowHidden).getMacroInfo();
+ const MacroInfo *getMacroInfo() const {
+ return getDefinition().getMacroInfo();
}
- MacroInfo *getMacroInfo(bool AllowHidden = false) {
- return getDefinition(AllowHidden).getMacroInfo();
+ MacroInfo *getMacroInfo() {
+ return getDefinition().getMacroInfo();
}
/// \brief Find macro definition active in the specified source location. If
@@ -538,10 +526,10 @@
}
inline MacroDirective::DefInfo
-MacroDirective::DefInfo::getPreviousDefinition(bool AllowHidden) {
+MacroDirective::DefInfo::getPreviousDefinition() {
if (isInvalid() || DefDirective->getPrevious() == 0)
return DefInfo();
- return DefDirective->getPrevious()->getDefinition(AllowHidden);
+ return DefDirective->getPrevious()->getDefinition();
}
} // end namespace clang
diff --git a/include/clang/Lex/Makefile b/include/clang/Lex/Makefile
deleted file mode 100644
index 762b9a2..0000000
--- a/include/clang/Lex/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-CLANG_LEVEL := ../../..
-TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrSpellings.inc
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/AttrSpellings.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute spellings with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-spelling-list -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 3a17157..1cd6d38 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -38,7 +38,7 @@
class ModuleMap {
SourceManager &SourceMgr;
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
+ DiagnosticsEngine &Diags;
const LangOptions &LangOpts;
const TargetInfo *Target;
HeaderSearch &HeaderInfo;
@@ -175,6 +175,13 @@
/// resolved.
Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
+ /// \brief Looks up the modules that \p File corresponds to.
+ ///
+ /// If \p File represents a builtin header within Clang's builtin include
+ /// directory, this also loads all of the module maps to see if it will get
+ /// associated with a specific module (e.g. in /usr/include).
+ HeadersMap::iterator findKnownHeader(const FileEntry *File);
+
public:
/// \brief Construct a new module map.
///
@@ -182,13 +189,12 @@
/// This source manager should be shared with the header-search mechanism,
/// since they will refer to the same headers.
///
- /// \param DC A diagnostic consumer that will be cloned for use in generating
- /// diagnostics.
+ /// \param Diags A diagnostic engine used for diagnostics.
///
/// \param LangOpts Language options for this translation unit.
///
/// \param Target The target for this translation unit.
- ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC,
+ ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
const LangOptions &LangOpts, const TargetInfo *Target,
HeaderSearch &HeaderInfo);
@@ -219,6 +225,19 @@
KnownHeader findModuleForHeader(const FileEntry *File,
Module *RequestingModule = NULL);
+ /// \brief Reports errors if a module must not include a specific file.
+ ///
+ /// \param RequestingModule The module including a file.
+ ///
+ /// \param FilenameLoc The location of the inclusion's filename.
+ ///
+ /// \param Filename The included filename as written.
+ ///
+ /// \param File The included file.
+ void diagnoseHeaderInclusion(Module *RequestingModule,
+ SourceLocation FilenameLoc, StringRef Filename,
+ const FileEntry *File);
+
/// \brief Determine whether the given header is part of a module
/// marked 'unavailable'.
bool isHeaderInUnavailableModule(const FileEntry *Header) const;
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 0e11218..974ab55 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -267,6 +267,10 @@
virtual void SourceRangeSkipped(SourceRange Range) {
}
+ enum ConditionValueKind {
+ CVK_NotEvaluated, CVK_False, CVK_True
+ };
+
/// \brief Hook called whenever an \#if is seen.
/// \param Loc the source location of the directive.
/// \param ConditionRange The SourceRange of the expression being tested.
@@ -274,7 +278,7 @@
///
// FIXME: better to pass in a list (or tree!) of Tokens.
virtual void If(SourceLocation Loc, SourceRange ConditionRange,
- bool ConditionValue) {
+ ConditionValueKind ConditionValue) {
}
/// \brief Hook called whenever an \#elif is seen.
@@ -284,7 +288,7 @@
/// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
// FIXME: better to pass in a list (or tree!) of Tokens.
virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
- bool ConditionValue, SourceLocation IfLoc) {
+ ConditionValueKind ConditionValue, SourceLocation IfLoc) {
}
/// \brief Hook called whenever an \#ifdef is seen.
@@ -329,35 +333,31 @@
delete First;
}
- virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- SrcMgr::CharacteristicKind FileType,
- FileID PrevFID) {
+ void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+ SrcMgr::CharacteristicKind FileType,
+ FileID PrevFID) override {
First->FileChanged(Loc, Reason, FileType, PrevFID);
Second->FileChanged(Loc, Reason, FileType, PrevFID);
}
- virtual void FileSkipped(const FileEntry &ParentFile,
- const Token &FilenameTok,
- SrcMgr::CharacteristicKind FileType) {
+ void FileSkipped(const FileEntry &ParentFile,
+ const Token &FilenameTok,
+ SrcMgr::CharacteristicKind FileType) override {
First->FileSkipped(ParentFile, FilenameTok, FileType);
Second->FileSkipped(ParentFile, FilenameTok, FileType);
}
- virtual bool FileNotFound(StringRef FileName,
- SmallVectorImpl<char> &RecoveryPath) {
+ bool FileNotFound(StringRef FileName,
+ SmallVectorImpl<char> &RecoveryPath) override {
return First->FileNotFound(FileName, RecoveryPath) ||
Second->FileNotFound(FileName, RecoveryPath);
}
- virtual void InclusionDirective(SourceLocation HashLoc,
- const Token &IncludeTok,
- StringRef FileName,
- bool IsAngled,
- CharSourceRange FilenameRange,
- const FileEntry *File,
- StringRef SearchPath,
- StringRef RelativePath,
- const Module *Imported) {
+ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+ StringRef FileName, bool IsAngled,
+ CharSourceRange FilenameRange, const FileEntry *File,
+ StringRef SearchPath, StringRef RelativePath,
+ const Module *Imported) override {
First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
FilenameRange, File, SearchPath, RelativePath,
Imported);
@@ -366,147 +366,142 @@
Imported);
}
- virtual void moduleImport(SourceLocation ImportLoc,
- ModuleIdPath Path,
- const Module *Imported) {
+ void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
+ const Module *Imported) override {
First->moduleImport(ImportLoc, Path, Imported);
Second->moduleImport(ImportLoc, Path, Imported);
}
- virtual void EndOfMainFile() {
+ void EndOfMainFile() override {
First->EndOfMainFile();
Second->EndOfMainFile();
}
- virtual void Ident(SourceLocation Loc, const std::string &str) {
+ void Ident(SourceLocation Loc, const std::string &str) override {
First->Ident(Loc, str);
Second->Ident(Loc, str);
}
- virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
- const std::string &Str) {
+ void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+ const std::string &Str) override {
First->PragmaComment(Loc, Kind, Str);
Second->PragmaComment(Loc, Kind, Str);
}
- virtual void PragmaDetectMismatch(SourceLocation Loc,
- const std::string &Name,
- const std::string &Value) {
+ void PragmaDetectMismatch(SourceLocation Loc, const std::string &Name,
+ const std::string &Value) override {
First->PragmaDetectMismatch(Loc, Name, Value);
Second->PragmaDetectMismatch(Loc, Name, Value);
}
- virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
- PragmaMessageKind Kind, StringRef Str) {
+ void PragmaMessage(SourceLocation Loc, StringRef Namespace,
+ PragmaMessageKind Kind, StringRef Str) override {
First->PragmaMessage(Loc, Namespace, Kind, Str);
Second->PragmaMessage(Loc, Namespace, Kind, Str);
}
- virtual void PragmaDiagnosticPush(SourceLocation Loc,
- StringRef Namespace) {
+ void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
First->PragmaDiagnosticPush(Loc, Namespace);
Second->PragmaDiagnosticPush(Loc, Namespace);
}
- virtual void PragmaDiagnosticPop(SourceLocation Loc,
- StringRef Namespace) {
+ void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
First->PragmaDiagnosticPop(Loc, Namespace);
Second->PragmaDiagnosticPop(Loc, Namespace);
}
- virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
- diag::Mapping mapping, StringRef Str) {
+ void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
+ diag::Mapping mapping, StringRef Str) override {
First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
}
- virtual void PragmaOpenCLExtension(SourceLocation NameLoc,
- const IdentifierInfo *Name,
- SourceLocation StateLoc, unsigned State) {
+ void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
+ SourceLocation StateLoc, unsigned State) override {
First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
}
- virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
- ArrayRef<int> Ids) {
+ void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
+ ArrayRef<int> Ids) override {
First->PragmaWarning(Loc, WarningSpec, Ids);
Second->PragmaWarning(Loc, WarningSpec, Ids);
}
- virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
+ void PragmaWarningPush(SourceLocation Loc, int Level) override {
First->PragmaWarningPush(Loc, Level);
Second->PragmaWarningPush(Loc, Level);
}
- virtual void PragmaWarningPop(SourceLocation Loc) {
+ void PragmaWarningPop(SourceLocation Loc) override {
First->PragmaWarningPop(Loc);
Second->PragmaWarningPop(Loc);
}
- virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
- SourceRange Range, const MacroArgs *Args) {
+ void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+ SourceRange Range, const MacroArgs *Args) override {
First->MacroExpands(MacroNameTok, MD, Range, Args);
Second->MacroExpands(MacroNameTok, MD, Range, Args);
}
- virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) {
+ void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override {
First->MacroDefined(MacroNameTok, MD);
Second->MacroDefined(MacroNameTok, MD);
}
- virtual void MacroUndefined(const Token &MacroNameTok,
- const MacroDirective *MD) {
+ void MacroUndefined(const Token &MacroNameTok,
+ const MacroDirective *MD) override {
First->MacroUndefined(MacroNameTok, MD);
Second->MacroUndefined(MacroNameTok, MD);
}
- virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
- SourceRange Range) {
+ void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+ SourceRange Range) override {
First->Defined(MacroNameTok, MD, Range);
Second->Defined(MacroNameTok, MD, Range);
}
- virtual void SourceRangeSkipped(SourceRange Range) {
+ void SourceRangeSkipped(SourceRange Range) override {
First->SourceRangeSkipped(Range);
Second->SourceRangeSkipped(Range);
}
/// \brief Hook called whenever an \#if is seen.
- virtual void If(SourceLocation Loc, SourceRange ConditionRange,
- bool ConditionValue) {
+ void If(SourceLocation Loc, SourceRange ConditionRange,
+ ConditionValueKind ConditionValue) override {
First->If(Loc, ConditionRange, ConditionValue);
Second->If(Loc, ConditionRange, ConditionValue);
}
/// \brief Hook called whenever an \#elif is seen.
- virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
- bool ConditionValue, SourceLocation IfLoc) {
+ void Elif(SourceLocation Loc, SourceRange ConditionRange,
+ ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
}
/// \brief Hook called whenever an \#ifdef is seen.
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) {
+ void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) override {
First->Ifdef(Loc, MacroNameTok, MD);
Second->Ifdef(Loc, MacroNameTok, MD);
}
/// \brief Hook called whenever an \#ifndef is seen.
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) {
+ void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) override {
First->Ifndef(Loc, MacroNameTok, MD);
Second->Ifndef(Loc, MacroNameTok, MD);
}
/// \brief Hook called whenever an \#else is seen.
- virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
+ void Else(SourceLocation Loc, SourceLocation IfLoc) override {
First->Else(Loc, IfLoc);
Second->Else(Loc, IfLoc);
}
/// \brief Hook called whenever an \#endif is seen.
- virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
+ void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
First->Endif(Loc, IfLoc);
Second->Endif(Loc, IfLoc);
}
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
index 54a132d..00d2d57 100644
--- a/include/clang/Lex/PPConditionalDirectiveRecord.h
+++ b/include/clang/Lex/PPConditionalDirectiveRecord.h
@@ -86,16 +86,16 @@
SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
private:
- virtual void If(SourceLocation Loc, SourceRange ConditionRange,
- bool ConditionValue);
- virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
- bool ConditionValue, SourceLocation IfLoc);
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD);
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD);
- virtual void Else(SourceLocation Loc, SourceLocation IfLoc);
- virtual void Endif(SourceLocation Loc, SourceLocation IfLoc);
+ void If(SourceLocation Loc, SourceRange ConditionRange,
+ ConditionValueKind ConditionValue) override;
+ void Elif(SourceLocation Loc, SourceRange ConditionRange,
+ ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
+ void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) override;
+ void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) override;
+ void Else(SourceLocation Loc, SourceLocation IfLoc) override;
+ void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
};
} // end namespace clang
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index d748bc1..2352cce 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -90,11 +90,11 @@
/// IndirectLex - An indirect call to 'Lex' that can be invoked via
/// the PreprocessorLexer interface.
- void IndirectLex(Token &Result) { Lex(Result); }
+ void IndirectLex(Token &Result) override { Lex(Result); }
/// getSourceLocation - Return a source location for the token in
/// the current file.
- SourceLocation getSourceLocation();
+ SourceLocation getSourceLocation() override;
/// SkipBlock - Used by Preprocessor to skip the current conditional block.
bool SkipBlock();
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index fad0806..11b5cea 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -114,7 +114,7 @@
/// Unlike the version in IdentifierTable, this returns a pointer instead
/// of a reference. If the pointer is NULL then the IdentifierInfo cannot
/// be found.
- IdentifierInfo *get(StringRef Name);
+ IdentifierInfo *get(StringRef Name) override;
/// Create - This method creates PTHManager objects. The 'file' argument
/// is the name of the PTH file. This method returns NULL upon failure.
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 087448f..f263820 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -78,8 +78,8 @@
public:
EmptyPragmaHandler();
- virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &FirstToken);
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken) override;
};
/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
@@ -114,10 +114,10 @@
return Handlers.empty();
}
- virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &FirstToken);
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken) override;
- virtual PragmaNamespace *getIfNamespace() { return this; }
+ PragmaNamespace *getIfNamespace() override { return this; }
};
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 2584340..495da76 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -304,6 +304,9 @@
/// and are referenced by the iterator using negative indices.
std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
+ /// \brief The set of ranges that were skipped by the preprocessor,
+ std::vector<SourceRange> SkippedRanges;
+
/// \brief Global (loaded or local) ID for a preprocessed entity.
/// Negative values are used to indicate preprocessed entities
/// loaded from the external source while non-negative values are used to
@@ -556,28 +559,32 @@
/// \brief Retrieve the macro definition that corresponds to the given
/// \c MacroInfo.
MacroDefinition *findMacroDefinition(const MacroInfo *MI);
+
+ /// \brief Retrieve all ranges that got skipped while preprocessing.
+ const std::vector<SourceRange> &getSkippedRanges() const {
+ return SkippedRanges;
+ }
private:
- virtual void MacroExpands(const Token &Id, const MacroDirective *MD,
- SourceRange Range, const MacroArgs *Args);
- virtual void MacroDefined(const Token &Id, const MacroDirective *MD);
- virtual void MacroUndefined(const Token &Id, const MacroDirective *MD);
- virtual void InclusionDirective(SourceLocation HashLoc,
- const Token &IncludeTok,
- StringRef FileName,
- bool IsAngled,
- CharSourceRange FilenameRange,
- const FileEntry *File,
- StringRef SearchPath,
- StringRef RelativePath,
- const Module *Imported);
- virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD);
- virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD);
+ void MacroExpands(const Token &Id, const MacroDirective *MD,
+ SourceRange Range, const MacroArgs *Args) override;
+ void MacroDefined(const Token &Id, const MacroDirective *MD) override;
+ void MacroUndefined(const Token &Id, const MacroDirective *MD) override;
+ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+ StringRef FileName, bool IsAngled,
+ CharSourceRange FilenameRange,
+ const FileEntry *File, StringRef SearchPath,
+ StringRef RelativePath,
+ const Module *Imported) override;
+ void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) override;
+ void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDirective *MD) override;
/// \brief Hook called whenever the 'defined' operator is seen.
- virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
- SourceRange Range);
+ void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+ SourceRange Range) override;
+
+ void SourceRangeSkipped(SourceRange Range) override;
void addMacroExpansion(const Token &Id, const MacroInfo *MI,
SourceRange Range);
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 223fd47..54dee61 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the Preprocessor interface.
-//
+///
+/// \file
+/// \brief Defines the clang::Preprocessor interface.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
@@ -28,10 +29,10 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
+#include <memory>
#include <vector>
namespace llvm {
@@ -78,11 +79,12 @@
}
};
-/// Preprocessor - This object engages in a tight little dance with the lexer to
-/// efficiently preprocess tokens. Lexers know only about tokens within a
-/// single source file, and don't know anything about preprocessor-level issues
-/// like the \#include stack, token expansion, etc.
+/// \brief Engages in a tight little dance with the lexer to efficiently
+/// preprocess tokens.
///
+/// Lexers know only about tokens within a single source file, and don't
+/// know anything about preprocessor-level issues like the \#include stack,
+/// token expansion, etc.
class Preprocessor : public RefCountedBase<Preprocessor> {
IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
@@ -98,12 +100,12 @@
ExternalPreprocessorSource *ExternalSource;
- /// PTH - An optional PTHManager object used for getting tokens from
- /// a token cache rather than lexing the original source file.
- OwningPtr<PTHManager> PTH;
+ /// An optional PTHManager object used for getting tokens from
+ /// a token cache rather than lexing the original source file.
+ std::unique_ptr<PTHManager> PTH;
- /// BP - A BumpPtrAllocator object used to quickly allocate and release
- /// objects internal to the Preprocessor.
+ /// A BumpPtrAllocator object used to quickly allocate and release
+ /// objects internal to the Preprocessor.
llvm::BumpPtrAllocator BP;
/// Identifiers for builtin macros and other builtins.
@@ -114,6 +116,7 @@
IdentifierInfo *Ident__TIMESTAMP__; // __TIMESTAMP__
IdentifierInfo *Ident__COUNTER__; // __COUNTER__
IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma
+ IdentifierInfo *Ident__identifier; // __identifier
IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__
IdentifierInfo *Ident__has_feature; // __has_feature
IdentifierInfo *Ident__has_extension; // __has_extension
@@ -129,7 +132,7 @@
unsigned CounterValue; // Next __COUNTER__ value.
enum {
- /// MaxIncludeStackDepth - Maximum depth of \#includes.
+ /// \brief Maximum depth of \#includes.
MaxAllowedIncludeStackDepth = 200
};
@@ -144,12 +147,11 @@
/// Whether the preprocessor owns the header search object.
bool OwnsHeaderSearch : 1;
- /// DisableMacroExpansion - True if macro expansion is disabled.
+ /// True if macro expansion is disabled.
bool DisableMacroExpansion : 1;
- /// MacroExpansionInDirectivesOverride - Temporarily disables
- /// DisableMacroExpansion (i.e. enables expansion) when parsing preprocessor
- /// directives.
+ /// Temporarily disables DisableMacroExpansion (i.e. enables expansion)
+ /// when parsing preprocessor directives.
bool MacroExpansionInDirectivesOverride : 1;
class ResetMacroExpansionHelper;
@@ -169,23 +171,25 @@
/// \brief True if we are pre-expanding macro arguments.
bool InMacroArgPreExpansion;
- /// Identifiers - This is mapping/lookup information for all identifiers in
+ /// \brief Mapping/lookup information for all identifiers in
/// the program, including program keywords.
mutable IdentifierTable Identifiers;
- /// Selectors - This table contains all the selectors in the program. Unlike
- /// IdentifierTable above, this table *isn't* populated by the preprocessor.
- /// It is declared/expanded here because it's role/lifetime is
- /// conceptually similar the IdentifierTable. In addition, the current control
- /// flow (in clang::ParseAST()), make it convenient to put here.
+ /// \brief This table contains all the selectors in the program.
+ ///
+ /// Unlike IdentifierTable above, this table *isn't* populated by the
+ /// preprocessor. It is declared/expanded here because its role/lifetime is
+ /// conceptually similar to the IdentifierTable. In addition, the current
+ /// control flow (in clang::ParseAST()), make it convenient to put here.
+ ///
/// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
/// the lifetime of the preprocessor.
SelectorTable Selectors;
- /// BuiltinInfo - Information about builtins.
+ /// \brief Information about builtins.
Builtin::Context BuiltinInfo;
- /// PragmaHandlers - This tracks all of the pragmas that the client registered
+ /// \brief Tracks all of the pragmas that the client registered
/// with this preprocessor.
PragmaNamespace *PragmaHandlers;
@@ -197,6 +201,9 @@
/// avoid tearing the Lexer and etc. down).
bool IncrementalProcessing;
+ /// The kind of translation unit we are processing.
+ TranslationUnitKind TUKind;
+
/// \brief The code-completion handler.
CodeCompletionHandler *CodeComplete;
@@ -216,7 +223,7 @@
/// for preprocessing.
SourceLocation CodeCompletionFileLoc;
- /// \brief The source location of the 'import' contextual keyword we just
+ /// \brief The source location of the \c import contextual keyword we just
/// lexed, if any.
SourceLocation ModuleImportLoc;
@@ -226,46 +233,53 @@
/// \brief Whether the last token we lexed was an '@'.
bool LastTokenWasAt;
- /// \brief Whether the module import expectes an identifier next. Otherwise,
+ /// \brief Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
bool ModuleImportExpectsIdentifier;
/// \brief The source location of the currently-active
- /// #pragma clang arc_cf_code_audited begin.
+ /// \#pragma clang arc_cf_code_audited begin.
SourceLocation PragmaARCCFCodeAuditedLoc;
/// \brief True if we hit the code-completion point.
bool CodeCompletionReached;
/// \brief The number of bytes that we will initially skip when entering the
- /// main file, which is used when loading a precompiled preamble, along
- /// with a flag that indicates whether skipping this number of bytes will
- /// place the lexer at the start of a line.
+ /// main file, along with a flag that indicates whether skipping this number
+ /// of bytes will place the lexer at the start of a line.
+ ///
+ /// This is used when loading a precompiled preamble.
std::pair<unsigned, bool> SkipMainFilePreamble;
- /// CurLexer - This is the current top of the stack that we're lexing from if
+ /// \brief The current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
- /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
- OwningPtr<Lexer> CurLexer;
+ ///
+ /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+ std::unique_ptr<Lexer> CurLexer;
- /// CurPTHLexer - This is the current top of stack that we're lexing from if
- /// not expanding from a macro and we are lexing from a PTH cache.
- /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
- OwningPtr<PTHLexer> CurPTHLexer;
+ /// \brief The current top of stack that we're lexing from if
+ /// not expanding from a macro and we are lexing from a PTH cache.
+ ///
+ /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+ std::unique_ptr<PTHLexer> CurPTHLexer;
- /// CurPPLexer - This is the current top of the stack what we're lexing from
- /// if not expanding a macro. This is an alias for either CurLexer or
- /// CurPTHLexer.
+ /// \brief The current top of the stack what we're lexing from
+ /// if not expanding a macro.
+ ///
+ /// This is an alias for either CurLexer or CurPTHLexer.
PreprocessorLexer *CurPPLexer;
- /// CurLookup - The DirectoryLookup structure used to find the current
- /// FileEntry, if CurLexer is non-null and if applicable. This allows us to
- /// implement \#include_next and find directory-specific properties.
+ /// \brief Used to find the current FileEntry, if CurLexer is non-null
+ /// and if applicable.
+ ///
+ /// This allows us to implement \#include_next and find directory-specific
+ /// properties.
const DirectoryLookup *CurDirLookup;
- /// CurTokenLexer - This is the current macro we are expanding, if we are
- /// expanding a macro. One of CurLexer and CurTokenLexer must be null.
- OwningPtr<TokenLexer> CurTokenLexer;
+ /// \brief The current macro we are expanding, if we are expanding a macro.
+ ///
+ /// One of CurLexer and CurTokenLexer must be null.
+ std::unique_ptr<TokenLexer> CurTokenLexer;
/// \brief The kind of lexer we're currently working with.
enum CurLexerKind {
@@ -276,26 +290,48 @@
CLK_LexAfterModuleImport
} CurLexerKind;
- /// IncludeMacroStack - This keeps track of the stack of files currently
+ /// \brief If the current lexer is for a submodule that is being built, this
+ /// is that submodule.
+ Module *CurSubmodule;
+
+ /// \brief Keeps track of the stack of files currently
/// \#included, and macros currently being expanded from, not counting
/// CurLexer/CurTokenLexer.
struct IncludeStackInfo {
- enum CurLexerKind CurLexerKind;
- Lexer *TheLexer;
- PTHLexer *ThePTHLexer;
- PreprocessorLexer *ThePPLexer;
- TokenLexer *TheTokenLexer;
- const DirectoryLookup *TheDirLookup;
+ enum CurLexerKind CurLexerKind;
+ Module *TheSubmodule;
+ std::unique_ptr<Lexer> TheLexer;
+ std::unique_ptr<PTHLexer> ThePTHLexer;
+ PreprocessorLexer *ThePPLexer;
+ std::unique_ptr<TokenLexer> TheTokenLexer;
+ const DirectoryLookup *TheDirLookup;
- IncludeStackInfo(enum CurLexerKind K, Lexer *L, PTHLexer* P,
- PreprocessorLexer* PPL,
- TokenLexer* TL, const DirectoryLookup *D)
- : CurLexerKind(K), TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL),
- TheTokenLexer(TL), TheDirLookup(D) {}
+ // The following constructors are completely useless copies of the default
+ // versions, only needed to pacify MSVC.
+ IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule,
+ std::unique_ptr<Lexer> &&TheLexer,
+ std::unique_ptr<PTHLexer> &&ThePTHLexer,
+ PreprocessorLexer *ThePPLexer,
+ std::unique_ptr<TokenLexer> &&TheTokenLexer,
+ const DirectoryLookup *TheDirLookup)
+ : CurLexerKind(std::move(CurLexerKind)),
+ TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
+ ThePTHLexer(std::move(ThePTHLexer)),
+ ThePPLexer(std::move(ThePPLexer)),
+ TheTokenLexer(std::move(TheTokenLexer)),
+ TheDirLookup(std::move(TheDirLookup)) {}
+ IncludeStackInfo(IncludeStackInfo &&RHS)
+ : CurLexerKind(std::move(RHS.CurLexerKind)),
+ TheSubmodule(std::move(RHS.TheSubmodule)),
+ TheLexer(std::move(RHS.TheLexer)),
+ ThePTHLexer(std::move(RHS.ThePTHLexer)),
+ ThePPLexer(std::move(RHS.ThePPLexer)),
+ TheTokenLexer(std::move(RHS.TheTokenLexer)),
+ TheDirLookup(std::move(RHS.TheDirLookup)) {}
};
std::vector<IncludeStackInfo> IncludeMacroStack;
- /// Callbacks - These are actions invoked when some preprocessor activity is
+ /// \brief Actions invoked when some preprocessor activity is
/// encountered (e.g. a file is \#included, etc).
PPCallbacks *Callbacks;
@@ -308,14 +344,16 @@
};
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
- /// Macros - For each IdentifierInfo that was associated with a macro, we
+ /// For each IdentifierInfo that was associated with a macro, we
/// keep a mapping to the history of all macro definitions and #undefs in
/// the reverse order (the latest one is in the head of the list).
llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
friend class ASTReader;
/// \brief Macros that we want to warn because they are not used at the end
- /// of the translation unit; we store just their SourceLocations instead
+ /// of the translation unit.
+ ///
+ /// We store just their SourceLocations instead of
/// something like MacroInfo*. The benefit of this is that when we are
/// deserializing from PCH, we don't need to deserialize identifier & macros
/// just so that we can report that they are unused, we just warn using
@@ -324,14 +362,13 @@
typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy;
WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
- /// MacroArgCache - This is a "freelist" of MacroArg objects that can be
+ /// \brief A "freelist" of MacroArg objects that can be
/// reused for quick allocation.
MacroArgs *MacroArgCache;
friend class MacroArgs;
- /// PragmaPushMacroInfo - For each IdentifierInfo used in a #pragma
- /// push_macro directive, we keep a MacroInfo stack used to restore
- /// previous macro value.
+ /// For each IdentifierInfo used in a \#pragma push_macro directive,
+ /// we keep a MacroInfo stack used to restore the previous macro value.
llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
// Various statistics we track for performance analysis.
@@ -342,17 +379,19 @@
unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
unsigned NumSkipped;
- /// Predefines - This string is the predefined macros that preprocessor
- /// should use from the command line etc.
+ /// \brief The predefined macros that preprocessor should use from the
+ /// command line etc.
std::string Predefines;
/// \brief The file ID for the preprocessor predefines.
FileID PredefinesFileID;
- /// TokenLexerCache - Cache macro expanders to reduce malloc traffic.
+ /// \{
+ /// \brief Cache of macro expanders to reduce malloc traffic.
enum { TokenLexerCacheSize = 8 };
unsigned NumCachedTokenLexers;
TokenLexer *TokenLexerCache[TokenLexerCacheSize];
+ /// \}
/// \brief Keeps macro expanded tokens for TokenLexers.
//
@@ -372,17 +411,20 @@
private: // Cached tokens state.
typedef SmallVector<Token, 1> CachedTokensTy;
- /// CachedTokens - Cached tokens are stored here when we do backtracking or
+ /// \brief Cached tokens are stored here when we do backtracking or
/// lookahead. They are "lexed" by the CachingLex() method.
CachedTokensTy CachedTokens;
- /// CachedLexPos - The position of the cached token that CachingLex() should
- /// "lex" next. If it points beyond the CachedTokens vector, it means that
- /// a normal Lex() should be invoked.
+ /// \brief The position of the cached token that CachingLex() should
+ /// "lex" next.
+ ///
+ /// If it points beyond the CachedTokens vector, it means that a normal
+ /// Lex() should be invoked.
CachedTokensTy::size_type CachedLexPos;
- /// BacktrackPositions - Stack of backtrack positions, allowing nested
- /// backtracks. The EnableBacktrackAtThisPos() method pushes a position to
+ /// \brief Stack of backtrack positions, allowing nested backtracks.
+ ///
+ /// The EnableBacktrackAtThisPos() method pushes a position to
/// indicate where CachedLexPos should be set when the BackTrack() method is
/// invoked (at which point the last position is popped).
std::vector<CachedTokensTy::size_type> BacktrackPositions;
@@ -397,7 +439,7 @@
/// of that list.
MacroInfoChain *MIChainHead;
- /// MICache - A "freelist" of MacroInfo objects that can be reused for quick
+ /// A "freelist" of MacroInfo objects that can be reused for quick
/// allocation.
MacroInfoChain *MICache;
@@ -418,7 +460,8 @@
IdentifierInfoLookup *IILookup = 0,
bool OwnsHeaderSearch = false,
bool DelayInitialization = false,
- bool IncrProcessing = false);
+ bool IncrProcessing = false,
+ TranslationUnitKind TUKind = TU_Complete);
~Preprocessor();
@@ -470,8 +513,7 @@
return ParsingIfOrElifDirective;
}
- /// SetCommentRetentionState - Control whether or not the preprocessor retains
- /// comments in output.
+ /// \brief Control whether the preprocessor retains comments in output.
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
this->KeepComments = KeepComments | KeepMacroComments;
this->KeepMacroComments = KeepMacroComments;
@@ -500,26 +542,29 @@
/// false if it is producing tokens to be consumed by Parse and Sema.
bool isPreprocessedOutput() const { return PreprocessedOutput; }
- /// isCurrentLexer - Return true if we are lexing directly from the specified
- /// lexer.
+ /// \brief Return true if we are lexing directly from the specified lexer.
bool isCurrentLexer(const PreprocessorLexer *L) const {
return CurPPLexer == L;
}
- /// getCurrentLexer - Return the current lexer being lexed from. Note
- /// that this ignores any potentially active macro expansions and _Pragma
+ /// \brief Return the current lexer being lexed from.
+ ///
+ /// Note that this ignores any potentially active macro expansions and _Pragma
/// expansions going on at the time.
PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
- /// getCurrentFileLexer - Return the current file lexer being lexed from.
+ /// \brief Return the current file lexer being lexed from.
+ ///
/// Note that this ignores any potentially active macro expansions and _Pragma
/// expansions going on at the time.
PreprocessorLexer *getCurrentFileLexer() const;
- /// \brief Returns the file ID for the preprocessor predefines.
+ /// \brief Returns the FileID for the preprocessor predefines.
FileID getPredefinesFileID() const { return PredefinesFileID; }
- /// getPPCallbacks/addPPCallbacks - Accessors for preprocessor callbacks.
+ /// \{
+ /// \brief Accessors for preprocessor callbacks.
+ ///
/// Note that this class takes ownership of any PPCallbacks object given to
/// it.
PPCallbacks *getPPCallbacks() const { return Callbacks; }
@@ -528,9 +573,10 @@
C = new PPChainedCallbacks(C, Callbacks);
Callbacks = C;
}
+ /// \}
/// \brief Given an identifier, return its latest MacroDirective if it is
- // \#defined or null if it isn't \#define'd.
+ /// \#defined or null if it isn't \#define'd.
MacroDirective *getMacroDirective(IdentifierInfo *II) const {
if (!II->hasMacroDefinition())
return 0;
@@ -551,9 +597,10 @@
}
/// \brief Given an identifier, return the (probably #undef'd) MacroInfo
- /// representing the most recent macro definition. One can iterate over all
- /// previous macro definitions from it. This method should only be called for
- /// identifiers that hadMacroDefinition().
+ /// representing the most recent macro definition.
+ ///
+ /// One can iterate over all previous macro definitions from the most recent
+ /// one. This should only be called for identifiers that hadMacroDefinition().
MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
/// \brief Add a directive to the macro directive history for this identifier.
@@ -571,14 +618,15 @@
/// \brief Set a MacroDirective that was loaded from a PCH file.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
- /// macro_iterator/macro_begin/macro_end - This allows you to walk the macro
- /// history table. Currently defined macros have
+ /// \{
+ /// Iterators for the macro history table. Currently defined macros have
/// IdentifierInfo::hasMacroDefinition() set and an empty
/// MacroInfo::getUndefLoc() at the head of the list.
typedef llvm::DenseMap<const IdentifierInfo *,
MacroDirective*>::const_iterator macro_iterator;
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+ /// \}
/// \brief Return the name of the macro defined before \p Loc that has
/// spelling \p Tokens. If there are multiple macros with same spelling,
@@ -587,8 +635,9 @@
ArrayRef<TokenValue> Tokens) const;
const std::string &getPredefines() const { return Predefines; }
- /// setPredefines - Set the predefines for this Preprocessor. These
- /// predefines are automatically injected when parsing the main file.
+ /// \brief Set the predefines for this Preprocessor.
+ ///
+ /// These predefines are automatically injected when parsing the main file.
void setPredefines(const char *P) { Predefines = P; }
void setPredefines(const std::string &P) { Predefines = P; }
@@ -598,18 +647,20 @@
return &Identifiers.get(Name);
}
- /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
- /// If 'Namespace' is non-null, then it is a token required to exist on the
+ /// \brief Add the specified pragma handler to this preprocessor.
+ ///
+ /// If \p Namespace is non-null, then it is a token required to exist on the
/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler);
void AddPragmaHandler(PragmaHandler *Handler) {
AddPragmaHandler(StringRef(), Handler);
}
- /// RemovePragmaHandler - Remove the specific pragma handler from
- /// the preprocessor. If \p Namespace is non-null, then it should
- /// be the namespace that \p Handler was added to. It is an error
- /// to remove a handler that has not been registered.
+ /// \brief Remove the specific pragma handler from this preprocessor.
+ ///
+ /// If \p Namespace is non-null, then it should be the namespace that
+ /// \p Handler was added to. It is an error to remove a handler that
+ /// has not been registered.
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler);
void RemovePragmaHandler(PragmaHandler *Handler) {
RemovePragmaHandler(StringRef(), Handler);
@@ -650,51 +701,51 @@
/// all macro expansions, macro definitions, etc.
void createPreprocessingRecord();
- /// EnterMainSourceFile - Enter the specified FileID as the main source file,
+ /// \brief Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
void EnterMainSourceFile();
- /// EndSourceFile - Inform the preprocessor callbacks that processing is
- /// complete.
+ /// \brief Inform the preprocessor callbacks that processing is complete.
void EndSourceFile();
- /// EnterSourceFile - Add a source file to the top of the include stack and
- /// start lexing tokens from it instead of the current buffer. Emit an error
- /// and don't enter the file on error.
- void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+ /// \brief Add a source file to the top of the include stack and
+ /// start lexing tokens from it instead of the current buffer.
+ ///
+ /// Emits a diagnostic, doesn't enter the file, and returns true on error.
+ bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
SourceLocation Loc);
- /// EnterMacro - Add a Macro to the top of the include stack and start lexing
- /// tokens from it instead of the current buffer. Args specifies the
- /// tokens input to a function-like macro.
+ /// \brief Add a Macro to the top of the include stack and start lexing
+ /// tokens from it instead of the current buffer.
///
- /// ILEnd specifies the location of the ')' for a function-like macro or the
- /// identifier for an object-like macro.
+ /// \param Args specifies the tokens input to a function-like macro.
+ /// \param ILEnd specifies the location of the ')' for a function-like macro
+ /// or the identifier for an object-like macro.
void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro,
MacroArgs *Args);
- /// EnterTokenStream - Add a "macro" context to the top of the include stack,
+ /// \brief Add a "macro" context to the top of the include stack,
/// which will cause the lexer to start returning the specified tokens.
///
- /// If DisableMacroExpansion is true, tokens lexed from the token stream will
- /// not be subject to further macro expansion. Otherwise, these tokens will
- /// be re-macro-expanded when/if expansion is enabled.
+ /// If \p DisableMacroExpansion is true, tokens lexed from the token stream
+ /// will not be subject to further macro expansion. Otherwise, these tokens
+ /// will be re-macro-expanded when/if expansion is enabled.
///
- /// If OwnsTokens is false, this method assumes that the specified stream of
- /// tokens has a permanent owner somewhere, so they do not need to be copied.
- /// If it is true, it assumes the array of tokens is allocated with new[] and
- /// must be freed.
- ///
+ /// If \p OwnsTokens is false, this method assumes that the specified stream
+ /// of tokens has a permanent owner somewhere, so they do not need to be
+ /// copied. If it is true, it assumes the array of tokens is allocated with
+ /// \c new[] and must be freed.
void EnterTokenStream(const Token *Toks, unsigned NumToks,
bool DisableMacroExpansion, bool OwnsTokens);
- /// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
- /// lexer stack. This should only be used in situations where the current
- /// state of the top-of-stack lexer is known.
+ /// \brief Pop the current lexer/macro exp off the top of the lexer stack.
+ ///
+ /// This should only be used in situations where the current state of the
+ /// top-of-stack lexer is known.
void RemoveTopOfLexerStack();
- /// EnableBacktrackAtThisPos - From the point that this method is called, and
- /// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
+ /// From the point that this method is called, and until
+ /// CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
/// keeps track of the lexed tokens so that a subsequent Backtrack() call will
/// make the Preprocessor re-lex the same tokens.
///
@@ -708,18 +759,18 @@
///
void EnableBacktrackAtThisPos();
- /// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
+ /// \brief Disable the last EnableBacktrackAtThisPos call.
void CommitBacktrackedTokens();
- /// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
+ /// \brief Make Preprocessor re-lex the tokens that were lexed since
/// EnableBacktrackAtThisPos() was previously called.
void Backtrack();
- /// isBacktrackEnabled - True if EnableBacktrackAtThisPos() was called and
+ /// \brief True if EnableBacktrackAtThisPos() was called and
/// caching of tokens is on.
bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
- /// Lex - Lex the next token for this preprocessor.
+ /// \brief Lex the next token for this preprocessor.
void Lex(Token &Result);
void LexAfterModuleImport(Token &Result);
@@ -743,17 +794,18 @@
const char *DiagnosticTag,
bool AllowMacroExpansion);
- /// LexNonComment - Lex a token. If it's a comment, keep lexing until we get
- /// something not a comment. This is useful in -E -C mode where comments
- /// would foul up preprocessor directive handling.
+ /// \brief Lex a token. If it's a comment, keep lexing until we get
+ /// something not a comment.
+ ///
+ /// This is useful in -E -C mode where comments would foul up preprocessor
+ /// directive handling.
void LexNonComment(Token &Result) {
do
Lex(Result);
while (Result.getKind() == tok::comment);
}
- /// LexUnexpandedToken - This is just like Lex, but this disables macro
- /// expansion of identifier tokens.
+ /// \brief Just like Lex, but disables macro expansion of identifier tokens.
void LexUnexpandedToken(Token &Result) {
// Disable macro expansion.
bool OldVal = DisableMacroExpansion;
@@ -765,24 +817,31 @@
DisableMacroExpansion = OldVal;
}
- /// LexUnexpandedNonComment - Like LexNonComment, but this disables macro
- /// expansion of identifier tokens.
+ /// \brief Like LexNonComment, but this disables macro expansion of
+ /// identifier tokens.
void LexUnexpandedNonComment(Token &Result) {
do
LexUnexpandedToken(Result);
while (Result.getKind() == tok::comment);
}
+ /// \brief Parses a simple integer literal to get its numeric value. Floating
+ /// point literals and user defined literals are rejected. Used primarily to
+ /// handle pragmas that accept integer arguments.
+ bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value);
+
/// Disables macro expansion everywhere except for preprocessor directives.
void SetMacroExpansionOnlyInDirectives() {
DisableMacroExpansion = true;
MacroExpansionInDirectivesOverride = true;
}
- /// LookAhead - This peeks ahead N tokens and returns that token without
- /// consuming any tokens. LookAhead(0) returns the next token that would be
- /// returned by Lex(), LookAhead(1) returns the token after it, etc. This
- /// returns normal tokens after phase 5. As such, it is equivalent to using
+ /// \brief Peeks ahead N tokens and returns that token without consuming any
+ /// tokens.
+ ///
+ /// LookAhead(0) returns the next token that would be returned by Lex(),
+ /// LookAhead(1) returns the token after it, etc. This returns normal
+ /// tokens after phase 5. As such, it is equivalent to using
/// 'Lex', not 'LexUnexpandedToken'.
const Token &LookAhead(unsigned N) {
if (CachedLexPos + N < CachedTokens.size())
@@ -791,8 +850,9 @@
return PeekAhead(N+1);
}
- /// RevertCachedTokens - When backtracking is enabled and tokens are cached,
+ /// \brief When backtracking is enabled and tokens are cached,
/// this allows to revert a specific number of tokens.
+ ///
/// Note that the number of tokens being reverted should be up to the last
/// backtrack position, not more.
void RevertCachedTokens(unsigned N) {
@@ -805,20 +865,21 @@
CachedLexPos -= N;
}
- /// EnterToken - Enters a token in the token stream to be lexed next. If
- /// BackTrack() is called afterwards, the token will remain at the insertion
- /// point.
+ /// \brief Enters a token in the token stream to be lexed next.
+ ///
+ /// If BackTrack() is called afterwards, the token will remain at the
+ /// insertion point.
void EnterToken(const Token &Tok) {
EnterCachingLexMode();
CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
}
- /// AnnotateCachedTokens - We notify the Preprocessor that if it is caching
- /// tokens (because backtrack is enabled) it should replace the most recent
- /// cached tokens with the given annotation token. This function has no effect
- /// if backtracking is not enabled.
+ /// We notify the Preprocessor that if it is caching tokens (because
+ /// backtrack is enabled) it should replace the most recent cached tokens
+ /// with the given annotation token. This function has no effect if
+ /// backtracking is not enabled.
///
- /// Note that the use of this function is just for optimization; so that the
+ /// Note that the use of this function is just for optimization, so that the
/// cached tokens doesn't get re-parsed and re-resolved after a backtrack is
/// invoked.
void AnnotateCachedTokens(const Token &Tok) {
@@ -848,7 +909,7 @@
CachedTokens[CachedLexPos-1] = Tok;
}
- /// TypoCorrectToken - Update the current token to represent the provided
+ /// Update the current token to represent the provided
/// identifier, in order to cache an action performed by typo correction.
void TypoCorrectToken(const Token &Tok) {
assert(Tok.getIdentifierInfo() && "Expected identifier token");
@@ -889,11 +950,13 @@
bool isCodeCompletionEnabled() const { return CodeCompletionFile != 0; }
/// \brief Returns the location of the code-completion point.
+ ///
/// Returns an invalid location if code-completion is not enabled or the file
/// containing the code-completion point has not been lexed yet.
SourceLocation getCodeCompletionLoc() const { return CodeCompletionLoc; }
/// \brief Returns the start location of the file of code-completion point.
+ ///
/// Returns an invalid location if code-completion is not enabled or the file
/// containing the code-completion point has not been lexed yet.
SourceLocation getCodeCompletionFileLoc() const {
@@ -913,8 +976,9 @@
}
/// \brief The location of the currently-active \#pragma clang
- /// arc_cf_code_audited begin. Returns an invalid location if there
- /// is no such pragma active.
+ /// arc_cf_code_audited begin.
+ ///
+ /// Returns an invalid location if there is no such pragma active.
SourceLocation getPragmaARCCFCodeAuditedLoc() const {
return PragmaARCCFCodeAuditedLoc;
}
@@ -936,7 +1000,7 @@
SkipMainFilePreamble.second = StartOfLine;
}
- /// Diag - Forwarding function for diagnostics. This emits a diagnostic at
+ /// Forwarding function for diagnostics. This emits a diagnostic at
/// the specified Token's location, translating the token's start
/// position in the current buffer into a SourcePosition object for rendering.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
@@ -947,7 +1011,7 @@
return Diags->Report(Tok.getLocation(), DiagID);
}
- /// getSpelling() - Return the 'spelling' of the token at the given
+ /// Return the 'spelling' of the token at the given
/// location; does not go up to the spelling location or down to the
/// expansion location.
///
@@ -960,21 +1024,24 @@
return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
}
- /// 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
- /// after trigraph expansion and escaped-newline folding. In particular, this
- /// wants to get the true, uncanonicalized, spelling of things like digraphs
- /// UCNs, etc.
+ /// \brief Return the 'spelling' of the Tok token.
+ ///
+ /// The spelling of a token is the characters used to represent the token in
+ /// the source file after trigraph expansion and escaped-newline folding. In
+ /// particular, this wants to get the true, uncanonicalized, spelling of
+ /// 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 {
return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
}
- /// getSpelling - This method is used to get the spelling of a token into a
- /// preallocated buffer, instead of as an std::string. The caller is required
- /// to allocate enough space for the token, which is guaranteed to be at least
- /// Tok.getLength() bytes long. The length of the actual result is returned.
+ /// \brief Get the spelling of a token into a preallocated buffer, instead
+ /// of as an std::string.
+ ///
+ /// The caller is required to allocate enough space for the token, which is
+ /// guaranteed to be at least Tok.getLength() bytes long. The length of the
+ /// actual result is returned.
///
/// Note that this method may do two possible things: it may either fill in
/// the buffer specified with characters, or it may *change the input pointer*
@@ -986,8 +1053,9 @@
return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
}
- /// getSpelling - This method is used to get the spelling of a token into a
- /// SmallVector. Note that the returned StringRef may not point to the
+ /// \brief Get the spelling of a token into a SmallVector.
+ ///
+ /// Note that the returned StringRef may not point to the
/// supplied buffer if a copy can be avoided.
StringRef getSpelling(const Token &Tok,
SmallVectorImpl<char> &Buffer,
@@ -1000,8 +1068,8 @@
return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace);
}
- /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
- /// with length 1, return the character.
+ /// \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 {
assert(Tok.is(tok::numeric_constant) &&
@@ -1019,18 +1087,21 @@
/// \brief Retrieve the name of the immediate macro expansion.
///
- /// This routine starts from a source location, and finds the name of the macro
- /// responsible for its immediate expansion. It looks through any intervening
- /// macro argument expansions to compute this. It returns a StringRef which
- /// refers to the SourceManager-owned buffer of the source where that macro
- /// name is spelled. Thus, the result shouldn't out-live the SourceManager.
+ /// This routine starts from a source location, and finds the name of the
+ /// macro responsible for its immediate expansion. It looks through any
+ /// intervening macro argument expansions to compute this. It returns a
+ /// StringRef that refers to the SourceManager-owned buffer of the source
+ /// where that macro name is spelled. Thus, the result shouldn't out-live
+ /// the SourceManager.
StringRef getImmediateMacroName(SourceLocation Loc) {
return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
}
- /// CreateString - Plop the specified string into a scratch buffer and set the
- /// specified token's location and length to it. If specified, the source
- /// location provides a location of the expansion point of the token.
+ /// \brief Plop the specified string into a scratch buffer and set the
+ /// specified token's location and length to it.
+ ///
+ /// If specified, the source location provides a location of the expansion
+ /// point of the token.
void CreateString(StringRef Str, Token &Tok,
SourceLocation ExpansionLocStart = SourceLocation(),
SourceLocation ExpansionLocEnd = SourceLocation());
@@ -1075,23 +1146,22 @@
return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
}
- /// DumpToken - Print the token to stderr, used for debugging.
- ///
+ /// \brief Print the token to stderr, used for debugging.
void DumpToken(const Token &Tok, bool DumpFlags = false) const;
void DumpLocation(SourceLocation Loc) const;
void DumpMacro(const MacroInfo &MI) const;
- /// AdvanceToTokenCharacter - Given a location that specifies the start of a
+ /// \brief Given a location that specifies the start of a
/// token, return a new location that specifies a character within the token.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
unsigned Char) const {
return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts);
}
- /// IncrementPasteCounter - Increment the counters for the number of token
- /// paste operations performed. If fast was specified, this is a 'fast paste'
- /// case we handled.
+ /// \brief Increment the counters for the number of token paste operations
+ /// performed.
///
+ /// If fast was specified, this is a 'fast paste' case we handled.
void IncrementPasteCounter(bool isFast) {
if (isFast)
++NumFastTokenPaste;
@@ -1103,16 +1173,16 @@
size_t getTotalMemory() const;
- /// HandleMicrosoftCommentPaste - When the macro expander pastes together a
- /// comment (/##/) in microsoft mode, this method handles updating the current
- /// state, returning the token on the next source line.
+ /// When the macro expander pastes together a comment (/##/) in Microsoft
+ /// mode, this method handles updating the current state, returning the
+ /// token on the next source line.
void HandleMicrosoftCommentPaste(Token &Tok);
//===--------------------------------------------------------------------===//
// Preprocessor callback methods. These are invoked by a lexer as various
// directives and events are found.
- /// LookUpIdentifierInfo - Given a tok::raw_identifier token, look up the
+ /// Given a tok::raw_identifier token, look up the
/// identifier information for the token and install it into the token,
/// updating the token kind accordingly.
IdentifierInfo *LookUpIdentifierInfo(Token &Identifier) const;
@@ -1122,14 +1192,13 @@
public:
- // SetPoisonReason - Call this function to indicate the reason for
- // poisoning an identifier. If that identifier is accessed while
- // poisoned, then this reason will be used instead of the default
- // "poisoned" diagnostic.
+ /// \brief Specifies the reason for poisoning an identifier.
+ ///
+ /// If that identifier is accessed while poisoned, then this reason will be
+ /// used instead of the default "poisoned" diagnostic.
void SetPoisonReason(IdentifierInfo *II, unsigned DiagID);
- // HandlePoisonedIdentifier - Display reason for poisoned
- // identifier.
+ /// \brief Display reason for poisoned identifier.
void HandlePoisonedIdentifier(Token & Tok);
void MaybeHandlePoisonedIdentifier(Token & Identifier) {
@@ -1155,45 +1224,53 @@
IdentifierInfo *Ident__abnormal_termination,
*Ident___abnormal_termination,
*Ident_AbnormalTermination;
+
+ const char *getCurLexerEndPos();
+
public:
void PoisonSEHIdentifiers(bool Poison = true); // Borland
- /// HandleIdentifier - This callback is invoked when the lexer reads an
- /// identifier and has filled in the tokens IdentifierInfo member. This
- /// callback potentially macro expands it or turns it into a named token (like
- /// 'for').
+ /// \brief Callback invoked when the lexer reads an identifier and has
+ /// filled in the tokens IdentifierInfo member.
+ ///
+ /// This callback potentially macro expands it or turns it into a named
+ /// token (like 'for').
///
/// \returns true if we actually computed a token, false if we need to
/// lex again.
bool HandleIdentifier(Token &Identifier);
- /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
- /// the current file. This either returns the EOF token and returns true, or
+ /// \brief Callback invoked when the lexer hits the end of the current file.
+ ///
+ /// This either returns the EOF token and returns true, or
/// pops a level off the include stack and returns false, at which point the
/// client should call lex again.
bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false);
- /// HandleEndOfTokenLexer - This callback is invoked when the current
- /// TokenLexer hits the end of its token stream.
+ /// \brief Callback invoked when the current TokenLexer hits the end of its
+ /// token stream.
bool HandleEndOfTokenLexer(Token &Result);
- /// HandleDirective - This callback is invoked when the lexer sees a # token
- /// at the start of a line. This consumes the directive, modifies the
- /// lexer/preprocessor state, and advances the lexer(s) so that the next token
- /// read is the correct one.
+ /// \brief Callback invoked when the lexer sees a # token at the start of a
+ /// line.
+ ///
+ /// This consumes the directive, modifies the lexer/preprocessor state, and
+ /// advances the lexer(s) so that the next token read is the correct one.
void HandleDirective(Token &Result);
- /// CheckEndOfDirective - Ensure that the next token is a tok::eod token. If
- /// not, emit a diagnostic and consume up until the eod. If EnableMacros is
- /// true, then we consider macros that expand to zero tokens as being ok.
+ /// \brief Ensure that the next token is a tok::eod token.
+ ///
+ /// If not, emit a diagnostic and consume up until the eod.
+ /// If \p EnableMacros is true, then we consider macros that expand to zero
+ /// tokens as being ok.
void CheckEndOfDirective(const char *Directive, bool EnableMacros = false);
- /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
- /// current line until the tok::eod token is found.
+ /// \brief Read and discard all tokens remaining on the current line until
+ /// the tok::eod token is found.
void DiscardUntilEndOfDirective();
- /// SawDateOrTime - This returns true if the preprocessor has seen a use of
+ /// \brief Returns true if the preprocessor has seen a use of
/// __DATE__ or __TIME__ in the file so far.
bool SawDateOrTime() const {
return DATELoc != SourceLocation() || TIMELoc != SourceLocation();
@@ -1234,17 +1311,20 @@
ModuleMap::KnownHeader *SuggestedModule,
bool SkipCache = false);
- /// GetCurLookup - The DirectoryLookup structure used to find the current
- /// FileEntry, if CurLexer is non-null and if applicable. This allows us to
- /// implement \#include_next and find directory-specific properties.
+ /// \brief Get the DirectoryLookup structure used to find the current
+ /// FileEntry, if CurLexer is non-null and if applicable.
+ ///
+ /// This allows us to implement \#include_next and find directory-specific
+ /// properties.
const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
/// \brief Return true if we're in the top-level file, not in a \#include.
bool isInPrimaryFile() const;
- /// ConcatenateIncludeName - Handle cases where the \#include name is expanded
- /// from a macro as multiple tokens, which need to be glued together. This
- /// occurs for code like:
+ /// \brief Handle cases where the \#include name is expanded
+ /// from a macro as multiple tokens, which need to be glued together.
+ ///
+ /// This occurs for code like:
/// \code
/// \#define FOO <x/y.h>
/// \#include FOO
@@ -1257,28 +1337,26 @@
bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
SourceLocation &End);
- /// LexOnOffSwitch - Lex an on-off-switch (C99 6.10.6p2) and verify that it is
+ /// \brief Lex an on-off-switch (C99 6.10.6p2) and verify that it is
/// followed by EOD. Return true if the token is not a valid on-off-switch.
bool LexOnOffSwitch(tok::OnOffSwitch &OOS);
private:
void PushIncludeMacroStack() {
- IncludeMacroStack.push_back(IncludeStackInfo(CurLexerKind,
- CurLexer.take(),
- CurPTHLexer.take(),
- CurPPLexer,
- CurTokenLexer.take(),
- CurDirLookup));
+ IncludeMacroStack.push_back(IncludeStackInfo(
+ CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
+ CurPPLexer, std::move(CurTokenLexer), CurDirLookup));
CurPPLexer = 0;
}
void PopIncludeMacroStack() {
- CurLexer.reset(IncludeMacroStack.back().TheLexer);
- CurPTHLexer.reset(IncludeMacroStack.back().ThePTHLexer);
+ CurLexer = std::move(IncludeMacroStack.back().TheLexer);
+ CurPTHLexer = std::move(IncludeMacroStack.back().ThePTHLexer);
CurPPLexer = IncludeMacroStack.back().ThePPLexer;
- CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer);
+ CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
+ CurSubmodule = IncludeMacroStack.back().TheSubmodule;
CurLexerKind = IncludeMacroStack.back().CurLexerKind;
IncludeMacroStack.pop_back();
}
@@ -1300,15 +1378,16 @@
/// This memory will be reused for allocating new MacroInfo objects.
void ReleaseMacroInfo(MacroInfo* MI);
- /// ReadMacroName - Lex and validate a macro name, which occurs after a
- /// \#define or \#undef. This emits a diagnostic, sets the token kind to eod,
+ /// \brief Lex and validate a macro name, which occurs after a
+ /// \#define or \#undef.
+ ///
+ /// This emits a diagnostic, sets the token kind to eod,
/// and discards the rest of the macro line if the macro name is invalid.
void ReadMacroName(Token &MacroNameTok, char isDefineUndef = 0);
- /// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
- /// definition has just been read. Lex the rest of the arguments and the
- /// closing ), updating MI with what we learn and saving in LastTok the
- /// last token read.
+ /// The ( starting an argument list of a macro definition has just been read.
+ /// Lex the rest of the arguments and the closing ), updating \p MI with
+ /// what we learn and saving in \p LastTok the last token read.
/// Return true if an error occurs parsing the arg list.
bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok);
@@ -1327,21 +1406,22 @@
/// \brief A fast PTH version of SkipExcludedConditionalBlock.
void PTHSkipExcludedConditionalBlock();
- /// EvaluateDirectiveExpression - Evaluate an integer constant expression that
- /// may occur after a #if or #elif directive and return it as a bool. If the
- /// expression is equivalent to "!defined(X)" return X in IfNDefMacro.
+ /// \brief Evaluate an integer constant expression that may occur after a
+ /// \#if or \#elif directive and return it as a bool.
+ ///
+ /// If the expression is equivalent to "!defined(X)" return X in IfNDefMacro.
bool EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
- /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
+ /// \brief Install the standard preprocessor pragmas:
/// \#pragma GCC poison/system_header/dependency and \#pragma once.
void RegisterBuiltinPragmas();
/// \brief Register builtin macros such as __LINE__ with the identifier table.
void RegisterBuiltinMacros();
- /// HandleMacroExpandedIdentifier - If an identifier token is read that is to
- /// be expanded as a macro, handle it and return the next token as 'Tok'. If
- /// we lexed a token, return true; otherwise the caller should lex again.
+ /// If an identifier token is read that is to be expanded as a macro, handle
+ /// it and return the next token as 'Tok'. If we lexed a token, return true;
+ /// otherwise the caller should lex again.
bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD);
/// \brief Cache macro expanded tokens for TokenLexers.
@@ -1354,52 +1434,51 @@
void removeCachedMacroExpandedTokensOfLastLexer();
friend void TokenLexer::ExpandFunctionArguments();
- /// isNextPPTokenLParen - Determine whether the next preprocessor token to be
+ /// Determine whether the next preprocessor token to be
/// lexed is a '('. If so, consume the token and return true, if not, this
/// method should have no observable side-effect on the lexed tokens.
bool isNextPPTokenLParen();
- /// ReadFunctionLikeMacroArgs - After reading "MACRO(", this method is
- /// invoked to read all of the formal arguments specified for the macro
- /// invocation. This returns null on error.
+ /// After reading "MACRO(", this method is invoked to read all of the formal
+ /// arguments specified for the macro invocation. Returns null on error.
MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
SourceLocation &ExpansionEnd);
- /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
+ /// \brief If an identifier token is read that is to be expanded
/// as a builtin macro, handle it and return the next token as 'Tok'.
void ExpandBuiltinMacro(Token &Tok);
- /// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
- /// return the first token after the directive. The _Pragma token has just
- /// been read into 'Tok'.
+ /// \brief Read a \c _Pragma directive, slice it up, process it, then
+ /// return the first token after the directive.
+ /// This assumes that the \c _Pragma token has just been read into \p Tok.
void Handle_Pragma(Token &Tok);
- /// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
- /// is not enclosed within a string literal.
+ /// \brief Like Handle_Pragma except the pragma text is not enclosed within
+ /// a string literal.
void HandleMicrosoft__pragma(Token &Tok);
- /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
+ /// \brief Add a lexer to the top of the include stack and
/// start lexing tokens from it instead of the current buffer.
void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
- /// EnterSourceFileWithPTH - Add a lexer to the top of the include stack and
+ /// \brief Add a lexer to the top of the include stack and
/// start getting tokens from it using the PTH cache.
void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
- /// \brief Set the file ID for the preprocessor predefines.
+ /// \brief Set the FileID for the preprocessor predefines.
void setPredefinesFileID(FileID FID) {
assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
PredefinesFileID = FID;
}
- /// IsFileLexer - Returns true if we are lexing from a file and not a
- /// pragma or a macro.
+ /// \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;
}
static bool IsFileLexer(const IncludeStackInfo& I) {
- return IsFileLexer(I.TheLexer, I.ThePPLexer);
+ return IsFileLexer(I.TheLexer.get(), I.ThePPLexer);
}
bool IsFileLexer() const {
@@ -1449,25 +1528,6 @@
/// points to.
Module *getModuleForLocation(SourceLocation FilenameLoc);
- /// \brief Verify that a private header is included only from within its
- /// module.
- bool violatesPrivateInclude(Module *RequestingModule,
- const FileEntry *IncFileEnt,
- ModuleMap::ModuleHeaderRole Role,
- Module *RequestedModule);
-
- /// \brief Verify that a module includes headers only from modules that it
- /// has declared that it uses.
- bool violatesUseDeclarations(Module *RequestingModule,
- Module *RequestedModule);
-
- /// \brief Verify that it is legal for the source file that \p FilenameLoc
- /// points to to include the file \p Filename.
- ///
- /// Tries to reuse \p IncFileEnt.
- void verifyModuleInclude(SourceLocation FilenameLoc, StringRef Filename,
- const FileEntry *IncFileEnt);
-
// Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
void HandleUndefDirective(Token &Tok);
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 4f6391d..580bb12 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -62,8 +62,7 @@
void *PtrData;
/// Kind - The actual flavor of token this is.
- ///
- unsigned short Kind;
+ tok::TokenKind Kind;
/// Flags - Bits we track about this token, members of the TokenFlags enum.
unsigned char Flags;
@@ -83,13 +82,13 @@
IgnoredComma = 0x80 // This comma is not a macro argument separator (MS).
};
- tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
+ tok::TokenKind getKind() const { return Kind; }
void setKind(tok::TokenKind K) { Kind = K; }
/// is/isNot - Predicates to check if this token is a specific kind, as in
/// "if (Tok.is(tok::l_brace)) {...}".
- bool is(tok::TokenKind K) const { return Kind == (unsigned) K; }
- bool isNot(tok::TokenKind K) const { return Kind != (unsigned) K; }
+ bool is(tok::TokenKind K) const { return Kind == K; }
+ bool isNot(tok::TokenKind K) const { return Kind != K; }
/// \brief Return true if this is a raw identifier (when lexing
/// in raw mode) or a non-keyword identifier (when lexing in non-raw mode).
@@ -145,9 +144,7 @@
setAnnotationEndLoc(R.getEnd());
}
- const char *getName() const {
- return tok::getTokenName( (tok::TokenKind) Kind);
- }
+ const char *getName() const { return tok::getTokenName(Kind); }
/// \brief Reset all flags to cleared.
void startToken() {
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index 7c8cfd0..659643d 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -81,6 +81,14 @@
bool AtStartOfLine : 1;
bool HasLeadingSpace : 1;
+ // NextTokGetsSpace - When this is true, the next token appended to the
+ // output list during function argument expansion will get a leading space,
+ // regardless of whether it had one to begin with or not. This is used for
+ // placemarker support. If still true after function argument expansion, the
+ // leading space will be applied to the first token following the macro
+ // expansion.
+ bool NextTokGetsSpace : 1;
+
/// OwnsTokens - This is true if this TokenLexer allocated the Tokens
/// array, and thus needs to free it when destroyed. For simple object-like
/// macros (for example) we just point into the token buffer of the macro
@@ -182,6 +190,13 @@
void updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc,
Token *begin_tokens, Token *end_tokens);
+ /// Remove comma ahead of __VA_ARGS__, if present, according to compiler
+ /// dialect settings. Returns true if the comma is removed.
+ bool MaybeRemoveCommaBeforeVaArgs(SmallVectorImpl<Token> &ResultToks,
+ bool HasPasteOperator,
+ MacroInfo *Macro, unsigned MacroArgNo,
+ Preprocessor &PP);
+
void PropagateLineStartLeadingSpaceInfo(Token &Result);
};
diff --git a/include/clang/Makefile b/include/clang/Makefile
index 5f2077d..5ba2dd2 100644
--- a/include/clang/Makefile
+++ b/include/clang/Makefile
@@ -1,5 +1,5 @@
CLANG_LEVEL := ../..
-DIRS := AST Basic Driver Lex Parse Sema Serialization
+DIRS := AST Basic Driver Parse Sema Serialization
include $(CLANG_LEVEL)/Makefile
diff --git a/include/clang/Parse/CMakeLists.txt b/include/clang/Parse/CMakeLists.txt
index ed80c18..ec75f7b 100644
--- a/include/clang/Parse/CMakeLists.txt
+++ b/include/clang/Parse/CMakeLists.txt
@@ -1,14 +1,4 @@
-clang_tablegen(AttrIdentifierArg.inc -gen-clang-attr-identifier-arg-list
+clang_tablegen(AttrParserStringSwitches.inc -gen-clang-attr-parser-string-switches
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
- TARGET ClangAttrIdentifierArg)
-
-clang_tablegen(AttrTypeArg.inc -gen-clang-attr-type-arg-list
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrTypeArg)
-
-clang_tablegen(AttrLateParsed.inc -gen-clang-attr-late-parsed-list
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrLateParsed)
+ TARGET ClangAttrParserStringSwitches)
diff --git a/include/clang/Parse/Makefile b/include/clang/Parse/Makefile
index 00d41fa..c477019 100644
--- a/include/clang/Parse/Makefile
+++ b/include/clang/Parse/Makefile
@@ -1,25 +1,13 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrIdentifierArg.inc AttrLateParsed.inc AttrTypeArg.inc
+BUILT_SOURCES = AttrParserStringSwitches.inc
TABLEGEN_INC_FILES_COMMON = 1
include $(CLANG_LEVEL)/Makefile
-$(ObjDir)/AttrIdentifierArg.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
+$(ObjDir)/AttrParserStringSwitches.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
$(ObjDir)/.dir
- $(Echo) "Building Clang attribute identifier argument table with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-identifier-arg-list -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrTypeArg.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute type argument table with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-type-arg-list -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrLateParsed.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute late-parsed table with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-late-parsed-list -o $(call SYSPATH, $@) \
+ $(Echo) "Building Clang parser-related attribute string switches"
+ $(Verb) $(ClangTableGen) -gen-clang-attr-parser-string-switches -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index bd49988..44f7cb1 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -21,11 +21,11 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Sema.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SaveAndRestore.h"
+#include <memory>
#include <stack>
namespace clang {
@@ -40,7 +40,6 @@
class ParsingDeclSpec;
class ParsingDeclarator;
class ParsingFieldDeclarator;
- class PragmaUnusedHandler;
class ColonProtectionRAIIObject;
class InMessageExpressionRAIIObject;
class PoisonSEHIdentifiersRAIIObject;
@@ -52,7 +51,6 @@
/// been read.
///
class Parser : public CodeCompletionHandler {
- friend class PragmaUnusedHandler;
friend class ColonProtectionRAIIObject;
friend class InMessageExpressionRAIIObject;
friend class PoisonSEHIdentifiersRAIIObject;
@@ -73,7 +71,7 @@
SourceLocation PrevTokLocation;
unsigned short ParenCount, BracketCount, BraceCount;
-
+
/// Actions - These are the callbacks we invoke as we parse various constructs
/// in the file.
Sema &Actions;
@@ -136,24 +134,28 @@
mutable IdentifierInfo *Ident_final;
mutable IdentifierInfo *Ident_override;
- // C++ type trait keywords that have can be reverted to identifiers and
- // still used as type traits.
- llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertableTypeTraits;
+ // Some token kinds such as C++ type traits can be reverted to identifiers and
+ // still get used as keywords depending on context.
+ llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind>
+ ContextualKeywords;
- OwningPtr<PragmaHandler> AlignHandler;
- OwningPtr<PragmaHandler> GCCVisibilityHandler;
- OwningPtr<PragmaHandler> OptionsHandler;
- OwningPtr<PragmaHandler> PackHandler;
- OwningPtr<PragmaHandler> MSStructHandler;
- OwningPtr<PragmaHandler> UnusedHandler;
- OwningPtr<PragmaHandler> WeakHandler;
- OwningPtr<PragmaHandler> RedefineExtnameHandler;
- OwningPtr<PragmaHandler> FPContractHandler;
- OwningPtr<PragmaHandler> OpenCLExtensionHandler;
- OwningPtr<CommentHandler> CommentSemaHandler;
- OwningPtr<PragmaHandler> OpenMPHandler;
- OwningPtr<PragmaHandler> MSCommentHandler;
- OwningPtr<PragmaHandler> MSDetectMismatchHandler;
+ std::unique_ptr<PragmaHandler> AlignHandler;
+ std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
+ std::unique_ptr<PragmaHandler> OptionsHandler;
+ std::unique_ptr<PragmaHandler> PackHandler;
+ std::unique_ptr<PragmaHandler> MSStructHandler;
+ std::unique_ptr<PragmaHandler> UnusedHandler;
+ std::unique_ptr<PragmaHandler> WeakHandler;
+ std::unique_ptr<PragmaHandler> RedefineExtnameHandler;
+ std::unique_ptr<PragmaHandler> FPContractHandler;
+ std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
+ std::unique_ptr<PragmaHandler> OpenMPHandler;
+ std::unique_ptr<PragmaHandler> MSCommentHandler;
+ std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
+ std::unique_ptr<PragmaHandler> MSPointersToMembers;
+ std::unique_ptr<PragmaHandler> MSVtorDisp;
+
+ std::unique_ptr<CommentHandler> CommentSemaHandler;
/// Whether the '>' token acts as an operator or not. This will be
/// true except when we are parsing an expression within a C++
@@ -167,7 +169,7 @@
/// ColonProtectionRAIIObject RAII object.
bool ColonIsSacred;
- /// \brief When true, we are directly inside an Objective-C messsage
+ /// \brief When true, we are directly inside an Objective-C message
/// send expression.
///
/// This is managed by the \c InMessageExpressionRAIIObject class, and
@@ -193,6 +195,10 @@
++Depth;
++AddedLevels;
}
+ void addDepth(unsigned D) {
+ Depth += D;
+ AddedLevels += D;
+ }
unsigned getDepth() const { return Depth; }
};
@@ -229,6 +235,9 @@
const Token &getCurToken() const { return Tok; }
Scope *getCurScope() const { return Actions.getCurScope(); }
+ void incrementMSLocalManglingNumber() const {
+ return Actions.incrementMSLocalManglingNumber();
+ }
Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
@@ -266,24 +275,40 @@
/// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
/// the EOF was encountered.
bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
+ bool ParseTopLevelDecl() {
+ DeclGroupPtrTy Result;
+ return ParseTopLevelDecl(Result);
+ }
/// ConsumeToken - Consume the current 'peek token' and lex the next one.
- /// This does not work with all kinds of tokens: strings and specific other
- /// tokens must be consumed with custom methods below. This returns the
- /// location of the consumed token.
- SourceLocation ConsumeToken(bool ConsumeCodeCompletionTok = false) {
- assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
- !isTokenBrace() &&
+ /// This does not work with special tokens: string literals, code completion
+ /// and balanced tokens must be handled using the specific consume methods.
+ /// Returns the location of the consumed token.
+ SourceLocation ConsumeToken() {
+ assert(!isTokenSpecial() &&
"Should consume special tokens with Consume*Token");
-
- if (!ConsumeCodeCompletionTok && Tok.is(tok::code_completion))
- return handleUnexpectedCodeCompletionToken();
-
PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
return PrevTokLocation;
}
+ bool TryConsumeToken(tok::TokenKind Expected) {
+ if (Tok.isNot(Expected))
+ return false;
+ assert(!isTokenSpecial() &&
+ "Should consume special tokens with Consume*Token");
+ PrevTokLocation = Tok.getLocation();
+ PP.Lex(Tok);
+ return true;
+ }
+
+ bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
+ if (!TryConsumeToken(Expected))
+ return false;
+ Loc = PrevTokLocation;
+ return true;
+ }
+
private:
//===--------------------------------------------------------------------===//
// Low-Level token peeking and consumption methods.
@@ -301,12 +326,15 @@
bool isTokenBrace() const {
return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
}
-
/// isTokenStringLiteral - True if this token is a string-literal.
- ///
bool isTokenStringLiteral() const {
return tok::isStringLiteral(Tok.getKind());
}
+ /// isTokenSpecial - True if this token requires special consumption methods.
+ bool isTokenSpecial() const {
+ return isTokenStringLiteral() || isTokenParen() || isTokenBracket() ||
+ isTokenBrace() || Tok.is(tok::code_completion);
+ }
/// \brief Returns true if the current token is '=' or is a type of '='.
/// For typos, give a fixit to '='
@@ -318,14 +346,16 @@
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
if (isTokenParen())
return ConsumeParen();
- else if (isTokenBracket())
+ if (isTokenBracket())
return ConsumeBracket();
- else if (isTokenBrace())
+ if (isTokenBrace())
return ConsumeBrace();
- else if (isTokenStringLiteral())
+ if (isTokenStringLiteral())
return ConsumeStringToken();
- else
- return ConsumeToken(ConsumeCodeCompletionTok);
+ if (Tok.is(tok::code_completion))
+ return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
+ : handleUnexpectedCodeCompletionToken();
+ return ConsumeToken();
}
/// ConsumeParen - This consume method keeps the paren count up-to-date.
@@ -408,6 +438,20 @@
Tok.setKind(tok::eof);
}
+ /// \brief Determine if we're at the end of the file or at a transition
+ /// between modules.
+ bool isEofOrEom() {
+ tok::TokenKind Kind = Tok.getKind();
+ return Kind == tok::eof || Kind == tok::annot_module_begin ||
+ Kind == tok::annot_module_end || Kind == tok::annot_module_include;
+ }
+
+ /// \brief Initialize all pragma handlers.
+ void initializePragmaHandlers();
+
+ /// \brief Destroy and reset all pragma handlers.
+ void resetPragmaHandlers();
+
/// \brief Handle the annotation token produced for #pragma unused(...)
void HandlePragmaUnused();
@@ -427,6 +471,10 @@
/// #pragma comment...
void HandlePragmaMSComment();
+ void HandlePragmaMSPointersToMembers();
+
+ void HandlePragmaMSVtorDisp();
+
/// \brief Handle the annotation token produced for
/// #pragma align...
void HandlePragmaAlign();
@@ -562,6 +610,12 @@
/// otherwise emits a diagnostic and returns true.
bool TryKeywordIdentFallback(bool DisableKeyword);
+ /// TryIdentKeywordUpgrade - Convert the current identifier token back to
+ /// its original kind and return true if it was disabled by
+ /// TryKeywordIdentFallback(), otherwise return false. Use this to
+ /// contextually enable keywords.
+ bool TryIdentKeywordUpgrade();
+
/// \brief Get the TemplateIdAnnotation from the token.
TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
@@ -641,12 +695,14 @@
/// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
/// input. If so, it is consumed and false is returned.
///
- /// If the input is malformed, this emits the specified diagnostic. Next, if
- /// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
+ /// If a trivial punctuator misspelling is encountered, a FixIt error
+ /// diagnostic is issued and false is returned after recovery.
+ ///
+ /// If the input is malformed, this emits the specified diagnostic and true is
/// returned.
- bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
- const char *DiagMsg = "",
- tok::TokenKind SkipToTok = tok::unknown);
+ bool ExpectAndConsume(tok::TokenKind ExpectedTok,
+ unsigned Diag = diag::err_expected,
+ const char *DiagMsg = "");
/// \brief The parser expects a semicolon and, if present, will consume it.
///
@@ -684,14 +740,18 @@
public:
// ParseScope - Construct a new object to manage a scope in the
// parser Self where the new Scope is created with the flags
- // ScopeFlags, but only when ManageScope is true (the default). If
- // ManageScope is false, this object does nothing.
- ParseScope(Parser *Self, unsigned ScopeFlags, bool ManageScope = true)
+ // ScopeFlags, but only when we aren't about to enter a compound statement.
+ ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
+ bool BeforeCompoundStmt = false)
: Self(Self) {
- if (ManageScope)
+ if (EnteredScope && !BeforeCompoundStmt)
Self->EnterScope(ScopeFlags);
- else
+ else {
+ if (BeforeCompoundStmt)
+ Self->incrementMSLocalManglingNumber();
+
this->Self = 0;
+ }
}
// Exit - Exit the scope associated with this object now, rather
@@ -818,10 +878,10 @@
LateParsedClass(Parser *P, ParsingClass *C);
virtual ~LateParsedClass();
- virtual void ParseLexedMethodDeclarations();
- virtual void ParseLexedMemberInitializers();
- virtual void ParseLexedMethodDefs();
- virtual void ParseLexedAttributes();
+ void ParseLexedMethodDeclarations() override;
+ void ParseLexedMemberInitializers() override;
+ void ParseLexedMethodDefs() override;
+ void ParseLexedAttributes() override;
private:
Parser *Self;
@@ -845,7 +905,7 @@
SourceLocation Loc)
: Self(P), AttrName(Name), AttrNameLoc(Loc) {}
- virtual void ParseLexedAttributes();
+ void ParseLexedAttributes() override;
void addDecl(Decl *D) { Decls.push_back(D); }
};
@@ -877,7 +937,7 @@
explicit LexedMethod(Parser* P, Decl *MD)
: Self(P), D(MD), TemplateScope(false) {}
- virtual void ParseLexedMethodDefs();
+ void ParseLexedMethodDefs() override;
};
/// LateParsedDefaultArgument - Keeps track of a parameter that may
@@ -907,7 +967,7 @@
explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
: Self(P), Method(M), TemplateScope(false), ExceptionSpecTokens(0) { }
- virtual void ParseLexedMethodDeclarations();
+ void ParseLexedMethodDeclarations() override;
Parser* Self;
@@ -938,7 +998,7 @@
LateParsedMemberInitializer(Parser *P, Decl *FD)
: Self(P), Field(FD) { }
- virtual void ParseLexedMemberInitializers();
+ void ParseLexedMemberInitializers() override;
Parser *Self;
@@ -1604,9 +1664,27 @@
DSC_class, // class context, enables 'friend'
DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
+ DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
DSC_top_level // top-level/namespace declaration context
};
+ /// Is this a context in which we are parsing just a type-specifier (or
+ /// trailing-type-specifier)?
+ static bool isTypeSpecifier(DeclSpecContext DSC) {
+ switch (DSC) {
+ case DSC_normal:
+ case DSC_class:
+ case DSC_top_level:
+ return false;
+
+ case DSC_type_specifier:
+ case DSC_trailing:
+ case DSC_alias_declaration:
+ return true;
+ }
+ llvm_unreachable("Missing DeclSpecContext case");
+ }
+
/// Information on a C++0x for-range-initializer found while parsing a
/// declaration which turns out to be a for-range-declaration.
struct ForRangeInit {
@@ -1726,12 +1804,13 @@
/// \brief Starting with a scope specifier, identifier, or
/// template-id that refers to the current class, determine whether
/// this is a constructor declarator.
- bool isConstructorDeclarator();
+ bool isConstructorDeclarator(bool Unqualified);
/// \brief Specifies the context in which type-id/expression
/// disambiguation will occur.
enum TentativeCXXTypeIdContext {
TypeIdInParens,
+ TypeIdUnambiguous,
TypeIdAsTemplateArgument
};
@@ -1750,6 +1829,16 @@
return isTypeIdInParens(isAmbiguous);
}
+ /// \brief Checks if the current tokens form type-id or expression.
+ /// It is similar to isTypeIdInParens but does not suppose that type-id
+ /// is in parenthesis.
+ bool isTypeIdUnambiguously() {
+ bool IsAmbiguous;
+ if (getLangOpts().CPlusPlus)
+ return isCXXTypeId(TypeIdUnambiguous, IsAmbiguous);
+ return isTypeSpecifierQualifier();
+ }
+
/// isCXXDeclarationStatement - C++-specialized function that disambiguates
/// between a declaration or an expression statement, when parsing function
/// bodies. Returns true for declaration, false for expression.
@@ -1907,12 +1996,22 @@
/// locations where attributes are not allowed.
void DiagnoseAndSkipCXX11Attributes();
+ /// \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);
+
void MaybeParseGNUAttributes(Declarator &D,
LateParsedAttrList *LateAttrs = 0) {
if (Tok.is(tok::kw___attribute)) {
ParsedAttributes attrs(AttrFactory);
SourceLocation endLoc;
- ParseGNUAttributes(attrs, &endLoc, LateAttrs);
+ ParseGNUAttributes(attrs, &endLoc, LateAttrs, &D);
D.takeAttributes(attrs, endLoc);
}
}
@@ -1924,14 +2023,16 @@
}
void ParseGNUAttributes(ParsedAttributes &attrs,
SourceLocation *endLoc = 0,
- LateParsedAttrList *LateAttrs = 0);
+ LateParsedAttrList *LateAttrs = 0,
+ Declarator *D = 0);
void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs,
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ AttributeList::Syntax Syntax,
+ Declarator *D);
IdentifierLoc *ParseIdentifierLoc();
void MaybeParseCXX11Attributes(Declarator &D) {
@@ -1962,6 +2063,13 @@
SourceLocation *EndLoc = 0);
void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
SourceLocation *EndLoc = 0);
+ /// \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,
+ SourceLocation AttrNameLoc,
+ ParsedAttributes &Attrs, SourceLocation *EndLoc,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc);
IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc);
@@ -1973,30 +2081,25 @@
void ParseMicrosoftAttributes(ParsedAttributes &attrs,
SourceLocation *endLoc = 0);
void ParseMicrosoftDeclSpec(ParsedAttributes &Attrs);
- bool IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident);
- void ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
- SourceLocation Loc,
- ParsedAttributes &Attrs);
- void ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs);
+ bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
+ SourceLocation AttrNameLoc,
+ ParsedAttributes &Attrs);
void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
void ParseOpenCLAttributes(ParsedAttributes &attrs);
- void ParseOpenCLQualifiers(DeclSpec &DS);
+ void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
VersionTuple ParseVersionTuple(SourceRange &Range);
void ParseAvailabilityAttribute(IdentifierInfo &Availability,
SourceLocation AvailabilityLoc,
ParsedAttributes &attrs,
SourceLocation *endLoc);
-
- bool IsThreadSafetyAttribute(StringRef AttrName);
- void ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs,
- SourceLocation *EndLoc);
+
+ void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
+ SourceLocation ObjCBridgeRelatedLoc,
+ ParsedAttributes &attrs,
+ SourceLocation *endLoc);
void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
@@ -2154,6 +2257,10 @@
Decl *TagDecl);
ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
SourceLocation &EqualLoc);
+ void ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
+ VirtSpecifiers &VS,
+ ExprResult &BitfieldSize,
+ LateParsedAttrList &LateAttrs);
void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
ParsingDeclRAIIObject *DiagsFromTParams = 0);
@@ -2295,9 +2402,7 @@
DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc);
//===--------------------------------------------------------------------===//
- // GNU G++: Type Traits [Type-Traits.html in the GCC manual]
- ExprResult ParseUnaryTypeTrait();
- ExprResult ParseBinaryTypeTrait();
+ // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
ExprResult ParseTypeTrait();
//===--------------------------------------------------------------------===//
@@ -2307,14 +2412,13 @@
//===--------------------------------------------------------------------===//
// Preprocessor code-completion pass-through
- virtual void CodeCompleteDirective(bool InConditional);
- virtual void CodeCompleteInConditionalExclusion();
- virtual void CodeCompleteMacroName(bool IsDefinition);
- virtual void CodeCompletePreprocessorExpression();
- virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
- MacroInfo *MacroInfo,
- unsigned ArgumentIndex);
- virtual void CodeCompleteNaturalLanguage();
+ void CodeCompleteDirective(bool InConditional) override;
+ void CodeCompleteInConditionalExclusion() override;
+ void CodeCompleteMacroName(bool IsDefinition) override;
+ void CodeCompletePreprocessorExpression() override;
+ void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo,
+ unsigned ArgumentIndex) override;
+ void CodeCompleteNaturalLanguage() override;
};
} // end namespace clang
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
index a5192ef..5167c50 100644
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_REWRITEROPE_H
#define LLVM_CLANG_REWRITEROPE_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
@@ -144,7 +145,11 @@
inline RopePieceBTreeIterator operator++(int) { // Postincrement
RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
}
- private:
+
+ llvm::StringRef piece() const {
+ return llvm::StringRef(&(*CurPiece)[0], CurPiece->size());
+ }
+
void MoveToNextPiece();
};
diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h
index ec0bb5b..c313b45 100644
--- a/include/clang/Rewrite/Core/TokenRewriter.h
+++ b/include/clang/Rewrite/Core/TokenRewriter.h
@@ -17,9 +17,9 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Token.h"
-#include "llvm/ADT/OwningPtr.h"
#include <list>
#include <map>
+#include <memory>
namespace clang {
class LangOptions;
@@ -41,7 +41,7 @@
/// ScratchBuf - This is the buffer that we create scratch tokens from.
///
- OwningPtr<ScratchBuffer> ScratchBuf;
+ std::unique_ptr<ScratchBuffer> ScratchBuf;
TokenRewriter(const TokenRewriter &) LLVM_DELETED_FUNCTION;
void operator=(const TokenRewriter &) LLVM_DELETED_FUNCTION;
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
index 423f066..ff03eff 100644
--- a/include/clang/Rewrite/Frontend/FixItRewriter.h
+++ b/include/clang/Rewrite/Frontend/FixItRewriter.h
@@ -112,12 +112,12 @@
/// returns true) indicates whether the diagnostics handled by this
/// DiagnosticConsumer should be included in the number of diagnostics
/// reported by DiagnosticsEngine.
- virtual bool IncludeInDiagnosticCounts() const;
+ bool IncludeInDiagnosticCounts() const override;
/// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
/// capturing it to a log as needed.
- virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
- const Diagnostic &Info);
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) override;
/// \brief Emit a diagnostic via the adapted diagnostic client.
void Diag(SourceLocation Loc, unsigned DiagID);
diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h
index ea876d9..fc79270 100644
--- a/include/clang/Rewrite/Frontend/FrontendActions.h
+++ b/include/clang/Rewrite/Frontend/FrontendActions.h
@@ -22,24 +22,24 @@
class HTMLPrintAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class FixItAction : public ASTFrontendAction {
protected:
- OwningPtr<FixItRewriter> Rewriter;
- OwningPtr<FixItOptions> FixItOpts;
+ std::unique_ptr<FixItRewriter> Rewriter;
+ std::unique_ptr<FixItOptions> FixItOpts;
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
- virtual bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename);
+ bool BeginSourceFileAction(CompilerInstance &CI,
+ StringRef Filename) override;
- virtual void EndSourceFileAction();
+ void EndSourceFileAction() override;
- virtual bool hasASTFileSupport() const { return false; }
+ bool hasASTFileSupport() const override { return false; }
public:
FixItAction();
@@ -54,28 +54,28 @@
: WrapperFrontendAction(WrappedAction) {}
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
+ bool BeginInvocation(CompilerInstance &CI) override;
};
class RewriteObjCAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class RewriteMacrosAction : public PreprocessorFrontendAction {
protected:
- void ExecuteAction();
+ void ExecuteAction() override;
};
class RewriteTestAction : public PreprocessorFrontendAction {
protected:
- void ExecuteAction();
+ void ExecuteAction() override;
};
class RewriteIncludesAction : public PreprocessorFrontendAction {
protected:
- void ExecuteAction();
+ void ExecuteAction() override;
};
} // end namespace clang
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 508064d..171f9f9 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -18,8 +18,9 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
#include "clang/Sema/Ownership.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/Allocator.h"
#include <cassert>
@@ -245,6 +246,26 @@
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
+ /// Constructor for objc_bridge_related attributes.
+ AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Parm1,
+ IdentifierLoc *Parm2,
+ IdentifierLoc *Parm3,
+ Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+ ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
+ Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+ IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
+ NextInPosition(0), NextInPool(0) {
+ ArgsVector Args;
+ Args.push_back(Parm1);
+ Args.push_back(Parm2);
+ Args.push_back(Parm3);
+ memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion));
+ AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+ }
+
/// Constructor for type_tag_for_datatype attribute.
AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
@@ -368,44 +389,6 @@
return getArg(Arg).get<IdentifierLoc*>();
}
- class arg_iterator {
- ArgsUnion const *X;
- unsigned Idx;
- public:
- arg_iterator(ArgsUnion const *x, unsigned idx) : X(x), Idx(idx) {}
-
- arg_iterator& operator++() {
- ++Idx;
- return *this;
- }
-
- bool operator==(const arg_iterator& I) const {
- assert (X == I.X &&
- "compared arg_iterators are for different argument lists");
- return Idx == I.Idx;
- }
-
- bool operator!=(const arg_iterator& I) const {
- return !operator==(I);
- }
-
- ArgsUnion operator*() const {
- return X[Idx];
- }
-
- unsigned getArgNum() const {
- return Idx+1;
- }
- };
-
- arg_iterator arg_begin() const {
- return arg_iterator(getArgsBuffer(), 0);
- }
-
- arg_iterator arg_end() const {
- return arg_iterator(getArgsBuffer(), NumArgs);
- }
-
const AvailabilityChange &getAvailabilityIntroduced() const {
assert(getKind() == AT_Availability && "Not an availability attribute");
return getAvailabilitySlot(IntroducedSlot);
@@ -464,9 +447,23 @@
/// to pretty print itself.
unsigned getAttributeSpellingListIndex() const;
+ bool isTargetSpecificAttr() const;
+ bool isTypeAttr() const;
+
bool hasCustomParsing() const;
unsigned getMinArgs() const;
unsigned getMaxArgs() const;
+ bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
+ bool diagnoseLangOpts(class Sema &S) const;
+ bool existsInTarget(const llvm::Triple &T) const;
+ bool isKnownToGCC() const;
+
+ /// \brief If the parsed attribute has a semantic equivalent, and it would
+ /// have a semantic Spelling enumeration (due to having semantically-distinct
+ /// spelling variations), return the value of that semantic spelling. If the
+ /// parsed attribute does not have a semantic equivalent, or would not have
+ /// a Spelling enumeration, the value UINT_MAX is returned.
+ unsigned getSemanticSpelling() const;
};
/// A factory, from which one makes pools, from which one creates
@@ -607,8 +604,19 @@
syntax));
}
- AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
- SourceLocation TokLoc, int Arg);
+ AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Param1,
+ IdentifierLoc *Param2,
+ IdentifierLoc *Param3,
+ AttributeList::Syntax syntax) {
+ size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
+ void *memory = allocate(size);
+ return add(new (memory) AttributeList(attrName, attrRange,
+ scopeName, scopeLoc,
+ Param1, Param2, Param3,
+ syntax));
+ }
AttributeList *createTypeTagForDatatype(
IdentifierInfo *attrName, SourceRange attrRange,
@@ -647,40 +655,6 @@
}
};
-/// addAttributeLists - Add two AttributeLists together
-/// The right-hand list is appended to the left-hand list, if any
-/// A pointer to the joined list is returned.
-/// Note: the lists are not left unmodified.
-inline AttributeList *addAttributeLists(AttributeList *Left,
- AttributeList *Right) {
- if (!Left)
- return Right;
-
- AttributeList *next = Left, *prev;
- do {
- prev = next;
- next = next->getNext();
- } while (next);
- prev->setNext(Right);
- return Left;
-}
-
-/// CXX11AttributeList - A wrapper around a C++11 attribute list.
-/// Stores, in addition to the list proper, whether or not an actual list was
-/// (as opposed to an empty list, which may be ill-formed in some places) and
-/// the source range of the list.
-struct CXX11AttributeList {
- AttributeList *AttrList;
- SourceRange Range;
- bool HasAttr;
- CXX11AttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
- : AttrList(attrList), Range(range), HasAttr (hasAttr) {
- }
- CXX11AttributeList ()
- : AttrList(0), Range(), HasAttr(false) {
- }
-};
-
/// ParsedAttributes - A collection of parsed attributes. Currently
/// we don't differentiate between the various attribute syntaxes,
/// which is basically silly.
@@ -693,10 +667,7 @@
: pool(factory), list(0) {
}
- ParsedAttributes(ParsedAttributes &attrs)
- : pool(attrs.pool), list(attrs.list) {
- attrs.list = 0;
- }
+ ParsedAttributes(const ParsedAttributes &) LLVM_DELETED_FUNCTION;
AttributePool &getPool() const { return pool; }
@@ -767,6 +738,20 @@
return attr;
}
+ /// Add objc_bridge_related attribute.
+ AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Param1,
+ IdentifierLoc *Param2,
+ IdentifierLoc *Param3,
+ AttributeList::Syntax syntax) {
+ AttributeList *attr =
+ pool.create(attrName, attrRange, scopeName, scopeLoc,
+ Param1, Param2, Param3, syntax);
+ add(attr);
+ return attr;
+ }
+
/// Add type_tag_for_datatype attribute.
AttributeList *addNewTypeTagForDatatype(
IdentifierInfo *attrName, SourceRange attrRange,
@@ -808,15 +793,6 @@
return attr;
}
- AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
- SourceLocation loc, int arg) {
- AttributeList *attr =
- pool.createIntegerAttribute(C, name, loc, arg);
- add(attr);
- return attr;
- }
-
-
private:
mutable AttributePool pool;
AttributeList *list;
@@ -831,6 +807,41 @@
AANT_ArgumentIdentifier
};
+/// These constants match the enumerated choices of
+/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
+enum AttributeDeclKind {
+ ExpectedFunction,
+ ExpectedUnion,
+ ExpectedVariableOrFunction,
+ ExpectedFunctionOrMethod,
+ ExpectedParameter,
+ ExpectedFunctionMethodOrBlock,
+ ExpectedFunctionMethodOrClass,
+ ExpectedFunctionMethodOrParameter,
+ ExpectedClass,
+ ExpectedVariable,
+ ExpectedMethod,
+ ExpectedVariableFunctionOrLabel,
+ ExpectedFieldOrGlobalVar,
+ ExpectedStruct,
+ ExpectedVariableFunctionOrTag,
+ ExpectedTLSVar,
+ ExpectedVariableOrField,
+ ExpectedVariableFieldOrTag,
+ ExpectedTypeOrNamespace,
+ ExpectedObjectiveCInterface,
+ ExpectedMethodOrProperty,
+ ExpectedStructOrUnion,
+ ExpectedStructOrUnionOrClass,
+ ExpectedType,
+ ExpectedObjCInstanceMethod,
+ ExpectedObjCInterfaceDeclInitMethod,
+ ExpectedFunctionVariableOrClass,
+ ExpectedObjectiveCProtocol,
+ ExpectedFunctionGlobalVarMethodOrProperty,
+ ExpectedStructOrTypedef
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 64de82c..11bdb76 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -966,20 +966,19 @@
CCTUInfo(new GlobalCodeCompletionAllocator) {}
/// \brief Prints the finalized code-completion results.
- virtual void ProcessCodeCompleteResults(Sema &S,
- CodeCompletionContext Context,
- CodeCompletionResult *Results,
- unsigned NumResults);
+ void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
+ CodeCompletionResult *Results,
+ unsigned NumResults) override;
- virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
- OverloadCandidate *Candidates,
- unsigned NumCandidates);
+ void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+ OverloadCandidate *Candidates,
+ unsigned NumCandidates) override;
- virtual CodeCompletionAllocator &getAllocator() {
+ CodeCompletionAllocator &getAllocator() override {
return CCTUInfo.getAllocator();
}
- virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
+ CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
};
} // end namespace clang
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 8f6bd18..2cd10da 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -285,14 +285,6 @@
static const TST TST_auto = clang::TST_auto;
static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
static const TST TST_atomic = clang::TST_atomic;
- static const TST TST_image1d_t = clang::TST_image1d_t;
- static const TST TST_image1d_array_t = clang::TST_image1d_array_t;
- static const TST TST_image1d_buffer_t = clang::TST_image1d_buffer_t;
- static const TST TST_image2d_t = clang::TST_image2d_t;
- static const TST TST_image2d_array_t = clang::TST_image2d_array_t;
- static const TST TST_image3d_t = clang::TST_image3d_t;
- static const TST TST_sampler_t = clang::TST_sampler_t;
- static const TST TST_event_t = clang::TST_event_t;
static const TST TST_error = clang::TST_error;
// type-qualifiers
@@ -516,7 +508,8 @@
bool hasTagDefinition() const;
/// \brief Turn a type-specifier-type into a string like "_Bool" or "union".
- static const char *getSpecifierName(DeclSpec::TST T);
+ static const char *getSpecifierName(DeclSpec::TST T,
+ const PrintingPolicy &Policy);
static const char *getSpecifierName(DeclSpec::TQ Q);
static const char *getSpecifierName(DeclSpec::TSS S);
static const char *getSpecifierName(DeclSpec::TSC C);
@@ -604,36 +597,45 @@
/// TODO: use a more general approach that still allows these
/// diagnostics to be ignored when desired.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID);
+ const char *&PrevSpec, unsigned &DiagID,
+ const PrintingPolicy &Policy);
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID);
bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
+ unsigned &DiagID, const PrintingPolicy &Policy);
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID);
bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID);
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID);
+ unsigned &DiagID, const PrintingPolicy &Policy);
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, ParsedType Rep);
+ unsigned &DiagID, ParsedType Rep,
+ const PrintingPolicy &Policy);
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, Decl *Rep, bool Owned);
+ unsigned &DiagID, Decl *Rep, bool Owned,
+ const PrintingPolicy &Policy);
bool SetTypeSpecType(TST T, SourceLocation TagKwLoc,
SourceLocation TagNameLoc, const char *&PrevSpec,
- unsigned &DiagID, ParsedType Rep);
+ unsigned &DiagID, ParsedType Rep,
+ const PrintingPolicy &Policy);
bool SetTypeSpecType(TST T, SourceLocation TagKwLoc,
SourceLocation TagNameLoc, const char *&PrevSpec,
- unsigned &DiagID, Decl *Rep, bool Owned);
+ unsigned &DiagID, Decl *Rep, bool Owned,
+ const PrintingPolicy &Policy);
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, Expr *Rep);
+ unsigned &DiagID, Expr *Rep,
+ const PrintingPolicy &policy);
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID);
+ const char *&PrevSpec, unsigned &DiagID,
+ const PrintingPolicy &Policy);
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID);
+ const char *&PrevSpec, unsigned &DiagID,
+ const PrintingPolicy &Policy);
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID);
+ const char *&PrevSpec, unsigned &DiagID,
+ const PrintingPolicy &Policy);
bool SetTypeSpecError();
void UpdateDeclRep(Decl *Rep) {
assert(isDeclRep((TST) TypeSpecType));
@@ -707,22 +709,12 @@
void addAttributes(AttributeList *AL) {
Attrs.addAll(AL);
}
- void setAttributes(AttributeList *AL) {
- Attrs.set(AL);
- }
bool hasAttributes() const { return !Attrs.empty(); }
ParsedAttributes &getAttributes() { return Attrs; }
const ParsedAttributes &getAttributes() const { return Attrs; }
- /// \brief Return the current attribute list and remove them from
- /// the DeclSpec so that it doesn't own them.
- ParsedAttributes takeAttributes() {
- // The non-const "copy" constructor clears the operand automatically.
- return Attrs;
- }
-
void takeAttributesFrom(ParsedAttributes &attrs) {
Attrs.takeAllFrom(attrs);
}
@@ -743,7 +735,8 @@
/// Finish - This does final analysis of the declspec, issuing diagnostics for
/// things like "_Imaginary" (lacking an FP type). After calling this method,
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
- void Finish(DiagnosticsEngine &D, Preprocessor &PP);
+ void Finish(DiagnosticsEngine &D, Preprocessor &PP,
+ const PrintingPolicy &Policy);
const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
return writtenBS;
@@ -828,8 +821,8 @@
// NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
unsigned PropertyAttributes : 12;
- IdentifierInfo *GetterName; // getter name of NULL if no getter
- IdentifierInfo *SetterName; // setter name of NULL if no setter
+ IdentifierInfo *GetterName; // getter name or NULL if no getter
+ IdentifierInfo *SetterName; // setter name or NULL if no setter
};
/// \brief Represents a C++ unqualified-id that has been parsed.
@@ -1112,7 +1105,8 @@
};
/// ParamInfo - An array of paraminfo objects is allocated whenever a function
- /// declarator is parsed. There are two interesting styles of arguments here:
+ /// declarator is parsed. There are two interesting styles of parameters
+ /// here:
/// K&R-style identifier lists and parameter type lists. K&R-style identifier
/// lists will have information about the identifier, but no type information.
/// Parameter type lists will have type info (if the actions module provides
@@ -1144,7 +1138,7 @@
struct FunctionTypeInfo : TypeInfoCommon {
/// hasPrototype - This is true if the function had at least one typed
- /// argument. If the function is () or (a,b,c), then it has no prototype,
+ /// parameter. If the function is () or (a,b,c), then it has no prototype,
/// and is treated as a K&R-style function.
unsigned hasPrototype : 1;
@@ -1167,8 +1161,8 @@
/// ExceptionSpecType - An ExceptionSpecificationType value.
unsigned ExceptionSpecType : 3;
- /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
- unsigned DeleteArgInfo : 1;
+ /// DeleteParams - If this is true, we need to delete[] Params.
+ unsigned DeleteParams : 1;
/// HasTrailingReturnType - If this is true, a trailing return type was
/// specified.
@@ -1183,9 +1177,9 @@
/// The location of the right parenthesis in the source.
unsigned RParenLoc;
- /// NumArgs - This is the number of formal arguments provided for the
+ /// NumParams - This is the number of formal parameters specified by the
/// declarator.
- unsigned NumArgs;
+ unsigned NumParams;
/// NumExceptions - This is the number of types in the dynamic-exception-
/// decl, if the function has one.
@@ -1213,10 +1207,10 @@
/// \brief The location of the keyword introducing the spec, if any.
unsigned ExceptionSpecLoc;
- /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
- /// describe the arguments for this function declarator. This is null if
- /// there are no arguments specified.
- ParamInfo *ArgInfo;
+ /// Params - This is a pointer to a new[]'d array of ParamInfo objects that
+ /// describe the parameters specified by this function declarator. null if
+ /// there are no parameters specified.
+ ParamInfo *Params;
union {
/// \brief Pointer to a new[]'d array of TypeAndRange objects that
@@ -1233,30 +1227,28 @@
/// type specified.
UnionParsedType TrailingReturnType;
- /// \brief Reset the argument list to having zero arguments.
+ /// \brief Reset the parameter list to having zero parameters.
///
/// This is used in various places for error recovery.
- void freeArgs() {
- if (DeleteArgInfo) {
- delete[] ArgInfo;
- DeleteArgInfo = false;
+ void freeParams() {
+ if (DeleteParams) {
+ delete[] Params;
+ DeleteParams = false;
}
- NumArgs = 0;
+ NumParams = 0;
}
void destroy() {
- if (DeleteArgInfo)
- delete[] ArgInfo;
+ if (DeleteParams)
+ delete[] Params;
if (getExceptionSpecType() == EST_Dynamic)
delete[] Exceptions;
}
/// isKNRPrototype - Return true if this is a K&R style identifier list,
/// like "void foo(a,b,c)". In a function definition, this will be followed
- /// by the argument type definitions.
- bool isKNRPrototype() const {
- return !hasPrototype && NumArgs != 0;
- }
+ /// by the parameter type definitions.
+ bool isKNRPrototype() const { return !hasPrototype && NumParams != 0; }
SourceLocation getLParenLoc() const {
return SourceLocation::getFromRawEncoding(LParenLoc);
@@ -1425,7 +1417,7 @@
static DeclaratorChunk getFunction(bool hasProto,
bool isAmbiguous,
SourceLocation LParenLoc,
- ParamInfo *ArgInfo, unsigned NumArgs,
+ ParamInfo *Params, unsigned NumParams,
SourceLocation EllipsisLoc,
SourceLocation RParenLoc,
unsigned TypeQuals,
@@ -2139,6 +2131,8 @@
bool SetSpecifier(Specifier VS, SourceLocation Loc,
const char *&PrevSpec);
+ bool isUnset() const { return Specifiers == 0; }
+
bool isOverrideSpecified() const { return Specifiers & VS_Override; }
SourceLocation getOverrideLoc() const { return VS_overrideLoc; }
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index 4f4a87f..9a0541d 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -113,7 +113,7 @@
/// the complete parsing of the current declaration.
class DelayedDiagnostic {
public:
- enum DDKind { Deprecation, Access, ForbiddenType };
+ enum DDKind { Deprecation, Unavailable, Access, ForbiddenType };
unsigned char Kind; // actually a DDKind
bool Triggered;
@@ -122,11 +122,13 @@
void Destroy();
- static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
- const NamedDecl *D,
- const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
- StringRef Msg);
+ static DelayedDiagnostic makeAvailability(Sema::AvailabilityDiagnostic AD,
+ SourceLocation Loc,
+ const NamedDecl *D,
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ const ObjCPropertyDecl *ObjCProperty,
+ StringRef Msg);
+
static DelayedDiagnostic makeAccess(SourceLocation Loc,
const AccessedEntity &Entity) {
@@ -162,12 +164,14 @@
}
const NamedDecl *getDeprecationDecl() const {
- assert(Kind == Deprecation && "Not a deprecation diagnostic.");
+ assert((Kind == Deprecation || Kind == Unavailable) &&
+ "Not a deprecation diagnostic.");
return DeprecationData.Decl;
}
StringRef getDeprecationMessage() const {
- assert(Kind == Deprecation && "Not a deprecation diagnostic.");
+ assert((Kind == Deprecation || Kind == Unavailable) &&
+ "Not a deprecation diagnostic.");
return StringRef(DeprecationData.Message,
DeprecationData.MessageLen);
}
@@ -257,7 +261,7 @@
if (pool.Diagnostics.empty()) return;
if (Diagnostics.empty()) {
- Diagnostics = llvm_move(pool.Diagnostics);
+ Diagnostics = std::move(pool.Diagnostics);
} else {
Diagnostics.append(pool.pool_begin(), pool.pool_end());
}
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
index 99d94a1..abe974c 100644
--- a/include/clang/Sema/IdentifierResolver.h
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -150,11 +150,14 @@
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
/// true if 'D' belongs to the given declaration context.
///
- /// \param ExplicitInstantiationOrSpecialization When true, we are checking
- /// whether the declaration is in scope for the purposes of explicit template
- /// instantiation or specialization. The default is false.
+ /// \param AllowInlineNamespace If \c true, we are checking whether a prior
+ /// declaration is in scope in a declaration that requires a prior
+ /// declaration (because it is either explicitly qualified or is a
+ /// 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 ExplicitInstantiationOrSpecialization = false) const;
+ bool AllowInlineNamespace = false) const;
/// AddDecl - Link the decl to its shadowed decl chain.
void AddDecl(NamedDecl *D);
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index 105c879..03643b0 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -259,7 +259,7 @@
}
LookupResultKind getResultKind() const {
- sanity();
+ assert(sanity());
return ResultKind;
}
@@ -637,13 +637,7 @@
void configure();
// Sanity checks.
- void sanityImpl() const;
-
- void sanity() const {
-#ifndef NDEBUG
- sanityImpl();
-#endif
- }
+ bool sanity() const;
bool sanityCheckUnresolved() const {
for (iterator I = begin(), E = end(); I != E; ++I)
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index e9ba479..1f517e7 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -65,31 +65,31 @@
/// \brief Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
- virtual Decl *GetExternalDecl(uint32_t ID);
+ Decl *GetExternalDecl(uint32_t ID) override;
/// \brief Resolve a selector ID into a selector.
- virtual Selector GetExternalSelector(uint32_t ID);
+ Selector GetExternalSelector(uint32_t ID) override;
/// \brief Returns the number of selectors known to the external AST
/// source.
- virtual uint32_t GetNumExternalSelectors();
+ uint32_t GetNumExternalSelectors() override;
/// \brief Resolve the offset of a statement in the decl stream into
/// a statement.
- virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
+ Stmt *GetExternalDeclStmt(uint64_t Offset) override;
/// \brief Resolve the offset of a set of C++ base specifiers in the decl
/// stream into an array of specifiers.
- virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
+ CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
/// \brief Find all declarations with the given name in the
/// given context.
- virtual bool
- FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
+ bool
+ FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) override;
/// \brief Ensures that the table of all visible declarations inside this
/// context is up to date.
- virtual void completeVisibleDeclsMap(const DeclContext *DC);
+ void completeVisibleDeclsMap(const DeclContext *DC) override;
/// \brief Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
@@ -99,9 +99,9 @@
/// are returned.
///
/// \return an indication of whether the load succeeded or failed.
- virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
- bool (*isKindWeWant)(Decl::Kind),
- SmallVectorImpl<Decl*> &Result);
+ ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+ bool (*isKindWeWant)(Decl::Kind),
+ SmallVectorImpl<Decl*> &Result) override;
/// \brief Finds all declarations lexically contained within the given
/// DeclContext.
@@ -121,12 +121,12 @@
/// \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);
+ void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
+ SmallVectorImpl<Decl *> &Decls) override;
/// \brief Gives the external AST source an opportunity to complete
/// an incomplete type.
- virtual void CompleteType(TagDecl *Tag);
+ void CompleteType(TagDecl *Tag) override;
/// \brief Gives the external AST source an opportunity to complete an
/// incomplete Objective-C class.
@@ -134,27 +134,27 @@
/// This routine will only be invoked if the "externally completed" bit is
/// set on the ObjCInterfaceDecl via the function
/// \c ObjCInterfaceDecl::setExternallyCompleted().
- virtual void CompleteType(ObjCInterfaceDecl *Class);
+ void CompleteType(ObjCInterfaceDecl *Class) override;
/// \brief Loads comment ranges.
- virtual void ReadComments();
+ void ReadComments() override;
/// \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.
- virtual void StartedDeserializing();
+ void StartedDeserializing() override;
/// \brief Notify ExternalASTSource that we finished the deserialization of
/// a decl or type. Must be paired with StartedDeserializing.
- virtual void FinishedDeserializing();
+ void FinishedDeserializing() override;
/// \brief Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
- virtual void StartTranslationUnit(ASTConsumer *Consumer);
+ void StartTranslationUnit(ASTConsumer *Consumer) override;
/// \brief Print any statistics that have been gathered regarding
/// the external AST source.
- virtual void PrintStats();
+ void PrintStats() override;
/// \brief Perform layout on the given record.
@@ -184,16 +184,17 @@
/// be laid out according to the ABI.
///
/// \returns true if the record layout was provided, false otherwise.
- virtual bool
+ 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);
+ llvm::DenseMap<const CXXRecordDecl *,
+ CharUnits> &VirtualBaseOffsets) override;
/// Return the amount of memory used by memory buffers, breaking down
/// by heap-backed versus mmap'ed memory.
- virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
+ void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
//===--------------------------------------------------------------------===//
// ExternalSemaSource.
@@ -202,24 +203,25 @@
/// \brief Initialize the semantic source with the Sema instance
/// being used to perform semantic analysis on the abstract syntax
/// tree.
- virtual void InitializeSema(Sema &S);
+ void InitializeSema(Sema &S) override;
/// \brief Inform the semantic consumer that Sema is no longer available.
- virtual void ForgetSema();
+ void ForgetSema() override;
/// \brief Load the contents of the global method pool for a given
/// selector.
- virtual void ReadMethodPool(Selector Sel);
+ void ReadMethodPool(Selector Sel) override;
/// \brief Load the set of namespaces that are known to the external source,
/// which will be used during typo correction.
- virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces);
+ void
+ ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces) override;
/// \brief Load the set of used but not defined functions or variables with
/// internal linkage, or used but not defined inline functions.
- virtual void ReadUndefinedButUsed(
- llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
-
+ void ReadUndefinedButUsed(
+ llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override;
+
/// \brief Do last resort, unqualified lookup on a LookupResult that
/// Sema cannot find.
///
@@ -228,7 +230,7 @@
/// \param S the Scope of the identifier occurrence.
///
/// \return true to tell Sema to recover using the LookupResult.
- virtual bool LookupUnqualified(LookupResult &R, Scope *S);
+ bool LookupUnqualified(LookupResult &R, Scope *S) override;
/// \brief Read the set of tentative definitions known to the external Sema
/// source.
@@ -237,8 +239,8 @@
/// given vector of tentative definitions. Note that this routine may be
/// invoked multiple times; the external source should take care not to
/// introduce the same declarations repeatedly.
- virtual void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs);
-
+ void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs) override;
+
/// \brief Read the set of unused file-scope declarations known to the
/// external Sema source.
///
@@ -246,9 +248,9 @@
/// given vector of declarations. Note that this routine may be
/// invoked multiple times; the external source should take care not to
/// introduce the same declarations repeatedly.
- virtual void ReadUnusedFileScopedDecls(
- SmallVectorImpl<const DeclaratorDecl*> &Decls);
-
+ void ReadUnusedFileScopedDecls(
+ SmallVectorImpl<const DeclaratorDecl*> &Decls) override;
+
/// \brief Read the set of delegating constructors known to the
/// external Sema source.
///
@@ -256,8 +258,8 @@
/// given vector of declarations. Note that this routine may be
/// invoked multiple times; the external source should take care not to
/// introduce the same declarations repeatedly.
- virtual void ReadDelegatingConstructors(
- SmallVectorImpl<CXXConstructorDecl*> &Decls);
+ void ReadDelegatingConstructors(
+ SmallVectorImpl<CXXConstructorDecl*> &Decls) override;
/// \brief Read the set of ext_vector type declarations known to the
/// external Sema source.
@@ -266,7 +268,7 @@
/// the given vector of declarations. Note that this routine may be
/// invoked multiple times; the external source should take care not to
/// introduce the same declarations repeatedly.
- virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls);
+ void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls) override;
/// \brief Read the set of dynamic classes known to the external Sema source.
///
@@ -274,7 +276,7 @@
/// the given vector of declarations. Note that this routine may be
/// invoked multiple times; the external source should take care not to
/// introduce the same declarations repeatedly.
- virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls);
+ void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls) override;
/// \brief Read the set of locally-scoped extern "C" declarations known to the
/// external Sema source.
@@ -283,7 +285,8 @@
/// declarations to the given vector of declarations. Note that this routine
/// may be invoked multiple times; the external source should take care not
/// to introduce the same declarations repeatedly.
- virtual void ReadLocallyScopedExternCDecls(SmallVectorImpl<NamedDecl*>&Decls);
+ void ReadLocallyScopedExternCDecls(
+ SmallVectorImpl<NamedDecl*> &Decls) override;
/// \brief Read the set of referenced selectors known to the
/// external Sema source.
@@ -292,8 +295,8 @@
/// given vector of selectors. Note that this routine
/// may be invoked multiple times; the external source should take care not
/// to introduce the same selectors repeatedly.
- virtual void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,
- SourceLocation> > &Sels);
+ void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,
+ SourceLocation> > &Sels) override;
/// \brief Read the set of weak, undeclared identifiers known to the
/// external Sema source.
@@ -302,15 +305,15 @@
/// the given vector. Note that this routine may be invoked multiple times;
/// the external source should take care not to introduce the same identifiers
/// repeatedly.
- virtual void ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI);
+ void ReadWeakUndeclaredIdentifiers(
+ SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) override;
/// \brief Read the set of used vtables known to the external Sema source.
///
/// The external source should append its own used vtables to the given
/// vector. Note that this routine may be invoked multiple times; the external
/// source should take care not to introduce the same vtables repeatedly.
- virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables);
+ void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
/// \brief Read the set of pending instantiations known to the external
/// Sema source.
@@ -319,8 +322,8 @@
/// given vector. Note that this routine may be invoked multiple times; the
/// external source should take care not to introduce the same instantiations
/// repeatedly.
- virtual void ReadPendingInstantiations(
- SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending);
+ void ReadPendingInstantiations(
+ SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending) override;
/// \brief Read the set of late parsed template functions for this source.
///
@@ -328,17 +331,18 @@
/// into the map. Note that this routine may be invoked multiple times; the
/// external source should take care not to introduce the same map entries
/// repeatedly.
- virtual void ReadLateParsedTemplates(
- llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap);
+ void ReadLateParsedTemplates(
+ llvm::DenseMap<const FunctionDecl *,
+ LateParsedTemplate *> &LPTMap) override;
/// \copydoc ExternalSemaSource::CorrectTypo
/// \note Returns the first nonempty correction.
- virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
- int LookupKind, Scope *S, CXXScopeSpec *SS,
- CorrectionCandidateCallback &CCC,
- DeclContext *MemberContext,
- bool EnteringContext,
- const ObjCObjectPointerType *OPT);
+ TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
+ int LookupKind, Scope *S, CXXScopeSpec *SS,
+ CorrectionCandidateCallback &CCC,
+ DeclContext *MemberContext,
+ bool EnteringContext,
+ const ObjCObjectPointerType *OPT) override;
/// \brief Produces a diagnostic note if one of the attached sources
/// contains a complete definition for \p T. Queries the sources in list
@@ -350,7 +354,8 @@
/// \param T the \c QualType that should have been complete at \p Loc
///
/// \return true if a diagnostic was produced, false otherwise.
- virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, QualType T);
+ bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
+ QualType T) override;
// isa/cast/dyn_cast support
static bool classof(const MultiplexExternalSemaSource*) { return true; }
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index b8bd14a..7086b72 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -579,7 +579,11 @@
/// (CUDA) This candidate was not viable because the callee
/// was not accessible from the caller's target (i.e. host->device,
/// global->host, device->host).
- ovl_fail_bad_target
+ ovl_fail_bad_target,
+
+ /// This candidate function was not viable because an enable_if
+ /// attribute disabled it.
+ ovl_fail_enable_if
};
/// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index b7d7710..4bbefcb 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -158,6 +158,7 @@
bool isInvalid() const { return Invalid; }
bool isUsable() const { return !Invalid && Val; }
+ bool isUnset() const { return !Invalid && !Val; }
PtrTy get() const { return Val; }
// FIXME: Replace with get.
@@ -199,6 +200,7 @@
bool isInvalid() const { return PtrWithInvalid & 0x01; }
bool isUsable() const { return PtrWithInvalid > 0x01; }
+ bool isUnset() const { return PtrWithInvalid == 0; }
PtrTy get() const {
void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/Sema/PrettyDeclStackTrace.h
index aa55705..c0c772d 100644
--- a/include/clang/Sema/PrettyDeclStackTrace.h
+++ b/include/clang/Sema/PrettyDeclStackTrace.h
@@ -39,7 +39,7 @@
const char *Msg)
: S(S), TheDecl(D), Loc(Loc), Message(Msg) {}
- virtual void print(raw_ostream &OS) const;
+ void print(raw_ostream &OS) const override;
};
}
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index 249a4c7..54ca2a6 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -18,6 +18,12 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+namespace llvm {
+
+class raw_ostream;
+
+}
+
namespace clang {
class Decl;
@@ -109,6 +115,10 @@
/// interrelates with other control flow statements.
unsigned short Flags;
+ /// \brief Declarations with static linkage are mangled with the number of
+ /// scopes seen as a component.
+ unsigned short MSLocalManglingNumber;
+
/// PrototypeDepth - This is the number of function prototype scopes
/// enclosing this scope, including this scope.
unsigned short PrototypeDepth;
@@ -120,6 +130,7 @@
/// FnParent - If this scope has a parent scope that is a function body, this
/// pointer is non-null and points to it. This is used for label processing.
Scope *FnParent;
+ Scope *MSLocalManglingParent;
/// BreakParent/ContinueParent - This is a direct link to the innermost
/// BreakScope/ContinueScope which contains the contents of this scope
@@ -181,6 +192,11 @@
const Scope *getFnParent() const { return FnParent; }
Scope *getFnParent() { return FnParent; }
+ const Scope *getMSLocalManglingParent() const {
+ return MSLocalManglingParent;
+ }
+ Scope *getMSLocalManglingParent() { return MSLocalManglingParent; }
+
/// getContinueParent - Return the closest scope that a continue statement
/// would be affected by.
Scope *getContinueParent() {
@@ -219,10 +235,11 @@
return PrototypeIndex++;
}
- typedef DeclSetTy::iterator decl_iterator;
- decl_iterator decl_begin() const { return DeclsInScope.begin(); }
- decl_iterator decl_end() const { return DeclsInScope.end(); }
- bool decl_empty() const { return DeclsInScope.empty(); }
+ typedef llvm::iterator_range<DeclSetTy::iterator> decl_range;
+ decl_range decls() const {
+ return decl_range(DeclsInScope.begin(), DeclsInScope.end());
+ }
+ bool decl_empty() const { return DeclsInScope.empty(); }
void AddDecl(Decl *D) {
DeclsInScope.insert(D);
@@ -232,6 +249,22 @@
DeclsInScope.erase(D);
}
+ void incrementMSLocalManglingNumber() {
+ if (Scope *MSLMP = getMSLocalManglingParent())
+ MSLMP->MSLocalManglingNumber += 1;
+ }
+
+ void decrementMSLocalManglingNumber() {
+ if (Scope *MSLMP = getMSLocalManglingParent())
+ MSLMP->MSLocalManglingNumber -= 1;
+ }
+
+ unsigned getMSLocalManglingNumber() const {
+ if (const Scope *MSLMP = getMSLocalManglingParent())
+ return MSLMP->MSLocalManglingNumber;
+ return 1;
+ }
+
/// isDeclScope - Return true if this is the scope that the specified decl is
/// declared in.
bool isDeclScope(Decl *D) {
@@ -273,6 +306,18 @@
return false;
}
+ /// isInObjcMethodOuterScope - Return true if this scope is an
+ /// Objective-C method outer most body.
+ bool isInObjcMethodOuterScope() const {
+ if (const Scope *S = this) {
+ // If this scope is an objc method scope, then we succeed.
+ if (S->getFlags() & ObjCMethodScope)
+ return true;
+ }
+ return false;
+ }
+
+
/// isTemplateParamScope - Return true if this scope is a C++
/// template parameter scope.
bool isTemplateParamScope() const {
@@ -316,32 +361,29 @@
/// is a FunctionPrototypeScope.
bool containedInPrototypeScope() const;
- typedef UsingDirectivesTy::iterator udir_iterator;
- typedef UsingDirectivesTy::const_iterator const_udir_iterator;
-
void PushUsingDirective(UsingDirectiveDecl *UDir) {
UsingDirectives.push_back(UDir);
}
- udir_iterator using_directives_begin() {
- return UsingDirectives.begin();
- }
+ typedef llvm::iterator_range<UsingDirectivesTy::iterator>
+ using_directives_range;
- udir_iterator using_directives_end() {
- return UsingDirectives.end();
- }
-
- const_udir_iterator using_directives_begin() const {
- return UsingDirectives.begin();
- }
-
- const_udir_iterator using_directives_end() const {
- return UsingDirectives.end();
+ using_directives_range using_directives() {
+ return using_directives_range(UsingDirectives.begin(),
+ UsingDirectives.end());
}
/// Init - This is used by the parser to implement scope caching.
///
void Init(Scope *parent, unsigned flags);
+
+ /// \brief Sets up the specified scope flags and adjusts the scope state
+ /// variables accordingly.
+ ///
+ void AddFlags(unsigned Flags);
+
+ void dumpImpl(raw_ostream &OS) const;
+ void dump() const;
};
} // end namespace clang
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 06afe1a..98af371 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -110,6 +110,21 @@
/// with \c __attribute__((objc_requires_super)).
bool ObjCShouldCallSuper;
+ /// True when this is a method marked as a designated initializer.
+ bool ObjCIsDesignatedInit;
+ /// This starts true for a method marked as designated initializer and will
+ /// be set to false if there is an invocation to a designated initializer of
+ /// the super class.
+ bool ObjCWarnForNoDesignatedInitChain;
+
+ /// True when this is an initializer method not marked as a designated
+ /// initializer within a class that has at least one initializer marked as a
+ /// designated initializer.
+ bool ObjCIsSecondaryInit;
+ /// This starts true for a secondary initializer method and will be set to
+ /// false if there is an invocation of an initializer on 'self'.
+ bool ObjCWarnForNoInitDelegation;
+
/// \brief Used to determine if errors occurred in this function or block.
DiagnosticErrorTrap ErrorTrap;
@@ -318,6 +333,10 @@
HasIndirectGoto(false),
HasDroppedStmt(false),
ObjCShouldCallSuper(false),
+ ObjCIsDesignatedInit(false),
+ ObjCWarnForNoDesignatedInitChain(false),
+ ObjCIsSecondaryInit(false),
+ ObjCWarnForNoInitDelegation(false),
ErrorTrap(Diag) { }
virtual ~FunctionScopeInfo();
@@ -708,10 +727,10 @@
/// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
/// if we can determine that the full expression is not instantiation-
/// dependent, then we can entirely avoid its capture.
- ///
- /// const int n = 0;
- /// [&] (auto x) {
- /// (void)+n + x;
+ ///
+ /// const int n = 0;
+ /// [&] (auto x) {
+ /// (void)+n + x;
/// };
/// Interestingly, this strategy would involve a capture of n, even though
/// it's obviously not odr-used here, because the full-expression is
@@ -725,12 +744,12 @@
/// Before anyone is tempted to implement a strategy for not-capturing 'n',
/// consider the insightful warning in:
/// /cfe-commits/Week-of-Mon-20131104/092596.html
- /// "The problem is that the set of captures for a lambda is part of the ABI
- /// (since lambda layout can be made visible through inline functions and the
- /// like), and there are no guarantees as to which cases we'll manage to build
- /// an lvalue-to-rvalue conversion in, when parsing a template -- some
- /// seemingly harmless change elsewhere in Sema could cause us to start or stop
- /// building such a node. So we need a rule that anyone can implement and get
+ /// "The problem is that the set of captures for a lambda is part of the ABI
+ /// (since lambda layout can be made visible through inline functions and the
+ /// like), and there are no guarantees as to which cases we'll manage to build
+ /// an lvalue-to-rvalue conversion in, when parsing a template -- some
+ /// seemingly harmless change elsewhere in Sema could cause us to start or stop
+ /// building such a node. So we need a rule that anyone can implement and get
/// exactly the same result".
///
void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
@@ -738,7 +757,7 @@
|| isa<MemberExpr>(CapturingVarExpr));
NonODRUsedCapturingExprs.insert(CapturingVarExpr);
}
- bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) {
+ bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
assert(isa<DeclRefExpr>(CapturingVarExpr)
|| isa<MemberExpr>(CapturingVarExpr));
return NonODRUsedCapturingExprs.count(CapturingVarExpr);
@@ -761,13 +780,11 @@
return getNumPotentialVariableCaptures() ||
PotentialThisCaptureLocation.isValid();
}
-
- // When passed the index, returns the VarDecl and Expr associated
- // with the index.
- void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E);
-
-};
+ // When passed the index, returns the VarDecl and Expr associated
+ // with the index.
+ void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const;
+};
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
: Base(0, false), Property(0) {}
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 48794d6..ea9344d 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -38,17 +38,18 @@
#include "clang/Sema/LocInfoType.h"
#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Ownership.h"
+#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/TypoCorrection.h"
#include "clang/Sema/Weak.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include <deque>
+#include <memory>
#include <string>
#include <vector>
@@ -101,6 +102,7 @@
class DependentDiagnostic;
class DesignatedInitExpr;
class Designation;
+ class EnableIfAttr;
class EnumConstantDecl;
class Expr;
class ExtVectorType;
@@ -152,7 +154,6 @@
class Stmt;
class StringLiteral;
class SwitchStmt;
- class TargetAttributesSema;
class TemplateArgument;
class TemplateArgumentList;
class TemplateArgumentLoc;
@@ -204,7 +205,6 @@
class Sema {
Sema(const Sema &) LLVM_DELETED_FUNCTION;
void operator=(const Sema &) LLVM_DELETED_FUNCTION;
- mutable const TargetAttributesSema* TheTargetAttributesSema;
///\brief Source of additional semantic information.
ExternalSemaSource *ExternalSource;
@@ -263,6 +263,32 @@
bool MSStructPragmaOn; // True when \#pragma ms_struct on
+ /// \brief Controls member pointer representation format under the MS ABI.
+ LangOptions::PragmaMSPointersToMembersKind
+ MSPointerToMemberRepresentationMethod;
+
+ enum PragmaVtorDispKind {
+ PVDK_Push, ///< #pragma vtordisp(push, mode)
+ PVDK_Set, ///< #pragma vtordisp(mode)
+ PVDK_Pop, ///< #pragma vtordisp(pop)
+ PVDK_Reset ///< #pragma vtordisp()
+ };
+
+ /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft
+ /// C++ ABI. Possible values are 0, 1, and 2, which mean:
+ ///
+ /// 0: Suppress all vtordisps
+ /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial
+ /// structors
+ /// 2: Always insert vtordisps to support RTTI on partially constructed
+ /// objects
+ ///
+ /// The stack always has at least one element in it.
+ SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack;
+
+ /// \brief Source location for newly created implicit MSInheritanceAttrs
+ SourceLocation ImplicitMSInheritanceAttrLoc;
+
/// VisContext - Manages the stack for \#pragma GCC visibility.
void *VisContext; // Really a "PragmaVisStack*"
@@ -307,7 +333,7 @@
ExtVectorDeclsType ExtVectorDecls;
/// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
- OwningPtr<CXXFieldCollector> FieldCollector;
+ std::unique_ptr<CXXFieldCollector> FieldCollector;
typedef llvm::SmallSetVector<const NamedDecl*, 16> NamedDeclSetType;
@@ -319,7 +345,7 @@
/// PureVirtualClassDiagSet - a set of class declarations which we have
/// emitted a list of pure virtual functions. Used to prevent emitting the
/// same list more than once.
- OwningPtr<RecordDeclSetTy> PureVirtualClassDiagSet;
+ std::unique_ptr<RecordDeclSetTy> PureVirtualClassDiagSet;
/// ParsingInitForAutoVars - a set of declarations with auto types for which
/// we are currently parsing the initializer.
@@ -480,13 +506,15 @@
QualType SavedCXXThisTypeOverride;
public:
- ContextRAII(Sema &S, DeclContext *ContextToPush)
+ ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true)
: S(S), SavedContext(S.CurContext),
SavedContextState(S.DelayedDiagnostics.pushUndelayed()),
SavedCXXThisTypeOverride(S.CXXThisTypeOverride)
{
assert(ContextToPush && "pushing null context");
S.CurContext = ContextToPush;
+ if (NewThisContext)
+ S.CXXThisTypeOverride = QualType();
}
void pop() {
@@ -569,7 +597,7 @@
RecordDecl *MSVCGuidDecl;
/// \brief Caches identifiers/selectors for NSFoundation APIs.
- OwningPtr<NSAPI> NSAPIObj;
+ std::unique_ptr<NSAPI> NSAPIObj;
/// \brief The declaration of the Objective-C NSNumber class.
ObjCInterfaceDecl *NSNumberDecl;
@@ -833,6 +861,7 @@
/// Private Helper predicate to check for 'self'.
bool isSelfExpr(Expr *RExpr);
+ bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method);
/// \brief Cause the active diagnostic on the DiagosticsEngine to be
/// emitted. This is closely coupled to the SemaDiagnosticBuilder class and
@@ -856,6 +885,8 @@
typedef llvm::MCAsmParserSemaCallback::InlineAsmIdentifierInfo
InlineAsmIdentifierInfo;
+ void addImplicitTypedef(StringRef Name, QualType T);
+
public:
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
TranslationUnitKind TUKind = TU_Complete,
@@ -872,7 +903,6 @@
DiagnosticsEngine &getDiagnostics() const { return Diags; }
SourceManager &getSourceManager() const { return SourceMgr; }
- const TargetAttributesSema &getTargetAttributesSema() const;
Preprocessor &getPreprocessor() const { return PP; }
ASTContext &getASTContext() const { return Context; }
ASTConsumer &getASTConsumer() const { return Consumer; }
@@ -967,7 +997,7 @@
void PushFunctionScope();
void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
sema::LambdaScopeInfo *PushLambdaScope();
-
+
/// \brief This is used to inform Sema what the current TemplateParameterDepth
/// is during Parsing. Currently it is used to pass on the depth
/// when parsing generic lambda 'auto' parameters.
@@ -983,6 +1013,18 @@
return FunctionScopes.back();
}
+ sema::FunctionScopeInfo *getEnclosingFunction() const {
+ if (FunctionScopes.empty())
+ return 0;
+
+ for (int e = FunctionScopes.size()-1; e >= 0; --e) {
+ if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
+ continue;
+ return FunctionScopes[e];
+ }
+ return 0;
+ }
+
template <typename ExprT>
void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
if (!isUnevaluatedContext())
@@ -1086,6 +1128,8 @@
CanThrowResult canThrow(const Expr *E);
const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
const FunctionProtoType *FPT);
+ void UpdateExceptionSpec(FunctionDecl *FD,
+ const FunctionProtoType::ExtProtoInfo &EPI);
bool CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range);
bool CheckDistantExceptionSpec(QualType T);
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
@@ -1148,7 +1192,7 @@
public:
BoundTypeDiagnoser1(unsigned DiagID, const T1 &Arg1)
: TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1) { }
- virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+ void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
if (Suppressed) return;
S.Diag(Loc, DiagID) << getPrintable(Arg1) << T;
}
@@ -1168,7 +1212,7 @@
: TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
Arg2(Arg2) { }
- virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+ void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
if (Suppressed) return;
S.Diag(Loc, DiagID) << getPrintable(Arg1) << getPrintable(Arg2) << T;
}
@@ -1189,7 +1233,7 @@
: TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
Arg2(Arg2), Arg3(Arg3) { }
- virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+ void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
if (Suppressed) return;
S.Diag(Loc, DiagID)
<< getPrintable(Arg1) << getPrintable(Arg2) << getPrintable(Arg3) << T;
@@ -1299,11 +1343,6 @@
/// function to pin them on. ActOnFunctionDeclarator reads this list and patches
/// them into the FunctionDecl.
std::vector<NamedDecl*> DeclsInPrototypeScope;
- /// Nonzero if we are currently parsing a function declarator. This is a counter
- /// as opposed to a boolean so we can deal with nested function declarators
- /// such as:
- /// void f(void (*g)(), ...)
- unsigned InFunctionDeclarator;
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = 0);
@@ -1325,7 +1364,8 @@
SourceLocation IILoc,
Scope *S,
CXXScopeSpec *SS,
- ParsedType &SuggestedType);
+ ParsedType &SuggestedType,
+ bool AllowClassTemplates = false);
/// \brief Describes the result of the name lookup and resolution performed
/// by \c ClassifyName().
@@ -1482,8 +1522,6 @@
void CheckVariableDeclarationType(VarDecl *NewVD);
void CheckCompleteVariableDeclaration(VarDecl *var);
void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
- void ActOnStartFunctionDeclarator();
- void ActOnEndFunctionDeclarator();
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
TypeSourceInfo *TInfo,
@@ -1491,7 +1529,6 @@
MultiTemplateParamsArg TemplateParamLists,
bool &AddToScope);
bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
- void checkVoidParamDecl(ParmVarDecl *Param);
bool CheckConstexprFunctionDecl(const FunctionDecl *FD);
bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body);
@@ -1555,6 +1592,16 @@
return D && isa<ObjCMethodDecl>(D);
}
+ /// \brief Determine whether we can delay parsing the body of a function or
+ /// function template until it is used, assuming we don't care about emitting
+ /// code for that function.
+ ///
+ /// This will be \c false if we may need the body of the function in the
+ /// middle of parsing an expression (where it's impractical to switch to
+ /// parsing a different function), for instance, if it's constexpr in C++11
+ /// or has an 'auto' return type in C++14. These cases are essentially bugs.
+ bool canDelayFunctionBody(const Declarator &D);
+
/// \brief Determine whether we can skip parsing the body of a function
/// definition, assuming we don't care about analyzing its body or emitting
/// code for that function.
@@ -1640,7 +1687,8 @@
Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
AccessSpecifier AS,
- RecordDecl *Record);
+ RecordDecl *Record,
+ const PrintingPolicy &Policy);
Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
RecordDecl *Record);
@@ -1665,7 +1713,8 @@
MultiTemplateParamsArg TemplateParameterLists,
bool &OwnedDecl, bool &IsDependent,
SourceLocation ScopedEnumKWLoc,
- bool ScopedEnumUsesClassTag, TypeResult UnderlyingType);
+ bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
+ bool IsTypeSpecifier);
Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
unsigned TagSpec, SourceLocation TagLoc,
@@ -1823,11 +1872,11 @@
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
/// true if 'D' belongs to the given declaration context.
///
- /// \param ExplicitInstantiationOrSpecialization When true, we are checking
- /// whether the declaration is in scope for the purposes of explicit template
- /// instantiation or specialization. The default is false.
+ /// \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 ExplicitInstantiationOrSpecialization = false);
+ bool AllowInlineNamespace = false);
/// Finds the scope corresponding to the given decl context, if it
/// happens to be an enclosing scope. Otherwise return NULL.
@@ -1858,6 +1907,10 @@
unsigned AttrSpellingListIndex);
DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
unsigned AttrSpellingListIndex);
+ MSInheritanceAttr *
+ mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
+ unsigned AttrSpellingListIndex,
+ MSInheritanceAttr::Spelling SemanticSpelling);
FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range,
IdentifierInfo *Format, int FormatIdx,
int FirstArg, unsigned AttrSpellingListIndex);
@@ -1880,7 +1933,7 @@
void mergeDeclAttributes(NamedDecl *New, Decl *Old,
AvailabilityMergeKind AMK = AMK_Redeclaration);
void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
- bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S,
+ bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S,
bool MergeTypeWithOld);
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
Scope *S, bool MergeTypeWithOld);
@@ -1951,9 +2004,9 @@
QualType &ConvertedType);
bool IsBlockPointerConversion(QualType FromType, QualType ToType,
QualType& ConvertedType);
- bool FunctionArgTypesAreEqual(const FunctionProtoType *OldType,
- const FunctionProtoType *NewType,
- unsigned *ArgPos = 0);
+ bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
+ const FunctionProtoType *NewType,
+ unsigned *ArgPos = 0);
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
QualType FromType, QualType ToType);
@@ -2067,10 +2120,10 @@
AllowScopedEnumerations(AllowScopedEnumerations) {}
/// Match an integral or (possibly scoped) enumeration type.
- bool match(QualType T);
+ bool match(QualType T) override;
SemaDiagnosticBuilder
- diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) {
+ diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override {
return diagnoseNotInt(S, Loc, T);
}
@@ -2160,13 +2213,13 @@
CXXRecordDecl *ActingContext,
Expr *From, QualType ToType,
OverloadCandidateSet& CandidateSet,
- bool AllowObjCConversionOnExplicit = false);
+ bool AllowObjCConversionOnExplicit);
void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
Expr *From, QualType ToType,
OverloadCandidateSet &CandidateSet,
- bool AllowObjCConversionOnExplicit = false);
+ bool AllowObjCConversionOnExplicit);
void AddSurrogateCandidate(CXXConversionDecl *Conversion,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
@@ -2199,6 +2252,11 @@
// identified by the expression Expr
void NoteAllOverloadCandidates(Expr* E, QualType DestType = QualType());
+ /// Check the enable_if expressions on the given function. Returns the first
+ /// failing attribute, or NULL if they were all successful.
+ EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
+ bool MissingImplicitThis = false);
+
// [PossiblyAFunctionType] --> [Return]
// NonFunctionType --> NonFunctionType
// R (A) --> R(A)
@@ -2484,6 +2542,7 @@
bool RValueThis, unsigned ThisQuals);
CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
+ bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id);
LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R,
ArrayRef<QualType> ArgTys,
bool AllowRaw,
@@ -2527,8 +2586,7 @@
AssociatedClassSet &AssociatedClasses);
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
- bool ConsiderLinkage,
- bool ExplicitInstantiationOrSpecialization);
+ bool ConsiderLinkage, bool AllowInlineNamespace);
void DiagnoseAmbiguousLookup(LookupResult &Result);
//@}
@@ -2562,6 +2620,9 @@
bool checkStringLiteralArgumentAttr(const AttributeList &Attr,
unsigned ArgNum, StringRef &Str,
SourceLocation *ArgLocation = 0);
+ bool checkMSInheritanceAttrOnDefinition(
+ CXXRecordDecl *RD, SourceRange Range, bool BestCase,
+ MSInheritanceAttr::Spelling SemanticSpelling);
void CheckAlignasUnderalignment(Decl *D);
@@ -2570,6 +2631,11 @@
/// function type typedefs and typename template arguments.
void adjustMemberFunctionCC(QualType &T, bool IsStatic);
+ // Check if there is an explicit attribute, but only look through parens.
+ // The intent is to look for an attribute on the current declarator, but not
+ // one that came from a typedef.
+ bool hasExplicitCallingConv(QualType &T);
+
/// Get the outermost AttributedType node that sets a calling convention.
/// Valid types should not have multiple attributes with different CCs.
const AttributedType *getCallingConvAttributedType(QualType T) const;
@@ -2578,8 +2644,6 @@
StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
SourceRange Range);
- void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
- bool &IncompleteImpl, unsigned DiagID);
void WarnConflictingTypedMethods(ObjCMethodDecl *Method,
ObjCMethodDecl *MethodDecl,
bool IsProtocolMethodDecl);
@@ -2597,15 +2661,6 @@
typedef llvm::SmallPtrSet<Selector, 8> SelectorSet;
typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap;
- /// CheckProtocolMethodDefs - This routine checks unimplemented
- /// methods declared in protocol, and those referenced by it.
- void CheckProtocolMethodDefs(SourceLocation ImpLoc,
- ObjCProtocolDecl *PDecl,
- bool& IncompleteImpl,
- const SelectorSet &InsMap,
- const SelectorSet &ClsMap,
- ObjCContainerDecl *CDecl);
-
/// CheckImplementationIvars - This routine checks if the instance variables
/// listed in the implelementation match those listed in the interface.
void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
@@ -2621,7 +2676,8 @@
/// DiagnoseUnimplementedProperties - This routine warns on those properties
/// which must be implemented by this implementation.
void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
- ObjCContainerDecl *CDecl);
+ ObjCContainerDecl *CDecl,
+ bool SynthesizeProperties);
/// DefaultSynthesizeProperties - This routine default synthesizes all
/// properties which must be synthesized in the class's \@implementation.
@@ -2629,12 +2685,6 @@
ObjCInterfaceDecl *IDecl);
void DefaultSynthesizeProperties(Scope *S, Decl *D);
- /// CollectImmediateProperties - This routine collects all properties in
- /// the class and its conforming protocols; but not those it its super class.
- void CollectImmediateProperties(ObjCContainerDecl *CDecl,
- llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
- llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap);
-
/// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is
/// an ivar synthesized for 'Method' and 'Method' is a property accessor
/// declared in class 'IFace'.
@@ -2643,7 +2693,8 @@
/// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which
/// backs the property is not used in the property's accessor.
- void DiagnoseUnusedBackingIvarInAccessor(Scope *S);
+ void DiagnoseUnusedBackingIvarInAccessor(Scope *S,
+ const ObjCImplementationDecl *ImplD);
/// GetIvarBackingPropertyAccessor - If method is a property setter/getter and
/// it property has a backing ivar, returns this ivar; otherwise, returns NULL.
@@ -2692,6 +2743,10 @@
void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D);
+ void DiagnoseMissingDesignatedInitOverrides(
+ const ObjCImplementationDecl *ImplD,
+ const ObjCInterfaceDecl *IFD);
+
void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
enum MethodMatchStrategy {
@@ -2785,12 +2840,6 @@
const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel,
QualType ObjectType=QualType());
-
- /// DiagnoseMismatchedMethodsInGlobalPool - This routine goes through list of
- /// methods in global pool and issues diagnostic on identical selectors which
- /// have mismathched types.
- void DiagnoseMismatchedMethodsInGlobalPool();
-
/// LookupImplementedMethodInGlobalPool - Returns the method which has an
/// implementation.
ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel);
@@ -3083,12 +3132,15 @@
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
- void EmitDeprecationWarning(NamedDecl *D, StringRef Message,
- SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty);
+ enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable };
- void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
+ void EmitAvailabilityWarning(AvailabilityDiagnostic AD,
+ NamedDecl *D, StringRef Message,
+ SourceLocation Loc,
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ const ObjCPropertyDecl *ObjCProperty);
+
+ void HandleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
bool makeUnavailableInSystemHeader(SourceLocation loc,
StringRef message);
@@ -3682,6 +3734,7 @@
const LookupResult &Previous);
bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
const CXXScopeSpec &SS,
+ const DeclarationNameInfo &NameInfo,
SourceLocation NameLoc);
NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
@@ -4208,32 +4261,6 @@
ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
SourceLocation RParen);
- /// ActOnUnaryTypeTrait - Parsed one of the unary type trait support
- /// pseudo-functions.
- ExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
- SourceLocation KWLoc,
- ParsedType Ty,
- SourceLocation RParen);
-
- ExprResult BuildUnaryTypeTrait(UnaryTypeTrait OTT,
- SourceLocation KWLoc,
- TypeSourceInfo *T,
- SourceLocation RParen);
-
- /// ActOnBinaryTypeTrait - Parsed one of the bianry type trait support
- /// pseudo-functions.
- ExprResult ActOnBinaryTypeTrait(BinaryTypeTrait OTT,
- SourceLocation KWLoc,
- ParsedType LhsTy,
- ParsedType RhsTy,
- SourceLocation RParen);
-
- ExprResult BuildBinaryTypeTrait(BinaryTypeTrait BTT,
- SourceLocation KWLoc,
- TypeSourceInfo *LhsT,
- TypeSourceInfo *RhsT,
- SourceLocation RParen);
-
/// \brief Parsed one of the type trait support pseudo-functions.
ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
ArrayRef<ParsedType> Args,
@@ -4647,8 +4674,7 @@
//
Decl *ActOnStartLinkageSpecification(Scope *S,
SourceLocation ExternLoc,
- SourceLocation LangLoc,
- StringRef Lang,
+ Expr *LangStr,
SourceLocation LBraceLoc);
Decl *ActOnFinishLinkageSpecification(Scope *S,
Decl *LinkageSpec,
@@ -4672,8 +4698,11 @@
MultiTemplateParamsArg TemplateParameterLists,
Expr *BitfieldWidth, const VirtSpecifiers &VS,
InClassInitStyle InitStyle);
- void ActOnCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc,
- Expr *Init);
+
+ void ActOnStartCXXInClassMemberInitializer();
+ void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl,
+ SourceLocation EqualLoc,
+ Expr *Init);
MemInitResult ActOnMemInitializer(Decl *ConstructorD,
Scope *S,
@@ -4799,6 +4828,7 @@
AttributeList *AttrList);
void ActOnFinishCXXMemberDecls();
+ void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);
void ActOnReenterTemplateScope(Scope *S, Decl *Template);
void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D);
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
@@ -5162,7 +5192,7 @@
SourceLocation RAngleLoc);
DeclResult ActOnVarTemplateSpecialization(
- Scope *S, VarTemplateDecl *VarTemplate, Declarator &D, TypeSourceInfo *DI,
+ Scope *S, Declarator &D, TypeSourceInfo *DI,
SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
StorageClass SC, bool IsPartialSpecialization);
@@ -5318,18 +5348,12 @@
/// \param Converted Will receive the converted, canonicalized template
/// arguments.
///
- ///
- /// \param ExpansionIntoFixedList If non-NULL, will be set true to indicate
- /// when the template arguments contain a pack expansion that is being
- /// expanded into a fixed parameter list.
- ///
- /// \returns True if an error occurred, false otherwise.
+ /// \returns true if an error occurred, false otherwise.
bool CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc,
TemplateArgumentListInfo &TemplateArgs,
bool PartialTemplateArgs,
- SmallVectorImpl<TemplateArgument> &Converted,
- bool *ExpansionIntoFixedList = 0);
+ SmallVectorImpl<TemplateArgument> &Converted);
bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
const TemplateArgumentLoc &Arg,
@@ -6249,13 +6273,15 @@
SourceRange InstantiationRange = SourceRange());
/// \brief Note that we are substituting prior template arguments into a
- /// non-type or template template parameter.
+ /// non-type parameter.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
NamedDecl *Template,
NonTypeTemplateParmDecl *Param,
ArrayRef<TemplateArgument> TemplateArgs,
SourceRange InstantiationRange);
+ /// \brief Note that we are substituting prior template arguments into a
+ /// template template parameter.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
NamedDecl *Template,
TemplateTemplateParmDecl *Param,
@@ -6287,6 +6313,15 @@
bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
SourceRange InstantiationRange);
+ // FIXME: Replace this with a constructor once we can use delegating
+ // constructors in llvm.
+ void Initialize(
+ ActiveTemplateInstantiation::InstantiationKind Kind,
+ SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
+ Decl *Entity, NamedDecl *Template = nullptr,
+ ArrayRef<TemplateArgument> TemplateArgs = ArrayRef<TemplateArgument>(),
+ sema::TemplateDeductionInfo *DeductionInfo = nullptr);
+
InstantiatingTemplate(const InstantiatingTemplate&) LLVM_DELETED_FUNCTION;
InstantiatingTemplate&
@@ -6902,6 +6937,22 @@
SourceLocation RParenLoc,
Expr *SubExpr);
+ void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr);
+
+ bool checkObjCBridgeRelatedComponents(SourceLocation Loc,
+ QualType DestType, QualType SrcType,
+ ObjCInterfaceDecl *&RelatedClass,
+ ObjCMethodDecl *&ClassMethod,
+ ObjCMethodDecl *&InstanceMethod,
+ TypedefNameDecl *&TDNDecl,
+ bool CfToNs);
+
+ bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
+ QualType DestType, QualType SrcType,
+ Expr *&SrcExpr);
+
+ bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
+
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
/// \brief Check whether the given new method is a valid override of the
@@ -6969,6 +7020,17 @@
/// \#pragma comment(kind, "arg").
void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg);
+ /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma
+ /// pointers_to_members(representation method[, general purpose
+ /// representation]).
+ void ActOnPragmaMSPointersToMembers(
+ LangOptions::PragmaMSPointersToMembersKind Kind,
+ SourceLocation PragmaLoc);
+
+ /// \brief Called on well formed \#pragma vtordisp().
+ void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc,
+ MSVtorDispAttr::Mode Value);
+
/// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
@@ -7052,6 +7114,9 @@
/// \brief Initialization of data-sharing attributes stack.
void InitDataSharingAttributesStack();
void DestroyDataSharingAttributesStack();
+ ExprResult PerformImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op);
+ ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op,
+ OpenMPClauseKind CKind);
public:
/// \brief Called on start of new data sharing attribute block.
void StartOpenMPDSABlock(OpenMPDirectiveKind K,
@@ -7086,6 +7151,32 @@
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed '\#pragma omp simd' after parsing
+ /// of the associated statement.
+ StmtResult ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
+ OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
+ Expr *Expr,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'if' clause.
+ OMPClause *ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'num_threads' clause.
+ OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+ /// \brief Called on well-formed 'safelen' clause.
+ OMPClause *ActOnOpenMPSafelenClause(Expr *Length,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
unsigned Argument,
@@ -7120,6 +7211,11 @@
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// \brief Called on well-formed 'copyin' clause.
+ OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// \brief The kind of conversion being performed.
enum CheckedConversionKind {
@@ -7155,6 +7251,10 @@
// functions and arrays to their respective pointers (C99 6.3.2.1).
ExprResult UsualUnaryConversions(Expr *E);
+ /// CallExprUnaryConversions - a special case of an unary conversion
+ /// performed on a function designator of a call expression.
+ ExprResult CallExprUnaryConversions(Expr *E);
+
// DefaultFunctionArrayConversion - converts functions and arrays
// to their respective pointers (C99 6.3.2.1).
ExprResult DefaultFunctionArrayConversion(Expr *E);
@@ -7204,13 +7304,14 @@
/// function, issuing a diagnostic if not.
void checkVariadicArgument(const Expr *E, VariadicCallType CT);
+ /// Check to see if a given expression could have '.c_str()' called on it.
+ bool hasCStrMethod(const Expr *E);
+
/// GatherArgumentsForCall - Collector argument expressions for various
/// form of call prototypes.
- bool GatherArgumentsForCall(SourceLocation CallLoc,
- FunctionDecl *FDecl,
+ bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
const FunctionProtoType *Proto,
- unsigned FirstProtoArg,
- ArrayRef<Expr *> Args,
+ unsigned FirstParam, ArrayRef<Expr *> Args,
SmallVectorImpl<Expr *> &AllArgs,
VariadicCallType CallType = VariadicDoesNotApply,
bool AllowExplicit = false,
@@ -7433,6 +7534,10 @@
bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
SourceLocation QuestionLoc);
+ void DiagnoseAlwaysNonNullPointer(Expr *E,
+ Expr::NullPointerConstantKind NullType,
+ bool IsEqual, SourceRange Range);
+
/// type checking for vector binary operators.
QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign);
@@ -7442,6 +7547,8 @@
QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc);
+ bool isLaxVectorConversion(QualType srcType, QualType destType);
+
/// type checking declaration initializers (C99 6.7.8)
bool CheckForConstantInitializer(Expr *e, QualType t);
@@ -7833,19 +7940,22 @@
SourceLocation Loc);
void checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
- unsigned NumProtoArgs, bool IsMemberFunction,
- SourceLocation Loc, SourceRange Range,
- VariadicCallType CallType);
-
+ unsigned NumParams, bool IsMemberFunction, SourceLocation Loc,
+ SourceRange Range, VariadicCallType CallType);
bool CheckObjCString(Expr *Arg);
ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
+ unsigned MaxWidth);
+ 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);
bool SemaBuiltinVAStart(CallExpr *TheCall);
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
@@ -7860,6 +7970,7 @@
private:
bool SemaBuiltinPrefetch(CallExpr *TheCall);
+ bool SemaBuiltinMMPrefetch(CallExpr *TheCall);
bool SemaBuiltinObjectSize(CallExpr *TheCall);
bool SemaBuiltinLongjmp(CallExpr *TheCall);
ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
@@ -7901,9 +8012,9 @@
SourceLocation Loc, SourceRange range,
llvm::SmallBitVector &CheckedVarArgs);
- void CheckNonNullArguments(const NonNullAttr *NonNull,
- const Expr * const *ExprArgs,
- SourceLocation CallSiteLoc);
+ void CheckAbsoluteValueFunction(const CallExpr *Call,
+ const FunctionDecl *FDecl,
+ IdentifierInfo *FnInfo);
void CheckMemaccessArguments(const CallExpr *Call,
unsigned BId,
@@ -7915,8 +8026,12 @@
void CheckStrncatArguments(const CallExpr *Call,
IdentifierInfo *FnName);
- void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
- SourceLocation ReturnLoc);
+ void CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
+ SourceLocation ReturnLoc,
+ bool isObjCMethod = false,
+ const AttrVec *Attrs = 0,
+ const FunctionDecl *FD = 0);
+
void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
void CheckForIntOverflow(Expr *E);
@@ -7930,6 +8045,10 @@
void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field,
Expr *Init);
+ /// \brief Check if the given expression contains 'break' or 'continue'
+ /// statement that produces control flow different from GCC.
+ void CheckBreakContinueBinding(Expr *E);
+
public:
/// \brief Register a magic integral constant to be used as a type tag.
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind,
@@ -7958,7 +8077,7 @@
private:
/// \brief A map from magic value to type information.
- OwningPtr<llvm::DenseMap<TypeTagMagicValue, TypeTagData> >
+ std::unique_ptr<llvm::DenseMap<TypeTagMagicValue, TypeTagData>>
TypeTagForDatatypeMagicValues;
/// \brief Peform checks on a call of a function with argument_with_type_tag
@@ -7991,6 +8110,10 @@
/// template substitution or instantiation.
Scope *getCurScope() const { return CurScope; }
+ void incrementMSLocalManglingNumber() const {
+ return CurScope->incrementMSLocalManglingNumber();
+ }
+
IdentifierInfo *getSuperIdentifier() const;
IdentifierInfo *getFloat128Identifier() const;
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 01d4cc9..0b3d32b 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -24,43 +24,43 @@
inline PartialDiagnostic Sema::PDiag(unsigned DiagID) {
return PartialDiagnostic(DiagID, Context.getDiagAllocator());
}
-
-
-// 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;
- return !isa<ParmVarDecl>(Var) &&
- Var->isUsableInConstantExpressions(Context) &&
- Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
-}
-
-// Directly mark a variable odr-used. Given a choice, prefer to use
-// MarkVariableReferenced since it does additional checks and then
-// calls MarkVarDeclODRUsed.
-// If the variable must be captured:
-// - if FunctionScopeIndexToStopAt is null, capture it in the CurContext
-// - else capture it in the DeclContext that maps to the
-// *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.
-inline void MarkVarDeclODRUsed(VarDecl *Var,
- SourceLocation Loc, Sema &SemaRef,
- const unsigned *const FunctionScopeIndexToStopAt) {
- // Keep track of used but undefined variables.
- // FIXME: We shouldn't suppress this warning for static data members.
- if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
- !Var->isExternallyVisible() &&
- !(Var->isStaticDataMember() && Var->hasInit())) {
- SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
- if (old.isInvalid()) old = Loc;
- }
- QualType CaptureType, DeclRefType;
- SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit,
- /*EllipsisLoc*/ SourceLocation(),
- /*BuildAndDiagnose*/ true,
- CaptureType, DeclRefType,
- FunctionScopeIndexToStopAt);
-
- Var->markUsed(SemaRef.Context);
+
+
+// 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;
+ return !isa<ParmVarDecl>(Var) &&
+ Var->isUsableInConstantExpressions(Context) &&
+ Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
+}
+
+// Directly mark a variable odr-used. Given a choice, prefer to use
+// MarkVariableReferenced since it does additional checks and then
+// calls MarkVarDeclODRUsed.
+// If the variable must be captured:
+// - if FunctionScopeIndexToStopAt is null, capture it in the CurContext
+// - else capture it in the DeclContext that maps to the
+// *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.
+inline void MarkVarDeclODRUsed(VarDecl *Var,
+ SourceLocation Loc, Sema &SemaRef,
+ const unsigned *const FunctionScopeIndexToStopAt) {
+ // Keep track of used but undefined variables.
+ // FIXME: We shouldn't suppress this warning for static data members.
+ if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
+ !Var->isExternallyVisible() &&
+ !(Var->isStaticDataMember() && Var->hasInit())) {
+ SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
+ if (old.isInvalid()) old = Loc;
+ }
+ QualType CaptureType, DeclRefType;
+ SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit,
+ /*EllipsisLoc*/ SourceLocation(),
+ /*BuildAndDiagnose*/ true,
+ CaptureType, DeclRefType,
+ FunctionScopeIndexToStopAt);
+
+ Var->markUsed(SemaRef.Context);
}
}
diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h
index cf9fff1..f636750 100644
--- a/include/clang/Sema/SemaLambda.h
+++ b/include/clang/Sema/SemaLambda.h
@@ -1,39 +1,36 @@
-//===--- SemaLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file provides some common utility functions for processing
-/// Lambdas.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_LAMBDA_H
-#define LLVM_CLANG_SEMA_LAMBDA_H
-#include "clang/AST/ASTLambda.h"
-#include "clang/Sema/ScopeInfo.h"
-namespace clang {
-
-// Given a lambda's call operator and a variable (or null for 'this'),
-// compute the nearest enclosing lambda that is capture-ready (i.e
-// the enclosing context is not dependent, and all intervening lambdas can
-// either implicitly or explicitly capture Var)
-//
-// Return the CallOperator of the capturable lambda and set function scope
-// index to the correct index within the function scope stack to correspond
-// to the capturable lambda.
-// If VarDecl *VD is null, we check for 'this' capture.
-CXXMethodDecl*
-GetInnermostEnclosingCapturableLambda(
- ArrayRef<sema::FunctionScopeInfo*> FunctionScopes,
- unsigned &FunctionScopeIndex,
- DeclContext *const CurContext, VarDecl *VD, Sema &S);
-
-} // clang
-
-#endif // LLVM_CLANG_SEMA_LAMBDA_H
+//===--- SemaLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file provides some common utility functions for processing
+/// Lambdas.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_LAMBDA_H
+#define LLVM_CLANG_SEMA_LAMBDA_H
+#include "clang/AST/ASTLambda.h"
+#include "clang/Sema/ScopeInfo.h"
+namespace clang {
+
+
+/// \brief Examines the FunctionScopeInfo stack to determine the nearest
+/// enclosing lambda (to the current lambda) that is 'capture-capable' for
+/// the variable referenced in the current lambda (i.e. \p VarToCapture).
+/// If successful, returns the index into Sema's FunctionScopeInfo stack
+/// of the capture-capable lambda's LambdaScopeInfo.
+/// See Implementation for more detailed comments.
+
+Optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda(
+ ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes,
+ VarDecl *VarToCapture, Sema &S);
+
+} // clang
+
+#endif // LLVM_CLANG_SEMA_LAMBDA_H
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index f0b7726..16d7328 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -294,7 +294,7 @@
template <class C>
class DeclFilterCCC : public CorrectionCandidateCallback {
public:
- virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+ bool ValidateCandidate(const TypoCorrection &candidate) override {
return candidate.getCorrectionDeclAs<C>();
}
};
@@ -305,13 +305,16 @@
class FunctionCallFilterCCC : public CorrectionCandidateCallback {
public:
FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
- bool HasExplicitTemplateArgs);
+ bool HasExplicitTemplateArgs,
+ bool AllowNonStaticMethods = true);
- virtual bool ValidateCandidate(const TypoCorrection &candidate);
+ bool ValidateCandidate(const TypoCorrection &candidate) override;
private:
unsigned NumArgs;
bool HasExplicitTemplateArgs;
+ bool AllowNonStaticMethods;
+ DeclContext *CurContext;
};
// @brief Callback class that effectively disabled typo correction
@@ -324,7 +327,7 @@
WantRemainingKeywords = false;
}
- virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+ bool ValidateCandidate(const TypoCorrection &candidate) override {
return false;
}
};
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 03d9050..35765b6 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -213,9 +213,6 @@
/// types and decls used within the AST file.
DECLTYPES_BLOCK_ID,
- /// \brief The block containing DECL_UPDATES records.
- DECL_UPDATES_BLOCK_ID,
-
/// \brief The block containing the detailed preprocessing record.
PREPROCESSOR_DETAIL_BLOCK_ID,
@@ -349,15 +346,15 @@
/// IDs).
IDENTIFIER_TABLE = 5,
- /// \brief Record code for the array of external definitions.
+ /// \brief Record code for the array of eagerly deserialized decls.
///
- /// The AST file contains a list of all of the unnamed external
- /// definitions present within the parsed headers, stored as an
- /// array of declaration IDs. These external definitions will be
+ /// The AST file contains a list of all of the declarations that should be
+ /// eagerly deserialized present within the parsed headers, stored as an
+ /// array of declaration IDs. These declarations will be
/// reported to the AST consumer after the AST file has been
/// read, since their presence can affect the semantics of the
/// program (e.g., for code generation).
- EXTERNAL_DEFINITIONS = 6,
+ EAGERLY_DESERIALIZED_DECLS = 6,
/// \brief Record code for the set of non-builtin, special
/// types.
@@ -841,7 +838,9 @@
/// \brief An AtomicType record.
TYPE_ATOMIC = 40,
/// \brief A DecayedType record.
- TYPE_DECAYED = 41
+ TYPE_DECAYED = 41,
+ /// \brief An AdjustedType record.
+ TYPE_ADJUSTED = 42
};
/// \brief The type IDs for special types constructed by semantic
@@ -1300,13 +1299,11 @@
EXPR_CXX_UNRESOLVED_MEMBER, // UnresolvedMemberExpr
EXPR_CXX_UNRESOLVED_LOOKUP, // UnresolvedLookupExpr
- EXPR_CXX_UNARY_TYPE_TRAIT, // UnaryTypeTraitExpr
EXPR_CXX_EXPRESSION_TRAIT, // ExpressionTraitExpr
EXPR_CXX_NOEXCEPT, // CXXNoexceptExpr
EXPR_OPAQUE_VALUE, // OpaqueValueExpr
EXPR_BINARY_CONDITIONAL_OPERATOR, // BinaryConditionalOperator
- EXPR_BINARY_TYPE_TRAIT, // BinaryTypeTraitExpr
EXPR_TYPE_TRAIT, // TypeTraitExpr
EXPR_ARRAY_TYPE_TRAIT, // ArrayTypeTraitIntExpr
@@ -1333,6 +1330,7 @@
// OpenMP drectives
STMT_OMP_PARALLEL_DIRECTIVE,
+ STMT_OMP_SIMD_DIRECTIVE,
// ARC
EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index d3cca1a..b0fde2b 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -36,7 +36,6 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -45,10 +44,11 @@
#include "llvm/Support/DataTypes.h"
#include <deque>
#include <map>
+#include <memory>
#include <string>
+#include <sys/stat.h>
#include <utility>
#include <vector>
-#include <sys/stat.h>
namespace llvm {
class MemoryBuffer;
@@ -64,6 +64,7 @@
class Attr;
class Decl;
class DeclContext;
+class DefMacroDirective;
class DiagnosticOptions;
class NestedNameSpecifier;
class CXXBaseSpecifier;
@@ -170,15 +171,58 @@
virtual void ReadCounter(const serialization::ModuleFile &M,
unsigned Value) {}
+ /// This is called for each AST file loaded.
+ virtual void visitModuleFile(StringRef Filename) {}
+
/// \brief Returns true if this \c ASTReaderListener wants to receive the
/// input files of the AST file via \c visitInputFile, false otherwise.
virtual bool needsInputFileVisitation() { return false; }
-
- /// \brief if \c needsInputFileVisitation returns true, this is called for each
- /// input file of the AST file.
+ /// \brief Returns true if this \c ASTReaderListener wants to receive the
+ /// system input files of the AST file via \c visitInputFile, false otherwise.
+ virtual bool needsSystemInputFileVisitation() { return false; }
+ /// \brief if \c needsInputFileVisitation returns true, this is called for
+ /// each non-system input file of the AST File. If
+ /// \c needsSystemInputFileVisitation is true, then it is called for all
+ /// system input files as well.
///
/// \returns true to continue receiving the next input file, false to stop.
- virtual bool visitInputFile(StringRef Filename, bool isSystem) { return true;}
+ virtual bool visitInputFile(StringRef Filename, bool isSystem,
+ bool isOverridden) {
+ return true;
+ }
+};
+
+/// \brief Simple wrapper class for chaining listeners.
+class ChainedASTReaderListener : public ASTReaderListener {
+ std::unique_ptr<ASTReaderListener> First;
+ std::unique_ptr<ASTReaderListener> Second;
+
+public:
+ /// Takes ownership of \p First and \p Second.
+ ChainedASTReaderListener(ASTReaderListener *First, ASTReaderListener *Second)
+ : First(First), Second(Second) { }
+
+ bool ReadFullVersionInformation(StringRef FullVersion) override;
+ bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain) override;
+ bool ReadTargetOptions(const TargetOptions &TargetOpts,
+ bool Complain) override;
+ bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts,
+ bool Complain) override;
+ bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
+ bool Complain) override;
+
+ bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ bool Complain) override;
+ bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+ bool Complain,
+ std::string &SuggestedPredefines) override;
+
+ void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
+ bool needsInputFileVisitation() override;
+ bool needsSystemInputFileVisitation() override;
+ void visitModuleFile(StringRef Filename) override;
+ bool visitInputFile(StringRef Filename, bool isSystem,
+ bool isOverridden) override;
};
/// \brief ASTReaderListener implementation to validate the information of
@@ -191,14 +235,13 @@
PCHValidator(Preprocessor &PP, ASTReader &Reader)
: PP(PP), Reader(Reader) {}
- virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
- bool Complain);
- virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
- bool Complain);
- virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
- bool Complain,
- std::string &SuggestedPredefines);
- virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value);
+ bool ReadLanguageOptions(const LangOptions &LangOpts,
+ bool Complain) override;
+ bool ReadTargetOptions(const TargetOptions &TargetOpts,
+ bool Complain) override;
+ bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
+ std::string &SuggestedPredefines) override;
+ void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
private:
void Error(const char *Msg);
@@ -285,7 +328,7 @@
private:
/// \brief The receiver of some callbacks invoked by ASTReader.
- OwningPtr<ASTReaderListener> Listener;
+ std::unique_ptr<ASTReaderListener> Listener;
/// \brief The receiver of deserialization events.
ASTDeserializationListener *DeserializationListener;
@@ -315,7 +358,7 @@
SourceLocation CurrentImportLoc;
/// \brief The global module index, if loaded.
- llvm::OwningPtr<GlobalModuleIndex> GlobalIndex;
+ std::unique_ptr<GlobalModuleIndex> GlobalIndex;
/// \brief A map of global bit offsets to the module that stores entities
/// at those bit offsets.
@@ -471,18 +514,22 @@
/// global submodule ID to produce a local ID.
GlobalSubmoduleMapType GlobalSubmoduleMap;
+ /// \brief Information on a macro definition or undefinition that is visible
+ /// at the end of a submodule.
+ struct ModuleMacroInfo;
+
/// \brief An entity that has been hidden.
class HiddenName {
public:
enum NameKind {
Declaration,
- MacroVisibility
+ Macro
} Kind;
private:
union {
Decl *D;
- MacroDirective *MD;
+ ModuleMacroInfo *MMI;
};
IdentifierInfo *Id;
@@ -490,8 +537,8 @@
public:
HiddenName(Decl *D) : Kind(Declaration), D(D), Id() { }
- HiddenName(IdentifierInfo *II, MacroDirective *MD)
- : Kind(MacroVisibility), MD(MD), Id(II) { }
+ HiddenName(IdentifierInfo *II, ModuleMacroInfo *MMI)
+ : Kind(Macro), MMI(MMI), Id(II) { }
NameKind getKind() const { return Kind; }
@@ -500,15 +547,21 @@
return D;
}
- std::pair<IdentifierInfo *, MacroDirective *> getMacro() const {
- assert(getKind() == MacroVisibility && "Hidden name is not a macro!");
- return std::make_pair(Id, MD);
+ std::pair<IdentifierInfo *, ModuleMacroInfo *> getMacro() const {
+ assert(getKind() == Macro && "Hidden name is not a macro!");
+ return std::make_pair(Id, MMI);
}
-};
+ };
+
+ typedef llvm::SmallDenseMap<IdentifierInfo*,
+ ModuleMacroInfo*> HiddenMacrosMap;
/// \brief A set of hidden declarations.
- typedef SmallVector<HiddenName, 2> HiddenNames;
-
+ struct HiddenNames {
+ SmallVector<Decl*, 2> HiddenDecls;
+ HiddenMacrosMap HiddenMacros;
+ };
+
typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
/// \brief A mapping from each of the hidden submodules to the deserialized
@@ -564,8 +617,8 @@
ModuleFile *M;
struct ModuleMacroDataTy {
- serialization::GlobalMacroID GMacID;
- unsigned ImportLoc;
+ uint32_t MacID;
+ serialization::SubmoduleID *Overrides;
};
struct PCHMacroDataTy {
uint64_t MacroDirectivesOffset;
@@ -577,10 +630,10 @@
};
PendingMacroInfo(ModuleFile *M,
- serialization::GlobalMacroID GMacID,
- SourceLocation ImportLoc) : M(M) {
- ModuleMacroData.GMacID = GMacID;
- ModuleMacroData.ImportLoc = ImportLoc.getRawEncoding();
+ uint32_t MacID,
+ serialization::SubmoduleID *Overrides) : M(M) {
+ ModuleMacroData.MacID = MacID;
+ ModuleMacroData.Overrides = Overrides;
}
PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) : M(M) {
@@ -610,10 +663,10 @@
/// \brief The IDs of all declarations that fulfill the criteria of
/// "interesting" decls.
///
- /// This contains the data loaded from all EXTERNAL_DEFINITIONS blocks in the
- /// chain. The referenced declarations are deserialized and passed to the
- /// consumer eagerly.
- SmallVector<uint64_t, 16> ExternalDefinitions;
+ /// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks
+ /// in the chain. The referenced declarations are deserialized and passed to
+ /// the consumer eagerly.
+ SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
/// \brief The IDs of all tentative definitions stored in the chain.
///
@@ -714,9 +767,17 @@
// \brief A list of late parsed template function data.
SmallVector<uint64_t, 1> LateParsedTemplates;
+ struct ImportedSubmodule {
+ serialization::SubmoduleID ID;
+ SourceLocation ImportLoc;
+
+ ImportedSubmodule(serialization::SubmoduleID ID, SourceLocation ImportLoc)
+ : ID(ID), ImportLoc(ImportLoc) {}
+ };
+
/// \brief A list of modules that were imported by precompiled headers or
/// any other non-module AST file.
- SmallVector<serialization::SubmoduleID, 2> ImportedModules;
+ SmallVector<ImportedSubmodule, 2> ImportedModules;
//@}
/// \brief The directory that the PCH we are reading is stored in.
@@ -733,6 +794,13 @@
/// \brief Whether to accept an AST file with compiler errors.
bool AllowASTWithCompilerErrors;
+ /// \brief Whether to accept an AST file that has a different configuration
+ /// from the current compiler instance.
+ bool AllowConfigurationMismatch;
+
+ /// \brief Whether validate system input files.
+ bool ValidateSystemInputs;
+
/// \brief Whether we are allowed to use the global module index.
bool UseGlobalIndex;
@@ -970,6 +1038,18 @@
/// \brief Reads a statement from the specified cursor.
Stmt *ReadStmtFromStream(ModuleFile &F);
+ struct InputFileInfo {
+ std::string Filename;
+ off_t StoredSize;
+ time_t StoredTime;
+ bool Overridden;
+ };
+
+ /// \brief Reads the stored information about an input file.
+ InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID);
+ /// \brief A convenience method to read the filename from an input file.
+ std::string getInputFileName(ModuleFile &F, unsigned ID);
+
/// \brief Retrieve the file entry and 'overridden' bit for an input
/// file in the given module file.
serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
@@ -1028,6 +1108,10 @@
};
QualType readTypeRecord(unsigned Index);
+ void readExceptionSpec(ModuleFile &ModuleFile,
+ SmallVectorImpl<QualType> &ExceptionStorage,
+ FunctionProtoType::ExtProtoInfo &EPI,
+ const RecordData &Record, unsigned &Index);
RecordLocation TypeCursorForIndex(unsigned Index);
void LoadedDecl(unsigned Index, Decl *D);
Decl *ReadDeclRecord(serialization::DeclID ID);
@@ -1174,11 +1258,20 @@
/// AST file the was created out of an AST with compiler errors,
/// otherwise it will reject it.
///
+ /// \param AllowConfigurationMismatch If true, the AST reader will not check
+ /// for configuration differences between the AST file and the invocation.
+ ///
+ /// \param ValidateSystemInputs If true, the AST reader will validate
+ /// system input files in addition to user input files. This is only
+ /// meaningful if \p DisableValidation is false.
+ ///
/// \param UseGlobalIndex If true, the AST reader will try to load and use
/// the global module index.
ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
bool DisableValidation = false,
bool AllowASTWithCompilerErrors = false,
+ bool AllowConfigurationMismatch = false,
+ bool ValidateSystemInputs = false,
bool UseGlobalIndex = true);
~ASTReader();
@@ -1237,24 +1330,33 @@
/// \param ImportLoc The location at which the import occurs.
///
/// \param Complain Whether to complain about conflicting module imports.
- void makeModuleVisible(Module *Mod,
+ void makeModuleVisible(Module *Mod,
Module::NameVisibilityKind NameVisibility,
SourceLocation ImportLoc,
bool Complain);
-
+
/// \brief Make the names within this set of hidden names visible.
void makeNamesVisible(const HiddenNames &Names, Module *Owner);
-
+
/// \brief Set the AST callbacks listener.
void setListener(ASTReaderListener *listener) {
Listener.reset(listener);
}
+ /// \brief Add an AST callbak listener.
+ ///
+ /// Takes ownership of \p L.
+ void addListener(ASTReaderListener *L) {
+ if (Listener)
+ L = new ChainedASTReaderListener(L, Listener.release());
+ Listener.reset(L);
+ }
+
/// \brief Set the AST deserialization listener.
void setDeserializationListener(ASTDeserializationListener *Listener);
/// \brief Determine whether this AST reader has a global index.
- bool hasGlobalIndex() const { return GlobalIndex.isValid(); }
+ bool hasGlobalIndex() const { return (bool)GlobalIndex; }
/// \brief Attempts to load the global index.
///
@@ -1325,20 +1427,20 @@
///
/// \returns null if an error occurred that prevented the preprocessed
/// entity from being loaded.
- virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index);
+ PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) override;
/// \brief Returns a pair of [Begin, End) indices of preallocated
/// preprocessed entities that \p Range encompasses.
- virtual std::pair<unsigned, unsigned>
- findPreprocessedEntitiesInRange(SourceRange Range);
+ std::pair<unsigned, unsigned>
+ findPreprocessedEntitiesInRange(SourceRange Range) override;
/// \brief Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
- virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
- FileID FID);
+ Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID) override;
/// \brief Read the header file information for the given file entry.
- virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE);
+ HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) override;
void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag);
@@ -1450,7 +1552,7 @@
/// \brief Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
Decl *GetDecl(serialization::DeclID ID);
- virtual Decl *GetExternalDecl(uint32_t ID);
+ Decl *GetExternalDecl(uint32_t ID) override;
/// \brief Reads a declaration with the given local ID in the given module.
Decl *GetLocalDecl(ModuleFile &F, uint32_t LocalID) {
@@ -1502,14 +1604,14 @@
uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record,
unsigned &Idx);
- virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
+ CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
/// \brief Resolve the offset of a statement into a statement.
///
/// This operation will read a new statement from the external
/// source each time it is called, and is meant to be used via a
/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
- virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
+ Stmt *GetExternalDeclStmt(uint64_t Offset) override;
/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
/// specified cursor. Read the abbreviations that are at the top of the block
@@ -1519,9 +1621,8 @@
/// \brief Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
- virtual bool
- FindExternalVisibleDeclsByName(const DeclContext *DC,
- DeclarationName Name);
+ bool FindExternalVisibleDeclsByName(const DeclContext *DC,
+ DeclarationName Name) override;
/// \brief Read all of the declarations lexically stored in a
/// declaration context.
@@ -1536,49 +1637,49 @@
///
/// \returns true if there was an error while reading the
/// declarations for this declaration context.
- virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
- bool (*isKindWeWant)(Decl::Kind),
- SmallVectorImpl<Decl*> &Decls);
+ ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+ bool (*isKindWeWant)(Decl::Kind),
+ SmallVectorImpl<Decl*> &Decls) override;
/// \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);
+ void FindFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
+ SmallVectorImpl<Decl *> &Decls) override;
/// \brief Notify ASTReader 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.
- virtual void StartedDeserializing() { ++NumCurrentElementsDeserializing; }
+ void StartedDeserializing() override { ++NumCurrentElementsDeserializing; }
/// \brief Notify ASTReader that we finished the deserialization of
/// a decl or type. Must be paired with StartedDeserializing.
- virtual void FinishedDeserializing();
+ void FinishedDeserializing() override;
/// \brief Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
///
/// This function will provide all of the external definitions to
/// the ASTConsumer.
- virtual void StartTranslationUnit(ASTConsumer *Consumer);
+ void StartTranslationUnit(ASTConsumer *Consumer) override;
/// \brief Print some statistics about AST usage.
- virtual void PrintStats();
+ void PrintStats() override;
/// \brief Dump information about the AST reader to standard error.
void dump();
/// Return the amount of memory used by memory buffers, breaking down
/// by heap-backed versus mmap'ed memory.
- virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
+ void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
/// \brief Initialize the semantic source with the Sema instance
/// being used to perform semantic analysis on the abstract syntax
/// tree.
- virtual void InitializeSema(Sema &S);
+ void InitializeSema(Sema &S) override;
/// \brief Inform the semantic consumer that Sema is no longer available.
- virtual void ForgetSema() { SemaObj = 0; }
+ void ForgetSema() override { SemaObj = 0; }
/// \brief Retrieve the IdentifierInfo for the named identifier.
///
@@ -1587,56 +1688,57 @@
/// declarations will be deserialized and introduced into the declaration
/// chain of the identifier.
virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd);
- IdentifierInfo *get(StringRef Name) {
+ IdentifierInfo *get(StringRef Name) override {
return get(Name.begin(), Name.end());
}
/// \brief Retrieve an iterator into the set of all identifiers
/// in all loaded AST files.
- virtual IdentifierIterator *getIdentifiers();
+ IdentifierIterator *getIdentifiers() override;
/// \brief Load the contents of the global method pool for a given
/// selector.
- virtual void ReadMethodPool(Selector Sel);
+ void ReadMethodPool(Selector Sel) override;
/// \brief Load the set of namespaces that are known to the external source,
/// which will be used during typo correction.
- virtual void ReadKnownNamespaces(
- SmallVectorImpl<NamespaceDecl *> &Namespaces);
+ void ReadKnownNamespaces(
+ SmallVectorImpl<NamespaceDecl *> &Namespaces) override;
- virtual void ReadUndefinedButUsed(
- llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined);
+ void ReadUndefinedButUsed(
+ llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) override;
- virtual void ReadTentativeDefinitions(
- SmallVectorImpl<VarDecl *> &TentativeDefs);
+ void ReadTentativeDefinitions(
+ SmallVectorImpl<VarDecl *> &TentativeDefs) override;
- virtual void ReadUnusedFileScopedDecls(
- SmallVectorImpl<const DeclaratorDecl *> &Decls);
+ void ReadUnusedFileScopedDecls(
+ SmallVectorImpl<const DeclaratorDecl *> &Decls) override;
- virtual void ReadDelegatingConstructors(
- SmallVectorImpl<CXXConstructorDecl *> &Decls);
+ void ReadDelegatingConstructors(
+ SmallVectorImpl<CXXConstructorDecl *> &Decls) override;
- virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls);
+ void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) override;
- virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls);
+ void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) override;
- virtual void ReadLocallyScopedExternCDecls(
- SmallVectorImpl<NamedDecl *> &Decls);
+ void ReadLocallyScopedExternCDecls(
+ SmallVectorImpl<NamedDecl *> &Decls) override;
- virtual void ReadReferencedSelectors(
- SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels);
+ void ReadReferencedSelectors(
+ SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) override;
- virtual void ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI);
+ void ReadWeakUndeclaredIdentifiers(
+ SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) override;
- virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables);
+ void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
- virtual void ReadPendingInstantiations(
+ void ReadPendingInstantiations(
SmallVectorImpl<std::pair<ValueDecl *,
- SourceLocation> > &Pending);
+ SourceLocation> > &Pending) override;
- virtual void ReadLateParsedTemplates(
- llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap);
+ void ReadLateParsedTemplates(
+ llvm::DenseMap<const FunctionDecl *,
+ LateParsedTemplate *> &LPTMap) override;
/// \brief Load a selector from disk, registering its ID if it exists.
void LoadSelector(Selector Sel);
@@ -1659,7 +1761,7 @@
return DecodeIdentifierInfo(getGlobalIdentifierID(M, Record[Idx++]));
}
- virtual IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) {
+ IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) override {
// Note that we are loading an identifier.
Deserializing AnIdentifier(this);
@@ -1671,14 +1773,27 @@
serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
unsigned LocalID);
+ ModuleMacroInfo *getModuleMacro(const PendingMacroInfo &PMInfo);
+
void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
void installPCHMacroDirectives(IdentifierInfo *II,
ModuleFile &M, uint64_t Offset);
- void installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
+ void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
Module *Owner);
+ typedef llvm::SmallVector<DefMacroDirective*, 1> AmbiguousMacros;
+ llvm::DenseMap<IdentifierInfo*, AmbiguousMacros> AmbiguousMacroDefs;
+
+ void
+ removeOverriddenMacros(IdentifierInfo *II, AmbiguousMacros &Ambig,
+ llvm::ArrayRef<serialization::SubmoduleID> Overrides);
+
+ AmbiguousMacros *
+ removeOverriddenMacros(IdentifierInfo *II,
+ llvm::ArrayRef<serialization::SubmoduleID> Overrides);
+
/// \brief Retrieve the macro with the given ID.
MacroInfo *getMacro(serialization::MacroID ID);
@@ -1687,11 +1802,11 @@
serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID);
/// \brief Read the source location entry with index ID.
- virtual bool ReadSLocEntry(int ID);
+ bool ReadSLocEntry(int ID) override;
/// \brief Retrieve the module import location and module name for the
/// given source manager entry ID.
- virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID);
+ std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) override;
/// \brief Retrieve the global submodule ID given a module and its local ID
/// number.
@@ -1705,7 +1820,7 @@
/// \brief Retrieve the module that corresponds to the given module ID.
///
/// Note: overrides method in ExternalASTSource
- virtual Module *getModule(unsigned ID);
+ Module *getModule(unsigned ID) override;
/// \brief Retrieve a selector from the given module with its local ID
/// number.
@@ -1713,8 +1828,8 @@
Selector DecodeSelector(serialization::SelectorID Idx);
- virtual Selector GetExternalSelector(serialization::SelectorID ID);
- uint32_t GetNumExternalSelectors();
+ Selector GetExternalSelector(serialization::SelectorID ID) override;
+ uint32_t GetNumExternalSelectors() override;
Selector ReadSelector(ModuleFile &M, const RecordData &Record, unsigned &Idx) {
return getLocalSelector(M, Record[Idx++]);
@@ -1832,7 +1947,7 @@
"Should be called only during statement reading!");
// Subexpressions are stored from last to first, so the next Stmt we need
// is at the back of the stack.
- assert(!StmtStack.empty() && "Read too many sub statements!");
+ assert(!StmtStack.empty() && "Read too many sub-statements!");
return StmtStack.pop_back_val();
}
@@ -1855,11 +1970,10 @@
/// \param II The name of the macro.
/// \param M The module file.
/// \param GMacID The global macro ID that is associated with this identifier.
- /// \param ImportLoc The location where the module is imported.
void addPendingMacroFromModule(IdentifierInfo *II,
ModuleFile *M,
serialization::GlobalMacroID GMacID,
- SourceLocation ImportLoc);
+ llvm::ArrayRef<serialization::SubmoduleID>);
/// \brief Add a macro to deserialize its macro directive history from a PCH.
///
@@ -1871,16 +1985,16 @@
ModuleFile *M, uint64_t MacroDirectivesOffset);
/// \brief Read the set of macros defined by this external macro source.
- virtual void ReadDefinedMacros();
+ void ReadDefinedMacros() override;
/// \brief Update an out-of-date identifier.
- virtual void updateOutOfDateIdentifier(IdentifierInfo &II);
+ void updateOutOfDateIdentifier(IdentifierInfo &II) override;
/// \brief Note that this identifier is up-to-date.
void markIdentifierUpToDate(IdentifierInfo *II);
/// \brief Load all external visible decls in the given DeclContext.
- void completeVisibleDeclsMap(const DeclContext *DC);
+ void completeVisibleDeclsMap(const DeclContext *DC) override;
/// \brief Retrieve the AST context that this AST reader supplements.
ASTContext &getContext() { return Context; }
@@ -1911,8 +2025,8 @@
SmallVector<std::pair<llvm::BitstreamCursor,
serialization::ModuleFile *>, 8> CommentsCursors;
- /// \brief Loads comments ranges.
- void ReadComments();
+ //RIDErief Loads comments ranges.
+ void ReadComments() override;
};
/// \brief Helper class that saves the current stream position and
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 07fdd06..4d93c1e 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -246,10 +246,10 @@
/// @name FlushStmt Caches
/// @{
- /// \brief Set of parent Stmts for the currently serializing sub stmt.
+ /// \brief Set of parent Stmts for the currently serializing sub-stmt.
llvm::DenseSet<Stmt *> ParentStmts;
- /// \brief Offsets of sub stmts already serialized. The offset points
+ /// \brief Offsets of sub-stmts already serialized. The offset points
/// just after the stmt record.
llvm::DenseMap<Stmt *, uint64_t> SubStmtEntries;
@@ -283,7 +283,37 @@
llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID>
MacroDefinitions;
- typedef SmallVector<uint64_t, 2> UpdateRecord;
+ /// An update to a Decl.
+ class DeclUpdate {
+ /// A DeclUpdateKind.
+ unsigned Kind;
+ union {
+ const Decl *Dcl;
+ void *Type;
+ unsigned Loc;
+ unsigned Val;
+ };
+
+ public:
+ DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(0) {}
+ DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {}
+ DeclUpdate(unsigned Kind, QualType Type)
+ : Kind(Kind), Type(Type.getAsOpaquePtr()) {}
+ DeclUpdate(unsigned Kind, SourceLocation Loc)
+ : Kind(Kind), Loc(Loc.getRawEncoding()) {}
+ DeclUpdate(unsigned Kind, unsigned Val)
+ : Kind(Kind), Val(Val) {}
+
+ unsigned getKind() const { return Kind; }
+ const Decl *getDecl() const { return Dcl; }
+ QualType getType() const { return QualType::getFromOpaquePtr(Type); }
+ SourceLocation getLoc() const {
+ return SourceLocation::getFromRawEncoding(Loc);
+ }
+ unsigned getNumber() const { return Val; }
+ };
+
+ typedef SmallVector<DeclUpdate, 1> UpdateRecord;
typedef llvm::DenseMap<const Decl *, UpdateRecord> DeclUpdateMap;
/// \brief Mapping from declarations that came from a chained PCH to the
/// record containing modifications to them.
@@ -297,16 +327,15 @@
/// \brief Declarations encountered that might be external
/// definitions.
///
- /// We keep track of external definitions (as well as tentative
- /// definitions) as we are emitting declarations to the AST
- /// file. The AST file contains a separate record for these external
- /// definitions, which are provided to the AST consumer by the AST
- /// reader. This is behavior is required to properly cope with,
+ /// We keep track of external definitions and other 'interesting' declarations
+ /// as we are emitting declarations to the AST file. The AST file contains a
+ /// separate record for these declarations, which are provided to the AST
+ /// consumer by the AST reader. This is behavior is required to properly cope with,
/// e.g., tentative variable definitions that occur within
/// headers. The declarations themselves are stored as declaration
- /// IDs, since they will be written out to an EXTERNAL_DEFINITIONS
+ /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
/// record.
- SmallVector<uint64_t, 16> ExternalDefinitions;
+ SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
/// \brief DeclContexts that have received extensions since their serialized
/// form.
@@ -438,6 +467,8 @@
bool isModule);
void WriteCXXBaseSpecifiersOffsets();
void WriteType(QualType T);
+ uint32_t GenerateNameLookupTable(const DeclContext *DC,
+ llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
void WriteTypeDeclOffsets();
@@ -448,8 +479,7 @@
void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
bool IsModule);
void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
- void ResolveDeclUpdatesBlocks();
- void WriteDeclUpdatesBlocks();
+ void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
void WriteDeclReplacementsBlock();
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
void WriteFPPragmaOptions(const FPOptions &Opts);
@@ -475,6 +505,7 @@
void WriteDeclsBlockAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
+ void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
void WriteASTCore(Sema &SemaRef,
StringRef isysroot, const std::string &OutputFile,
@@ -715,35 +746,36 @@
bool hasChain() const { return Chain; }
// ASTDeserializationListener implementation
- void ReaderInitialized(ASTReader *Reader);
- void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II);
- void MacroRead(serialization::MacroID ID, MacroInfo *MI);
- void TypeRead(serialization::TypeIdx Idx, QualType T);
- void SelectorRead(serialization::SelectorID ID, Selector Sel);
+ void ReaderInitialized(ASTReader *Reader) override;
+ void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override;
+ void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
+ void TypeRead(serialization::TypeIdx Idx, QualType T) override;
+ void SelectorRead(serialization::SelectorID ID, Selector Sel) override;
void MacroDefinitionRead(serialization::PreprocessedEntityID ID,
- MacroDefinition *MD);
- void ModuleRead(serialization::SubmoduleID ID, Module *Mod);
+ MacroDefinition *MD) override;
+ void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
// ASTMutationListener implementation.
- virtual void CompletedTagDefinition(const TagDecl *D);
- virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
- virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D);
- virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
- const ClassTemplateSpecializationDecl *D);
- virtual void
- AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
- const VarTemplateSpecializationDecl *D);
- virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
- const FunctionDecl *D);
- virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
- virtual void CompletedImplicitDefinition(const FunctionDecl *D);
- virtual void StaticDataMemberInstantiated(const VarDecl *D);
- virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
- const ObjCInterfaceDecl *IFD);
- virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
- const ObjCPropertyDecl *OrigProp,
- const ObjCCategoryDecl *ClassExt);
- void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE;
+ void CompletedTagDefinition(const TagDecl *D) override;
+ void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
+ void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
+ void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
+ const ClassTemplateSpecializationDecl *D) override;
+ void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
+ const VarTemplateSpecializationDecl *D) override;
+ void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
+ const FunctionDecl *D) override;
+ void ResolvedExceptionSpec(const FunctionDecl *FD) override;
+ void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
+ void CompletedImplicitDefinition(const FunctionDecl *D) override;
+ void StaticDataMemberInstantiated(const VarDecl *D) override;
+ void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
+ void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
+ const ObjCInterfaceDecl *IFD) override;
+ void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+ const ObjCPropertyDecl *OrigProp,
+ const ObjCCategoryDecl *ClassExt) override;
+ void DeclarationMarkedUsed(const Decl *D) override;
};
/// \brief AST and semantic-analysis consumer that generates a
@@ -771,10 +803,10 @@
StringRef isysroot, raw_ostream *Out,
bool AllowASTWithErrors = false);
~PCHGenerator();
- virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
- virtual void HandleTranslationUnit(ASTContext &Ctx);
- virtual ASTMutationListener *GetASTMutationListener();
- virtual ASTDeserializationListener *GetASTDeserializationListener();
+ void InitializeSema(Sema &S) override { SemaPtr = &S; }
+ void HandleTranslationUnit(ASTContext &Ctx) override;
+ ASTMutationListener *GetASTMutationListener() override;
+ ASTDeserializationListener *GetASTDeserializationListener() override;
bool hasEmittedPCH() const { return HasEmittedPCH; }
};
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index 76414ba..0d9835a 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -17,11 +17,11 @@
#define LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include <memory>
#include <utility>
namespace llvm {
@@ -59,7 +59,7 @@
class GlobalModuleIndex {
/// \brief Buffer containing the index file, which is lazily accessed so long
/// as the global module index is live.
- llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
/// \brief The hash table.
///
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 89c604f..469785d 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -18,9 +18,9 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ContinuousRangeMap.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Bitcode/BitstreamReader.h"
+#include <memory>
#include <string>
namespace clang {
@@ -57,11 +57,12 @@
/// \brief The input file that has been loaded from this AST file, along with
/// bools indicating whether this was an overridden buffer or if it was
-/// out-of-date.
+/// out-of-date or not-found.
class InputFile {
enum {
Overridden = 1,
- OutOfDate = 2
+ OutOfDate = 2,
+ NotFound = 3
};
llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val;
@@ -79,9 +80,16 @@
Val.setPointerAndInt(File, intVal);
}
+ static InputFile getNotFound() {
+ InputFile File;
+ File.Val.setInt(NotFound);
+ return File;
+ }
+
const FileEntry *getFile() const { return Val.getPointer(); }
bool isOverridden() const { return Val.getInt() == Overridden; }
bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
+ bool isNotFound() const { return Val.getInt() == NotFound; }
};
/// \brief Information about a module that has been loaded by the ASTReader.
@@ -107,6 +115,10 @@
/// \brief The file name of the module file.
std::string FileName;
+ std::string getTimestampFilename() const {
+ return FileName + ".timestamp";
+ }
+
/// \brief The original source file name that was used to build the
/// primary AST file, which may have been modified for
/// relocatable-pch support.
@@ -139,7 +151,7 @@
/// \brief The memory buffer that stores the data associated with
/// this AST file.
- OwningPtr<llvm::MemoryBuffer> Buffer;
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
/// \brief The size of this file, in bits.
uint64_t SizeInBits;
@@ -159,6 +171,9 @@
/// If module A depends on and imports module B, both modules will have the
/// same DirectImportLoc, but different ImportLoc (B's ImportLoc will be a
/// source location inside module A).
+ ///
+ /// WARNING: This is largely useless. It doesn't tell you when a module was
+ /// made visible, just when the first submodule of that module was imported.
SourceLocation DirectImportLoc;
/// \brief The source location where this module was first imported.
@@ -177,6 +192,12 @@
/// \brief The input files that have been loaded from this AST file.
std::vector<InputFile> InputFilesLoaded;
+ /// \brief If non-zero, specifies the time when we last validated input
+ /// files. Zero means we never validated them.
+ ///
+ /// The time is specified in seconds since the start of the Epoch.
+ uint64_t InputFilesValidationTimestamp;
+
// === Source Locations ===
/// \brief Cursor used to read source location entries.
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
index 5978299..507c267 100644
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
@@ -114,8 +114,6 @@
/// Indicates that the object is not owned and controlled by the
/// Garbage collector.
GCNotOwnedSymbol,
- /// Indicates that the object is not owned and controlled by ARC.
- ARCNotOwnedSymbol,
/// Indicates that the return value is an owned object when the
/// receiver is also a tracked object.
OwnedWhenTrackedReceiver,
@@ -154,7 +152,7 @@
}
bool notOwned() const {
- return K == NotOwnedSymbol || K == ARCNotOwnedSymbol;
+ return K == NotOwnedSymbol;
}
bool operator==(const RetEffect &Other) const {
@@ -174,9 +172,6 @@
static RetEffect MakeGCNotOwned() {
return RetEffect(GCNotOwnedSymbol, ObjC);
}
- static RetEffect MakeARCNotOwned() {
- return RetEffect(ARCNotOwnedSymbol, ObjC);
- }
static RetEffect MakeNoRet() {
return RetEffect(NoRet);
}
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 618782e..42b6ca5 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -54,6 +54,7 @@
enum AnalysisDiagClients {
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
#include "clang/StaticAnalyzer/Core/Analyses.def"
+PD_NONE,
NUM_ANALYSIS_DIAG_CLIENTS
};
@@ -198,6 +199,9 @@
/// \sa mayInlineTemplateFunctions
Optional<bool> InlineTemplateFunctions;
+ /// \sa mayInlineCXXAllocator
+ Optional<bool> InlineCXXAllocator;
+
/// \sa mayInlineCXXContainerCtorsAndDtors
Optional<bool> InlineCXXContainerCtorsAndDtors;
@@ -290,6 +294,12 @@
/// accepts the values "true" and "false".
bool mayInlineTemplateFunctions();
+ /// Returns whether or not allocator call may be considered for inlining.
+ ///
+ /// This is controlled by the 'c++-allocator-inlining' config option, which
+ /// accepts the values "true" and "false".
+ bool mayInlineCXXAllocator();
+
/// Returns whether or not constructors and destructors of C++ container
/// objects may be considered for inlining.
///
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 9584b8b..ccbc47f 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -19,6 +19,7 @@
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
@@ -463,7 +464,12 @@
/// reports.
void emitReport(BugReport *R);
- void EmitBasicReport(const Decl *DeclWithIssue,
+ void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker,
+ StringRef BugName, StringRef BugCategory,
+ StringRef BugStr, PathDiagnosticLocation Loc,
+ ArrayRef<SourceRange> Ranges = None);
+
+ void EmitBasicReport(const Decl *DeclWithIssue, CheckName CheckName,
StringRef BugName, StringRef BugCategory,
StringRef BugStr, PathDiagnosticLocation Loc,
ArrayRef<SourceRange> Ranges = None);
@@ -473,7 +479,8 @@
/// \brief Returns a BugType that is associated with the given name and
/// category.
- BugType *getBugTypeForName(StringRef name, StringRef category);
+ BugType *getBugTypeForName(CheckName CheckName, StringRef name,
+ StringRef category);
};
// FIXME: Get rid of GRBugReporter. It's the wrong abstraction.
@@ -505,9 +512,8 @@
///
/// \return True if the report was valid and a path was generated,
/// false if the reports should be considered invalid.
- virtual bool generatePathDiagnostic(PathDiagnostic &PD,
- PathDiagnosticConsumer &PC,
- ArrayRef<BugReport*> &bugReports);
+ bool generatePathDiagnostic(PathDiagnostic &PD, PathDiagnosticConsumer &PC,
+ ArrayRef<BugReport*> &bugReports) override;
/// classof - Used by isa<>, cast<>, and dyn_cast<>.
static bool classof(const BugReporter* R) {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index 2e67180..302e0f8 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -89,7 +89,7 @@
/// will have to provide your own implementation.)
template <class DERIVED>
class BugReporterVisitorImpl : public BugReporterVisitor {
- virtual BugReporterVisitor *clone() const {
+ BugReporterVisitor *clone() const override {
return new DERIVED(*static_cast<const DERIVED *>(this));
}
};
@@ -118,12 +118,12 @@
Satisfied(false),
EnableNullFPSuppression(InEnableNullFPSuppression) {}
- void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
BugReporterContext &BRC,
- BugReport &BR);
+ BugReport &BR) override;
};
class TrackConstraintBRVisitor
@@ -144,7 +144,7 @@
IsZeroCheck(!Assumption && Constraint.getAs<Loc>()),
IsTrackingTurnedOn(false) {}
- void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
/// Return the tag associated with this visitor. This tag will be used
/// to make all PathDiagnosticPieces created by this visitor.
@@ -153,7 +153,7 @@
PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
BugReporterContext &BRC,
- BugReport &BR);
+ BugReport &BR) override;
private:
/// Checks if the constraint is valid in the current state.
@@ -166,8 +166,8 @@
class NilReceiverBRVisitor
: public BugReporterVisitorImpl<NilReceiverBRVisitor> {
public:
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override {
static int x = 0;
ID.AddPointer(&x);
}
@@ -175,7 +175,7 @@
PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
BugReporterContext &BRC,
- BugReport &BR);
+ BugReport &BR) override;
/// If the statement is a message send expression with nil receiver, returns
/// the receiver expression. Returns NULL otherwise.
@@ -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 {
+ void Profile(llvm::FoldingSetNodeID &ID) const override{
static int x = 0;
ID.AddPointer(&x);
}
@@ -193,11 +193,11 @@
/// Return the tag associated with this visitor. This tag will be used
/// to make all PathDiagnosticPieces created by this visitor.
static const char *getTag();
-
- virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR);
+
+ PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+ const ExplodedNode *Prev,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
PathDiagnosticPiece *VisitNodeImpl(const ExplodedNode *N,
const ExplodedNode *Prev,
@@ -257,20 +257,20 @@
return static_cast<void *>(&Tag);
}
- void Profile(llvm::FoldingSetNodeID &ID) const {
+ void Profile(llvm::FoldingSetNodeID &ID) const override {
ID.AddPointer(getTag());
}
- virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR) {
+ PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+ const ExplodedNode *Prev,
+ BugReporterContext &BRC,
+ BugReport &BR) override {
return 0;
}
- virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
- const ExplodedNode *N,
- BugReport &BR);
+ PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
+ const ExplodedNode *N,
+ BugReport &BR) override;
};
/// \brief When a region containing undefined value or '0' value is passed
@@ -287,7 +287,7 @@
public:
UndefOrNullArgVisitor(const MemRegion *InR) : R(InR) {}
- virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+ void Profile(llvm::FoldingSetNodeID &ID) const override {
static int Tag = 0;
ID.AddPointer(&Tag);
ID.AddPointer(R);
@@ -296,7 +296,7 @@
PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
BugReporterContext &BRC,
- BugReport &BR);
+ BugReport &BR) override;
};
class SuppressInlineDefensiveChecksVisitor
@@ -319,7 +319,7 @@
public:
SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N);
- void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
/// Return the tag associated with this visitor. This tag will be used
/// to make all PathDiagnosticPieces created by this visitor.
@@ -328,7 +328,7 @@
PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
const ExplodedNode *Pred,
BugReporterContext &BRC,
- BugReport &BR);
+ BugReport &BR) override;
};
namespace bugreporter {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 49f9c83..24c7785 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -14,8 +14,9 @@
#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
#define LLVM_CLANG_ANALYSIS_BUGTYPE
-#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
#include "llvm/ADT/FoldingSet.h"
#include <string>
@@ -29,20 +30,25 @@
class BugType {
private:
+ const CheckName Check;
const std::string Name;
const std::string Category;
bool SuppressonSink;
virtual void anchor();
public:
- BugType(StringRef name, StringRef cat)
- : Name(name), Category(cat), SuppressonSink(false) {}
+ BugType(class CheckName check, StringRef name, StringRef cat)
+ : Check(check), Name(name), Category(cat), SuppressonSink(false) {}
+ BugType(const CheckerBase *checker, StringRef name, StringRef cat)
+ : Check(checker->getCheckName()), Name(name), Category(cat),
+ SuppressonSink(false) {}
virtual ~BugType() {}
// FIXME: Should these be made strings as well?
StringRef getName() const { return Name; }
StringRef getCategory() const { return Category; }
-
+ StringRef getCheckName() const { return Check.getName(); }
+
/// isSuppressOnSink - Returns true if bug reports associated with this bug
/// type should be suppressed if the end node of the report is post-dominated
/// by a sink node.
@@ -54,14 +60,18 @@
class BuiltinBug : public BugType {
const std::string desc;
- virtual void anchor();
+ void anchor() override;
public:
- BuiltinBug(const char *name, const char *description)
- : BugType(name, categories::LogicError), desc(description) {}
-
- BuiltinBug(const char *name)
- : BugType(name, categories::LogicError), desc(name) {}
-
+ BuiltinBug(class CheckName check, const char *name, const char *description)
+ : BugType(check, name, categories::LogicError), desc(description) {}
+
+ BuiltinBug(const CheckerBase *checker, const char *name,
+ const char *description)
+ : BugType(checker, name, categories::LogicError), desc(description) {}
+
+ BuiltinBug(const CheckerBase *checker, const char *name)
+ : BugType(checker, name, categories::LogicError), desc(name) {}
+
StringRef getDescription() const { return desc; }
};
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index b0670da..cc31593 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -21,13 +21,13 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include <deque>
-#include <list>
#include <iterator>
+#include <list>
#include <string>
#include <vector>
namespace clang {
-
+class ConditionalOperator;
class AnalysisDeclContext;
class BinaryOperator;
class CompoundStmt;
@@ -211,6 +211,9 @@
/// Assumes the statement has a valid location.
static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO,
const SourceManager &SM);
+ static PathDiagnosticLocation createConditionalColonLoc(
+ const ConditionalOperator *CO,
+ const SourceManager &SM);
/// For member expressions, return the location of the '.' or '->'.
/// Assumes the statement has a valid location.
@@ -420,7 +423,7 @@
return Result;
}
- LLVM_ATTRIBUTE_USED void dump() const;
+ void dump() const;
};
class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
@@ -437,10 +440,10 @@
if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
}
- PathDiagnosticLocation getLocation() const { return Pos; }
- virtual void flattenLocations() { Pos.flatten(); }
+ PathDiagnosticLocation getLocation() const override { return Pos; }
+ void flattenLocations() override { Pos.flatten(); }
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
static bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Event || P->getKind() == Macro;
@@ -476,7 +479,7 @@
/// \brief Search the call expression for the symbol Sym and dispatch the
/// 'getMessageForX()' methods to construct a specific message.
- virtual std::string getMessage(const ExplodedNode *N);
+ std::string getMessage(const ExplodedNode *N) override;
/// Produces the message of the following form:
/// 'Msg via Nth parameter'
@@ -496,7 +499,7 @@
/// supply a message that will be used to construct an extra hint on the
/// returns from all the calls on the stack from this event to the final
/// diagnostic.
- OwningPtr<StackHintGenerator> CallStackHint;
+ std::unique_ptr<StackHintGenerator> CallStackHint;
public:
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
@@ -520,10 +523,8 @@
bool isPrunable() const {
return IsPrunable.hasValue() ? IsPrunable.getValue() : false;
}
-
- bool hasCallStackHint() {
- return CallStackHint.isValid();
- }
+
+ bool hasCallStackHint() { return (bool)CallStackHint; }
/// Produce the hint for the given node. The node contains
/// information about the call for which the diagnostic can be generated.
@@ -533,7 +534,7 @@
return "";
}
- virtual void dump() const;
+ void dump() const override;
static inline bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Event;
@@ -579,7 +580,7 @@
CallStackMessage = st;
}
- virtual PathDiagnosticLocation getLocation() const {
+ PathDiagnosticLocation getLocation() const override {
return callEnter;
}
@@ -588,7 +589,7 @@
getCallEnterWithinCallerEvent() const;
IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallExitEvent() const;
- virtual void flattenLocations() {
+ void flattenLocations() override {
callEnter.flatten();
callReturn.flatten();
for (PathPieces::iterator I = path.begin(),
@@ -601,10 +602,10 @@
static PathDiagnosticCallPiece *construct(PathPieces &pieces,
const Decl *caller);
-
- virtual void dump() const;
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+ void dump() const override;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
static inline bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Call;
@@ -651,7 +652,7 @@
void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
- virtual PathDiagnosticLocation getLocation() const {
+ PathDiagnosticLocation getLocation() const override {
return getStartLocation();
}
@@ -659,7 +660,7 @@
iterator begin() { return LPairs.begin(); }
iterator end() { return LPairs.end(); }
- virtual void flattenLocations() {
+ void flattenLocations() override {
for (iterator I=begin(), E=end(); I!=E; ++I) I->flatten();
}
@@ -672,9 +673,9 @@
return P->getKind() == ControlFlow;
}
- virtual void dump() const;
+ void dump() const override;
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
};
class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
@@ -688,7 +689,7 @@
bool containsEvent() const;
- virtual void flattenLocations() {
+ void flattenLocations() override {
PathDiagnosticSpotPiece::flattenLocations();
for (PathPieces::iterator I = subPieces.begin(),
E = subPieces.end(); I != E; ++I) (*I)->flattenLocations();
@@ -698,15 +699,16 @@
return P->getKind() == Macro;
}
- virtual void dump() const;
+ void dump() const override;
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
};
/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
/// each which represent the pieces of the path.
class PathDiagnostic : public llvm::FoldingSetNode {
+ std::string CheckName;
const Decl *DeclWithIssue;
std::string BugType;
std::string VerboseDesc;
@@ -727,8 +729,8 @@
PathDiagnostic() LLVM_DELETED_FUNCTION;
public:
- PathDiagnostic(const Decl *DeclWithIssue, StringRef bugtype,
- StringRef verboseDesc, StringRef shortDesc,
+ PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue,
+ StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
StringRef category, PathDiagnosticLocation LocationToUnique,
const Decl *DeclToUnique);
@@ -785,6 +787,7 @@
StringRef getShortDescription() const {
return ShortDesc.empty() ? VerboseDesc : ShortDesc;
}
+ StringRef getCheckName() const { return CheckName; }
StringRef getBugType() const { return BugType; }
StringRef getCategory() const { return Category; }
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index cf7cf05..be1e9cf 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -453,14 +453,29 @@
} // end eval namespace
class CheckerBase : public ProgramPointTag {
+ CheckName Name;
+ friend class ::clang::ento::CheckerManager;
+
public:
- StringRef getTagDescription() const;
+ StringRef getTagDescription() const override;
+ CheckName getCheckName() const;
/// See CheckerManager::runCheckersForPrintState.
virtual void printState(raw_ostream &Out, ProgramStateRef State,
const char *NL, const char *Sep) const { }
};
-
+
+/// Dump checker name to stream.
+raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
+
+/// Tag that can use a checker name as a message provider
+/// (see SimpleProgramPointTag).
+class CheckerProgramPointTag : public SimpleProgramPointTag {
+public:
+ CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
+ CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
+};
+
template <typename CHECK1, typename CHECK2=check::_VoidCheck,
typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 8ad67c1..b364115 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -16,8 +16,8 @@
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include <vector>
@@ -29,11 +29,11 @@
namespace ento {
class CheckerBase;
+ class CheckerRegistry;
class ExprEngine;
class AnalysisManager;
class BugReporter;
class CheckerContext;
- class SimpleCall;
class ObjCMethodCall;
class SVal;
class ExplodedNode;
@@ -132,9 +132,26 @@
PSK_EscapeOther
};
+// This wrapper is used to ensure that only StringRefs originating from the
+// CheckerRegistry are used as check names. We want to make sure all check
+// name strings have a lifetime that keeps them alive at least until the path
+// diagnostics have been processed.
+class CheckName {
+ StringRef Name;
+ friend class ::clang::ento::CheckerRegistry;
+ explicit CheckName(StringRef Name) : Name(Name) {}
+
+public:
+ CheckName() {}
+ CheckName(const CheckName &Other) : Name(Other.Name) {}
+ StringRef getName() const { return Name; }
+};
+
class CheckerManager {
const LangOptions LangOpts;
AnalyzerOptionsRef AOptions;
+ CheckName CurrentCheckName;
+
public:
CheckerManager(const LangOptions &langOpts,
AnalyzerOptionsRef AOptions)
@@ -143,6 +160,9 @@
~CheckerManager();
+ void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
+ CheckName getCurrentCheckName() const { return CurrentCheckName; }
+
bool hasPathSensitiveCheckers() const;
void finishedCheckerRegistration();
@@ -169,6 +189,7 @@
return static_cast<CHECKER *>(ref); // already registered.
CHECKER *checker = new CHECKER();
+ checker->Name = CurrentCheckName;
CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
CHECKER::_register(checker, *this);
ref = checker;
@@ -183,6 +204,7 @@
return static_cast<CHECKER *>(ref); // already registered.
CHECKER *checker = new CHECKER(AOpts);
+ checker->Name = CurrentCheckName;
CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
CHECKER::_register(checker, *this);
ref = checker;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
index 9502900..37be69a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_SA_CORE_APSINTTYPE_H
#include "llvm/ADT/APSInt.h"
+#include <tuple>
namespace clang {
namespace ento {
@@ -97,13 +98,8 @@
/// Unsigned integers are considered to be better conversion types than
/// signed integers of the same width.
bool operator<(const APSIntType &Other) const {
- if (BitWidth < Other.BitWidth)
- return true;
- if (BitWidth > Other.BitWidth)
- return false;
- if (!IsUnsigned && Other.IsUnsigned)
- return true;
- return false;
+ return std::tie(BitWidth, IsUnsigned) <
+ std::tie(Other.BitWidth, Other.IsUnsigned);
}
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index d7d83ce..1a398b8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -65,8 +65,8 @@
StoreManagerCreator getStoreManagerCreator() {
return CreateStoreMgr;
}
-
- AnalyzerOptions& getAnalyzerOptions() {
+
+ AnalyzerOptions& getAnalyzerOptions() override {
return options;
}
@@ -76,15 +76,15 @@
CheckerManager *getCheckerManager() const { return CheckerMgr; }
- virtual ASTContext &getASTContext() {
+ ASTContext &getASTContext() override {
return Ctx;
}
- virtual SourceManager &getSourceManager() {
+ SourceManager &getSourceManager() override {
return getASTContext().getSourceManager();
}
- virtual DiagnosticsEngine &getDiagnostic() {
+ DiagnosticsEngine &getDiagnostic() override {
return Diags;
}
@@ -92,7 +92,7 @@
return LangOpts;
}
- ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() {
+ ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() override {
return PathConsumers;
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
index 2483a79..abb9519 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
@@ -16,9 +16,7 @@
#ifndef LLVM_CLANG_GR_BLOCKCOUNTER
#define LLVM_CLANG_GR_BLOCKCOUNTER
-namespace llvm {
- class BumpPtrAllocator;
-}
+#include "llvm/Support/Allocator.h"
namespace clang {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index cfaf085..d347be0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -33,9 +33,6 @@
enum CallEventKind {
CE_Function,
- CE_Block,
- CE_BEG_SIMPLE_CALLS = CE_Function,
- CE_END_SIMPLE_CALLS = CE_Block,
CE_CXXMember,
CE_CXXMemberOperator,
CE_CXXDestructor,
@@ -45,6 +42,7 @@
CE_CXXAllocator,
CE_BEG_FUNCTION_CALLS = CE_Function,
CE_END_FUNCTION_CALLS = CE_CXXAllocator,
+ CE_Block,
CE_ObjCMessage
};
@@ -344,23 +342,16 @@
// Iterator access to formal parameters and their types.
private:
typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;
-
-public:
- typedef const ParmVarDecl * const *param_iterator;
- /// Returns an iterator over the call's formal parameters.
+public:
+ /// Return call's formal parameters.
///
/// Remember that the number of formal parameters may not match the number
/// of arguments for all calls. However, the first parameter will always
/// correspond with the argument value returned by \c getArgSVal(0).
- ///
- /// If the call has no accessible declaration, \c param_begin() will be equal
- /// to \c param_end().
- virtual param_iterator param_begin() const = 0;
- /// \sa param_begin()
- virtual param_iterator param_end() const = 0;
+ virtual ArrayRef<ParmVarDecl*> parameters() const = 0;
- typedef llvm::mapped_iterator<param_iterator, get_type_fun>
+ typedef llvm::mapped_iterator<ArrayRef<ParmVarDecl*>::iterator, get_type_fun>
param_type_iterator;
/// Returns an iterator over the types of the call's formal parameters.
@@ -369,17 +360,18 @@
/// definition because it represents a public interface, and probably has
/// more annotations.
param_type_iterator param_type_begin() const {
- return llvm::map_iterator(param_begin(),
+ return llvm::map_iterator(parameters().begin(),
get_type_fun(&ParmVarDecl::getType));
}
/// \sa param_type_begin()
param_type_iterator param_type_end() const {
- return llvm::map_iterator(param_end(), get_type_fun(&ParmVarDecl::getType));
+ return llvm::map_iterator(parameters().end(),
+ get_type_fun(&ParmVarDecl::getType));
}
// For debugging purposes only
void dump(raw_ostream &Out) const;
- LLVM_ATTRIBUTE_USED void dump() const;
+ void dump() const;
};
@@ -398,11 +390,11 @@
public:
// This function is overridden by subclasses, but they must return
// a FunctionDecl.
- virtual const FunctionDecl *getDecl() const {
+ const FunctionDecl *getDecl() const override {
return cast<FunctionDecl>(CallEvent::getDecl());
}
- virtual RuntimeDefinition getRuntimeDefinition() const {
+ RuntimeDefinition getRuntimeDefinition() const override {
const FunctionDecl *FD = getDecl();
// Note that the AnalysisDeclContext will have the FunctionDecl with
// the definition (if one exists).
@@ -417,13 +409,12 @@
return RuntimeDefinition();
}
- virtual bool argumentsMayEscape() const;
+ bool argumentsMayEscape() const override;
- virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const;
+ void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+ BindingsTy &Bindings) const override;
- virtual param_iterator param_begin() const;
- virtual param_iterator param_end() const;
+ ArrayRef<ParmVarDecl *> parameters() const override;
static bool classof(const CallEvent *CA) {
return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&
@@ -431,49 +422,36 @@
}
};
-/// \brief Represents a call to a non-C++ function, written as a CallExpr.
-class SimpleCall : public AnyFunctionCall {
+/// \brief Represents a C function or static C++ member function call.
+///
+/// Example: \c fun()
+class SimpleFunctionCall : public AnyFunctionCall {
+ friend class CallEventManager;
+
protected:
- SimpleCall(const CallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
+ SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
+ const LocationContext *LCtx)
: AnyFunctionCall(CE, St, LCtx) {}
- SimpleCall(const SimpleCall &Other) : AnyFunctionCall(Other) {}
+ SimpleFunctionCall(const SimpleFunctionCall &Other)
+ : AnyFunctionCall(Other) {}
+ void cloneTo(void *Dest) const override {
+ new (Dest) SimpleFunctionCall(*this);
+ }
public:
virtual const CallExpr *getOriginExpr() const {
return cast<CallExpr>(AnyFunctionCall::getOriginExpr());
}
- virtual const FunctionDecl *getDecl() const;
+ const FunctionDecl *getDecl() const override;
- virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
+ unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
- virtual const Expr *getArgExpr(unsigned Index) const {
+ const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index);
}
- static bool classof(const CallEvent *CA) {
- return CA->getKind() >= CE_BEG_SIMPLE_CALLS &&
- CA->getKind() <= CE_END_SIMPLE_CALLS;
- }
-};
-
-/// \brief Represents a C function or static C++ member function call.
-///
-/// Example: \c fun()
-class FunctionCall : public SimpleCall {
- friend class CallEventManager;
-
-protected:
- FunctionCall(const CallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : SimpleCall(CE, St, LCtx) {}
-
- FunctionCall(const FunctionCall &Other) : SimpleCall(Other) {}
- virtual void cloneTo(void *Dest) const { new (Dest) FunctionCall(*this); }
-
-public:
- virtual Kind getKind() const { return CE_Function; }
+ Kind getKind() const override { return CE_Function; }
static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_Function;
@@ -483,47 +461,56 @@
/// \brief Represents a call to a block.
///
/// Example: <tt>^{ /* ... */ }()</tt>
-class BlockCall : public SimpleCall {
+class BlockCall : public CallEvent {
friend class CallEventManager;
protected:
BlockCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : SimpleCall(CE, St, LCtx) {}
+ : CallEvent(CE, St, LCtx) {}
- BlockCall(const BlockCall &Other) : SimpleCall(Other) {}
- virtual void cloneTo(void *Dest) const { new (Dest) BlockCall(*this); }
+ BlockCall(const BlockCall &Other) : CallEvent(Other) {}
+ void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); }
- virtual void getExtraInvalidatedValues(ValueList &Values) const;
+ void getExtraInvalidatedValues(ValueList &Values) const override;
public:
+ virtual const CallExpr *getOriginExpr() const {
+ return cast<CallExpr>(CallEvent::getOriginExpr());
+ }
+
+ unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
+
+ const Expr *getArgExpr(unsigned Index) const override {
+ return getOriginExpr()->getArg(Index);
+ }
+
/// \brief Returns the region associated with this instance of the block.
///
/// This may be NULL if the block's origin is unknown.
const BlockDataRegion *getBlockRegion() const;
- /// \brief Gets the declaration of the block.
- ///
- /// This is not an override of getDecl() because AnyFunctionCall has already
- /// assumed that it's a FunctionDecl.
- const BlockDecl *getBlockDecl() const {
+ const BlockDecl *getDecl() const override {
const BlockDataRegion *BR = getBlockRegion();
if (!BR)
return 0;
return BR->getDecl();
}
- virtual RuntimeDefinition getRuntimeDefinition() const {
- return RuntimeDefinition(getBlockDecl());
+ RuntimeDefinition getRuntimeDefinition() const override {
+ return RuntimeDefinition(getDecl());
}
- virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const;
+ bool argumentsMayEscape() const override {
+ return true;
+ }
- virtual param_iterator param_begin() const;
- virtual param_iterator param_end() const;
+ void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+ BindingsTy &Bindings) const override;
- virtual Kind getKind() const { return CE_Block; }
+ ArrayRef<ParmVarDecl*> parameters() const override;
+
+ Kind getKind() const override { return CE_Block; }
static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_Block;
@@ -534,7 +521,7 @@
/// it is written.
class CXXInstanceCall : public AnyFunctionCall {
protected:
- virtual void getExtraInvalidatedValues(ValueList &Values) const;
+ void getExtraInvalidatedValues(ValueList &Values) const override;
CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
@@ -553,12 +540,12 @@
/// \brief Returns the value of the implicit 'this' object.
virtual SVal getCXXThisVal() const;
- virtual const FunctionDecl *getDecl() const;
+ const FunctionDecl *getDecl() const override;
- virtual RuntimeDefinition getRuntimeDefinition() const;
+ RuntimeDefinition getRuntimeDefinition() const override;
- virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const;
+ void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+ BindingsTy &Bindings) const override;
static bool classof(const CallEvent *CA) {
return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
@@ -578,28 +565,28 @@
: CXXInstanceCall(CE, St, LCtx) {}
CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
- virtual void cloneTo(void *Dest) const { new (Dest) CXXMemberCall(*this); }
+ void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); }
public:
virtual const CXXMemberCallExpr *getOriginExpr() const {
return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr());
}
- virtual unsigned getNumArgs() const {
+ unsigned getNumArgs() const override {
if (const CallExpr *CE = getOriginExpr())
return CE->getNumArgs();
return 0;
}
- virtual const Expr *getArgExpr(unsigned Index) const {
+ const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index);
}
- virtual const Expr *getCXXThisExpr() const;
-
- virtual RuntimeDefinition getRuntimeDefinition() const;
+ const Expr *getCXXThisExpr() const override;
- virtual Kind getKind() const { return CE_CXXMember; }
+ RuntimeDefinition getRuntimeDefinition() const override;
+
+ Kind getKind() const override { return CE_CXXMember; }
static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_CXXMember;
@@ -620,7 +607,7 @@
CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
: CXXInstanceCall(Other) {}
- virtual void cloneTo(void *Dest) const {
+ void cloneTo(void *Dest) const override {
new (Dest) CXXMemberOperatorCall(*this);
}
@@ -629,16 +616,16 @@
return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr());
}
- virtual unsigned getNumArgs() const {
+ unsigned getNumArgs() const override {
return getOriginExpr()->getNumArgs() - 1;
}
- virtual const Expr *getArgExpr(unsigned Index) const {
+ const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index + 1);
}
- virtual const Expr *getCXXThisExpr() const;
+ const Expr *getCXXThisExpr() const override;
- virtual Kind getKind() const { return CE_CXXMemberOperator; }
+ Kind getKind() const override { return CE_CXXMemberOperator; }
static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_CXXMemberOperator;
@@ -671,23 +658,23 @@
}
CXXDestructorCall(const CXXDestructorCall &Other) : CXXInstanceCall(Other) {}
- virtual void cloneTo(void *Dest) const { new (Dest) CXXDestructorCall(*this); }
+ void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);}
public:
- virtual SourceRange getSourceRange() const { return Location; }
- virtual unsigned getNumArgs() const { return 0; }
+ SourceRange getSourceRange() const override { return Location; }
+ unsigned getNumArgs() const override { return 0; }
- virtual RuntimeDefinition getRuntimeDefinition() const;
+ RuntimeDefinition getRuntimeDefinition() const override;
/// \brief Returns the value of the implicit 'this' object.
- virtual SVal getCXXThisVal() const;
+ SVal getCXXThisVal() const override;
/// Returns true if this is a call to a base class destructor.
bool isBaseDestructor() const {
return DtorDataTy::getFromOpaqueValue(Data).getInt();
}
- virtual Kind getKind() const { return CE_CXXDestructor; }
+ Kind getKind() const override { return CE_CXXDestructor; }
static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_CXXDestructor;
@@ -715,32 +702,32 @@
}
CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){}
- virtual void cloneTo(void *Dest) const { new (Dest) CXXConstructorCall(*this); }
+ void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); }
- virtual void getExtraInvalidatedValues(ValueList &Values) const;
+ void getExtraInvalidatedValues(ValueList &Values) const override;
public:
virtual const CXXConstructExpr *getOriginExpr() const {
return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());
}
- virtual const CXXConstructorDecl *getDecl() const {
+ const CXXConstructorDecl *getDecl() const override {
return getOriginExpr()->getConstructor();
}
- virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
+ unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
- virtual const Expr *getArgExpr(unsigned Index) const {
+ const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index);
}
/// \brief Returns the value of the implicit 'this' object.
SVal getCXXThisVal() const;
- virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const;
+ void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+ BindingsTy &Bindings) const override;
- virtual Kind getKind() const { return CE_CXXConstructor; }
+ Kind getKind() const override { return CE_CXXConstructor; }
static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_CXXConstructor;
@@ -759,29 +746,29 @@
: AnyFunctionCall(E, St, LCtx) {}
CXXAllocatorCall(const CXXAllocatorCall &Other) : AnyFunctionCall(Other) {}
- virtual void cloneTo(void *Dest) const { new (Dest) CXXAllocatorCall(*this); }
+ void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); }
public:
virtual const CXXNewExpr *getOriginExpr() const {
return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());
}
- virtual const FunctionDecl *getDecl() const {
+ const FunctionDecl *getDecl() const override {
return getOriginExpr()->getOperatorNew();
}
- virtual unsigned getNumArgs() const {
+ unsigned getNumArgs() const override {
return getOriginExpr()->getNumPlacementArgs() + 1;
}
- virtual const Expr *getArgExpr(unsigned Index) const {
+ 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 getOriginExpr()->getPlacementArg(Index - 1);
}
- virtual Kind getKind() const { return CE_CXXAllocator; }
+ Kind getKind() const override { return CE_CXXAllocator; }
static bool classof(const CallEvent *CE) {
return CE->getKind() == CE_CXXAllocator;
@@ -814,9 +801,9 @@
}
ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
- virtual void cloneTo(void *Dest) const { new (Dest) ObjCMethodCall(*this); }
+ void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); }
- virtual void getExtraInvalidatedValues(ValueList &Values) const;
+ void getExtraInvalidatedValues(ValueList &Values) const override;
/// Check if the selector may have multiple definitions (may have overrides).
virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
@@ -826,13 +813,13 @@
virtual const ObjCMessageExpr *getOriginExpr() const {
return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
}
- virtual const ObjCMethodDecl *getDecl() const {
+ const ObjCMethodDecl *getDecl() const override {
return getOriginExpr()->getMethodDecl();
}
- virtual unsigned getNumArgs() const {
+ unsigned getNumArgs() const override {
return getOriginExpr()->getNumArgs();
}
- virtual const Expr *getArgExpr(unsigned Index) const {
+ const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index);
}
@@ -846,7 +833,7 @@
return getOriginExpr()->getSelector();
}
- virtual SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const override;
/// \brief Returns the value of the receiver at the time of this call.
SVal getReceiverSVal() const;
@@ -883,15 +870,16 @@
llvm_unreachable("Unknown message kind");
}
- virtual RuntimeDefinition getRuntimeDefinition() const;
+ RuntimeDefinition getRuntimeDefinition() const override;
- virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
- BindingsTy &Bindings) const;
+ bool argumentsMayEscape() const override;
- virtual param_iterator param_begin() const;
- virtual param_iterator param_end() const;
+ void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+ BindingsTy &Bindings) const override;
- virtual Kind getKind() const { return CE_ObjCMessage; }
+ ArrayRef<ParmVarDecl*> parameters() const override;
+
+ Kind getKind() const override { return CE_ObjCMessage; }
static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_ObjCMessage;
@@ -911,6 +899,7 @@
llvm::BumpPtrAllocator &Alloc;
SmallVector<void *, 8> Cache;
+ typedef SimpleFunctionCall CallEventTemplateTy;
void reclaim(const void *Memory) {
Cache.push_back(const_cast<void *>(Memory));
@@ -919,24 +908,30 @@
/// Returns memory that can be initialized as a CallEvent.
void *allocate() {
if (Cache.empty())
- return Alloc.Allocate<FunctionCall>();
+ return Alloc.Allocate<CallEventTemplateTy>();
else
return Cache.pop_back_val();
}
template <typename T, typename Arg>
T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) {
+ static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+ "CallEvent subclasses are not all the same size");
return new (allocate()) T(A, St, LCtx);
}
template <typename T, typename Arg1, typename Arg2>
T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) {
+ static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+ "CallEvent subclasses are not all the same size");
return new (allocate()) T(A1, A2, St, LCtx);
}
template <typename T, typename Arg1, typename Arg2, typename Arg3>
T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St,
const LocationContext *LCtx) {
+ static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+ "CallEvent subclasses are not all the same size");
return new (allocate()) T(A1, A2, A3, St, LCtx);
}
@@ -944,6 +939,8 @@
typename Arg4>
T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St,
const LocationContext *LCtx) {
+ static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+ "CallEvent subclasses are not all the same size");
return new (allocate()) T(A1, A2, A3, A4, St, LCtx);
}
@@ -989,7 +986,8 @@
template <typename T>
CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {
assert(isa<T>(*this) && "Cloning to unrelated type");
- assert(sizeof(T) == sizeof(CallEvent) && "Subclasses may not add fields");
+ static_assert(sizeof(T) == sizeof(CallEvent),
+ "Subclasses may not add fields");
if (NewState == State)
return cast<T>(this);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index a2e211e..14a0417 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -21,7 +21,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
namespace clang {
@@ -60,12 +60,12 @@
SubEngine& SubEng;
/// G - The simulation graph. Each node is a (location,state) pair.
- OwningPtr<ExplodedGraph> G;
+ std::unique_ptr<ExplodedGraph> G;
/// WList - A set of queued nodes that need to be processed by the
/// worklist algorithm. It is up to the implementation of WList to decide
/// the order that nodes are processed.
- OwningPtr<WorkList> WList;
+ std::unique_ptr<WorkList> WList;
/// BCounterFactory - A factory object for created BlockCounter objects.
/// These are used to record for key nodes in the ExplodedGraph the
@@ -120,7 +120,7 @@
/// takeGraph - Returns the exploded graph. Ownership of the graph is
/// transferred to the caller.
- ExplodedGraph* takeGraph() { return G.take(); }
+ ExplodedGraph *takeGraph() { return G.release(); }
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of
/// steps. Returns true if there is still simulation state on the worklist.
@@ -312,7 +312,7 @@
/// \class NodeBuilderWithSinks
/// \brief This node builder keeps track of the generated sink nodes.
class NodeBuilderWithSinks: public NodeBuilder {
- virtual void anchor();
+ void anchor() override;
protected:
SmallVector<ExplodedNode*, 2> sinksGenerated;
ProgramPoint &Location;
@@ -399,7 +399,7 @@
/// \brief BranchNodeBuilder is responsible for constructing the nodes
/// corresponding to the two branches of the if statement - true and false.
class BranchNodeBuilder: public NodeBuilder {
- virtual void anchor();
+ void anchor() override;
const CFGBlock *DstT;
const CFGBlock *DstF;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index bf17cd8..706081e 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -27,11 +27,11 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
+#include <memory>
#include <vector>
namespace clang {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index d89dffe..2fbe565 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -43,7 +43,6 @@
class AnalysisManager;
class CallEvent;
-class SimpleCall;
class CXXConstructorCall;
class ExprEngine : public SubEngine {
@@ -123,7 +122,7 @@
/// getContext - Return the ASTContext associated with this analysis.
ASTContext &getContext() const { return AMgr.getASTContext(); }
- virtual AnalysisManager &getAnalysisManager() { return AMgr; }
+ AnalysisManager &getAnalysisManager() override { return AMgr; }
CheckerManager &getCheckerManager() const {
return *AMgr.getCheckerManager();
@@ -155,7 +154,7 @@
/// getInitialState - Return the initial state used for the root vertex
/// in the ExplodedGraph.
- ProgramStateRef getInitialState(const LocationContext *InitLoc);
+ ProgramStateRef getInitialState(const LocationContext *InitLoc) override;
ExplodedGraph& getGraph() { return G; }
const ExplodedGraph& getGraph() const { return G; }
@@ -193,7 +192,7 @@
/// processCFGElement - Called by CoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a CFG element.
void processCFGElement(const CFGElement E, ExplodedNode *Pred,
- unsigned StmtIdx, NodeBuilderContext *Ctx);
+ unsigned StmtIdx, NodeBuilderContext *Ctx) override;
void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
@@ -201,7 +200,9 @@
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
- void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
+ void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred);
+
+ void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
ExplodedNode *Pred, ExplodedNodeSet &Dst);
void ProcessDeleteDtor(const CFGDeleteDtor D,
ExplodedNode *Pred, ExplodedNodeSet &Dst);
@@ -213,10 +214,10 @@
ExplodedNode *Pred, ExplodedNodeSet &Dst);
/// Called by CoreEngine when processing the entrance of a CFGBlock.
- virtual void processCFGBlockEntrance(const BlockEdge &L,
- NodeBuilderWithSinks &nodeBuilder,
- ExplodedNode *Pred);
-
+ void processCFGBlockEntrance(const BlockEdge &L,
+ NodeBuilderWithSinks &nodeBuilder,
+ ExplodedNode *Pred) override;
+
/// ProcessBranch - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
void processBranch(const Stmt *Condition, const Stmt *Term,
@@ -224,7 +225,7 @@
ExplodedNode *Pred,
ExplodedNodeSet &Dst,
const CFGBlock *DstT,
- const CFGBlock *DstF);
+ const CFGBlock *DstF) override;
/// Called by CoreEngine. Used to processing branching behavior
/// at static initalizers.
@@ -233,20 +234,20 @@
ExplodedNode *Pred,
ExplodedNodeSet &Dst,
const CFGBlock *DstT,
- const CFGBlock *DstF);
+ const CFGBlock *DstF) override;
/// processIndirectGoto - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a computed goto jump.
- void processIndirectGoto(IndirectGotoNodeBuilder& builder);
+ void processIndirectGoto(IndirectGotoNodeBuilder& builder) override;
/// ProcessSwitch - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a switch statement.
- void processSwitch(SwitchNodeBuilder& builder);
+ void processSwitch(SwitchNodeBuilder& builder) override;
/// Called by CoreEngine. Used to generate end-of-path
/// nodes when the control reaches the end of a function.
void processEndOfFunction(NodeBuilderContext& BC,
- ExplodedNode *Pred);
+ ExplodedNode *Pred) override;
/// Remove dead bindings/symbols before exiting a function.
void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
@@ -254,22 +255,23 @@
ExplodedNodeSet &Dst);
/// Generate the entry node of the callee.
- void processCallEnter(CallEnter CE, ExplodedNode *Pred);
+ void processCallEnter(CallEnter CE, ExplodedNode *Pred) override;
/// Generate the sequence of nodes that simulate the call exit and the post
/// visit for CallExpr.
- void processCallExit(ExplodedNode *Pred);
+ void processCallExit(ExplodedNode *Pred) override;
/// Called by CoreEngine when the analysis worklist has terminated.
- void processEndWorklist(bool hasWorkRemaining);
+ void processEndWorklist(bool hasWorkRemaining) override;
/// evalAssume - Callback function invoked by the ConstraintManager when
/// making assumptions about state values.
- ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption);
+ ProgramStateRef processAssume(ProgramStateRef state, SVal cond,
+ bool assumption) override;
/// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
/// region change should trigger a processRegionChanges update.
- bool wantsRegionChangeUpdate(ProgramStateRef state);
+ bool wantsRegionChangeUpdate(ProgramStateRef state) override;
/// processRegionChanges - Called by ProgramStateManager whenever a change is made
/// to the store. Used to update checkers that track region values.
@@ -278,13 +280,13 @@
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call);
+ const CallEvent *Call) override;
/// printState - Called by ProgramStateManager to print checker-specific data.
void printState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep);
+ const char *NL, const char *Sep) override;
- virtual ProgramStateManager& getStateManager() { return StateMgr; }
+ ProgramStateManager& getStateManager() override { return StateMgr; }
StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
@@ -420,6 +422,10 @@
const Stmt *S, bool IsBaseDtor,
ExplodedNode *Pred, ExplodedNodeSet &Dst);
+ void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
@@ -475,17 +481,17 @@
/// Call PointerEscape callback when a value escapes as a result of bind.
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
- SVal Loc, SVal Val);
+ SVal Loc, SVal Val) override;
/// Call PointerEscape callback when a value escapes as a result of
/// region invalidation.
/// \param[in] ITraits Specifies invalidation traits for regions/symbols.
ProgramStateRef notifyCheckersOfPointerEscape(
- ProgramStateRef State,
- const InvalidatedSymbols *Invalidated,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- const CallEvent *Call,
- RegionAndSymbolInvalidationTraits &ITraits);
+ ProgramStateRef State,
+ const InvalidatedSymbols *Invalidated,
+ ArrayRef<const MemRegion *> ExplicitRegions,
+ ArrayRef<const MemRegion *> Regions,
+ const CallEvent *Call,
+ RegionAndSymbolInvalidationTraits &ITraits) override;
public:
// FIXME: 'tag' should be removed, and a LocationContext should be used
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index cc790c1..e3173a0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -23,13 +23,10 @@
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
#include <string>
-namespace llvm {
-class BumpPtrAllocator;
-}
-
namespace clang {
class LocationContext;
@@ -204,12 +201,12 @@
assert(classof(this));
}
- MemRegionManager* getMemRegionManager() const { return Mgr; }
+ MemRegionManager* getMemRegionManager() const override { return Mgr; }
public:
- bool isBoundable() const { return false; }
-
- void Profile(llvm::FoldingSetNodeID &ID) const;
+ bool isBoundable() const override { return false; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
static bool classof(const MemRegion *R) {
Kind k = R->getKind();
@@ -243,9 +240,9 @@
: GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
public:
- void Profile(llvm::FoldingSetNodeID &ID) const;
-
- void dumpToStream(raw_ostream &os) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+ void dumpToStream(raw_ostream &os) const override;
const CodeTextRegion *getCodeRegion() const { return CR; }
@@ -286,7 +283,7 @@
public:
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
return R->getKind() == GlobalSystemSpaceRegionKind;
@@ -306,7 +303,7 @@
public:
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
return R->getKind() == GlobalImmutableSpaceRegionKind;
@@ -324,7 +321,7 @@
public:
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
return R->getKind() == GlobalInternalSpaceRegionKind;
@@ -339,7 +336,7 @@
: MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
public:
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
return R->getKind() == HeapSpaceRegionKind;
@@ -353,7 +350,7 @@
: MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
public:
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
return R->getKind() == UnknownSpaceRegionKind;
@@ -373,7 +370,7 @@
public:
const StackFrameContext *getStackFrame() const { return SFC; }
- void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
static bool classof(const MemRegion *R) {
Kind k = R->getKind();
@@ -389,7 +386,7 @@
: StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
public:
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
return R->getKind() == StackLocalsSpaceRegionKind;
@@ -404,7 +401,7 @@
: StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
public:
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
return R->getKind() == StackArgumentsSpaceRegionKind;
@@ -430,9 +427,9 @@
return UnknownVal();
}
- MemRegionManager* getMemRegionManager() const;
+ MemRegionManager* getMemRegionManager() const override;
- virtual bool isSubRegionOf(const MemRegion* R) const;
+ bool isSubRegionOf(const MemRegion* R) const override;
static bool classof(const MemRegion* R) {
return R->getKind() > END_MEMSPACES;
@@ -459,16 +456,16 @@
const Expr *getExpr() const { return Ex; }
- bool isBoundable() const { return true; }
+ bool isBoundable() const override { return true; }
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+ DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
- void Profile(llvm::FoldingSetNodeID& ID) const;
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
unsigned Cnt, const MemRegion *superRegion);
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion* R) {
return R->getKind() == AllocaRegionKind;
@@ -478,7 +475,7 @@
/// TypedRegion - An abstract class representing regions that are typed.
class TypedRegion : public SubRegion {
public:
- virtual void anchor();
+ void anchor() override;
protected:
TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
@@ -489,7 +486,7 @@
return getLocationType().getDesugaredType(Context);
}
- bool isBoundable() const { return true; }
+ bool isBoundable() const override { return true; }
static bool classof(const MemRegion* R) {
unsigned k = R->getKind();
@@ -500,14 +497,14 @@
/// TypedValueRegion - An abstract class representing regions having a typed value.
class TypedValueRegion : public TypedRegion {
public:
- virtual void anchor();
+ void anchor() override;
protected:
TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
public:
virtual QualType getValueType() const = 0;
- virtual QualType getLocationType() const {
+ QualType getLocationType() const override {
// FIXME: We can possibly optimize this later to cache this value.
QualType T = getValueType();
ASTContext &ctx = getContext();
@@ -521,7 +518,7 @@
return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
}
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+ DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
static bool classof(const MemRegion* R) {
unsigned k = R->getKind();
@@ -532,12 +529,12 @@
class CodeTextRegion : public TypedRegion {
public:
- virtual void anchor();
+ void anchor() override;
protected:
CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
public:
- bool isBoundable() const { return false; }
-
+ bool isBoundable() const override { return false; }
+
static bool classof(const MemRegion* R) {
Kind k = R->getKind();
return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
@@ -552,8 +549,8 @@
: CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {
assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
}
-
- QualType getLocationType() const {
+
+ QualType getLocationType() const override {
const ASTContext &Ctx = getContext();
if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) {
return Ctx.getPointerType(D->getType());
@@ -570,11 +567,11 @@
const NamedDecl *getDecl() const {
return FD;
}
-
- virtual void dumpToStream(raw_ostream &os) const;
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
+
+ void dumpToStream(raw_ostream &os) const override;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
+
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
const MemRegion*);
@@ -602,7 +599,7 @@
: CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
public:
- QualType getLocationType() const {
+ QualType getLocationType() const override {
return locTy;
}
@@ -611,11 +608,11 @@
}
AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
-
- virtual void dumpToStream(raw_ostream &os) const;
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
+
+ virtual void dumpToStream(raw_ostream &os) const override;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
+
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
CanQualType, const AnalysisDeclContext*,
const MemRegion*);
@@ -650,8 +647,8 @@
const BlockDecl *getDecl() const { return BC->getDecl(); }
- QualType getLocationType() const { return BC->getLocationType(); }
-
+ QualType getLocationType() const override { return BC->getLocationType(); }
+
class referenced_vars_iterator {
const MemRegion * const *R;
const MemRegion * const *OriginalR;
@@ -688,11 +685,11 @@
referenced_vars_iterator referenced_vars_begin() const;
referenced_vars_iterator referenced_vars_end() const;
-
- virtual void dumpToStream(raw_ostream &os) const;
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
+
+ void dumpToStream(raw_ostream &os) const override;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
+
static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
const LocationContext *, unsigned,
const MemRegion *);
@@ -723,17 +720,17 @@
return sym;
}
- bool isBoundable() const { return true; }
+ bool isBoundable() const override { return true; }
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+ DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
- void Profile(llvm::FoldingSetNodeID& ID) const;
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
static void ProfileRegion(llvm::FoldingSetNodeID& ID,
SymbolRef sym,
const MemRegion* superRegion);
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion* R) {
return R->getKind() == SymbolicRegionKind;
@@ -757,19 +754,19 @@
const StringLiteral* getStringLiteral() const { return Str; }
- QualType getValueType() const {
+ QualType getValueType() const override {
return Str->getType();
}
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+ DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
- bool isBoundable() const { return false; }
+ bool isBoundable() const override { return false; }
- void Profile(llvm::FoldingSetNodeID& ID) const {
+ void Profile(llvm::FoldingSetNodeID& ID) const override {
ProfileRegion(ID, Str, superRegion);
}
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion* R) {
return R->getKind() == StringRegionKind;
@@ -792,19 +789,19 @@
public:
const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
-
- QualType getValueType() const {
+
+ QualType getValueType() const override {
return Str->getType();
}
-
- bool isBoundable() const { return false; }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
+
+ bool isBoundable() const override { return false; }
+
+ void Profile(llvm::FoldingSetNodeID& ID) const override {
ProfileRegion(ID, Str, superRegion);
}
-
- void dumpToStream(raw_ostream &os) const;
-
+
+ void dumpToStream(raw_ostream &os) const override;
+
static bool classof(const MemRegion* R) {
return R->getKind() == ObjCStringRegionKind;
}
@@ -825,15 +822,15 @@
const CompoundLiteralExpr *CL,
const MemRegion* superRegion);
public:
- QualType getValueType() const {
+ QualType getValueType() const override {
return CL->getType();
}
- bool isBoundable() const { return !CL->isFileScope(); }
+ bool isBoundable() const override { return !CL->isFileScope(); }
- void Profile(llvm::FoldingSetNodeID& ID) const;
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
@@ -854,7 +851,7 @@
public:
const Decl *getDecl() const { return D; }
- void Profile(llvm::FoldingSetNodeID& ID) const;
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
static bool classof(const MemRegion* R) {
unsigned k = R->getKind();
@@ -874,27 +871,27 @@
DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
}
- void Profile(llvm::FoldingSetNodeID& ID) const;
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
public:
const VarDecl *getDecl() const { return cast<VarDecl>(D); }
const StackFrameContext *getStackFrame() const;
-
- QualType getValueType() const {
+
+ QualType getValueType() const override {
// FIXME: We can cache this if needed.
return getDecl()->getType();
}
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion* R) {
return R->getKind() == VarRegionKind;
}
- bool canPrintPrettyAsExpr() const;
+ bool canPrintPrettyAsExpr() const override;
- void printPrettyAsExpr(raw_ostream &os) const;
+ void printPrettyAsExpr(raw_ostream &os) const override;
};
/// CXXThisRegion - Represents the region for the implicit 'this' parameter
@@ -910,15 +907,15 @@
const PointerType *PT,
const MemRegion *sReg);
- void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
-public:
- QualType getValueType() const {
+public:
+ QualType getValueType() const override {
return QualType(ThisPointerTy, 0);
}
- void dumpToStream(raw_ostream &os) const;
-
+ void dumpToStream(raw_ostream &os) const override;
+
static bool classof(const MemRegion* R) {
return R->getKind() == CXXThisRegionKind;
}
@@ -936,12 +933,12 @@
public:
const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
- QualType getValueType() const {
+ QualType getValueType() const override {
// FIXME: We can cache this if needed.
return getDecl()->getType();
}
- DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+ DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
const MemRegion* superRegion) {
@@ -952,12 +949,12 @@
return R->getKind() == FieldRegionKind;
}
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
- bool canPrintPretty() const;
- void printPretty(raw_ostream &os) const;
- bool canPrintPrettyAsExpr() const;
- void printPrettyAsExpr(raw_ostream &os) const;
+ bool canPrintPretty() const override;
+ void printPretty(raw_ostream &os) const override;
+ bool canPrintPrettyAsExpr() const override;
+ void printPrettyAsExpr(raw_ostream &os) const override;
};
class ObjCIvarRegion : public DeclRegion {
@@ -971,12 +968,12 @@
public:
const ObjCIvarDecl *getDecl() const;
- QualType getValueType() const;
+ QualType getValueType() const override;
- bool canPrintPrettyAsExpr() const;
- void printPrettyAsExpr(raw_ostream &os) const;
+ bool canPrintPrettyAsExpr() const override;
+ void printPrettyAsExpr(raw_ostream &os) const override;
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion* R) {
return R->getKind() == ObjCIvarRegionKind;
@@ -1029,7 +1026,7 @@
NonLoc getIndex() const { return Index; }
- QualType getValueType() const {
+ QualType getValueType() const override {
return ElementType;
}
@@ -1039,9 +1036,9 @@
/// Compute the offset within the array. The array might also be a subobject.
RegionRawOffset getAsArrayOffset() const;
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
- void Profile(llvm::FoldingSetNodeID& ID) const;
+ void Profile(llvm::FoldingSetNodeID& ID) const override;
static bool classof(const MemRegion* R) {
return R->getKind() == ElementRegionKind;
@@ -1063,13 +1060,13 @@
public:
const Expr *getExpr() const { return Ex; }
- QualType getValueType() const {
+ QualType getValueType() const override {
return Ex->getType();
}
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
- void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
static bool classof(const MemRegion* R) {
return R->getKind() == CXXTempObjectRegionKind;
@@ -1094,19 +1091,19 @@
const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
bool isVirtual() const { return Data.getInt(); }
- QualType getValueType() const;
+ QualType getValueType() const override;
- void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
- void Profile(llvm::FoldingSetNodeID &ID) const;
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
static bool classof(const MemRegion *region) {
return region->getKind() == CXXBaseObjectRegionKind;
}
- bool canPrintPrettyAsExpr() const;
-
- void printPrettyAsExpr(raw_ostream &os) const;
+ bool canPrintPrettyAsExpr() const override;
+
+ void printPrettyAsExpr(raw_ostream &os) const override;
};
template<typename RegionTy>
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 03739ed..4d345eb 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -25,10 +25,10 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
namespace llvm {
class APSInt;
-class BumpPtrAllocator;
}
namespace clang {
@@ -441,8 +441,8 @@
SubEngine *Eng; /* Can be null. */
EnvironmentManager EnvMgr;
- OwningPtr<StoreManager> StoreMgr;
- OwningPtr<ConstraintManager> ConstraintMgr;
+ std::unique_ptr<StoreManager> StoreMgr;
+ std::unique_ptr<ConstraintManager> ConstraintMgr;
ProgramState::GenericDataMap::Factory GDMFactory;
@@ -454,10 +454,10 @@
llvm::FoldingSet<ProgramState> StateSet;
/// Object that manages the data for all created SVals.
- OwningPtr<SValBuilder> svalBuilder;
+ std::unique_ptr<SValBuilder> svalBuilder;
/// Manages memory for created CallEvents.
- OwningPtr<CallEventManager> CallEventMgr;
+ std::unique_ptr<CallEventManager> CallEventMgr;
/// A BumpPtrAllocator to allocate states.
llvm::BumpPtrAllocator &Alloc;
@@ -676,10 +676,8 @@
inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
SVal Base) const {
StoreManager &SM = *getStateManager().StoreMgr;
- for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
- E = D->chain_end();
- I != E; ++I) {
- Base = SM.getLValueField(cast<FieldDecl>(*I), Base);
+ for (const auto *I : D->chain()) {
+ Base = SM.getLValueField(cast<FieldDecl>(I), Base);
}
return Base;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index eb52ae4..88098ee 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -18,10 +18,10 @@
#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
- class BumpPtrAllocator;
template <typename K, typename D, typename I> class ImmutableMap;
template <typename K, typename I> class ImmutableSet;
template <typename T> class ImmutableList;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index c5d0a92..5da1dd9 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -88,7 +88,7 @@
virtual SVal evalComplement(NonLoc val) = 0;
- /// Create a new value which represents a binary expression with two non
+ /// Create a new value which represents a binary expression with two non-
/// location operands.
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
@@ -99,7 +99,7 @@
Loc lhs, Loc rhs, QualType resultTy) = 0;
/// Create a new value which represents a binary expression with a memory
- /// location and non location operands. For example, this would be used to
+ /// location and non-location operands. For example, this would be used to
/// evaluate a pointer arithmetic operation.
virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
Loc lhs, NonLoc rhs, QualType resultTy) = 0;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 530dae5..a6da2e1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -223,7 +223,7 @@
FindUniqueBinding(SymbolRef sym) : Sym(sym), Binding(0), First(true) {}
bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
- SVal val);
+ SVal val) override;
LLVM_EXPLICIT operator bool() { return First && Binding; }
const MemRegion *getRegion() { return Binding; }
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 914b2be..e491fb0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -23,12 +23,9 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
-namespace llvm {
-class BumpPtrAllocator;
-}
-
namespace clang {
class ASTContext;
class StackFrameContext;
@@ -105,7 +102,7 @@
/// \brief A symbol representing data which can be stored in a memory location
/// (region).
class SymbolData : public SymExpr {
- virtual void anchor();
+ void anchor() override;
const SymbolID Sym;
protected:
@@ -138,13 +135,13 @@
profile.AddPointer(R);
}
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ void Profile(llvm::FoldingSetNodeID& profile) override {
Profile(profile, R);
}
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
- QualType getType() const;
+ QualType getType() const override;
// Implement isa<T> support.
static inline bool classof(const SymExpr *SE) {
@@ -173,9 +170,9 @@
unsigned getCount() const { return Count; }
const void *getTag() const { return SymbolTag; }
- QualType getType() const;
+ QualType getType() const override;
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S,
QualType T, unsigned Count, const LocationContext *LCtx,
@@ -188,7 +185,7 @@
profile.AddPointer(SymbolTag);
}
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ void Profile(llvm::FoldingSetNodeID& profile) override {
Profile(profile, S, T, Count, LCtx, SymbolTag);
}
@@ -211,9 +208,9 @@
SymbolRef getParentSymbol() const { return parentSymbol; }
const TypedValueRegion *getRegion() const { return R; }
- QualType getType() const;
+ QualType getType() const override;
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
const TypedValueRegion *r) {
@@ -222,7 +219,7 @@
profile.AddPointer(parent);
}
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ void Profile(llvm::FoldingSetNodeID& profile) override {
Profile(profile, parentSymbol, R);
}
@@ -244,16 +241,16 @@
const SubRegion *getRegion() const { return R; }
- QualType getType() const;
+ QualType getType() const override;
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) {
profile.AddInteger((unsigned) ExtentKind);
profile.AddPointer(R);
}
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ void Profile(llvm::FoldingSetNodeID& profile) override {
Profile(profile, R);
}
@@ -283,9 +280,9 @@
unsigned getCount() const { return Count; }
const void *getTag() const { return Tag; }
- QualType getType() const;
+ QualType getType() const override;
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R,
const Stmt *S, QualType T, unsigned Count,
@@ -298,7 +295,7 @@
profile.AddPointer(Tag);
}
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
+ void Profile(llvm::FoldingSetNodeID& profile) override {
Profile(profile, R, S, T, Count, Tag);
}
@@ -320,11 +317,11 @@
SymbolCast(const SymExpr *In, QualType From, QualType To) :
SymExpr(CastSymbolKind), Operand(In), FromTy(From), ToTy(To) { }
- QualType getType() const { return ToTy; }
+ QualType getType() const override { return ToTy; }
const SymExpr *getOperand() const { return Operand; }
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static void Profile(llvm::FoldingSetNodeID& ID,
const SymExpr *In, QualType From, QualType To) {
@@ -334,7 +331,7 @@
ID.Add(To);
}
- void Profile(llvm::FoldingSetNodeID& ID) {
+ void Profile(llvm::FoldingSetNodeID& ID) override {
Profile(ID, Operand, FromTy, ToTy);
}
@@ -356,7 +353,7 @@
public:
// FIXME: We probably need to make this out-of-line to avoid redundant
// generation of virtual functions.
- QualType getType() const { return T; }
+ QualType getType() const override { return T; }
BinaryOperator::Opcode getOpcode() const { return Op; }
@@ -377,7 +374,7 @@
const llvm::APSInt& rhs, QualType t)
: BinarySymExpr(SymIntKind, op, t), LHS(lhs), RHS(rhs) {}
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
const SymExpr *getLHS() const { return LHS; }
const llvm::APSInt &getRHS() const { return RHS; }
@@ -392,7 +389,7 @@
ID.Add(t);
}
- void Profile(llvm::FoldingSetNodeID& ID) {
+ void Profile(llvm::FoldingSetNodeID& ID) override {
Profile(ID, LHS, getOpcode(), RHS, getType());
}
@@ -412,7 +409,7 @@
const SymExpr *rhs, QualType t)
: BinarySymExpr(IntSymKind, op, t), LHS(lhs), RHS(rhs) {}
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
const SymExpr *getRHS() const { return RHS; }
const llvm::APSInt &getLHS() const { return LHS; }
@@ -427,7 +424,7 @@
ID.Add(t);
}
- void Profile(llvm::FoldingSetNodeID& ID) {
+ void Profile(llvm::FoldingSetNodeID& ID) override {
Profile(ID, LHS, getOpcode(), RHS, getType());
}
@@ -450,7 +447,7 @@
const SymExpr *getLHS() const { return LHS; }
const SymExpr *getRHS() const { return RHS; }
- virtual void dumpToStream(raw_ostream &os) const;
+ void dumpToStream(raw_ostream &os) const override;
static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) {
@@ -461,7 +458,7 @@
ID.Add(t);
}
- void Profile(llvm::FoldingSetNodeID& ID) {
+ void Profile(llvm::FoldingSetNodeID& ID) override {
Profile(ID, LHS, getOpcode(), RHS, getType());
}
diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
new file mode 100644
index 0000000..30e5d3d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -0,0 +1,49 @@
+//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains the functions necessary for a front-end to run various
+// analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_ANALYSISCONSUMER_H
+#define LLVM_CLANG_GR_ANALYSISCONSUMER_H
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include <string>
+
+namespace clang {
+
+class Preprocessor;
+class DiagnosticsEngine;
+
+namespace ento {
+class CheckerManager;
+
+class AnalysisASTConsumer : public ASTConsumer {
+public:
+ virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) = 0;
+};
+
+/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
+/// analysis passes. (The set of analyses run is controlled by command-line
+/// options.)
+AnalysisASTConsumer *CreateAnalysisConsumer(const Preprocessor &pp,
+ const std::string &output,
+ AnalyzerOptionsRef opts,
+ ArrayRef<std::string> plugins);
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
index 838ac92..21ecfc2 100644
--- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -22,8 +22,8 @@
class AnalysisAction : public ASTFrontendAction {
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h
index 71acef8..765e7d2 100644
--- a/include/clang/Tooling/ArgumentsAdjusters.h
+++ b/include/clang/Tooling/ArgumentsAdjusters.h
@@ -49,13 +49,13 @@
/// This class implements ArgumentsAdjuster interface and converts input
/// command line arguments to the "syntax check only" variant.
class ClangSyntaxOnlyAdjuster : public ArgumentsAdjuster {
- virtual CommandLineArguments Adjust(const CommandLineArguments &Args);
+ CommandLineArguments Adjust(const CommandLineArguments &Args) override;
};
/// \brief An argument adjuster which removes output-related command line
/// arguments.
class ClangStripOutputAdjuster : public ArgumentsAdjuster {
- virtual CommandLineArguments Adjust(const CommandLineArguments &Args);
+ CommandLineArguments Adjust(const CommandLineArguments &Args) override;
};
} // end namespace tooling
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index eaffe43..1f32cd8 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -28,6 +28,7 @@
#define LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H
#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/Support/CommandLine.h"
namespace clang {
namespace tooling {
@@ -46,13 +47,14 @@
/// using namespace clang::tooling;
/// using namespace llvm;
///
+/// static cl::OptionCategory MyToolCategory("My tool options");
/// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
/// static cl::extrahelp MoreHelp("\nMore help text...");
/// static cl:opt<bool> YourOwnOption(...);
/// ...
///
/// int main(int argc, const char **argv) {
-/// CommonOptionsParser OptionsParser(argc, argv);
+/// CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
/// ClangTool Tool(OptionsParser.getCompilations(),
/// OptionsParser.getSourcePathListi());
/// return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
@@ -61,10 +63,16 @@
class CommonOptionsParser {
public:
/// \brief Parses command-line, initializes a compilation database.
+ ///
/// This constructor can change argc and argv contents, e.g. consume
/// command-line options used for creating FixedCompilationDatabase.
+ ///
+ /// All options not belonging to \p Category become hidden.
+ ///
/// This constructor exits program in case of error.
- CommonOptionsParser(int &argc, const char **argv, const char *Overview = 0);
+ CommonOptionsParser(int &argc, const char **argv,
+ llvm::cl::OptionCategory &Category,
+ const char *Overview = 0);
/// Returns a reference to the loaded compilations database.
CompilationDatabase &getCompilations() {
@@ -79,7 +87,7 @@
static const char *const HelpMessage;
private:
- OwningPtr<CompilationDatabase> Compilations;
+ std::unique_ptr<CompilationDatabase> Compilations;
std::vector<std::string> SourcePathList;
};
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index 8cca329..d1e729a 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -30,9 +30,9 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include <memory>
#include <string>
#include <vector>
@@ -42,8 +42,8 @@
/// \brief Specifies the working directory and command of a compilation.
struct CompileCommand {
CompileCommand() {}
- CompileCommand(Twine Directory, ArrayRef<std::string> CommandLine)
- : Directory(Directory.str()), CommandLine(CommandLine) {}
+ CompileCommand(Twine Directory, std::vector<std::string> CommandLine)
+ : Directory(Directory.str()), CommandLine(std::move(CommandLine)) {}
/// \brief The working directory the command was executed from.
std::string Directory;
@@ -166,7 +166,7 @@
/// The argument list is meant to be compatible with normal llvm command line
/// parsing in main methods.
/// int main(int argc, char **argv) {
- /// OwningPtr<FixedCompilationDatabase> Compilations(
+ /// std::unique_ptr<FixedCompilationDatabase> Compilations(
/// FixedCompilationDatabase::loadFromCommandLine(argc, argv));
/// cl::ParseCommandLineOptions(argc, argv);
/// ...
@@ -190,19 +190,19 @@
/// Will always return a vector with one entry that contains the directory
/// and command line specified at construction with "clang-tool" as argv[0]
/// and 'FilePath' as positional argument.
- virtual std::vector<CompileCommand> getCompileCommands(
- StringRef FilePath) const;
+ std::vector<CompileCommand>
+ getCompileCommands(StringRef FilePath) const override;
/// \brief Returns the list of all files available in the compilation database.
///
/// Note: This is always an empty list for the fixed compilation database.
- virtual std::vector<std::string> getAllFiles() const;
+ std::vector<std::string> getAllFiles() const override;
/// \brief Returns all compile commands for all the files in the compilation
/// database.
///
/// Note: This is always an empty list for the fixed compilation database.
- virtual std::vector<CompileCommand> getAllCompileCommands() const;
+ std::vector<CompileCommand> getAllCompileCommands() const override;
private:
/// This is built up to contain a single entry vector to be returned from
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
index e531854..be37baf 100644
--- a/include/clang/Tooling/FileMatchTrie.h
+++ b/include/clang/Tooling/FileMatchTrie.h
@@ -16,8 +16,8 @@
#define LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
+#include <memory>
#include <string>
#include <vector>
@@ -79,7 +79,7 @@
raw_ostream &Error) const;
private:
FileMatchTrieNode *Root;
- OwningPtr<PathComparator> Comparator;
+ std::unique_ptr<PathComparator> Comparator;
};
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
index e3f149b..1b33359 100644
--- a/include/clang/Tooling/JSONCompilationDatabase.h
+++ b/include/clang/Tooling/JSONCompilationDatabase.h
@@ -18,12 +18,12 @@
#include "clang/Basic/LLVM.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/FileMatchTrie.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
+#include <memory>
#include <string>
#include <vector>
@@ -67,17 +67,17 @@
///
/// FIXME: Currently FilePath must be an absolute path inside the
/// source directory which does not have symlinks resolved.
- virtual std::vector<CompileCommand> getCompileCommands(
- StringRef FilePath) const;
+ std::vector<CompileCommand>
+ getCompileCommands(StringRef FilePath) const override;
/// \brief Returns the list of all files available in the compilation database.
///
/// These are the 'file' entries of the JSON objects.
- virtual std::vector<std::string> getAllFiles() const;
+ std::vector<std::string> getAllFiles() const override;
/// \brief Returns all compile commands for all the files in the compilation
/// database.
- virtual std::vector<CompileCommand> getAllCompileCommands() const;
+ std::vector<CompileCommand> getAllCompileCommands() const override;
private:
/// \brief Constructs a JSON compilation database on a memory buffer.
@@ -104,7 +104,7 @@
FileMatchTrie MatchTrie;
- OwningPtr<llvm::MemoryBuffer> Database;
+ std::unique_ptr<llvm::MemoryBuffer> Database;
llvm::SourceMgr SM;
llvm::yaml::Stream YAMLStream;
};
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
index 43ec9ac..cd2fb9f 100644
--- a/include/clang/Tooling/Refactoring.h
+++ b/include/clang/Tooling/Refactoring.h
@@ -83,16 +83,16 @@
/// \brief Creates a Replacement of the range [Start, Start+Length) with
/// ReplacementText.
- Replacement(SourceManager &Sources, SourceLocation Start, unsigned Length,
+ Replacement(const SourceManager &Sources, SourceLocation Start, unsigned Length,
StringRef ReplacementText);
/// \brief Creates a Replacement of the given range with ReplacementText.
- Replacement(SourceManager &Sources, const CharSourceRange &Range,
+ Replacement(const SourceManager &Sources, const CharSourceRange &Range,
StringRef ReplacementText);
/// \brief Creates a Replacement of the node with ReplacementText.
template <typename Node>
- Replacement(SourceManager &Sources, const Node &NodeToReplace,
+ Replacement(const SourceManager &Sources, const Node &NodeToReplace,
StringRef ReplacementText);
/// \brief Returns whether this replacement can be applied to a file.
@@ -115,9 +115,10 @@
std::string toString() const;
private:
- void setFromSourceLocation(SourceManager &Sources, SourceLocation Start,
+ void setFromSourceLocation(const SourceManager &Sources, SourceLocation Start,
unsigned Length, StringRef ReplacementText);
- void setFromSourceRange(SourceManager &Sources, const CharSourceRange &Range,
+ void setFromSourceRange(const SourceManager &Sources,
+ const CharSourceRange &Range,
StringRef ReplacementText);
std::string FilePath;
@@ -230,8 +231,8 @@
};
template <typename Node>
-Replacement::Replacement(SourceManager &Sources, const Node &NodeToReplace,
- StringRef ReplacementText) {
+Replacement::Replacement(const SourceManager &Sources,
+ const Node &NodeToReplace, StringRef ReplacementText) {
const CharSourceRange Range =
CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
setFromSourceRange(Sources, Range, ReplacementText);
diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h
index c500f35..19f2774 100644
--- a/include/clang/Tooling/RefactoringCallbacks.h
+++ b/include/clang/Tooling/RefactoringCallbacks.h
@@ -52,7 +52,7 @@
class ReplaceStmtWithText : public RefactoringCallback {
public:
ReplaceStmtWithText(StringRef FromId, StringRef ToText);
- virtual void run(const ast_matchers::MatchFinder::MatchResult &Result);
+ void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
std::string FromId;
@@ -64,7 +64,7 @@
class ReplaceStmtWithStmt : public RefactoringCallback {
public:
ReplaceStmtWithStmt(StringRef FromId, StringRef ToId);
- virtual void run(const ast_matchers::MatchFinder::MatchResult &Result);
+ void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
std::string FromId;
@@ -77,7 +77,7 @@
class ReplaceIfStmtWithItsBody : public RefactoringCallback {
public:
ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch);
- virtual void run(const ast_matchers::MatchFinder::MatchResult &Result);
+ void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
std::string Id;
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
index 18d3259..ac9f469 100644
--- a/include/clang/Tooling/ReplacementsYaml.h
+++ b/include/clang/Tooling/ReplacementsYaml.h
@@ -18,26 +18,14 @@
#include "clang/Tooling/Refactoring.h"
#include "llvm/Support/YAMLTraits.h"
-#include <vector>
#include <string>
+#include <vector>
LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement)
namespace llvm {
namespace yaml {
-/// \brief ScalarTraits to read/write std::string objects.
-template <> struct ScalarTraits<std::string> {
- static void output(const std::string &Val, void *, llvm::raw_ostream &Out) {
- Out << Val;
- }
-
- static StringRef input(StringRef Scalar, void *, std::string &Val) {
- Val = Scalar;
- return StringRef();
- }
-};
-
/// \brief Specialized MappingTraits to describe how a Replacement is
/// (de)serialized.
template <> struct MappingTraits<clang::tooling::Replacement> {
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index de507a7..097a7a8 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -80,7 +80,7 @@
/// \brief Invokes the compiler with a FrontendAction created by create().
bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
- DiagnosticConsumer *DiagConsumer);
+ DiagnosticConsumer *DiagConsumer) override;
/// \brief Returns a new clang::FrontendAction.
///
@@ -186,7 +186,7 @@
/// \param FAction The action to be executed. Class takes ownership.
/// \param Files The FileManager used for the execution. Class does not take
/// ownership.
- ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *FAction,
+ ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
FileManager *Files);
/// \brief Create a tool invocation.
@@ -194,7 +194,7 @@
/// \param CommandLine The command line arguments to clang.
/// \param Action The action to be executed.
/// \param Files The FileManager used for the execution.
- ToolInvocation(ArrayRef<std::string> CommandLine, ToolAction *Action,
+ ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
FileManager *Files);
~ToolInvocation();
@@ -306,7 +306,7 @@
FrontendActionFactory *newFrontendActionFactory() {
class SimpleFrontendActionFactory : public FrontendActionFactory {
public:
- virtual clang::FrontendAction *create() { return new T; }
+ clang::FrontendAction *create() override { return new T; }
};
return new SimpleFrontendActionFactory;
@@ -321,7 +321,7 @@
SourceFileCallbacks *Callbacks)
: ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
- virtual clang::FrontendAction *create() {
+ clang::FrontendAction *create() override {
return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
}
@@ -333,20 +333,20 @@
: ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
- StringRef) {
+ StringRef) override {
return ConsumerFactory->newASTConsumer();
}
protected:
- virtual bool BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename) LLVM_OVERRIDE {
+ bool BeginSourceFileAction(CompilerInstance &CI,
+ StringRef Filename) override {
if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
return false;
if (Callbacks != NULL)
return Callbacks->handleBeginSource(CI, Filename);
return true;
}
- virtual void EndSourceFileAction() LLVM_OVERRIDE {
+ void EndSourceFileAction() override {
if (Callbacks != NULL)
Callbacks->handleEndSource();
clang::ASTFrontendAction::EndSourceFileAction();