summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/clang-c/Index.h280
-rw-r--r--include/clang/AST/ASTContext.h58
-rw-r--r--include/clang/AST/ASTImporter.h6
-rw-r--r--include/clang/AST/Attr.h36
-rw-r--r--include/clang/AST/CXXInheritance.h7
-rw-r--r--include/clang/AST/CanonicalType.h21
-rw-r--r--include/clang/AST/Decl.h8
-rw-r--r--include/clang/AST/DeclBase.h5
-rw-r--r--include/clang/AST/DeclCXX.h29
-rw-r--r--include/clang/AST/DeclObjC.h32
-rw-r--r--include/clang/AST/Expr.h6
-rw-r--r--include/clang/AST/ExprCXX.h140
-rw-r--r--include/clang/AST/Type.h9
-rw-r--r--include/clang/AST/TypeNodes.def19
-rw-r--r--include/clang/Analysis/Analyses/PrintfFormatString.h62
-rw-r--r--include/clang/Analysis/Analyses/ReachableCode.h55
-rw-r--r--include/clang/Analysis/AnalysisContext.h2
-rw-r--r--include/clang/Analysis/CFG.h2
-rw-r--r--include/clang/Analysis/ProgramPoint.h33
-rw-r--r--include/clang/Analysis/Support/BumpVector.h1
-rw-r--r--include/clang/Basic/Builtins.def2
-rw-r--r--include/clang/Basic/Diagnostic.h51
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td25
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticGroups.td7
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td9
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td97
-rw-r--r--include/clang/Basic/LangOptions.h4
-rw-r--r--include/clang/Basic/OnDiskHashTable.h7
-rw-r--r--include/clang/Checker/PathSensitive/Checker.h10
-rw-r--r--include/clang/Checker/PathSensitive/GRCoreEngine.h75
-rw-r--r--include/clang/Checker/PathSensitive/GRExprEngine.h8
-rw-r--r--include/clang/Checker/PathSensitive/GRState.h24
-rw-r--r--include/clang/Checker/PathSensitive/GRSubEngine.h8
-rw-r--r--include/clang/Checker/PathSensitive/MemRegion.h15
-rw-r--r--include/clang/Checker/PathSensitive/SymbolManager.h25
-rw-r--r--include/clang/Checker/PathSensitive/ValueManager.h3
-rw-r--r--include/clang/CodeGen/CodeGenOptions.h3
-rw-r--r--include/clang/Driver/CC1Options.td2
-rw-r--r--include/clang/Driver/Driver.h6
-rw-r--r--include/clang/Driver/Options.td3
-rw-r--r--include/clang/Driver/Types.h4
-rw-r--r--include/clang/Frontend/ASTConsumers.h20
-rw-r--r--include/clang/Frontend/ASTUnit.h38
-rw-r--r--include/clang/Frontend/CodeGenAction.h65
-rw-r--r--include/clang/Frontend/FrontendActions.h40
-rw-r--r--include/clang/Frontend/PCHBitCodes.h4
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h8
-rw-r--r--include/clang/Lex/Preprocessor.h6
-rw-r--r--include/clang/Parse/Action.h91
-rw-r--r--include/clang/Parse/AttributeList.h10
-rw-r--r--include/clang/Parse/Parser.h111
-rw-r--r--include/clang/Parse/Scope.h12
54 files changed, 1182 insertions, 428 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 84ec472..7bc290d 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -18,6 +18,7 @@
#include <sys/stat.h>
#include <time.h>
+#include <stdio.h>
#ifdef __cplusplus
extern "C" {
@@ -86,14 +87,12 @@ struct CXUnsavedFile {
const char *Filename;
/**
- * \brief A null-terminated buffer containing the unsaved contents
- * of this file.
+ * \brief A buffer containing the unsaved contents of this file.
*/
const char *Contents;
/**
- * \brief The length of the unsaved contents of this buffer, not
- * counting the NULL at the end of the buffer.
+ * \brief The length of the unsaved contents of this buffer.
*/
unsigned long Length;
};
@@ -145,8 +144,8 @@ CINDEX_LINKAGE void clang_disposeString(CXString string);
*
* Here is an example:
*
- * // excludeDeclsFromPCH = 1
- * Idx = clang_createIndex(1);
+ * // excludeDeclsFromPCH = 1, displayDiagnostics=1
+ * Idx = clang_createIndex(1, 1);
*
* // IndexTest.pch was produced with the following command:
* // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
@@ -170,7 +169,8 @@ CINDEX_LINKAGE void clang_disposeString(CXString string);
* -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
* (which gives the indexer the same performance benefit as the compiler).
*/
-CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH);
+CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+ int displayDiagnostics);
/**
* \brief Destroy the given index.
@@ -207,7 +207,7 @@ typedef void *CXFile;
/**
* \brief Retrieve the complete file and path name of the given file.
*/
-CINDEX_LINKAGE const char *clang_getFileName(CXFile SFile);
+CINDEX_LINKAGE CXString clang_getFileName(CXFile SFile);
/**
* \brief Retrieve the last modification time of the given file.
@@ -388,45 +388,105 @@ enum CXDiagnosticSeverity {
};
/**
- * \brief Describes the kind of fix-it hint expressed within a
- * diagnostic.
+ * \brief A single diagnostic, containing the diagnostic's severity,
+ * location, text, source ranges, and fix-it hints.
*/
-enum CXFixItKind {
+typedef void *CXDiagnostic;
+
+/**
+ * \brief Determine the number of diagnostics produced for the given
+ * translation unit.
+ */
+CINDEX_LINKAGE unsigned clang_getNumDiagnostics(CXTranslationUnit Unit);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given translation unit.
+ *
+ * \param Unit the translation unit to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit,
+ unsigned Index);
+
+/**
+ * \brief Destroy a diagnostic.
+ */
+CINDEX_LINKAGE void clang_disposeDiagnostic(CXDiagnostic Diagnostic);
+
+/**
+ * \brief Options to control the display of diagnostics.
+ *
+ * The values in this enum are meant to be combined to customize the
+ * behavior of \c clang_displayDiagnostic().
+ */
+enum CXDiagnosticDisplayOptions {
/**
- * \brief A fix-it hint that inserts code at a particular position.
+ * \brief Display the source-location information where the
+ * diagnostic was located.
+ *
+ * When set, diagnostics will be prefixed by the file, line, and
+ * (optionally) column to which the diagnostic refers. For example,
+ *
+ * \code
+ * test.c:28: warning: extra tokens at end of #endif directive
+ * \endcode
+ *
+ * This option corresponds to the clang flag \c -fshow-source-location.
*/
- CXFixIt_Insertion = 0,
+ CXDiagnostic_DisplaySourceLocation = 0x01,
/**
- * \brief A fix-it hint that removes code within a range.
+ * \brief If displaying the source-location information of the
+ * diagnostic, also include the column number.
+ *
+ * This option corresponds to the clang flag \c -fshow-column.
*/
- CXFixIt_Removal = 1,
+ CXDiagnostic_DisplayColumn = 0x02,
/**
- * \brief A fix-it hint that replaces the code within a range with another
- * string.
+ * \brief If displaying the source-location information of the
+ * diagnostic, also include information about source ranges in a
+ * machine-parsable format.
+ *
+ * This option corresponds to the clang flag
+ * \c -fdiagnostics-print-source-range-info.
*/
- CXFixIt_Replacement = 2
+ CXDiagnostic_DisplaySourceRanges = 0x04
};
/**
- * \brief A single diagnostic, containing the diagnostic's severity,
- * location, text, source ranges, and fix-it hints.
+ * \brief Format the given diagnostic in a manner that is suitable for display.
+ *
+ * This routine will format the given diagnostic to a string, rendering
+ * the diagnostic according to the various options given. The
+ * \c clang_defaultDiagnosticDisplayOptions() function returns the set of
+ * options that most closely mimics the behavior of the clang compiler.
+ *
+ * \param Diagnostic The diagnostic to print.
+ *
+ * \param Options A set of options that control the diagnostic display,
+ * created by combining \c CXDiagnosticDisplayOptions values.
+ *
+ * \returns A new string containing for formatted diagnostic.
*/
-typedef void *CXDiagnostic;
+CINDEX_LINKAGE CXString clang_formatDiagnostic(CXDiagnostic Diagnostic,
+ unsigned Options);
/**
- * \brief Callback function invoked for each diagnostic emitted during
- * translation.
- *
- * \param Diagnostic the diagnostic emitted during translation. This
- * diagnostic pointer is only valid during the execution of the
- * callback.
+ * \brief Retrieve the set of display options most similar to the
+ * default behavior of the clang compiler.
*
- * \param ClientData the callback client data.
+ * \returns A set of display options suitable for use with \c
+ * clang_displayDiagnostic().
+ */
+CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void);
+
+/**
+ * \brief Print a diagnostic to the given file.
*/
-typedef void (*CXDiagnosticCallback)(CXDiagnostic Diagnostic,
- CXClientData ClientData);
/**
* \brief Determine the severity of the given diagnostic.
@@ -476,69 +536,33 @@ CINDEX_LINKAGE CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic,
CINDEX_LINKAGE unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic);
/**
- * \brief Retrieve the kind of the given fix-it.
- *
- * \param Diagnostic the diagnostic whose fix-its are being queried.
- *
- * \param FixIt the zero-based index of the fix-it to query.
- */
-CINDEX_LINKAGE enum CXFixItKind
-clang_getDiagnosticFixItKind(CXDiagnostic Diagnostic, unsigned FixIt);
-
-/**
- * \brief Retrieve the insertion information for an insertion fix-it.
+ * \brief Retrieve the replacement information for a given fix-it.
*
- * For a fix-it that describes an insertion into a text buffer,
- * retrieve the source location where the text should be inserted and
- * the text to be inserted.
+ * Fix-its are described in terms of a source range whose contents
+ * should be replaced by a string. This approach generalizes over
+ * three kinds of operations: removal of source code (the range covers
+ * the code to be removed and the replacement string is empty),
+ * replacement of source code (the range covers the code to be
+ * replaced and the replacement string provides the new code), and
+ * insertion (both the start and end of the range point at the
+ * insertion location, and the replacement string provides the text to
+ * insert).
*
- * \param Diagnostic the diagnostic whose fix-its are being queried.
+ * \param Diagnostic The diagnostic whose fix-its are being queried.
*
- * \param FixIt the zero-based index of the insertion fix-it.
+ * \param FixIt The zero-based index of the fix-it.
*
- * \param Location will be set to the location where text should be
- * inserted.
+ * \param ReplacementRange The source range whose contents will be
+ * replaced with the returned replacement string. Note that source
+ * ranges are half-open ranges [a, b), so the source code should be
+ * replaced from a and up to (but not including) b.
*
- * \returns the text string to insert at the given location.
+ * \returns A string containing text that should be replace the source
+ * code indicated by the \c ReplacementRange.
*/
-CINDEX_LINKAGE CXString
-clang_getDiagnosticFixItInsertion(CXDiagnostic Diagnostic, unsigned FixIt,
- CXSourceLocation *Location);
-
-/**
- * \brief Retrieve the removal information for a removal fix-it.
- *
- * For a fix-it that describes a removal from a text buffer, retrieve
- * the source range that should be removed.
- *
- * \param Diagnostic the diagnostic whose fix-its are being queried.
- *
- * \param FixIt the zero-based index of the removal fix-it.
- *
- * \returns a source range describing the text that should be removed
- * from the buffer.
- */
-CINDEX_LINKAGE CXSourceRange
-clang_getDiagnosticFixItRemoval(CXDiagnostic Diagnostic, unsigned FixIt);
-
-/**
- * \brief Retrieve the replacement information for an replacement fix-it.
- *
- * For a fix-it that describes replacement of text in the text buffer
- * with alternative text.
- *
- * \param Diagnostic the diagnostic whose fix-its are being queried.
- *
- * \param FixIt the zero-based index of the replacement fix-it.
- *
- * \param Range will be set to the source range whose text should be
- * replaced with the returned text.
- *
- * \returns the text string to use as replacement text.
- */
-CINDEX_LINKAGE CXString
-clang_getDiagnosticFixItReplacement(CXDiagnostic Diagnostic, unsigned FixIt,
- CXSourceRange *Range);
+CINDEX_LINKAGE CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic,
+ unsigned FixIt,
+ CXSourceRange *ReplacementRange);
/**
* @}
@@ -600,17 +624,13 @@ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
int num_clang_command_line_args,
const char **clang_command_line_args,
unsigned num_unsaved_files,
- struct CXUnsavedFile *unsaved_files,
- CXDiagnosticCallback diag_callback,
- CXClientData diag_client_data);
+ struct CXUnsavedFile *unsaved_files);
/**
* \brief Create a translation unit from an AST file (-emit-ast).
*/
CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(CXIndex,
- const char *ast_filename,
- CXDiagnosticCallback diag_callback,
- CXClientData diag_client_data);
+ const char *ast_filename);
/**
* \brief Destroy the specified CXTranslationUnit object.
@@ -764,7 +784,19 @@ enum CXCursorKind {
* The translation unit cursor exists primarily to act as the root
* cursor for traversing the contents of a translation unit.
*/
- CXCursor_TranslationUnit = 300
+ CXCursor_TranslationUnit = 300,
+
+ /* Attributes */
+ CXCursor_FirstAttr = 400,
+ /**
+ * \brief An attribute whose specific kind is not exposed via this
+ * interface.
+ */
+ CXCursor_UnexposedAttr = 400,
+
+ CXCursor_IBActionAttr = 401,
+ CXCursor_IBOutletAttr = 402,
+ CXCursor_LastAttr = CXCursor_IBOutletAttr
};
/**
@@ -857,6 +889,32 @@ CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind);
CINDEX_LINKAGE unsigned clang_isTranslationUnit(enum CXCursorKind);
/**
+ * \brief Describe the linkage of the entity referred to by a cursor.
+ */
+enum CXLinkageKind {
+ /** \brief This value indicates that no linkage information is available
+ * for a provided CXCursor. */
+ CXLinkage_Invalid,
+ /**
+ * \brief This is the linkage for variables, parameters, and so on that
+ * have automatic storage. This covers normal (non-extern) local variables.
+ */
+ CXLinkage_NoLinkage,
+ /** \brief This is the linkage for static variables and static functions. */
+ CXLinkage_Internal,
+ /** \brief This is the linkage for entities with external linkage that live
+ * in C++ anonymous namespaces.*/
+ CXLinkage_UniqueExternal,
+ /** \brief This is the linkage for entities with true, external linkage. */
+ CXLinkage_External
+};
+
+/**
+ * \brief Determine the linkage of the entity referred to be a given cursor.
+ */
+CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor);
+
+/**
* @}
*/
@@ -1221,7 +1279,7 @@ CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU,
*/
/* for debug/testing */
-CINDEX_LINKAGE const char *clang_getCursorKindSpelling(enum CXCursorKind Kind);
+CINDEX_LINKAGE CXString clang_getCursorKindSpelling(enum CXCursorKind Kind);
CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,
const char **startBuf,
const char **endBuf,
@@ -1229,7 +1287,7 @@ CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,
unsigned *startColumn,
unsigned *endLine,
unsigned *endColumn);
-
+CINDEX_LINKAGE void clang_enableStackTraces(void);
/**
* @}
*/
@@ -1313,13 +1371,13 @@ enum CXCompletionChunkKind {
* - a Placeholder chunk for "int x"
* - an Optional chunk containing the remaining defaulted arguments, e.g.,
* - a Comma chunk for ","
- * - a Placeholder chunk for "float x"
+ * - a Placeholder chunk for "float y"
* - an Optional chunk containing the last defaulted argument:
* - a Comma chunk for ","
* - a Placeholder chunk for "double z"
* - a RightParen chunk for ")"
*
- * There are many ways two handle Optional chunks. Two simple approaches are:
+ * There are many ways to handle Optional chunks. Two simple approaches are:
* - Completely ignore optional chunks, in which case the template for the
* function "f" would only include the first parameter ("int x").
* - Fully expand all optional chunks, in which case the template for the
@@ -1478,7 +1536,7 @@ clang_getCompletionChunkKind(CXCompletionString completion_string,
*
* \returns the text associated with the chunk at index \c chunk_number.
*/
-CINDEX_LINKAGE const char *
+CINDEX_LINKAGE CXString
clang_getCompletionChunkText(CXCompletionString completion_string,
unsigned chunk_number);
@@ -1613,9 +1671,7 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
struct CXUnsavedFile *unsaved_files,
const char *complete_filename,
unsigned complete_line,
- unsigned complete_column,
- CXDiagnosticCallback diag_callback,
- CXClientData diag_client_data);
+ unsigned complete_column);
/**
* \brief Free the given set of code-completion results.
@@ -1624,6 +1680,26 @@ CINDEX_LINKAGE
void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results);
/**
+ * \brief Determine the number of diagnostics produced prior to the
+ * location where code completion was performed.
+ */
+CINDEX_LINKAGE
+unsigned clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *Results);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given code completion.
+ *
+ * \param Result the code completion results to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE
+CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results,
+ unsigned Index);
+
+/**
* @}
*/
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 2ed9fd7..6767f52 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -67,6 +67,28 @@ namespace clang {
namespace Builtin { class Context; }
+/// \brief A vector of C++ member functions that is optimized for
+/// storing a single method.
+class CXXMethodVector {
+ /// \brief Storage for the vector.
+ ///
+ /// When the low bit is zero, this is a const CXXMethodDecl *. When the
+ /// low bit is one, this is a std::vector<const CXXMethodDecl *> *.
+ mutable uintptr_t Storage;
+
+ typedef std::vector<const CXXMethodDecl *> vector_type;
+
+public:
+ CXXMethodVector() : Storage(0) { }
+
+ typedef const CXXMethodDecl **iterator;
+ iterator begin() const;
+ iterator end() const;
+
+ void push_back(const CXXMethodDecl *Method);
+ void Destroy();
+};
+
/// ASTContext - This class holds long-lived AST nodes (such as types and
/// decls) that can be referred to throughout the semantic analysis of a file.
class ASTContext {
@@ -219,6 +241,14 @@ class ASTContext {
llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
+ /// \brief Mapping that stores the methods overridden by a given C++
+ /// member function.
+ ///
+ /// Since most C++ member functions aren't virtual and therefore
+ /// don't override anything, we store the overridden functions in
+ /// this map on the side rather than within the CXXMethodDecl structure.
+ llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
+
TranslationUnitDecl *TUDecl;
/// SourceMgr - The associated SourceManager object.
@@ -310,6 +340,19 @@ public:
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
+ // Access to the set of methods overridden by the given C++ method.
+ typedef CXXMethodVector::iterator overridden_cxx_method_iterator;
+ overridden_cxx_method_iterator
+ overridden_methods_begin(const CXXMethodDecl *Method) const;
+
+ overridden_cxx_method_iterator
+ overridden_methods_end(const CXXMethodDecl *Method) const;
+
+ /// \brief Note that the given C++ \p Method overrides the given \p
+ /// Overridden method.
+ void addOverriddenMethod(const CXXMethodDecl *Method,
+ const CXXMethodDecl *Overridden);
+
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
@@ -529,11 +572,11 @@ public:
/// list. isVariadic indicates whether the argument list includes '...'.
QualType getFunctionType(QualType ResultTy, const QualType *ArgArray,
unsigned NumArgs, bool isVariadic,
- unsigned TypeQuals, bool hasExceptionSpec = false,
- bool hasAnyExceptionSpec = false,
- unsigned NumExs = 0, const QualType *ExArray = 0,
- bool NoReturn = false,
- CallingConv CallConv = CC_Default);
+ unsigned TypeQuals, bool hasExceptionSpec,
+ bool hasAnyExceptionSpec,
+ unsigned NumExs, const QualType *ExArray,
+ bool NoReturn,
+ CallingConv CallConv);
/// getTypeDeclType - Return the unique reference to the type for
/// the specified type declaration.
@@ -882,9 +925,8 @@ public:
llvm::SmallVectorImpl<FieldDecl*> &Fields);
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars,
- bool CollectSynthesized = true);
- void CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
+ llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+ void CollectNonClassIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
void CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index f5f11ca..7975c43 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -156,6 +156,12 @@ namespace clang {
/// \returns the equivalent identifier in the "to" context.
IdentifierInfo *Import(IdentifierInfo *FromId);
+ /// \brief Import the given Objective-C selector from the "from"
+ /// context into the "to" context.
+ ///
+ /// \returns the equivalent selector in the "to" context.
+ Selector Import(Selector FromSel);
+
/// \brief Import the given file ID from the "from" context into the
/// "to" context.
///
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 3722590..1974493 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -62,7 +62,8 @@ public:
FormatArg,
GNUInline,
Hiding,
- IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
+ IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
+ IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
Malloc,
NoDebug,
NoInline,
@@ -72,8 +73,10 @@ public:
ObjCException,
ObjCNSObject,
Override,
- CFReturnsRetained, // Clang/Checker-specific.
- NSReturnsRetained, // Clang/Checker-specific.
+ CFReturnsRetained, // Clang/Checker-specific.
+ CFReturnsNotRetained, // Clang/Checker-specific.
+ NSReturnsRetained, // Clang/Checker-specific.
+ NSReturnsNotRetained, // Clang/Checker-specific.
Overloadable, // Clang-specific
Packed,
PragmaPack,
@@ -91,6 +94,7 @@ public:
WarnUnusedResult,
Weak,
WeakImport,
+ WeakRef,
FIRST_TARGET_ATTRIBUTE,
DLLExport,
@@ -300,37 +304,38 @@ public:
static bool classof(const DestructorAttr *A) { return true; }
};
-class GNUInlineAttr : public Attr {
+class IBOutletAttr : public Attr {
public:
- GNUInlineAttr() : Attr(GNUInline) {}
+ IBOutletAttr() : Attr(IBOutletKind) {}
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == GNUInline;
+ return A->getKind() == IBOutletKind;
}
- static bool classof(const GNUInlineAttr *A) { return true; }
+ static bool classof(const IBOutletAttr *A) { return true; }
};
-class IBOutletAttr : public Attr {
+class IBActionAttr : public Attr {
public:
- IBOutletAttr() : Attr(IBOutletKind) {}
+ IBActionAttr() : Attr(IBActionKind) {}
virtual Attr *clone(ASTContext &C) const;
- // Implement isa/cast/dyncast/etc.
+ // Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
- return A->getKind() == IBOutletKind;
+ return A->getKind() == IBActionKind;
}
- static bool classof(const IBOutletAttr *A) { return true; }
+ static bool classof(const IBActionAttr *A) { return true; }
};
-DEF_SIMPLE_ATTR(Malloc);
-DEF_SIMPLE_ATTR(NoReturn);
DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
DEF_SIMPLE_ATTR(Final);
+DEF_SIMPLE_ATTR(GNUInline);
+DEF_SIMPLE_ATTR(Malloc);
+DEF_SIMPLE_ATTR(NoReturn);
class SectionAttr : public AttrWithString {
public:
@@ -353,6 +358,7 @@ DEF_SIMPLE_ATTR(Unused);
DEF_SIMPLE_ATTR(Used);
DEF_SIMPLE_ATTR(Weak);
DEF_SIMPLE_ATTR(WeakImport);
+DEF_SIMPLE_ATTR(WeakRef);
DEF_SIMPLE_ATTR(NoThrow);
DEF_SIMPLE_ATTR(Const);
DEF_SIMPLE_ATTR(Pure);
@@ -543,7 +549,9 @@ public:
};
// Checker-specific attributes.
+DEF_SIMPLE_ATTR(CFReturnsNotRetained);
DEF_SIMPLE_ATTR(CFReturnsRetained);
+DEF_SIMPLE_ATTR(NSReturnsNotRetained);
DEF_SIMPLE_ATTR(NSReturnsRetained);
// C++0x member checking attributes.
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 79a3022..c89e5e4 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -16,6 +16,7 @@
#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "llvm/ADT/SmallVector.h"
@@ -159,7 +160,11 @@ class CXXBasePaths {
friend class CXXRecordDecl;
void ComputeDeclsFound();
-
+
+ bool lookupInBases(ASTContext &Context,
+ const CXXRecordDecl *Record,
+ CXXRecordDecl::BaseMatchesCallback *BaseMatches,
+ void *UserData);
public:
typedef std::list<CXXBasePath>::iterator paths_iterator;
typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 93e41d3..1f459b0 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -120,6 +120,13 @@ public:
return Stored.isLocalRestrictQualified();
}
+ /// \brief Determines if this canonical type is furthermore
+ /// canonical as a parameter. The parameter-canonicalization
+ /// process decays arrays to pointers and drops top-level qualifiers.
+ bool isCanonicalAsParam() const {
+ return Stored.isCanonicalAsParam();
+ }
+
/// \brief Retrieve the unqualified form of this type.
CanQual<T> getUnqualifiedType() const;
@@ -157,6 +164,10 @@ public:
/// ensure that the given type is a canonical type with the correct
// (dynamic) type.
static CanQual<T> CreateUnsafe(QualType Other);
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddPointer(getAsOpaquePtr());
+ }
};
template<typename T, typename U>
@@ -172,6 +183,10 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) {
/// \brief Represents a canonical, potentially-qualified type.
typedef CanQual<Type> CanQualType;
+inline CanQualType Type::getCanonicalTypeUnqualified() const {
+ return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
+}
+
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
CanQualType T) {
DB << static_cast<QualType>(T);
@@ -547,18 +562,24 @@ struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
template<>
struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv)
};
template<>
struct CanProxyAdaptor<FunctionNoProtoType>
: public CanProxyBase<FunctionNoProtoType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv)
};
template<>
struct CanProxyAdaptor<FunctionProtoType>
: public CanProxyBase<FunctionProtoType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
CanQualType getArgType(unsigned i) const {
return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 0744289..91aeff3 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -267,8 +267,8 @@ public:
}
void setAnonymousNamespace(NamespaceDecl *D) {
- assert(D->isAnonymousNamespace());
- assert(D->getParent() == this);
+ assert(!D || D->isAnonymousNamespace());
+ assert(!D || D->getParent() == this);
AnonymousNamespace = D;
}
@@ -561,7 +561,7 @@ public:
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
- bool isOutOfLine() const;
+ virtual bool isOutOfLine() const;
/// \brief If this is a static data member, find its out-of-line definition.
VarDecl *getOutOfLineDefinition();
@@ -1306,7 +1306,7 @@ public:
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a member function.
- bool isOutOfLine() const;
+ virtual bool isOutOfLine() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index a407a16..7fb5f9d 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -279,7 +279,8 @@ public:
/// \brief Whether this declaration was used, meaning that a definition
/// is required.
- bool isUsed() const { return Used; }
+ bool isUsed() const;
+
void setUsed(bool U = true) { Used = U; }
/// \brief Retrieve the level of precompiled header from which this
@@ -330,7 +331,7 @@ public:
return const_cast<Decl*>(this)->getLexicalDeclContext();
}
- bool isOutOfLine() const {
+ virtual bool isOutOfLine() const {
return getLexicalDeclContext() != getDeclContext();
}
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 0978c6d..af00c8d 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -710,7 +710,7 @@ public:
CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
/// getDestructor - Returns the destructor decl for this class.
- CXXDestructorDecl *getDestructor(ASTContext &Context);
+ CXXDestructorDecl *getDestructor(ASTContext &Context) const;
/// isLocalClass - If the class is a local class [class.local], returns
/// the enclosing function declaration.
@@ -751,6 +751,21 @@ public:
/// tangling input and output in \p Paths
bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const;
+ /// \brief Determine whether this class is virtually derived from
+ /// the class \p Base.
+ ///
+ /// This routine only determines whether this class is virtually
+ /// derived from \p Base, but does not account for factors that may
+ /// make a Derived -> Base class ill-formed, such as
+ /// private/protected inheritance or multiple, ambiguous base class
+ /// subobjects.
+ ///
+ /// \param Base the base class we are searching for.
+ ///
+ /// \returns true if this class is virtually derived from Base,
+ /// false otherwise.
+ bool isVirtuallyDerivedFrom(CXXRecordDecl *Base) const;
+
/// \brief Determine whether this class is provably not derived from
/// the type \p Base.
bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
@@ -824,6 +839,18 @@ public:
/// base class that we are searching for.
static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, void *BaseRecord);
+
+ /// \brief Base-class lookup callback that determines whether the
+ /// given base class specifier refers to a specific class
+ /// declaration and describes virtual derivation.
+ ///
+ /// This callback can be used with \c lookupInBases() to determine
+ /// whether a given derived class has is a virtual base class
+ /// subobject of a particular type. The user data pointer should
+ /// refer to the canonical CXXRecordDecl of the base class that we
+ /// are searching for.
+ static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, void *BaseRecord);
/// \brief Base-class lookup callback that determines whether there exists
/// a tag with the given name.
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index e562d35..26656bf 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -494,11 +494,13 @@ public:
}
unsigned protocol_size() const { return ReferencedProtocols.size(); }
- typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator;
- ivar_iterator ivar_begin() const { return IVars.begin(); }
- ivar_iterator ivar_end() const { return IVars.end(); }
- unsigned ivar_size() const { return IVars.size(); }
- bool ivar_empty() const { return IVars.empty(); }
+ typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); }
+ ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); }
+ unsigned ivar_size() const {
+ return std::distance(ivar_begin(), ivar_end());
+ }
+ bool ivar_empty() const { return ivar_begin() == ivar_end(); }
/// setProtocolList - Set the list of protocols that this interface
/// implements.
@@ -514,10 +516,6 @@ public:
const SourceLocation *Locs,
ASTContext &C);
- void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) {
- IVars.set(List, Num, C);
- }
-
bool isForwardDecl() const { return ForwardDecl; }
void setForwardDecl(bool val) { ForwardDecl = val; }
@@ -529,6 +527,8 @@ public:
CategoryList = category;
}
+ ObjCCategoryDecl* getClassExtension() const;
+
/// isSuperClassOf - Return true if this class is the specified class or is a
/// super class of the specified interface class.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
@@ -951,6 +951,20 @@ public:
bool IsClassExtension() const { return getIdentifier() == 0; }
+ typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ ivar_iterator ivar_begin() const {
+ return ivar_iterator(decls_begin());
+ }
+ ivar_iterator ivar_end() const {
+ return ivar_iterator(decls_end());
+ }
+ unsigned ivar_size() const {
+ return std::distance(ivar_begin(), ivar_end());
+ }
+ bool ivar_empty() const {
+ return ivar_begin() == ivar_end();
+ }
+
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation At) { AtLoc = At; }
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 114a198..23076b9 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -150,7 +150,8 @@ public:
LV_InvalidExpression,
LV_MemberFunction,
LV_SubObjCPropertySetting,
- LV_SubObjCPropertyGetterSetting
+ LV_SubObjCPropertyGetterSetting,
+ LV_ClassTemporary
};
isLvalueResult isLvalue(ASTContext &Ctx) const;
@@ -181,7 +182,8 @@ public:
MLV_NoSetterProperty,
MLV_MemberFunction,
MLV_SubObjCPropertySetting,
- MLV_SubObjCPropertyGetterSetting
+ MLV_SubObjCPropertyGetterSetting,
+ MLV_ClassTemporary
};
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
SourceLocation *Loc = 0) const;
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index e4bc4b7..d1351b8 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -997,21 +997,59 @@ public:
virtual child_iterator child_end();
};
+/// \brief Structure used to store the type being destroyed by a
+/// pseudo-destructor expression.
+class PseudoDestructorTypeStorage {
+ /// \brief Either the type source information or the name of the type, if
+ /// it couldn't be resolved due to type-dependence.
+ llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
+
+ /// \brief The starting source location of the pseudo-destructor type.
+ SourceLocation Location;
+
+public:
+ PseudoDestructorTypeStorage() { }
+
+ PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
+ : Type(II), Location(Loc) { }
+
+ PseudoDestructorTypeStorage(TypeSourceInfo *Info);
+
+ TypeSourceInfo *getTypeSourceInfo() const {
+ return Type.dyn_cast<TypeSourceInfo *>();
+ }
+
+ IdentifierInfo *getIdentifier() const {
+ return Type.dyn_cast<IdentifierInfo *>();
+ }
+
+ SourceLocation getLocation() const { return Location; }
+};
+
/// \brief Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
///
-/// Example:
+/// A pseudo-destructor is an expression that looks like a member access to a
+/// destructor of a scalar type, except that scalar types don't have
+/// destructors. For example:
///
/// \code
+/// typedef int T;
+/// void f(int *p) {
+/// p->T::~T();
+/// }
+/// \endcode
+///
+/// Pseudo-destructors typically occur when instantiating templates such as:
+///
+/// \code
/// template<typename T>
/// void destroy(T* ptr) {
-/// ptr->~T();
+/// ptr->T::~T();
/// }
/// \endcode
///
-/// When the template is parsed, the expression \c ptr->~T will be stored as
-/// a member reference expression. If it then instantiated with a scalar type
-/// as a template argument for T, the resulting expression will be a
-/// pseudo-destructor expression.
+/// for scalar types. A pseudo-destructor expression has no run-time semantics
+/// beyond evaluating the base expression.
class CXXPseudoDestructorExpr : public Expr {
/// \brief The base expression (that is being destroyed).
Stmt *Base;
@@ -1030,28 +1068,44 @@ class CXXPseudoDestructorExpr : public Expr {
/// present.
SourceRange QualifierRange;
- /// \brief The type being destroyed.
- QualType DestroyedType;
-
- /// \brief The location of the type after the '~'.
- SourceLocation DestroyedTypeLoc;
+ /// \brief The type that precedes the '::' in a qualified pseudo-destructor
+ /// expression.
+ TypeSourceInfo *ScopeType;
+
+ /// \brief The location of the '::' in a qualified pseudo-destructor
+ /// expression.
+ SourceLocation ColonColonLoc;
+
+ /// \brief The location of the '~'.
+ SourceLocation TildeLoc;
+
+ /// \brief The type being destroyed, or its name if we were unable to
+ /// resolve the name.
+ PseudoDestructorTypeStorage DestroyedType;
public:
CXXPseudoDestructorExpr(ASTContext &Context,
Expr *Base, bool isArrow, SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- QualType DestroyedType,
- SourceLocation DestroyedTypeLoc)
+ TypeSourceInfo *ScopeType,
+ SourceLocation ColonColonLoc,
+ SourceLocation TildeLoc,
+ PseudoDestructorTypeStorage DestroyedType)
: Expr(CXXPseudoDestructorExprClass,
Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0,
- false, 0)),
- /*isTypeDependent=*/false,
+ false, 0, false,
+ false, 0, 0, false,
+ CC_Default)),
+ /*isTypeDependent=*/(Base->isTypeDependent() ||
+ (DestroyedType.getTypeSourceInfo() &&
+ DestroyedType.getTypeSourceInfo()->getType()->isDependentType())),
/*isValueDependent=*/Base->isValueDependent()),
Base(static_cast<Stmt *>(Base)), IsArrow(isArrow),
OperatorLoc(OperatorLoc), Qualifier(Qualifier),
- QualifierRange(QualifierRange), DestroyedType(DestroyedType),
- DestroyedTypeLoc(DestroyedTypeLoc) { }
+ QualifierRange(QualifierRange),
+ ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc),
+ DestroyedType(DestroyedType) { }
void setBase(Expr *E) { Base = E; }
Expr *getBase() const { return cast<Expr>(Base); }
@@ -1079,15 +1133,51 @@ public:
/// \brief Retrieve the location of the '.' or '->' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
- /// \brief Retrieve the type that is being destroyed.
- QualType getDestroyedType() const { return DestroyedType; }
-
- /// \brief Retrieve the location of the type being destroyed.
- SourceLocation getDestroyedTypeLoc() const { return DestroyedTypeLoc; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(Base->getLocStart(), DestroyedTypeLoc);
+ /// \brief Retrieve the scope type in a qualified pseudo-destructor
+ /// expression.
+ ///
+ /// Pseudo-destructor expressions can have extra qualification within them
+ /// that is not part of the nested-name-specifier, e.g., \c p->T::~T().
+ /// Here, if the object type of the expression is (or may be) a scalar type,
+ /// \p T may also be a scalar type and, therefore, cannot be part of a
+ /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
+ /// destructor expression.
+ TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
+
+ /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
+ /// expression.
+ SourceLocation getColonColonLoc() const { return ColonColonLoc; }
+
+ /// \brief Retrieve the location of the '~'.
+ SourceLocation getTildeLoc() const { return TildeLoc; }
+
+ /// \brief Retrieve the source location information for the type
+ /// being destroyed.
+ ///
+ /// This type-source information is available for non-dependent
+ /// pseudo-destructor expressions and some dependent pseudo-destructor
+ /// expressions. Returns NULL if we only have the identifier for a
+ /// dependent pseudo-destructor expression.
+ TypeSourceInfo *getDestroyedTypeInfo() const {
+ return DestroyedType.getTypeSourceInfo();
}
+
+ /// \brief In a dependent pseudo-destructor expression for which we do not
+ /// have full type information on the destroyed type, provides the name
+ /// of the destroyed type.
+ IdentifierInfo *getDestroyedTypeIdentifier() const {
+ return DestroyedType.getIdentifier();
+ }
+
+ /// \brief Retrieve the type being destroyed.
+ QualType getDestroyedType() const;
+
+ /// \brief Retrieve the starting location of the type being destroyed.
+ SourceLocation getDestroyedTypeLoc() const {
+ return DestroyedType.getLocation();
+ }
+
+ virtual SourceRange getSourceRange() const;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXPseudoDestructorExprClass;
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 40e5098..bd8a6bc 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -90,9 +90,13 @@ namespace clang {
class TemplateArgument;
class TemplateArgumentLoc;
class TemplateArgumentListInfo;
+ class Type;
class QualifiedNameType;
struct PrintingPolicy;
+ template <typename> class CanQual;
+ typedef CanQual<Type> CanQualType;
+
// Provide forward declarations for all of the *Type classes
#define TYPE(Class, Base) class Class##Type;
#include "clang/AST/TypeNodes.def"
@@ -976,7 +980,10 @@ public:
/// \brief Determine the linkage of this type.
virtual Linkage getLinkage() const;
- QualType getCanonicalTypeInternal() const { return CanonicalType; }
+ QualType getCanonicalTypeInternal() const {
+ return CanonicalType;
+ }
+ CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
void dump() const;
static bool classof(const Type *) { return true; }
};
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 9cf2cb7..8187cad 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -31,7 +31,11 @@
// type that is always dependent. Clients that do not need to deal
// with uninstantiated C++ templates can ignore these types.
//
-// There is a fifth macro, independent of the others. Most clients
+// NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
+// is non-canonical unless it is dependent. Defaults to TYPE because
+// it is neither reliably dependent nor reliably non-canonical.
+//
+// There is a sixth macro, independent of the others. Most clients
// will not need to use it.
//
// LEAF_TYPE(Class) - A type that never has inner types. Clients
@@ -51,6 +55,10 @@
# define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
#endif
+#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
+# define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
TYPE(Builtin, Type)
TYPE(Complex, Type)
TYPE(Pointer, Type)
@@ -72,16 +80,16 @@ TYPE(FunctionProto, FunctionType)
TYPE(FunctionNoProto, FunctionType)
DEPENDENT_TYPE(UnresolvedUsing, Type)
NON_CANONICAL_TYPE(Typedef, Type)
-NON_CANONICAL_TYPE(TypeOfExpr, Type)
-NON_CANONICAL_TYPE(TypeOf, Type)
-NON_CANONICAL_TYPE(Decltype, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
ABSTRACT_TYPE(Tag, Type)
TYPE(Record, TagType)
TYPE(Enum, TagType)
NON_CANONICAL_TYPE(Elaborated, Type)
DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
-TYPE(TemplateSpecialization, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
@@ -101,6 +109,7 @@ LEAF_TYPE(TemplateTypeParm)
#undef LEAF_TYPE
#endif
+#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
#undef DEPENDENT_TYPE
#undef NON_CANONICAL_TYPE
#undef ABSTRACT_TYPE
diff --git a/include/clang/Analysis/Analyses/PrintfFormatString.h b/include/clang/Analysis/Analyses/PrintfFormatString.h
index a4ad0b7..e4f7c57 100644
--- a/include/clang/Analysis/Analyses/PrintfFormatString.h
+++ b/include/clang/Analysis/Analyses/PrintfFormatString.h
@@ -75,11 +75,14 @@ public:
VoidPtrArg, // 'p'
OutIntPtrArg, // 'n'
PercentArg, // '%'
- // Objective-C specific specifiers.
+ // MacOS X unicode extensions.
+ CArg, // 'C'
+ UnicodeStrArg, // 'S'
+ // Objective-C specific specifiers.
ObjCObjArg, // '@'
- // GlibC specific specifiers.
+ // GlibC specific specifiers.
PrintErrno, // 'm'
- // Specifier ranges.
+ // Specifier ranges.
IntArgBeg = dArg,
IntArgEnd = iArg,
UIntArgBeg = oArg,
@@ -147,20 +150,27 @@ enum LengthModifier {
class OptionalAmount {
public:
- enum HowSpecified { NotSpecified, Constant, Arg };
+ enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
- OptionalAmount(HowSpecified h, const char *st)
- : start(st), hs(h), amt(0) {}
+ OptionalAmount(HowSpecified h, unsigned i, const char *st)
+ : start(st), hs(h), amt(i) {}
- OptionalAmount()
- : start(0), hs(NotSpecified), amt(0) {}
+ OptionalAmount(bool b = true)
+ : start(0), hs(b ? NotSpecified : Invalid), amt(0) {}
- OptionalAmount(unsigned i, const char *st)
- : start(st), hs(Constant), amt(i) {}
+ bool isInvalid() const {
+ return hs == Invalid;
+ }
HowSpecified getHowSpecified() const { return hs; }
+
bool hasDataArgument() const { return hs == Arg; }
+ unsigned getArgIndex() const {
+ assert(hasDataArgument());
+ return amt;
+ }
+
unsigned getConstantAmount() const {
assert(hs == Constant);
return amt;
@@ -185,14 +195,19 @@ class FormatSpecifier {
unsigned HasSpacePrefix : 1;
unsigned HasAlternativeForm : 1;
unsigned HasLeadingZeroes : 1;
- unsigned flags : 5;
+ /// Positional arguments, an IEEE extension:
+ /// IEEE Std 1003.1, 2004 Edition
+ /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
+ unsigned UsesPositionalArg : 1;
+ unsigned argIndex;
ConversionSpecifier CS;
OptionalAmount FieldWidth;
OptionalAmount Precision;
public:
FormatSpecifier() : LM(None),
IsLeftJustified(0), HasPlusPrefix(0), HasSpacePrefix(0),
- HasAlternativeForm(0), HasLeadingZeroes(0) {}
+ HasAlternativeForm(0), HasLeadingZeroes(0), UsesPositionalArg(0),
+ argIndex(0) {}
static FormatSpecifier Parse(const char *beg, const char *end);
@@ -208,6 +223,17 @@ public:
void setHasSpacePrefix() { HasSpacePrefix = 1; }
void setHasAlternativeForm() { HasAlternativeForm = 1; }
void setHasLeadingZeros() { HasLeadingZeroes = 1; }
+ void setUsesPositionalArg() { UsesPositionalArg = 1; }
+
+ void setArgIndex(unsigned i) {
+ assert(CS.consumesDataArgument());
+ argIndex = i;
+ }
+
+ unsigned getArgIndex() const {
+ assert(CS.consumesDataArgument());
+ return argIndex;
+ }
// Methods for querying the format specifier.
@@ -247,8 +273,11 @@ public:
bool hasAlternativeForm() const { return (bool) HasAlternativeForm; }
bool hasLeadingZeros() const { return (bool) HasLeadingZeroes; }
bool hasSpacePrefix() const { return (bool) HasSpacePrefix; }
+ bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
};
+enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
+
class FormatStringHandler {
public:
FormatStringHandler() {}
@@ -259,10 +288,15 @@ public:
virtual void HandleNullChar(const char *nullCharacter) {}
- virtual void
+ virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
+ PositionContext p) {}
+
+ virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
+
+ virtual bool
HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
const char *startSpecifier,
- unsigned specifierLen) {}
+ unsigned specifierLen) { return true; }
virtual bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
const char *startSpecifier,
diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h
new file mode 100644
index 0000000..e0c84f9
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ReachableCode.h
@@ -0,0 +1,55 @@
+//===- ReachableCode.h -----------------------------------------*- C++ --*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A flow-sensitive, path-insensitive analysis of unreachable code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REACHABLECODE_H
+#define LLVM_CLANG_REACHABLECODE_H
+
+#include "clang/Basic/SourceLocation.h"
+
+//===----------------------------------------------------------------------===//
+// Forward declarations.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+ class BitVector;
+}
+
+namespace clang {
+ class AnalysisContext;
+ class CFGBlock;
+}
+
+//===----------------------------------------------------------------------===//
+// API.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+namespace reachable_code {
+
+class Callback {
+public:
+ virtual ~Callback() {}
+ virtual void HandleUnreachable(SourceLocation L, SourceRange R1,
+ SourceRange R2) = 0;
+};
+
+/// ScanReachableFromBlock - Mark all blocks reachable from Start.
+/// Returns the total number of blocks that were marked reachable.
+unsigned ScanReachableFromBlock(const CFGBlock &Start,
+ llvm::BitVector &Reachable);
+
+void FindUnreachableCode(AnalysisContext &AC, Callback &CB);
+
+}} // end namespace clang::reachable_code
+
+#endif
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index ea4f5b2..bde4417 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -110,6 +110,8 @@ public:
const LocationContext *getParent() const { return Parent; }
+ bool isParentOf(const LocationContext *LC) const;
+
const Decl *getDecl() const { return getAnalysisContext()->getDecl(); }
CFG *getCFG() const { return getAnalysisContext()->getCFG(); }
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index e87784f..528cf87 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -245,8 +245,6 @@ public:
Stmt* getLabel() { return Label; }
const Stmt* getLabel() const { return Label; }
- void reverseStmts();
-
unsigned getBlockID() const { return BlockID; }
void dump(const CFG *cfg, const LangOptions &LO) const;
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 332f9d3..fb8d4d5 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -26,6 +26,7 @@
namespace clang {
class LocationContext;
+class FunctionDecl;
class ProgramPoint {
public:
@@ -41,6 +42,8 @@ public:
PostPurgeDeadSymbolsKind,
PostStmtCustomKind,
PostLValueKind,
+ CallEnterKind,
+ CallExitKind,
MinPostStmtKind = PostStmtKind,
MaxPostStmtKind = PostLValueKind };
@@ -308,6 +311,36 @@ public:
}
};
+class CallEnter : public StmtPoint {
+public:
+ // CallEnter uses the caller's location context.
+ CallEnter(const Stmt *S, const FunctionDecl *fd, const LocationContext *L)
+ : StmtPoint(S, fd, CallEnterKind, L, 0) {}
+
+ const Stmt *getCallExpr() const {
+ return static_cast<const Stmt *>(getData1());
+ }
+
+ const FunctionDecl *getCallee() const {
+ return static_cast<const FunctionDecl *>(getData2());
+ }
+
+ static bool classof(const ProgramPoint *Location) {
+ return Location->getKind() == CallEnterKind;
+ }
+};
+
+class CallExit : public StmtPoint {
+public:
+ // CallExit uses the callee's location context.
+ CallExit(const Stmt *S, const LocationContext *L)
+ : StmtPoint(S, 0, CallExitKind, L, 0) {}
+
+ static bool classof(const ProgramPoint *Location) {
+ return Location->getKind() == CallExitKind;
+ }
+};
+
} // end namespace clang
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index 48851d0..c6c9eed 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -23,6 +23,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/PointerIntPair.h"
#include <algorithm>
+#include <cstring>
namespace clang {
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 3251ec4..9442ac3 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -317,7 +317,7 @@ BUILTIN(__builtin_frob_return_addr, "v*v*", "n")
BUILTIN(__builtin_dwarf_cfa, "v*", "n")
BUILTIN(__builtin_init_dwarf_reg_size_table, "vv*", "n")
BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
-BUILTIN(__builtin_extend_pointer, "iv*", "n")
+BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
// GCC Object size checking builtins
BUILTIN(__builtin_object_size, "zv*i", "n")
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index d2516f8..d6c8797 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -403,13 +403,6 @@ public:
/// \brief Clear out the current diagnostic.
void Clear() { CurDiagID = ~0U; }
- /// Deserialize - Deserialize the first diagnostic within the memory
- /// [Memory, MemoryEnd), producing a new diagnostic builder describing the
- /// deserialized diagnostic. If the memory does not contain a
- /// diagnostic, returns a diagnostic builder with no diagnostic ID.
- DiagnosticBuilder Deserialize(FileManager &FM, SourceManager &SM,
- const char *&Memory, const char *MemoryEnd);
-
private:
/// getDiagnosticMappingInfo - Return the mapping info currently set for the
/// specified builtin diagnostic. This returns the high bit encoding, or zero
@@ -799,12 +792,54 @@ public:
/// output buffer using the arguments stored in this diagnostic.
void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
llvm::SmallVectorImpl<char> &OutStr) const;
+};
+
+/**
+ * \brief Represents a diagnostic in a form that can be serialized and
+ * deserialized.
+ */
+class StoredDiagnostic {
+ Diagnostic::Level Level;
+ FullSourceLoc Loc;
+ std::string Message;
+ std::vector<SourceRange> Ranges;
+ std::vector<CodeModificationHint> FixIts;
+
+public:
+ StoredDiagnostic();
+ StoredDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info);
+ StoredDiagnostic(Diagnostic::Level Level, llvm::StringRef Message);
+ ~StoredDiagnostic();
+
+ /// \brief Evaluates true when this object stores a diagnostic.
+ operator bool() const { return Message.size() > 0; }
+
+ Diagnostic::Level getLevel() const { return Level; }
+ const FullSourceLoc &getLocation() const { return Loc; }
+ llvm::StringRef getMessage() const { return Message; }
+
+ typedef std::vector<SourceRange>::const_iterator range_iterator;
+ range_iterator range_begin() const { return Ranges.begin(); }
+ range_iterator range_end() const { return Ranges.end(); }
+ unsigned range_size() const { return Ranges.size(); }
+
+ typedef std::vector<CodeModificationHint>::const_iterator fixit_iterator;
+ fixit_iterator fixit_begin() const { return FixIts.begin(); }
+ fixit_iterator fixit_end() const { return FixIts.end(); }
+ unsigned fixit_size() const { return FixIts.size(); }
/// Serialize - Serialize the given diagnostic (with its diagnostic
/// level) to the given stream. Serialization is a lossy operation,
/// since the specific diagnostic ID and any macro-instantiation
/// information is lost.
- void Serialize(Diagnostic::Level DiagLevel, llvm::raw_ostream &OS) const;
+ void Serialize(llvm::raw_ostream &OS) const;
+
+ /// Deserialize - Deserialize the first diagnostic within the memory
+ /// [Memory, MemoryEnd), producing a new diagnostic builder describing the
+ /// deserialized diagnostic. If the memory does not contain a
+ /// diagnostic, returns a diagnostic builder with no diagnostic ID.
+ static StoredDiagnostic Deserialize(FileManager &FM, SourceManager &SM,
+ const char *&Memory, const char *MemoryEnd);
};
/// DiagnosticClient - This is an abstract interface implemented by clients of
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index b6c2b13..cc89c7c 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -53,6 +53,29 @@ def note_odr_number_of_bases : Note<
"class has %0 base %plural{1:class|:classes}0">;
def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
-
+def err_odr_ivar_type_inconsistent : Error<
+ "instance variable %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">;
+def err_odr_objc_superclass_inconsistent : Error<
+ "class %0 has incompatible superclasses">;
+def note_odr_objc_superclass : Note<"inherits from superclass %0 here">;
+def note_odr_objc_missing_superclass : Note<"no corresponding superclass here">;
+def err_odr_objc_method_result_type_inconsistent : Error<
+ "%select{class|instance}0 method %1 has incompatible result types in "
+ "different translation units (%2 vs. %3)">;
+def err_odr_objc_method_num_params_inconsistent : Error<
+ "%select{class|instance}0 method %1 has a different number of parameters in "
+ "different translation units (%2 vs. %3)">;
+def err_odr_objc_method_param_type_inconsistent : Error<
+ "%select{class|instance}0 method %1 has a parameter with a different types "
+ "in different translation units (%2 vs. %3)">;
+def err_odr_objc_method_variadic_inconsistent : Error<
+ "%select{class|instance}0 method %1 is variadic in one translation unit "
+ "and not variadic in another">;
+def note_odr_objc_method_here : Note<
+ "%select{class|instance}0 method %1 also declared here">;
+def err_odr_objc_property_type_inconsistent : Error<
+ "property %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">;
def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
}
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index dc5ccfd..9175bef 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -88,6 +88,8 @@ def warn_ignoring_ftabstop_value : Warning<
def warn_drv_missing_resource_library : Warning<
"missing resource library '%0', link may fail">;
def warn_drv_conflicting_deployment_targets : Warning<
- "conflicting deployment targets, both MACOSX_DEPLOYMENT_TARGET '%0' and IPHONEOS_DEPLOYMENT_TARGET '%1' are present in environment">;
+ "conflicting deployment targets, both MACOSX_DEPLOYMENT_TARGET '%0' and IPHONEOS_DEPLOYMENT_TARGET '%1' are present in environment">;
+def warn_drv_treating_input_as_cxx : Warning<
+ "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">;
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 79147ea..b77614b 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -82,7 +82,7 @@ def note_fixit_main_file_unchanged : Note<
def warn_fixit_no_changes : Note<
"FIX-IT detected errors it could not fix; no output will be generated">;
-def err_fe_clang : Error<"error invoking%s: %s">, DefaultFatal;
+def err_fe_invoking : Error<"error invoking%0: %1">, DefaultFatal;
// PCH reader
def err_relocatable_without_without_isysroot : Error<
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 82f9eca..c3c0cf5 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -18,11 +18,13 @@ def Implicit : DiagGroup<"implicit", [
-// Empty DiagGroups: these are recognized by clang but ignored.
+// Empty DiagGroups are recognized by clang but ignored.
def : DiagGroup<"address">;
+def AddressOfTemporary : DiagGroup<"address-of-temporary">;
def : DiagGroup<"aggregate-return">;
def : DiagGroup<"attributes">;
def : DiagGroup<"bad-function-cast">;
+def BadLiteral : DiagGroup<"bad-literal">;
def : DiagGroup<"c++-compat">;
def : DiagGroup<"cast-align">;
def : DiagGroup<"cast-qual">;
@@ -119,7 +121,6 @@ def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def : DiagGroup<"write-strings">;
def CharSubscript : DiagGroup<"char-subscripts">;
-def ForceAlignArgPointer : DiagGroup<"force-align-arg-pointer">;
// Aggregation warning settings.
@@ -180,4 +181,4 @@ def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
// A warning group for warnings that we want to have on by default in clang,
// but which aren't on by default in GCC.
def NonGCC : DiagGroup<"non-gcc",
- [SignCompare, Conversion, ForceAlignArgPointer]>;
+ [SignCompare, Conversion, BadLiteral]>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index bc26c3b..fb80dcc 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -146,8 +146,6 @@ def err_missing_comma_before_ellipsis : Error<
def err_unexpected_typedef_ident : Error<
"unexpected type name %0: expected identifier">;
def err_expected_class_name : Error<"expected class name">;
-def err_destructor_class_name : Error<
- "expected the class name after '~' to name a destructor">;
def err_unspecified_vla_size_with_static : Error<
"'static' may not be used with an unspecified variable length array size">;
@@ -247,8 +245,10 @@ def err_expected_catch : Error<"expected catch">;
def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
def err_using_namespace_in_class : Error<
"'using namespace' is not allowed in classes">;
-def err_ident_in_pseudo_dtor_not_a_type : Error<
- "identifier %0 in pseudo-destructor expression does not name a type">;
+def err_destructor_tilde_identifier : Error<
+ "expected a class name after '~' to name a destructor">;
+def err_destructor_template_id : Error<
+ "destructor name %0 does not refer to a template">;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -300,6 +300,7 @@ def err_explicit_instantiation_with_definition : Error<
"explicit template instantiation cannot have a definition; if this "
"definition is meant to be an explicit specialization, add '<>' after the "
"'template' keyword">;
+def err_enum_template : Error<"enumeration cannot be a template">;
// Constructor template diagnostics.
def err_out_of_line_constructor_template_id : Error<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 19b242e..9f77655 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -29,10 +29,12 @@ def ext_null_pointer_expr_not_ice : Extension<
// Semantic analysis of constant literals.
def ext_predef_outside_function : Warning<
"predefined identifier is only valid inside function">;
-def err_float_overflow : Error<
- "magnitude of floating-point constant too large for type %0; maximum is %1">;
-def err_float_underflow : Error<
- "magnitude of floating-point constant too small for type %0; minimum is %1">;
+def warn_float_overflow : Warning<
+ "magnitude of floating-point constant too large for type %0; maximum is %1">,
+ InGroup<BadLiteral>;
+def warn_float_underflow : Warning<
+ "magnitude of floating-point constant too small for type %0; minimum is %1">,
+ InGroup<BadLiteral>;
// C99 Designated Initializers
def err_array_designator_negative : Error<
@@ -253,6 +255,12 @@ def err_dup_implementation_category : Error<
"reimplementation of category %1 for class %0">;
def err_conflicting_ivar_type : Error<
"instance variable %0 has conflicting type: %1 vs %2">;
+def err_duplicate_ivar_declaration : Error<
+ "instance variable is already declared">;
+def warn_on_superclass_use : Warning<
+ "class implementation may not have super class">;
+def err_non_private_ivar_declaration : Error<
+ "only private ivars may be declared in implementation">;
def err_conflicting_ivar_bitwidth : Error<
"instance variable %0 has conflicting bit-field width">;
def err_conflicting_ivar_name : Error<
@@ -447,6 +455,8 @@ def err_qualified_member_nonclass : Error<
"qualified member access refers to a member in %0">;
def err_incomplete_member_access : Error<
"member access into incomplete type %0">;
+def err_incomplete_type : Error<
+ "incomplete type %0 where a complete type is required">;
// C++ class members
def err_storageclass_invalid_for_member : Error<
@@ -486,8 +496,7 @@ def err_implicit_object_parameter_init : Error<
def note_field_decl : Note<"member is declared here">;
def note_bitfield_decl : Note<"bit-field is declared here">;
-def note_previous_decl : Note<
- "%0 declared here">;
+def note_previous_decl : Note<"%0 declared here">;
def note_member_synthesized_at : Note<
"implicit default %select{constructor|copy constructor|"
"copy assignment operator|destructor}0 for %1 first required here">;
@@ -557,6 +566,10 @@ def err_destructor_typedef_name : Error<
"destructor cannot be declared using a typedef %0 of the class name">;
def err_destructor_name : Error<
"expected the class name after '~' to name the enclosing class">;
+def err_destructor_class_name : Error<
+ "expected the class name after '~' to name a destructor">;
+def err_ident_in_pseudo_dtor_not_a_type : Error<
+ "identifier %0 in pseudo-destructor expression does not name a type">;
// C++ initialization
def err_init_conversion_failed : Error<
@@ -724,9 +737,6 @@ def err_attribute_aligned_not_power_of_two : Error<
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
"'%0' redeclared without %1 attribute: previous %1 ignored">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
-def warn_faap_attribute_ignored : Warning<
- "force_align_arg_pointer used on function pointer; attribute ignored">,
- InGroup<ForceAlignArgPointer>;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">;
def warn_attribute_void_function : Warning<
@@ -741,6 +751,12 @@ def err_attribute_weak_static : Error<
"weak declaration of '%0' must be public">;
def warn_attribute_weak_import_invalid_on_definition : Warning<
"'weak_import' attribute cannot be specified on a definition">;
+def err_attribute_weakref_not_static : Error<
+ "weakref declaration of '%0' must be static">;
+def err_attribute_weakref_not_global_context : Error<
+ "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">;
def warn_attribute_wrong_decl_type : Warning<
"%0 attribute only applies to %select{function|union|"
"variable and function|function or method|parameter|"
@@ -846,8 +862,10 @@ def err_attribute_regparm_invalid_number : Error<
// Clang-Specific Attributes
def err_attribute_iboutlet : Error<
- "'iboutlet' attribute can only be applied to instance variables or "
+ "iboutlet attribute can only be applied to instance variables or "
"properties">;
+def err_attribute_ibaction: Error<
+ "ibaction attribute can only be applied to Objective-C instance methods">;
def err_attribute_overloadable_not_function : Error<
"'overloadable' attribute can only be applied to a function">;
def err_attribute_overloadable_missing : Error<
@@ -1482,6 +1500,8 @@ def err_forward_ref_enum : Error<
"ISO C++ forbids forward references to 'enum' types">;
def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
def err_duplicate_member : Error<"duplicate member %0">;
+def err_misplaced_ivar : Error<"ivar may be placed in a class extension "
+ "in non-fragile-abi2 mode only">;
def ext_enum_value_not_int : Extension<
"ISO C restricts enumerator values to range of 'int' (%0 is too "
"%select{small|large}1)">;
@@ -1572,6 +1592,8 @@ def err_indirect_goto_in_protected_scope : Error<
def err_addr_of_label_in_protected_scope : Error<
"address taken of label in protected scope, jump to it would have "
"unknown effect on scope">;
+def note_protected_by_variable_init : Note<
+ "jump bypasses variable initialization">;
def note_protected_by_vla_typedef : Note<
"jump bypasses initialization of VLA typedef">;
def note_protected_by_vla : Note<
@@ -1761,7 +1783,8 @@ def err_typecheck_incomplete_array_needs_initializer : Error<
def err_array_init_not_init_list : Error<
"array initializer must be an initializer "
"list%select{| or string literal}0">;
-
+def warn_deprecated_string_literal_conversion : Warning<
+ "conversion from string literal to %0 is deprecated">;
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">;
@@ -1777,6 +1800,11 @@ def err_unqualified_pointer_member_function : Error<
"must explicitly qualify member function %0 when taking its address">;
def err_typecheck_invalid_lvalue_addrof : Error<
"address expression must be an lvalue or a function designator">;
+def ext_typecheck_addrof_class_temporary : ExtWarn<
+ "taking the address of a temporary object of type %0">,
+ InGroup<DiagGroup<"address-of-temporary">>, DefaultError;
+def err_typecheck_addrof_class_temporary : Error<
+ "taking the address of a temporary object of type %0">;
def err_typecheck_unary_expr : Error<
"invalid argument type %0 to unary expression">;
def err_typecheck_indirection_requires_pointer : Error<
@@ -1807,6 +1835,9 @@ def ext_typecheck_cond_incompatible_operands : ExtWarn<
"incompatible operand types (%0 and %1)">;
def err_typecheck_comparison_of_distinct_pointers : Error<
"comparison of distinct pointer types (%0 and %1)">;
+def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn<
+ "comparison of distinct pointer types (%0 and %1) uses non-standard "
+ "composite pointer type %2">;
def err_typecheck_vector_comparison : Error<
"comparison of vector types (%0 and %1) not supported yet">;
def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
@@ -1992,6 +2023,9 @@ def err_new_array_nonconst : Error<
"only the first dimension of an allocated array may have dynamic size">;
def err_new_paren_array_nonconst : Error<
"when type is in parentheses, array cannot have dynamic size">;
+def err_placement_new_non_placement_delete : Error<
+ "'new' expression with placement arguments refers to non-placement "
+ "'operator delete'">;
def err_array_size_not_integral : Error<
"array size expression must have integral or enumerated type, not %0">;
def err_default_init_const : Error<
@@ -2057,7 +2091,12 @@ def err_pseudo_dtor_call_with_args : Error<
def err_dtor_expr_without_call : Error<
"%select{destructor reference|pseudo-destructor expression}0 must be "
"called immediately with '()'">;
-
+def err_pseudo_dtor_destructor_non_type : Error<
+ "%0 does not refer to a type name in pseudo-destructor expression; expected "
+ "the name of type %1">;
+def err_pseudo_dtor_template : Error<
+ "specialization of template %0 does not refer to a scalar type in pseudo-"
+ "destructor expression">;
def err_invalid_use_of_function_type : Error<
"a function type is not allowed here">;
def err_invalid_use_of_array_type : Error<"an array type is not allowed here">;
@@ -2226,6 +2265,9 @@ def err_typecheck_expect_scalar_operand : Error<
"operand of type %0 where arithmetic or pointer type is required">;
def err_typecheck_cond_incompatible_operands : Error<
"incompatible operand types (%0 and %1)">;
+def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn<
+ "incompatible operand types (%0 and %1) use non-standard composite pointer "
+ "type %2">;
def err_cast_selector_expr : Error<
"cannot type cast @selector expression">;
def warn_typecheck_cond_incompatible_pointers : ExtWarn<
@@ -2486,8 +2528,8 @@ def warn_printf_write_back : Warning<
InGroup<FormatSecurity>;
def warn_printf_insufficient_data_args : Warning<
"more '%%' conversions than data arguments">, InGroup<Format>;
-def warn_printf_too_many_data_args : Warning<
- "more data arguments than format specifiers">, InGroup<FormatExtraArgs>;
+def warn_printf_data_arg_not_used : Warning<
+ "data argument not used by format string">, InGroup<FormatExtraArgs>;
def warn_printf_invalid_conversion : Warning<
"invalid conversion specifier '%0'">, InGroup<Format>;
def warn_printf_incomplete_specifier : Warning<
@@ -2497,6 +2539,15 @@ def warn_printf_missing_format_string : Warning<
def warn_printf_conversion_argument_type_mismatch : Warning<
"conversion specifies type %0 but the argument has type %1">,
InGroup<Format>;
+def warn_printf_zero_positional_specifier : Warning<
+ "position arguments in format strings start counting at 1 (not 0)">,
+ InGroup<Format>;
+def warn_printf_invalid_positional_specifier : Warning<
+ "invalid position specified for %select{field width|field precision}0">,
+ InGroup<Format>;
+def warn_printf_mix_positional_nonpositional_args : Warning<
+ "cannot mix positional and non-positional arguments in format string">,
+ InGroup<Format>;
def warn_null_arg : Warning<
"null passed to a callee which requires a non-null argument">,
InGroup<NonNull>;
@@ -2506,15 +2557,10 @@ def warn_printf_format_string_is_wide_literal : Warning<
"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_asterisk_width_missing_arg : Warning<
- "'*' specified field width is missing a matching 'int' argument">;
-def warn_printf_asterisk_precision_missing_arg : Warning<
- "'.*' specified field precision is missing a matching 'int' argument">;
-def warn_printf_asterisk_width_wrong_type : Warning<
- "field width should have type %0, but argument has type %1">,
- InGroup<Format>;
-def warn_printf_asterisk_precision_wrong_type : Warning<
- "field precision should have type %0, but argument has type %1">,
+def warn_printf_asterisk_missing_arg : Warning<
+ "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">;
+def warn_printf_asterisk_wrong_type : Warning<
+ "field %select{width|precision}0 should have type %1, but argument has type %2">,
InGroup<Format>;
def warn_printf_nonsensical_precision: Warning<
"precision used in '%0' conversion specifier (where it has no meaning)">,
@@ -2571,7 +2617,8 @@ def err_case_not_in_switch : Error<"'case' statement not in switch statement">;
def warn_bool_switch_condition : Warning<
"switch condition is a bool">;
def warn_case_value_overflow : Warning<
- "overflow converting case value to switch condition type (%0 to %1)">;
+ "overflow converting case value to switch condition type (%0 to %1)">,
+ InGroup<DiagGroup<"switch">>;
def err_duplicate_case : Error<"duplicate case value '%0'">;
def warn_case_empty_range : Warning<"empty case range specified">;
def warn_missing_cases : Warning<"enumeration value %0 not handled in switch">,
@@ -2695,6 +2742,8 @@ def ext_c99_array_usage : Extension<
def err_c99_array_usage_cxx : Error<
"C99-specific array features are not permitted in C++">;
+def note_getter_unavailable : Note<
+ "or because setter is declared here, but no getter method %0 is found">;
def err_invalid_protocol_qualifiers : Error<
"invalid protocol qualifiers on non-ObjC type">;
def warn_ivar_use_hidden : Warning<
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index d909f83..23e6efe 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -59,7 +59,6 @@ public:
unsigned POSIXThreads : 1; // Compiling with POSIX thread support
// (-pthread)
unsigned Blocks : 1; // block extension to C
- unsigned BlockIntrospection: 1; // block have ObjC type encodings.
unsigned EmitAllDecls : 1; // Emit all declarations, even if
// they are unused.
unsigned MathErrno : 1; // Math functions must respect errno
@@ -143,7 +142,6 @@ public:
ThreadsafeStatics = 1;
POSIXThreads = 0;
Blocks = 0;
- BlockIntrospection = 0;
EmitAllDecls = 0;
MathErrno = 1;
@@ -156,7 +154,7 @@ public:
OverflowChecking = 0;
ObjCGCBitmapPrint = 0;
- InstantiationDepth = 99;
+ InstantiationDepth = 500;
Optimize = 0;
OptimizeSize = 0;
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index 9b50e8d..2019e27 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -38,6 +38,13 @@ inline void Emit16(llvm::raw_ostream& Out, uint32_t V) {
assert((V >> 16) == 0);
}
+inline void Emit24(llvm::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(llvm::raw_ostream& Out, uint32_t V) {
Out << (unsigned char)(V);
Out << (unsigned char)(V >> 8);
diff --git a/include/clang/Checker/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h
index d498044..2401a72 100644
--- a/include/clang/Checker/PathSensitive/Checker.h
+++ b/include/clang/Checker/PathSensitive/Checker.h
@@ -147,12 +147,22 @@ public:
void addTransition(const GRState *state) {
assert(state);
+ // If the 'state' is not new, we need to check if the cached state 'ST'
+ // is new.
if (state != getState() || (ST && ST != B.GetState(Pred)))
GenerateNode(state, true);
else
Dst.Add(Pred);
}
+ // Generate a node with a new program point different from the one that will
+ // be created by the GRStmtNodeBuilder.
+ void addTransition(const GRState *state, ProgramPoint Loc) {
+ ExplodedNode *N = B.generateNode(Loc, state, Pred);
+ if (N)
+ addTransition(N);
+ }
+
void EmitReport(BugReport *R) {
Eng.getBugReporter().EmitReport(R);
}
diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h
index 6da4581..c5bf513 100644
--- a/include/clang/Checker/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h
@@ -40,6 +40,8 @@ class GRCoreEngine {
friend class GRIndirectGotoNodeBuilder;
friend class GRSwitchNodeBuilder;
friend class GREndPathNodeBuilder;
+ friend class GRCallEnterNodeBuilder;
+ friend class GRCallExitNodeBuilder;
GRSubEngine& SubEngine;
@@ -67,6 +69,9 @@ class GRCoreEngine {
void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
ExplodedNode* Pred);
+ void HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
+ unsigned Index, ExplodedNode *Pred);
+ void HandleCallExit(const CallExit &L, ExplodedNode *Pred);
/// Get the initial state from the subengine.
const GRState* getInitialState(const LocationContext *InitLoc) {
@@ -90,6 +95,9 @@ class GRCoreEngine {
void ProcessSwitch(GRSwitchNodeBuilder& Builder);
+ void ProcessCallEnter(GRCallEnterNodeBuilder &Builder);
+ void ProcessCallExit(GRCallExitNodeBuilder &Builder);
+
private:
GRCoreEngine(const GRCoreEngine&); // Do not implement.
GRCoreEngine& operator=(const GRCoreEngine&);
@@ -130,7 +138,6 @@ class GRStmtNodeBuilder {
CFGBlock& B;
const unsigned Idx;
ExplodedNode* Pred;
- ExplodedNode* LastNode;
GRStateManager& Mgr;
GRAuditor* Auditor;
@@ -157,10 +164,6 @@ public:
ExplodedNode* getBasePredecessor() const { return Pred; }
- ExplodedNode* getLastNode() const {
- return LastNode ? (LastNode->isSink() ? NULL : LastNode) : NULL;
- }
-
// FIXME: This should not be exposed.
GRWorkList *getWorkList() { return Eng.WList; }
@@ -194,6 +197,12 @@ public:
return generateNode(S, St, Pred, PointKind);
}
+ ExplodedNode *generateNode(const ProgramPoint &PP, const GRState* State,
+ ExplodedNode* Pred) {
+ HasGeneratedNode = true;
+ return generateNodeInternal(PP, State, Pred);
+ }
+
ExplodedNode*
generateNodeInternal(const ProgramPoint &PP, const GRState* State,
ExplodedNode* Pred);
@@ -431,6 +440,8 @@ public:
ExplodedNode* generateNode(const GRState* State, const void *tag = 0,
ExplodedNode *P = 0);
+ void GenerateCallExitNode(const GRState *state);
+
CFGBlock* getBlock() const { return &B; }
const GRState* getState() const {
@@ -438,6 +449,60 @@ public:
}
};
+class GRCallEnterNodeBuilder {
+ GRCoreEngine &Eng;
+
+ const ExplodedNode *Pred;
+
+ // The call site.
+ const Stmt *CE;
+
+ // The definition of callee.
+ const FunctionDecl *FD;
+
+ // The parent block of the CallExpr.
+ const CFGBlock *Block;
+
+ // The CFGBlock index of the CallExpr.
+ unsigned Index;
+
+public:
+ GRCallEnterNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred,
+ const Stmt *s, const FunctionDecl *fd,
+ const CFGBlock *blk, unsigned idx)
+ : Eng(eng), Pred(pred), CE(s), FD(fd), Block(blk), Index(idx) {}
+
+ const GRState *getState() const { return Pred->getState(); }
+
+ const LocationContext *getLocationContext() const {
+ return Pred->getLocationContext();
+ }
+
+ const Stmt *getCallExpr() const { return CE; }
+
+ const FunctionDecl *getCallee() const { return FD; }
+
+ const CFGBlock *getBlock() const { return Block; }
+
+ unsigned getIndex() const { return Index; }
+
+ void GenerateNode(const GRState *state, const LocationContext *LocCtx);
+};
+
+class GRCallExitNodeBuilder {
+ GRCoreEngine &Eng;
+ const ExplodedNode *Pred;
+
+public:
+ GRCallExitNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred)
+ : Eng(eng), Pred(pred) {}
+
+ const ExplodedNode *getPredecessor() const { return Pred; }
+
+ const GRState *getState() const { return Pred->getState(); }
+
+ void GenerateNode(const GRState *state);
+};
} // end clang namespace
#endif
diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h
index 90a2cd5..763bbcc 100644
--- a/include/clang/Checker/PathSensitive/GRExprEngine.h
+++ b/include/clang/Checker/PathSensitive/GRExprEngine.h
@@ -171,7 +171,13 @@ public:
/// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
/// nodes when the control reaches the end of a function.
void ProcessEndPath(GREndPathNodeBuilder& builder);
-
+
+ // Generate the entry node of the callee.
+ void ProcessCallEnter(GRCallEnterNodeBuilder &builder);
+
+ // Generate the first post callsite node.
+ void ProcessCallExit(GRCallExitNodeBuilder &builder);
+
/// EvalAssume - Callback function invoked by the ConstraintManager when
/// making assumptions about state values.
const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption);
diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h
index 4e44697..9194ee8 100644
--- a/include/clang/Checker/PathSensitive/GRState.h
+++ b/include/clang/Checker/PathSensitive/GRState.h
@@ -16,25 +16,24 @@
// FIXME: Reduce the number of includes.
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Checker/PathSensitive/ConstraintManager.h"
#include "clang/Checker/PathSensitive/Environment.h"
+#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/Store.h"
-#include "clang/Checker/PathSensitive/ConstraintManager.h"
#include "clang/Checker/PathSensitive/ValueManager.h"
-#include "clang/Checker/PathSensitive/GRCoreEngine.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/System/DataTypes.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
-
+#include "llvm/System/DataTypes.h"
#include <functional>
namespace clang {
@@ -77,16 +76,13 @@ public:
typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
private:
- void operator=(const GRState& R) const;
+ void operator=(const GRState& R) const; // Do not implement.
friend class GRStateManager;
GRStateManager *StateMgr;
Environment Env;
Store St;
-
- // FIXME: Make these private.
-public:
GenericDataMap GDM;
public:
diff --git a/include/clang/Checker/PathSensitive/GRSubEngine.h b/include/clang/Checker/PathSensitive/GRSubEngine.h
index ce57c2c..f2cd048 100644
--- a/include/clang/Checker/PathSensitive/GRSubEngine.h
+++ b/include/clang/Checker/PathSensitive/GRSubEngine.h
@@ -28,6 +28,8 @@ class GRBranchNodeBuilder;
class GRIndirectGotoNodeBuilder;
class GRSwitchNodeBuilder;
class GREndPathNodeBuilder;
+class GRCallEnterNodeBuilder;
+class GRCallExitNodeBuilder;
class LocationContext;
class GRSubEngine {
@@ -64,6 +66,12 @@ public:
/// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
/// nodes when the control reaches the end of a function.
virtual void ProcessEndPath(GREndPathNodeBuilder& builder) = 0;
+
+ // Generate the entry node of the callee.
+ virtual void ProcessCallEnter(GRCallEnterNodeBuilder &builder) = 0;
+
+ // Generate the first post callsite node.
+ virtual void ProcessCallExit(GRCallExitNodeBuilder &builder) = 0;
/// EvalAssume - Called by ConstraintManager. Used to call checker-specific
/// logic for handling assumptions on symbolic values.
diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h
index 12bc0b7..be89d2a 100644
--- a/include/clang/Checker/PathSensitive/MemRegion.h
+++ b/include/clang/Checker/PathSensitive/MemRegion.h
@@ -428,7 +428,6 @@ public:
/// which correspond to "code+data". The distinction is important, because
/// like a closure a block captures the values of externally referenced
/// variables.
-/// BlockDataRegion - A region that represents code texts of blocks (closures).
class BlockDataRegion : public SubRegion {
friend class MemRegionManager;
const BlockTextRegion *BC;
@@ -798,11 +797,10 @@ class MemRegionManager {
GlobalsSpaceRegion *globals;
- const StackFrameContext *cachedStackLocalsFrame;
- StackLocalsSpaceRegion *cachedStackLocalsRegion;
-
- const StackFrameContext *cachedStackArgumentsFrame;
- StackArgumentsSpaceRegion *cachedStackArgumentsRegion;
+ llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
+ StackLocalsSpaceRegions;
+ llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
+ StackArgumentsSpaceRegions;
HeapSpaceRegion *heap;
UnknownSpaceRegion *unknown;
@@ -810,10 +808,7 @@ class MemRegionManager {
public:
MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
- : C(c), A(a), globals(0),
- cachedStackLocalsFrame(0), cachedStackLocalsRegion(0),
- cachedStackArgumentsFrame(0), cachedStackArgumentsRegion(0),
- heap(0), unknown(0), code(0) {}
+ : C(c), A(a), globals(0), heap(0), unknown(0), code(0) {}
~MemRegionManager();
diff --git a/include/clang/Checker/PathSensitive/SymbolManager.h b/include/clang/Checker/PathSensitive/SymbolManager.h
index 8eb3196..d49f5e8 100644
--- a/include/clang/Checker/PathSensitive/SymbolManager.h
+++ b/include/clang/Checker/PathSensitive/SymbolManager.h
@@ -89,27 +89,23 @@ public:
typedef const SymbolData* SymbolRef;
+// A symbol representing the value of a MemRegion.
class SymbolRegionValue : public SymbolData {
- const MemRegion *R;
- // We may cast the region to another type, so the expected type of the symbol
- // may be different from the region's original type.
- QualType T;
+ const TypedRegion *R;
public:
- SymbolRegionValue(SymbolID sym, const MemRegion *r, QualType t = QualType())
- : SymbolData(RegionValueKind, sym), R(r), T(t) {}
+ SymbolRegionValue(SymbolID sym, const TypedRegion *r)
+ : SymbolData(RegionValueKind, sym), R(r) {}
- const MemRegion* getRegion() const { return R; }
+ const TypedRegion* getRegion() const { return R; }
- static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R,
- QualType T) {
+ static void Profile(llvm::FoldingSetNodeID& profile, const TypedRegion* R) {
profile.AddInteger((unsigned) RegionValueKind);
profile.AddPointer(R);
- T.Profile(profile);
}
virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, R, T);
+ Profile(profile, R);
}
void dumpToStream(llvm::raw_ostream &os) const;
@@ -122,6 +118,7 @@ public:
}
};
+// A symbol representing the result of an expression.
class SymbolConjured : public SymbolData {
const Stmt* S;
QualType T;
@@ -161,6 +158,8 @@ public:
}
};
+// A symbol representing the value of a MemRegion whose parent region has
+// symbolic value.
class SymbolDerived : public SymbolData {
SymbolRef parentSymbol;
const TypedRegion *R;
@@ -294,8 +293,8 @@ public:
static bool canSymbolicate(QualType T);
/// Make a unique symbol for MemRegion R according to its kind.
- const SymbolRegionValue* getRegionValueSymbol(const MemRegion* R,
- QualType T = QualType());
+ const SymbolRegionValue* getRegionValueSymbol(const TypedRegion* R);
+
const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
unsigned VisitCount,
const void* SymbolTag = 0);
diff --git a/include/clang/Checker/PathSensitive/ValueManager.h b/include/clang/Checker/PathSensitive/ValueManager.h
index ea3af57..f80ad42 100644
--- a/include/clang/Checker/PathSensitive/ValueManager.h
+++ b/include/clang/Checker/PathSensitive/ValueManager.h
@@ -94,8 +94,7 @@ public:
DefinedOrUnknownSVal makeZeroVal(QualType T);
/// getRegionValueSymbolVal - make a unique symbol for value of R.
- DefinedOrUnknownSVal getRegionValueSymbolVal(const MemRegion *R,
- QualType T = QualType());
+ DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R);
DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
const Expr *E, unsigned Count);
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
index e1d4ad1..e0e0f77 100644
--- a/include/clang/CodeGen/CodeGenOptions.h
+++ b/include/clang/CodeGen/CodeGenOptions.h
@@ -53,6 +53,8 @@ public:
unsigned UnwindTables : 1; /// Emit unwind tables.
unsigned VerifyModule : 1; /// Control whether the module should be run
/// through the LLVM Verifier.
+ unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
+ /// aliases to base ctors when possible.
/// The code model to use (-mcmodel).
std::string CodeModel;
@@ -101,6 +103,7 @@ public:
UnrollLoops = 0;
UnwindTables = 0;
VerifyModule = 1;
+ CXXCtorDtorAliases = 0;
Inlining = NoInlining;
RelocationModel = "pic";
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 047363e..7cd26ef 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -143,6 +143,8 @@ def mrelocation_model : Separate<"-mrelocation-model">,
HelpText<"The relocation model to use">;
def munwind_tables : Flag<"-munwind-tables">,
HelpText<"Generate unwinding tables for all functions">;
+def mconstructor_aliases : Flag<"-mconstructor-aliases">,
+ HelpText<"Emit complete constructors and destructors as aliases when possible">;
def O : Joined<"-O">, HelpText<"Optimization level">;
def Os : Flag<"-Os">, HelpText<"Optimize for size">;
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 64f88ed..59c3946 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -70,6 +70,9 @@ public:
/// Default name for linked images (e.g., "a.out").
std::string DefaultImageName;
+ /// Driver title to use with help.
+ std::string DriverTitle;
+
/// Host information for the platform the driver is running as. This
/// will generally be the actual host platform, but not always.
const HostInfo *Host;
@@ -137,6 +140,9 @@ public:
void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
+ const std::string &getTitle() { return DriverTitle; }
+ void setTitle(std::string Value) { DriverTitle = Value; }
+
/// @}
/// @name Primary Functionality
/// @{
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 4693e5c..b462a4d 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -235,7 +235,6 @@ def fastcp : Flag<"-fastcp">, Group<f_Group>;
def fastf : Flag<"-fastf">, Group<f_Group>;
def fast : Flag<"-fast">, Group<f_Group>;
def fasynchronous_unwind_tables : Flag<"-fasynchronous-unwind-tables">, Group<f_Group>;
-def fblock_introspection : Flag<"-fblock-introspection">, Group<f_Group>;
def fblocks : Flag<"-fblocks">, Group<f_Group>;
def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>;
def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>;
@@ -445,7 +444,7 @@ def multiply__defined : Separate<"-multiply_defined">;
def mwarn_nonportable_cfstrings : Flag<"-mwarn-nonportable-cfstrings">, Group<m_Group>;
def m_Separate : Separate<"-m">, Group<m_Group>;
def m_Joined : Joined<"-m">, Group<m_Group>;
-def no_canonical_prefixes : Flag<"-no-canonical-prefixes">, Flags<[DriverOption, HelpHidden]>,
+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">;
def no_integrated_as : Flag<"-no-integrated-as">, Flags<[DriverOption]>;
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index 3a343b3..d933230 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -80,6 +80,10 @@ namespace types {
/// getCompilationPhase - Return the \args N th compilation phase to
/// be done for this type.
phases::ID getCompilationPhase(ID Id, unsigned N);
+
+ /// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given
+ /// C type (used for clang++ emulation of g++ behaviour)
+ ID lookupCXXTypeForCType(ID Id);
} // end namespace types
} // end namespace driver
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 7ec5063..b5b09f5 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -69,26 +69,6 @@ ASTConsumer *CreateObjCRewriter(const std::string &InFile,
const LangOptions &LOpts,
bool SilenceRewriteMacroWarning);
-// LLVM code generator: uses the code generation backend to generate LLVM
-// assembly. This runs optimizations depending on the CodeGenOptions
-// parameter. The output depends on the Action parameter.
-enum BackendAction {
- Backend_EmitAssembly, // Emit native assembly files
- Backend_EmitBC, // Emit LLVM bitcode files
- Backend_EmitLL, // Emit human-readable LLVM assembly
- Backend_EmitNothing, // Don't emit anything (benchmarking mode)
- Backend_EmitObj // Emit native object files
-};
-ASTConsumer *CreateBackendConsumer(BackendAction Action,
- Diagnostic &Diags,
- const LangOptions &Features,
- const CodeGenOptions &CodeGenOpts,
- const TargetOptions &TargetOpts,
- bool TimePasses,
- const std::string &ModuleID,
- llvm::raw_ostream *OS,
- llvm::LLVMContext& C);
-
/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
/// HTML with syntax highlighting suitable for viewing in a web-browser.
ASTConsumer *CreateHTMLPrinter(llvm::raw_ostream *OS, Preprocessor &PP,
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index f122dd9..626a162 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -18,6 +18,8 @@
#include "llvm/ADT/OwningPtr.h"
#include "clang/Basic/FileManager.h"
#include "clang/Index/ASTLocation.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/System/Path.h"
#include <string>
#include <vector>
#include <cassert>
@@ -51,7 +53,6 @@ class ASTUnit {
llvm::OwningPtr<TargetInfo> Target;
llvm::OwningPtr<Preprocessor> PP;
llvm::OwningPtr<ASTContext> Ctx;
- bool tempFile;
/// Optional owned invocation, just used to make the invocation used in
/// LoadFromCommandLine available.
@@ -80,6 +81,14 @@ class ASTUnit {
// Critical optimization when using clang_getCursor().
ASTLocation LastLoc;
+ /// \brief The set of diagnostics produced when creating this
+ /// translation unit.
+ llvm::SmallVector<StoredDiagnostic, 4> Diagnostics;
+
+ /// \brief Temporary files that should be removed when the ASTUnit is
+ /// destroyed.
+ llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles;
+
ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
@@ -104,8 +113,13 @@ public:
const std::string &getOriginalSourceFileName();
const std::string &getPCHFileName();
- void unlinkTemporaryFile() { tempFile = true; }
-
+ /// \brief Add a temporary file that the ASTUnit depends on.
+ ///
+ /// This file will be erased when the ASTUnit is destroyed.
+ void addTemporaryFile(const llvm::sys::Path &TempFile) {
+ TemporaryFiles.push_back(TempFile);
+ }
+
bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; }
@@ -120,6 +134,15 @@ public:
return TopLevelDecls;
}
+ // Retrieve the diagnostics associated with this AST
+ typedef const StoredDiagnostic * diag_iterator;
+ diag_iterator diag_begin() const { return Diagnostics.begin(); }
+ diag_iterator diag_end() const { return Diagnostics.end(); }
+ unsigned diag_size() const { return Diagnostics.size(); }
+ llvm::SmallVector<StoredDiagnostic, 4> &getDiagnostics() {
+ return Diagnostics;
+ }
+
/// \brief A mapping from a file name to the memory buffer that stores the
/// remapped contents of that file.
typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile;
@@ -136,7 +159,8 @@ public:
Diagnostic &Diags,
bool OnlyLocalDecls = false,
RemappedFile *RemappedFiles = 0,
- unsigned NumRemappedFiles = 0);
+ unsigned NumRemappedFiles = 0,
+ bool CaptureDiagnostics = false);
/// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
/// CompilerInvocation object.
@@ -151,7 +175,8 @@ public:
// shouldn't need to specify them at construction time.
static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
Diagnostic &Diags,
- bool OnlyLocalDecls = false);
+ bool OnlyLocalDecls = false,
+ bool CaptureDiagnostics = false);
/// LoadFromCommandLine - Create an ASTUnit from a vector of command line
/// arguments, which must specify exactly one source file.
@@ -173,7 +198,8 @@ public:
llvm::StringRef ResourceFilesPath,
bool OnlyLocalDecls = false,
RemappedFile *RemappedFiles = 0,
- unsigned NumRemappedFiles = 0);
+ unsigned NumRemappedFiles = 0,
+ bool CaptureDiagnostics = false);
};
} // namespace clang
diff --git a/include/clang/Frontend/CodeGenAction.h b/include/clang/Frontend/CodeGenAction.h
new file mode 100644
index 0000000..a1e3c42
--- /dev/null
+++ b/include/clang/Frontend/CodeGenAction.h
@@ -0,0 +1,65 @@
+//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace llvm {
+ class Module;
+}
+
+namespace clang {
+
+class CodeGenAction : public ASTFrontendAction {
+private:
+ unsigned Act;
+ llvm::OwningPtr<llvm::Module> TheModule;
+
+protected:
+ CodeGenAction(unsigned _Act);
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile);
+
+ virtual void EndSourceFileAction();
+
+public:
+ ~CodeGenAction();
+
+ /// takeModule - Take the generated LLVM module, for use after the action has
+ /// been run. The result may be null on failure.
+ llvm::Module *takeModule();
+};
+
+class EmitAssemblyAction : public CodeGenAction {
+public:
+ EmitAssemblyAction();
+};
+
+class EmitBCAction : public CodeGenAction {
+public:
+ EmitBCAction();
+};
+
+class EmitLLVMAction : public CodeGenAction {
+public:
+ EmitLLVMAction();
+};
+
+class EmitLLVMOnlyAction : public CodeGenAction {
+public:
+ EmitLLVMOnlyAction();
+};
+
+class EmitObjAction : public CodeGenAction {
+public:
+ EmitObjAction();
+};
+
+}
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index cbb3508..5348e6b 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -159,46 +159,6 @@ public:
};
//===----------------------------------------------------------------------===//
-// Code Gen AST Actions
-//===----------------------------------------------------------------------===//
-
-class CodeGenAction : public ASTFrontendAction {
-private:
- unsigned Act;
-
-protected:
- CodeGenAction(unsigned _Act);
-
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile);
-};
-
-class EmitAssemblyAction : public CodeGenAction {
-public:
- EmitAssemblyAction();
-};
-
-class EmitBCAction : public CodeGenAction {
-public:
- EmitBCAction();
-};
-
-class EmitLLVMAction : public CodeGenAction {
-public:
- EmitLLVMAction();
-};
-
-class EmitLLVMOnlyAction : public CodeGenAction {
-public:
- EmitLLVMOnlyAction();
-};
-
-class EmitObjAction : public CodeGenAction {
-public:
- EmitObjAction();
-};
-
-//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index e22d37b..d4014b3 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -524,7 +524,9 @@ namespace clang {
/// associates a declaration name with one or more declaration
/// IDs. This data is used when performing qualified name lookup
/// into a DeclContext via DeclContext::lookup.
- DECL_CONTEXT_VISIBLE
+ DECL_CONTEXT_VISIBLE,
+ /// \brief A NamespaceDecl record.
+ DECL_NAMESPACE
};
/// \brief Record codes for each kind of statement or expression.
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index d727e48..d09e51f 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -37,11 +37,19 @@ class TextDiagnosticPrinter : public DiagnosticClient {
unsigned LastCaretDiagnosticWasNote : 1;
unsigned OwnsOutputStream : 1;
+ /// A string to prefix to error messages.
+ std::string Prefix;
+
public:
TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags,
bool OwnsOutputStream = false);
virtual ~TextDiagnosticPrinter();
+ /// setPrefix - Set the diagnostic printer prefix string, which will be
+ /// printed at the start of any diagnostics. If empty, no prefix string is
+ /// used.
+ void setPrefix(std::string Value) { Prefix = Value; }
+
void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) {
LangOpts = &LO;
}
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index dedbbd8..db9c884 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -570,6 +570,12 @@ public:
/// if an internal buffer is returned.
unsigned getSpelling(const Token &Tok, const char *&Buffer) const;
+ /// 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
+ /// supplied buffer if a copy can be avoided.
+ llvm::StringRef getSpelling(const Token &Tok,
+ llvm::SmallVectorImpl<char> &Buffer) const;
+
/// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
/// with length 1, return the character.
char getSpellingOfSingleCharacterNumericConstant(const Token &Tok) const {
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index ec542f0..f211b5c 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -327,13 +327,26 @@ public:
return false;
}
+ /// \brief Determine whether the given name refers to a non-type nested name
+ /// specifier, e.g., the name of a namespace or namespace alias.
+ ///
+ /// This actual is used in the parsing of pseudo-destructor names to
+ /// distinguish a nested-name-specifier and a "type-name ::" when we
+ /// see the token sequence "X :: ~".
+ virtual bool isNonTypeNestedNameSpecifier(Scope *S, const CXXScopeSpec &SS,
+ SourceLocation IdLoc,
+ IdentifierInfo &II,
+ TypeTy *ObjectType) {
+ return false;
+ }
+
/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
/// global scope ('::').
virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
SourceLocation CCLoc) {
return 0;
}
-
+
/// \brief Parsed an identifier followed by '::' in a C++
/// nested-name-specifier.
///
@@ -490,6 +503,12 @@ public:
return;
}
+ /// \brief Note that the given declaration had an initializer that could not
+ /// be parsed.
+ virtual void ActOnInitializerError(DeclPtrTy Dcl) {
+ return;
+ }
+
/// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
/// gives the actions implementation a chance to process the group as a whole.
virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec& DS,
@@ -1075,7 +1094,7 @@ public:
SourceLocation RLoc) {
return ExprEmpty();
}
-
+
/// \brief Parsed a member access expresion (C99 6.5.2.3, C++ [expr.ref])
/// of the form \c x.m or \c p->m.
///
@@ -1473,6 +1492,18 @@ public:
//===------------------------- C++ Expressions --------------------------===//
+ /// \brief Parsed a destructor name or pseudo-destructor name.
+ ///
+ /// \returns the type being destructed.
+ virtual TypeTy *getDestructorName(SourceLocation TildeLoc,
+ IdentifierInfo &II, SourceLocation NameLoc,
+ Scope *S, const CXXScopeSpec &SS,
+ TypeTy *ObjectType,
+ bool EnteringContext) {
+ return getTypeName(II, NameLoc, S, &SS, false, ObjectType);
+ }
+
+
/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
tok::TokenKind Kind,
@@ -1594,12 +1625,66 @@ public:
/// with the type into which name lookup should look to find the member in
/// the member access expression.
///
+ /// \param MayBePseudoDestructor Originally false. The action should
+ /// set this true if the expression may end up being a
+ /// pseudo-destructor expression, indicating to the parser that it
+ /// shoudl be parsed as a pseudo-destructor rather than as a member
+ /// access expression. Note that this should apply both when the
+ /// object type is a scalar and when the object type is dependent.
+ ///
/// \returns the (possibly modified) \p Base expression
virtual OwningExprResult ActOnStartCXXMemberReference(Scope *S,
ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
- TypeTy *&ObjectType) {
+ TypeTy *&ObjectType,
+ bool &MayBePseudoDestructor) {
+ return ExprEmpty();
+ }
+
+ /// \brief Parsed a C++ pseudo-destructor expression or a dependent
+ /// member access expression that has the same syntactic form as a
+ /// pseudo-destructor expression.
+ ///
+ /// \param S The scope in which the member access expression occurs.
+ ///
+ /// \param Base The expression in which a member is being accessed, e.g., the
+ /// "x" in "x.f".
+ ///
+ /// \param OpLoc The location of the member access operator ("." or "->")
+ ///
+ /// \param OpKind The kind of member access operator ("." or "->")
+ ///
+ /// \param SS The nested-name-specifier that precedes the type names
+ /// in the grammar. Note that this nested-name-specifier will not
+ /// cover the last "type-name ::" in the grammar, because it isn't
+ /// necessarily a nested-name-specifier.
+ ///
+ /// \param FirstTypeName The type name that follows the optional
+ /// nested-name-specifier but precedes the '::', e.g., the first
+ /// type-name in "type-name :: type-name". This type name may be
+ /// empty. This will be either an identifier or a template-id.
+ ///
+ /// \param CCLoc The location of the '::' in "type-name ::
+ /// typename". May be invalid, if there is no \p FirstTypeName.
+ ///
+ /// \param TildeLoc The location of the '~'.
+ ///
+ /// \param SecondTypeName The type-name following the '~', which is
+ /// the name of the type being destroyed. This will be either an
+ /// identifier or a template-id.
+ ///
+ /// \param HasTrailingLParen Whether the next token in the stream is
+ /// a left parentheses.
+ virtual OwningExprResult ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ UnqualifiedId &FirstTypeName,
+ SourceLocation CCLoc,
+ SourceLocation TildeLoc,
+ UnqualifiedId &SecondTypeName,
+ bool HasTrailingLParen) {
return ExprEmpty();
}
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index ecaa6ae..37acab9 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -51,7 +51,8 @@ public:
AttributeList *Next, bool declspec = false, bool cxx0x = false);
~AttributeList();
- enum Kind { // Please keep this list alphabetized.
+ enum Kind { // Please keep this list alphabetized.
+ AT_IBAction, // Clang-specific.
AT_IBOutlet, // Clang-specific.
AT_address_space,
AT_alias,
@@ -88,8 +89,10 @@ public:
AT_nsobject,
AT_objc_exception,
AT_override,
- AT_cf_returns_retained, // Clang-specific.
- AT_ns_returns_retained, // Clang-specific.
+ AT_cf_returns_not_retained, // Clang-specific.
+ AT_cf_returns_retained, // Clang-specific.
+ AT_ns_returns_not_retained, // Clang-specific.
+ AT_ns_returns_retained, // Clang-specific.
AT_objc_gc,
AT_overloadable, // Clang-specific.
AT_packed,
@@ -106,6 +109,7 @@ public:
AT_visibility,
AT_warn_unused_result,
AT_weak,
+ AT_weakref,
AT_weak_import,
AT_reqd_wg_size,
IgnoredAttribute,
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index f4d3d3e..f034aa1 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -320,86 +320,39 @@ private:
/// This returns true if the token was annotated.
bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false);
- /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but only
- /// annotates C++ scope specifiers. This returns true if the token was
- /// annotated.
+ /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but
+ /// only annotates C++ scope specifiers. This returns true if there
+ /// was an unrecoverable error.
bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
/// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
/// replacing them with the non-context-sensitive keywords. This returns
/// true if the token was replaced.
bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID, bool &isInvalid) {
- if (getLang().AltiVec) {
- if (Tok.getIdentifierInfo() == Ident_vector) {
- const Token nextToken = NextToken();
- switch (nextToken.getKind()) {
- case tok::kw_short:
- case tok::kw_long:
- case tok::kw_signed:
- case tok::kw_unsigned:
- case tok::kw_void:
- case tok::kw_char:
- case tok::kw_int:
- case tok::kw_float:
- case tok::kw_double:
- case tok::kw_bool:
- case tok::kw___pixel:
- isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
- return true;
- case tok::identifier:
- if (nextToken.getIdentifierInfo() == Ident_pixel) {
- isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
- return true;
- }
- break;
- default:
- break;
- }
- } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
- DS.isTypeAltiVecVector()) {
- isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
- return true;
- }
- }
- return false;
+ const char *&PrevSpec, unsigned &DiagID,
+ bool &isInvalid) {
+ if (!getLang().AltiVec ||
+ (Tok.getIdentifierInfo() != Ident_vector &&
+ Tok.getIdentifierInfo() != Ident_pixel))
+ return false;
+
+ return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid);
}
/// TryAltiVecVectorToken - Check for context-sensitive AltiVec vector
/// identifier token, replacing it with the non-context-sensitive __vector.
/// This returns true if the token was replaced.
bool TryAltiVecVectorToken() {
- if (getLang().AltiVec) {
- if (Tok.getIdentifierInfo() == Ident_vector) {
- const Token nextToken = NextToken();
- switch (nextToken.getKind()) {
- case tok::kw_short:
- case tok::kw_long:
- case tok::kw_signed:
- case tok::kw_unsigned:
- case tok::kw_void:
- case tok::kw_char:
- case tok::kw_int:
- case tok::kw_float:
- case tok::kw_double:
- case tok::kw_bool:
- case tok::kw___pixel:
- Tok.setKind(tok::kw___vector);
- return true;
- case tok::identifier:
- if (nextToken.getIdentifierInfo() == Ident_pixel) {
- Tok.setKind(tok::kw___vector);
- return true;
- }
- break;
- default:
- break;
- }
- }
- }
- return false;
+ if (!getLang().AltiVec ||
+ Tok.getIdentifierInfo() != Ident_vector) return false;
+ return TryAltiVecVectorTokenOutOfLine();
}
-
+
+ bool TryAltiVecVectorTokenOutOfLine();
+ bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID,
+ bool &isInvalid);
+
/// TentativeParsingAction - An object that is used as a kind of "tentative
/// parsing transaction". It gets instantiated to mark the token position and
/// after the token consumption is done, Commit() or Revert() is called to
@@ -849,6 +802,7 @@ private:
DeclPtrTy ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
AttributeList *prefixAttrs = 0);
void ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
+ tok::ObjCKeywordKind visibility,
SourceLocation atLoc);
bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &P,
llvm::SmallVectorImpl<SourceLocation> &PLocs,
@@ -962,7 +916,8 @@ private:
bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
TypeTy *ObjectType,
- bool EnteringContext);
+ bool EnteringContext,
+ bool *MayBePseudoDestructor = 0);
//===--------------------------------------------------------------------===//
// C++ 5.2p1: C++ Casts
@@ -973,6 +928,13 @@ private:
OwningExprResult ParseCXXTypeid();
//===--------------------------------------------------------------------===//
+ // C++ 5.2.4: C++ Pseudo-Destructor Expressions
+ OwningExprResult ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ CXXScopeSpec &SS,
+ Action::TypeTy *ObjectType);
+
+ //===--------------------------------------------------------------------===//
// C++ 9.3.2: C++ 'this' pointer
OwningExprResult ParseCXXThis();
@@ -1153,7 +1115,7 @@ private:
void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
- AccessSpecifier AS = AS_none);
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), AccessSpecifier AS = AS_none);
void ParseEnumBody(SourceLocation StartLoc, DeclPtrTy TagDecl);
void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
DeclPtrTy TagDecl);
@@ -1172,6 +1134,11 @@ private:
bool isDeclarationSpecifier();
bool isTypeSpecifierQualifier();
bool isTypeQualifier() const;
+
+ /// isKnownToBeTypeSpecifier - Return true if we know that the specified token
+ /// is definitely a type-specifier. Return false if it isn't part of a type
+ /// specifier or if we're not sure.
+ bool isKnownToBeTypeSpecifier(const Token &Tok) const;
/// isDeclarationStatement - Disambiguates between a declaration or an
/// expression statement, when parsing function bodies.
@@ -1387,8 +1354,7 @@ private:
//===--------------------------------------------------------------------===//
// C++ 9: classes [class] and C structs/unions.
TypeResult ParseClassName(SourceLocation &EndLocation,
- const CXXScopeSpec *SS = 0,
- bool DestrExpected = false);
+ const CXXScopeSpec *SS = 0);
void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
@@ -1414,7 +1380,8 @@ private:
SourceLocation NameLoc,
bool EnteringContext,
TypeTy *ObjectType,
- UnqualifiedId &Id);
+ UnqualifiedId &Id,
+ bool AssumeTemplateId = false);
bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
TypeTy *ObjectType,
UnqualifiedId &Result);
diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h
index c6a1e53..c9825f6 100644
--- a/include/clang/Parse/Scope.h
+++ b/include/clang/Parse/Scope.h
@@ -129,6 +129,9 @@ private:
typedef llvm::SmallVector<Action::DeclPtrTy, 2> UsingDirectivesTy;
UsingDirectivesTy UsingDirectives;
+ /// \brief The number of errors at the start of the given scope.
+ unsigned NumErrorsAtStart;
+
public:
Scope(Scope *Parent, unsigned ScopeFlags) {
Init(Parent, ScopeFlags);
@@ -208,6 +211,14 @@ public:
void* getEntity() const { return Entity; }
void setEntity(void *E) { Entity = E; }
+ /// \brief Retrieve the number of errors that had been emitted when we
+ /// entered this scope.
+ unsigned getNumErrorsAtStart() const { return NumErrorsAtStart; }
+
+ void setNumErrorsAtStart(unsigned NumErrors) {
+ NumErrorsAtStart = NumErrors;
+ }
+
/// isClassScope - Return true if this scope is a class/struct/union scope.
bool isClassScope() const {
return (getFlags() & Scope::ClassScope);
@@ -300,6 +311,7 @@ public:
DeclsInScope.clear();
UsingDirectives.clear();
Entity = 0;
+ NumErrorsAtStart = 0;
}
};
OpenPOWER on IntegriCloud