diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include')
237 files changed, 12164 insertions, 5710 deletions
diff --git a/contrib/llvm/tools/clang/include/clang-c/Index.h b/contrib/llvm/tools/clang/include/clang-c/Index.h index 4852ded..1320145 100644 --- a/contrib/llvm/tools/clang/include/clang-c/Index.h +++ b/contrib/llvm/tools/clang/include/clang-c/Index.h @@ -115,7 +115,12 @@ enum CXAvailabilityKind { /** * \brief The entity is not available; any use of it will be an error. */ - CXAvailability_NotAvailable + CXAvailability_NotAvailable, + /** + * \brief The entity is available, but not accessible; any use of it will be + * an error. + */ + CXAvailability_NotAccessible }; /** @@ -263,7 +268,7 @@ CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu, * \brief Identifies a specific source location within a translation * unit. * - * Use clang_getInstantiationLocation() or clang_getSpellingLocation() + * Use clang_getExpansionLocation() or clang_getSpellingLocation() * to map a source location to a particular file, line, and column. */ typedef struct { @@ -328,11 +333,24 @@ CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end); /** + * \brief Determine whether two ranges are equivalent. + * + * \returns non-zero if the ranges are the same, zero if they differ. + */ +CINDEX_LINKAGE unsigned clang_equalRanges(CXSourceRange range1, + CXSourceRange range2); + +/** + * \brief Returns non-zero if \arg range is null. + */ +CINDEX_LINKAGE int clang_Range_isNull(CXSourceRange range); + +/** * \brief Retrieve the file, line, column, and offset represented by * the given source location. * - * If the location refers into a macro instantiation, retrieves the - * location of the macro instantiation. + * If the location refers into a macro expansion, retrieves the + * location of the macro expansion. * * \param location the location within a source file that will be decomposed * into its parts. @@ -349,6 +367,63 @@ CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin, * \param offset [out] if non-NULL, will be set to the offset into the * buffer to which the given source location points. */ +CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location, + CXFile *file, + unsigned *line, + unsigned *column, + unsigned *offset); + +/** + * \brief Retrieve the file, line, column, and offset represented by + * the given source location, as specified in a # line directive. + * + * Example: given the following source code in a file somefile.c + * + * #123 "dummy.c" 1 + * + * static int func(void) + * { + * return 0; + * } + * + * the location information returned by this function would be + * + * File: dummy.c Line: 124 Column: 12 + * + * whereas clang_getExpansionLocation would have returned + * + * File: somefile.c Line: 3 Column: 12 + * + * \param location the location within a source file that will be decomposed + * into its parts. + * + * \param filename [out] if non-NULL, will be set to the filename of the + * source location. Note that filenames returned will be for "virtual" files, + * which don't necessarily exist on the machine running clang - e.g. when + * parsing preprocessed output obtained from a different environment. If + * a non-NULL value is passed in, remember to dispose of the returned value + * using \c clang_disposeString() once you've finished with it. For an invalid + * source location, an empty string is returned. + * + * \param line [out] if non-NULL, will be set to the line number of the + * source location. For an invalid source location, zero is returned. + * + * \param column [out] if non-NULL, will be set to the column number of the + * source location. For an invalid source location, zero is returned. + */ +CINDEX_LINKAGE void clang_getPresumedLocation(CXSourceLocation location, + CXString *filename, + unsigned *line, + unsigned *column); + +/** + * \brief Legacy API to retrieve the file, line, column, and offset represented + * by the given source location. + * + * This interface has been replaced by the newer interface + * \see clang_getExpansionLocation(). See that interface's documentation for + * details. + */ CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location, CXFile *file, unsigned *line, @@ -816,18 +891,18 @@ enum CXTranslationUnit_Flags { */ CXTranslationUnit_CacheCompletionResults = 0x08, /** - * \brief Enable precompiled preambles in C++. + * \brief DEPRECATED: Enable precompiled preambles in C++. * * Note: this is a *temporary* option that is available only while - * we are testing C++ precompiled preamble support. + * we are testing C++ precompiled preamble support. It is deprecated. */ CXTranslationUnit_CXXPrecompiledPreamble = 0x10, /** - * \brief Enabled chained precompiled preambles in C++. + * \brief DEPRECATED: Enabled chained precompiled preambles in C++. * * Note: this is a *temporary* option that is available only while - * we are testing C++ precompiled preamble support. + * we are testing C++ precompiled preamble support. It is deprecated. */ CXTranslationUnit_CXXChainedPCH = 0x20, @@ -1094,12 +1169,14 @@ enum CXTUResourceUsageKind { CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10, CXTUResourceUsage_Preprocessor = 11, CXTUResourceUsage_PreprocessingRecord = 12, + CXTUResourceUsage_SourceManager_DataStructures = 13, + CXTUResourceUsage_Preprocessor_HeaderSearch = 14, CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST, CXTUResourceUsage_MEMORY_IN_BYTES_END = - CXTUResourceUsage_PreprocessingRecord, + CXTUResourceUsage_Preprocessor_HeaderSearch, CXTUResourceUsage_First = CXTUResourceUsage_AST, - CXTUResourceUsage_Last = CXTUResourceUsage_PreprocessingRecord + CXTUResourceUsage_Last = CXTUResourceUsage_Preprocessor_HeaderSearch }; /** @@ -1237,8 +1314,11 @@ enum CXCursorKind { CXCursor_ObjCSynthesizeDecl = 37, /** \brief An Objective-C @dynamic definition. */ CXCursor_ObjCDynamicDecl = 38, + /** \brief An access specifier. */ + CXCursor_CXXAccessSpecifier = 39, + CXCursor_FirstDecl = CXCursor_UnexposedDecl, - CXCursor_LastDecl = CXCursor_ObjCDynamicDecl, + CXCursor_LastDecl = CXCursor_CXXAccessSpecifier, /* References */ CXCursor_FirstRef = 40, /* Decl references */ @@ -1377,7 +1457,207 @@ enum CXCursorKind { /** \brief An expression that represents a block literal. */ CXCursor_BlockExpr = 105, - CXCursor_LastExpr = 105, + /** \brief An integer literal. + */ + CXCursor_IntegerLiteral = 106, + + /** \brief A floating point number literal. + */ + CXCursor_FloatingLiteral = 107, + + /** \brief An imaginary number literal. + */ + CXCursor_ImaginaryLiteral = 108, + + /** \brief A string literal. + */ + CXCursor_StringLiteral = 109, + + /** \brief A character literal. + */ + CXCursor_CharacterLiteral = 110, + + /** \brief A parenthesized expression, e.g. "(1)". + * + * This AST node is only formed if full location information is requested. + */ + CXCursor_ParenExpr = 111, + + /** \brief This represents the unary-expression's (except sizeof and + * alignof). + */ + CXCursor_UnaryOperator = 112, + + /** \brief [C99 6.5.2.1] Array Subscripting. + */ + CXCursor_ArraySubscriptExpr = 113, + + /** \brief A builtin binary operation expression such as "x + y" or + * "x <= y". + */ + CXCursor_BinaryOperator = 114, + + /** \brief Compound assignment such as "+=". + */ + CXCursor_CompoundAssignOperator = 115, + + /** \brief The ?: ternary operator. + */ + CXCursor_ConditionalOperator = 116, + + /** \brief An explicit cast in C (C99 6.5.4) or a C-style cast in C++ + * (C++ [expr.cast]), which uses the syntax (Type)expr. + * + * For example: (int)f. + */ + CXCursor_CStyleCastExpr = 117, + + /** \brief [C99 6.5.2.5] + */ + CXCursor_CompoundLiteralExpr = 118, + + /** \brief Describes an C or C++ initializer list. + */ + CXCursor_InitListExpr = 119, + + /** \brief The GNU address of label extension, representing &&label. + */ + CXCursor_AddrLabelExpr = 120, + + /** \brief This is the GNU Statement Expression extension: ({int X=4; X;}) + */ + CXCursor_StmtExpr = 121, + + /** \brief Represents a C1X generic selection. + */ + CXCursor_GenericSelectionExpr = 122, + + /** \brief Implements the GNU __null extension, which is a name for a null + * pointer constant that has integral type (e.g., int or long) and is the same + * size and alignment as a pointer. + * + * The __null extension is typically only used by system headers, which define + * NULL as __null in C++ rather than using 0 (which is an integer that may not + * match the size of a pointer). + */ + CXCursor_GNUNullExpr = 123, + + /** \brief C++'s static_cast<> expression. + */ + CXCursor_CXXStaticCastExpr = 124, + + /** \brief C++'s dynamic_cast<> expression. + */ + CXCursor_CXXDynamicCastExpr = 125, + + /** \brief C++'s reinterpret_cast<> expression. + */ + CXCursor_CXXReinterpretCastExpr = 126, + + /** \brief C++'s const_cast<> expression. + */ + CXCursor_CXXConstCastExpr = 127, + + /** \brief Represents an explicit C++ type conversion that uses "functional" + * notion (C++ [expr.type.conv]). + * + * Example: + * \code + * x = int(0.5); + * \endcode + */ + CXCursor_CXXFunctionalCastExpr = 128, + + /** \brief A C++ typeid expression (C++ [expr.typeid]). + */ + CXCursor_CXXTypeidExpr = 129, + + /** \brief [C++ 2.13.5] C++ Boolean Literal. + */ + CXCursor_CXXBoolLiteralExpr = 130, + + /** \brief [C++0x 2.14.7] C++ Pointer Literal. + */ + CXCursor_CXXNullPtrLiteralExpr = 131, + + /** \brief Represents the "this" expression in C++ + */ + CXCursor_CXXThisExpr = 132, + + /** \brief [C++ 15] C++ Throw Expression. + * + * This handles 'throw' and 'throw' assignment-expression. When + * assignment-expression isn't present, Op will be null. + */ + CXCursor_CXXThrowExpr = 133, + + /** \brief A new expression for memory allocation and constructor calls, e.g: + * "new CXXNewExpr(foo)". + */ + CXCursor_CXXNewExpr = 134, + + /** \brief A delete expression for memory deallocation and destructor calls, + * e.g. "delete[] pArray". + */ + CXCursor_CXXDeleteExpr = 135, + + /** \brief A unary expression. + */ + CXCursor_UnaryExpr = 136, + + /** \brief ObjCStringLiteral, used for Objective-C string literals i.e. "foo". + */ + CXCursor_ObjCStringLiteral = 137, + + /** \brief ObjCEncodeExpr, used for in Objective-C. + */ + CXCursor_ObjCEncodeExpr = 138, + + /** \brief ObjCSelectorExpr used for in Objective-C. + */ + CXCursor_ObjCSelectorExpr = 139, + + /** \brief Objective-C's protocol expression. + */ + CXCursor_ObjCProtocolExpr = 140, + + /** \brief An Objective-C "bridged" cast expression, which casts between + * Objective-C pointers and C pointers, transferring ownership in the process. + * + * \code + * NSString *str = (__bridge_transfer NSString *)CFCreateString(); + * \endcode + */ + CXCursor_ObjCBridgedCastExpr = 141, + + /** \brief Represents a C++0x pack expansion that produces a sequence of + * expressions. + * + * A pack expansion expression contains a pattern (which itself is an + * expression) followed by an ellipsis. For example: + * + * \code + * template<typename F, typename ...Types> + * void forward(F f, Types &&...args) { + * f(static_cast<Types&&>(args)...); + * } + * \endcode + */ + CXCursor_PackExpansionExpr = 142, + + /** \brief Represents an expression that computes the length of a parameter + * pack. + * + * \code + * template<typename ...Types> + * struct count { + * static const unsigned value = sizeof...(Types); + * }; + * \endcode + */ + CXCursor_SizeOfPackExpr = 143, + + CXCursor_LastExpr = CXCursor_SizeOfPackExpr, /* Statements */ CXCursor_FirstStmt = 200, @@ -1404,8 +1684,130 @@ enum CXCursorKind { * */ CXCursor_LabelStmt = 201, - - CXCursor_LastStmt = CXCursor_LabelStmt, + + /** \brief A group of statements like { stmt stmt }. + * + * This cursor kind is used to describe compound statements, e.g. function + * bodies. + */ + CXCursor_CompoundStmt = 202, + + /** \brief A case statment. + */ + CXCursor_CaseStmt = 203, + + /** \brief A default statement. + */ + CXCursor_DefaultStmt = 204, + + /** \brief An if statement + */ + CXCursor_IfStmt = 205, + + /** \brief A switch statement. + */ + CXCursor_SwitchStmt = 206, + + /** \brief A while statement. + */ + CXCursor_WhileStmt = 207, + + /** \brief A do statement. + */ + CXCursor_DoStmt = 208, + + /** \brief A for statement. + */ + CXCursor_ForStmt = 209, + + /** \brief A goto statement. + */ + CXCursor_GotoStmt = 210, + + /** \brief An indirect goto statement. + */ + CXCursor_IndirectGotoStmt = 211, + + /** \brief A continue statement. + */ + CXCursor_ContinueStmt = 212, + + /** \brief A break statement. + */ + CXCursor_BreakStmt = 213, + + /** \brief A return statement. + */ + CXCursor_ReturnStmt = 214, + + /** \brief A GNU inline assembly statement extension. + */ + CXCursor_AsmStmt = 215, + + /** \brief Objective-C's overall @try-@catc-@finall statement. + */ + CXCursor_ObjCAtTryStmt = 216, + + /** \brief Objective-C's @catch statement. + */ + CXCursor_ObjCAtCatchStmt = 217, + + /** \brief Objective-C's @finally statement. + */ + CXCursor_ObjCAtFinallyStmt = 218, + + /** \brief Objective-C's @throw statement. + */ + CXCursor_ObjCAtThrowStmt = 219, + + /** \brief Objective-C's @synchronized statement. + */ + CXCursor_ObjCAtSynchronizedStmt = 220, + + /** \brief Objective-C's autorelease pool statement. + */ + CXCursor_ObjCAutoreleasePoolStmt = 221, + + /** \brief Objective-C's collection statement. + */ + CXCursor_ObjCForCollectionStmt = 222, + + /** \brief C++'s catch statement. + */ + CXCursor_CXXCatchStmt = 223, + + /** \brief C++'s try statement. + */ + CXCursor_CXXTryStmt = 224, + + /** \brief C++'s for (* : *) statement. + */ + CXCursor_CXXForRangeStmt = 225, + + /** \brief Windows Structured Exception Handling's try statement. + */ + CXCursor_SEHTryStmt = 226, + + /** \brief Windows Structured Exception Handling's except statement. + */ + CXCursor_SEHExceptStmt = 227, + + /** \brief Windows Structured Exception Handling's finally statement. + */ + CXCursor_SEHFinallyStmt = 228, + + /** \brief The null satement ";": C99 6.8.3p3. + * + * This cursor kind is used to describe the null statement. + */ + CXCursor_NullStmt = 230, + + /** \brief Adaptor class for mixing declarations with statements and + * expressions. + */ + CXCursor_DeclStmt = 231, + + CXCursor_LastStmt = CXCursor_DeclStmt, /** * \brief Cursor that represents the translation unit itself. @@ -1426,7 +1828,10 @@ enum CXCursorKind { CXCursor_IBActionAttr = 401, CXCursor_IBOutletAttr = 402, CXCursor_IBOutletCollectionAttr = 403, - CXCursor_LastAttr = CXCursor_IBOutletCollectionAttr, + CXCursor_CXXFinalAttr = 404, + CXCursor_CXXOverrideAttr = 405, + CXCursor_AnnotateAttr = 406, + CXCursor_LastAttr = CXCursor_AnnotateAttr, /* Preprocessing */ CXCursor_PreprocessingDirective = 500, @@ -1458,6 +1863,7 @@ enum CXCursorKind { */ typedef struct { enum CXCursorKind kind; + int xdata; void *data[3]; } CXCursor; @@ -1486,6 +1892,11 @@ CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit); CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor); /** + * \brief Returns non-zero if \arg cursor is null. + */ +int clang_Cursor_isNull(CXCursor); + +/** * \brief Compute a hash value for the given cursor. */ CINDEX_LINKAGE unsigned clang_hashCursor(CXCursor); @@ -1600,6 +2011,11 @@ CINDEX_LINKAGE enum CXLanguageKind { */ CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); +/** + * \brief Returns the translation unit that a cursor originated from. + */ +CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor); + /** * \brief A fast container representing a set of CXCursors. @@ -1886,7 +2302,8 @@ enum CXTypeKind { CXType_ObjCInterface = 108, CXType_ObjCObjectPointer = 109, CXType_FunctionNoProto = 110, - CXType_FunctionProto = 111 + CXType_FunctionProto = 111, + CXType_ConstantArray = 112 }; /** @@ -1978,6 +2395,20 @@ CINDEX_LINKAGE CXType clang_getCursorResultType(CXCursor C); CINDEX_LINKAGE unsigned clang_isPODType(CXType T); /** + * \brief Return the element type of an array type. + * + * If a non-array type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_getArrayElementType(CXType T); + +/** + * \brief Return the the array size of a constant array. + * + * If a non-array type is passed in, -1 is returned. + */ +CINDEX_LINKAGE long long clang_getArraySize(CXType T); + +/** * \brief Returns 1 if the base class specified by the cursor with kind * CX_CXXBaseSpecifier is virtual. */ @@ -1996,7 +2427,8 @@ enum CX_CXXAccessSpecifier { /** * \brief Returns the access control level for the C++ base specifier - * represented by a cursor with kind CX_CXXBaseSpecifier. + * represented by a cursor with kind CXCursor_CXXBaseSpecifier or + * CXCursor_AccessSpecifier. */ CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor); @@ -2377,6 +2809,54 @@ CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C); * from which it was instantiated. Otherwise, returns a NULL cursor. */ CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C); + +/** + * \brief Given a cursor that references something else, return the source range + * covering that reference. + * + * \param C A cursor pointing to a member reference, a declaration reference, or + * an operator call. + * \param NameFlags A bitset with three independent flags: + * CXNameRange_WantQualifier, CXNameRange_WantTemplateArgs, and + * CXNameRange_WantSinglePiece. + * \param PieceIndex For contiguous names or when passing the flag + * CXNameRange_WantSinglePiece, only one piece with index 0 is + * available. When the CXNameRange_WantSinglePiece flag is not passed for a + * non-contiguous names, this index can be used to retreive the individual + * pieces of the name. See also CXNameRange_WantSinglePiece. + * + * \returns The piece of the name pointed to by the given cursor. If there is no + * name, or if the PieceIndex is out-of-range, a null-cursor will be returned. + */ +CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, + unsigned NameFlags, + unsigned PieceIndex); + +enum CXNameRefFlags { + /** + * \brief Include the nested-name-specifier, e.g. Foo:: in x.Foo::y, in the + * range. + */ + CXNameRange_WantQualifier = 0x1, + + /** + * \brief Include the explicit template arguments, e.g. <int> in x.f<int>, in + * the range. + */ + CXNameRange_WantTemplateArgs = 0x2, + + /** + * \brief If the name is non-contiguous, return the full spanning range. + * + * Non-contiguous names occur in Objective-C when a selector with two or more + * parameters is used, or in C++ when using an operator: + * \code + * [object doSomething:here withValue:there]; // ObjC + * return some_vector[1]; // C++ + * \endcode + */ + CXNameRange_WantSinglePiece = 0x4 +}; /** * @} @@ -2801,8 +3281,7 @@ clang_getCompletionChunkText(CXCompletionString completion_string, * \param chunk_number the 0-based index of the chunk in the completion string. * * \returns the completion string associated with the chunk at index - * \c chunk_number, or NULL if that chunk is not represented by a completion - * string. + * \c chunk_number. */ CINDEX_LINKAGE CXCompletionString clang_getCompletionChunkCompletionString(CXCompletionString completion_string, @@ -2841,6 +3320,45 @@ CINDEX_LINKAGE enum CXAvailabilityKind clang_getCompletionAvailability(CXCompletionString completion_string); /** + * \brief Retrieve the number of annotations associated with the given + * completion string. + * + * \param completion_string the completion string to query. + * + * \returns the number of annotations associated with the given completion + * string. + */ +CINDEX_LINKAGE unsigned +clang_getCompletionNumAnnotations(CXCompletionString completion_string); + +/** + * \brief Retrieve the annotation associated with the given completion string. + * + * \param completion_string the completion string to query. + * + * \param annotation_number the 0-based index of the annotation of the + * completion string. + * + * \returns annotation string associated with the completion at index + * \c annotation_number, or a NULL string if that annotation is not available. + */ +CINDEX_LINKAGE CXString +clang_getCompletionAnnotation(CXCompletionString completion_string, + unsigned annotation_number); + +/** + * \brief Retrieve a completion string for an arbitrary declaration or macro + * definition cursor. + * + * \param cursor The cursor to query. + * + * \returns A non-context-sensitive completion string for declaration and macro + * definition cursors, or NULL for other kinds of cursors. + */ +CINDEX_LINKAGE CXCompletionString +clang_getCursorCompletionString(CXCursor cursor); + +/** * \brief Contains the results of code-completion. * * This data structure contains the results of code completion, as @@ -3144,6 +3662,54 @@ CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results, CINDEX_LINKAGE unsigned long long clang_codeCompleteGetContexts( CXCodeCompleteResults *Results); + +/** + * \brief Returns the cursor kind for the container for the current code + * completion context. The container is only guaranteed to be set for + * contexts where a container exists (i.e. member accesses or Objective-C + * message sends); if there is not a container, this function will return + * CXCursor_InvalidCode. + * + * \param Results the code completion results to query + * + * \param IsIncomplete on return, this value will be false if Clang has complete + * information about the container. If Clang does not have complete + * information, this value will be true. + * + * \returns the container kind, or CXCursor_InvalidCode if there is not a + * container + */ +CINDEX_LINKAGE +enum CXCursorKind clang_codeCompleteGetContainerKind( + CXCodeCompleteResults *Results, + unsigned *IsIncomplete); + +/** + * \brief Returns the USR for the container for the current code completion + * context. If there is not a container for the current context, this + * function will return the empty string. + * + * \param Results the code completion results to query + * + * \returns the USR for the container + */ +CINDEX_LINKAGE +CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results); + + +/** + * \brief Returns the currently-entered selector for an Objective-C message + * send, formatted like "initWithFoo:bar:". Only guaranteed to return a + * non-empty string for CXCompletionContext_ObjCInstanceMessage and + * CXCompletionContext_ObjCClassMessage. + * + * \param Results the code completion results to query + * + * \returns the selector (or partial selector) that has been entered thus far + * for an Objective-C message send. + */ +CINDEX_LINKAGE +CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results); /** * @} @@ -3246,6 +3812,53 @@ CINDEX_LINKAGE void clang_remap_dispose(CXRemapping); * @} */ +/** \defgroup CINDEX_HIGH Higher level API functions + * + * @{ + */ + +enum CXVisitorResult { + CXVisit_Break, + CXVisit_Continue +}; + +typedef struct { + void *context; + enum CXVisitorResult (*visit)(void *context, CXCursor, CXSourceRange); +} CXCursorAndRangeVisitor; + +/** + * \brief Find references of a declaration in a specific file. + * + * \param cursor pointing to a declaration or a reference of one. + * + * \param file to search for references. + * + * \param visitor callback that will receive pairs of CXCursor/CXSourceRange for + * each reference found. + * The CXSourceRange will point inside the file; if the reference is inside + * a macro (and not a macro argument) the CXSourceRange will be invalid. + */ +CINDEX_LINKAGE void clang_findReferencesInFile(CXCursor cursor, CXFile file, + CXCursorAndRangeVisitor visitor); + +#ifdef __has_feature +# if __has_feature(blocks) + +typedef enum CXVisitorResult + (^CXCursorAndRangeVisitorBlock)(CXCursor, CXSourceRange); + +CINDEX_LINKAGE +void clang_findReferencesInFileWithBlock(CXCursor, CXFile, + CXCursorAndRangeVisitorBlock); + +# endif +#endif + +/** + * @} + */ + /** * @} */ diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h index ad5cf4a..d8dea0b 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h @@ -15,7 +15,7 @@ namespace clang { class ASTContext; - class DiagnosticClient; + class DiagnosticConsumer; namespace arcmt { class MigrationPass; @@ -28,35 +28,53 @@ namespace arcmt { /// It then checks the AST and produces errors/warning for ARC migration issues /// that the user needs to handle manually. /// +/// \param emitPremigrationARCErrors if true all ARC errors will get emitted +/// even if the migrator can fix them, but the function will still return false +/// if all ARC errors can be fixed. +/// +/// \param plistOut if non-empty, it is the file path to store the plist with +/// the pre-migration ARC diagnostics. +/// /// \returns false if no error is produced, true otherwise. bool checkForManualIssues(CompilerInvocation &CI, - llvm::StringRef Filename, InputKind Kind, - DiagnosticClient *DiagClient); + StringRef Filename, InputKind Kind, + DiagnosticConsumer *DiagClient, + bool emitPremigrationARCErrors = false, + StringRef plistOut = StringRef()); /// \brief Works similar to checkForManualIssues but instead of checking, it /// applies automatic modifications to source files to conform to ARC. /// /// \returns false if no error is produced, true otherwise. bool applyTransformations(CompilerInvocation &origCI, - llvm::StringRef Filename, InputKind Kind, - DiagnosticClient *DiagClient); + StringRef Filename, InputKind Kind, + DiagnosticConsumer *DiagClient); /// \brief Applies automatic modifications and produces temporary files /// and metadata into the \arg outputDir path. /// +/// \param emitPremigrationARCErrors if true all ARC errors will get emitted +/// even if the migrator can fix them, but the function will still return false +/// if all ARC errors can be fixed. +/// +/// \param plistOut if non-empty, it is the file path to store the plist with +/// the pre-migration ARC diagnostics. +/// /// \returns false if no error is produced, true otherwise. bool migrateWithTemporaryFiles(CompilerInvocation &origCI, - llvm::StringRef Filename, InputKind Kind, - DiagnosticClient *DiagClient, - llvm::StringRef outputDir); + StringRef Filename, InputKind Kind, + DiagnosticConsumer *DiagClient, + StringRef outputDir, + bool emitPremigrationARCErrors, + StringRef plistOut); /// \brief Get the set of file remappings from the \arg outputDir path that /// migrateWithTemporaryFiles produced. /// /// \returns false if no error is produced, true otherwise. bool getFileRemappings(std::vector<std::pair<std::string,std::string> > &remap, - llvm::StringRef outputDir, - DiagnosticClient *DiagClient); + StringRef outputDir, + DiagnosticConsumer *DiagClient); typedef void (*TransformFn)(MigrationPass &pass); @@ -64,12 +82,12 @@ std::vector<TransformFn> getAllTransformations(); class MigrationProcess { CompilerInvocation OrigCI; - DiagnosticClient *DiagClient; + DiagnosticConsumer *DiagClient; FileRemapper Remapper; public: - MigrationProcess(const CompilerInvocation &CI, DiagnosticClient *diagClient, - llvm::StringRef outputDir = llvm::StringRef()); + MigrationProcess(const CompilerInvocation &CI, DiagnosticConsumer *diagClient, + StringRef outputDir = StringRef()); class RewriteListener { public: @@ -78,7 +96,7 @@ public: virtual void start(ASTContext &Ctx) { } virtual void finish() { } - virtual void insert(SourceLocation loc, llvm::StringRef text) { } + virtual void insert(SourceLocation loc, StringRef text) { } virtual void remove(CharSourceRange range) { } }; diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h index 4c714f5..4eac4fa 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h @@ -34,11 +34,15 @@ public: class MigrateAction : public WrapperFrontendAction { std::string MigrateDir; + std::string PlistOut; + bool EmitPremigrationARCErros; protected: virtual bool BeginInvocation(CompilerInstance &CI); public: - MigrateAction(FrontendAction *WrappedAction, llvm::StringRef migrateDir); + MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, + StringRef plistOut, + bool emitPremigrationARCErrors); }; } diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h index 809f6a5..9a0b690 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h @@ -10,6 +10,7 @@ #ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H #define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/DenseMap.h" @@ -22,7 +23,7 @@ namespace llvm { namespace clang { class FileManager; class FileEntry; - class Diagnostic; + class DiagnosticsEngine; class CompilerInvocation; namespace arcmt { @@ -41,32 +42,32 @@ public: FileRemapper(); ~FileRemapper(); - bool initFromDisk(llvm::StringRef outputDir, Diagnostic &Diag, + bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag, bool ignoreIfFilesChanged); - bool flushToDisk(llvm::StringRef outputDir, Diagnostic &Diag); + bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag); - bool overwriteOriginal(Diagnostic &Diag, - llvm::StringRef outputDir = llvm::StringRef()); + bool overwriteOriginal(DiagnosticsEngine &Diag, + StringRef outputDir = StringRef()); - void remap(llvm::StringRef filePath, llvm::MemoryBuffer *memBuf); - void remap(llvm::StringRef filePath, llvm::StringRef newPath); + void remap(StringRef filePath, llvm::MemoryBuffer *memBuf); + void remap(StringRef filePath, StringRef newPath); void applyMappings(CompilerInvocation &CI) const; void transferMappingsAndClear(CompilerInvocation &CI); - void clear(llvm::StringRef outputDir = llvm::StringRef()); + void clear(StringRef outputDir = StringRef()); private: void remap(const FileEntry *file, llvm::MemoryBuffer *memBuf); void remap(const FileEntry *file, const FileEntry *newfile); - const FileEntry *getOriginalFile(llvm::StringRef filePath); + const FileEntry *getOriginalFile(StringRef filePath); void resetTarget(Target &targ); - bool report(const std::string &err, Diagnostic &Diag); + bool report(const Twine &err, DiagnosticsEngine &Diag); - std::string getRemapInfoFile(llvm::StringRef outputDir); + std::string getRemapInfoFile(StringRef outputDir); }; } // end namespace arcmt diff --git a/contrib/llvm/tools/clang/include/clang/AST/APValue.h b/contrib/llvm/tools/clang/include/clang/AST/APValue.h index fec7d29..375af28 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/APValue.h +++ b/contrib/llvm/tools/clang/include/clang/AST/APValue.h @@ -14,11 +14,13 @@ #ifndef LLVM_CLANG_AST_APVALUE_H #define LLVM_CLANG_AST_APVALUE_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/APFloat.h" namespace clang { class CharUnits; + class DiagnosticBuilder; class Expr; /// APValue - This class implements a discriminated union of [uninitialized] @@ -103,7 +105,7 @@ public: bool isLValue() const { return Kind == LValue; } bool isVector() const { return Kind == Vector; } - void print(llvm::raw_ostream &OS) const; + void print(raw_ostream &OS) const; void dump() const; APSInt &getInt() { @@ -233,11 +235,15 @@ private: void MakeLValue(); }; -inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) { +inline raw_ostream &operator<<(raw_ostream &OS, const APValue &V) { V.print(OS); return OS; } +// Writes a concise representation of V to DB, in a single << operation. +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const APValue &V); + } // end namespace clang. #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h index 1526f36..c4ffac5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h @@ -37,7 +37,6 @@ namespace llvm { struct fltSemantics; - class raw_ostream; } namespace clang { @@ -45,7 +44,7 @@ namespace clang { class ASTRecordLayout; class BlockExpr; class CharUnits; - class Diagnostic; + class DiagnosticsEngine; class Expr; class ExternalASTSource; class ASTMutationListener; @@ -64,6 +63,7 @@ namespace clang { class ObjCIvarDecl; class ObjCIvarRefExpr; class ObjCPropertyDecl; + class ParmVarDecl; class RecordDecl; class StoredDeclsMap; class TagDecl; @@ -120,6 +120,7 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> { mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes; mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes; mutable llvm::FoldingSet<AutoType> AutoTypes; + mutable llvm::FoldingSet<AtomicType> AtomicTypes; llvm::FoldingSet<AttributedType> AttributedTypes; mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; @@ -149,10 +150,19 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> { /// \brief Mapping from ObjCContainers to their ObjCImplementations. llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls; + + /// \brief Mapping from ObjCMethod to its duplicate declaration in the same + /// interface. + llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls; /// \brief Mapping from __block VarDecls to their copy initialization expr. llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits; + /// \brief Mapping from class scope functions specialization to their + /// template patterns. + llvm::DenseMap<const FunctionDecl*, FunctionDecl*> + ClassScopeSpecializationPattern; + /// \brief Representation of a "canonical" template template parameter that /// is used in canonical template names. class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode { @@ -175,34 +185,41 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> { TemplateTemplateParmDecl * getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; - /// \brief Whether __[u]int128_t identifier is installed. - bool IsInt128Installed; + /// \brief The typedef for the __int128_t type. + mutable TypedefDecl *Int128Decl; + /// \brief The typedef for the __uint128_t type. + mutable TypedefDecl *UInt128Decl; + /// BuiltinVaListType - built-in va list type. /// This is initially null and set by Sema::LazilyCreateBuiltin when /// a builtin that takes a valist is encountered. QualType BuiltinVaListType; - /// ObjCIdType - a pseudo built-in typedef type (set by Sema). - QualType ObjCIdTypedefType; - - /// ObjCSelType - another pseudo built-in typedef type (set by Sema). - QualType ObjCSelTypedefType; + /// \brief The typedef for the predefined 'id' type. + mutable TypedefDecl *ObjCIdDecl; + + /// \brief The typedef for the predefined 'SEL' type. + mutable TypedefDecl *ObjCSelDecl; - /// ObjCProtoType - another pseudo built-in typedef type (set by Sema). QualType ObjCProtoType; const RecordType *ProtoStructType; - /// ObjCClassType - another pseudo built-in typedef type (set by Sema). - QualType ObjCClassTypedefType; + /// \brief The typedef for the predefined 'Class' type. + mutable TypedefDecl *ObjCClassDecl; + + // Typedefs which may be provided defining the structure of Objective-C + // pseudo-builtins + QualType ObjCIdRedefinitionType; + QualType ObjCClassRedefinitionType; + QualType ObjCSelRedefinitionType; QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTypeDecl; - mutable RecordDecl *NSConstantStringTypeDecl; - - mutable RecordDecl *ObjCFastEnumerationStateTypeDecl; - + /// \brief The typedef declaration for the Objective-C "instancetype" type. + TypedefDecl *ObjCInstanceTypeDecl; + /// \brief The type for the C FILE type. TypeDecl *FILEDecl; @@ -213,9 +230,15 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> { TypeDecl *sigjmp_bufDecl; /// \brief Type for the Block descriptor for Blocks CodeGen. + /// + /// Since this is only used for generation of debug info, it is not + /// serialized. mutable RecordDecl *BlockDescriptorType; /// \brief Type for the Block descriptor for Blocks CodeGen. + /// + /// Since this is only used for generation of debug info, it is not + /// serialized. mutable RecordDecl *BlockDescriptorExtendedType; /// \brief Declaration for the CUDA cudaConfigureCall function. @@ -295,6 +318,12 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> { typedef UsuallyTinyPtrVector<const CXXMethodDecl> CXXMethodVector; llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods; + /// \brief Mapping that stores parameterIndex values for ParmVarDecls + /// when that value exceeds the bitfield size of + /// ParmVarDeclBits.ParameterIndex. + typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable; + ParameterIndexTable ParamIndices; + TranslationUnitDecl *TUDecl; /// SourceMgr - The associated SourceManager object. @@ -302,7 +331,7 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> { /// LangOpts - The language options used to create the AST associated with /// this ASTContext object. - LangOptions LangOpts; + LangOptions &LangOpts; /// \brief The allocator used to create AST objects. /// @@ -318,26 +347,29 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> { CXXABI *createCXXABI(const TargetInfo &T); /// \brief The logical -> physical address space map. - const LangAS::Map &AddrSpaceMap; + const LangAS::Map *AddrSpaceMap; friend class ASTDeclReader; - + friend class ASTReader; + friend class ASTWriter; + + const TargetInfo *Target; + clang::PrintingPolicy PrintingPolicy; + public: - const TargetInfo &Target; IdentifierTable &Idents; SelectorTable &Selectors; Builtin::Context &BuiltinInfo; mutable DeclarationNameTable DeclarationNames; llvm::OwningPtr<ExternalASTSource> ExternalSource; ASTMutationListener *Listener; - clang::PrintingPolicy PrintingPolicy; - // Typedefs which may be provided defining the structure of Objective-C - // pseudo-builtins - QualType ObjCIdRedefinitionType; - QualType ObjCClassRedefinitionType; - QualType ObjCSelRedefinitionType; + clang::PrintingPolicy getPrintingPolicy() const { return PrintingPolicy; } + void setPrintingPolicy(clang::PrintingPolicy Policy) { + PrintingPolicy = Policy; + } + SourceManager& getSourceManager() { return SourceMgr; } const SourceManager& getSourceManager() const { return SourceMgr; } void *Allocate(unsigned Size, unsigned Align = 8) const { @@ -357,9 +389,11 @@ public: return DiagAllocator; } + const TargetInfo &getTargetInfo() const { return *Target; } + const LangOptions& getLangOptions() const { return LangOpts; } - Diagnostic &getDiagnostics() const; + DiagnosticsEngine &getDiagnostics() const; FullSourceLoc getFullLoc(SourceLocation Loc) const { return FullSourceLoc(Loc,SourceMgr); @@ -377,6 +411,11 @@ public: MemberSpecializationInfo *getInstantiatedFromStaticDataMember( const VarDecl *Var); + FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD); + + void setClassScopeSpecializationPattern(FunctionDecl *FD, + FunctionDecl *Pattern); + /// \brief Note that the static data member \p Inst is an instantiation of /// the static data member template \p Tmpl of a class template. void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, @@ -413,17 +452,17 @@ public: /// BitfieldFollowsBitfield - return 'true" if 'FD' is a /// bitfield which follows the bitfield 'LastFD'. bool BitfieldFollowsBitfield(const FieldDecl *FD, - const FieldDecl *LastFD) const; + const FieldDecl *LastFD) const; - /// NoneBitfieldFollowsBitfield - return 'true" if 'FD' is not a + /// NonBitfieldFollowsBitfield - return 'true" if 'FD' is not a /// bitfield which follows the bitfield 'LastFD'. - bool NoneBitfieldFollowsBitfield(const FieldDecl *FD, - const FieldDecl *LastFD) const; + bool NonBitfieldFollowsBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; - /// BitfieldFollowsNoneBitfield - return 'true" if 'FD' is a + /// BitfieldFollowsNonBitfield - return 'true" if 'FD' is a /// bitfield which follows the none bitfield 'LastFD'. - bool BitfieldFollowsNoneBitfield(const FieldDecl *FD, - const FieldDecl *LastFD) const; + bool BitfieldFollowsNonBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; // Access to the set of methods overridden by the given C++ method. typedef CXXMethodVector::iterator overridden_cxx_method_iterator; @@ -454,6 +493,7 @@ public: CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy; CanQualType UnsignedLongLongTy, UnsignedInt128Ty; CanQualType FloatTy, DoubleTy, LongDoubleTy; + CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType VoidPtrTy, NullPtrTy; CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; @@ -463,10 +503,11 @@ public: mutable QualType AutoDeductTy; // Deduction against 'auto'. mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'. - ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t, + ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins, - unsigned size_reserve); + unsigned size_reserve, + bool DelayInitialization = false); ~ASTContext(); @@ -497,6 +538,12 @@ public: void PrintStats() const; const std::vector<Type*>& getTypes() const { return Types; } + /// \brief Retrieve the declaration for the 128-bit signed integer type. + TypedefDecl *getInt128Decl() const; + + /// \brief Retrieve the declaration for the 128-bit unsigned integer type. + TypedefDecl *getUInt128Decl() const; + //===--------------------------------------------------------------------===// // Type Constructors //===--------------------------------------------------------------------===// @@ -560,6 +607,10 @@ public: return CanQualType::CreateUnsafe(getPointerType((QualType) T)); } + /// getAtomicType - Return the uniqued reference to the atomic type for + /// the specified type. + QualType getAtomicType(QualType T) const; + /// getBlockPointerType - Return the uniqued reference to the type for a block /// of the specified type. QualType getBlockPointerType(QualType T) const; @@ -568,29 +619,10 @@ public: /// blocks. QualType getBlockDescriptorType() const; - // Set the type for a Block descriptor type. - void setBlockDescriptorType(QualType T); - /// Get the BlockDescriptorType type, or NULL if it hasn't yet been built. - QualType getRawBlockdescriptorType() { - if (BlockDescriptorType) - return getTagDeclType(BlockDescriptorType); - return QualType(); - } - /// This gets the struct used to keep track of the extended descriptor for /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; - // Set the type for a Block descriptor extended type. - void setBlockDescriptorExtendedType(QualType T); - /// Get the BlockDescriptorExtendedType type, or NULL if it hasn't yet been - /// built. - QualType getRawBlockdescriptorExtendedType() const { - if (BlockDescriptorExtendedType) - return getTagDeclType(BlockDescriptorExtendedType); - return QualType(); - } - void setcudaConfigureCallDecl(FunctionDecl *FD) { cudaConfigureCallDecl = FD; } @@ -599,7 +631,7 @@ public: } /// This builds the struct used for __block variables. - QualType BuildByRefType(llvm::StringRef DeclName, QualType Ty) const; + QualType BuildByRefType(StringRef DeclName, QualType Ty) const; /// Returns true iff we need copy/dispose helpers for the given type. bool BlockRequiresCopying(QualType Ty) const; @@ -824,19 +856,6 @@ public: // constant CFStrings. QualType getCFConstantStringType() const; - // getNSConstantStringType - Return the C structure type used to represent - // constant NSStrings. - QualType getNSConstantStringType() const; - /// Get the structure type used to representation NSStrings, or NULL - /// if it hasn't yet been built. - QualType getRawNSConstantStringType() const { - if (NSConstantStringTypeDecl) - return getTagDeclType(NSConstantStringTypeDecl); - return QualType(); - } - void setNSConstantStringType(QualType T); - - /// Get the structure type used to representation CFStrings, or NULL /// if it hasn't yet been built. QualType getRawCFConstantStringType() const { @@ -852,19 +871,56 @@ public: return ObjCConstantStringType; } - //// This gets the struct used to keep track of fast enumerations. - QualType getObjCFastEnumerationStateType() const; + /// \brief Retrieve the type that 'id' has been defined to, which may be + /// different from the built-in 'id' if 'id' has been typedef'd. + QualType getObjCIdRedefinitionType() const { + if (ObjCIdRedefinitionType.isNull()) + return getObjCIdType(); + return ObjCIdRedefinitionType; + } + + /// \brief Set the user-written type that redefines 'id'. + void setObjCIdRedefinitionType(QualType RedefType) { + ObjCIdRedefinitionType = RedefType; + } - /// Get the ObjCFastEnumerationState type, or NULL if it hasn't yet - /// been built. - QualType getRawObjCFastEnumerationStateType() const { - if (ObjCFastEnumerationStateTypeDecl) - return getTagDeclType(ObjCFastEnumerationStateTypeDecl); - return QualType(); + /// \brief Retrieve the type that 'Class' has been defined to, which may be + /// different from the built-in 'Class' if 'Class' has been typedef'd. + QualType getObjCClassRedefinitionType() const { + if (ObjCClassRedefinitionType.isNull()) + return getObjCClassType(); + return ObjCClassRedefinitionType; + } + + /// \brief Set the user-written type that redefines 'SEL'. + void setObjCClassRedefinitionType(QualType RedefType) { + ObjCClassRedefinitionType = RedefType; + } + + /// \brief Retrieve the type that 'SEL' has been defined to, which may be + /// different from the built-in 'SEL' if 'SEL' has been typedef'd. + QualType getObjCSelRedefinitionType() const { + if (ObjCSelRedefinitionType.isNull()) + return getObjCSelType(); + return ObjCSelRedefinitionType; + } + + + /// \brief Set the user-written type that redefines 'SEL'. + void setObjCSelRedefinitionType(QualType RedefType) { + ObjCSelRedefinitionType = RedefType; } - void setObjCFastEnumerationStateType(QualType T); + /// \brief Retrieve the Objective-C "instancetype" type, if already known; + /// otherwise, returns a NULL type; + QualType getObjCInstanceType() { + return getTypeDeclType(getObjCInstanceTypeDecl()); + } + /// \brief Retrieve the typedef declaration corresponding to the Objective-C + /// "instancetype" type. + TypedefDecl *getObjCInstanceTypeDecl(); + /// \brief Set the type for the C FILE type. void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; } @@ -950,26 +1006,39 @@ public: /// purpose in characters. CharUnits getObjCEncodingTypeSize(QualType t) const; - /// \brief Whether __[u]int128_t identifier is installed. - bool isInt128Installed() const { return IsInt128Installed; } - void setInt128Installed() { IsInt128Installed = true; } - + /// \brief Retrieve the typedef corresponding to the predefined 'id' type + /// in Objective-C. + TypedefDecl *getObjCIdDecl() const; + /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct. - QualType getObjCIdType() const { return ObjCIdTypedefType; } - void setObjCIdType(QualType T); + QualType getObjCIdType() const { + return getTypeDeclType(getObjCIdDecl()); + } - void setObjCSelType(QualType T); - QualType getObjCSelType() const { return ObjCSelTypedefType; } + /// \brief Retrieve the typedef corresponding to the predefined 'SEL' type + /// in Objective-C. + TypedefDecl *getObjCSelDecl() const; + + /// \brief Retrieve the type that corresponds to the predefined Objective-C + /// 'SEL' type. + QualType getObjCSelType() const { + return getTypeDeclType(getObjCSelDecl()); + } void setObjCProtoType(QualType QT); QualType getObjCProtoType() const { return ObjCProtoType; } + /// \brief Retrieve the typedef declaration corresponding to the predefined + /// Objective-C 'Class' type. + TypedefDecl *getObjCClassDecl() const; + /// This setter/getter repreents the ObjC 'Class' type. It is setup lazily, by /// Sema. 'Class' is always a (typedef for a) pointer type, a pointer to a /// struct. - QualType getObjCClassType() const { return ObjCClassTypedefType; } - void setObjCClassType(QualType T); + QualType getObjCClassType() const { + return getTypeDeclType(getObjCClassDecl()); + } void setBuiltinVaListType(QualType T); QualType getBuiltinVaListType() const { return BuiltinVaListType; } @@ -1145,7 +1214,7 @@ public: const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const; - void DumpRecordLayout(const RecordDecl *RD, llvm::raw_ostream &OS) const; + void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS) const; /// getASTObjCImplementationLayout - Get or compute information about /// the layout of the specified Objective-C implementation. This may @@ -1164,13 +1233,9 @@ public: bool isNearlyEmpty(const CXXRecordDecl *RD) const; MangleContext *createMangleContext(); - - void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI, - llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) - const; void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, - llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) const; + SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const; unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const; void CollectInheritedProtocols(const Decl *CDecl, @@ -1261,7 +1326,7 @@ public: /// \brief Retrieves the canonical representation of the given /// calling convention. CallingConv getCanonicalCallConv(CallingConv CC) const { - if (CC == CC_C) + if (!LangOpts.MRTD && CC == CC_C) return CC_Default; return CC; } @@ -1400,7 +1465,7 @@ public: if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count) return AS; else - return AddrSpaceMap[AS - LangAS::Offset]; + return (*AddrSpaceMap)[AS - LangAS::Offset]; } private: @@ -1421,13 +1486,13 @@ public: bool typesAreBlockPointerCompatible(QualType, QualType); bool isObjCIdType(QualType T) const { - return T == ObjCIdTypedefType; + return T == getObjCIdType(); } bool isObjCClassType(QualType T) const { - return T == ObjCClassTypedefType; + return T == getObjCClassType(); } bool isObjCSelType(QualType T) const { - return T == ObjCSelTypedefType; + return T == getObjCSelType(); } bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS); bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, @@ -1462,6 +1527,10 @@ public: bool Unqualified = false); QualType mergeObjCGCQualifiers(QualType, QualType); + + bool FunctionTypesMatchOnNSConsumedAttrs( + const FunctionProtoType *FromFunctionType, + const FunctionProtoType *ToFunctionType); void ResetObjCLayout(const ObjCContainerDecl *CD) { ObjCLayouts[CD] = 0; @@ -1521,6 +1590,22 @@ public: /// \brief Set the implementation of ObjCCategoryDecl. void setObjCImplementation(ObjCCategoryDecl *CatD, ObjCCategoryImplDecl *ImplD); + + /// \brief Get the duplicate declaration of a ObjCMethod in the same + /// interface, or null if non exists. + const ObjCMethodDecl *getObjCMethodRedeclaration( + const ObjCMethodDecl *MD) const { + llvm::DenseMap<const ObjCMethodDecl*, const ObjCMethodDecl*>::const_iterator + I = ObjCMethodRedecls.find(MD); + if (I == ObjCMethodRedecls.end()) + return 0; + return I->second; + } + + void setObjCMethodRedeclaration(const ObjCMethodDecl *MD, + const ObjCMethodDecl *Redecl) { + ObjCMethodRedecls[MD] = Redecl; + } /// \brief Set the copy inialization expression of a block var decl. void setBlockVarCopyInits(VarDecl*VD, Expr* Init); @@ -1570,6 +1655,15 @@ public: /// it is not used. bool DeclMustBeEmitted(const Decl *D); + + /// \brief Used by ParmVarDecl to store on the side the + /// index of the parameter when it exceeds the size of the normal bitfield. + void setParameterIndex(const ParmVarDecl *D, unsigned index); + + /// \brief Used by ParmVarDecl to retrieve on the side the + /// index of the parameter when it exceeds the size of the normal bitfield. + unsigned getParameterIndex(const ParmVarDecl *D) const; + //===--------------------------------------------------------------------===// // Statistics //===--------------------------------------------------------------------===// @@ -1620,7 +1714,18 @@ private: ASTContext(const ASTContext&); // DO NOT IMPLEMENT void operator=(const ASTContext&); // DO NOT IMPLEMENT - void InitBuiltinTypes(); +public: + /// \brief Initialize built-in types. + /// + /// This routine may only be invoked once for a given ASTContext object. + /// It is normally invoked by the ASTContext constructor. However, the + /// constructor can be asked to delay initialization, which places the burden + /// of calling this function on the user of that object. + /// + /// \param Target The target + void InitBuiltinTypes(const TargetInfo &Target); + +private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); // Return the ObjC type encoding for a given type. @@ -1644,7 +1749,7 @@ private: private: /// \brief A set of deallocations that should be performed when the /// ASTContext is destroyed. - llvm::SmallVector<std::pair<void (*)(void*), void *>, 16> Deallocations; + SmallVector<std::pair<void (*)(void*), void *>, 16> Deallocations; // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, @@ -1660,13 +1765,13 @@ private: }; /// @brief Utility function for constructing a nullary selector. -static inline Selector GetNullarySelector(llvm::StringRef name, ASTContext& Ctx) { +static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(0, &II); } /// @brief Utility function for constructing an unary selector. -static inline Selector GetUnarySelector(llvm::StringRef name, ASTContext& Ctx) { +static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(1, &II); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h b/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h index 70a548d..b005711 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM, #define ASTSTART #include "clang/Basic/DiagnosticASTKinds.inc" #undef DIAG @@ -24,27 +24,27 @@ namespace clang { }; } // end namespace diag - /// \brief Diagnostic argument formatting function for diagnostics that + /// \brief DiagnosticsEngine argument formatting function for diagnostics that /// involve AST nodes. /// /// This function formats diagnostic arguments for various AST nodes, /// including types, declaration names, nested name specifiers, and /// declaration contexts, into strings that can be printed as part of /// diagnostics. It is meant to be used as the argument to - /// \c Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext - /// pointer. + /// \c DiagnosticsEngine::SetArgToStringFn(), where the cookie is an \c + /// ASTContext pointer. void FormatASTNodeDiagnosticArgument( - Diagnostic::ArgumentKind Kind, + DiagnosticsEngine::ArgumentKind Kind, intptr_t Val, const char *Modifier, unsigned ModLen, const char *Argument, unsigned ArgLen, - const Diagnostic::ArgumentValue *PrevArgs, + const DiagnosticsEngine::ArgumentValue *PrevArgs, unsigned NumPrevArgs, - llvm::SmallVectorImpl<char> &Output, + SmallVectorImpl<char> &Output, void *Cookie, - llvm::SmallVectorImpl<intptr_t> &QualTypeVals); + SmallVectorImpl<intptr_t> &QualTypeVals); } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h b/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h index e153596..b583fbf 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h @@ -25,7 +25,7 @@ namespace clang { class ASTContext; class Decl; class DeclContext; - class Diagnostic; + class DiagnosticsEngine; class Expr; class FileManager; class IdentifierInfo; @@ -67,7 +67,7 @@ namespace clang { /// \brief Imported, anonymous tag declarations that are missing their /// corresponding typedefs. - llvm::SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs; + SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs; /// \brief Declaration (from, to) pairs that are known not to be equivalent /// (which we have already complained about). diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h index 470cca8..793d3ee 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h @@ -22,6 +22,8 @@ namespace clang { class ClassTemplateSpecializationDecl; class FunctionDecl; class FunctionTemplateDecl; + class ObjCCategoryDecl; + class ObjCInterfaceDecl; /// \brief An abstract interface that should be implemented by listeners /// that want to be notified when an AST entity gets modified after its @@ -54,6 +56,10 @@ public: /// \brief A static data member was implicitly instantiated. virtual void StaticDataMemberInstantiated(const VarDecl *D) {} + + /// \brief A new objc category class was added for an interface. + virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, + const ObjCInterfaceDecl *IFD) {} }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/Attr.h b/contrib/llvm/tools/clang/include/clang/AST/Attr.h index 7190239..cf2e3c5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Attr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Attr.h @@ -14,18 +14,18 @@ #ifndef LLVM_CLANG_AST_ATTR_H #define LLVM_CLANG_AST_ATTR_H -#include "llvm/Support/Casting.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSwitch.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/AttrKinds.h" #include "clang/AST/Type.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" #include <cassert> #include <cstring> #include <algorithm> -using llvm::dyn_cast; namespace clang { class ASTContext; @@ -58,7 +58,7 @@ namespace clang { /// Attr - This represents one attribute. class Attr { private: - SourceLocation Loc; + SourceRange Range; unsigned AttrKind : 16; protected: @@ -67,11 +67,10 @@ protected: virtual ~Attr(); void* operator new(size_t bytes) throw() { - assert(0 && "Attrs cannot be allocated with regular 'new'."); - return 0; + llvm_unreachable("Attrs cannot be allocated with regular 'new'."); } void operator delete(void* data) throw() { - assert(0 && "Attrs cannot be released with regular 'delete'."); + llvm_unreachable("Attrs cannot be released with regular 'delete'."); } public: @@ -86,8 +85,8 @@ public: } protected: - Attr(attr::Kind AK, SourceLocation L) - : Loc(L), AttrKind(AK), Inherited(false) {} + Attr(attr::Kind AK, SourceRange R) + : Range(R), AttrKind(AK), Inherited(false) {} public: @@ -95,8 +94,9 @@ public: return static_cast<attr::Kind>(AttrKind); } - SourceLocation getLocation() const { return Loc; } - void setLocation(SourceLocation L) { Loc = L; } + SourceLocation getLocation() const { return Range.getBegin(); } + SourceRange getRange() const { return Range; } + void setRange(SourceRange R) { Range = R; } bool isInherited() const { return Inherited; } @@ -109,8 +109,8 @@ public: class InheritableAttr : public Attr { protected: - InheritableAttr(attr::Kind AK, SourceLocation L) - : Attr(AK, L) {} + InheritableAttr(attr::Kind AK, SourceRange R) + : Attr(AK, R) {} public: void setInherited(bool I) { Inherited = I; } @@ -124,8 +124,8 @@ public: class InheritableParamAttr : public InheritableAttr { protected: - InheritableParamAttr(attr::Kind AK, SourceLocation L) - : InheritableAttr(AK, L) {} + InheritableParamAttr(attr::Kind AK, SourceRange R) + : InheritableAttr(AK, R) {} public: // Implement isa/cast/dyncast/etc. @@ -138,8 +138,8 @@ public: #include "clang/AST/Attrs.inc" /// AttrVec - A vector of Attr, which is how they are stored on the AST. -typedef llvm::SmallVector<Attr*, 2> AttrVec; -typedef llvm::SmallVector<const Attr*, 2> ConstAttrVec; +typedef SmallVector<Attr*, 2> AttrVec; +typedef SmallVector<const Attr*, 2> ConstAttrVec; /// DestroyAttrs - Destroy the contents of an AttrVec. inline void DestroyAttrs (AttrVec& V, ASTContext &C) { @@ -159,12 +159,12 @@ class specific_attr_iterator { mutable AttrVec::const_iterator Current; void AdvanceToNext() const { - while (!llvm::isa<SpecificAttr>(*Current)) + while (!isa<SpecificAttr>(*Current)) ++Current; } void AdvanceToNext(AttrVec::const_iterator I) const { - while (Current != I && !llvm::isa<SpecificAttr>(*Current)) + while (Current != I && !isa<SpecificAttr>(*Current)) ++Current; } @@ -180,11 +180,11 @@ public: reference operator*() const { AdvanceToNext(); - return llvm::cast<SpecificAttr>(*Current); + return cast<SpecificAttr>(*Current); } pointer operator->() const { AdvanceToNext(); - return llvm::cast<SpecificAttr>(*Current); + return cast<SpecificAttr>(*Current); } specific_attr_iterator& operator++() { diff --git a/contrib/llvm/tools/clang/include/clang/AST/BaseSubobject.h b/contrib/llvm/tools/clang/include/clang/AST/BaseSubobject.h new file mode 100644 index 0000000..6a036bb --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/BaseSubobject.h @@ -0,0 +1,87 @@ +//===--- BaseSubobject.h - BaseSubobject class ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides a definition of the BaseSubobject class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_BASESUBOBJECT_H +#define LLVM_CLANG_AST_BASESUBOBJECT_H + +#include "clang/AST/CharUnits.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/type_traits.h" + +namespace clang { + class CXXRecordDecl; + +// BaseSubobject - Uniquely identifies a direct or indirect base class. +// Stores both the base class decl and the offset from the most derived class to +// the base class. Used for vtable and VTT generation. +class BaseSubobject { + /// Base - The base class declaration. + const CXXRecordDecl *Base; + + /// BaseOffset - The offset from the most derived class to the base class. + CharUnits BaseOffset; + +public: + BaseSubobject() { } + BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset) + : Base(Base), BaseOffset(BaseOffset) { } + + /// getBase - Returns the base class declaration. + const CXXRecordDecl *getBase() const { return Base; } + + /// getBaseOffset - Returns the base class offset. + CharUnits getBaseOffset() const { return BaseOffset; } + + friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) { + return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset; + } +}; + +} // end namespace clang + +namespace llvm { + +template<> struct DenseMapInfo<clang::BaseSubobject> { + static clang::BaseSubobject getEmptyKey() { + return clang::BaseSubobject( + DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(), + clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey())); + } + + static clang::BaseSubobject getTombstoneKey() { + return clang::BaseSubobject( + DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(), + clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey())); + } + + static unsigned getHashValue(const clang::BaseSubobject &Base) { + return + DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^ + DenseMapInfo<int64_t>::getHashValue(Base.getBaseOffset().getQuantity()); + } + + static bool isEqual(const clang::BaseSubobject &LHS, + const clang::BaseSubobject &RHS) { + return LHS == RHS; + } +}; + +// It's OK to treat BaseSubobject as a POD type. +template <> struct isPodLike<clang::BaseSubobject> { + static const bool value = true; +}; + +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h index d712e7d..44c554b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h @@ -66,7 +66,7 @@ struct CXXBasePathElement { /// structure, which captures both the link from a derived class to one of its /// direct bases and identification describing which base class /// subobject is being used. -class CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> { +class CXXBasePath : public SmallVector<CXXBasePathElement, 4> { public: CXXBasePath() : Access(AS_public) {} @@ -80,7 +80,7 @@ public: DeclContext::lookup_result Decls; void clear() { - llvm::SmallVectorImpl<CXXBasePathElement>::clear(); + SmallVectorImpl<CXXBasePathElement>::clear(); Access = AS_public; } }; @@ -272,14 +272,14 @@ struct UniqueVirtualMethod { /// pair is the virtual method that overrides it (including the /// subobject in which that virtual function occurs). class OverridingMethods { - llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> > + llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> > Overrides; public: // Iterate over the set of subobjects that have overriding methods. - typedef llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> > + typedef llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> > ::iterator iterator; - typedef llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> > + typedef llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> > ::const_iterator const_iterator; iterator begin() { return Overrides.begin(); } const_iterator begin() const { return Overrides.begin(); } @@ -289,9 +289,9 @@ public: // Iterate over the set of overriding virtual methods in a given // subobject. - typedef llvm::SmallVector<UniqueVirtualMethod, 4>::iterator + typedef SmallVector<UniqueVirtualMethod, 4>::iterator overriding_iterator; - typedef llvm::SmallVector<UniqueVirtualMethod, 4>::const_iterator + typedef SmallVector<UniqueVirtualMethod, 4>::const_iterator overriding_const_iterator; // Add a new overriding method for a particular subobject. diff --git a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h index d7cbd08..5be3582 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h @@ -125,6 +125,12 @@ namespace clang { /// isNegative - Test whether the quantity is less than zero. bool isNegative() const { return Quantity < 0; } + /// isPowerOfTwo - Test whether the quantity is a power of two. + /// Zero is not a power of two. + bool isPowerOfTwo() const { + return (Quantity & -Quantity) == Quantity; + } + // Arithmetic operators. CharUnits operator* (QuantityType N) const { return CharUnits(Quantity * N); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Decl.h b/contrib/llvm/tools/clang/include/clang/AST/Decl.h index 5691e99..a02a2ce 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Decl.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Decl.h @@ -20,6 +20,7 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" #include "clang/Basic/Linkage.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" namespace clang { @@ -32,6 +33,7 @@ class StringLiteral; class NestedNameSpecifier; class TemplateParameterList; class TemplateArgumentList; +struct ASTTemplateArgumentListInfo; class MemberSpecializationInfo; class FunctionTemplateSpecializationInfo; class DependentFunctionTemplateSpecializationInfo; @@ -115,7 +117,7 @@ public: /// getName - Get the name of identifier for this declaration as a StringRef. /// This requires that the declaration have a name and that it be a simple /// identifier. - llvm::StringRef getName() const { + StringRef getName() const { assert(Name.isIdentifier() && "Name is not a simple identifier"); return getIdentifier() ? getIdentifier()->getName() : ""; } @@ -132,7 +134,7 @@ public: // FIXME: Deprecated, move clients to getName(). std::string getNameAsString() const { return Name.getAsString(); } - void printName(llvm::raw_ostream &os) const { return Name.printName(os); } + void printName(raw_ostream &os) const { return Name.printName(os); } /// getDeclName - Get the actual, stored name of the declaration, /// which may be a special name. @@ -180,6 +182,16 @@ public: /// \brief Determine whether this declaration has linkage. bool hasLinkage() const; + /// \brief Whether this declaration was marked as being private to the + /// module in which it was defined. + bool isModulePrivate() const { return ModulePrivate; } + + /// \brief Specify whether this declaration was marked as being private + /// to the module in which it was defined. + void setModulePrivate(bool MP = true) { + ModulePrivate = MP; + } + /// \brief Determine whether this declaration is a C++ class member. bool isCXXClassMember() const { const DeclContext *DC = getDeclContext(); @@ -294,9 +306,8 @@ public: static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; } }; -inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, - const NamedDecl *ND) { - ND->getDeclName().printName(OS); +inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) { + ND.printName(OS); return OS; } @@ -706,13 +717,18 @@ private: /// \brief Whether this variable is an ARC pseudo-__strong /// variable; see isARCPseudoStrong() for details. unsigned ARCPseudoStrong : 1; + + /// \brief Whether this variable is (C++0x) constexpr. + unsigned IsConstexpr : 1; }; - enum { NumVarDeclBits = 13 }; // one reserved bit + enum { NumVarDeclBits = 13 }; friend class ASTDeclReader; friend class StmtIteratorBase; protected: + enum { NumParameterIndexBits = 8 }; + class ParmVarDeclBitfields { friend class ParmVarDecl; friend class ASTDeclReader; @@ -737,7 +753,7 @@ protected: /// The number of parameters preceding this parameter in the /// function parameter scope in which it was declared. - unsigned ParameterIndex : 8; + unsigned ParameterIndex : NumParameterIndexBits; }; union { @@ -802,7 +818,7 @@ public: return !isFileVarDecl(); // Return true for: Auto, Register. - // Return false for: Extern, Static, PrivateExtern. + // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal. return getStorageClass() >= SC_Auto; } @@ -1128,6 +1144,10 @@ public: bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; } void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; } + /// Whether this variable is (C++0x) constexpr. + bool isConstexpr() const { return VarDeclBits.IsConstexpr; } + void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; } + /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. @@ -1198,11 +1218,11 @@ public: StorageClass S, StorageClass SCAsWritten, Expr *DefArg); + virtual SourceRange getSourceRange() const; + void setObjCMethodScopeInfo(unsigned parameterIndex) { ParmVarDeclBits.IsObjCMethodParam = true; - - ParmVarDeclBits.ParameterIndex = parameterIndex; - assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!"); + setParameterIndex(parameterIndex); } void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) { @@ -1211,8 +1231,7 @@ public: ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth; assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && "truncation!"); - ParmVarDeclBits.ParameterIndex = parameterIndex; - assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!"); + setParameterIndex(parameterIndex); } bool isObjCMethodParameter() const { @@ -1226,7 +1245,7 @@ public: /// Returns the index of this parameter in its prototype or method scope. unsigned getFunctionScopeIndex() const { - return ParmVarDeclBits.ParameterIndex; + return getParameterIndex(); } ObjCDeclQualifier getObjCDeclQualifier() const { @@ -1343,6 +1362,26 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const ParmVarDecl *D) { return true; } static bool classofKind(Kind K) { return K == ParmVar; } + +private: + enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 }; + + void setParameterIndex(unsigned parameterIndex) { + if (parameterIndex >= ParameterIndexSentinel) { + setParameterIndexLarge(parameterIndex); + return; + } + + ParmVarDeclBits.ParameterIndex = parameterIndex; + assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!"); + } + unsigned getParameterIndex() const { + unsigned d = ParmVarDeclBits.ParameterIndex; + return d == ParameterIndexSentinel ? getParameterIndexLarge() : d; + } + + void setParameterIndexLarge(unsigned parameterIndex); + unsigned getParameterIndexLarge() const; }; /// FunctionDecl - An instance of this class is created to represent a @@ -1394,6 +1433,7 @@ private: bool IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl bool HasImplicitReturnZero : 1; bool IsLateTemplateParsed : 1; + bool IsConstexpr : 1; /// \brief End part of this FunctionDecl's source range. /// @@ -1460,13 +1500,14 @@ private: void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD, TemplateSpecializationKind TSK); - void setParams(ASTContext &C, ParmVarDecl **NewParamInfo, unsigned NumParams); + void setParams(ASTContext &C, llvm::ArrayRef<ParmVarDecl *> NewParamInfo); protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified) + StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified, + bool isConstexprSpecified) : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, StartLoc), DeclContext(DK), @@ -1477,7 +1518,7 @@ protected: HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), IsDefaulted(false), IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), - EndRangeLoc(NameInfo.getEndLoc()), + IsConstexpr(isConstexprSpecified), EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), DNLoc(NameInfo.getInfo()) {} @@ -1500,11 +1541,13 @@ public: StorageClass SC = SC_None, StorageClass SCAsWritten = SC_None, bool isInlineSpecified = false, - bool hasWrittenPrototype = true) { + bool hasWrittenPrototype = true, + bool isConstexprSpecified = false) { DeclarationNameInfo NameInfo(N, NLoc); return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC, SCAsWritten, - isInlineSpecified, hasWrittenPrototype); + isInlineSpecified, hasWrittenPrototype, + isConstexprSpecified); } static FunctionDecl *Create(ASTContext &C, DeclContext *DC, @@ -1514,7 +1557,8 @@ public: StorageClass SC = SC_None, StorageClass SCAsWritten = SC_None, bool isInlineSpecified = false, - bool hasWrittenPrototype = true); + bool hasWrittenPrototype = true, + bool isConstexprSpecified = false); DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); @@ -1600,10 +1644,6 @@ public: bool isPure() const { return IsPure; } void setPure(bool P = true); - /// Whether this is a constexpr function or constexpr constructor. - // FIXME: C++0x: Implement tracking of the constexpr specifier. - bool isConstExpr() const { return false; } - /// Whether this templated function will be late parsed. bool isLateTemplateParsed() const { return IsLateTemplateParsed; } void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; } @@ -1646,6 +1686,10 @@ public: bool hasInheritedPrototype() const { return HasInheritedPrototype; } void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; } + /// Whether this is a (C++0x) constexpr function or constexpr constructor. + bool isConstexpr() const { return IsConstexpr; } + void setConstexpr(bool IC) { IsConstexpr = IC; } + /// \brief Whether this function has been deleted. /// /// A function that is "deleted" (via the C++0x "= delete" syntax) @@ -1726,8 +1770,8 @@ public: assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } - void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) { - setParams(getASTContext(), NewParamInfo, NumParams); + void setParams(llvm::ArrayRef<ParmVarDecl *> NewParamInfo) { + setParams(getASTContext(), NewParamInfo); } /// getMinRequiredArguments - Returns the minimum number of arguments @@ -1768,11 +1812,13 @@ public: } /// \brief Determine whether this function should be inlined, because it is - /// either marked "inline" or is a member function of a C++ class that - /// was defined in the class body. + /// either marked "inline" or "constexpr" or is a member function of a class + /// that was defined in the class body. bool isInlined() const; bool isInlineDefinitionExternallyVisible() const; + + bool doesDeclarationForceExternallyVisibleDefinition() const; /// isOverloadedOperator - Whether this function declaration /// represents an C++ overloaded operator, e.g., "operator+". @@ -1847,7 +1893,11 @@ public: bool isFunctionTemplateSpecialization() const { return getPrimaryTemplate() != 0; } - + + /// \brief Retrieve the class scope template pattern that this function + /// template specialization is instantiated from. + FunctionDecl *getClassScopeSpecializationPattern() const; + /// \brief If this function is actually a function template specialization, /// retrieve information about this function template specialization. /// Otherwise, returns NULL. @@ -1887,7 +1937,7 @@ public: /// or if it had no explicit template argument list, returns NULL. /// Note that it an explicit template argument list may be written empty, /// e.g., template<> void foo<>(char* s); - const TemplateArgumentListInfo* + const ASTTemplateArgumentListInfo* getTemplateSpecializationArgsAsWritten() const; /// \brief Specify that this function declaration is actually a function @@ -1945,7 +1995,7 @@ public: /// specialization or a member of a class template specialization. /// /// \returns the first point of instantiation, if this function was - /// instantiated from a template; otherwie, returns an invalid source + /// instantiated from a template; otherwise, returns an invalid source /// location. SourceLocation getPointOfInstantiation() const; @@ -2033,6 +2083,7 @@ public: Expr *getBitWidth() const { return isBitField() ? InitializerOrBitWidth.getPointer() : 0; } + unsigned getBitWidthValue(const ASTContext &Ctx) const; void setBitWidth(Expr *BW) { assert(!InitializerOrBitWidth.getPointer() && "bit width or initializer already set"); @@ -2308,9 +2359,10 @@ private: /// TagDeclKind - The TagKind enum. unsigned TagDeclKind : 2; - /// IsDefinition - True if this is a definition ("struct foo {};"), false if - /// it is a declaration ("struct foo;"). - bool IsDefinition : 1; + /// IsCompleteDefinition - True if this is a definition ("struct foo + /// {};"), false if it is a declaration ("struct foo;"). It is not + /// a definition until the definition has been fully processed. + bool IsCompleteDefinition : 1; /// IsBeingDefined - True if this is currently being defined. bool IsBeingDefined : 1; @@ -2320,6 +2372,9 @@ private: /// in the syntax of a declarator. bool IsEmbeddedInDeclarator : 1; + /// /brief True if this tag is free standing, e.g. "struct foo;". + bool IsFreeStanding : 1; + protected: // These are used by (and only defined for) EnumDecl. unsigned NumPositiveBits : 8; @@ -2367,9 +2422,10 @@ protected: assert((DK != Enum || TK == TTK_Enum) && "EnumDecl not matched with TTK_Enum"); TagDeclKind = TK; - IsDefinition = false; + IsCompleteDefinition = false; IsBeingDefined = false; IsEmbeddedInDeclarator = false; + IsFreeStanding = false; setPreviousDeclaration(PrevDecl); } @@ -2408,14 +2464,15 @@ public: } /// isThisDeclarationADefinition() - Return true if this declaration - /// defines the type. Provided for consistency. + /// is a completion definintion of the type. Provided for consistency. bool isThisDeclarationADefinition() const { - return isDefinition(); + return isCompleteDefinition(); } - /// isDefinition - Return true if this decl has its body specified. - bool isDefinition() const { - return IsDefinition; + /// isCompleteDefinition - Return true if this decl has its body + /// fully specified. + bool isCompleteDefinition() const { + return IsCompleteDefinition; } /// isBeingDefined - Return true if this decl is currently being defined. @@ -2430,6 +2487,11 @@ public: IsEmbeddedInDeclarator = isInDeclarator; } + bool isFreeStanding() const { return IsFreeStanding; } + void setFreeStanding(bool isFreeStanding = true) { + IsFreeStanding = isFreeStanding; + } + /// \brief Whether this declaration declares a type that is /// dependent, i.e., a type that somehow depends on template /// parameters. @@ -2444,14 +2506,15 @@ public: /// getDefinition - Returns the TagDecl that actually defines this /// struct/union/class/enum. When determining whether or not a - /// struct/union/class/enum is completely defined, one should use this method - /// as opposed to 'isDefinition'. 'isDefinition' indicates whether or not a - /// specific TagDecl is defining declaration, not whether or not the - /// struct/union/class/enum type is defined. This method returns NULL if - /// there is no TagDecl that defines the struct/union/class/enum. - TagDecl* getDefinition() const; + /// struct/union/class/enum has a definition, one should use this + /// method as opposed to 'isDefinition'. 'isDefinition' indicates + /// whether or not a specific TagDecl is defining declaration, not + /// whether or not the struct/union/class/enum type is defined. + /// This method returns NULL if there is no TagDecl that defines + /// the struct/union/class/enum. + TagDecl *getDefinition() const; - void setDefinition(bool V) { IsDefinition = V; } + void setCompleteDefinition(bool V) { IsCompleteDefinition = V; } const char *getKindName() const { return TypeWithKeyword::getTagTypeKindName(getTagKind()); @@ -2691,7 +2754,7 @@ public: /// \brief Returns true if this can be considered a complete type. bool isComplete() const { - return isDefinition() || isFixed(); + return isCompleteDefinition() || isFixed(); } /// \brief Returns the enumeration (declared within the template) @@ -2794,14 +2857,15 @@ public: /// \endcode bool isInjectedClassName() const; - /// getDefinition - Returns the RecordDecl that actually defines this - /// struct/union/class. When determining whether or not a struct/union/class - /// is completely defined, one should use this method as opposed to - /// 'isDefinition'. 'isDefinition' indicates whether or not a specific - /// RecordDecl is defining declaration, not whether or not the record - /// type is defined. This method returns NULL if there is no RecordDecl - /// that defines the struct/union/tag. - RecordDecl* getDefinition() const { + /// getDefinition - Returns the RecordDecl that actually defines + /// this struct/union/class. When determining whether or not a + /// struct/union/class is completely defined, one should use this + /// method as opposed to 'isCompleteDefinition'. + /// 'isCompleteDefinition' indicates whether or not a specific + /// RecordDecl is a completed definition, not whether or not the + /// record type is defined. This method returns NULL if there is + /// no RecordDecl that defines the struct/union/tag. + RecordDecl *getDefinition() const { return cast_or_null<RecordDecl>(TagDecl::getDefinition()); } @@ -2967,7 +3031,7 @@ public: assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } - void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams); + void setParams(llvm::ArrayRef<ParmVarDecl *> NewParamInfo); /// hasCaptures - True if this block (or its nested blocks) captures /// anything of local storage from its enclosing scopes. @@ -3010,8 +3074,9 @@ public: /// Insertion operator for diagnostics. This allows sending NamedDecl's /// into a diagnostic with <<. inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, - NamedDecl* ND) { - DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND), Diagnostic::ak_nameddecl); + const NamedDecl* ND) { + DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND), + DiagnosticsEngine::ak_nameddecl); return DB; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h index 8b2ef2a..9f29411 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h @@ -243,19 +243,23 @@ private: /// evaluated context or not, e.g. functions used in uninstantiated templates /// are regarded as "referenced" but not "used". unsigned Referenced : 1; - + protected: /// Access - Used by C++ decls for the access specifier. // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum unsigned Access : 2; friend class CXXClassMemberWrapper; - /// PCHLevel - the "level" of AST file from which this declaration was built. - unsigned PCHLevel : 2; - + /// \brief Whether this declaration was loaded from an AST file. + unsigned FromASTFile : 1; + /// ChangedAfterLoad - if this declaration has changed since being loaded unsigned ChangedAfterLoad : 1; + /// \brief Whether this declaration is private to the module in which it was + /// defined. + unsigned ModulePrivate : 1; + /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. unsigned IdentifierNamespace : 12; @@ -269,7 +273,9 @@ protected: /// This field is only valid for NamedDecls subclasses. mutable unsigned CachedLinkage : 2; - + friend class ASTDeclWriter; + friend class ASTDeclReader; + private: void CheckAccessDeclContext() const; @@ -279,7 +285,8 @@ protected: : NextDeclInContext(0), DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false), Referenced(false), - Access(AS_none), PCHLevel(0), ChangedAfterLoad(false), + Access(AS_none), FromASTFile(0), ChangedAfterLoad(false), + ModulePrivate(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), HasCachedLinkage(0) { @@ -289,7 +296,8 @@ protected: Decl(Kind DK, EmptyShell Empty) : NextDeclInContext(0), DeclKind(DK), InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false), Referenced(false), - Access(AS_none), PCHLevel(0), ChangedAfterLoad(false), + Access(AS_none), FromASTFile(0), ChangedAfterLoad(false), + ModulePrivate(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), HasCachedLinkage(0) { @@ -493,25 +501,10 @@ public: /// declaration cannot be weak-imported because it has a definition. bool canBeWeakImported(bool &IsDefinition) const; - /// \brief Retrieve the level of precompiled header from which this - /// declaration was generated. - /// - /// The PCH level of a declaration describes where the declaration originated - /// from. A PCH level of 0 indicates that the declaration was parsed from - /// source. A PCH level of 1 indicates that the declaration was loaded from - /// a top-level AST file. A PCH level 2 indicates that the declaration was - /// loaded from a PCH file the AST file depends on, and so on. - unsigned getPCHLevel() const { return PCHLevel; } - - /// \brief The maximum PCH level that any declaration may have. - static const unsigned MaxPCHLevel = 3; - - /// \brief Set the PCH level of this declaration. - void setPCHLevel(unsigned Level) { - assert(Level <= MaxPCHLevel && "PCH level exceeds the maximum"); - PCHLevel = Level; - } - + /// \brief Determine whether this declaration came from an AST file (such as + /// a precompiled header or module) rather than having been parsed. + bool isFromASTFile() const { return FromASTFile; } + /// \brief Query whether this declaration was changed in a significant way /// since being loaded from an AST file. /// @@ -574,7 +567,17 @@ public: /// scoped decl is defined outside the current function or method. This is /// roughly global variables and functions, but also handles enums (which /// could be defined inside or outside a function etc). - bool isDefinedOutsideFunctionOrMethod() const; + bool isDefinedOutsideFunctionOrMethod() const { + return getParentFunctionOrMethod() == 0; + } + + /// \brief If this decl is defined inside a function/method/block it returns + /// the corresponding DeclContext, otherwise it returns null. + const DeclContext *getParentFunctionOrMethod() const; + DeclContext *getParentFunctionOrMethod() { + return const_cast<DeclContext*>( + const_cast<const Decl*>(this)->getParentFunctionOrMethod()); + } /// \brief Retrieves the "canonical" declaration of the given declaration. virtual Decl *getCanonicalDecl() { return this; } @@ -671,6 +674,9 @@ public: /// \brief Whether this declaration is a parameter pack. bool isParameterPack() const; + /// \brief returns true if this declaration is a template + bool isTemplateDecl() const; + /// \brief Whether this declaration is a function or function template. bool isFunctionOrFunctionTemplate() const; @@ -734,15 +740,16 @@ public: static DeclContext *castToDeclContext(const Decl *); static Decl *castFromDeclContext(const DeclContext *); - void print(llvm::raw_ostream &Out, unsigned Indentation = 0) const; - void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy, - unsigned Indentation = 0) const; + void print(raw_ostream &Out, unsigned Indentation = 0, + bool PrintInstantiation = false) const; + void print(raw_ostream &Out, const PrintingPolicy &Policy, + unsigned Indentation = 0, bool PrintInstantiation = false) const; static void printGroup(Decl** Begin, unsigned NumDecls, - llvm::raw_ostream &Out, const PrintingPolicy &Policy, + raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); void dump() const; void dumpXML() const; - void dumpXML(llvm::raw_ostream &OS) const; + void dumpXML(raw_ostream &OS) const; private: const Attr *getAttrsImpl() const; @@ -763,7 +770,7 @@ public: SourceManager &sm, const char *Msg) : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} - virtual void print(llvm::raw_ostream &OS) const; + virtual void print(raw_ostream &OS) const; }; class DeclContextLookupResult @@ -839,7 +846,7 @@ protected: /// /// \returns the first/last pair of declarations. static std::pair<Decl *, Decl *> - BuildDeclChain(const llvm::SmallVectorImpl<Decl*> &Decls); + BuildDeclChain(const SmallVectorImpl<Decl*> &Decls, bool FieldsAlreadyLoaded); DeclContext(Decl::Kind K) : DeclKind(K), ExternalLexicalStorage(false), @@ -892,6 +899,18 @@ public: return DeclKind == Decl::Block; } + bool isObjCContainer() const { + switch (DeclKind) { + case Decl::ObjCCategory: + case Decl::ObjCCategoryImpl: + case Decl::ObjCImplementation: + case Decl::ObjCInterface: + case Decl::ObjCProtocol: + return true; + } + return false; + } + bool isFunctionOrMethod() const { switch (DeclKind) { case Decl::Block: @@ -1243,6 +1262,15 @@ public: lookup_result lookup(DeclarationName Name); lookup_const_result lookup(DeclarationName Name) const; + /// \brief A simplistic name lookup mechanism that performs name lookup + /// into this declaration context without consulting the external source. + /// + /// This function should almost never be used, because it subverts the + /// usual relationship between a DeclContext and the external source. + /// See the ASTImporter for the (few, but important) use cases. + void localUncachedLookup(DeclarationName Name, + llvm::SmallVectorImpl<NamedDecl *> &Results); + /// @brief Makes a declaration visible within this context. /// /// This routine makes the declaration D visible to name lookup @@ -1263,14 +1291,6 @@ public: /// the declaration chains. void makeDeclVisibleInContext(NamedDecl *D, bool Recoverable = true); - /// \brief Deserialize all the visible declarations from external storage. - /// - /// Name lookup deserializes visible declarations lazily, thus a DeclContext - /// may not have a complete name lookup table. This function deserializes - /// the rest of visible declarations from the external storage and completes - /// the name lookup table. - void MaterializeVisibleDeclsFromExternalStorage(); - /// udir_iterator - Iterates through the using-directives stored /// within this context. typedef UsingDirectiveDecl * const * udir_iterator; @@ -1317,6 +1337,12 @@ public: ExternalVisibleStorage = ES; } + /// \brief Determine whether the given declaration is stored in the list of + /// declarations lexically within this context. + bool isDeclInLexicalTraversal(const Decl *D) const { + return D && (D->NextDeclInContext || D == FirstDecl || D == LastDecl); + } + static bool classof(const Decl *D); static bool classof(const DeclContext *D) { return true; } #define DECL(NAME, BASE) diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h index dd490f4..7e60773 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h @@ -363,10 +363,10 @@ class CXXRecordDecl : public RecordDecl { /// default constructor. bool HasTrivialDefaultConstructor : 1; - /// HasConstExprNonCopyMoveConstructor - True when this class has at least + /// HasConstexprNonCopyMoveConstructor - True when this class has at least /// one constexpr constructor which is neither the copy nor move /// constructor. - bool HasConstExprNonCopyMoveConstructor : 1; + bool HasConstexprNonCopyMoveConstructor : 1; /// HasTrivialCopyConstructor - True when this class has a trivial copy /// constructor. @@ -468,6 +468,14 @@ class CXXRecordDecl : public RecordDecl { /// \brief Whether we have already declared a destructor within the class. bool DeclaredDestructor : 1; + /// \brief Whether an implicit move constructor was attempted to be declared + /// but would have been deleted. + bool FailedImplicitMoveConstructor : 1; + + /// \brief Whether an implicit move assignment operator was attempted to be + /// declared but would have been deleted. + bool FailedImplicitMoveAssignment : 1; + /// NumBases - The number of base class specifiers in Bases. unsigned NumBases; @@ -780,6 +788,33 @@ public: return data().DeclaredMoveConstructor; } + /// \brief Determine whether implicit move constructor generation for this + /// class has failed before. + bool hasFailedImplicitMoveConstructor() const { + return data().FailedImplicitMoveConstructor; + } + + /// \brief Set whether implicit move constructor generation for this class + /// has failed before. + void setFailedImplicitMoveConstructor(bool Failed = true) { + data().FailedImplicitMoveConstructor = Failed; + } + + /// \brief Determine whether this class should get an implicit move + /// constructor or if any existing special member function inhibits this. + /// + /// Covers all bullets of C++0x [class.copy]p9 except the last, that the + /// constructor wouldn't be deleted, which is only looked up from a cached + /// result. + bool needsImplicitMoveConstructor() const { + return !hasFailedImplicitMoveConstructor() && + !hasDeclaredMoveConstructor() && + !hasUserDeclaredCopyConstructor() && + !hasUserDeclaredCopyAssignment() && + !hasUserDeclaredMoveAssignment() && + !hasUserDeclaredDestructor(); + } + /// hasUserDeclaredCopyAssignment - Whether this class has a /// user-declared copy assignment operator. When false, a copy /// assigment operator will be implicitly declared. @@ -807,6 +842,33 @@ public: return data().DeclaredMoveAssignment; } + /// \brief Determine whether implicit move assignment generation for this + /// class has failed before. + bool hasFailedImplicitMoveAssignment() const { + return data().FailedImplicitMoveAssignment; + } + + /// \brief Set whether implicit move assignment generation for this class + /// has failed before. + void setFailedImplicitMoveAssignment(bool Failed = true) { + data().FailedImplicitMoveAssignment = Failed; + } + + /// \brief Determine whether this class should get an implicit move + /// assignment operator or if any existing special member function inhibits + /// this. + /// + /// Covers all bullets of C++0x [class.copy]p20 except the last, that the + /// constructor wouldn't be deleted. + bool needsImplicitMoveAssignment() const { + return !hasFailedImplicitMoveAssignment() && + !hasDeclaredMoveAssignment() && + !hasUserDeclaredCopyConstructor() && + !hasUserDeclaredCopyAssignment() && + !hasUserDeclaredMoveConstructor() && + !hasUserDeclaredDestructor(); + } + /// hasUserDeclaredDestructor - Whether this class has a /// user-declared destructor. When false, a destructor will be /// implicitly declared. @@ -889,10 +951,10 @@ public: data().DeclaredDefaultConstructor); } - // hasConstExprNonCopyMoveConstructor - Whether this class has at least one - // constexpr constructor other than the copy or move constructors - bool hasConstExprNonCopyMoveConstructor() const { - return data().HasConstExprNonCopyMoveConstructor; + // hasConstexprNonCopyMoveConstructor - Whether this class has at least one + // constexpr constructor other than the copy or move constructors. + bool hasConstexprNonCopyMoveConstructor() const { + return data().HasConstexprNonCopyMoveConstructor; } // hasTrivialCopyConstructor - Whether this class has a trivial copy @@ -942,6 +1004,25 @@ public: return isTriviallyCopyable() && hasTrivialDefaultConstructor(); } + // isLiteral - Whether this class is a literal type. + // + // C++0x [basic.types]p10 + // A class type that has all the following properties: + // -- a trivial destructor + // -- every constructor call and full-expression in the + // brace-or-equal-intializers for non-static data members (if any) is + // a constant expression. + // -- it is an aggregate type or has at least one constexpr constructor or + // constructor template that is not a copy or move constructor, and + // -- all non-static data members and base classes of literal types + // + // We resolve DR1361 by ignoring the second bullet. + bool isLiteral() const { + return hasTrivialDestructor() && + (isAggregate() || hasConstexprNonCopyMoveConstructor()) && + !hasNonLiteralTypeFieldsOrBases(); + } + /// \brief If this record is an instantiation of a member class, /// retrieves the member class from which it was instantiated. /// @@ -1237,10 +1318,10 @@ protected: const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isStatic, StorageClass SCAsWritten, bool isInline, - SourceLocation EndLocation) + bool isConstexpr, SourceLocation EndLocation) : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo, (isStatic ? SC_Static : SC_None), - SCAsWritten, isInline) { + SCAsWritten, isInline, isConstexpr) { if (EndLocation.isValid()) setRangeEnd(EndLocation); } @@ -1253,6 +1334,7 @@ public: bool isStatic, StorageClass SCAsWritten, bool isInline, + bool isConstexpr, SourceLocation EndLocation); bool isStatic() const { return getStorageClass() == SC_Static; } @@ -1333,6 +1415,7 @@ public: /// void g() &&; /// void h(); /// }; + /// \endcode RefQualifierKind getRefQualifier() const { return getType()->getAs<FunctionProtoType>()->getRefQualifier(); } @@ -1630,9 +1713,9 @@ class CXXConstructorDecl : public CXXMethodDecl { const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, - bool isImplicitlyDeclared) + bool isImplicitlyDeclared, bool isConstexpr) : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false, - SC_None, isInline, SourceLocation()), + SC_None, isInline, isConstexpr, SourceLocation()), IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false), CtorInitializers(0), NumCtorInitializers(0) { setImplicit(isImplicitlyDeclared); @@ -1645,7 +1728,8 @@ public: const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicit, - bool isInline, bool isImplicitlyDeclared); + bool isInline, bool isImplicitlyDeclared, + bool isConstexpr); /// isExplicitSpecified - Whether this constructor declaration has the /// 'explicit' keyword specified. @@ -1853,7 +1937,7 @@ class CXXDestructorDecl : public CXXMethodDecl { QualType T, TypeSourceInfo *TInfo, bool isInline, bool isImplicitlyDeclared) : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false, - SC_None, isInline, SourceLocation()), + SC_None, isInline, /*isConstexpr=*/false, SourceLocation()), ImplicitlyDefined(false), OperatorDelete(0) { setImplicit(isImplicitlyDeclared); } @@ -1916,9 +2000,9 @@ class CXXConversionDecl : public CXXMethodDecl { const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isExplicitSpecified, - SourceLocation EndLocation) + bool isConstexpr, SourceLocation EndLocation) : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false, - SC_None, isInline, EndLocation), + SC_None, isInline, isConstexpr, EndLocation), IsExplicitSpecified(isExplicitSpecified) { } public: @@ -1928,6 +2012,7 @@ public: const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isExplicit, + bool isConstexpr, SourceLocation EndLocation); /// IsExplicitSpecified - Whether this conversion function declaration is diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h b/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h index 97da6ca..c5f2aa0 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h @@ -31,7 +31,7 @@ class DependentDiagnostic; struct StoredDeclsList { /// DeclsTy - When in vector form, this is what the Data pointer points to. - typedef llvm::SmallVector<NamedDecl *, 4> DeclsTy; + typedef SmallVector<NamedDecl *, 4> DeclsTy; /// \brief The stored data, which will be either a pointer to a NamedDecl, /// or a pointer to a vector. diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h index d318fc2..425c89d 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLOBJC_H #include "clang/AST/Decl.h" +#include "clang/AST/SelectorLocationsKind.h" #include "llvm/ADT/STLExtras.h" namespace clang { @@ -127,6 +128,12 @@ private: // Method has a definition. unsigned IsDefined : 1; + /// \brief Method redeclaration in the same interface. + unsigned IsRedeclaration : 1; + + /// \brief Is redeclared in the same interface. + mutable unsigned HasRedeclaration : 1; + // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum /// @required/@optional unsigned DeclImplementation : 2; @@ -138,8 +145,9 @@ private: /// \brief Indicates whether this method has a related result type. unsigned RelatedResultType : 1; - // Number of args separated by ':' in a method declaration. - unsigned NumSelectorArgs; + /// \brief Whether the locations of the selector identifiers are in a + /// "standard" position, a enum SelectorLocationsKind. + unsigned SelLocsKind : 2; // Result type of this method. QualType MethodDeclType; @@ -147,9 +155,10 @@ private: // Type source information for the result type. TypeSourceInfo *ResultTInfo; - /// ParamInfo - List of pointers to VarDecls for the formal parameters of this - /// Method. - ObjCList<ParmVarDecl> ParamInfo; + /// \brief Array of ParmVarDecls for the formal parameters of this method + /// and optionally followed by selector locations. + void *ParamsAndSelLocs; + unsigned NumParams; /// List of attributes for this method declaration. SourceLocation EndLoc; // the location of the ';' or '}'. @@ -165,6 +174,43 @@ private: /// constructed by createImplicitParams. ImplicitParamDecl *CmdDecl; + SelectorLocationsKind getSelLocsKind() const { + return (SelectorLocationsKind)SelLocsKind; + } + bool hasStandardSelLocs() const { + return getSelLocsKind() != SelLoc_NonStandard; + } + + /// \brief Get a pointer to the stored selector identifiers locations array. + /// No locations will be stored if HasStandardSelLocs is true. + SourceLocation *getStoredSelLocs() { + return reinterpret_cast<SourceLocation*>(getParams() + NumParams); + } + const SourceLocation *getStoredSelLocs() const { + return reinterpret_cast<const SourceLocation*>(getParams() + NumParams); + } + + /// \brief Get a pointer to the stored selector identifiers locations array. + /// No locations will be stored if HasStandardSelLocs is true. + ParmVarDecl **getParams() { + return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs); + } + const ParmVarDecl *const *getParams() const { + return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs); + } + + /// \brief Get the number of stored selector identifiers locations. + /// No locations will be stored if HasStandardSelLocs is true. + unsigned getNumStoredSelLocs() const { + if (hasStandardSelLocs()) + return 0; + return getNumSelectorLocs(); + } + + void setParamsAndSelLocs(ASTContext &C, + ArrayRef<ParmVarDecl*> Params, + ArrayRef<SourceLocation> SelLocs); + ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ResultTInfo, @@ -172,19 +218,23 @@ private: bool isInstance = true, bool isVariadic = false, bool isSynthesized = false, + bool isImplicitlyDeclared = false, bool isDefined = false, ImplementationControl impControl = None, - bool HasRelatedResultType = false, - unsigned numSelectorArgs = 0) + bool HasRelatedResultType = false) : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), IsInstance(isInstance), IsVariadic(isVariadic), IsSynthesized(isSynthesized), - IsDefined(isDefined), + IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), - RelatedResultType(HasRelatedResultType), NumSelectorArgs(numSelectorArgs), + RelatedResultType(HasRelatedResultType), + SelLocsKind(SelLoc_StandardNoSpace), MethodDeclType(T), ResultTInfo(ResultTInfo), - EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {} + ParamsAndSelLocs(0), NumParams(0), + EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) { + setImplicit(isImplicitlyDeclared); + } /// \brief A definition will return its interface declaration. /// An interface declaration will return its definition. @@ -194,17 +244,18 @@ private: public: static ObjCMethodDecl *Create(ASTContext &C, SourceLocation beginLoc, - SourceLocation endLoc, Selector SelInfo, + SourceLocation endLoc, + Selector SelInfo, QualType T, TypeSourceInfo *ResultTInfo, DeclContext *contextDecl, bool isInstance = true, bool isVariadic = false, bool isSynthesized = false, + bool isImplicitlyDeclared = false, bool isDefined = false, ImplementationControl impControl = None, - bool HasRelatedResultType = false, - unsigned numSelectorArgs = 0); + bool HasRelatedResultType = false); virtual ObjCMethodDecl *getCanonicalDecl(); const ObjCMethodDecl *getCanonicalDecl() const { @@ -222,11 +273,10 @@ public: /// \brief Note whether this method has a related result type. void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; } - - unsigned getNumSelectorArgs() const { return NumSelectorArgs; } - void setNumSelectorArgs(unsigned numSelectorArgs) { - NumSelectorArgs = numSelectorArgs; - } + + /// \brief True if this is a method redeclaration in the same interface. + bool isRedeclaration() const { return IsRedeclaration; } + void setAsRedeclaration(const ObjCMethodDecl *PrevMethod); // Location information, modeled after the Stmt API. SourceLocation getLocStart() const { return getLocation(); } @@ -236,6 +286,29 @@ public: return SourceRange(getLocation(), EndLoc); } + SourceLocation getSelectorStartLoc() const { return getSelectorLoc(0); } + SourceLocation getSelectorLoc(unsigned Index) const { + assert(Index < getNumSelectorLocs() && "Index out of range!"); + if (hasStandardSelLocs()) + return getStandardSelectorLoc(Index, getSelector(), + getSelLocsKind() == SelLoc_StandardWithSpace, + llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()), + NumParams), + EndLoc); + return getStoredSelLocs()[Index]; + } + + void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; + + unsigned getNumSelectorLocs() const { + if (isImplicit()) + return 0; + Selector Sel = getSelector(); + if (Sel.isUnarySelector()) + return 1; + return Sel.getNumArgs(); + } + ObjCInterfaceDecl *getClassInterface(); const ObjCInterfaceDecl *getClassInterface() const { return const_cast<ObjCMethodDecl*>(this)->getClassInterface(); @@ -256,25 +329,31 @@ public: void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; } // Iterator access to formal parameters. - unsigned param_size() const { return ParamInfo.size(); } - typedef ObjCList<ParmVarDecl>::iterator param_iterator; - param_iterator param_begin() const { return ParamInfo.begin(); } - param_iterator param_end() const { return ParamInfo.end(); } + unsigned param_size() const { return NumParams; } + typedef const ParmVarDecl *const *param_const_iterator; + typedef ParmVarDecl *const *param_iterator; + param_const_iterator param_begin() const { return getParams(); } + param_const_iterator param_end() const { return getParams() + NumParams; } + param_iterator param_begin() { return getParams(); } + param_iterator param_end() { return getParams() + NumParams; } // This method returns and of the parameters which are part of the selector // name mangling requirements. - param_iterator sel_param_end() const { - return ParamInfo.begin() + NumSelectorArgs; + param_const_iterator sel_param_end() const { + return param_begin() + getSelector().getNumArgs(); } - void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num, - unsigned numSelectorArgs) { - ParamInfo.set(List, Num, C); - NumSelectorArgs = numSelectorArgs; - } + /// \brief Sets the method's parameters and selector source locations. + /// If the method is implicit (not coming from source) \arg SelLocs is + /// ignored. + void setMethodParams(ASTContext &C, + ArrayRef<ParmVarDecl*> Params, + ArrayRef<SourceLocation> SelLocs = + ArrayRef<SourceLocation>()); // Iterator access to parameter types. typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun; - typedef llvm::mapped_iterator<param_iterator, deref_fun> arg_type_iterator; + typedef llvm::mapped_iterator<param_const_iterator, deref_fun> + arg_type_iterator; arg_type_iterator arg_type_begin() const { return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType)); @@ -337,6 +416,9 @@ public: static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) { return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC)); } + + friend class ASTDeclReader; + friend class ASTDeclWriter; }; /// ObjCContainerDecl - Represents a container for method declarations. @@ -344,14 +426,17 @@ public: /// ObjCProtocolDecl, and ObjCImplDecl. /// class ObjCContainerDecl : public NamedDecl, public DeclContext { + SourceLocation AtStart; + // These two locations in the range mark the end of the method container. // The first points to the '@' token, and the second to the 'end' token. SourceRange AtEnd; public: - ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id) - : NamedDecl(DK, DC, L, Id), DeclContext(DK) {} + ObjCContainerDecl(Kind DK, DeclContext *DC, + IdentifierInfo *Id, SourceLocation nameLoc, + SourceLocation atStartLoc) + : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} // Iterator access to properties. typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator; @@ -403,6 +488,9 @@ public: ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; + SourceLocation getAtStartLoc() const { return AtStart; } + void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } + // Marks the end of the container. SourceRange getAtEndRange() const { return AtEnd; @@ -412,7 +500,7 @@ public: } virtual SourceRange getSourceRange() const { - return SourceRange(getLocation(), getAtEndRange().getEnd()); + return SourceRange(AtStart, getAtEndRange().getEnd()); } // Implement isa/cast/dyncast/etc. @@ -485,7 +573,6 @@ class ObjCInterfaceDecl : public ObjCContainerDecl { /// completed by the external AST source when required. mutable bool ExternallyCompleted : 1; - SourceLocation ClassLoc; // location of the class identifier. SourceLocation SuperClassLoc; // location of the super class identifier. SourceLocation EndLoc; // marks the '>', '}', or identifier. @@ -576,7 +663,7 @@ public: typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; - ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); } + ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); } ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); } unsigned ivar_size() const { @@ -585,7 +672,12 @@ public: bool ivar_empty() const { return ivar_begin() == ivar_end(); } - ObjCIvarDecl *all_declared_ivar_begin(); + ObjCIvarDecl *all_declared_ivar_begin(); + const ObjCIvarDecl *all_declared_ivar_begin() const { + // Even though this modifies IvarList, it's conceptually const: + // the ivar chain is essentially a cached property of ObjCInterfaceDecl. + return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin(); + } void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; } /// setProtocolList - Set the list of protocols that this interface @@ -675,12 +767,10 @@ public: ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, bool Instance=true); // Location information, modeled after the Stmt API. - SourceLocation getLocStart() const { return getLocation(); } // '@'interface + SourceLocation getLocStart() const { return getAtStartLoc(); } // '@'interface SourceLocation getLocEnd() const { return EndLoc; } void setLocEnd(SourceLocation LE) { EndLoc = LE; } - void setClassLoc(SourceLocation Loc) { ClassLoc = Loc; } - SourceLocation getClassLoc() const { return ClassLoc; } void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; } SourceLocation getSuperClassLoc() const { return SuperClassLoc; } @@ -754,6 +844,7 @@ public: const ObjCInterfaceDecl *getContainingInterface() const; ObjCIvarDecl *getNextIvar() { return NextIvar; } + const ObjCIvarDecl *getNextIvar() const { return NextIvar; } void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; } void setAccessControl(AccessControl ac) { DeclAccess = ac; } @@ -837,14 +928,17 @@ class ObjCProtocolDecl : public ObjCContainerDecl { SourceLocation EndLoc; // marks the '>' or identifier. - ObjCProtocolDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) - : ObjCContainerDecl(ObjCProtocol, DC, L, Id), + ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, + SourceLocation nameLoc, SourceLocation atStartLoc) + : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), isForwardProtoDecl(true) { } public: static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id); + IdentifierInfo *Id, + SourceLocation nameLoc, + SourceLocation atStartLoc); const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; @@ -884,7 +978,7 @@ public: void setForwardDecl(bool val) { isForwardProtoDecl = val; } // Location information, modeled after the Stmt API. - SourceLocation getLocStart() const { return getLocation(); } // '@'protocol + SourceLocation getLocStart() const { return getAtStartLoc(); } // '@'protocol SourceLocation getLocEnd() const { return EndLoc; } void setLocEnd(SourceLocation LE) { EndLoc = LE; } @@ -908,29 +1002,23 @@ public: ObjCInterfaceDecl *getInterface() const { return ID; } }; private: - ObjCClassRef *ForwardDecls; - unsigned NumDecls; + ObjCClassRef *ForwardDecl; ObjCClassDecl(DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs, - unsigned nElts, ASTContext &C); + ObjCInterfaceDecl *const Elt, const SourceLocation Loc, + ASTContext &C); public: static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *const *Elts = 0, - const SourceLocation *Locs = 0, - unsigned nElts = 0); + ObjCInterfaceDecl *const Elt = 0, + const SourceLocation Locs = SourceLocation()); + + ObjCInterfaceDecl *getForwardInterfaceDecl() { return ForwardDecl->getInterface(); } + ObjCClassRef *getForwardDecl() { return ForwardDecl; } + void setClass(ASTContext &C, ObjCInterfaceDecl*const Cls, + const SourceLocation Locs); virtual SourceRange getSourceRange() const; - typedef const ObjCClassRef* iterator; - iterator begin() const { return ForwardDecls; } - iterator end() const { return ForwardDecls + NumDecls; } - unsigned size() const { return NumDecls; } - - /// setClassList - Set the list of forward classes. - void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, - const SourceLocation *Locs, unsigned Num); - static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const ObjCClassDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCClass; } @@ -1013,19 +1101,16 @@ class ObjCCategoryDecl : public ObjCContainerDecl { /// true of class extension has at least one bitfield ivar. bool HasSynthBitfield : 1; - - /// \brief The location of the '@' in '@interface' - SourceLocation AtLoc; /// \brief The location of the category name in this declaration. SourceLocation CategoryNameLoc; ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, - IdentifierInfo *Id) - : ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id), - ClassInterface(0), NextClassCategory(0), HasSynthBitfield(false), - AtLoc(AtLoc), CategoryNameLoc(CategoryNameLoc) { + IdentifierInfo *Id, ObjCInterfaceDecl *IDecl) + : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), + ClassInterface(IDecl), NextClassCategory(0), HasSynthBitfield(false), + CategoryNameLoc(CategoryNameLoc) { } public: @@ -1033,11 +1118,12 @@ public: SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, - IdentifierInfo *Id); + IdentifierInfo *Id, + ObjCInterfaceDecl *IDecl); + static ObjCCategoryDecl *Create(ASTContext &C, EmptyShell Empty); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } - void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; } ObjCCategoryImplDecl *getImplementation() const; void setImplementation(ObjCCategoryImplDecl *ImplD); @@ -1066,14 +1152,6 @@ public: } ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } - void setNextClassCategory(ObjCCategoryDecl *Cat) { - NextClassCategory = Cat; - } - void insertNextClassCategory() { - NextClassCategory = ClassInterface->getCategoryList(); - ClassInterface->setCategoryList(this); - ClassInterface->setChangedSinceDeserialization(true); - } bool IsClassExtension() const { return getIdentifier() == 0; } const ObjCCategoryDecl *getNextClassExtension() const; @@ -1094,20 +1172,16 @@ public: bool ivar_empty() const { return ivar_begin() == ivar_end(); } - - SourceLocation getAtLoc() const { return AtLoc; } - void setAtLoc(SourceLocation At) { AtLoc = At; } SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; } - virtual SourceRange getSourceRange() const { - return SourceRange(AtLoc, getAtEndRange().getEnd()); - } - static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const ObjCCategoryDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCCategory; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; }; class ObjCImplDecl : public ObjCContainerDecl { @@ -1115,10 +1189,12 @@ class ObjCImplDecl : public ObjCContainerDecl { ObjCInterfaceDecl *ClassInterface; protected: - ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *classInterface) - : ObjCContainerDecl(DK, DC, L, - classInterface? classInterface->getIdentifier() : 0), + ObjCImplDecl(Kind DK, DeclContext *DC, + ObjCInterfaceDecl *classInterface, + SourceLocation nameLoc, SourceLocation atStartLoc) + : ObjCContainerDecl(DK, DC, + classInterface? classInterface->getIdentifier() : 0, + nameLoc, atStartLoc), ClassInterface(classInterface) {} public: @@ -1175,13 +1251,17 @@ class ObjCCategoryImplDecl : public ObjCImplDecl { // Category name IdentifierInfo *Id; - ObjCCategoryImplDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - ObjCInterfaceDecl *classInterface) - : ObjCImplDecl(ObjCCategoryImpl, DC, L, classInterface), Id(Id) {} + ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id, + ObjCInterfaceDecl *classInterface, + SourceLocation nameLoc, SourceLocation atStartLoc) + : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc), + Id(Id) {} public: static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - ObjCInterfaceDecl *classInterface); + IdentifierInfo *Id, + ObjCInterfaceDecl *classInterface, + SourceLocation nameLoc, + SourceLocation atStartLoc); /// getIdentifier - Get the identifier that names the category /// interface associated with this implementation. @@ -1203,7 +1283,7 @@ public: // // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean // something different. - llvm::StringRef getName() const { + StringRef getName() const { return Id ? Id->getNameStart() : ""; } @@ -1228,7 +1308,7 @@ public: static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} }; -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, +raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl *CID); /// ObjCImplementationDecl - Represents a class definition - this is where @@ -1259,17 +1339,19 @@ class ObjCImplementationDecl : public ObjCImplDecl { /// true of class extension has at least one bitfield ivar. bool HasSynthBitfield : 1; - ObjCImplementationDecl(DeclContext *DC, SourceLocation L, + ObjCImplementationDecl(DeclContext *DC, ObjCInterfaceDecl *classInterface, - ObjCInterfaceDecl *superDecl) - : ObjCImplDecl(ObjCImplementation, DC, L, classInterface), + ObjCInterfaceDecl *superDecl, + SourceLocation nameLoc, SourceLocation atStartLoc) + : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0), HasCXXStructors(false), HasSynthBitfield(false) {} public: static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, ObjCInterfaceDecl *classInterface, - ObjCInterfaceDecl *superDecl); + ObjCInterfaceDecl *superDecl, + SourceLocation nameLoc, + SourceLocation atStartLoc); /// init_iterator - Iterates through the ivar initializer list. typedef CXXCtorInitializer **init_iterator; @@ -1320,7 +1402,7 @@ public: // // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean // something different. - llvm::StringRef getName() const { + StringRef getName() const { assert(getIdentifier() && "Name is not a simple identifier"); return getIdentifier()->getName(); } @@ -1368,7 +1450,7 @@ public: friend class ASTDeclWriter; }; -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, +raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl *ID); /// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is @@ -1423,7 +1505,7 @@ public: NumPropertyAttrsBits = 12 }; - enum SetterKind { Assign, Retain, Copy }; + enum SetterKind { Assign, Retain, Copy, Weak }; enum PropertyControl { None, Required, Optional }; private: SourceLocation AtLoc; // location of @property @@ -1495,14 +1577,29 @@ public: return (PropertyAttributes & OBJC_PR_readonly); } + /// isAtomic - Return true if the property is atomic. + bool isAtomic() const { + return (PropertyAttributes & OBJC_PR_atomic); + } + + /// isRetaining - Return true if the property retains its value. + bool isRetaining() const { + return (PropertyAttributes & + (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); + } + /// getSetterKind - Return the method used for doing assignment in /// the property setter. This is only valid if the property has been /// defined to have a setter. SetterKind getSetterKind() const { - if (PropertyAttributes & (OBJC_PR_retain|OBJC_PR_strong)) + if (PropertyAttributes & OBJC_PR_strong) + return getType()->isBlockPointerType() ? Copy : Retain; + if (PropertyAttributes & OBJC_PR_retain) return Retain; if (PropertyAttributes & OBJC_PR_copy) return Copy; + if (PropertyAttributes & OBJC_PR_weak) + return Weak; return Assign; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h index d2b1d39..138e47d 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h @@ -264,7 +264,7 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode { FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, - const TemplateArgumentListInfo *TemplateArgsAsWritten, + const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI) : Function(FD), Template(Template, TSK - 1), @@ -278,12 +278,7 @@ public: TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, - SourceLocation POI) { - return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, - TemplateArgs, - TemplateArgsAsWritten, - POI); - } + SourceLocation POI); /// \brief The function template specialization that this structure /// describes. @@ -300,7 +295,7 @@ public: const TemplateArgumentList *TemplateArguments; /// \brief The template arguments as written in the sources, if provided. - const TemplateArgumentListInfo *TemplateArgumentsAsWritten; + const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten; /// \brief The point at which this function template specialization was /// first instantiated. @@ -913,7 +908,7 @@ protected: // FIXME: This should probably never be called, but it's here as TemplateParmPosition() : Depth(0), Position(0) - { /* assert(0 && "Cannot create positionless template parameter"); */ } + { /* llvm_unreachable("Cannot create positionless template parameter"); */ } TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) @@ -1864,7 +1859,7 @@ public: /// \brief Retrieve the partial specializations as an ordered list. void getPartialSpecializations( - llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS); + SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS); /// \brief Find a class template partial specialization with the given /// type T. @@ -2097,6 +2092,58 @@ public: friend class ASTDeclWriter; }; +/// Declaration of a function specialization at template class scope. +/// This is a non standard extension needed to support MSVC. +/// For example: +/// template <class T> +/// class A { +/// template <class U> void foo(U a) { } +/// template<> void foo(int a) { } +/// } +/// +/// "template<> foo(int a)" will be saved in Specialization as a normal +/// CXXMethodDecl. Then during an instantiation of class A, it will be +/// transformed into an actual function specialization. +class ClassScopeFunctionSpecializationDecl : public Decl { +private: + ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc, + CXXMethodDecl *FD) + : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc), + Specialization(FD) {} + + ClassScopeFunctionSpecializationDecl(EmptyShell Empty) + : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {} + + CXXMethodDecl *Specialization; + +public: + CXXMethodDecl *getSpecialization() const { return Specialization; } + + static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C, + DeclContext *DC, + SourceLocation Loc, + CXXMethodDecl *FD) { + return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD); + } + + static ClassScopeFunctionSpecializationDecl *Create(ASTContext &Context, + EmptyShell Empty) { + return new (Context)ClassScopeFunctionSpecializationDecl(0, + SourceLocation(), 0); + } + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { + return K == Decl::ClassScopeFunctionSpecialization; + } + static bool classof(const ClassScopeFunctionSpecializationDecl *D) { + return true; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + /// Implementation of inline functions that require the template declarations inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD) : Function(FTD) { } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/DeclVisitor.h index aee1998..b5b6bd4 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclVisitor.h @@ -30,7 +30,7 @@ class DeclVisitor { public: RetTy Visit(Decl *D) { switch (D->getKind()) { - default: assert(false && "Decl that isn't part of DeclNodes.inc!"); + default: llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); #define DECL(DERIVED, BASE) \ case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl); #define ABSTRACT_DECL(DECL) diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h index bb09831..2170f2b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h @@ -203,7 +203,7 @@ public: std::string getAsString() const; /// printName - Print the human-readable name to a stream. - void printName(llvm::raw_ostream &OS) const; + void printName(raw_ostream &OS) const; /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in /// this declaration name, or NULL if this declaration name isn't a @@ -503,7 +503,7 @@ public: std::string getAsString() const; /// printName - Print the human-readable name to a stream. - void printName(llvm::raw_ostream &OS) const; + void printName(raw_ostream &OS) const; /// getBeginLoc - Retrieve the location of the first token. SourceLocation getBeginLoc() const { return NameLoc; } @@ -520,7 +520,7 @@ public: inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, DeclarationName N) { DB.AddTaggedVal(N.getAsOpaqueInteger(), - Diagnostic::ak_declarationname); + DiagnosticsEngine::ak_declarationname); return DB; } @@ -529,11 +529,11 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, DeclarationName N) { PD.AddTaggedVal(N.getAsOpaqueInteger(), - Diagnostic::ak_declarationname); + DiagnosticsEngine::ak_declarationname); return PD; } -inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, +inline raw_ostream &operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) { DNInfo.printName(OS); return OS; diff --git a/contrib/llvm/tools/clang/include/clang/AST/Expr.h b/contrib/llvm/tools/clang/include/clang/AST/Expr.h index c7f8707..1242f4e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Expr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Expr.h @@ -20,6 +20,7 @@ #include "clang/AST/DeclAccessPair.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/ASTVector.h" +#include "clang/AST/TemplateBase.h" #include "clang/AST/UsuallyTinyPtrVector.h" #include "clang/Basic/TypeTraits.h" #include "llvm/ADT/APSInt.h" @@ -41,12 +42,10 @@ namespace clang { class CXXOperatorCallExpr; class CXXMemberCallExpr; class ObjCPropertyRefExpr; - class TemplateArgumentLoc; - class TemplateArgumentListInfo; class OpaqueValueExpr; /// \brief A simple array of base specifiers. -typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; +typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; /// Expr - This represents one expression. Note that Expr's are subclasses of /// Stmt. This allows an expression to be transparently used any place a Stmt @@ -454,9 +453,14 @@ public: /// EvaluateAsBooleanCondition - Return true if this is a constant /// which we we can fold and convert to a boolean condition using - /// any crazy technique that we want to. + /// any crazy technique that we want to, even if the expression has + /// side-effects. bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const; + /// EvaluateAsInt - Return true if this is a constant which we can fold and + /// convert to an integer using any crazy technique that we want to. + bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx) const; + /// isEvaluatable - Call Evaluate to see if this expression can be constant /// folded, but discard the result. bool isEvaluatable(const ASTContext &Ctx) const; @@ -467,9 +471,9 @@ public: /// variable read. bool HasSideEffects(const ASTContext &Ctx) const; - /// EvaluateAsInt - Call Evaluate and return the folded integer. This + /// EvaluateKnownConstInt - Call Evaluate and return the folded integer. This /// must be called on an expression that constant folds to an integer. - llvm::APSInt EvaluateAsInt(const ASTContext &Ctx) const; + llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const; /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue /// with link time known address. @@ -688,39 +692,6 @@ public: static bool classof(const OpaqueValueExpr *) { return true; } }; -/// \brief Represents an explicit template argument list in C++, e.g., -/// the "<int>" in "sort<int>". -struct ExplicitTemplateArgumentList { - /// \brief The source location of the left angle bracket ('<'); - SourceLocation LAngleLoc; - - /// \brief The source location of the right angle bracket ('>'); - SourceLocation RAngleLoc; - - /// \brief The number of template arguments in TemplateArgs. - /// The actual template arguments (if any) are stored after the - /// ExplicitTemplateArgumentList structure. - unsigned NumTemplateArgs; - - /// \brief Retrieve the template arguments - TemplateArgumentLoc *getTemplateArgs() { - return reinterpret_cast<TemplateArgumentLoc *> (this + 1); - } - - /// \brief Retrieve the template arguments - const TemplateArgumentLoc *getTemplateArgs() const { - return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); - } - - void initializeFrom(const TemplateArgumentListInfo &List); - void initializeFrom(const TemplateArgumentListInfo &List, - bool &Dependent, bool &InstantiationDependent, - bool &ContainsUnexpandedParameterPack); - void copyInto(TemplateArgumentListInfo &List) const; - static std::size_t sizeFor(unsigned NumTemplateArgs); - static std::size_t sizeFor(const TemplateArgumentListInfo &List); -}; - /// \brief A reference to a declared variable, function, enum, etc. /// [C99 6.5.1p2] /// @@ -804,6 +775,7 @@ public: DeclRefExprBits.HasQualifier = 0; DeclRefExprBits.HasExplicitTemplateArgs = 0; DeclRefExprBits.HasFoundDecl = 0; + DeclRefExprBits.HadMultipleCandidates = 0; computeDependence(); } @@ -887,29 +859,29 @@ public: /// \brief Retrieve the explicit template argument list that followed the /// member template name. - ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { assert(hasExplicitTemplateArgs()); if (hasFoundDecl()) - return *reinterpret_cast<ExplicitTemplateArgumentList *>( + return *reinterpret_cast<ASTTemplateArgumentListInfo *>( &getInternalFoundDecl() + 1); if (hasQualifier()) - return *reinterpret_cast<ExplicitTemplateArgumentList *>( + return *reinterpret_cast<ASTTemplateArgumentListInfo *>( &getInternalQualifierLoc() + 1); - return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); + return *reinterpret_cast<ASTTemplateArgumentListInfo *>(this + 1); } /// \brief Retrieve the explicit template argument list that followed the /// member template name. - const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgs(); } /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ExplicitTemplateArgumentList *getExplicitTemplateArgsOpt() const { + const ASTTemplateArgumentListInfo *getExplicitTemplateArgsOpt() const { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -957,6 +929,18 @@ public: return getExplicitTemplateArgs().RAngleLoc; } + /// \brief Returns true if this expression refers to a function that + /// was resolved from an overloaded set having size greater than 1. + bool hadMultipleCandidates() const { + return DeclRefExprBits.HadMultipleCandidates; + } + /// \brief Sets the flag telling whether this expression refers to + /// a function that was resolved from an overloaded set having size + /// greater than 1. + void setHadMultipleCandidates(bool V = true) { + DeclRefExprBits.HadMultipleCandidates = V; + } + static bool classof(const Stmt *T) { return T->getStmtClass() == DeclRefExprClass; } @@ -1112,29 +1096,39 @@ public: }; class CharacterLiteral : public Expr { +public: + enum CharacterKind { + Ascii, + Wide, + UTF16, + UTF32 + }; + +private: unsigned Value; SourceLocation Loc; - bool IsWide; + unsigned Kind : 2; public: // type should be IntTy - CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l) + CharacterLiteral(unsigned value, CharacterKind kind, QualType type, + SourceLocation l) : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false, false, false), - Value(value), Loc(l), IsWide(iswide) { + Value(value), Loc(l), Kind(kind) { } /// \brief Construct an empty character literal. CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { } SourceLocation getLocation() const { return Loc; } - bool isWide() const { return IsWide; } + CharacterKind getKind() const { return static_cast<CharacterKind>(Kind); } SourceRange getSourceRange() const { return SourceRange(Loc); } unsigned getValue() const { return Value; } void setLocation(SourceLocation Location) { Loc = Location; } - void setWide(bool W) { IsWide = W; } + void setKind(CharacterKind kind) { Kind = kind; } void setValue(unsigned Val) { Value = Val; } static bool classof(const Stmt *T) { @@ -1243,13 +1237,23 @@ public: /// In this case, getByteLength() will return 6, but the string literal will /// have type "char[2]". class StringLiteral : public Expr { +public: + enum StringKind { + Ascii, + Wide, + UTF8, + UTF16, + UTF32 + }; + +private: friend class ASTStmtReader; const char *StrData; unsigned ByteLength; - bool IsWide; - bool IsPascal; unsigned NumConcatenated; + unsigned Kind : 3; + bool IsPascal : 1; SourceLocation TokLocs[1]; StringLiteral(QualType Ty) : @@ -1259,33 +1263,39 @@ class StringLiteral : public Expr { public: /// This is the "fully general" constructor that allows representation of /// strings formed from multiple concatenated tokens. - static StringLiteral *Create(ASTContext &C, llvm::StringRef Str, bool Wide, + static StringLiteral *Create(ASTContext &C, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs); /// Simple constructor for string literals made from one token. - static StringLiteral *Create(ASTContext &C, llvm::StringRef Str, bool Wide, - bool Pascal, QualType Ty, SourceLocation Loc) { - return Create(C, Str, Wide, Pascal, Ty, &Loc, 1); + static StringLiteral *Create(ASTContext &C, StringRef Str, StringKind Kind, + bool Pascal, QualType Ty, + SourceLocation Loc) { + return Create(C, Str, Kind, Pascal, Ty, &Loc, 1); } /// \brief Construct an empty string literal. static StringLiteral *CreateEmpty(ASTContext &C, unsigned NumStrs); - llvm::StringRef getString() const { - return llvm::StringRef(StrData, ByteLength); + StringRef getString() const { + return StringRef(StrData, ByteLength); } unsigned getByteLength() const { return ByteLength; } /// \brief Sets the string data to the given string data. - void setString(ASTContext &C, llvm::StringRef Str); - - bool isWide() const { return IsWide; } + void setString(ASTContext &C, StringRef Str); + + StringKind getKind() const { return static_cast<StringKind>(Kind); } + bool isAscii() const { return Kind == Ascii; } + bool isWide() const { return Kind == Wide; } + bool isUTF8() const { return Kind == UTF8; } + bool isUTF16() const { return Kind == UTF16; } + bool isUTF32() const { return Kind == UTF32; } bool isPascal() const { return IsPascal; } - + bool containsNonAsciiOrNull() const { - llvm::StringRef Str = getString(); + StringRef Str = getString(); for (unsigned i = 0, e = Str.size(); i != e; ++i) if (!isascii(Str[i]) || !Str[i]) return true; @@ -2029,6 +2039,10 @@ class MemberExpr : public Expr { /// the MemberNameQualifier structure. bool HasExplicitTemplateArgumentList : 1; + /// \brief True if this member expression refers to a method that + /// was resolved from an overloaded set having size greater than 1. + bool HadMultipleCandidates : 1; + /// \brief Retrieve the qualifier that preceded the member name, if any. MemberNameQualifier *getMemberQualifier() { assert(HasQualifierOrFoundDecl); @@ -2051,7 +2065,8 @@ public: base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) { + HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false), + HadMultipleCandidates(false) { assert(memberdecl->getDeclName() == NameInfo.getName()); } @@ -2068,7 +2083,8 @@ public: base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {} + HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false), + HadMultipleCandidates(false) {} static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow, NestedNameSpecifierLoc QualifierLoc, @@ -2136,26 +2152,26 @@ public: /// \brief Retrieve the explicit template argument list that /// follow the member template name. This must only be called on an /// expression with explicit template arguments. - ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { assert(HasExplicitTemplateArgumentList); if (!HasQualifierOrFoundDecl) - return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); + return *reinterpret_cast<ASTTemplateArgumentListInfo *>(this + 1); - return *reinterpret_cast<ExplicitTemplateArgumentList *>( + return *reinterpret_cast<ASTTemplateArgumentListInfo *>( getMemberQualifier() + 1); } /// \brief Retrieve the explicit template argument list that /// followed the member template name. This must only be called on /// an expression with explicit template arguments. - const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { return const_cast<MemberExpr *>(this)->getExplicitTemplateArgs(); } /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() const { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -2218,7 +2234,19 @@ public: bool isImplicitAccess() const { return getBase() && getBase()->isImplicitCXXThis(); } - + + /// \brief Returns true if this member expression refers to a method that + /// was resolved from an overloaded set having size greater than 1. + bool hadMultipleCandidates() const { + return HadMultipleCandidates; + } + /// \brief Sets the flag telling whether this expression refers to + /// a method that was resolved from an overloaded set having size + /// greater than 1. + void setHadMultipleCandidates(bool V = true) { + HadMultipleCandidates = V; + } + static bool classof(const Stmt *T) { return T->getStmtClass() == MemberExprClass; } @@ -2301,68 +2329,7 @@ public: private: Stmt *Op; - void CheckCastConsistency() const { -#ifndef NDEBUG - switch (getCastKind()) { - case CK_DerivedToBase: - case CK_UncheckedDerivedToBase: - case CK_DerivedToBaseMemberPointer: - case CK_BaseToDerived: - case CK_BaseToDerivedMemberPointer: - assert(!path_empty() && "Cast kind should have a base path!"); - break; - - // These should not have an inheritance path. - case CK_BitCast: - case CK_Dynamic: - case CK_ToUnion: - case CK_ArrayToPointerDecay: - case CK_FunctionToPointerDecay: - case CK_NullToMemberPointer: - case CK_NullToPointer: - case CK_ConstructorConversion: - case CK_IntegralToPointer: - case CK_PointerToIntegral: - case CK_ToVoid: - case CK_VectorSplat: - case CK_IntegralCast: - case CK_IntegralToFloating: - case CK_FloatingToIntegral: - case CK_FloatingCast: - case CK_AnyPointerToObjCPointerCast: - case CK_AnyPointerToBlockPointerCast: - case CK_ObjCObjectLValueCast: - case CK_FloatingRealToComplex: - case CK_FloatingComplexToReal: - case CK_FloatingComplexCast: - case CK_FloatingComplexToIntegralComplex: - case CK_IntegralRealToComplex: - case CK_IntegralComplexToReal: - case CK_IntegralComplexCast: - case CK_IntegralComplexToFloatingComplex: - case CK_ObjCProduceObject: - case CK_ObjCConsumeObject: - case CK_ObjCReclaimReturnedObject: - assert(!getType()->isBooleanType() && "unheralded conversion to bool"); - // fallthrough to check for null base path - - case CK_Dependent: - case CK_LValueToRValue: - case CK_GetObjCProperty: - case CK_NoOp: - case CK_PointerToBoolean: - case CK_IntegralToBoolean: - case CK_FloatingToBoolean: - case CK_MemberPointerToBoolean: - case CK_FloatingComplexToBoolean: - case CK_IntegralComplexToBoolean: - case CK_LValueBitCast: // -> bool& - case CK_UserDefinedConversion: // operator bool() - assert(path_empty() && "Cast kind should not have a base path!"); - break; - } -#endif - } + void CheckCastConsistency() const; const CXXBaseSpecifier * const *path_buffer() const { return const_cast<CastExpr*>(this)->path_buffer(); @@ -2393,7 +2360,9 @@ protected: assert(kind != CK_Invalid && "creating cast with invalid cast kind"); CastExprBits.Kind = kind; setBasePathSize(BasePathSize); +#ifndef NDEBUG CheckCastConsistency(); +#endif } /// \brief Construct an empty cast. @@ -2746,7 +2715,7 @@ protected: /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep /// track of the type the operation is performed in. Due to the semantics of -/// these operators, the operands are promoted, the aritmetic performed, an +/// these operators, the operands are promoted, the arithmetic performed, an /// implicit conversion back to the result type done, then the assignment takes /// place. This captures the intermediate type which the computation is done /// in. @@ -3134,7 +3103,7 @@ public: unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) { assert((N < NumExprs - 2) && "Shuffle idx out of range!"); - return getExpr(N+2)->EvaluateAsInt(Ctx).getZExtValue(); + return getExpr(N+2)->EvaluateKnownConstInt(Ctx).getZExtValue(); } // Iterators @@ -4045,7 +4014,7 @@ public: /// getEncodedElementAccess - Encode the elements accessed into an llvm /// aggregate Constant of ConstantInt(s). - void getEncodedElementAccess(llvm::SmallVectorImpl<unsigned> &Elts) const; + void getEncodedElementAccess(SmallVectorImpl<unsigned> &Elts) const; SourceRange getSourceRange() const { return SourceRange(getBase()->getLocStart(), AccessorLoc); @@ -4193,6 +4162,101 @@ public: // Iterators child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } }; + +/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, +/// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the +/// similarly-named C++0x instructions. All of these instructions take one +/// primary pointer and at least one memory order. +class AtomicExpr : public Expr { +public: + enum AtomicOp { Load, Store, CmpXchgStrong, CmpXchgWeak, Xchg, + Add, Sub, And, Or, Xor }; +private: + enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, END_EXPR }; + Stmt* SubExprs[END_EXPR]; + unsigned NumSubExprs; + SourceLocation BuiltinLoc, RParenLoc; + AtomicOp Op; + +public: + AtomicExpr(SourceLocation BLoc, Expr **args, unsigned nexpr, QualType t, + AtomicOp op, SourceLocation RP); + + /// \brief Build an empty AtomicExpr. + explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { } + + Expr *getPtr() const { + return cast<Expr>(SubExprs[PTR]); + } + void setPtr(Expr *E) { + SubExprs[PTR] = E; + } + Expr *getOrder() const { + return cast<Expr>(SubExprs[ORDER]); + } + void setOrder(Expr *E) { + SubExprs[ORDER] = E; + } + Expr *getVal1() const { + assert(NumSubExprs >= 3); + return cast<Expr>(SubExprs[VAL1]); + } + void setVal1(Expr *E) { + assert(NumSubExprs >= 3); + SubExprs[VAL1] = E; + } + Expr *getOrderFail() const { + assert(NumSubExprs == 5); + return cast<Expr>(SubExprs[ORDER_FAIL]); + } + void setOrderFail(Expr *E) { + assert(NumSubExprs == 5); + SubExprs[ORDER_FAIL] = E; + } + Expr *getVal2() const { + assert(NumSubExprs == 5); + return cast<Expr>(SubExprs[VAL2]); + } + void setVal2(Expr *E) { + assert(NumSubExprs == 5); + SubExprs[VAL2] = E; + } + + AtomicOp getOp() const { return Op; } + void setOp(AtomicOp op) { Op = op; } + unsigned getNumSubExprs() { return NumSubExprs; } + void setNumSubExprs(unsigned num) { NumSubExprs = num; } + + Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); } + + bool isVolatile() const { + return getPtr()->getType()->getPointeeType().isVolatileQualified(); + } + + bool isCmpXChg() const { + return getOp() == AtomicExpr::CmpXchgStrong || + getOp() == AtomicExpr::CmpXchgWeak; + } + + SourceLocation getBuiltinLoc() const { return BuiltinLoc; } + void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; } + + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + + SourceRange getSourceRange() const { + return SourceRange(BuiltinLoc, RParenLoc); + } + static bool classof(const Stmt *T) { + return T->getStmtClass() == AtomicExprClass; + } + static bool classof(const AtomicExpr *) { return true; } + + // Iterators + child_range children() { + return child_range(SubExprs, SubExprs+NumSubExprs); + } +}; } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h index 1911704..3cc09cd 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h @@ -807,37 +807,41 @@ private: SourceLocation Loc; SourceRange ParenRange; + unsigned NumArgs : 16; bool Elidable : 1; + bool HadMultipleCandidates : 1; bool ZeroInitialization : 1; unsigned ConstructKind : 2; Stmt **Args; - unsigned NumArgs; protected: CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, CXXConstructorDecl *d, bool elidable, Expr **args, unsigned numargs, + bool HadMultipleCandidates, bool ZeroInitialization = false, ConstructionKind ConstructKind = CK_Complete, SourceRange ParenRange = SourceRange()); /// \brief Construct an empty C++ construction expression. CXXConstructExpr(StmtClass SC, EmptyShell Empty) - : Expr(SC, Empty), Constructor(0), Elidable(0), ZeroInitialization(0), - ConstructKind(0), Args(0), NumArgs(0) { } + : Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(0), + HadMultipleCandidates(false), ZeroInitialization(0), + ConstructKind(0), Args(0) { } public: /// \brief Construct an empty C++ construction expression. explicit CXXConstructExpr(EmptyShell Empty) : Expr(CXXConstructExprClass, Empty), Constructor(0), - Elidable(0), ZeroInitialization(0), - ConstructKind(0), Args(0), NumArgs(0) { } + NumArgs(0), Elidable(0), HadMultipleCandidates(false), + ZeroInitialization(0), ConstructKind(0), Args(0) { } static CXXConstructExpr *Create(ASTContext &C, QualType T, SourceLocation Loc, CXXConstructorDecl *D, bool Elidable, Expr **Args, unsigned NumArgs, + bool HadMultipleCandidates, bool ZeroInitialization = false, ConstructionKind ConstructKind = CK_Complete, SourceRange ParenRange = SourceRange()); @@ -852,7 +856,12 @@ public: /// \brief Whether this construction is elidable. bool isElidable() const { return Elidable; } void setElidable(bool E) { Elidable = E; } - + + /// \brief Whether the referred constructor was resolved from + /// an overloaded set having size greater than 1. + bool hadMultipleCandidates() const { return HadMultipleCandidates; } + void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; } + /// \brief Whether this construction first requires /// zero-initialization before the initializer is called. bool requiresZeroInitialization() const { return ZeroInitialization; } @@ -980,6 +989,7 @@ public: TypeSourceInfo *Type, Expr **Args,unsigned NumArgs, SourceRange parenRange, + bool HadMultipleCandidates, bool ZeroInitialization = false); explicit CXXTemporaryObjectExpr(EmptyShell Empty) : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { } @@ -1049,8 +1059,11 @@ class CXXNewExpr : public Expr { // If this is an array allocation, does the usual deallocation // function for the allocated type want to know the allocated size? bool UsualArrayDeleteWantsSize : 1; + // Whether the referred constructor (if any) was resolved from an + // overload set having size greater than 1. + bool HadMultipleCandidates : 1; // The number of placement new arguments. - unsigned NumPlacementArgs : 14; + unsigned NumPlacementArgs : 13; // The number of constructor arguments. This may be 1 even for non-class // types; use the pseudo copy constructor. unsigned NumConstructorArgs : 14; @@ -1086,6 +1099,7 @@ public: SourceRange TypeIdParens, Expr *arraySize, CXXConstructorDecl *constructor, bool initializer, Expr **constructorArgs, unsigned numConsArgs, + bool HadMultipleCandidates, FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize, QualType ty, TypeSourceInfo *AllocatedTypeInfo, SourceLocation startLoc, SourceLocation endLoc, @@ -1174,6 +1188,11 @@ public: return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]); } + /// \brief Whether the new expression refers a constructor that was + /// resolved from an overloaded set having size greater than 1. + bool hadMultipleCandidates() const { return HadMultipleCandidates; } + void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; } + typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; @@ -1842,16 +1861,16 @@ public: /// template argument list, e.g. f<int>. bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } - ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below + ASTTemplateArgumentListInfo &getExplicitTemplateArgs(); // defined far below - const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs(); } /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -1969,21 +1988,21 @@ public: // nodes, users are *forbidden* from calling these methods on objects // without explicit template arguments. - ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1); + return *reinterpret_cast<ASTTemplateArgumentListInfo*>(this + 1); } /// Gets a reference to the explicit template argument list. - const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1); + return *reinterpret_cast<const ASTTemplateArgumentListInfo*>(this + 1); } /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -2094,21 +2113,21 @@ public: // nodes, users are *forbidden* from calling these methods on objects // without explicit template arguments. - ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1); + return *reinterpret_cast<ASTTemplateArgumentListInfo*>(this + 1); } /// Gets a reference to the explicit template argument list. - const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1); + return *reinterpret_cast<const ASTTemplateArgumentListInfo*>(this + 1); } /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -2470,14 +2489,14 @@ public: /// \brief Retrieve the explicit template argument list that followed the /// member template name, if any. - ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { assert(HasExplicitTemplateArgs); - return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); + return *reinterpret_cast<ASTTemplateArgumentListInfo *>(this + 1); } /// \brief Retrieve the explicit template argument list that followed the /// member template name, if any. - const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { return const_cast<CXXDependentScopeMemberExpr *>(this) ->getExplicitTemplateArgs(); } @@ -2485,7 +2504,7 @@ public: /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -2663,22 +2682,22 @@ public: /// \brief Retrieve the explicit template argument list that followed the /// member template name. - ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); + return *reinterpret_cast<ASTTemplateArgumentListInfo *>(this + 1); } /// \brief Retrieve the explicit template argument list that followed the /// member template name, if any. - const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1); + return *reinterpret_cast<const ASTTemplateArgumentListInfo *>(this + 1); } /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -2856,7 +2875,7 @@ public: } }; -inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() { +inline ASTTemplateArgumentListInfo &OverloadExpr::getExplicitTemplateArgs() { if (isa<UnresolvedLookupExpr>(this)) return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs(); else diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h index 49d4cfe..55726eb 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h @@ -16,6 +16,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" +#include "clang/AST/SelectorLocationsKind.h" #include "clang/Basic/IdentifierTable.h" namespace clang { @@ -359,12 +360,12 @@ public: QualType ArgType; if (isImplicitProperty()) { const ObjCMethodDecl *Setter = getImplicitPropertySetter(); - ObjCMethodDecl::param_iterator P = Setter->param_begin(); + ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); ArgType = (*P)->getType(); } else { if (ObjCPropertyDecl *PDecl = getExplicitProperty()) if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) { - ObjCMethodDecl::param_iterator P = Setter->param_begin(); + ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); ArgType = (*P)->getType(); } if (ArgType.isNull()) @@ -444,9 +445,21 @@ private: /// class, and can be distinguished via \c getReceiverKind(). Example: /// class ObjCMessageExpr : public Expr { + /// \brief Stores either the selector that this message is sending + /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer + /// referring to the method that we type-checked against. + uintptr_t SelectorOrMethod; + + enum { NumArgsBitWidth = 16 }; + /// \brief The number of arguments in the message send, not /// including the receiver. - unsigned NumArgs : 16; + unsigned NumArgs : NumArgsBitWidth; + + void setNumArgs(unsigned Num) { + assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!"); + NumArgs = Num; + } /// \brief The kind of message send this is, which is one of the /// ReceiverKind values. @@ -464,26 +477,24 @@ class ObjCMessageExpr : public Expr { /// \brief Whether this message send is a "delegate init call", /// i.e. a call of an init method on self from within an init method. unsigned IsDelegateInitCall : 1; + + /// \brief Whether the locations of the selector identifiers are in a + /// "standard" position, a enum SelectorLocationsKind. + unsigned SelLocsKind : 2; /// \brief When the message expression is a send to 'super', this is /// the location of the 'super' keyword. SourceLocation SuperLoc; - /// \brief Stores either the selector that this message is sending - /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer - /// referring to the method that we type-checked against. - uintptr_t SelectorOrMethod; - - /// \brief Location of the selector. - SourceLocation SelectorLoc; - /// \brief The source locations of the open and close square /// brackets ('[' and ']', respectively). SourceLocation LBracLoc, RBracLoc; ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) - : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), - HasMethod(0), IsDelegateInitCall(0), SelectorOrMethod(0) { } + : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0), + HasMethod(0), IsDelegateInitCall(0) { + setNumArgs(NumArgs); + } ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, @@ -491,27 +502,34 @@ class ObjCMessageExpr : public Expr { bool IsInstanceSuper, QualType SuperType, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SelLocs, + SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RBracLoc); ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SelLocs, + SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RBracLoc); ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SelLocs, + SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RBracLoc); + void initArgsAndSelLocs(ArrayRef<Expr *> Args, + ArrayRef<SourceLocation> SelLocs, + SelectorLocationsKind SelLocsK); + /// \brief Retrieve the pointer value of the message receiver. void *getReceiverPointer() const { return *const_cast<void **>( @@ -523,6 +541,40 @@ class ObjCMessageExpr : public Expr { *reinterpret_cast<void **>(this + 1) = Value; } + SelectorLocationsKind getSelLocsKind() const { + return (SelectorLocationsKind)SelLocsKind; + } + bool hasStandardSelLocs() const { + return getSelLocsKind() != SelLoc_NonStandard; + } + + /// \brief Get a pointer to the stored selector identifiers locations array. + /// No locations will be stored if HasStandardSelLocs is true. + SourceLocation *getStoredSelLocs() { + return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs()); + } + const SourceLocation *getStoredSelLocs() const { + return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs()); + } + + /// \brief Get the number of stored selector identifiers locations. + /// No locations will be stored if HasStandardSelLocs is true. + unsigned getNumStoredSelLocs() const { + if (hasStandardSelLocs()) + return 0; + return getNumSelectorLocs(); + } + + static ObjCMessageExpr *alloc(ASTContext &C, + ArrayRef<Expr *> Args, + SourceLocation RBraceLoc, + ArrayRef<SourceLocation> SelLocs, + Selector Sel, + SelectorLocationsKind &SelLocsK); + static ObjCMessageExpr *alloc(ASTContext &C, + unsigned NumArgs, + unsigned NumStoredSelLocs); + public: /// \brief The kind of receiver this message is sending to. enum ReceiverKind { @@ -570,9 +622,9 @@ public: bool IsInstanceSuper, QualType SuperType, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SelLocs, ObjCMethodDecl *Method, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RBracLoc); /// \brief Create a class message send. @@ -605,9 +657,9 @@ public: SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SelLocs, ObjCMethodDecl *Method, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RBracLoc); /// \brief Create an instance message send. @@ -640,9 +692,9 @@ public: SourceLocation LBracLoc, Expr *Receiver, Selector Sel, - SourceLocation SelLoc, + ArrayRef<SourceLocation> SeLocs, ObjCMethodDecl *Method, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RBracLoc); /// \brief Create an empty Objective-C message expression, to be @@ -652,7 +704,9 @@ public: /// /// \param NumArgs The number of message arguments, not including /// the receiver. - static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs); + static ObjCMessageExpr *CreateEmpty(ASTContext &Context, + unsigned NumArgs, + unsigned NumStoredSelLocs); /// \brief Determine the kind of receiver that this message is being /// sent to. @@ -822,7 +876,27 @@ public: SourceLocation getLeftLoc() const { return LBracLoc; } SourceLocation getRightLoc() const { return RBracLoc; } - SourceLocation getSelectorLoc() const { return SelectorLoc; } + + SourceLocation getSelectorStartLoc() const { return getSelectorLoc(0); } + SourceLocation getSelectorLoc(unsigned Index) const { + assert(Index < getNumSelectorLocs() && "Index out of range!"); + if (hasStandardSelLocs()) + return getStandardSelectorLoc(Index, getSelector(), + getSelLocsKind() == SelLoc_StandardWithSpace, + llvm::makeArrayRef(const_cast<Expr**>(getArgs()), + getNumArgs()), + RBracLoc); + return getStoredSelLocs()[Index]; + } + + void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; + + unsigned getNumSelectorLocs() const { + Selector Sel = getSelector(); + if (Sel.isUnarySelector()) + return 1; + return Sel.getNumArgs(); + } void setSourceRange(SourceRange R) { LBracLoc = R.getBegin(); @@ -989,10 +1063,10 @@ class ObjCBridgedCastExpr : public ExplicitCastExpr { public: ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, - SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, - Expr *Operand) + CastKind CK, SourceLocation BridgeKeywordLoc, + TypeSourceInfo *TSInfo, Expr *Operand) : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue, - CK_BitCast, Operand, 0, TSInfo), + CK, Operand, 0, TSInfo), LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { } /// \brief Construct an empty Objective-C bridged cast. @@ -1007,7 +1081,7 @@ public: } /// \brief Retrieve the kind of bridge being performed as a string. - llvm::StringRef getBridgeKindName() const; + StringRef getBridgeKindName() const; /// \brief The location of the bridge keyword. SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h index ef1f161..96d14b2 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h @@ -15,11 +15,6 @@ #define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H #include "clang/AST/DeclBase.h" -#include <cassert> - -namespace llvm { -template <class T> class SmallVectorImpl; -} namespace clang { @@ -129,16 +124,6 @@ public: virtual DeclContextLookupResult FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); - /// \brief Deserialize all the visible declarations from external storage. - /// - /// Name lookup deserializes visible declarations lazily, thus a DeclContext - /// may not have a complete name lookup table. This function deserializes - /// the rest of visible declarations from the external storage and completes - /// the name lookup table of the DeclContext. - /// - /// The default implementation of this method is a no-op. - virtual void MaterializeVisibleDecls(const DeclContext *DC); - /// \brief Finds all declarations lexically contained within the given /// DeclContext, after applying an optional filter predicate. /// @@ -151,20 +136,20 @@ public: /// The default implementation of this method is a no-op. virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), - llvm::SmallVectorImpl<Decl*> &Result); + SmallVectorImpl<Decl*> &Result); /// \brief Finds all declarations lexically contained within the given /// DeclContext. /// /// \return true if an error occurred ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, - llvm::SmallVectorImpl<Decl*> &Result) { + SmallVectorImpl<Decl*> &Result) { return FindExternalLexicalDecls(DC, 0, Result); } template <typename DeclTy> ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC, - llvm::SmallVectorImpl<Decl*> &Result) { + SmallVectorImpl<Decl*> &Result) { return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result); } @@ -231,15 +216,11 @@ protected: static DeclContextLookupResult SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, - llvm::SmallVectorImpl<NamedDecl*> &Decls); + ArrayRef<NamedDecl*> Decls); static DeclContextLookupResult SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name); - - void MaterializeVisibleDeclsForName(const DeclContext *DC, - DeclarationName Name, - llvm::SmallVectorImpl<NamedDecl*> &Decls); }; /// \brief A lazy pointer to an AST node (of base type T) that resides @@ -305,6 +286,178 @@ public: } }; +/// \brief Represents a lazily-loaded vector of data. +/// +/// The lazily-loaded vector of data contains data that is partially loaded +/// from an external source and partially added by local translation. The +/// items loaded from the external source are loaded lazily, when needed for +/// iteration over the complete vector. +template<typename T, typename Source, + void (Source::*Loader)(SmallVectorImpl<T>&), + unsigned LoadedStorage = 2, unsigned LocalStorage = 4> +class LazyVector { + SmallVector<T, LoadedStorage> Loaded; + SmallVector<T, LocalStorage> Local; + +public: + // Iteration over the elements in the vector. + class iterator { + LazyVector *Self; + + /// \brief Position within the vector.. + /// + /// In a complete iteration, the Position field walks the range [-M, N), + /// where negative values are used to indicate elements + /// loaded from the external source while non-negative values are used to + /// indicate elements added via \c push_back(). + /// However, to provide iteration in source order (for, e.g., chained + /// precompiled headers), dereferencing the iterator flips the negative + /// values (corresponding to loaded entities), so that position -M + /// corresponds to element 0 in the loaded entities vector, position -M+1 + /// corresponds to element 1 in the loaded entities vector, etc. This + /// gives us a reasonably efficient, source-order walk. + int Position; + + friend class LazyVector; + + public: + typedef T value_type; + typedef value_type& reference; + typedef value_type* pointer; + typedef std::random_access_iterator_tag iterator_category; + typedef int difference_type; + + iterator() : Self(0), Position(0) { } + + iterator(LazyVector *Self, int Position) + : Self(Self), Position(Position) { } + + reference operator*() const { + if (Position < 0) + return Self->Loaded.end()[Position]; + return Self->Local[Position]; + } + + pointer operator->() const { + if (Position < 0) + return &Self->Loaded.end()[Position]; + + return &Self->Local[Position]; + } + + reference operator[](difference_type D) { + return *(*this + D); + } + + iterator &operator++() { + ++Position; + return *this; + } + + iterator operator++(int) { + iterator Prev(*this); + ++Position; + return Prev; + } + + iterator &operator--() { + --Position; + return *this; + } + + iterator operator--(int) { + iterator Prev(*this); + --Position; + return Prev; + } + + friend bool operator==(const iterator &X, const iterator &Y) { + return X.Position == Y.Position; + } + + friend bool operator!=(const iterator &X, const iterator &Y) { + return X.Position != Y.Position; + } + + friend bool operator<(const iterator &X, const iterator &Y) { + return X.Position < Y.Position; + } + + friend bool operator>(const iterator &X, const iterator &Y) { + return X.Position > Y.Position; + } + + friend bool operator<=(const iterator &X, const iterator &Y) { + return X.Position < Y.Position; + } + + friend bool operator>=(const iterator &X, const iterator &Y) { + return X.Position > Y.Position; + } + + friend iterator& operator+=(iterator &X, difference_type D) { + X.Position += D; + return X; + } + + friend iterator& operator-=(iterator &X, difference_type D) { + X.Position -= D; + return X; + } + + friend iterator operator+(iterator X, difference_type D) { + X.Position += D; + return X; + } + + friend iterator operator+(difference_type D, iterator X) { + X.Position += D; + return X; + } + + friend difference_type operator-(const iterator &X, const iterator &Y) { + return X.Position - Y.Position; + } + + friend iterator operator-(iterator X, difference_type D) { + X.Position -= D; + return X; + } + }; + friend class iterator; + + iterator begin(Source *source, bool LocalOnly = false) { + if (LocalOnly) + return iterator(this, 0); + + if (source) + (source->*Loader)(Loaded); + return iterator(this, -(int)Loaded.size()); + } + + iterator end() { + return iterator(this, Local.size()); + } + + void push_back(const T& LocalValue) { + Local.push_back(LocalValue); + } + + void erase(iterator From, iterator To) { + if (From.Position < 0 && To.Position < 0) { + Loaded.erase(Loaded.end() + From.Position, Loaded.end() + To.Position); + return; + } + + if (From.Position < 0) { + Loaded.erase(Loaded.end() + From.Position, Loaded.end()); + From = begin(0, true); + } + + Local.erase(Local.begin() + From.Position, Local.begin() + To.Position); + } +}; + /// \brief A lazy pointer to a statement. typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt> LazyDeclStmtPtr; diff --git a/contrib/llvm/tools/clang/include/clang/AST/Mangle.h b/contrib/llvm/tools/clang/include/clang/AST/Mangle.h index 7af7702..f58a83b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Mangle.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Mangle.h @@ -39,25 +39,25 @@ namespace clang { /// external memory ownership. class MangleBuffer { public: - void setString(llvm::StringRef Ref) { + void setString(StringRef Ref) { String = Ref; } - llvm::SmallVectorImpl<char> &getBuffer() { + SmallVectorImpl<char> &getBuffer() { return Buffer; } - llvm::StringRef getString() const { + StringRef getString() const { if (!String.empty()) return String; return Buffer.str(); } - operator llvm::StringRef() const { + operator StringRef() const { return getString(); } private: - llvm::StringRef String; + StringRef String; llvm::SmallString<256> Buffer; }; @@ -65,21 +65,21 @@ private: /// calls to the C++ name mangler. class MangleContext { ASTContext &Context; - Diagnostic &Diags; + DiagnosticsEngine &Diags; llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds; llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds; public: explicit MangleContext(ASTContext &Context, - Diagnostic &Diags) + DiagnosticsEngine &Diags) : Context(Context), Diags(Diags) { } virtual ~MangleContext() { } ASTContext &getASTContext() const { return Context; } - Diagnostic &getDiags() const { return Diags; } + DiagnosticsEngine &getDiags() const { return Diags; } virtual void startNewFunction() { LocalBlockIds.clear(); } @@ -95,55 +95,55 @@ public: /// @{ virtual bool shouldMangleDeclName(const NamedDecl *D) = 0; - virtual void mangleName(const NamedDecl *D, llvm::raw_ostream &)=0; + virtual void mangleName(const NamedDecl *D, raw_ostream &)=0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, - llvm::raw_ostream &) = 0; + raw_ostream &) = 0; virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &ThisAdjustment, - llvm::raw_ostream &) = 0; + raw_ostream &) = 0; virtual void mangleReferenceTemporary(const VarDecl *D, - llvm::raw_ostream &) = 0; + raw_ostream &) = 0; virtual void mangleCXXVTable(const CXXRecordDecl *RD, - llvm::raw_ostream &) = 0; + raw_ostream &) = 0; virtual void mangleCXXVTT(const CXXRecordDecl *RD, - llvm::raw_ostream &) = 0; + raw_ostream &) = 0; virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, const CXXRecordDecl *Type, - llvm::raw_ostream &) = 0; - virtual void mangleCXXRTTI(QualType T, llvm::raw_ostream &) = 0; - virtual void mangleCXXRTTIName(QualType T, llvm::raw_ostream &) = 0; + raw_ostream &) = 0; + virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; + virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, - llvm::raw_ostream &) = 0; + raw_ostream &) = 0; virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, - llvm::raw_ostream &) = 0; + raw_ostream &) = 0; void mangleGlobalBlock(const BlockDecl *BD, - llvm::raw_ostream &Out); + raw_ostream &Out); void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, - const BlockDecl *BD, llvm::raw_ostream &Out); + const BlockDecl *BD, raw_ostream &Out); void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, - const BlockDecl *BD, llvm::raw_ostream &Out); + const BlockDecl *BD, raw_ostream &Out); void mangleBlock(const DeclContext *DC, const BlockDecl *BD, - llvm::raw_ostream &Out); + raw_ostream &Out); // Do the right thing. - void mangleBlock(const BlockDecl *BD, llvm::raw_ostream &Out); + void mangleBlock(const BlockDecl *BD, raw_ostream &Out); void mangleObjCMethodName(const ObjCMethodDecl *MD, - llvm::raw_ostream &); + raw_ostream &); // This is pretty lame. virtual void mangleItaniumGuardVariable(const VarDecl *D, - llvm::raw_ostream &) { - assert(0 && "Target does not support mangling guard variables"); + raw_ostream &) { + llvm_unreachable("Target does not support mangling guard variables"); } /// @} }; MangleContext *createItaniumMangleContext(ASTContext &Context, - Diagnostic &Diags); + DiagnosticsEngine &Diags); MangleContext *createMicrosoftMangleContext(ASTContext &Context, - Diagnostic &Diags); + DiagnosticsEngine &Diags); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h index 018041f..c81c06e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h +++ b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h @@ -18,10 +18,6 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerIntPair.h" -namespace llvm { - class raw_ostream; -} - namespace clang { class ASTContext; @@ -196,7 +192,7 @@ public: /// \brief Print this nested name specifier to the given output /// stream. - void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const; + void print(raw_ostream &OS, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(Prefix.getOpaqueValue()); @@ -469,7 +465,7 @@ public: inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, NestedNameSpecifier *NNS) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS), - Diagnostic::ak_nestednamespec); + DiagnosticsEngine::ak_nestednamespec); return DB; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h b/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h index 92ff604..469da99 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h +++ b/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h @@ -31,9 +31,12 @@ enum CastKind { /// to be reinterpreted as a bit pattern of another type. Generally /// the operands must have equivalent size and unrelated types. /// - /// The pointer conversion char* -> int* is a bitcast. Many other - /// pointer conversions which are "physically" bitcasts are given - /// special cast kinds. + /// The pointer conversion char* -> int* is a bitcast. A conversion + /// from any pointer type to a C pointer type is a bitcast unless + /// it's actually BaseToDerived or DerivedToBase. A conversion to a + /// block pointer or ObjC pointer type is a bitcast only if the + /// operand has the same type kind; otherwise, it's one of the + /// specialized casts below. /// /// Vector coercions are bitcasts. CK_BitCast, @@ -186,12 +189,16 @@ enum CastKind { /// (float) ld CK_FloatingCast, - /// CK_AnyPointerToObjCPointerCast - Casting any other pointer kind - /// to an Objective-C pointer. - CK_AnyPointerToObjCPointerCast, + /// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an + /// Objective-C pointer. + CK_CPointerToObjCPointerCast, - /// CK_AnyPointerToBlockPointerCast - Casting any other pointer kind - /// to a block pointer. + /// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an + /// ObjC pointer. + CK_BlockPointerToObjCPointerCast, + + /// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer + /// to a block pointer. Block-to-block casts are bitcasts. CK_AnyPointerToBlockPointerCast, /// \brief Converting between two Objective-C object types, which @@ -247,20 +254,27 @@ enum CastKind { /// _Complex unsigned -> _Complex float CK_IntegralComplexToFloatingComplex, - /// \brief Produces a retainable object pointer so that it may be - /// consumed, e.g. by being passed to a consuming parameter. Calls - /// objc_retain. - CK_ObjCProduceObject, + /// \brief [ARC] Produces a retainable object pointer so that it may + /// be consumed, e.g. by being passed to a consuming parameter. + /// Calls objc_retain. + CK_ARCProduceObject, - /// \brief Consumes a retainable object pointer that has just been - /// produced, e.g. as the return value of a retaining call. Enters - /// a cleanup to call objc_release at some indefinite time. - CK_ObjCConsumeObject, + /// \brief [ARC] Consumes a retainable object pointer that has just + /// been produced, e.g. as the return value of a retaining call. + /// Enters a cleanup to call objc_release at some indefinite time. + CK_ARCConsumeObject, - /// \brief Reclaim a retainable object pointer object that may have - /// been produced and autoreleased as part of a function return + /// \brief [ARC] Reclaim a retainable object pointer object that may + /// have been produced and autoreleased as part of a function return /// sequence. - CK_ObjCReclaimReturnedObject + CK_ARCReclaimReturnedObject, + + /// \brief [ARC] Causes a value of block type to be copied to the + /// heap, if it is not already there. A number of other operations + /// in ARC cause blocks to be copied; this is for cases where that + /// would not otherwise be guaranteed, such as when casting to a + /// non-block pointer type. + CK_ARCExtendBlockObject }; #define CK_Invalid ((CastKind) -1) diff --git a/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h b/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h index 22c1e72..62eae02 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h @@ -32,6 +32,7 @@ public: Stmt *getParent(Stmt*) const; Stmt *getParentIgnoreParens(Stmt *) const; Stmt *getParentIgnoreParenCasts(Stmt *) const; + Stmt *getParentIgnoreParenImpCasts(Stmt *) const; Stmt *getOuterParenParent(Stmt *) const; const Stmt *getParent(const Stmt* S) const { diff --git a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h index fc8ac36..2bdd8d3 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h @@ -15,10 +15,7 @@ #define LLVM_CLANG_AST_PRETTY_PRINTER_H #include "clang/Basic/LangOptions.h" - -namespace llvm { - class raw_ostream; -} +#include "clang/Basic/LLVM.h" namespace clang { @@ -29,7 +26,7 @@ class LangOptions; class PrinterHelper { public: virtual ~PrinterHelper(); - virtual bool handledStmt(Stmt* E, llvm::raw_ostream& OS) = 0; + virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0; }; /// \brief Describes how types, statements, expressions, and @@ -41,13 +38,14 @@ struct PrintingPolicy { SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false), SuppressInitializers(false), Dump(false), ConstantArraySizeAsWritten(false), - AnonymousTagLocations(true), SuppressStrongLifetime(false) { } + AnonymousTagLocations(true), SuppressStrongLifetime(false), + Bool(LO.Bool) { } /// \brief The number of spaces to use to indent each line. unsigned Indentation : 8; /// \brief What language we're printing. - const LangOptions LangOpts; + LangOptions LangOpts; /// \brief Whether we should suppress printing of the actual specifiers for /// the given type or declaration. @@ -133,6 +131,10 @@ struct PrintingPolicy { /// \brief When true, suppress printing of the __strong lifetime qualifier in /// ARC. unsigned SuppressStrongLifetime : 1; + + /// \brief Whether we can use 'bool' rather than '_Bool', even if the language + /// doesn't actually have 'bool' (because, e.g., it is defined as a macro). + unsigned Bool : 1; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h index d7bab80..b0186ce 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h @@ -63,6 +63,9 @@ class ASTRecordLayout { /// any empty subobjects. CharUnits SizeOfLargestEmptySubobject; + /// VBPtrOffset - Virtual base table offset. + CharUnits VBPtrOffset; + /// PrimaryBase - The primary base info for this record. llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase; @@ -89,7 +92,8 @@ class ASTRecordLayout { // Constructor for C++ records. typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; ASTRecordLayout(const ASTContext &Ctx, - CharUnits size, CharUnits alignment, CharUnits datasize, + CharUnits size, CharUnits alignment, CharUnits vbptroffset, + CharUnits datasize, const uint64_t *fieldoffsets, unsigned fieldcount, CharUnits nonvirtualsize, CharUnits nonvirtualalign, CharUnits SizeOfLargestEmptySubobject, @@ -199,6 +203,10 @@ public: assert(CXXInfo && "Record layout does not have C++ specific info!"); return CXXInfo->SizeOfLargestEmptySubobject; } + + CharUnits getVBPtrOffset() const { + return CXXInfo->VBPtrOffset; + } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h index 85c5c08..0ec09c9 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h @@ -813,6 +813,10 @@ DEF_TRAVERSE_TYPE(ObjCObjectPointerType, { TRY_TO(TraverseType(T->getPointeeType())); }) +DEF_TRAVERSE_TYPE(AtomicType, { + TRY_TO(TraverseType(T->getValueType())); + }) + #undef DEF_TRAVERSE_TYPE // ----------------- TypeLoc traversal ----------------- @@ -1041,6 +1045,10 @@ DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) +DEF_TRAVERSE_TYPELOC(AtomicType, { + TRY_TO(TraverseTypeLoc(TL.getValueLoc())); + }) + #undef DEF_TRAVERSE_TYPELOC // ----------------- Decl traversal ----------------- @@ -1114,6 +1122,10 @@ DEF_TRAVERSE_DECL(FriendTemplateDecl, { } }) +DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, { + TRY_TO(TraverseDecl(D->getSpecialization())); + }) + DEF_TRAVERSE_DECL(LinkageSpecDecl, { }) DEF_TRAVERSE_DECL(ObjCClassDecl, { @@ -1252,7 +1264,7 @@ bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations( = (U.get<ClassTemplatePartialSpecializationDecl*>() == Pattern); if (ShouldVisit) - TRY_TO(TraverseClassTemplateSpecializationDecl(SD)); + TRY_TO(TraverseDecl(SD)); break; } @@ -1280,7 +1292,7 @@ DEF_TRAVERSE_DECL(ClassTemplateDecl, { TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); // By default, we do not traverse the instantiations of - // class templates since they do not apprear in the user code. The + // class templates since they do not appear in the user code. The // following code optionally traverses them. if (getDerived().shouldVisitTemplateInstantiations()) { // If this is the definition of the primary template, visit @@ -1318,7 +1330,7 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations( case TSK_ExplicitSpecialization: break; default: - assert(false && "Unknown specialization kind."); + llvm_unreachable("Unknown specialization kind."); } } @@ -1548,10 +1560,10 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) { // A specialization might not have explicit template arguments if it has // a templated return type and concrete arguments. - if (const TemplateArgumentListInfo *TALI = + if (const ASTTemplateArgumentListInfo *TALI = FTSI->TemplateArgumentsAsWritten) { - TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getArgumentArray(), - TALI->size())); + TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(), + TALI->NumTemplateArgs)); } } } @@ -1980,6 +1992,7 @@ DEF_TRAVERSE_STMT(SizeOfPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { }) DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { }) +DEF_TRAVERSE_STMT(AtomicExpr, { }) // These literals (all of them) do not need any action. DEF_TRAVERSE_STMT(IntegerLiteral, { }) diff --git a/contrib/llvm/tools/clang/include/clang/AST/SelectorLocationsKind.h b/contrib/llvm/tools/clang/include/clang/AST/SelectorLocationsKind.h new file mode 100644 index 0000000..cd43a5c --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/SelectorLocationsKind.h @@ -0,0 +1,83 @@ +//===--- SelectorLocationsKind.h - Kind of selector locations ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Describes whether the identifier locations for a selector are "standard" +// or not. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H +#define LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H + +#include "clang/Basic/LLVM.h" + +namespace clang { + class Selector; + class SourceLocation; + class Expr; + class ParmVarDecl; + +/// \brief Whether all locations of the selector identifiers are in a +/// "standard" position. +enum SelectorLocationsKind { + /// \brief Non-standard. + SelLoc_NonStandard = 0, + + /// \brief For nullary selectors, immediately before the end: + /// "[foo release]" / "-(void)release;" + /// Or immediately before the arguments: + /// "[foo first:1 second:2]" / "-(id)first:(int)x second:(int)y; + SelLoc_StandardNoSpace = 1, + + /// \brief For nullary selectors, immediately before the end: + /// "[foo release]" / "-(void)release;" + /// Or with a space between the arguments: + /// "[foo first: 1 second: 2]" / "-(id)first: (int)x second: (int)y; + SelLoc_StandardWithSpace = 2 +}; + +/// \brief Returns true if all \arg SelLocs are in a "standard" location. +SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, + ArrayRef<SourceLocation> SelLocs, + ArrayRef<Expr *> Args, + SourceLocation EndLoc); + +/// \brief Get the "standard" location of a selector identifier, e.g: +/// For nullary selectors, immediately before ']': "[foo release]" +/// +/// \param WithArgSpace if true the standard location is with a space apart +/// before arguments: "[foo first: 1 second: 2]" +/// If false: "[foo first:1 second:2]" +SourceLocation getStandardSelectorLoc(unsigned Index, + Selector Sel, + bool WithArgSpace, + ArrayRef<Expr *> Args, + SourceLocation EndLoc); + +/// \brief Returns true if all \arg SelLocs are in a "standard" location. +SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, + ArrayRef<SourceLocation> SelLocs, + ArrayRef<ParmVarDecl *> Args, + SourceLocation EndLoc); + +/// \brief Get the "standard" location of a selector identifier, e.g: +/// For nullary selectors, immediately before ']': "[foo release]" +/// +/// \param WithArgSpace if true the standard location is with a space apart +/// before arguments: "-(id)first: (int)x second: (int)y;" +/// If false: "-(id)first:(int)x second:(int)y;" +SourceLocation getStandardSelectorLoc(unsigned Index, + Selector Sel, + bool WithArgSpace, + ArrayRef<ParmVarDecl *> Args, + SourceLocation EndLoc); + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h index bf5f383..2a6fd6b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h @@ -14,16 +14,15 @@ #ifndef LLVM_CLANG_AST_STMT_H #define LLVM_CLANG_AST_STMT_H -#include "llvm/Support/Casting.h" -#include "llvm/Support/raw_ostream.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/StmtIterator.h" #include "clang/AST/DeclGroup.h" -#include "llvm/ADT/SmallVector.h" #include "clang/AST/ASTContext.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/SmallVector.h" #include <string> -using llvm::dyn_cast_or_null; namespace llvm { class FoldingSetNodeID; @@ -108,11 +107,10 @@ public: // Make vanilla 'new' and 'delete' illegal for Stmts. protected: void* operator new(size_t bytes) throw() { - assert(0 && "Stmts cannot be allocated with regular 'new'."); - return 0; + llvm_unreachable("Stmts cannot be allocated with regular 'new'."); } void operator delete(void* data) throw() { - assert(0 && "Stmts cannot be released with regular 'delete'."); + llvm_unreachable("Stmts cannot be released with regular 'delete'."); } class StmtBitfields { @@ -148,6 +146,7 @@ protected: friend class CXXUnresolvedConstructExpr; // ctor friend class CXXDependentScopeMemberExpr; // ctor friend class OverloadExpr; // ctor + friend class AtomicExpr; // ctor unsigned : NumStmtBits; unsigned ValueKind : 2; @@ -167,6 +166,7 @@ protected: unsigned HasQualifier : 1; unsigned HasExplicitTemplateArgs : 1; unsigned HasFoundDecl : 1; + unsigned HadMultipleCandidates : 1; }; class CastExprBitfields { @@ -270,7 +270,7 @@ public: /// This is useful in a debugger. void dump() const; void dump(SourceManager &SM) const; - void dump(llvm::raw_ostream &OS, SourceManager &SM) const; + void dump(raw_ostream &OS, SourceManager &SM) const; /// dumpAll - This does a dump of the specified AST fragment and all subtrees. void dumpAll() const; @@ -279,12 +279,12 @@ public: /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST /// back to its original source language syntax. void dumpPretty(ASTContext& Context) const; - void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper, + void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation = 0) const { printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation); } - void printPretty(llvm::raw_ostream &OS, ASTContext &Context, + void printPretty(raw_ostream &OS, ASTContext &Context, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation = 0) const; @@ -297,6 +297,12 @@ public: /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes. Stmt *IgnoreImplicit(); + const Stmt *stripLabelLikeStatements() const; + Stmt *stripLabelLikeStatements() { + return const_cast<Stmt*>( + const_cast<const Stmt*>(this)->stripLabelLikeStatements()); + } + // Implement isa<T> support. static bool classof(const Stmt *) { return true; } @@ -407,25 +413,25 @@ public: class NullStmt : public Stmt { SourceLocation SemiLoc; - /// \brief If the null statement was preceded by an empty macro this is - /// its instantiation source location, e.g: + /// \brief True if the null statement was preceded by an empty macro, e.g: /// @code /// #define CALL(x) /// CALL(0); /// @endcode - SourceLocation LeadingEmptyMacro; + bool HasLeadingEmptyMacro; public: - NullStmt(SourceLocation L, SourceLocation LeadingEmptyMacro =SourceLocation()) - : Stmt(NullStmtClass), SemiLoc(L), LeadingEmptyMacro(LeadingEmptyMacro) {} + NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false) + : Stmt(NullStmtClass), SemiLoc(L), + HasLeadingEmptyMacro(hasLeadingEmptyMacro) {} /// \brief Build an empty null statement. - explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { } + explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty), + HasLeadingEmptyMacro(false) { } SourceLocation getSemiLoc() const { return SemiLoc; } void setSemiLoc(SourceLocation L) { SemiLoc = L; } - bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro.isValid(); } - SourceLocation getLeadingEmptyMacroLoc() const { return LeadingEmptyMacro; } + bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; } SourceRange getSourceRange() const { return SourceRange(SemiLoc); } @@ -525,6 +531,10 @@ public: child_range children() { return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); } + + const_child_range children() const { + return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts); + } }; // SwitchCase is the base class for CaseStmt and DefaultStmt, @@ -1308,7 +1318,7 @@ public: /// true, otherwise return false. This handles canonicalization and /// translation of strings from GCC syntax to LLVM IR syntax, and handles //// flattening of named references like %[foo] to Operand AsmStringPiece's. - unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces, + unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces, ASTContext &C, unsigned &DiagOffs) const; @@ -1320,17 +1330,17 @@ public: return Names[i]; } - llvm::StringRef getOutputName(unsigned i) const { + StringRef getOutputName(unsigned i) const { if (IdentifierInfo *II = getOutputIdentifier(i)) return II->getName(); - return llvm::StringRef(); + return StringRef(); } /// getOutputConstraint - Return the constraint string for the specified /// output operand. All output constraints are known to be non-empty (either /// '=' or '+'). - llvm::StringRef getOutputConstraint(unsigned i) const; + StringRef getOutputConstraint(unsigned i) const; const StringLiteral *getOutputConstraintLiteral(unsigned i) const { return Constraints[i]; @@ -1364,16 +1374,16 @@ public: return Names[i + NumOutputs]; } - llvm::StringRef getInputName(unsigned i) const { + StringRef getInputName(unsigned i) const { if (IdentifierInfo *II = getInputIdentifier(i)) return II->getName(); - return llvm::StringRef(); + return StringRef(); } /// getInputConstraint - Return the specified input constraint. Unlike output /// constraints, these can be empty. - llvm::StringRef getInputConstraint(unsigned i) const; + StringRef getInputConstraint(unsigned i) const; const StringLiteral *getInputConstraintLiteral(unsigned i) const { return Constraints[i + NumOutputs]; @@ -1403,7 +1413,7 @@ public: /// getNamedOperand - Given a symbolic operand reference like %[foo], /// translate this into a numeric value needed to reference the same operand. /// This returns -1 if the operand name is invalid. - int getNamedOperand(llvm::StringRef SymbolicName) const; + int getNamedOperand(StringRef SymbolicName) const; unsigned getNumClobbers() const { return NumClobbers; } StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h index 29d2347..48a0123 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h @@ -42,7 +42,7 @@ public: // below. if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) { switch (BinOp->getOpcode()) { - default: assert(0 && "Unknown binary operator!"); + default: llvm_unreachable("Unknown binary operator!"); case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator); case BO_PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator); case BO_Mul: DISPATCH(BinMul, BinaryOperator); @@ -80,7 +80,7 @@ public: } } else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) { switch (UnOp->getOpcode()) { - default: assert(0 && "Unknown unary operator!"); + default: llvm_unreachable("Unknown unary operator!"); case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator); case UO_PostDec: DISPATCH(UnaryPostDec, UnaryOperator); case UO_PreInc: DISPATCH(UnaryPreInc, UnaryOperator); @@ -99,7 +99,7 @@ public: // Top switch stmt: dispatch to VisitFooStmt for each FooStmt. switch (S->getStmtClass()) { - default: assert(0 && "Unknown stmt kind!"); + default: llvm_unreachable("Unknown stmt kind!"); #define ABSTRACT_STMT(STMT) #define STMT(CLASS, PARENT) \ case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS); diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h index 1c693e0..371c27a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h @@ -23,7 +23,6 @@ namespace llvm { class FoldingSetNodeID; - class raw_ostream; } namespace clang { @@ -354,7 +353,7 @@ public: TemplateArgument getPackExpansionPattern() const; /// \brief Print this template argument to the given output stream. - void print(const PrintingPolicy &Policy, llvm::raw_ostream &Out) const; + void print(const PrintingPolicy &Policy, raw_ostream &Out) const; /// \brief Used to insert TemplateArguments into FoldingSets. void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; @@ -515,10 +514,14 @@ public: /// A convenient class for passing around template argument /// information. Designed to be passed by reference. class TemplateArgumentListInfo { - llvm::SmallVector<TemplateArgumentLoc, 8> Arguments; + SmallVector<TemplateArgumentLoc, 8> Arguments; SourceLocation LAngleLoc; SourceLocation RAngleLoc; + // This can leak if used in an AST node, use ASTTemplateArgumentListInfo + // instead. + void* operator new(size_t bytes, ASTContext& C); + public: TemplateArgumentListInfo() {} @@ -547,6 +550,48 @@ public: } }; +/// \brief Represents an explicit template argument list in C++, e.g., +/// the "<int>" in "sort<int>". +/// This is safe to be used inside an AST node, in contrast with +/// TemplateArgumentListInfo. +struct ASTTemplateArgumentListInfo { + /// \brief The source location of the left angle bracket ('<'); + SourceLocation LAngleLoc; + + /// \brief The source location of the right angle bracket ('>'); + SourceLocation RAngleLoc; + + /// \brief The number of template arguments in TemplateArgs. + /// The actual template arguments (if any) are stored after the + /// ExplicitTemplateArgumentList structure. + unsigned NumTemplateArgs; + + /// \brief Retrieve the template arguments + TemplateArgumentLoc *getTemplateArgs() { + return reinterpret_cast<TemplateArgumentLoc *> (this + 1); + } + + /// \brief Retrieve the template arguments + const TemplateArgumentLoc *getTemplateArgs() const { + return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); + } + + const TemplateArgumentLoc &operator[](unsigned I) const { + return getTemplateArgs()[I]; + } + + static const ASTTemplateArgumentListInfo *Create(ASTContext &C, + const TemplateArgumentListInfo &List); + + void initializeFrom(const TemplateArgumentListInfo &List); + void initializeFrom(const TemplateArgumentListInfo &List, + bool &Dependent, bool &InstantiationDependent, + bool &ContainsUnexpandedParameterPack); + void copyInto(TemplateArgumentListInfo &List) const; + static std::size_t sizeFor(unsigned NumTemplateArgs); + static std::size_t sizeFor(const TemplateArgumentListInfo &List); +}; + const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const TemplateArgument &Arg); diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h index a180f58..7dc75b1 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h @@ -14,14 +14,11 @@ #ifndef LLVM_CLANG_AST_TEMPLATENAME_H #define LLVM_CLANG_AST_TEMPLATENAME_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerUnion.h" #include "clang/Basic/OperatorKinds.h" -namespace llvm { - class raw_ostream; -} - namespace clang { class ASTContext; @@ -308,7 +305,7 @@ public: /// \param SuppressNNS if true, don't print the /// nested-name-specifier that precedes the template name (if it has /// one). - void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy, + void print(raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS = false) const; /// \brief Debugging aid that dumps the template name to standard diff --git a/contrib/llvm/tools/clang/include/clang/AST/Type.h b/contrib/llvm/tools/clang/include/clang/AST/Type.h index ef0dbda..dd9aa56 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Type.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Type.h @@ -22,19 +22,15 @@ #include "clang/Basic/Visibility.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" -#include "llvm/Support/Casting.h" #include "llvm/Support/type_traits.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" +#include "clang/Basic/LLVM.h" -using llvm::isa; -using llvm::cast; -using llvm::cast_or_null; -using llvm::dyn_cast; -using llvm::dyn_cast_or_null; namespace clang { enum { TypeAlignmentInBits = 4, @@ -508,6 +504,9 @@ public: const Type *getTypePtrOrNull() const; + /// Retrieves a pointer to the name of the base type. + const IdentifierInfo *getBaseTypeIdentifier() const; + /// Divides a QualType into its unqualified type and a set of local /// qualifiers. SplitQualType split() const; @@ -868,8 +867,9 @@ public: /// type other than void. bool isCForbiddenLValueType() const; - /// \brief Determine whether this type has trivial copy-assignment semantics. - bool hasTrivialCopyAssignment(ASTContext &Context) const; + /// \brief Determine whether this type has trivial copy/move-assignment + /// semantics. + bool hasTrivialAssignment(ASTContext &Context, bool Copying) const; private: // These methods are implemented in a separate translation unit; @@ -1362,6 +1362,7 @@ public: /// various convenient purposes within Clang. All such types are /// BuiltinTypes. bool isPlaceholderType() const; + const BuiltinType *getAsPlaceholderType() const; /// isSpecificPlaceholderType - Test for a specific placeholder type. bool isSpecificPlaceholderType(unsigned K) const; @@ -1373,6 +1374,8 @@ public: bool isBooleanType() const; bool isCharType() const; bool isWideCharType() const; + bool isChar16Type() const; + bool isChar32Type() const; bool isAnyCharacterType() const; bool isIntegralType(ASTContext &Ctx) const; @@ -1389,6 +1392,7 @@ public: bool isComplexType() const; // C99 6.2.5p11 (complex) bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) + bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) bool isVoidType() const; // C99 6.2.5p19 @@ -1447,6 +1451,7 @@ public: bool isCARCBridgableType() const; bool isTemplateTypeParmType() const; // C++ template type parameter bool isNullPtrType() const; // C++0x nullptr_t + bool isAtomicType() const; // C1X _Atomic() /// Determines if this type, which must satisfy /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather @@ -1457,7 +1462,9 @@ public: Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; enum ScalarTypeKind { - STK_Pointer, + STK_CPointer, + STK_BlockPointer, + STK_ObjCObjectPointer, STK_MemberPointer, STK_Bool, STK_Integral, @@ -1693,6 +1700,8 @@ public: LongLong, Int128, // __int128_t + Half, // This is the 'half' type in OpenCL, + // __fp16 in case of ARM NEON. Float, Double, LongDouble, NullPtr, // This is the type of C++0x 'nullptr'. @@ -1755,7 +1764,7 @@ public: } Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } - const char *getName(const LangOptions &LO) const; + const char *getName(const PrintingPolicy &Policy) const; bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -1773,7 +1782,7 @@ public: } bool isFloatingPoint() const { - return getKind() >= Float && getKind() <= LongDouble; + return getKind() >= Half && getKind() <= LongDouble; } /// Determines whether this type is a placeholder type, i.e. a type @@ -2249,7 +2258,7 @@ public: friend class StmtIteratorBase; void Profile(llvm::FoldingSetNodeID &ID) { - assert(0 && "Cannot unique VariableArrayTypes."); + llvm_unreachable("Cannot unique VariableArrayTypes."); } }; @@ -2635,7 +2644,7 @@ public: return getResultType().getNonLValueExprType(Context); } - static llvm::StringRef getNameForCallConv(CallingConv CC); + static StringRef getNameForCallConv(CallingConv CC); static bool classof(const Type *T) { return T->getTypeClass() == FunctionNoProto || @@ -2696,8 +2705,17 @@ public: unsigned char TypeQuals; RefQualifierKind RefQualifier; unsigned NumExceptions; + + /// Exceptions - A variable size array after that holds the exception types. const QualType *Exceptions; + + /// NoexceptExpr - Instead of Exceptions, there may be a single Expr* + /// pointing to the expression in the noexcept() specifier. Expr *NoexceptExpr; + + /// ConsumedArgs - A variable size array, following Exceptions + /// and of length NumArgs, holding flags indicating which arguments + /// are consumed. This only appears if HasAnyConsumedArgs is true. const bool *ConsumedArguments; }; @@ -2728,19 +2746,6 @@ private: /// HasAnyConsumedArgs - Whether this function has any consumed arguments. unsigned HasAnyConsumedArgs : 1; - /// ArgInfo - There is an variable size array after the class in memory that - /// holds the argument types. - - /// Exceptions - There is another variable size array after ArgInfo that - /// holds the exception types. - - /// NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing - /// to the expression in the noexcept() specifier. - - /// ConsumedArgs - A variable size array, following Exceptions - /// and of length NumArgs, holding flags indicating which arguments - /// are consumed. This only appears if HasAnyConsumedArgs is true. - friend class ASTContext; // ASTContext creates these. const bool *getConsumedArgsBuffer() const { @@ -4348,6 +4353,37 @@ public: static bool classof(const ObjCObjectPointerType *) { return true; } }; +class AtomicType : public Type, public llvm::FoldingSetNode { + QualType ValueType; + + AtomicType(QualType ValTy, QualType Canonical) + : Type(Atomic, Canonical, ValTy->isDependentType(), + ValTy->isInstantiationDependentType(), + ValTy->isVariablyModifiedType(), + ValTy->containsUnexpandedParameterPack()), + ValueType(ValTy) {} + friend class ASTContext; // ASTContext creates these. + + public: + /// getValueType - Gets the type contained by this atomic type, i.e. + /// the type returned by performing an atomic load of this atomic type. + QualType getValueType() const { return ValueType; } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getValueType()); + } + static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { + ID.AddPointer(T.getAsOpaquePtr()); + } + static bool classof(const Type *T) { + return T->getTypeClass() == Atomic; + } + static bool classof(const AtomicType *) { return true; } +}; + /// A qualifier set is used to build a set of qualifiers. class QualifierCollector : public Qualifiers { public: @@ -4673,6 +4709,9 @@ inline bool Type::isObjCObjectOrInterfaceType() const { return isa<ObjCInterfaceType>(CanonicalType) || isa<ObjCObjectType>(CanonicalType); } +inline bool Type::isAtomicType() const { + return isa<AtomicType>(CanonicalType); +} inline bool Type::isObjCQualifiedIdType() const { if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) @@ -4714,11 +4753,18 @@ inline bool Type::isSpecificBuiltinType(unsigned K) const { } inline bool Type::isPlaceholderType() const { - if (const BuiltinType *BT = getAs<BuiltinType>()) + if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) return BT->isPlaceholderType(); return false; } +inline const BuiltinType *Type::getAsPlaceholderType() const { + if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) + if (BT->isPlaceholderType()) + return BT; + return 0; +} + inline bool Type::isSpecificPlaceholderType(unsigned K) const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(this)) return (BT->getKind() == (BuiltinType::Kind) K); @@ -4757,7 +4803,7 @@ inline const Type *Type::getBaseElementTypeUnsafe() const { inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, QualType T) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), - Diagnostic::ak_qualtype); + DiagnosticsEngine::ak_qualtype); return DB; } @@ -4766,7 +4812,7 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, QualType T) { PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), - Diagnostic::ak_qualtype); + DiagnosticsEngine::ak_qualtype); return PD; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h index f5669f7..20acada 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h @@ -538,6 +538,10 @@ class InjectedClassNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, InjectedClassNameTypeLoc, InjectedClassNameType> { +public: + CXXRecordDecl *getDecl() const { + return getTypePtr()->getDecl(); + } }; /// \brief Wrapper for source info for unresolved typename using decls. @@ -561,6 +565,12 @@ class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, TagType> { public: TagDecl *getDecl() const { return getTypePtr()->getDecl(); } + + /// \brief True if the tag was defined in this type specifier. + bool isDefinition() const { + return getDecl()->isCompleteDefinition() && + (getNameLoc().isInvalid() || getNameLoc() == getDecl()->getLocation()); + } }; /// \brief Wrapper for source info for record types. @@ -1408,6 +1418,8 @@ public: class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DecltypeTypeLoc, DecltypeType> { +public: + Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } }; struct UnaryTransformTypeLocInfo { @@ -1718,6 +1730,62 @@ public: } }; +struct AtomicTypeLocInfo { + SourceLocation KWLoc, LParenLoc, RParenLoc; +}; + +class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, + AtomicType, AtomicTypeLocInfo> { +public: + TypeLoc getValueLoc() const { + return this->getInnerTypeLoc(); + } + + SourceRange getLocalSourceRange() const { + return SourceRange(getKWLoc(), getRParenLoc()); + } + + SourceLocation getKWLoc() const { + return this->getLocalData()->KWLoc; + } + void setKWLoc(SourceLocation Loc) { + this->getLocalData()->KWLoc = Loc; + } + + SourceLocation getLParenLoc() const { + return this->getLocalData()->LParenLoc; + } + void setLParenLoc(SourceLocation Loc) { + this->getLocalData()->LParenLoc = Loc; + } + + SourceLocation getRParenLoc() const { + return this->getLocalData()->RParenLoc; + } + void setRParenLoc(SourceLocation Loc) { + this->getLocalData()->RParenLoc = Loc; + } + + SourceRange getParensRange() const { + return SourceRange(getLParenLoc(), getRParenLoc()); + } + void setParensRange(SourceRange Range) { + setLParenLoc(Range.getBegin()); + setRParenLoc(Range.getEnd()); + } + + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + setKWLoc(Loc); + setLParenLoc(Loc); + setRParenLoc(Loc); + } + + QualType getInnerType() const { + return this->getTypePtr()->getValueType(); + } +}; + + } #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def b/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def index 0792d0d..d5c485f 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def @@ -102,9 +102,10 @@ DEPENDENT_TYPE(PackExpansion, Type) TYPE(ObjCObject, Type) TYPE(ObjCInterface, ObjCObjectType) TYPE(ObjCObjectPointer, Type) +TYPE(Atomic, Type) #ifdef LAST_TYPE -LAST_TYPE(ObjCObjectPointer) +LAST_TYPE(Atomic) #undef LAST_TYPE #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h index c52926b..9eebc4b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h @@ -28,7 +28,7 @@ public: RetTy Visit(const Type *T) { // Top switch stmt: dispatch to VisitFooType for each FooType. switch (T->getTypeClass()) { - default: assert(0 && "Unknown type class!"); + default: llvm_unreachable("Unknown type class!"); #define ABSTRACT_TYPE(CLASS, PARENT) #define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type); #include "clang/AST/TypeNodes.def" diff --git a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h index a548b0b..0918dc4 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h +++ b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h @@ -25,7 +25,7 @@ namespace clang { /// non-const iterator. class UnresolvedSetIterator { private: - typedef llvm::SmallVectorImpl<DeclAccessPair> DeclsTy; + typedef SmallVectorImpl<DeclAccessPair> DeclsTy; typedef DeclsTy::iterator IteratorTy; IteratorTy ir; @@ -177,7 +177,7 @@ private: /// A set of unresolved declarations template <unsigned InlineCapacity> class UnresolvedSet : public UnresolvedSetImpl { - llvm::SmallVector<DeclAccessPair, InlineCapacity> Decls; + SmallVector<DeclAccessPair, InlineCapacity> Decls; }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h new file mode 100644 index 0000000..6756dd1 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h @@ -0,0 +1,176 @@ +//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This contains code dealing with generation of the layout of virtual table +// tables (VTT). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_VTTBUILDER_H +#define LLVM_CLANG_AST_VTTBUILDER_H + +#include "clang/AST/BaseSubobject.h" +#include "clang/AST/CXXInheritance.h" +#include "clang/AST/GlobalDecl.h" +#include "clang/AST/RecordLayout.h" +#include "clang/Basic/ABI.h" +#include "llvm/ADT/SetVector.h" +#include <utility> + +namespace clang { + +class VTTVTable { + llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual; + CharUnits BaseOffset; + +public: + VTTVTable() {} + VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual) + : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {} + VTTVTable(BaseSubobject Base, bool BaseIsVirtual) + : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual), + BaseOffset(Base.getBaseOffset()) {} + + const CXXRecordDecl *getBase() const { + return BaseAndIsVirtual.getPointer(); + } + + CharUnits getBaseOffset() const { + return BaseOffset; + } + + bool isVirtual() const { + return BaseAndIsVirtual.getInt(); + } + + BaseSubobject getBaseSubobject() const { + return BaseSubobject(getBase(), getBaseOffset()); + } +}; + +struct VTTComponent { + uint64_t VTableIndex; + BaseSubobject VTableBase; + + VTTComponent() {} + VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase) + : VTableIndex(VTableIndex), VTableBase(VTableBase) {} +}; + +/// VTT builder - Class for building VTT layout information. +class VTTBuilder { + + ASTContext &Ctx; + + /// MostDerivedClass - The most derived class for which we're building this + /// vtable. + const CXXRecordDecl *MostDerivedClass; + + typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy; + + /// VTTVTables - The VTT vtables. + VTTVTablesVectorTy VTTVTables; + + typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy; + + /// VTTComponents - The VTT components. + VTTComponentsVectorTy VTTComponents; + + /// MostDerivedClassLayout - the AST record layout of the most derived class. + const ASTRecordLayout &MostDerivedClassLayout; + + typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; + + typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; + + /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived + /// class. + llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies; + + /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of + /// all subobjects of the most derived class. + llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices; + + /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for + /// the VTT. + bool GenerateDefinition; + + /// AddVTablePointer - Add a vtable pointer to the VTT currently being built. + /// + /// \param AddressPoints - If the vtable is a construction vtable, this has + /// the address points for it. + void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, + const CXXRecordDecl *VTableClass); + + /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base + /// subobject. + void LayoutSecondaryVTTs(BaseSubobject Base); + + /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers + /// for the given base subobject. + /// + /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base + /// or a direct or indirect base of a virtual base. + /// + /// \param AddressPoints - If the vtable is a construction vtable, this has + /// the address points for it. + void LayoutSecondaryVirtualPointers(BaseSubobject Base, + bool BaseIsMorallyVirtual, + uint64_t VTableIndex, + const CXXRecordDecl *VTableClass, + VisitedVirtualBasesSetTy &VBases); + + /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers + /// for the given base subobject. + /// + /// \param AddressPoints - If the vtable is a construction vtable, this has + /// the address points for it. + void LayoutSecondaryVirtualPointers(BaseSubobject Base, + uint64_t VTableIndex); + + /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the + /// given record decl. + void LayoutVirtualVTTs(const CXXRecordDecl *RD, + VisitedVirtualBasesSetTy &VBases); + + /// LayoutVTT - Will lay out the VTT for the given subobject, including any + /// secondary VTTs, secondary virtual pointers and virtual VTTs. + void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual); + +public: + VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass, + bool GenerateDefinition); + + // getVTTComponents - Returns a reference to the VTT components. + const VTTComponentsVectorTy &getVTTComponents() const { + return VTTComponents; + } + + // getVTTVTables - Returns a reference to the VTT vtables. + const VTTVTablesVectorTy &getVTTVTables() const { + return VTTVTables; + } + + /// getSubVTTIndicies - Returns a reference to the sub-VTT indices. + const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const { + return SubVTTIndicies; + } + + /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary + /// virtual pointer indices. + const llvm::DenseMap<BaseSubobject, uint64_t> & + getSecondaryVirtualPointerIndices() const { + return SecondaryVirtualPointerIndices; + } + +}; + +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h new file mode 100644 index 0000000..59bab03 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h @@ -0,0 +1,357 @@ +//===--- VTableBuilder.h - C++ vtable layout builder --------------*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This contains code dealing with generation of the layout of virtual tables. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_VTABLEBUILDER_H +#define LLVM_CLANG_AST_VTABLEBUILDER_H + +#include "clang/AST/BaseSubobject.h" +#include "clang/AST/CXXInheritance.h" +#include "clang/AST/GlobalDecl.h" +#include "clang/AST/RecordLayout.h" +#include "clang/Basic/ABI.h" +#include "llvm/ADT/SetVector.h" +#include <utility> + +namespace clang { + class CXXRecordDecl; + +/// VTableComponent - Represents a single component in a vtable. +class VTableComponent { +public: + enum Kind { + CK_VCallOffset, + CK_VBaseOffset, + CK_OffsetToTop, + CK_RTTI, + CK_FunctionPointer, + + /// CK_CompleteDtorPointer - A pointer to the complete destructor. + CK_CompleteDtorPointer, + + /// CK_DeletingDtorPointer - A pointer to the deleting destructor. + CK_DeletingDtorPointer, + + /// CK_UnusedFunctionPointer - In some cases, a vtable function pointer + /// will end up never being called. Such vtable function pointers are + /// represented as a CK_UnusedFunctionPointer. + CK_UnusedFunctionPointer + }; + + VTableComponent() { } + + static VTableComponent MakeVCallOffset(CharUnits Offset) { + return VTableComponent(CK_VCallOffset, Offset); + } + + static VTableComponent MakeVBaseOffset(CharUnits Offset) { + return VTableComponent(CK_VBaseOffset, Offset); + } + + static VTableComponent MakeOffsetToTop(CharUnits Offset) { + return VTableComponent(CK_OffsetToTop, Offset); + } + + static VTableComponent MakeRTTI(const CXXRecordDecl *RD) { + return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD)); + } + + static VTableComponent MakeFunction(const CXXMethodDecl *MD) { + assert(!isa<CXXDestructorDecl>(MD) && + "Don't use MakeFunction with destructors!"); + + return VTableComponent(CK_FunctionPointer, + reinterpret_cast<uintptr_t>(MD)); + } + + static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) { + return VTableComponent(CK_CompleteDtorPointer, + reinterpret_cast<uintptr_t>(DD)); + } + + static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) { + return VTableComponent(CK_DeletingDtorPointer, + reinterpret_cast<uintptr_t>(DD)); + } + + static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD) { + assert(!isa<CXXDestructorDecl>(MD) && + "Don't use MakeUnusedFunction with destructors!"); + return VTableComponent(CK_UnusedFunctionPointer, + reinterpret_cast<uintptr_t>(MD)); + } + + static VTableComponent getFromOpaqueInteger(uint64_t I) { + return VTableComponent(I); + } + + /// getKind - Get the kind of this vtable component. + Kind getKind() const { + return (Kind)(Value & 0x7); + } + + CharUnits getVCallOffset() const { + assert(getKind() == CK_VCallOffset && "Invalid component kind!"); + + return getOffset(); + } + + CharUnits getVBaseOffset() const { + assert(getKind() == CK_VBaseOffset && "Invalid component kind!"); + + return getOffset(); + } + + CharUnits getOffsetToTop() const { + assert(getKind() == CK_OffsetToTop && "Invalid component kind!"); + + return getOffset(); + } + + const CXXRecordDecl *getRTTIDecl() const { + assert(getKind() == CK_RTTI && "Invalid component kind!"); + + return reinterpret_cast<CXXRecordDecl *>(getPointer()); + } + + const CXXMethodDecl *getFunctionDecl() const { + assert(getKind() == CK_FunctionPointer); + + return reinterpret_cast<CXXMethodDecl *>(getPointer()); + } + + const CXXDestructorDecl *getDestructorDecl() const { + assert((getKind() == CK_CompleteDtorPointer || + getKind() == CK_DeletingDtorPointer) && "Invalid component kind!"); + + return reinterpret_cast<CXXDestructorDecl *>(getPointer()); + } + + const CXXMethodDecl *getUnusedFunctionDecl() const { + assert(getKind() == CK_UnusedFunctionPointer); + + return reinterpret_cast<CXXMethodDecl *>(getPointer()); + } + +private: + VTableComponent(Kind ComponentKind, CharUnits Offset) { + assert((ComponentKind == CK_VCallOffset || + ComponentKind == CK_VBaseOffset || + ComponentKind == CK_OffsetToTop) && "Invalid component kind!"); + assert(Offset.getQuantity() <= ((1LL << 56) - 1) && "Offset is too big!"); + + Value = ((Offset.getQuantity() << 3) | ComponentKind); + } + + VTableComponent(Kind ComponentKind, uintptr_t Ptr) { + assert((ComponentKind == CK_RTTI || + ComponentKind == CK_FunctionPointer || + ComponentKind == CK_CompleteDtorPointer || + ComponentKind == CK_DeletingDtorPointer || + ComponentKind == CK_UnusedFunctionPointer) && + "Invalid component kind!"); + + assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!"); + + Value = Ptr | ComponentKind; + } + + CharUnits getOffset() const { + assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset || + getKind() == CK_OffsetToTop) && "Invalid component kind!"); + + return CharUnits::fromQuantity(Value >> 3); + } + + uintptr_t getPointer() const { + assert((getKind() == CK_RTTI || + getKind() == CK_FunctionPointer || + getKind() == CK_CompleteDtorPointer || + getKind() == CK_DeletingDtorPointer || + getKind() == CK_UnusedFunctionPointer) && + "Invalid component kind!"); + + return static_cast<uintptr_t>(Value & ~7ULL); + } + + explicit VTableComponent(uint64_t Value) + : Value(Value) { } + + /// The kind is stored in the lower 3 bits of the value. For offsets, we + /// make use of the facts that classes can't be larger than 2^55 bytes, + /// so we store the offset in the lower part of the 61 bytes that remain. + /// (The reason that we're not simply using a PointerIntPair here is that we + /// need the offsets to be 64-bit, even when on a 32-bit machine). + int64_t Value; +}; + +class VTableLayout { +public: + typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy; + typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; + + typedef const VTableComponent *vtable_component_iterator; + typedef const VTableThunkTy *vtable_thunk_iterator; + + typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; +private: + uint64_t NumVTableComponents; + VTableComponent *VTableComponents; + + /// VTableThunks - Contains thunks needed by vtables. + uint64_t NumVTableThunks; + VTableThunkTy *VTableThunks; + + /// Address points - Address points for all vtables. + AddressPointsMapTy AddressPoints; + +public: + VTableLayout(uint64_t NumVTableComponents, + const VTableComponent *VTableComponents, + uint64_t NumVTableThunks, + const VTableThunkTy *VTableThunks, + const AddressPointsMapTy &AddressPoints); + ~VTableLayout(); + + uint64_t getNumVTableComponents() const { + return NumVTableComponents; + } + + vtable_component_iterator vtable_component_begin() const { + return VTableComponents; + } + + vtable_component_iterator vtable_component_end() const { + return VTableComponents+NumVTableComponents; + } + + uint64_t getNumVTableThunks() const { + return NumVTableThunks; + } + + vtable_thunk_iterator vtable_thunk_begin() const { + return VTableThunks; + } + + vtable_thunk_iterator vtable_thunk_end() const { + return VTableThunks+NumVTableThunks; + } + + uint64_t getAddressPoint(BaseSubobject Base) const { + assert(AddressPoints.count(Base) && + "Did not find address point!"); + + uint64_t AddressPoint = AddressPoints.lookup(Base); + assert(AddressPoint && "Address point must not be zero!"); + + return AddressPoint; + } + + const AddressPointsMapTy &getAddressPoints() const { + return AddressPoints; + } +}; + +class VTableContext { + ASTContext &Context; + +public: + typedef SmallVector<std::pair<uint64_t, ThunkInfo>, 1> + VTableThunksTy; + typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; + +private: + /// MethodVTableIndices - Contains the index (relative to the vtable address + /// point) where the function pointer for a virtual function is stored. + typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy; + MethodVTableIndicesTy MethodVTableIndices; + + typedef llvm::DenseMap<const CXXRecordDecl *, const VTableLayout *> + VTableLayoutMapTy; + VTableLayoutMapTy VTableLayouts; + + /// NumVirtualFunctionPointers - Contains the number of virtual function + /// pointers in the vtable for a given record decl. + llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers; + + typedef std::pair<const CXXRecordDecl *, + const CXXRecordDecl *> ClassPairTy; + + /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to + /// the address point) in chars where the offsets for virtual bases of a class + /// are stored. + typedef llvm::DenseMap<ClassPairTy, CharUnits> + VirtualBaseClassOffsetOffsetsMapTy; + VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets; + + typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; + + /// Thunks - Contains all thunks that a given method decl will need. + ThunksMapTy Thunks; + + void ComputeMethodVTableIndices(const CXXRecordDecl *RD); + + /// ComputeVTableRelatedInformation - Compute and store all vtable related + /// information (vtable layout, vbase offset offsets, thunks etc) for the + /// given record decl. + void ComputeVTableRelatedInformation(const CXXRecordDecl *RD); + +public: + VTableContext(ASTContext &Context) : Context(Context) {} + ~VTableContext(); + + const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) { + ComputeVTableRelatedInformation(RD); + assert(VTableLayouts.count(RD) && "No layout for this record decl!"); + + return *VTableLayouts[RD]; + } + + VTableLayout * + createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass, + CharUnits MostDerivedClassOffset, + bool MostDerivedClassIsVirtual, + const CXXRecordDecl *LayoutClass); + + const ThunkInfoVectorTy *getThunkInfo(const CXXMethodDecl *MD) { + ComputeVTableRelatedInformation(MD->getParent()); + + ThunksMapTy::const_iterator I = Thunks.find(MD); + if (I == Thunks.end()) { + // We did not find a thunk for this method. + return 0; + } + + return &I->second; + } + + /// getNumVirtualFunctionPointers - Return the number of virtual function + /// pointers in the vtable for a given record decl. + uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD); + + /// getMethodVTableIndex - Return the index (relative to the vtable address + /// point) where the function pointer for the given virtual function is + /// stored. + uint64_t getMethodVTableIndex(GlobalDecl GD); + + /// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the + /// vtable address point) where the offset of the virtual base that contains + /// the given base is stored, otherwise, if no virtual base contains the given + /// class, return 0. Base must be a virtual base class or an unambigious + /// base. + CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, + const CXXRecordDecl *VBase); +}; + +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h index 069ead3..a3f9c53 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h @@ -169,8 +169,8 @@ public: return Position; } - llvm::StringRef getCharacters() const { - return llvm::StringRef(getStart(), getLength()); + StringRef getCharacters() const { + return StringRef(getStart(), getLength()); } bool consumesDataArgument() const { @@ -276,7 +276,7 @@ public: ArgTypeResult getArgType(ASTContext &Ctx) const; - void toString(llvm::raw_ostream &os) const; + void toString(raw_ostream &os) const; bool usesPositionalArg() const { return (bool) UsesPositionalArg; } unsigned getPositionalArgIndex() const { @@ -470,7 +470,7 @@ public: /// was not successful. bool fixType(QualType QT); - void toString(llvm::raw_ostream &os) const; + void toString(raw_ostream &os) const; // Validation methods - to check if any element results in undefined behavior bool hasValidPlusPrefix() const; diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/LiveVariables.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/LiveVariables.h index fbbd261..302ae1c 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/LiveVariables.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/LiveVariables.h @@ -1,4 +1,4 @@ -//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-===// +//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-// // // The LLVM Compiler Infrastructure // @@ -14,110 +14,105 @@ #ifndef LLVM_CLANG_LIVEVARIABLES_H #define LLVM_CLANG_LIVEVARIABLES_H +#include "clang/Analysis/AnalysisContext.h" #include "clang/AST/Decl.h" -#include "clang/Analysis/Support/BlkExprDeclBitVector.h" -#include "clang/Analysis/FlowSensitive/DataflowValues.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/ImmutableSet.h" namespace clang { +class CFG; +class CFGBlock; class Stmt; class DeclRefExpr; class SourceManager; -class AnalysisContext; - -struct LiveVariables_ValueTypes { - - struct ObserverTy; - - // We keep dataflow state for declarations and block-level expressions; - typedef StmtDeclBitVector_Types::ValTy ValTy; - - // We need to keep track of both declarations and CFGBlock-level expressions, - // (so that we don't explore such expressions twice). We also want - // to compute liveness information for block-level expressions, since these - // act as "temporary" values. - - struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy { - ObserverTy* Observer; - ValTy AlwaysLive; - AnalysisContext *AC; - bool killAtAssign; - - AnalysisDataTy() : Observer(NULL), AC(NULL), killAtAssign(true) {} + +class LiveVariables : public ManagedAnalysis { +public: + class LivenessValues { + public: + + llvm::ImmutableSet<const Stmt *> liveStmts; + llvm::ImmutableSet<const VarDecl *> liveDecls; + + bool equals(const LivenessValues &V) const; + + LivenessValues() + : liveStmts(0), liveDecls(0) {} + + LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts, + llvm::ImmutableSet<const VarDecl *> LiveDecls) + : liveStmts(LiveStmts), liveDecls(LiveDecls) {} + + ~LivenessValues() {} + + bool isLive(const Stmt *S) const; + bool isLive(const VarDecl *D) const; + + friend class LiveVariables; }; - - //===-----------------------------------------------------===// - // ObserverTy - Observer for uninitialized values queries. - //===-----------------------------------------------------===// - - struct ObserverTy { - virtual ~ObserverTy() {} - - /// ObserveStmt - A callback invoked right before invoking the + + struct Observer { + virtual ~Observer() {} + + /// A callback invoked right before invoking the /// liveness transfer function on the given statement. - virtual void ObserveStmt(Stmt* S, const CFGBlock *currentBlock, - const AnalysisDataTy& AD, - const ValTy& V) {} - - virtual void ObserverKill(DeclRefExpr* DR) {} - }; -}; - -class LiveVariables : public DataflowValues<LiveVariables_ValueTypes, - dataflow::backward_analysis_tag> { - - -public: - typedef LiveVariables_ValueTypes::ObserverTy ObserverTy; - - LiveVariables(AnalysisContext &AC, bool killAtAssign = true); - - /// IsLive - Return true if a variable is live at the end of a + virtual void observeStmt(const Stmt *S, + const CFGBlock *currentBlock, + const LivenessValues& V) {} + + /// Called when the live variables analysis registers + /// that a variable is killed. + virtual void observerKill(const DeclRefExpr *DR) {} + }; + + + virtual ~LiveVariables(); + + /// Compute the liveness information for a given CFG. + static LiveVariables *computeLiveness(AnalysisContext &analysisContext, + bool killAtAssign); + + /// Return true if a variable is live at the end of a /// specified block. - bool isLive(const CFGBlock* B, const VarDecl* D) const; - - /// IsLive - Returns true if a variable is live at the beginning of the + bool isLive(const CFGBlock *B, const VarDecl *D); + + /// Returns true if a variable is live at the beginning of the /// the statement. This query only works if liveness information /// has been recorded at the statement level (see runOnAllBlocks), and /// only returns liveness information for block-level expressions. - bool isLive(const Stmt* S, const VarDecl* D) const; - - /// IsLive - Returns true the block-level expression "value" is live + bool isLive(const Stmt *S, const VarDecl *D); + + /// Returns true the block-level expression "value" is live /// before the given block-level expression (see runOnAllBlocks). - bool isLive(const Stmt* Loc, const Stmt* StmtVal) const; - - /// IsLive - Return true if a variable is live according to the - /// provided livness bitvector. - bool isLive(const ValTy& V, const VarDecl* D) const; - - /// dumpLiveness - Print to stderr the liveness information encoded - /// by a specified bitvector. - void dumpLiveness(const ValTy& V, const SourceManager& M) const; - - /// dumpBlockLiveness - Print to stderr the liveness information - /// associated with each basic block. - void dumpBlockLiveness(const SourceManager& M) const; - - /// getNumDecls - Return the number of variables (declarations) that - /// whose liveness status is being tracked by the dataflow - /// analysis. - unsigned getNumDecls() const { return getAnalysisData().getNumDecls(); } - - /// IntializeValues - This routine can perform extra initialization, but - /// for LiveVariables this does nothing since all that logic is in - /// the constructor. - void InitializeValues(const CFG& cfg) {} - - void runOnCFG(CFG& cfg); - - /// runOnAllBlocks - Propagate the dataflow values once for each block, - /// starting from the current dataflow values. 'recordStmtValues' indicates - /// whether the method should store dataflow values per each individual - /// block-level expression. - void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs, - bool recordStmtValues=false); + bool isLive(const Stmt *Loc, const Stmt *StmtVal); + + /// Print to stderr the liveness information associated with + /// each basic block. + void dumpBlockLiveness(const SourceManager& M); + + void runOnAllBlocks(Observer &obs); + + static LiveVariables *create(AnalysisContext &analysisContext) { + return computeLiveness(analysisContext, true); + } + + static const void *getTag(); + +private: + LiveVariables(void *impl); + void *impl; }; - + +class RelaxedLiveVariables : public LiveVariables { +public: + static LiveVariables *create(AnalysisContext &analysisContext) { + return computeLiveness(analysisContext, false); + } + + static const void *getTag(); +}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ReachableCode.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ReachableCode.h index e0c84f9..6cf7fa4 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ReachableCode.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ReachableCode.h @@ -45,7 +45,7 @@ public: /// ScanReachableFromBlock - Mark all blocks reachable from Start. /// Returns the total number of blocks that were marked reachable. -unsigned ScanReachableFromBlock(const CFGBlock &Start, +unsigned ScanReachableFromBlock(const CFGBlock *Start, llvm::BitVector &Reachable); void FindUnreachableCode(AnalysisContext &AC, Callback &CB); diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h new file mode 100644 index 0000000..a325056 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h @@ -0,0 +1,153 @@ +//===- ThreadSafety.h ------------------------------------------*- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +// A intra-procedural analysis for thread safety (e.g. deadlocks and race +// conditions), based off of an annotation system. +// +// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety for more +// information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_THREADSAFETY_H +#define LLVM_CLANG_THREADSAFETY_H + +#include "clang/Analysis/AnalysisContext.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { +namespace thread_safety { + +/// This enum distinguishes between different kinds of operations that may +/// need to be protected by locks. We use this enum in error handling. +enum ProtectedOperationKind { + POK_VarDereference, /// Dereferencing a variable (e.g. p in *p = 5;) + POK_VarAccess, /// Reading or writing a variable (e.g. x in x = 5;) + POK_FunctionCall /// Making a function call (e.g. fool()) +}; + +/// This enum distinguishes between different kinds of lock actions. For +/// example, it is an error to write a variable protected by shared version of a +/// mutex. +enum LockKind { + LK_Shared, /// Shared/reader lock of a mutex + LK_Exclusive /// Exclusive/writer lock of a mutex +}; + +/// This enum distinguishes between different ways to access (read or write) a +/// variable. +enum AccessKind { + AK_Read, /// Reading a variable + AK_Written /// Writing a variable +}; + +/// This enum distinguishes between different situations where we warn due to +/// inconsistent locking. +/// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all +/// loop iterations. +/// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all +/// predecessors of a CFGBlock. +/// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a +/// function. +enum LockErrorKind { + LEK_LockedSomeLoopIterations, + LEK_LockedSomePredecessors, + LEK_LockedAtEndOfFunction +}; + +/// Handler class for thread safety warnings. +class ThreadSafetyHandler { +public: + typedef llvm::StringRef Name; + virtual ~ThreadSafetyHandler() = 0; + + /// Warn about lock expressions which fail to resolve to lockable objects. + /// \param Loc -- the SourceLocation of the unresolved expression. + virtual void handleInvalidLockExp(SourceLocation Loc) {} + + /// Warn about unlock function calls that do not have a prior matching lock + /// expression. + /// \param LockName -- A StringRef name for the lock expression, to be printed + /// in the error message. + /// \param Loc -- The SourceLocation of the Unlock + virtual void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {} + + /// Warn about lock function calls for locks which are already held. + /// \param LockName -- A StringRef name for the lock expression, to be printed + /// in the error message. + /// \param Loc -- The location of the second lock expression. + virtual void handleDoubleLock(Name LockName, SourceLocation Loc) {} + + /// Warn about situations where a mutex is sometimes held and sometimes not. + /// The three situations are: + /// 1. a mutex is locked on an "if" branch but not the "else" branch, + /// 2, or a mutex is only held at the start of some loop iterations, + /// 3. or when a mutex is locked but not unlocked inside a function. + /// \param LockName -- A StringRef name for the lock expression, to be printed + /// in the error message. + /// \param Loc -- The location of the lock expression where the mutex is locked + /// \param LEK -- which of the three above cases we should warn for + virtual void handleMutexHeldEndOfScope(Name LockName, SourceLocation Loc, + LockErrorKind LEK){} + + /// Warn when a mutex is held exclusively and shared at the same point. For + /// example, if a mutex is locked exclusively during an if branch and shared + /// during the else branch. + /// \param LockName -- A StringRef name for the lock expression, to be printed + /// in the error message. + /// \param Loc1 -- The location of the first lock expression. + /// \param Loc2 -- The location of the second lock expression. + virtual void handleExclusiveAndShared(Name LockName, SourceLocation Loc1, + SourceLocation Loc2) {} + + /// Warn when a protected operation occurs while no locks are held. + /// \param D -- The decl for the protected variable or function + /// \param POK -- The kind of protected operation (e.g. variable access) + /// \param AK -- The kind of access (i.e. read or write) that occurred + /// \param Loc -- The location of the protected operation. + virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, + AccessKind AK, SourceLocation Loc) {} + + /// Warn when a protected operation occurs while the specific mutex protecting + /// the operation is not locked. + /// \param LockName -- A StringRef name for the lock expression, to be printed + /// in the error message. + /// \param D -- The decl for the protected variable or function + /// \param POK -- The kind of protected operation (e.g. variable access) + /// \param AK -- The kind of access (i.e. read or write) that occurred + /// \param Loc -- The location of the protected operation. + virtual void handleMutexNotHeld(const NamedDecl *D, + ProtectedOperationKind POK, Name LockName, + LockKind LK, SourceLocation Loc) {} + + /// Warn when a function is called while an excluded mutex is locked. For + /// example, the mutex may be locked inside the function. + /// \param FunName -- The name of the function + /// \param LockName -- A StringRef name for the lock expression, to be printed + /// in the error message. + /// \param Loc -- The location of the function call. + virtual void handleFunExcludesLock(Name FunName, Name LockName, + SourceLocation Loc) {} +}; + +/// \brief Check a function's CFG for thread-safety violations. +/// +/// We traverse the blocks in the CFG, compute the set of mutexes that are held +/// at the end of each block, and issue warnings for thread safety violations. +/// Each block in the CFG is traversed exactly once. +void runThreadSafetyAnalysis(AnalysisContext &AC, ThreadSafetyHandler &Handler); + +/// \brief Helper function that returns a LockKind required for the given level +/// of access. +LockKind getLockKindFromAccessKind(AccessKind AK); + +}} // end namespace clang::thread_safety +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h index badb493..e2e4f35 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h @@ -27,10 +27,16 @@ class UninitVariablesHandler { public: UninitVariablesHandler() {} virtual ~UninitVariablesHandler(); - + + /// Called when the uninitialized variable is used at the given expression. virtual void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd, bool isAlwaysUninit) {} + + /// Called when the uninitialized variable analysis detects the + /// idiom 'int x = x'. All other uses of 'x' within the initializer + /// are handled by handleUseOfUninitVariable. + virtual void handleSelfInit(const VarDecl *vd) {} }; struct UninitVariablesAnalysisStats { diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h index 6a1876e..3d0e88a 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h @@ -19,6 +19,7 @@ #include "clang/AST/Expr.h" #include "clang/Analysis/CFG.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/DenseMap.h" @@ -31,14 +32,35 @@ class Stmt; class CFGReverseBlockReachabilityAnalysis; class CFGStmtMap; class LiveVariables; +class ManagedAnalysis; class ParentMap; class PseudoConstantAnalysis; class ImplicitParamDecl; class LocationContextManager; class StackFrameContext; - + namespace idx { class TranslationUnit; } +/// The base class of a hierarchy of objects representing analyses tied +/// to AnalysisContext. +class ManagedAnalysis { +protected: + ManagedAnalysis() {} +public: + virtual ~ManagedAnalysis(); + + // Subclasses need to implement: + // + // static const void *getTag(); + // + // Which returns a fixed pointer address to distinguish classes of + // analysis objects. They also need to implement: + // + // static [Derived*] create(AnalysisContext &Ctx); + // + // which creates the analysis object given an AnalysisContext. +}; + /// AnalysisContext contains the context data for the function or method under /// analysis. class AnalysisContext { @@ -54,7 +76,6 @@ class AnalysisContext { CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs; bool builtCFG, builtCompleteCFG; - const bool useUnoptimizedCFG; llvm::OwningPtr<LiveVariables> liveness; llvm::OwningPtr<LiveVariables> relaxedLiveness; @@ -67,12 +88,13 @@ class AnalysisContext { // FIXME: remove. llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars; + void *ManagedAnalyses; + public: + AnalysisContext(const Decl *d, idx::TranslationUnit *tu); + AnalysisContext(const Decl *d, idx::TranslationUnit *tu, - bool useUnoptimizedCFG = false, - bool addehedges = false, - bool addImplicitDtors = false, - bool addInitializers = false); + const CFG::BuildOptions &buildOptions); ~AnalysisContext(); @@ -81,13 +103,22 @@ public: idx::TranslationUnit *getTranslationUnit() const { return TU; } + /// Return the build options used to construct the CFG. + CFG::BuildOptions &getCFGBuildOptions() { + return cfgBuildOptions; + } + + const CFG::BuildOptions &getCFGBuildOptions() const { + return cfgBuildOptions; + } + /// getAddEHEdges - Return true iff we are adding exceptional edges from /// callExprs. If this is false, then try/catch statements and blocks /// reachable from them can appear to be dead in the CFG, analysis passes must /// cope with that. bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; } bool getUseUnoptimizedCFG() const { - return cfgBuildOptions.PruneTriviallyFalseEdges; + return !cfgBuildOptions.PruneTriviallyFalseEdges; } bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; } bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; } @@ -95,7 +126,7 @@ public: void registerForcedBlockExpression(const Stmt *stmt); const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt); - Stmt *getBody(); + Stmt *getBody() const; CFG *getCFG(); CFGStmtMap *getCFGStmtMap(); @@ -114,8 +145,6 @@ public: ParentMap &getParentMap(); PseudoConstantAnalysis *getPseudoConstantAnalysis(); - LiveVariables *getLiveVariables(); - LiveVariables *getRelaxedLiveVariables(); typedef const VarDecl * const * referenced_decls_iterator; @@ -125,29 +154,44 @@ public: /// Return the ImplicitParamDecl* associated with 'self' if this /// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise. const ImplicitParamDecl *getSelfDecl() const; + + /// Return the specified analysis object, lazily running the analysis if + /// necessary. Return NULL if the analysis could not run. + template <typename T> + T *getAnalysis() { + const void *tag = T::getTag(); + ManagedAnalysis *&data = getAnalysisImpl(tag); + if (!data) { + data = T::create(*this); + } + return static_cast<T*>(data); + } +private: + ManagedAnalysis *&getAnalysisImpl(const void* tag); }; class AnalysisContextManager { typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap; ContextMap Contexts; - bool UseUnoptimizedCFG; - bool AddImplicitDtors; - bool AddInitializers; + CFG::BuildOptions cfgBuildOptions; public: AnalysisContextManager(bool useUnoptimizedCFG = false, - bool addImplicitDtors = false, bool addInitializers = false) - : UseUnoptimizedCFG(useUnoptimizedCFG), AddImplicitDtors(addImplicitDtors), - AddInitializers(addInitializers) {} + bool addImplicitDtors = false, + bool addInitializers = false); ~AnalysisContextManager(); AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0); - bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; } - bool getAddImplicitDtors() const { return AddImplicitDtors; } - bool getAddInitializers() const { return AddInitializers; } + bool getUseUnoptimizedCFG() const { + return !cfgBuildOptions.PruneTriviallyFalseEdges; + } + + CFG::BuildOptions &getCFGBuildOptions() { + return cfgBuildOptions; + } - // Discard all previously created AnalysisContexts. + /// Discard all previously created AnalysisContexts. void clear(); }; @@ -187,8 +231,9 @@ public: CFG *getCFG() const { return getAnalysisContext()->getCFG(); } - LiveVariables *getLiveVariables() const { - return getAnalysisContext()->getLiveVariables(); + template <typename T> + T *getAnalysis() const { + return getAnalysisContext()->getAnalysis<T>(); } ParentMap &getParentMap() const { @@ -212,7 +257,7 @@ public: ContextKind ck, AnalysisContext *ctx, const LocationContext *parent, - const void* data); + const void *data); }; class StackFrameContext : public LocationContext { @@ -251,7 +296,7 @@ public: ID.AddInteger(idx); } - static bool classof(const LocationContext* Ctx) { + static bool classof(const LocationContext *Ctx) { return Ctx->getKind() == StackFrame; } }; @@ -274,7 +319,7 @@ public: ProfileCommon(ID, Scope, ctx, parent, s); } - static bool classof(const LocationContext* Ctx) { + static bool classof(const LocationContext *Ctx) { return Ctx->getKind() == Scope; } }; @@ -302,7 +347,7 @@ public: ProfileCommon(ID, Block, ctx, parent, bd); } - static bool classof(const LocationContext* Ctx) { + static bool classof(const LocationContext *Ctx) { return Ctx->getKind() == Block; } }; diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h index dbf4e4c..16d31b4 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM, #define ANALYSISSTART #include "clang/Basic/DiagnosticAnalysisKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h index ca46459..f191c80 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h @@ -21,15 +21,13 @@ #include "llvm/Support/Casting.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/BitVector.h" +#include "clang/AST/Stmt.h" #include "clang/Analysis/Support/BumpVector.h" #include "clang/Basic/SourceLocation.h" #include <cassert> #include <iterator> -namespace llvm { - class raw_ostream; -} - namespace clang { class CXXDestructorDecl; class Decl; @@ -98,7 +96,9 @@ class CFGStmt : public CFGElement { public: CFGStmt(Stmt *S) : CFGElement(Statement, S) {} - Stmt *getStmt() const { return static_cast<Stmt *>(Data1.getPointer()); } + const Stmt *getStmt() const { + return static_cast<const Stmt *>(Data1.getPointer()); + } static bool classof(const CFGElement *E) { return E->getKind() == Statement; @@ -280,7 +280,7 @@ class CFGBlock { void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); } reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E, - BumpVectorContext& C) { + BumpVectorContext &C) { return Impl.insert(I, Cnt, E, C); } @@ -333,10 +333,21 @@ class CFGBlock { AdjacentBlocks Preds; AdjacentBlocks Succs; + /// NoReturn - This bit is set when the basic block contains a function call + /// or implicit destructor that is attributed as 'noreturn'. In that case, + /// control cannot technically ever proceed past this block. All such blocks + /// will have a single immediate successor: the exit block. This allows them + /// to be easily reached from the exit block and using this bit quickly + /// recognized without scanning the contents of the block. + /// + /// Optimization Note: This bit could be profitably folded with Terminator's + /// storage if the memory usage of CFGBlock becomes an issue. + unsigned HasNoReturnElement : 1; + public: explicit CFGBlock(unsigned blockid, BumpVectorContext &C) : Elements(C), Label(NULL), Terminator(NULL), LoopTarget(NULL), - BlockID(blockid), Preds(C, 1), Succs(C, 1) {} + BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false) {} ~CFGBlock() {} // Statement iterators @@ -455,42 +466,45 @@ public: // Manipulation of block contents - void setTerminator(Stmt* Statement) { Terminator = Statement; } - void setLabel(Stmt* Statement) { Label = Statement; } + void setTerminator(Stmt *Statement) { Terminator = Statement; } + void setLabel(Stmt *Statement) { Label = Statement; } void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; } + void setHasNoReturnElement() { HasNoReturnElement = true; } CFGTerminator getTerminator() { return Terminator; } const CFGTerminator getTerminator() const { return Terminator; } - Stmt* getTerminatorCondition(); + Stmt *getTerminatorCondition(); - const Stmt* getTerminatorCondition() const { + const Stmt *getTerminatorCondition() const { return const_cast<CFGBlock*>(this)->getTerminatorCondition(); } const Stmt *getLoopTarget() const { return LoopTarget; } - Stmt* getLabel() { return Label; } - const Stmt* getLabel() const { return Label; } + Stmt *getLabel() { return Label; } + const Stmt *getLabel() const { return Label; } + + bool hasNoReturnElement() const { return HasNoReturnElement; } unsigned getBlockID() const { return BlockID; } void dump(const CFG *cfg, const LangOptions &LO) const; - void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const; - void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const; + void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const; + void printTerminator(raw_ostream &OS, const LangOptions &LO) const; - void addSuccessor(CFGBlock* Block, BumpVectorContext &C) { + void addSuccessor(CFGBlock *Block, BumpVectorContext &C) { if (Block) Block->Preds.push_back(this, C); Succs.push_back(Block, C); } - void appendStmt(Stmt* statement, BumpVectorContext &C) { + void appendStmt(Stmt *statement, BumpVectorContext &C) { Elements.push_back(CFGStmt(statement), C); } void appendInitializer(CXXCtorInitializer *initializer, - BumpVectorContext& C) { + BumpVectorContext &C) { Elements.push_back(CFGInitializer(initializer), C); } @@ -506,14 +520,18 @@ public: Elements.push_back(CFGTemporaryDtor(E), C); } + void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) { + Elements.push_back(CFGAutomaticObjDtor(VD, S), C); + } + // Destructors must be inserted in reversed order. So insertion is in two // steps. First we prepare space for some number of elements, then we insert // the elements beginning at the last position in prepared space. iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, - BumpVectorContext& C) { + BumpVectorContext &C) { return iterator(Elements.insert(I.base(), Cnt, CFGElement(), C)); } - iterator insertAutomaticObjDtor(iterator I, VarDecl* VD, Stmt* S) { + iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) { *I = CFGAutomaticObjDtor(VD, S); return ++I; } @@ -533,30 +551,46 @@ public: //===--------------------------------------------------------------------===// class BuildOptions { + llvm::BitVector alwaysAddMask; public: typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs; ForcedBlkExprs **forcedBlkExprs; - bool PruneTriviallyFalseEdges:1; - bool AddEHEdges:1; - bool AddInitializers:1; - bool AddImplicitDtors:1; + bool PruneTriviallyFalseEdges; + bool AddEHEdges; + bool AddInitializers; + bool AddImplicitDtors; + + bool alwaysAdd(const Stmt *stmt) const { + return alwaysAddMask[stmt->getStmtClass()]; + } + + BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) { + alwaysAddMask[stmtClass] = val; + return *this; + } + + BuildOptions &setAllAlwaysAdd() { + alwaysAddMask.set(); + return *this; + } BuildOptions() - : forcedBlkExprs(0), PruneTriviallyFalseEdges(true) - , AddEHEdges(false) - , AddInitializers(false) - , AddImplicitDtors(false) {} + : alwaysAddMask(Stmt::lastStmtConstant, false) + ,forcedBlkExprs(0), PruneTriviallyFalseEdges(true) + ,AddEHEdges(false) + ,AddInitializers(false) + ,AddImplicitDtors(false) {} }; /// buildCFG - Builds a CFG from an AST. The responsibility to free the /// constructed CFG belongs to the caller. - static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C, + static CFG* buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO); /// createBlock - Create a new block in the CFG. The CFG owns the block; /// the caller should not directly free it. - CFGBlock* createBlock(); + CFGBlock *createBlock(); /// setEntry - Set the entry block of the CFG. This is typically used /// only during CFG construction. Most CFG clients expect that the @@ -565,7 +599,7 @@ public: /// setIndirectGotoBlock - Set the block used for indirect goto jumps. /// This is typically used only during CFG construction. - void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; } + void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; } //===--------------------------------------------------------------------===// // Block Iterators @@ -577,8 +611,8 @@ public: typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - CFGBlock& front() { return *Blocks.front(); } - CFGBlock& back() { return *Blocks.back(); } + CFGBlock & front() { return *Blocks.front(); } + CFGBlock & back() { return *Blocks.back(); } iterator begin() { return Blocks.begin(); } iterator end() { return Blocks.end(); } @@ -590,13 +624,25 @@ public: const_reverse_iterator rbegin() const { return Blocks.rbegin(); } const_reverse_iterator rend() const { return Blocks.rend(); } - CFGBlock& getEntry() { return *Entry; } - const CFGBlock& getEntry() const { return *Entry; } - CFGBlock& getExit() { return *Exit; } - const CFGBlock& getExit() const { return *Exit; } + CFGBlock & getEntry() { return *Entry; } + const CFGBlock & getEntry() const { return *Entry; } + CFGBlock & getExit() { return *Exit; } + const CFGBlock & getExit() const { return *Exit; } - CFGBlock* getIndirectGotoBlock() { return IndirectGotoBlock; } - const CFGBlock* getIndirectGotoBlock() const { return IndirectGotoBlock; } + CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; } + const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; } + + typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator; + try_block_iterator try_blocks_begin() const { + return TryDispatchBlocks.begin(); + } + try_block_iterator try_blocks_end() const { + return TryDispatchBlocks.end(); + } + + void addTryDispatchBlock(const CFGBlock *block) { + TryDispatchBlocks.push_back(block); + } //===--------------------------------------------------------------------===// // Member templates useful for various batch operations over CFGs. @@ -608,7 +654,7 @@ public: for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end(); BI != BE; ++BI) { if (const CFGStmt *stmt = BI->getAs<CFGStmt>()) - O(stmt->getStmt()); + O(const_cast<Stmt*>(stmt->getStmt())); } } @@ -624,11 +670,11 @@ public: operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; } }; - bool isBlkExpr(const Stmt* S) { return getBlkExprNum(S); } + bool isBlkExpr(const Stmt *S) { return getBlkExprNum(S); } bool isBlkExpr(const Stmt *S) const { return const_cast<CFG*>(this)->isBlkExpr(S); } - BlkExprNumTy getBlkExprNum(const Stmt* S); + BlkExprNumTy getBlkExprNum(const Stmt *S); unsigned getNumBlkExprs(); /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which @@ -640,7 +686,7 @@ public: //===--------------------------------------------------------------------===// void viewCFG(const LangOptions &LO) const; - void print(llvm::raw_ostream& OS, const LangOptions &LO) const; + void print(raw_ostream &OS, const LangOptions &LO) const; void dump(const LangOptions &LO) const; //===--------------------------------------------------------------------===// @@ -661,8 +707,8 @@ public: } private: - CFGBlock* Entry; - CFGBlock* Exit; + CFGBlock *Entry; + CFGBlock *Exit; CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch // for indirect gotos unsigned NumBlockIDs; @@ -670,11 +716,15 @@ private: // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h. // It represents a map from Expr* to integers to record the set of // block-level expressions and their "statement number" in the CFG. - void* BlkExprMap; + void * BlkExprMap; BumpVectorContext BlkBVC; CFGBlockListTy Blocks; + + /// C++ 'try' statements are modeled with an indirect dispatch block. + /// This is the collection of such blocks present in the CFG. + std::vector<const CFGBlock *> TryDispatchBlocks; }; } // end namespace clang @@ -703,11 +753,11 @@ template <> struct simplify_type< ::clang::CFGTerminator> { // Traits for: CFGBlock -template <> struct GraphTraits< ::clang::CFGBlock* > { +template <> struct GraphTraits< ::clang::CFGBlock *> { typedef ::clang::CFGBlock NodeType; typedef ::clang::CFGBlock::succ_iterator ChildIteratorType; - static NodeType* getEntryNode(::clang::CFGBlock* BB) + static NodeType* getEntryNode(::clang::CFGBlock *BB) { return BB; } static inline ChildIteratorType child_begin(NodeType* N) @@ -717,11 +767,11 @@ template <> struct GraphTraits< ::clang::CFGBlock* > { { return N->succ_end(); } }; -template <> struct GraphTraits< const ::clang::CFGBlock* > { +template <> struct GraphTraits< const ::clang::CFGBlock *> { typedef const ::clang::CFGBlock NodeType; typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType; - static NodeType* getEntryNode(const clang::CFGBlock* BB) + static NodeType* getEntryNode(const clang::CFGBlock *BB) { return BB; } static inline ChildIteratorType child_begin(NodeType* N) @@ -748,7 +798,7 @@ template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > { // Traits for: CFG template <> struct GraphTraits< ::clang::CFG* > - : public GraphTraits< ::clang::CFGBlock* > { + : public GraphTraits< ::clang::CFGBlock *> { typedef ::clang::CFG::iterator nodes_iterator; @@ -758,7 +808,7 @@ template <> struct GraphTraits< ::clang::CFG* > }; template <> struct GraphTraits<const ::clang::CFG* > - : public GraphTraits<const ::clang::CFGBlock* > { + : public GraphTraits<const ::clang::CFGBlock *> { typedef ::clang::CFG::const_iterator nodes_iterator; diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/contrib/llvm/tools/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h index 5a4e06f..fa8afcc 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h @@ -14,12 +14,13 @@ #ifndef LLVM_CLANG_ANALYSIS_DS_COCOA #define LLVM_CLANG_ANALYSIS_DS_COCOA +#include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/StringRef.h" -#include "clang/AST/Type.h" namespace clang { - +class FunctionDecl; class ObjCMethodDecl; +class QualType; namespace ento { namespace cocoa { @@ -33,8 +34,8 @@ namespace cocoa { return deriveNamingConvention(S, MD) == CreateRule; } - bool isRefType(QualType RetTy, llvm::StringRef Prefix, - llvm::StringRef Name = llvm::StringRef()); + bool isRefType(QualType RetTy, StringRef Prefix, + StringRef Name = StringRef()); bool isCocoaObjectRef(QualType T); @@ -43,7 +44,7 @@ namespace cocoa { namespace coreFoundation { bool isCFObjectRef(QualType T); - bool followsCreateRule(llvm::StringRef functionName); + bool followsCreateRule(const FunctionDecl *FD); } }} // end: "clang:ento" diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h index 9561b96..017da63 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h @@ -30,11 +30,11 @@ namespace clang { class DataflowWorkListTy { llvm::DenseMap<const CFGBlock*, unsigned char> BlockSet; - llvm::SmallVector<const CFGBlock *, 10> BlockQueue; + SmallVector<const CFGBlock *, 10> BlockQueue; public: /// enqueue - Add a block to the worklist. Blocks already on the /// worklist are not added a second time. - void enqueue(const CFGBlock* B) { + void enqueue(const CFGBlock *B) { unsigned char &x = BlockSet[B]; if (x == 1) return; @@ -43,7 +43,7 @@ public: } /// dequeue - Remove a block from the worklist. - const CFGBlock* dequeue() { + const CFGBlock *dequeue() { assert(!BlockQueue.empty()); const CFGBlock *B = BlockQueue.back(); BlockQueue.pop_back(); @@ -69,20 +69,20 @@ template <> struct ItrTraits<forward_analysis_tag> { typedef CFGBlock::const_succ_iterator NextBItr; typedef CFGBlock::const_iterator StmtItr; - static PrevBItr PrevBegin(const CFGBlock* B) { return B->pred_begin(); } - static PrevBItr PrevEnd(const CFGBlock* B) { return B->pred_end(); } + static PrevBItr PrevBegin(const CFGBlock *B) { return B->pred_begin(); } + static PrevBItr PrevEnd(const CFGBlock *B) { return B->pred_end(); } - static NextBItr NextBegin(const CFGBlock* B) { return B->succ_begin(); } - static NextBItr NextEnd(const CFGBlock* B) { return B->succ_end(); } + static NextBItr NextBegin(const CFGBlock *B) { return B->succ_begin(); } + static NextBItr NextEnd(const CFGBlock *B) { return B->succ_end(); } - static StmtItr StmtBegin(const CFGBlock* B) { return B->begin(); } - static StmtItr StmtEnd(const CFGBlock* B) { return B->end(); } + static StmtItr StmtBegin(const CFGBlock *B) { return B->begin(); } + static StmtItr StmtEnd(const CFGBlock *B) { return B->end(); } - static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) { + static BlockEdge PrevEdge(const CFGBlock *B, const CFGBlock *Prev) { return BlockEdge(Prev, B, 0); } - static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) { + static BlockEdge NextEdge(const CFGBlock *B, const CFGBlock *Next) { return BlockEdge(B, Next, 0); } }; @@ -92,20 +92,20 @@ template <> struct ItrTraits<backward_analysis_tag> { typedef CFGBlock::const_pred_iterator NextBItr; typedef CFGBlock::const_reverse_iterator StmtItr; - static PrevBItr PrevBegin(const CFGBlock* B) { return B->succ_begin(); } - static PrevBItr PrevEnd(const CFGBlock* B) { return B->succ_end(); } + static PrevBItr PrevBegin(const CFGBlock *B) { return B->succ_begin(); } + static PrevBItr PrevEnd(const CFGBlock *B) { return B->succ_end(); } - static NextBItr NextBegin(const CFGBlock* B) { return B->pred_begin(); } - static NextBItr NextEnd(const CFGBlock* B) { return B->pred_end(); } + static NextBItr NextBegin(const CFGBlock *B) { return B->pred_begin(); } + static NextBItr NextEnd(const CFGBlock *B) { return B->pred_end(); } - static StmtItr StmtBegin(const CFGBlock* B) { return B->rbegin(); } - static StmtItr StmtEnd(const CFGBlock* B) { return B->rend(); } + static StmtItr StmtBegin(const CFGBlock *B) { return B->rbegin(); } + static StmtItr StmtEnd(const CFGBlock *B) { return B->rend(); } - static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) { + static BlockEdge PrevEdge(const CFGBlock *B, const CFGBlock *Prev) { return BlockEdge(B, Prev, 0); } - static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) { + static BlockEdge NextEdge(const CFGBlock *B, const CFGBlock *Next) { return BlockEdge(Next, B, 0); } }; @@ -162,7 +162,7 @@ public: /// dataflow values using runOnCFG, as runOnBlock is intended to /// only be used for querying the dataflow values within a block /// with and Observer object. - void runOnBlock(const CFGBlock* B, bool recordStmtValues) { + void runOnBlock(const CFGBlock *B, bool recordStmtValues) { BlockDataMapTy& M = D.getBlockDataMap(); typename BlockDataMapTy::iterator I = M.find(B); @@ -172,13 +172,13 @@ public: } } - void runOnBlock(const CFGBlock& B, bool recordStmtValues) { + void runOnBlock(const CFGBlock &B, bool recordStmtValues) { runOnBlock(&B, recordStmtValues); } - void runOnBlock(CFG::iterator& I, bool recordStmtValues) { + void runOnBlock(CFG::iterator &I, bool recordStmtValues) { runOnBlock(*I, recordStmtValues); } - void runOnBlock(CFG::const_iterator& I, bool recordStmtValues) { + void runOnBlock(CFG::const_iterator &I, bool recordStmtValues) { runOnBlock(*I, recordStmtValues); } @@ -199,7 +199,7 @@ private: EnqueueBlocksOnWorklist(cfg, AnalysisDirTag()); while (!WorkList.isEmpty()) { - const CFGBlock* B = WorkList.dequeue(); + const CFGBlock *B = WorkList.dequeue(); ProcessMerge(cfg, B); ProcessBlock(B, recordStmtValues, AnalysisDirTag()); UpdateEdges(cfg, B, TF.getVal()); @@ -222,7 +222,7 @@ private: WorkList.enqueue(&**I); } - void ProcessMerge(CFG& cfg, const CFGBlock* B) { + void ProcessMerge(CFG& cfg, const CFGBlock *B) { ValTy& V = TF.getVal(); TF.SetTopValue(V); @@ -270,7 +270,7 @@ private: } /// ProcessBlock - Process the transfer functions for a given block. - void ProcessBlock(const CFGBlock* B, bool recordStmtValues, + void ProcessBlock(const CFGBlock *B, bool recordStmtValues, dataflow::forward_analysis_tag) { TF.setCurrentBlock(B); @@ -284,7 +284,7 @@ private: TF.VisitTerminator(const_cast<CFGBlock*>(B)); } - void ProcessBlock(const CFGBlock* B, bool recordStmtValues, + void ProcessBlock(const CFGBlock *B, bool recordStmtValues, dataflow::backward_analysis_tag) { TF.setCurrentBlock(B); @@ -298,12 +298,12 @@ private: } } - void ProcessStmt(const Stmt* S, bool record, dataflow::forward_analysis_tag) { + void ProcessStmt(const Stmt *S, bool record, dataflow::forward_analysis_tag) { if (record) D.getStmtDataMap()[S] = TF.getVal(); TF.BlockStmt_Visit(const_cast<Stmt*>(S)); } - void ProcessStmt(const Stmt* S, bool record, dataflow::backward_analysis_tag){ + void ProcessStmt(const Stmt *S, bool record, dataflow::backward_analysis_tag){ TF.BlockStmt_Visit(const_cast<Stmt*>(S)); if (record) D.getStmtDataMap()[S] = TF.getVal(); } @@ -312,14 +312,14 @@ private: /// block, update the dataflow value associated with the block's /// outgoing/incoming edges (depending on whether we do a // forward/backward analysis respectively) - void UpdateEdges(CFG& cfg, const CFGBlock* B, ValTy& V) { + void UpdateEdges(CFG& cfg, const CFGBlock *B, ValTy& V) { for (NextBItr I=ItrTraits::NextBegin(B), E=ItrTraits::NextEnd(B); I!=E; ++I) if (CFGBlock *NextBlk = *I) UpdateEdgeValue(ItrTraits::NextEdge(B, NextBlk),V, NextBlk); } /// UpdateEdgeValue - Update the value associated with a given edge. - void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock* TargetBlock) { + void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock *TargetBlock) { EdgeDataMapTy& M = D.getEdgeDataMap(); typename EdgeDataMapTy::iterator I = M.find(E); diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h index 7aa15c5..f86b2b0 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h @@ -84,13 +84,13 @@ public: /// getEdgeData - Retrieves the dataflow values associated with a /// CFG edge. - ValTy& getEdgeData(const BlockEdge& E) { + ValTy& getEdgeData(const BlockEdge &E) { typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E); assert (I != EdgeDataMap.end() && "No data associated with Edge."); return I->second; } - const ValTy& getEdgeData(const BlockEdge& E) const { + const ValTy& getEdgeData(const BlockEdge &E) const { return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E); } @@ -98,13 +98,13 @@ public: /// specified CFGBlock. If the dataflow analysis is a forward analysis, /// this data is associated with the END of the block. If the analysis /// is a backwards analysis, it is associated with the ENTRY of the block. - ValTy& getBlockData(const CFGBlock* B) { + ValTy& getBlockData(const CFGBlock *B) { typename BlockDataMapTy::iterator I = BlockDataMap.find(B); assert (I != BlockDataMap.end() && "No data associated with block."); return I->second; } - const ValTy& getBlockData(const CFGBlock* B) const { + const ValTy& getBlockData(const CFGBlock *B) const { return const_cast<DataflowValues*>(this)->getBlockData(B); } @@ -114,14 +114,14 @@ public: /// If the analysis is a backwards analysis, it is associated with /// the point after a Stmt. This data is only computed for block-level /// expressions, and only when requested when the analysis is executed. - ValTy& getStmtData(const Stmt* S) { + ValTy& getStmtData(const Stmt *S) { assert (StmtDataMap && "Dataflow values were not computed for statements."); typename StmtDataMapTy::iterator I = StmtDataMap->find(S); assert (I != StmtDataMap->end() && "No data associated with statement."); return I->second; } - const ValTy& getStmtData(const Stmt* S) const { + const ValTy& getStmtData(const Stmt *S) const { return const_cast<DataflowValues*>(this)->getStmtData(S); } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h index 07b4dea..7ec4ecd 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h @@ -21,15 +21,18 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/Support/Casting.h" +#include "llvm/ADT/StringRef.h" #include <cassert> #include <utility> +#include <string> namespace clang { -class LocationContext; class AnalysisContext; class FunctionDecl; - +class LocationContext; +class ProgramPointTag; + class ProgramPoint { public: enum Kind { BlockEdgeKind, @@ -42,7 +45,6 @@ public: PreStoreKind, PostStoreKind, PostPurgeDeadSymbolsKind, - PostStmtCustomKind, PostConditionKind, PostLValueKind, PostInitializerKind, @@ -58,25 +60,33 @@ private: // The LocationContext could be NULL to allow ProgramPoint to be used in // context insensitive analysis. const LocationContext *L; - const void *Tag; + const ProgramPointTag *Tag; + ProgramPoint(); + protected: - ProgramPoint(const void* P, Kind k, const LocationContext *l, - const void *tag = 0) + ProgramPoint(const void *P, Kind k, const LocationContext *l, + const ProgramPointTag *tag = 0) : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {} - ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l, - const void *tag = 0) + ProgramPoint(const void *P1, const void *P2, Kind k, const LocationContext *l, + const ProgramPointTag *tag = 0) : Data(P1, P2), K(k), L(l), Tag(tag) {} protected: - const void* getData1() const { return Data.first; } - const void* getData2() const { return Data.second; } + const void *getData1() const { return Data.first; } + const void *getData2() const { return Data.second; } public: + /// Create a new ProgramPoint object that is the same as the original + /// except for using the specified tag value. + ProgramPoint withTag(const ProgramPointTag *tag) const { + return ProgramPoint(Data.first, Data.second, K, L, tag); + } + Kind getKind() const { return K; } - const void *getTag() const { return Tag; } + const ProgramPointTag *getTag() const { return Tag; } const LocationContext *getLocationContext() const { return L; } @@ -93,7 +103,7 @@ public: return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag; } - bool operator!=(const ProgramPoint& RHS) const { + bool operator!=(const ProgramPoint &RHS) const { return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag; } @@ -104,29 +114,30 @@ public: ID.AddPointer(L); ID.AddPointer(Tag); } + + static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, + const LocationContext *LC, + const ProgramPointTag *tag); + }; class BlockEntrance : public ProgramPoint { public: - BlockEntrance(const CFGBlock* B, const LocationContext *L, - const void *tag = 0) - : ProgramPoint(B, BlockEntranceKind, L, tag) {} + BlockEntrance(const CFGBlock *B, const LocationContext *L, + const ProgramPointTag *tag = 0) + : ProgramPoint(B, BlockEntranceKind, L, tag) { + assert(B && "BlockEntrance requires non-null block"); + } - const CFGBlock* getBlock() const { + const CFGBlock *getBlock() const { return reinterpret_cast<const CFGBlock*>(getData1()); } const CFGElement getFirstElement() const { - const CFGBlock* B = getBlock(); + const CFGBlock *B = getBlock(); return B->empty() ? CFGElement() : B->front(); } - /// Create a new BlockEntrance object that is the same as the original - /// except for using the specified tag value. - BlockEntrance withTag(const void *tag) { - return BlockEntrance(getBlock(), getLocationContext(), tag); - } - static bool classof(const ProgramPoint* Location) { return Location->getKind() == BlockEntranceKind; } @@ -134,14 +145,14 @@ public: class BlockExit : public ProgramPoint { public: - BlockExit(const CFGBlock* B, const LocationContext *L) + BlockExit(const CFGBlock *B, const LocationContext *L) : ProgramPoint(B, BlockExitKind, L) {} - const CFGBlock* getBlock() const { + const CFGBlock *getBlock() const { return reinterpret_cast<const CFGBlock*>(getData1()); } - const Stmt* getTerminator() const { + const Stmt *getTerminator() const { return getBlock()->getTerminator(); } @@ -153,7 +164,7 @@ public: class StmtPoint : public ProgramPoint { public: StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, - const void *tag) + const ProgramPointTag *tag) : ProgramPoint(S, p2, k, L, tag) {} const Stmt *getStmt() const { return (const Stmt*) getData1(); } @@ -170,7 +181,7 @@ public: class PreStmt : public StmtPoint { public: - PreStmt(const Stmt *S, const LocationContext *L, const void *tag, + PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag, const Stmt *SubStmt = 0) : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} @@ -183,16 +194,17 @@ public: class PostStmt : public StmtPoint { protected: - PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L, - const void *tag =0) + PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L, + const ProgramPointTag *tag =0) : StmtPoint(S, data, k, L, tag) {} public: - explicit PostStmt(const Stmt* S, Kind k, - const LocationContext *L, const void *tag = 0) + explicit PostStmt(const Stmt *S, Kind k, + const LocationContext *L, const ProgramPointTag *tag = 0) : StmtPoint(S, NULL, k, L, tag) {} - explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0) + explicit PostStmt(const Stmt *S, const LocationContext *L, + const ProgramPointTag *tag = 0) : StmtPoint(S, NULL, PostStmtKind, L, tag) {} static bool classof(const ProgramPoint* Location) { @@ -201,31 +213,11 @@ public: } }; -class PostStmtCustom : public PostStmt { -public: - PostStmtCustom(const Stmt* S, - const std::pair<const void*, const void*>* TaggedData,\ - const LocationContext *L) - : PostStmt(S, TaggedData, PostStmtCustomKind, L) {} - - const std::pair<const void*, const void*>& getTaggedPair() const { - return - *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2()); - } - - const void* getTag() const { return getTaggedPair().first; } - - const void* getTaggedData() const { return getTaggedPair().second; } - - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PostStmtCustomKind; - } -}; - // PostCondition represents the post program point of a branch condition. class PostCondition : public PostStmt { public: - PostCondition(const Stmt* S, const LocationContext *L, const void *tag = 0) + PostCondition(const Stmt *S, const LocationContext *L, + const ProgramPointTag *tag = 0) : PostStmt(S, PostConditionKind, L, tag) {} static bool classof(const ProgramPoint* Location) { @@ -236,7 +228,7 @@ public: class LocationCheck : public StmtPoint { protected: LocationCheck(const Stmt *S, const LocationContext *L, - ProgramPoint::Kind K, const void *tag) + ProgramPoint::Kind K, const ProgramPointTag *tag) : StmtPoint(S, NULL, K, L, tag) {} static bool classof(const ProgramPoint *location) { @@ -247,7 +239,8 @@ protected: class PreLoad : public LocationCheck { public: - PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0) + PreLoad(const Stmt *S, const LocationContext *L, + const ProgramPointTag *tag = 0) : LocationCheck(S, L, PreLoadKind, tag) {} static bool classof(const ProgramPoint *location) { @@ -257,7 +250,8 @@ public: class PreStore : public LocationCheck { public: - PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0) + PreStore(const Stmt *S, const LocationContext *L, + const ProgramPointTag *tag = 0) : LocationCheck(S, L, PreStoreKind, tag) {} static bool classof(const ProgramPoint *location) { @@ -267,7 +261,8 @@ public: class PostLoad : public PostStmt { public: - PostLoad(const Stmt* S, const LocationContext *L, const void *tag = 0) + PostLoad(const Stmt *S, const LocationContext *L, + const ProgramPointTag *tag = 0) : PostStmt(S, PostLoadKind, L, tag) {} static bool classof(const ProgramPoint* Location) { @@ -277,7 +272,8 @@ public: class PostStore : public PostStmt { public: - PostStore(const Stmt* S, const LocationContext *L, const void *tag = 0) + PostStore(const Stmt *S, const LocationContext *L, + const ProgramPointTag *tag = 0) : PostStmt(S, PostStoreKind, L, tag) {} static bool classof(const ProgramPoint* Location) { @@ -287,7 +283,8 @@ public: class PostLValue : public PostStmt { public: - PostLValue(const Stmt* S, const LocationContext *L, const void *tag = 0) + PostLValue(const Stmt *S, const LocationContext *L, + const ProgramPointTag *tag = 0) : PostStmt(S, PostLValueKind, L, tag) {} static bool classof(const ProgramPoint* Location) { @@ -297,8 +294,8 @@ public: class PostPurgeDeadSymbols : public PostStmt { public: - PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L, - const void *tag = 0) + PostPurgeDeadSymbols(const Stmt *S, const LocationContext *L, + const ProgramPointTag *tag = 0) : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {} static bool classof(const ProgramPoint* Location) { @@ -308,14 +305,17 @@ public: class BlockEdge : public ProgramPoint { public: - BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L) - : ProgramPoint(B1, B2, BlockEdgeKind, L) {} + BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L) + : ProgramPoint(B1, B2, BlockEdgeKind, L) { + assert(B1 && "BlockEdge: source block must be non-null"); + assert(B2 && "BlockEdge: destination block must be non-null"); + } - const CFGBlock* getSrc() const { + const CFGBlock *getSrc() const { return static_cast<const CFGBlock*>(getData1()); } - const CFGBlock* getDst() const { + const CFGBlock *getDst() const { return static_cast<const CFGBlock*>(getData2()); } @@ -365,6 +365,29 @@ public: } }; +/// ProgramPoints can be "tagged" as representing points specific to a given +/// analysis entity. Tags are abstract annotations, with an associated +/// description and potentially other information. +class ProgramPointTag { +public: + ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {} + virtual ~ProgramPointTag(); + virtual StringRef getTagDescription() const = 0; + +protected: + /// Used to implement 'classof' in subclasses. + const void *getTagKind() { return TagKind; } + +private: + const void *TagKind; +}; + +class SimpleProgramPointTag : public ProgramPointTag { + std::string desc; +public: + SimpleProgramPointTag(StringRef description); + StringRef getTagDescription() const; +}; } // end namespace clang @@ -385,12 +408,12 @@ static inline clang::ProgramPoint getTombstoneKey() { return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0); } -static unsigned getHashValue(const clang::ProgramPoint& Loc) { +static unsigned getHashValue(const clang::ProgramPoint &Loc) { return Loc.getHashValue(); } -static bool isEqual(const clang::ProgramPoint& L, - const clang::ProgramPoint& R) { +static bool isEqual(const clang::ProgramPoint &L, + const clang::ProgramPoint &R) { return L == R; } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h index 27ecc66..d25b848 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h @@ -62,16 +62,16 @@ struct DeclBitVector_Types { AnalysisDataTy() : NDecls(0) {} virtual ~AnalysisDataTy() {} - bool isTracked(const NamedDecl* SD) { return DMap.find(SD) != DMap.end(); } + bool isTracked(const NamedDecl *SD) { return DMap.find(SD) != DMap.end(); } - Idx getIdx(const NamedDecl* SD) const { + Idx getIdx(const NamedDecl *SD) const { DMapTy::const_iterator I = DMap.find(SD); return I == DMap.end() ? Idx() : Idx(I->second); } unsigned getNumDecls() const { return NDecls; } - void Register(const NamedDecl* SD) { + void Register(const NamedDecl *SD) { if (!isTracked(SD)) DMap[SD] = NDecls++; } @@ -117,11 +117,11 @@ struct DeclBitVector_Types { } llvm::BitVector::reference - operator()(const NamedDecl* ND, const AnalysisDataTy& AD) { + operator()(const NamedDecl *ND, const AnalysisDataTy& AD) { return getBit(AD.getIdx(ND)); } - bool operator()(const NamedDecl* ND, const AnalysisDataTy& AD) const { + bool operator()(const NamedDecl *ND, const AnalysisDataTy& AD) const { return getBit(AD.getIdx(ND)); } @@ -171,14 +171,14 @@ struct StmtDeclBitVector_Types { //===--------------------------------------------------------------------===// class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy { - ASTContext* ctx; + ASTContext *ctx; CFG* cfg; public: AnalysisDataTy() : ctx(0), cfg(0) {} virtual ~AnalysisDataTy() {} - void setContext(ASTContext& c) { ctx = &c; } - ASTContext& getContext() { + void setContext(ASTContext &c) { ctx = &c; } + ASTContext &getContext() { assert(ctx && "ASTContext should not be NULL."); return *ctx; } @@ -186,10 +186,10 @@ struct StmtDeclBitVector_Types { void setCFG(CFG& c) { cfg = &c; } CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; } - bool isTracked(const Stmt* S) { return cfg->isBlkExpr(S); } + bool isTracked(const Stmt *S) { return cfg->isBlkExpr(S); } using DeclBitVector_Types::AnalysisDataTy::isTracked; - unsigned getIdx(const Stmt* S) const { + unsigned getIdx(const Stmt *S) const { CFG::BlkExprNumTy I = cfg->getBlkExprNum(S); assert(I && "Stmtession not tracked for bitvector."); return I; @@ -248,11 +248,11 @@ struct StmtDeclBitVector_Types { } llvm::BitVector::reference - operator()(const Stmt* S, const AnalysisDataTy& AD) { + operator()(const Stmt *S, const AnalysisDataTy& AD) { return BlkExprBV[AD.getIdx(S)]; } const llvm::BitVector::reference - operator()(const Stmt* S, const AnalysisDataTy& AD) const { + operator()(const Stmt *S, const AnalysisDataTy& AD) const { return const_cast<ValTy&>(*this)(S,AD); } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h index 95f4ace..5c5ec2d 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h @@ -28,8 +28,8 @@ static_cast<ImplClass*>(this)->Visit##CLASS##Decl( \ static_cast<CLASS##Decl*>(D)); \ break; -#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS##Decl(CLASS##Decl* D) {} -#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS##Decl(CLASS##Decl* D)\ +#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS##Decl(CLASS##Decl *D) {} +#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS##Decl(CLASS##Decl *D)\ { static_cast<ImplClass*>(this)->VisitVarDecl(D); } @@ -38,23 +38,23 @@ template <typename ImplClass> class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor<ImplClass> { public: - void VisitDeclRefExpr(DeclRefExpr* DR) { + void VisitDeclRefExpr(DeclRefExpr *DR) { static_cast<ImplClass*>(this)->VisitDecl(DR->getDecl()); } - void VisitDeclStmt(DeclStmt* DS) { + void VisitDeclStmt(DeclStmt *DS) { for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end(); DI != DE; ++DI) { - Decl* D = *DI; + Decl *D = *DI; static_cast<ImplClass*>(this)->VisitDecl(D); // Visit the initializer. - if (VarDecl* VD = dyn_cast<VarDecl>(D)) - if (Expr* I = VD->getInit()) + if (VarDecl *VD = dyn_cast<VarDecl>(D)) + if (Expr *I = VD->getInit()) static_cast<ImplClass*>(this)->Visit(I); } } - void VisitDecl(Decl* D) { + void VisitDecl(Decl *D) { switch (D->getKind()) { DISPATCH_CASE(Function) DISPATCH_CASE(CXXMethod) @@ -69,7 +69,7 @@ public: DISPATCH_CASE(UsingDirective) DISPATCH_CASE(Using) default: - assert(false && "Subtype of ScopedDecl not handled."); + llvm_unreachable("Subtype of ScopedDecl not handled."); } } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h index bb7cf0b..4d1cabf 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h @@ -22,7 +22,7 @@ template <typename ImplClass> class CFGRecStmtVisitor : public CFGStmtVisitor<ImplClass,void> { public: - void VisitStmt(Stmt* S) { + void VisitStmt(Stmt *S) { static_cast< ImplClass* >(this)->VisitChildren(S); } @@ -45,13 +45,13 @@ break; CONDVAR_CASE(WhileStmt) #undef CONDVAR_CASE default: - assert(false && "Infeasible"); + llvm_unreachable("Infeasible"); } static_cast<ImplClass*>(this)->Visit(CondVar->getInit()); } // Defining operator() allows the visitor to be used as a C++ style functor. - void operator()(Stmt* S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);} + void operator()(Stmt *S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);} }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h index 7fb4ab3..b354ba7 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h @@ -33,7 +33,7 @@ static_cast<ImplClass*>(this)->BlockStmt_Visit ## CLASS(static_cast<CLASS*>(S)); template <typename ImplClass, typename RetTy=void> class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> { - Stmt* CurrentBlkStmt; + Stmt *CurrentBlkStmt; struct NullifyStmt { Stmt*& S; @@ -45,9 +45,9 @@ class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> { public: CFGStmtVisitor() : CurrentBlkStmt(NULL) {} - Stmt* getCurrentBlkStmt() const { return CurrentBlkStmt; } + Stmt *getCurrentBlkStmt() const { return CurrentBlkStmt; } - RetTy Visit(Stmt* S) { + RetTy Visit(Stmt *S) { if (S == CurrentBlkStmt || !static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S)) return StmtVisitor<ImplClass,RetTy>::Visit(S); @@ -67,7 +67,7 @@ public: /// the list of statements in a CFGBlock. For substatements, or when there /// is no implementation provided for a BlockStmt_XXX method, we default /// to using StmtVisitor's Visit method. - RetTy BlockStmt_Visit(Stmt* S) { + RetTy BlockStmt_Visit(Stmt *S) { CurrentBlkStmt = S; NullifyStmt cleanup(CurrentBlkStmt); @@ -106,23 +106,23 @@ public: DEFAULT_BLOCKSTMT_VISIT(ConditionalOperator) DEFAULT_BLOCKSTMT_VISIT(BinaryConditionalOperator) - RetTy BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) { + RetTy BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); } - RetTy BlockStmt_VisitCXXForRangeStmt(CXXForRangeStmt* S) { + RetTy BlockStmt_VisitCXXForRangeStmt(CXXForRangeStmt *S) { return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); } - RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr* E) { + RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr *E) { return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E); } - RetTy BlockStmt_VisitExpr(Expr* E) { + RetTy BlockStmt_VisitExpr(Expr *E) { return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(E); } - RetTy BlockStmt_VisitStmt(Stmt* S) { + RetTy BlockStmt_VisitStmt(Stmt *S) { return static_cast<ImplClass*>(this)->Visit(S); } @@ -141,14 +141,14 @@ public: //===--------------------------------------------------------------------===// /// VisitChildren: Call "Visit" on each child of S. - void VisitChildren(Stmt* S) { + void VisitChildren(Stmt *S) { switch (S->getStmtClass()) { default: break; case Stmt::StmtExprClass: { - CompoundStmt* CS = cast<StmtExpr>(S)->getSubStmt(); + CompoundStmt *CS = cast<StmtExpr>(S)->getSubStmt(); if (CS->body_empty()) return; static_cast<ImplClass*>(this)->Visit(CS->body_back()); return; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td index e64dc6a..2a4ba5c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td @@ -54,7 +54,9 @@ class ExprArgument<string name> : Argument<name>; class FunctionArgument<string name> : Argument<name>; class TypeArgument<string name> : Argument<name>; class UnsignedArgument<string name> : Argument<name>; +class SourceLocArgument<string name> : Argument<name>; class VariadicUnsignedArgument<string name> : Argument<name>; +class VariadicExprArgument<string name> : Argument<name>; // A version of the form major.minor[.subminor]. class VersionArgument<string name> : Argument<name>; @@ -89,7 +91,9 @@ class Attr { // The attribute will not be permitted in C++0x attribute-specifiers if // this is empty; the empty string can be used as a namespace. list<string> Namespaces = []; - // Any additional text that should be included verbatim in the class. + // Set to true for attributes with arguments which require delayed parsing. + bit LateParsed = 0; + // Any additional text that should be included verbatim in the class. code AdditionalMembers = [{}]; } @@ -110,7 +114,7 @@ def Alias : InheritableAttr { } def Aligned : InheritableAttr { - let Spellings = ["align", "aligned"]; + let Spellings = ["aligned"]; let Subjects = [NonBitField, NormalVar, Tag]; let Args = [AlignedArgument<"Alignment">]; let Namespaces = ["", "std"]; @@ -128,7 +132,7 @@ def AnalyzerNoReturn : InheritableAttr { let Spellings = ["analyzer_noreturn"]; } -def Annotate : InheritableAttr { +def Annotate : InheritableParamAttr { let Spellings = ["annotate"]; let Args = [StringArgument<"Annotation">]; } @@ -167,6 +171,23 @@ def CDecl : InheritableAttr { let Spellings = ["cdecl", "__cdecl"]; } +// cf_audited_transfer indicates that the given function has been +// audited and has been marked with the appropriate cf_consumed and +// cf_returns_retained attributes. It is generally applied by +// '#pragma clang arc_cf_code_audited' rather than explicitly. +def CFAuditedTransfer : InheritableAttr { + let Spellings = ["cf_audited_transfer"]; + let Subjects = [Function]; +} + +// cf_unknown_transfer is an explicit opt-out of cf_audited_transfer. +// It indicates that the function has unknown or unautomatable +// transfer semantics. +def CFUnknownTransfer : InheritableAttr { + let Spellings = ["cf_unknown_transfer"]; + let Subjects = [Function]; +} + def CFReturnsRetained : InheritableAttr { let Spellings = ["cf_returns_retained"]; let Subjects = [ObjCMethod, Function]; @@ -284,7 +305,7 @@ def IBOutlet : InheritableAttr { def IBOutletCollection : InheritableAttr { let Spellings = ["iboutletcollection"]; - let Args = [TypeArgument<"InterFace">]; + let Args = [TypeArgument<"Interface">, SourceLocArgument<"InterfaceLoc">]; } def Malloc : InheritableAttr { @@ -317,6 +338,10 @@ def Naked : InheritableAttr { let Spellings = ["naked"]; } +def ReturnsTwice : InheritableAttr { + let Spellings = ["returns_twice"]; +} + def NoCommon : InheritableAttr { let Spellings = ["nocommon"]; } @@ -358,6 +383,12 @@ def NoThrow : InheritableAttr { let Spellings = ["nothrow"]; } +def NSBridged : InheritableAttr { + let Spellings = ["ns_bridged"]; + let Subjects = [Record]; + let Args = [IdentifierArgument<"BridgedType">]; +} + def NSReturnsRetained : InheritableAttr { let Spellings = ["ns_returns_retained"]; let Subjects = [ObjCMethod, Function]; @@ -405,6 +436,11 @@ def ObjCPreciseLifetime : Attr { let Subjects = [Var]; } +def ObjCReturnsInnerPointer : Attr { + let Spellings = ["objc_returns_inner_pointer"]; + let Subjects = [ObjCMethod]; +} + def Overloadable : Attr { let Spellings = ["overloadable"]; } @@ -533,3 +569,108 @@ def WeakRef : InheritableAttr { def X86ForceAlignArgPointer : InheritableAttr { let Spellings = []; } + + +// C/C++ Thread safety attributes (e.g. for deadlock, data race checking) + +def GuardedVar : InheritableAttr { + let Spellings = ["guarded_var"]; +} + +def PtGuardedVar : InheritableAttr { + let Spellings = ["pt_guarded_var"]; +} + +def Lockable : InheritableAttr { + let Spellings = ["lockable"]; +} + +def ScopedLockable : InheritableAttr { + let Spellings = ["scoped_lockable"]; +} + +def NoThreadSafetyAnalysis : InheritableAttr { + let Spellings = ["no_thread_safety_analysis"]; +} + +def GuardedBy : InheritableAttr { + let Spellings = ["guarded_by"]; + let Args = [ExprArgument<"Arg">]; + let LateParsed = 1; +} + +def PtGuardedBy : InheritableAttr { + let Spellings = ["pt_guarded_by"]; + let Args = [ExprArgument<"Arg">]; + let LateParsed = 1; +} + +def AcquiredAfter : InheritableAttr { + let Spellings = ["acquired_after"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def AcquiredBefore : InheritableAttr { + let Spellings = ["acquired_before"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def ExclusiveLockFunction : InheritableAttr { + let Spellings = ["exclusive_lock_function"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def SharedLockFunction : InheritableAttr { + let Spellings = ["shared_lock_function"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +// The first argument is an integer or boolean value specifying the return value +// of a successful lock acquisition. +def ExclusiveTrylockFunction : InheritableAttr { + let Spellings = ["exclusive_trylock_function"]; + let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +// The first argument is an integer or boolean value specifying the return value +// of a successful lock acquisition. +def SharedTrylockFunction : InheritableAttr { + let Spellings = ["shared_trylock_function"]; + let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def UnlockFunction : InheritableAttr { + let Spellings = ["unlock_function"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def LockReturned : InheritableAttr { + let Spellings = ["lock_returned"]; + let Args = [ExprArgument<"Arg">]; + let LateParsed = 1; +} + +def LocksExcluded : InheritableAttr { + let Spellings = ["locks_excluded"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def ExclusiveLocksRequired : InheritableAttr { + let Spellings = ["exclusive_locks_required"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def SharedLocksRequired : InheritableAttr { + let Spellings = ["shared_locks_required"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def index a3cc615..e06e05b 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def @@ -35,6 +35,7 @@ // A -> "reference" to __builtin_va_list // V -> Vector, following num elements and a base type. // X -> _Complex, followed by the base type. +// Y -> ptrdiff_t // P -> FILE // J -> jmp_buf // SJ -> sigjmp_buf @@ -76,6 +77,7 @@ // in that it accepts its arguments as a va_list rather than // through an ellipsis // e -> const, but only when -fmath-errno=0 +// j -> returns_twice (like setjmp) // FIXME: gcc has nonnull #if defined(BUILTIN) && !defined(LIBBUILTIN) @@ -96,9 +98,9 @@ BUILTIN(__builtin_fabsl, "LdLd", "ncF") BUILTIN(__builtin_fmod , "ddd" , "Fnc") BUILTIN(__builtin_fmodf, "fff" , "Fnc") BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc") -BUILTIN(__builtin_frexp , "ddi*" , "Fnc") -BUILTIN(__builtin_frexpf, "ffi*" , "Fnc") -BUILTIN(__builtin_frexpl, "LdLdi*", "Fnc") +BUILTIN(__builtin_frexp , "ddi*" , "Fn") +BUILTIN(__builtin_frexpf, "ffi*" , "Fn") +BUILTIN(__builtin_frexpl, "LdLdi*", "Fn") BUILTIN(__builtin_huge_val, "d", "nc") BUILTIN(__builtin_huge_valf, "f", "nc") BUILTIN(__builtin_huge_vall, "Ld", "nc") @@ -108,9 +110,9 @@ BUILTIN(__builtin_infl , "Ld" , "nc") BUILTIN(__builtin_ldexp , "ddi" , "Fnc") BUILTIN(__builtin_ldexpf, "ffi" , "Fnc") BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc") -BUILTIN(__builtin_modf , "ddd*" , "Fnc") -BUILTIN(__builtin_modff, "fff*" , "Fnc") -BUILTIN(__builtin_modfl, "LdLdLd*", "Fnc") +BUILTIN(__builtin_modf , "ddd*" , "Fn") +BUILTIN(__builtin_modff, "fff*" , "Fn") +BUILTIN(__builtin_modfl, "LdLdLd*", "Fn") BUILTIN(__builtin_nan, "dcC*" , "ncF") BUILTIN(__builtin_nanf, "fcC*" , "ncF") BUILTIN(__builtin_nanl, "LdcC*", "ncF") @@ -233,9 +235,9 @@ BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc") BUILTIN(__builtin_remainder , "ddd", "Fnc") BUILTIN(__builtin_remainderf, "fff", "Fnc") BUILTIN(__builtin_remainderl, "LdLdLd", "Fnc") -BUILTIN(__builtin_remquo , "dddi*", "Fnc") -BUILTIN(__builtin_remquof, "fffi*", "Fnc") -BUILTIN(__builtin_remquol, "LdLdLdi*", "Fnc") +BUILTIN(__builtin_remquo , "dddi*", "Fn") +BUILTIN(__builtin_remquof, "fffi*", "Fn") +BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn") BUILTIN(__builtin_rint , "dd", "Fnc") BUILTIN(__builtin_rintf, "ff", "Fnc") BUILTIN(__builtin_rintl, "LdLd", "Fnc") @@ -388,7 +390,7 @@ BUILTIN(__builtin_constant_p, "i.", "nct") BUILTIN(__builtin_classify_type, "i.", "nct") BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc") BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc") -BUILTIN(__builtin_va_start, "vA.", "n") +BUILTIN(__builtin_va_start, "vA.", "nt") BUILTIN(__builtin_va_end, "vA", "n") BUILTIN(__builtin_va_copy, "vAA", "n") BUILTIN(__builtin_stdarg_start, "vA.", "n") @@ -426,7 +428,7 @@ BUILTIN(__builtin_return_address, "v*IUi", "n") BUILTIN(__builtin_extract_return_addr, "v*v*", "n") BUILTIN(__builtin_frame_address, "v*IUi", "n") BUILTIN(__builtin_flt_rounds, "i", "nc") -BUILTIN(__builtin_setjmp, "iv**", "") +BUILTIN(__builtin_setjmp, "iv**", "j") BUILTIN(__builtin_longjmp, "vv**i", "r") BUILTIN(__builtin_unwind_init, "v", "") BUILTIN(__builtin_eh_return_data_regno, "iIi", "nc") @@ -584,12 +586,21 @@ BUILTIN(__sync_swap_4, "iiD*i.", "n") BUILTIN(__sync_swap_8, "LLiLLiD*LLi.", "n") BUILTIN(__sync_swap_16, "LLLiLLLiD*LLLi.", "n") - +BUILTIN(__atomic_load, "v.", "t") +BUILTIN(__atomic_store, "v.", "t") +BUILTIN(__atomic_exchange, "v.", "t") +BUILTIN(__atomic_compare_exchange_strong, "v.", "t") +BUILTIN(__atomic_compare_exchange_weak, "v.", "t") +BUILTIN(__atomic_fetch_add, "v.", "t") +BUILTIN(__atomic_fetch_sub, "v.", "t") +BUILTIN(__atomic_fetch_and, "v.", "t") +BUILTIN(__atomic_fetch_or, "v.", "t") +BUILTIN(__atomic_fetch_xor, "v.", "t") +BUILTIN(__atomic_thread_fence, "vi", "n") +BUILTIN(__atomic_signal_fence, "vi", "n") // Non-overloaded atomic builtins. BUILTIN(__sync_synchronize, "v.", "n") -// LLVM instruction builtin [Clang extension]. -BUILTIN(__builtin_llvm_memory_barrier,"vbbbbb", "n") // GCC does not support these, they are a Clang extension. BUILTIN(__sync_fetch_and_min, "iiD*i", "n") BUILTIN(__sync_fetch_and_max, "iiD*i", "n") @@ -661,9 +672,26 @@ LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_LANGUAGES) LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_LANGUAGES) // POSIX unistd.h LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_LANGUAGES) +LIBBUILTIN(vfork, "i", "fj", "unistd.h", ALL_LANGUAGES) // POSIX setjmp.h + +// In some systems setjmp is a macro that expands to _setjmp. We undefine +// it here to avoid having two identical LIBBUILTIN entries. +#undef setjmp +LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(__sigsetjmp, "iJi", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(sigsetjmp, "iJi", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(setjmp_syscall, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(savectx, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(qsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(getcontext, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) + LIBBUILTIN(_longjmp, "vJi", "fr", "setjmp.h", ALL_LANGUAGES) LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h", ALL_LANGUAGES) +// non-standard but very common +LIBBUILTIN(strlcpy, "zc*cC*z", "f", "string.h", ALL_LANGUAGES) +LIBBUILTIN(strlcat, "zc*cC*z", "f", "string.h", ALL_LANGUAGES) // id objc_msgSend(id, SEL, ...) LIBBUILTIN(objc_msgSend, "GGH.", "f", "objc/message.h", OBJC_LANG) @@ -687,8 +715,7 @@ LIBBUILTIN(objc_read_weak, "GG*", "f", "/objc/objc-auto.h", OBJC_LANG) // id objc_assign_weak(id value, id *location) LIBBUILTIN(objc_assign_weak, "GGG*", "f", "/objc/objc-auto.h", OBJC_LANG) // id objc_assign_ivar(id value, id dest, ptrdiff_t offset) -// FIXME. Darwin has ptrdiff_t typedef'ed to int. -LIBBUILTIN(objc_assign_ivar, "GGGi", "f", "/objc/objc-auto.h", OBJC_LANG) +LIBBUILTIN(objc_assign_ivar, "GGGY", "f", "/objc/objc-auto.h", OBJC_LANG) // id objc_assign_global(id val, id *dest) LIBBUILTIN(objc_assign_global, "GGG*", "f", "/objc/objc-auto.h", OBJC_LANG) // id objc_assign_strongCast(id val, id *dest @@ -738,5 +765,8 @@ LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES) LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES) // FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock. +// Annotation function +BUILTIN(__builtin_annotation, "UiUicC*", "nc") + #undef BUILTIN #undef LIBBUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h index 7469e14..5afa020 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h @@ -15,16 +15,13 @@ #ifndef LLVM_CLANG_BASIC_BUILTINS_H #define LLVM_CLANG_BASIC_BUILTINS_H +#include "clang/Basic/LLVM.h" #include <cstring> // VC++ defines 'alloca' as an object-like macro, which interferes with our // builtins. #undef alloca -namespace llvm { - template <typename T> class SmallVectorImpl; -} - namespace clang { class TargetInfo; class IdentifierTable; @@ -65,15 +62,18 @@ class Context { const Info *TSRecords; unsigned NumTSRecords; public: - Context(const TargetInfo &Target); + Context(); + /// \brief Perform target-specific initialization + void InitializeTarget(const TargetInfo &Target); + /// InitializeBuiltins - Mark the identifiers for all the builtins with their /// appropriate builtin ID # and mark any non-portable builtin identifiers as /// such. void InitializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts); /// \brief Popular the vector with the names of all of the builtins. - void GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names, + void GetBuiltinNames(SmallVectorImpl<const char *> &Names, bool NoBuiltins); /// Builtin::GetName - Return the identifier name for the specified builtin, @@ -103,6 +103,11 @@ public: return strchr(GetRecord(ID).Attributes, 'r') != 0; } + /// isReturnsTwice - Return true if we know this builtin can return twice. + bool isReturnsTwice(unsigned ID) const { + return strchr(GetRecord(ID).Attributes, 'j') != 0; + } + /// isLibFunction - Return true if this is a builtin for a libc/libm function, /// with a "__builtin_" prefix (e.g. __builtin_abs). bool isLibFunction(unsigned ID) const { diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td b/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td index ddd0827..a37dc10 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td @@ -74,3 +74,4 @@ def Friend : Decl; def FriendTemplate : Decl; def StaticAssert : Decl; def Block : Decl, DeclContext; +def ClassScopeFunctionSpecialization : Decl; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DelayedCleanupPool.h b/contrib/llvm/tools/clang/include/clang/Basic/DelayedCleanupPool.h index 843205f..8575bc2 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DelayedCleanupPool.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/DelayedCleanupPool.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H #define LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -66,7 +67,7 @@ public: } void doCleanup() { - for (llvm::SmallVector<std::pair<void *, CleanupFn>, 8>::reverse_iterator + for (SmallVector<std::pair<void *, CleanupFn>, 8>::reverse_iterator I = Cleanups.rbegin(), E = Cleanups.rend(); I != E; ++I) I->second(I->first); Cleanups.clear(); @@ -79,7 +80,7 @@ public: private: llvm::DenseMap<void *, CleanupFn> Ptrs; - llvm::SmallVector<std::pair<void *, CleanupFn>, 8> Cleanups; + SmallVector<std::pair<void *, CleanupFn>, 8> Cleanups; template <typename T> static void cleanupWithDelete(void *ptr) { diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h index 6f72976..fefc44c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h @@ -16,6 +16,7 @@ #include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/OwningPtr.h" @@ -25,7 +26,7 @@ #include <list> namespace clang { - class DiagnosticClient; + class DiagnosticConsumer; class DiagnosticBuilder; class IdentifierInfo; class DeclContext; @@ -64,7 +65,7 @@ public: /// \brief Create a code modification hint that inserts the given /// code string at a specific location. static FixItHint CreateInsertion(SourceLocation InsertionLoc, - llvm::StringRef Code) { + StringRef Code) { FixItHint Hint; Hint.RemoveRange = CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false); @@ -86,7 +87,7 @@ public: /// \brief Create a code modification hint that replaces the given /// source range with the given code string. static FixItHint CreateReplacement(CharSourceRange RemoveRange, - llvm::StringRef Code) { + StringRef Code) { FixItHint Hint; Hint.RemoveRange = RemoveRange; Hint.CodeToInsert = Code; @@ -94,17 +95,17 @@ public: } static FixItHint CreateReplacement(SourceRange RemoveRange, - llvm::StringRef Code) { + StringRef Code) { return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code); } }; -/// Diagnostic - This concrete class is used by the front-end to report +/// DiagnosticsEngine - This concrete class is used by the front-end to report /// problems and issues. It massages the diagnostics (e.g. handling things like -/// "report warnings as errors" and passes them off to the DiagnosticClient for -/// reporting to the user. Diagnostic is tied to one translation unit and -/// one SourceManager. -class Diagnostic : public llvm::RefCountedBase<Diagnostic> { +/// "report warnings as errors" and passes them off to the DiagnosticConsumer +/// for reporting to the user. DiagnosticsEngine is tied to one translation unit +/// and one SourceManager. +class DiagnosticsEngine : public llvm::RefCountedBase<DiagnosticsEngine> { public: /// Level - The level of the diagnostic, after it has been through mapping. enum Level { @@ -148,7 +149,8 @@ public: private: unsigned char AllExtensionsSilenced; // Used by __extension__ bool IgnoreAllWarnings; // Ignore all warnings: -w - bool WarningsAsErrors; // Treat warnings like errors: + bool WarningsAsErrors; // Treat warnings like errors. + bool EnableAllWarnings; // Enable all warnings. bool ErrorsAsFatal; // Treat errors like fatal errors. bool SuppressSystemWarnings; // Suppress warnings in system headers. bool SuppressAllDiagnostics; // Suppress all diagnostics. @@ -158,7 +160,7 @@ private: // 0 -> no limit. ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors? llvm::IntrusiveRefCntPtr<DiagnosticIDs> Diags; - DiagnosticClient *Client; + DiagnosticConsumer *Client; bool OwnsDiagClient; SourceManager *SourceMgr; @@ -173,22 +175,22 @@ private: /// the state so that we know what is the diagnostic state at any given /// source location. class DiagState { - llvm::DenseMap<unsigned, unsigned> DiagMap; + llvm::DenseMap<unsigned, DiagnosticMappingInfo> DiagMap; public: - typedef llvm::DenseMap<unsigned, unsigned>::const_iterator iterator; + typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::iterator + iterator; + typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::const_iterator + const_iterator; - void setMapping(diag::kind Diag, unsigned Map) { DiagMap[Diag] = Map; } - - diag::Mapping getMapping(diag::kind Diag) const { - iterator I = DiagMap.find(Diag); - if (I != DiagMap.end()) - return (diag::Mapping)I->second; - return diag::Mapping(); + void setMappingInfo(diag::kind Diag, DiagnosticMappingInfo Info) { + DiagMap[Diag] = Info; } - iterator begin() const { return DiagMap.begin(); } - iterator end() const { return DiagMap.end(); } + DiagnosticMappingInfo &getOrAddMappingInfo(diag::kind Diag); + + const_iterator begin() const { return DiagMap.begin(); } + const_iterator end() const { return DiagMap.end(); } }; /// \brief Keeps and automatically disposes all DiagStates that we create. @@ -254,10 +256,10 @@ private: /// \brief Indicates that an unrecoverable error has occurred. bool UnrecoverableErrorOccurred; - /// \brief Toggles for DiagnosticErrorTrap to check whether an error occurred + /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred /// during a parsing section, e.g. during parsing a function. - bool TrapErrorOccurred; - bool TrapUnrecoverableErrorOccurred; + unsigned TrapNumErrorsOccurred; + unsigned TrapNumUnrecoverableErrorsOccurred; /// LastDiagLevel - This is the level of the last diagnostic emitted. This is /// used to emit continuation diagnostics with the same level as the @@ -283,9 +285,9 @@ private: const char *Argument, unsigned ArgumentLen, const ArgumentValue *PrevArgs, unsigned NumPrevArgs, - llvm::SmallVectorImpl<char> &Output, + SmallVectorImpl<char> &Output, void *Cookie, - llvm::SmallVectorImpl<intptr_t> &QualTypeVals); + SmallVectorImpl<intptr_t> &QualTypeVals); void *ArgToStringCookie; ArgToStringFnTy ArgToStringFn; @@ -301,21 +303,25 @@ private: std::string DelayedDiagArg2; public: - explicit Diagnostic(const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &Diags, - DiagnosticClient *client = 0, + explicit DiagnosticsEngine( + const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &Diags, + DiagnosticConsumer *client = 0, bool ShouldOwnClient = true); - ~Diagnostic(); + ~DiagnosticsEngine(); const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const { return Diags; } - DiagnosticClient *getClient() { return Client; } - const DiagnosticClient *getClient() const { return Client; } + DiagnosticConsumer *getClient() { return Client; } + const DiagnosticConsumer *getClient() const { return Client; } + /// \brief Determine whether this \c DiagnosticsEngine object own its client. + bool ownsClient() const { return OwnsDiagClient; } + /// \brief Return the current diagnostic client along with ownership of that /// client. - DiagnosticClient *takeClient() { + DiagnosticConsumer *takeClient() { OwnsDiagClient = false; return Client; } @@ -328,8 +334,8 @@ public: void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; } //===--------------------------------------------------------------------===// - // Diagnostic characterization methods, used by a client to customize how - // diagnostics are emitted. + // DiagnosticsEngine characterization methods, used by a client to customize + // how diagnostics are emitted. // /// pushMappings - Copies the current DiagMappings and pushes the new copy @@ -346,7 +352,7 @@ public: /// /// \param ShouldOwnClient true if the diagnostic object should take /// ownership of \c client. - void setClient(DiagnosticClient *client, bool ShouldOwnClient = true); + void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true); /// setErrorLimit - Specify a limit for the number of errors we should /// emit before giving up. Zero disables the limit. @@ -369,6 +375,12 @@ public: void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; } bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; } + /// setEnableAllWarnings - When set to true, any unmapped ignored warnings + /// are no longer ignored. If this and IgnoreAllWarnings are both set, + /// then that one wins. + void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; } + bool getEnableAllWarnngs() const { return EnableAllWarnings; } + /// setWarningsAsErrors - When set to true, any warnings reported are issued /// as errors. void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; } @@ -435,10 +447,20 @@ public: /// /// 'Loc' is the source location that this change of diagnostic state should /// take affect. It can be null if we are setting the state from command-line. - bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map, - SourceLocation Loc = SourceLocation()) { - return Diags->setDiagnosticGroupMapping(Group, Map, Loc, *this); - } + bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map, + SourceLocation Loc = SourceLocation()); + + /// \brief Set the warning-as-error flag for the given diagnostic group. This + /// function always only operates on the current diagnostic state. + /// + /// \returns True if the given group is unknown, false otherwise. + bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled); + + /// \brief Set the error-as-fatal flag for the given diagnostic group. This + /// function always only operates on the current diagnostic state. + /// + /// \returns True if the given group is unknown, false otherwise. + bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled); bool hasErrorOccurred() const { return ErrorOccurred; } bool hasFatalErrorOccurred() const { return FatalErrorOccurred; } @@ -457,7 +479,7 @@ public: /// getCustomDiagID - Return an ID for a diagnostic with the specified message /// and level. If this is the first request for this diagnosic, it is /// registered and created, otherwise the existing ID is returned. - unsigned getCustomDiagID(Level L, llvm::StringRef Message) { + unsigned getCustomDiagID(Level L, StringRef Message) { return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message); } @@ -467,8 +489,8 @@ public: const char *Modifier, unsigned ModLen, const char *Argument, unsigned ArgLen, const ArgumentValue *PrevArgs, unsigned NumPrevArgs, - llvm::SmallVectorImpl<char> &Output, - llvm::SmallVectorImpl<intptr_t> &QualTypeVals) const { + SmallVectorImpl<char> &Output, + SmallVectorImpl<intptr_t> &QualTypeVals) const { ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, PrevArgs, NumPrevArgs, Output, ArgToStringCookie, QualTypeVals); @@ -484,18 +506,17 @@ public: void Reset(); //===--------------------------------------------------------------------===// - // Diagnostic classification and reporting interfaces. + // DiagnosticsEngine classification and reporting interfaces. // - /// \brief Based on the way the client configured the Diagnostic + /// \brief Based on the way the client configured the DiagnosticsEngine /// object, classify the specified diagnostic ID into a Level, consumable by - /// the DiagnosticClient. + /// the DiagnosticConsumer. /// /// \param Loc The source location we are interested in finding out the /// diagnostic state. Can be null in order to query the latest state. - Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, - diag::Mapping *mapping = 0) const { - return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this, mapping); + Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const { + return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this); } /// Report - Issue the message to the client. @c DiagID is a member of the @@ -527,13 +548,13 @@ public: /// /// \param Arg1 A string argument that will be provided to the /// diagnostic. A copy of this string will be stored in the - /// Diagnostic object itself. + /// DiagnosticsEngine object itself. /// /// \param Arg2 A string argument that will be provided to the /// diagnostic. A copy of this string will be stored in the - /// Diagnostic object itself. - void SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1 = "", - llvm::StringRef Arg2 = ""); + /// DiagnosticsEngine object itself. + void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "", + StringRef Arg2 = ""); /// \brief Clear out the current diagnostic. void Clear() { CurDiagID = ~0U; } @@ -542,23 +563,6 @@ private: /// \brief Report the delayed diagnostic. void ReportDelayed(); - - /// getDiagnosticMappingInfo - Return the mapping info currently set for the - /// specified builtin diagnostic. This returns the high bit encoding, or zero - /// if the field is completely uninitialized. - diag::Mapping getDiagnosticMappingInfo(diag::kind Diag, - DiagState *State) const { - return State->getMapping(Diag); - } - - void setDiagnosticMappingInternal(unsigned DiagId, unsigned Map, - DiagState *State, - bool isUser, bool isPragma) const { - if (isUser) Map |= 8; // Set the high bit for user mappings. - if (isPragma) Map |= 0x10; // Set the bit for diagnostic pragma mappings. - State->setMapping((diag::kind)DiagId, Map); - } - // This is private state used by DiagnosticBuilder. We put it here instead of // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight // object. This implementation choice means that we can only have one @@ -567,7 +571,7 @@ private: // diagnostic is in flight at a time. friend class DiagnosticIDs; friend class DiagnosticBuilder; - friend class DiagnosticInfo; + friend class Diagnostic; friend class PartialDiagnostic; friend class DiagnosticErrorTrap; @@ -614,7 +618,7 @@ private: /// only support 10 ranges, could easily be extended if needed. CharSourceRange DiagRanges[10]; - enum { MaxFixItHints = 3 }; + enum { MaxFixItHints = 6 }; /// FixItHints - If valid, provides a hint with some code /// to insert, remove, or modify at a particular position. @@ -637,28 +641,30 @@ private: /// between the time the instance was created and the time it was /// queried. class DiagnosticErrorTrap { - Diagnostic &Diag; + DiagnosticsEngine &Diag; + unsigned NumErrors; + unsigned NumUnrecoverableErrors; public: - explicit DiagnosticErrorTrap(Diagnostic &Diag) + explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag) : Diag(Diag) { reset(); } /// \brief Determine whether any errors have occurred since this /// object instance was created. bool hasErrorOccurred() const { - return Diag.TrapErrorOccurred; + return Diag.TrapNumErrorsOccurred > NumErrors; } /// \brief Determine whether any unrecoverable errors have occurred since this /// object instance was created. bool hasUnrecoverableErrorOccurred() const { - return Diag.TrapUnrecoverableErrorOccurred; + return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors; } // Set to initial state of "no errors occurred". void reset() { - Diag.TrapErrorOccurred = false; - Diag.TrapUnrecoverableErrorOccurred = false; + NumErrors = Diag.TrapNumErrorsOccurred; + NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred; } }; @@ -667,9 +673,9 @@ public: //===----------------------------------------------------------------------===// /// DiagnosticBuilder - This is a little helper class used to produce -/// diagnostics. This is constructed by the Diagnostic::Report method, and -/// allows insertion of extra information (arguments and source ranges) into the -/// currently "in flight" diagnostic. When the temporary for the builder is +/// diagnostics. This is constructed by the DiagnosticsEngine::Report method, +/// and allows insertion of extra information (arguments and source ranges) into +/// the currently "in flight" diagnostic. When the temporary for the builder is /// destroyed, the diagnostic is issued. /// /// Note that many of these will be created as temporary objects (many call @@ -678,12 +684,12 @@ public: /// the common fields to registers, eliminating increments of the NumArgs field, /// for example. class DiagnosticBuilder { - mutable Diagnostic *DiagObj; + mutable DiagnosticsEngine *DiagObj; mutable unsigned NumArgs, NumRanges, NumFixItHints; void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT - friend class Diagnostic; - explicit DiagnosticBuilder(Diagnostic *diagObj) + friend class DiagnosticsEngine; + explicit DiagnosticBuilder(DiagnosticsEngine *diagObj) : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixItHints(0) {} friend class PartialDiagnostic; @@ -731,7 +737,7 @@ public: /// /// \pre \c isActive() unsigned getDiagID() const { - assert(isActive() && "Diagnostic is inactive"); + assert(isActive() && "DiagnosticsEngine is inactive"); return DiagObj->CurDiagID; } @@ -743,17 +749,17 @@ public: /// return Diag(...); operator bool() const { return true; } - void AddString(llvm::StringRef S) const { - assert(NumArgs < Diagnostic::MaxArguments && + void AddString(StringRef S) const { + assert(NumArgs < DiagnosticsEngine::MaxArguments && "Too many arguments to diagnostic!"); if (DiagObj) { - DiagObj->DiagArgumentsKind[NumArgs] = Diagnostic::ak_std_string; + DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string; DiagObj->DiagArgumentsStr[NumArgs++] = S; } } - void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const { - assert(NumArgs < Diagnostic::MaxArguments && + void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { + assert(NumArgs < DiagnosticsEngine::MaxArguments && "Too many arguments to diagnostic!"); if (DiagObj) { DiagObj->DiagArgumentsKind[NumArgs] = Kind; @@ -770,15 +776,17 @@ public: } void AddFixItHint(const FixItHint &Hint) const { - assert(NumFixItHints < Diagnostic::MaxFixItHints && + assert(NumFixItHints < DiagnosticsEngine::MaxFixItHints && "Too many fix-it hints!"); + if (NumFixItHints >= DiagnosticsEngine::MaxFixItHints) + return; // Don't crash in release builds if (DiagObj) DiagObj->FixItHints[NumFixItHints++] = Hint; } }; inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, - llvm::StringRef S) { + StringRef S) { DB.AddString(S); return DB; } @@ -786,30 +794,30 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const char *Str) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str), - Diagnostic::ak_c_string); + DiagnosticsEngine::ak_c_string); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) { - DB.AddTaggedVal(I, Diagnostic::ak_sint); + DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) { - DB.AddTaggedVal(I, Diagnostic::ak_sint); + DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, unsigned I) { - DB.AddTaggedVal(I, Diagnostic::ak_uint); + DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const IdentifierInfo *II) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(II), - Diagnostic::ak_identifierinfo); + DiagnosticsEngine::ak_identifierinfo); return DB; } @@ -823,7 +831,7 @@ typename llvm::enable_if<llvm::is_same<T, DeclContext>, const DiagnosticBuilder &>::type operator<<(const DiagnosticBuilder &DB, T *DC) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC), - Diagnostic::ak_declcontext); + DiagnosticsEngine::ak_declcontext); return DB; } @@ -848,33 +856,33 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, /// Report - Issue the message to the client. DiagID is a member of the /// diag::kind enum. This actually returns a new instance of DiagnosticBuilder /// which emits the diagnostics (through ProcessDiag) when it is destroyed. -inline DiagnosticBuilder Diagnostic::Report(SourceLocation Loc, +inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, unsigned DiagID){ assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!"); CurDiagLoc = Loc; CurDiagID = DiagID; return DiagnosticBuilder(this); } -inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) { +inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) { return Report(SourceLocation(), DiagID); } //===----------------------------------------------------------------------===// -// DiagnosticInfo +// Diagnostic //===----------------------------------------------------------------------===// -/// DiagnosticInfo - This is a little helper class (which is basically a smart -/// pointer that forward info from Diagnostic) that allows clients to enquire -/// about the currently in-flight diagnostic. -class DiagnosticInfo { - const Diagnostic *DiagObj; - llvm::StringRef StoredDiagMessage; +/// Diagnostic - This is a little helper class (which is basically a smart +/// pointer that forward info from DiagnosticsEngine) that allows clients to +/// enquire about the currently in-flight diagnostic. +class Diagnostic { + const DiagnosticsEngine *DiagObj; + StringRef StoredDiagMessage; public: - explicit DiagnosticInfo(const Diagnostic *DO) : DiagObj(DO) {} - DiagnosticInfo(const Diagnostic *DO, llvm::StringRef storedDiagMessage) + explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {} + Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage) : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {} - const Diagnostic *getDiags() const { return DiagObj; } + const DiagnosticsEngine *getDiags() const { return DiagObj; } unsigned getID() const { return DiagObj->CurDiagID; } const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; } bool hasSourceManager() const { return DiagObj->hasSourceManager(); } @@ -884,49 +892,49 @@ public: /// getArgKind - Return the kind of the specified index. Based on the kind /// of argument, the accessors below can be used to get the value. - Diagnostic::ArgumentKind getArgKind(unsigned Idx) const { + DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const { assert(Idx < getNumArgs() && "Argument index out of range!"); - return (Diagnostic::ArgumentKind)DiagObj->DiagArgumentsKind[Idx]; + return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx]; } /// getArgStdStr - Return the provided argument string specified by Idx. const std::string &getArgStdStr(unsigned Idx) const { - assert(getArgKind(Idx) == Diagnostic::ak_std_string && + assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string && "invalid argument accessor!"); return DiagObj->DiagArgumentsStr[Idx]; } /// getArgCStr - Return the specified C string argument. const char *getArgCStr(unsigned Idx) const { - assert(getArgKind(Idx) == Diagnostic::ak_c_string && + assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string && "invalid argument accessor!"); return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]); } /// getArgSInt - Return the specified signed integer argument. int getArgSInt(unsigned Idx) const { - assert(getArgKind(Idx) == Diagnostic::ak_sint && + assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint && "invalid argument accessor!"); return (int)DiagObj->DiagArgumentsVal[Idx]; } /// getArgUInt - Return the specified unsigned integer argument. unsigned getArgUInt(unsigned Idx) const { - assert(getArgKind(Idx) == Diagnostic::ak_uint && + assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint && "invalid argument accessor!"); return (unsigned)DiagObj->DiagArgumentsVal[Idx]; } /// getArgIdentifier - Return the specified IdentifierInfo argument. const IdentifierInfo *getArgIdentifier(unsigned Idx) const { - assert(getArgKind(Idx) == Diagnostic::ak_identifierinfo && + assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo && "invalid argument accessor!"); return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]); } /// getRawArg - Return the specified non-string argument in an opaque form. intptr_t getRawArg(unsigned Idx) const { - assert(getArgKind(Idx) != Diagnostic::ak_std_string && + assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string && "invalid argument accessor!"); return DiagObj->DiagArgumentsVal[Idx]; } @@ -959,12 +967,12 @@ public: /// FormatDiagnostic - Format this diagnostic into a string, substituting the /// formal arguments into the %0 slots. The result is appended onto the Str /// array. - void FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const; + void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const; /// FormatDiagnostic - Format the given format-string into the /// output buffer using the arguments stored in this diagnostic. void FormatDiagnostic(const char *DiagStr, const char *DiagEnd, - llvm::SmallVectorImpl<char> &OutStr) const; + SmallVectorImpl<char> &OutStr) const; }; /** @@ -973,7 +981,7 @@ public: */ class StoredDiagnostic { unsigned ID; - Diagnostic::Level Level; + DiagnosticsEngine::Level Level; FullSourceLoc Loc; std::string Message; std::vector<CharSourceRange> Ranges; @@ -981,18 +989,22 @@ class StoredDiagnostic { public: StoredDiagnostic(); - StoredDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info); - StoredDiagnostic(Diagnostic::Level Level, unsigned ID, - llvm::StringRef Message); + StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info); + StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, + StringRef Message); + StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, + StringRef Message, FullSourceLoc Loc, + ArrayRef<CharSourceRange> Ranges, + ArrayRef<FixItHint> Fixits); ~StoredDiagnostic(); /// \brief Evaluates true when this object stores a diagnostic. operator bool() const { return Message.size() > 0; } unsigned getID() const { return ID; } - Diagnostic::Level getLevel() const { return Level; } + DiagnosticsEngine::Level getLevel() const { return Level; } const FullSourceLoc &getLocation() const { return Loc; } - llvm::StringRef getMessage() const { return Message; } + StringRef getMessage() const { return Message; } void setLocation(FullSourceLoc Loc) { this->Loc = Loc; } @@ -1007,20 +1019,20 @@ public: unsigned fixit_size() const { return FixIts.size(); } }; -/// DiagnosticClient - This is an abstract interface implemented by clients of +/// DiagnosticConsumer - This is an abstract interface implemented by clients of /// the front-end, which formats and prints fully processed diagnostics. -class DiagnosticClient { +class DiagnosticConsumer { protected: unsigned NumWarnings; // Number of warnings reported unsigned NumErrors; // Number of errors reported public: - DiagnosticClient() : NumWarnings(0), NumErrors(0) { } + DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { } unsigned getNumErrors() const { return NumErrors; } unsigned getNumWarnings() const { return NumWarnings; } - virtual ~DiagnosticClient(); + virtual ~DiagnosticConsumer(); /// BeginSourceFile - Callback to inform the diagnostic client that processing /// of a source file is beginning. @@ -1043,8 +1055,8 @@ public: /// IncludeInDiagnosticCounts - This method (whose default implementation /// returns true) indicates whether the diagnostics handled by this - /// DiagnosticClient should be included in the number of diagnostics reported - /// by Diagnostic. + /// DiagnosticConsumer should be included in the number of diagnostics + /// reported by DiagnosticsEngine. virtual bool IncludeInDiagnosticCounts() const; /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or @@ -1052,8 +1064,24 @@ public: /// /// Default implementation just keeps track of the total number of warnings /// and errors. - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info); + + /// \brief Clone the diagnostic consumer, producing an equivalent consumer + /// that can be used in a different context. + virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0; +}; + +/// IgnoringDiagConsumer - This is a diagnostic client that just ignores all +/// diags. +class IgnoringDiagConsumer : public DiagnosticConsumer { + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) { + // Just ignore it. + } + DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { + return new IgnoringDiagConsumer(); + } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td index 50a22c4..8ae69fe 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td @@ -18,8 +18,6 @@ def MAP_IGNORE : DiagMapping; def MAP_WARNING : DiagMapping; def MAP_ERROR : DiagMapping; def MAP_FATAL : DiagMapping; -def MAP_WARNING_NO_WERROR : DiagMapping; -def MAP_WARNING_SHOW_IN_SYSTEM_HEADER : DiagMapping; // Define the diagnostic classes. class DiagClass; @@ -59,6 +57,8 @@ class Diagnostic<string text, DiagClass DC, DiagMapping defaultmapping> { DiagClass Class = DC; bit SFINAE = 1; bit AccessControl = 0; + bit WarningNoWerror = 0; + bit WarningShowInSystemHeader = 0; DiagMapping DefaultMapping = defaultmapping; DiagGroup Group; string CategoryName = ""; @@ -77,9 +77,11 @@ class DefaultIgnore { DiagMapping DefaultMapping = MAP_IGNORE; } class DefaultWarn { DiagMapping DefaultMapping = MAP_WARNING; } class DefaultError { DiagMapping DefaultMapping = MAP_ERROR; } class DefaultFatal { DiagMapping DefaultMapping = MAP_FATAL; } -class DefaultWarnNoWerror { DiagMapping DefaultMapping= MAP_WARNING_NO_WERROR; } +class DefaultWarnNoWerror { + bit WarningNoWerror = 1; +} class DefaultWarnShowInSystemHeader { - DiagMapping DefaultMapping = MAP_WARNING_SHOW_IN_SYSTEM_HEADER; + bit WarningShowInSystemHeader = 1; } class NoSFINAE { bit SFINAE = 0; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td index 7d45bc5..705c95b 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -57,6 +57,10 @@ def note_odr_number_of_bases : Note< def note_odr_enumerator : Note<"enumerator %0 with value %1 here">; def note_odr_missing_enumerator : Note<"no corresponding enumerator here">; +def err_odr_field_type_inconsistent : Error< + "field %0 declared with incompatible types in different " + "translation units (%1 vs. %2)">; + // Importing Objective-C ASTs def err_odr_ivar_type_inconsistent : Error< "instance variable %0 declared with incompatible types in different " diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td index 4b5de36..f9a910a 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -52,18 +52,31 @@ def err_invalid_storage_class_in_func_decl : Error< "invalid storage class specifier in function declarator">; def err_expected_namespace_name : Error<"expected namespace name">; def ext_variadic_templates : ExtWarn< - "variadic templates are a C++0x extension">, InGroup<CXX0x>; + "variadic templates are a C++11 extension">, InGroup<CXX11>; +def warn_cxx98_compat_variadic_templates : + Warning<"variadic templates are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; def err_default_special_members : Error< "only special member functions may be defaulted">; def err_friends_define_only_namespace_scope : Error< "cannot define a function with non-namespace scope in a friend declaration">; def err_deleted_non_function : Error< "only functions can have deleted definitions">; +def err_module_not_found : Error<"module '%0' not found">, DefaultFatal; +def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal; +def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, + DefaultFatal; +def warn_module_build : Warning<"building module '%0' from source">, + InGroup<ModuleBuild>, DefaultIgnore; +def note_pragma_entered_here : Note<"#pragma entered here">; // Sema && Lex def ext_longlong : Extension< "'long long' is an extension when C99 mode is not enabled">, InGroup<LongLong>; +def warn_cxx98_compat_longlong : Warning< + "'long long' is incompatible with C++98">, + InGroup<CXX98CompatPedantic>, DefaultIgnore; def warn_integer_too_large : Warning< "integer constant is too large for its type">; def warn_integer_too_large_for_signed : Warning< diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td index e33b67e..3c0e4f5 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -65,6 +65,9 @@ def err_drv_command_signalled : Error< "%0 command failed due to signal %1 (use -v to see invocation)">; def err_drv_invalid_mfloat_abi : Error< "invalid float ABI '%0'">; +def err_drv_invalid_libcxx_deployment : Error< + "invalid deployment target for -stdlib=libc++ (requires %0 or later)">; + def err_drv_I_dash_not_supported : Error< "'%0' not supported, please use -iquote instead">; def err_drv_unknown_argument : Error<"unknown argument: '%0'">; @@ -123,4 +126,7 @@ def warn_drv_objc_gc_unsupported : Warning< def warn_drv_pch_not_first_include : Warning< "precompiled header '%0' was ignored because '%1' is not first '-include'">; +def note_drv_command_failed_diag_msg : Note< + "diagnostic msg: %0">; + } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 120ba67..fffa42f 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -112,139 +112,11 @@ def err_relocatable_without_isysroot : Error< def warn_pch_target_triple : Error< "PCH file was compiled for the target '%0' but the current translation " "unit is being compiled for target '%1'">; -def warn_pch_c99 : Error< - "C99 support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_c1x : Error< - "C1X support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_cplusplus : Error< - "C++ support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_cplusplus0x : Error< - "C++0x support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_objective_c : Error< - "Objective-C support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_objective_c2 : Error< - "Objective-C 2.0 support was %select{disabled|enabled}0 in PCH file but " - "is currently %select{disabled|enabled}1">; -def warn_pch_nonfragile_abi : Error< - "PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C " - "ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">; -def warn_pch_nonfragile_abi2 : Error< - "PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 " - "Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 " - "Objective-C ABI is selected">; -def warn_pch_auto_ref_count : Error< - "PCH file was compiled %select{without|with} automated reference counting," - "which is currently %select{disabled|enabled}">; -def warn_pch_apple_kext : Error< - "PCH file was compiled %select{with|without}0 support for Apple's kernel " - "extensions ABI but it is currently %select{disabled|enabled}1">; -def warn_pch_objc_auto_properties : Error< - "PCH file was compiled %select{with|without}0 support for auto-synthesized " - "@properties but it is currently %select{disabled|enabled}1">; -def warn_pch_no_constant_cfstrings : Error< - "Objctive-C NSstring generation support was %select{disabled|enabled}0 " - "in PCH file but currently %select{disabled|enabled}1">; -def warn_pch_extensions : Error< - "extensions were %select{enabled|disabled}0 in PCH file but are " - "currently %select{enabled|disabled}1">; -def warn_pch_gnu_extensions : Error< - "GNU extensions were %select{disabled|enabled}0 in PCH file but are " - "currently %select{disabled|enabled}1">; -def warn_pch_gnu_keywords : Error< - "GNU keywords were %select{disabled|enabled}0 in PCH file but are " - "currently %select{disabled|enabled}1">; -def warn_pch_microsoft_extensions : Error< - "Microsoft extensions were %select{disabled|enabled}0 in PCH file but are " - "currently %select{disabled|enabled}1">; -def warn_pch_ms_bitfields : Error< - "Microsoft-compatible structure layout was %select{disabled|enabled}0 in " - "PCH file but is currently %select{disabled|enabled}1">; -def warn_pch_heinous_extensions : Error< - "heinous extensions were %select{disabled|enabled}0 in PCH file but are " - "currently %select{disabled|enabled}1">; -def warn_pch_lax_vector_conversions : Error< - "lax vector conversions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_altivec : Error< - "AltiVec initializers were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_opencl : Error< - "OpenCL language extensions were %select{disabled|enabled}0 in PCH file " - "but are currently %select{disabled|enabled}1">; -def warn_pch_cuda : Error< - "CUDA language extensions were %select{disabled|enabled}0 in PCH file " - "but are currently %select{disabled|enabled}1">; -def warn_pch_elide_constructors : Error< - "Elidable copy constructors were %select{disabled|enabled}0 in PCH file " - "but are currently %select{disabled|enabled}1">; -def warn_pch_exceptions : Error< - "exceptions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_objc_exceptions : Error< - "Objective-C exceptions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_cxx_exceptions : Error< - "C++ exceptions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_sjlj_exceptions : Error< - "sjlj-exceptions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_objc_runtime : Error< - "PCH file was compiled with the %select{NeXT|GNU}0 runtime but the " - "%select{NeXT|GNU}1 runtime is selected">; -def warn_pch_freestanding : Error< - "PCH file was compiled with a %select{hosted|freestanding}0 " - "implementation but a %select{hosted|freestanding}1 implementation " - "is selected">; -def warn_pch_builtins : Error< - "PCH file was compiled with builtins %select{enabled|disabled}0 but " - "builtins are currently %select{enabled|disabled}1">; -def warn_pch_thread_safe_statics : Error< - "PCH file was compiled %select{without|with}0 thread-safe statics but " - "thread-safe statics are currently %select{disabled|enabled}1">; -def warn_pch_posix_threads : Error< - "PCH file was compiled %select{without|with}0 POSIX thread support but " - "POSIX threads are currently %select{disabled|enabled}1">; -def warn_pch_stack_protector : Error< - "stack protector was %select{off|on|required}0 in PCH file but " - "is currently %select{off|on|required}1">; -def warn_pch_blocks : Error< - "blocks were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_math_errno : Error< - "math functions %select{do not respect|respect}0 'errno' in PCH " - "file but they are currently set to %select{not respect|respect}1 " - "'errno'">; -def warn_pch_optimize : Error< - "the macro '__OPTIMIZE__' was %select{not defined|defined}0 in " - "the PCH file but is currently %select{undefined|defined}1">; -def warn_pch_optimize_size : Error< - "the macro '__OPTIMIZE_SIZE__' was %select{not defined|defined}0 in " - "the PCH file but is currently %select{undefined|defined}1">; -def warn_pch_static : Error< - "the PCH file was compiled %select{dynamic|static}0 but the " - "current translation unit is being compiled as %select{dynamic|static}1">; -def warn_pch_pic_level : Error< - "PCH file was compiled with PIC level %0, but the current translation " - "unit will be compiled with PIC level %1">; -def warn_pch_gnu_inline : Error< - "PCH file was compiled with %select{C99|GNU|}0 inline semantics but " - "%select{C99|GNU}1 inline semantics are currently selected">; -def warn_pch_no_inline : Error< - "the macro '__NO_INLINE__' was %select{not defined|defined}0 in " - "the PCH file but is currently %select{undefined|defined}1">; -def warn_pch_deprecated : Error< - "the macro '__DEPRECATED' was %select{not defined|defined}0 in " - "the PCH file but is currently %select{undefined|defined}1">; -def warn_pch_gc_mode : Error< - "the PCH file was built with %select{no||hybrid}0 garbage collection but " - "the current translation unit will compiled with %select{no||hybrid}1 " - "garbage collection">; +def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in " + "PCH file but is currently %select{disabled|enabled}2">; +def err_pch_langopt_value_mismatch : Error< + "%0 differs in PCH file vs. current file">; + def warn_pch_version_too_old : Error< "PCH file uses an older PCH format that is no longer supported">; def warn_pch_version_too_new : Error< @@ -266,18 +138,6 @@ def warn_macro_name_used_in_pch : Error< def warn_pch_compiler_options_mismatch : Error< "compiler options used when building the precompiled header differ from " "the options used when using the precompiled header">; -def warn_pch_access_control : Error< - "C++ access control was %select{disabled|enabled}0 in the PCH file but " - "is currently %select{disabled|enabled}1">; -def warn_pch_char_signed : Error< - "char was %select{unsigned|signed}0 in the PCH file but " - "is currently %select{unsigned|signed}1">; -def warn_pch_short_wchar : Error< - "-fshort-wchar was %select{disabled|enabled}0 in the PCH file but " - "is currently %select{disabled|enabled}1">; -def warn_pch_short_enums : Error< - "-fshort-enums was %select{disabled|enabled}0 in the PCH file but " - "is currently %select{disabled|enabled}1">; def err_not_a_pch_file : Error< "'%0' does not appear to be a precompiled header file">, DefaultFatal; @@ -291,6 +151,11 @@ def warn_unknown_warning_specifier : Warning< "unknown %0 warning specifier: '%1'">, InGroup<DiagGroup<"unknown-warning-option"> >; -def warn_unkwown_analyzer_checker : Warning< +def warn_unknown_analyzer_checker : Warning< "no analyzer checkers are associated with '%0'">; +def warn_incompatible_analyzer_plugin_api : Warning< + "checker plugin '%0' is not compatible with this version of the analyzer">, + InGroup<DiagGroup<"analyzer-incompatible-plugin"> >; +def note_incompatible_analyzer_plugin_api : Note< + "current API version is '%0', but plugin was compiled with version '%1'">; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td index 8a10914..49603eb 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td @@ -54,9 +54,16 @@ def ExtraTokens : DiagGroup<"extra-tokens">; def FormatExtraArgs : DiagGroup<"format-extra-args">; def FormatZeroLength : DiagGroup<"format-zero-length">; -def CXXHexFloats : DiagGroup<"c++-hex-floats">; +def CXX98Compat : DiagGroup<"c++98-compat">; +// Warnings for C++11 features which are Extensions in C++98 mode. +def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", [CXX98Compat]>; + +def CXX11Narrowing : DiagGroup<"c++11-narrowing">; +def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>; + +def CXX11Compat : DiagGroup<"c++11-compat", [CXX11Narrowing]>; +def : DiagGroup<"c++0x-compat", [CXX11Compat]>; -def : DiagGroup<"c++0x-compat", [CXXHexFloats]>; def : DiagGroup<"effc++">; def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; def FourByteMultiChar : DiagGroup<"four-char-constants">; @@ -66,13 +73,15 @@ def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">; def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">; def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">; def : DiagGroup<"import">; +def IncompatiblePointerTypes : DiagGroup<"incompatible-pointer-types">; def : DiagGroup<"init-self">; def : DiagGroup<"inline">; def : DiagGroup<"int-to-pointer-cast">; def : DiagGroup<"invalid-pch">; def LiteralRange : DiagGroup<"literal-range">; def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args">; -def : DiagGroup<"main">; +def MalformedWarningCheck : DiagGroup<"malformed-warning-check">; +def Main : DiagGroup<"main">; def MissingBraces : DiagGroup<"missing-braces">; def MissingDeclarations: DiagGroup<"missing-declarations">; def : DiagGroup<"missing-format-attribute">; @@ -84,6 +93,7 @@ def : DiagGroup<"newline-eof">; def LongLong : DiagGroup<"long-long">; def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; +def ModuleBuild : DiagGroup<"module-build">; def NullDereference : DiagGroup<"null-dereference">; def InitializerOverrides : DiagGroup<"initializer-overrides">; def NonNull : DiagGroup<"nonnull">; @@ -95,6 +105,9 @@ def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">; def : DiagGroup<"overflow">; def OverlengthStrings : DiagGroup<"overlength-strings">; def OverloadedVirtual : DiagGroup<"overloaded-virtual">; +def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">; +def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">; +def ObjCContinuationPropertyType :DiagGroup<"objc-continuation-property-type">; def Packed : DiagGroup<"packed">; def Padded : DiagGroup<"padded">; def PointerArith : DiagGroup<"pointer-arith">; @@ -108,6 +121,8 @@ def ReturnType : DiagGroup<"return-type">; def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy">; def SelfAssignment : DiagGroup<"self-assign">; def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">; +def Sentinel : DiagGroup<"sentinel">; +def MissingMethodReturnType : DiagGroup<"missing-method-return-type">; def : DiagGroup<"sequence-point">; def Shadow : DiagGroup<"shadow">; def : DiagGroup<"shorten-64-to-32">; @@ -152,6 +167,7 @@ def UnknownPragmas : DiagGroup<"unknown-pragmas">; def UnknownAttributes : DiagGroup<"attributes">; def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args">; def UnusedArgument : DiagGroup<"unused-argument">; +def UnusedComparison : DiagGroup<"unused-comparison">; def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">; def UnneededInternalDecl : DiagGroup<"unneeded-internal-declaration">; def UnneededMemberFunction : DiagGroup<"unneeded-member-function">; @@ -160,9 +176,11 @@ def UnusedMemberFunction : DiagGroup<"unused-member-function", [UnneededMemberFunction]>; def UnusedLabel : DiagGroup<"unused-label">; def UnusedParameter : DiagGroup<"unused-parameter">; -def UnusedValue : DiagGroup<"unused-value">; +def UnusedResult : DiagGroup<"unused-result">; +def UnusedValue : DiagGroup<"unused-value", [UnusedComparison, UnusedResult]>; def UnusedVariable : DiagGroup<"unused-variable">; def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">; +def UserDefinedLiterals : DiagGroup<"user-defined-literals">; def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">; def Reorder : DiagGroup<"reorder">; def UndeclaredSelector : DiagGroup<"undeclared-selector">; @@ -183,6 +201,7 @@ def Selector : DiagGroup<"selector">; def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">; def Protocol : DiagGroup<"protocol">; def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">; +def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">; def : DiagGroup<"variadic-macros">; def VariadicMacros : DiagGroup<"variadic-macros">; def VectorConversions : DiagGroup<"vector-conversions">; // clang specific @@ -202,9 +221,11 @@ def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">; // missing parentheses; it is off by default. We do not include it // in -Wparentheses because most users who use -Wparentheses explicitly // do not want these warnings. +def ParenthesesOnEquality : DiagGroup<"parentheses-equality">; def Parentheses : DiagGroup<"parentheses", [LogicalOpParentheses, - BitwiseOpParentheses]>; + BitwiseOpParentheses, + ParenthesesOnEquality]>; // -Wconversion has its own warnings, but we split a few out for // legacy reasons: @@ -216,6 +237,7 @@ def Conversion : DiagGroup<"conversion", [DiagGroup<"shorten-64-to-32">, DiagGroup<"constant-conversion">, DiagGroup<"literal-conversion">, + DiagGroup<"string-conversion">, DiagGroup<"sign-conversion">, BoolConversions]>, DiagCategory<"Value Conversion Issue">; @@ -228,11 +250,12 @@ def Unused : DiagGroup<"unused", DiagCategory<"Unused Entity Issue">; // Format settings. +def FormatInvalidSpecifier : DiagGroup<"format-invalid-specifier">; def FormatSecurity : DiagGroup<"format-security">; def FormatY2K : DiagGroup<"format-y2k">; def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull, - FormatSecurity, FormatY2K]>, + FormatSecurity, FormatY2K, FormatInvalidSpecifier]>, DiagCategory<"Format String Issue">; def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>; def Format2 : DiagGroup<"format=2", @@ -243,6 +266,7 @@ def Extra : DiagGroup<"extra", [ IgnoredQualifiers, InitializerOverrides, SemiBeforeMethodBody, + MissingMethodReturnType, SignCompare, UnusedParameter ]>; @@ -265,12 +289,15 @@ def Most : DiagGroup<"most", [ Uninitialized, UnknownPragmas, Unused, - VectorConversions, VolatileRegisterVar, + ObjCMissingSuperCalls, OverloadedVirtual ]>; -// -Wall is -Wmost -Wparentheses +// Thread Safety warnings +def ThreadSafety : DiagGroup<"thread-safety">; + +// -Wall is -Wmost -Wparentheses -Wtop-level-comparison def : DiagGroup<"all", [Most, Parentheses]>; // Aliases. @@ -283,14 +310,16 @@ def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment def NonGCC : DiagGroup<"non-gcc", [SignCompare, Conversion, LiteralRange]>; -// A warning group for warnings about using C++0x features as extensions in +// A warning group for warnings about using C++11 features as extensions in // earlier C++ versions. -def CXX0xStaticNonIntegralInitializer : - DiagGroup<"c++0x-static-nonintegral-init">; -def CXX0x : DiagGroup<"c++0x-extensions", [CXX0xStaticNonIntegralInitializer]>; +def CXX11 : DiagGroup<"c++11-extensions">; +def : DiagGroup<"c++0x-extensions", [CXX11]>; def DelegatingCtorCycles : DiagGroup<"delegating-ctor-cycles">; +// A warning group for warnings about using C1X features as extensions. +def C1X : DiagGroup<"c1x-extensions">; + // A warning group for warnings about GCC extensions. def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>; @@ -299,3 +328,4 @@ def Microsoft : DiagGroup<"microsoft">; def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">; +def ObjCProtocolMethodImpl : DiagGroup<"objc-protocol-method-implementation">; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h index ae4ed5b..16d9b39 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h @@ -16,10 +16,16 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" +#include "clang/Basic/LLVM.h" + +namespace llvm { + template<typename T, unsigned> class SmallVector; +} namespace clang { - class Diagnostic; + class DiagnosticsEngine; class SourceLocation; + struct WarningOption; // Import the diagnostic enums themselves. namespace diag { @@ -43,7 +49,7 @@ namespace clang { // Get typedefs for common diagnostics. enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER,BRIEF,FULL) ENUM, #include "clang/Basic/DiagnosticCommonKinds.inc" NUM_BUILTIN_COMMON_DIAGNOSTICS #undef DIAG @@ -59,20 +65,47 @@ namespace clang { MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it. MAP_WARNING = 2, //< Map this diagnostic to a warning. MAP_ERROR = 3, //< Map this diagnostic to an error. - MAP_FATAL = 4, //< Map this diagnostic to a fatal error. - - /// Map this diagnostic to "warning", but make it immune to -Werror. This - /// happens when you specify -Wno-error=foo. - MAP_WARNING_NO_WERROR = 5, - /// Map this diagnostic to "warning", but make it immune to - /// -Wno-system-headers. - MAP_WARNING_SHOW_IN_SYSTEM_HEADER = 6, - /// Map this diagnostic to "error", but make it immune to -Wfatal-errors. - /// This happens for -Wno-fatal-errors=foo. - MAP_ERROR_NO_WFATAL = 7 + MAP_FATAL = 4 //< Map this diagnostic to a fatal error. }; } +class DiagnosticMappingInfo { + unsigned Mapping : 3; + unsigned IsUser : 1; + unsigned IsPragma : 1; + unsigned HasShowInSystemHeader : 1; + unsigned HasNoWarningAsError : 1; + unsigned HasNoErrorAsFatal : 1; + +public: + static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser, + bool IsPragma) { + DiagnosticMappingInfo Result; + Result.Mapping = Mapping; + Result.IsUser = IsUser; + Result.IsPragma = IsPragma; + Result.HasShowInSystemHeader = 0; + Result.HasNoWarningAsError = 0; + Result.HasNoErrorAsFatal = 0; + return Result; + } + + diag::Mapping getMapping() const { return diag::Mapping(Mapping); } + void setMapping(diag::Mapping Value) { Mapping = Value; } + + bool isUser() const { return IsUser; } + bool isPragma() const { return IsPragma; } + + bool hasShowInSystemHeader() const { return HasShowInSystemHeader; } + void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; } + + bool hasNoWarningAsError() const { return HasNoWarningAsError; } + void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } + + bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } + void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } +}; + /// \brief Used for handling and querying diagnostic IDs. Can be used and shared /// by multiple Diagnostics for multiple translation units. class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> { @@ -93,7 +126,7 @@ public: /// getCustomDiagID - Return an ID for a diagnostic with the specified message /// and level. If this is the first request for this diagnosic, it is /// registered and created, otherwise the existing ID is returned. - unsigned getCustomDiagID(Level L, llvm::StringRef Message); + unsigned getCustomDiagID(Level L, StringRef Message); //===--------------------------------------------------------------------===// // Diagnostic classification and reporting interfaces. @@ -101,14 +134,18 @@ public: /// getDescription - Given a diagnostic ID, return a description of the /// issue. - llvm::StringRef getDescription(unsigned DiagID) const; + StringRef getDescription(unsigned DiagID) const; - /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic - /// level of the specified diagnostic ID is a Warning or Extension. - /// This only works on builtin diagnostics, not custom ones, and is not legal to - /// call on NOTEs. + /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic level + /// of the specified diagnostic ID is a Warning or Extension. This only works + /// on builtin diagnostics, not custom ones, and is not legal to call on + /// NOTEs. static bool isBuiltinWarningOrExtension(unsigned DiagID); + /// \brief Return true if the specified diagnostic is mapped to errors by + /// default. + static bool isDefaultMappingAsError(unsigned DiagID); + /// \brief Determine whether the given built-in diagnostic ID is a /// Note. static bool isBuiltinNote(unsigned DiagID); @@ -132,7 +169,7 @@ public: /// getWarningOptionForDiag - Return the lowest-level warning option that /// enables the specified diagnostic. If there is no -Wfoo flag that controls /// the diagnostic, this returns null. - static llvm::StringRef getWarningOptionForDiag(unsigned DiagID); + static StringRef getWarningOptionForDiag(unsigned DiagID); /// getCategoryNumberForDiag - Return the category number that a specified /// DiagID belongs to, or 0 if no category. @@ -143,7 +180,7 @@ public: /// getCategoryNameFromID - Given a category ID, return the name of the /// category. - static llvm::StringRef getCategoryNameFromID(unsigned CategoryID); + static StringRef getCategoryNameFromID(unsigned CategoryID); /// \brief Enumeration describing how the the emission of a diagnostic should /// be treated when it occurs during C++ template argument deduction. @@ -182,56 +219,80 @@ public: static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); /// getName - Given a diagnostic ID, return its name - static llvm::StringRef getName(unsigned DiagID); + static StringRef getName(unsigned DiagID); /// getIdFromName - Given a diagnostic name, return its ID, or 0 - static unsigned getIdFromName(llvm::StringRef Name); + static unsigned getIdFromName(StringRef Name); /// getBriefExplanation - Given a diagnostic ID, return a brief explanation /// of the issue - static llvm::StringRef getBriefExplanation(unsigned DiagID); + static StringRef getBriefExplanation(unsigned DiagID); /// getFullExplanation - Given a diagnostic ID, return a full explanation /// of the issue - static llvm::StringRef getFullExplanation(unsigned DiagID); + static StringRef getFullExplanation(unsigned DiagID); + + /// Iterator class used for traversing all statically declared + /// diagnostics. + class diag_iterator { + const void *impl; -private: - /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g. - /// "unknown-pragmas" to have the specified mapping. This returns true and - /// ignores the request if "Group" was unknown, false otherwise. - bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map, - SourceLocation Loc, Diagnostic &Diag) const; + friend class DiagnosticIDs; + diag_iterator(const void *im) : impl(im) {} + public: + diag_iterator &operator++(); + bool operator==(const diag_iterator &x) const { return impl == x.impl; } + bool operator!=(const diag_iterator &x) const { return impl != x.impl; } + + llvm::StringRef getDiagName() const; + unsigned getDiagID() const; + }; - /// \brief Based on the way the client configured the Diagnostic + static diag_iterator diags_begin(); + static diag_iterator diags_end(); + + /// \brief Get the set of all diagnostic IDs in the group with the given name. + /// + /// \param Diags [out] - On return, the diagnostics in the group. + /// \returns True if the given group is unknown, false otherwise. + bool getDiagnosticsInGroup(StringRef Group, + llvm::SmallVectorImpl<diag::kind> &Diags) const; + +private: + /// \brief Get the set of all diagnostic IDs in the given group. + /// + /// \param Diags [out] - On return, the diagnostics in the group. + void getDiagnosticsInGroup(const WarningOption *Group, + llvm::SmallVectorImpl<diag::kind> &Diags) const; + + /// \brief Based on the way the client configured the DiagnosticsEngine /// object, classify the specified diagnostic ID into a Level, consumable by /// the DiagnosticClient. /// /// \param Loc The source location we are interested in finding out the /// diagnostic state. Can be null in order to query the latest state. DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, - const Diagnostic &Diag, - diag::Mapping *mapping = 0) const; + const DiagnosticsEngine &Diag) const; /// getDiagnosticLevel - This is an internal implementation helper used when /// DiagClass is already known. DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, SourceLocation Loc, - const Diagnostic &Diag, - diag::Mapping *mapping = 0) const; + const DiagnosticsEngine &Diag) const; /// ProcessDiag - This is the method used to report a diagnostic that is /// finally fully formed. /// /// \returns true if the diagnostic was emitted, false if it was /// suppressed. - bool ProcessDiag(Diagnostic &Diag) const; + bool ProcessDiag(DiagnosticsEngine &Diag) const; /// \brief Whether the diagnostic may leave the AST in a state where some /// invariants can break. bool isUnrecoverable(unsigned DiagID) const; - friend class Diagnostic; + friend class DiagnosticsEngine; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td index 38d6a80..9b3a178 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -24,6 +24,11 @@ def escaped_newline_block_comment_end : Warning< def backslash_newline_space : Warning< "backslash and newline separated by space">; +// Digraphs. +def warn_cxx98_compat_less_colon_colon : Warning< + "'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98">, + InGroup<CXX98Compat>, DefaultIgnore; + // Trigraphs. def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>; def trigraph_ignored_block_comment : Warning< @@ -38,12 +43,16 @@ def ext_multi_line_bcpl_comment : Extension<"multi-line // comment">, def ext_bcpl_comment : Extension< "// comments are not allowed in this language">, InGroup<Comment>; -def ext_no_newline_eof : Extension<"no newline at end of file">; -def ext_backslash_newline_eof : Extension<"backslash-newline at end of file">; +def ext_no_newline_eof : Extension<"no newline at end of file">, + InGroup<DiagGroup<"newline-eof">>; def ext_dollar_in_identifier : Extension<"'$' in identifier">; def charize_microsoft_ext : Extension<"@# is a microsoft extension">; -def ext_token_used : Extension<"extension used">; +def ext_token_used : Extension<"extension used">, + InGroup<DiagGroup<"language-extension-token">>; + +def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">, + InGroup<CXX11Compat>; def warn_unterminated_string : ExtWarn<"missing terminating '\"' character">; def warn_unterminated_char : ExtWarn<"missing terminating ' character">; @@ -55,6 +64,18 @@ def err_unterminated___pragma : Error<"missing terminating ')' character">; def err_conflict_marker : Error<"version control conflict marker in file">; +def err_raw_delim_too_long : Error< + "raw string delimiter longer than 16 characters" + "; use PREFIX( )PREFIX to delimit raw string">; +def err_invalid_char_raw_delim : Error< + "invalid character '%0' character in raw string delimiter" + "; use PREFIX( )PREFIX to delimit raw string">; +def err_unterminated_raw_string : Error< + "raw string missing terminating delimiter )%0\"">; +def warn_cxx98_compat_raw_string_literal : Warning< + "raw string literals are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; + def ext_multichar_character_literal : ExtWarn< "multi-character character constant">, InGroup<MultiChar>; def ext_four_char_character_literal : Extension< @@ -77,17 +98,14 @@ def err_invalid_suffix_integer_constant : Error< "invalid suffix '%0' on integer constant">; def err_invalid_suffix_float_constant : Error< "invalid suffix '%0' on floating constant">; -def warn_extraneous_wide_char_constant : Warning< - "extraneous characters in wide character constant ignored">; +def warn_extraneous_char_constant : Warning< + "extraneous characters in character constant ignored">; def warn_char_constant_too_large : Warning< "character constant too long for its type">; def err_exponent_has_no_digits : Error<"exponent has no digits">; def ext_imaginary_constant : Extension<"imaginary constants are an extension">; def err_hexconstant_requires_exponent : Error< "hexadecimal floating constants require an exponent">; -def ext_hexconstant_cplusplus : Extension< - "hexadecimal floating constants are a C99 feature that is incompatible with " - "C++0x">, InGroup<CXXHexFloats>; def ext_hexconstant_invalid : Extension< "hexadecimal floating constants are a C99 feature">; def ext_binary_literal : Extension< @@ -102,6 +120,11 @@ def warn_ucn_escape_too_large : ExtWarn< "character unicode escape sequence too long for its type">; def warn_ucn_not_valid_in_c89 : ExtWarn< "unicode escape sequences are only valid in C99 or C++">; +def warn_cxx98_compat_unicode_literal : Warning< + "unicode literals are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; +def err_unsupported_string_concat : Error< + "unsupported non-standard concatenation of string literals">; //===----------------------------------------------------------------------===// // PTH Diagnostics @@ -167,6 +190,9 @@ def ext_pp_bad_vaargs_use : Extension< def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">; def ext_variadic_macro : Extension<"variadic macros were introduced in C99">, InGroup<VariadicMacros>; +def warn_cxx98_compat_variadic_macro : Warning< + "variadic macros are incompatible with C++98">, + InGroup<CXX98CompatPedantic>, DefaultIgnore; def ext_named_variadic_macro : Extension< "named variadic macros are a GNU extension">, InGroup<VariadicMacros>; def ext_embedded_directive : Extension< @@ -175,10 +201,13 @@ def ext_missing_varargs_arg : Extension< "varargs argument missing, but tolerated as an extension">; def ext_empty_fnmacro_arg : Extension< "empty macro arguments were standardized in C99">; +def warn_cxx98_compat_empty_fnmacro_arg : Warning< + "empty macro argument list is incompatible with C++98">, + InGroup<CXX98CompatPedantic>, DefaultIgnore; def err_pp_invalid_directive : Error<"invalid preprocessing directive">; def err_pp_hash_error : Error<"#error%0">; -def warn_pp_file_not_found : Warning<"'%0' file not found">, DefaultFatal; +def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal; def err_pp_error_opening_file : Error< "error opening file '%0': %1">, DefaultFatal; def err_pp_empty_filename : Error<"empty filename">; @@ -230,6 +259,13 @@ def err_pp_used_poisoned_id : Error<"attempt to use a poisoned identifier">; def err_feature_check_malformed : Error< "builtin feature check macro requires a parenthesized identifier">; +def err_warning_check_malformed : Error< + "builtin warning check macro requires a parenthesized string">, + InGroup<MalformedWarningCheck>; +def warn_has_warning_invalid_option : + ExtWarn<"__has_warning expected option name (e.g. \"-Wundef\")">, + InGroup<MalformedWarningCheck>; + def err__Pragma_malformed : Error< "_Pragma takes a parenthesized string literal">; def err_pragma_comment_malformed : Error< @@ -315,5 +351,20 @@ def err_pp_linemarker_invalid_pop : Error< "invalid line marker flag '2': cannot pop empty include stack">; def ext_pp_line_too_big : Extension< "C requires #line number to be less than %0, allowed as extension">; +def warn_cxx98_compat_pp_line_too_big : Warning< + "#line number greater than 32767 is incompatible with C++98">, + InGroup<CXX98CompatPedantic>, DefaultIgnore; + +def err_pp_export_non_macro : Error<"no macro named %0 to export">; + +def err_pp_arc_cf_code_audited_syntax : Error<"expected 'begin' or 'end'">; +def err_pp_double_begin_of_arc_cf_code_audited : Error< + "already inside '#pragma clang arc_cf_code_audited'">; +def err_pp_unmatched_end_of_arc_cf_code_audited : Error< + "not currently inside '#pragma clang arc_cf_code_audited'">; +def err_pp_include_in_arc_cf_code_audited : Error< + "cannot #include files inside '#pragma clang arc_cf_code_audited'">; +def err_pp_eof_in_arc_cf_code_audited : Error< + "'#pragma clang arc_cf_code_audited' was not ended within this file">; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td index 3764a40..73437b2 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -28,10 +28,6 @@ def ext_extra_struct_semi : Extension< def ext_extra_ivar_semi : Extension< "extra ';' inside instance variable list">; -def auto_storage_class : ExtWarn< - "'auto' storage class specifier is redundant and will be " - "removed in future releases">; - def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">; def ext_plain_complex : ExtWarn< "plain '_Complex' requires a type specifier; assuming '_Complex double'">; @@ -57,7 +53,7 @@ def ext_c99_variable_decl_in_for_loop : Extension< def ext_c99_compound_literal : Extension< "compound literals are a C99-specific feature">; def ext_enumerator_list_comma : Extension< - "commas at the end of enumerator lists are a %select{C99|C++0x}0-specific " + "commas at the end of enumerator lists are a %select{C99|C++11}0-specific " "feature">; def err_enumerator_list_missing_comma : Error< "missing ',' between enumerators">; @@ -68,12 +64,15 @@ def ext_ms_enum_fixed_underlying_type : Extension< InGroup<Microsoft>; def ext_c1x_generic_selection : Extension< - "generic selections are a C1X-specific feature">; + "generic selections are a C1X-specific feature">, InGroup<C1X>; def err_duplicate_default_assoc : Error< "duplicate default generic association">; def note_previous_default_assoc : Note< "previous default generic association is here">; +def ext_c1x_alignas : Extension< + "_Alignas is a C1X-specific feature">, InGroup<C1X>; + def ext_gnu_indirect_goto : Extension< "use of GNU indirect-goto extension">, InGroup<GNU>; def ext_gnu_address_of_label : Extension< @@ -188,16 +187,26 @@ def err_invalid_reference_qualifier_application : Error< def err_illegal_decl_reference_to_reference : Error< "%0 declared as a reference to a reference">; def ext_rvalue_reference : ExtWarn< - "rvalue references are a C++0x extension">, InGroup<CXX0x>; + "rvalue references are a C++11 extension">, InGroup<CXX11>; def ext_ref_qualifier : ExtWarn< - "reference qualifiers on functions are a C++0x extension">, InGroup<CXX0x>; + "reference qualifiers on functions are a C++11 extension">, InGroup<CXX11>; def ext_inline_namespace : ExtWarn< - "inline namespaces are a C++0x feature">, InGroup<CXX0x>; + "inline namespaces are a C++11 feature">, InGroup<CXX11>; def err_generalized_initializer_lists : Error< - "generalized initializer lists are a C++0x extension unsupported in Clang">; + "generalized initializer lists are a C++11 extension unsupported in Clang">; def ext_generalized_initializer_lists : ExtWarn< - "generalized initializer lists are a C++0x extension unsupported in Clang">, - InGroup<CXX0x>; + "generalized initializer lists are a C++11 extension unsupported in Clang">, + InGroup<CXX11>; +def ext_auto_type_specifier : ExtWarn< + "'auto' type specifier is a C++11 extension">, InGroup<CXX11>; +def warn_auto_storage_class : Warning< + "'auto' storage class specifier is redundant and incompatible with C++11">, + InGroup<CXX11Compat>; +def ext_auto_storage_class : ExtWarn< + "'auto' storage class specifier is not permitted in C++11, and will not " + "be supported in future releases">; +def ext_for_range : ExtWarn< + "range-based for loop is a C++11 extension">, InGroup<CXX11>; def err_argument_required_after_attribute : Error< "argument required after attribute">; def err_missing_param : Error<"expected parameter declarator">; @@ -219,6 +228,9 @@ def err_typename_invalid_storageclass : Error< "type name does not allow storage class to be specified">; def err_typename_invalid_functionspec : Error< "type name does not allow function specifier to be specified">; +def err_typename_identifiers_only : Error< + "typename is allowed for identifiers only">; + def err_invalid_decl_spec_combination : Error< "cannot combine with previous '%0' declaration specifier">; def err_invalid_vector_decl_spec_combination : Error< @@ -250,7 +262,7 @@ def err_unexected_colon_in_nested_name_spec : Error< def err_bool_redeclaration : Error< "redeclaration of C++ built-in type 'bool'">; def ext_c1x_static_assert : Extension< - "_Static_assert is a C1X-specific feature">; + "_Static_assert is a C1X-specific feature">, InGroup<C1X>; /// Objective-C parser diagnostics def err_expected_minus_or_plus : Error< @@ -342,6 +354,8 @@ def err_destructor_template_id : Error< "destructor name %0 does not refer to a template">; def err_default_arg_unparsed : Error< "unexpected end of default argument expression">; +def err_parser_impl_limit_overflow : Error< + "parser recursion limit reached, program too complex">, DefaultFatal; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; @@ -357,10 +371,15 @@ def err_default_delete_in_multiple_declaration : Error< "'= %select{default|delete}0' is a function definition and must occur in a " "standalone declaration">; +def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; +def warn_cxx98_compat_attribute : Warning< + "attributes are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; def err_cxx0x_attribute_forbids_arguments : Error< - "C++0x attribute '%0' cannot have an argument list">; + "C++11 attribute '%0' cannot have an argument list">; def err_cxx0x_attribute_requires_arguments : Error< - "C++0x attribute '%0' must have an argument list">; + "C++1 attribute '%0' must have an argument list">; def err_attributes_not_allowed : Error<"an attribute list cannot appear here">; /// C++ Templates @@ -385,7 +404,7 @@ def err_two_right_angle_brackets_need_space : Error< "a space is required between consecutive right angle brackets (use '> >')">; def warn_cxx0x_right_shift_in_template_arg : Warning< "use of right-shift operator ('>>') in template argument will require " - "parentheses in C++0x">; + "parentheses in C++11">; def err_multiple_template_declarators : Error< "%select{|a template declaration|an explicit template specialization|" "an explicit template instantiation}0 can " @@ -446,31 +465,31 @@ def err_missing_whitespace_digraph : Error< " which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?">; def warn_deleted_function_accepted_as_extension: ExtWarn< - "deleted function definition accepted as a C++0x extension">, InGroup<CXX0x>; + "deleted function definition accepted as a C++11 extension">, InGroup<CXX11>; def warn_defaulted_function_accepted_as_extension: ExtWarn< - "defaulted function definition accepted as a C++0x extension">, - InGroup<CXX0x>; + "defaulted function definition accepted as a C++11 extension">, + InGroup<CXX11>; -// C++0x in-class member initialization +// C++11 in-class member initialization def warn_nonstatic_member_init_accepted_as_extension: ExtWarn< - "in-class initialization of non-static data member accepted as a C++0x extension">, - InGroup<CXX0x>; + "in-class initialization of non-static data member accepted as a C++11 extension">, + InGroup<CXX11>; def err_bitfield_member_init: Error< "bitfield member cannot have an in-class initializer">; def err_incomplete_array_member_init: Error< "array bound cannot be deduced from an in-class initializer">; -// C++0x alias-declaration +// C++11 alias-declaration def ext_alias_declaration : ExtWarn< - "alias declarations accepted as a C++0x extension">, InGroup<CXX0x>; + "alias declarations accepted as a C++11 extension">, InGroup<CXX11>; def err_alias_declaration_not_identifier : Error< "name defined in alias declaration must be an identifier">; def err_alias_declaration_specialization : Error< "%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">; -// C++0x override control +// C++11 override control def ext_override_control_keyword : Extension< - "'%0' keyword accepted as a C++0x extension">, InGroup<CXX0x>; + "'%0' keyword accepted as a C++11 extension">, InGroup<CXX11>; def err_duplicate_virt_specifier : Error< "class member already marked '%0'">; @@ -487,6 +506,15 @@ def err_paren_sizeof_parameter_pack : Error< def err_sizeof_parameter_pack : Error< "expected parenthesized parameter pack name in 'sizeof...' expression">; +// C++11 lambda expressions +def err_expected_comma_or_rsquare : Error< + "expected ',' or ']' in lambda capture list">; +def err_this_captured_by_reference : Error< + "'this' cannot be captured by reference">; +def err_expected_capture : Error< + "expected variable name or 'this' in lambda capture list">; +def err_expected_lambda_body : Error<"expected body of lambda expression">; + // Availability attribute def err_expected_version : Error< "expected a version of the form 'major[.minor[.subminor]]'">; @@ -559,6 +587,14 @@ def err_seh___except_filter : Error< def err_seh___finally_block : Error< "%0 only allowed in __finally block">; - + } // end of Parse Issue category. + +let CategoryName = "Modules Issue" in { +def err_module_expected_ident : Error< + "expected a module name after '__import_module__'">; +def err_module_expected_semi : Error< + "expected a semicolon name after module name">; +} + } // end of Parser diagnostics diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index 97414f2..0fbf0ce 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -23,7 +23,8 @@ def ext_expr_not_ice : Extension< // Semantic analysis of constant literals. def ext_predef_outside_function : Warning< - "predefined identifier is only valid inside function">; + "predefined identifier is only valid inside function">, + InGroup<DiagGroup<"predefined-identifier-outside-function">>; def warn_float_overflow : Warning< "magnitude of floating-point constant too large for type %0; maximum is %1">, InGroup<LiteralRange>; @@ -102,7 +103,7 @@ def ext_flexible_array_init : Extension< def ext_anon_param_requires_type_specifier : Extension< "type specifier required for unnamed parameter, defaults to int">; def err_bad_variable_name : Error< - "'%0' cannot be the name of a variable or data member">; + "%0 cannot be the name of a variable or data member">; def err_bad_parameter_name : Error< "'%0' cannot be the name of a parameter">; def err_parameter_name_omitted : Error<"parameter name omitted">; @@ -236,10 +237,10 @@ def err_maybe_falloff_nonvoid_block : Error< def err_falloff_nonvoid_block : Error< "control reaches end of non-void block">; def warn_suggest_noreturn_function : Warning< - "function could be attribute 'noreturn'">, + "%select{function|method}0 %1 could be declared with attribute 'noreturn'">, InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore; def warn_suggest_noreturn_block : Warning< - "block could be attribute 'noreturn'">, + "block could be declared with attribute 'noreturn'">, InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore; def warn_unreachable : Warning<"will never be executed">, InGroup<DiagGroup<"unreachable-code">>, DefaultIgnore; @@ -264,8 +265,9 @@ def err_types_compatible_p_in_cplusplus : Error< "__builtin_types_compatible_p is not valid in C++">; def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError; def warn_dyn_class_memaccess : Warning< - "%select{destination for|source of}0 this %1 call is a pointer to dynamic " - "class %2; vtable pointer will be overwritten">, + "%select{destination for|source of|first operand of|second operand of}0 this " + "%1 call is a pointer to dynamic class %2; vtable pointer will be " + "%select{overwritten|copied|moved|compared}3">, InGroup<DiagGroup<"dynamic-class-memaccess">>; def note_bad_memaccess_silence : Note< "explicitly cast the pointer to silence this warning">; @@ -278,18 +280,25 @@ def warn_sizeof_pointer_type_memaccess : Warning< "argument to 'sizeof' in %0 call is the same pointer type %1 as the " "%select{destination|source}2; expected %3 or an explicit length">, InGroup<DiagGroup<"sizeof-pointer-memaccess">>; +def warn_strlcpycat_wrong_size : Warning< + "size argument in %0 call appears to be size of the source; expected the size of " + "the destination">, + InGroup<DiagGroup<"strlcpy-strlcat-size">>; +def note_strlcpycat_wrong_size : Note< + "change size argument to be the size of the destination">; /// main() // static/inline main() are not errors in C, just in C++. -def warn_unusual_main_decl : Warning<"'main' should not be declared " - "%select{static|inline|static or inline}0">; -def err_unusual_main_decl : Error<"'main' is not allowed to be declared " - "%select{static|inline|static or inline}0">; +def warn_static_main : Warning<"'main' should not be declared static">, + InGroup<Main>; +def err_static_main : Error<"'main' is not allowed to be declared static">; +def err_inline_main : Error<"'main' is not allowed to be declared inline">; def err_main_template_decl : Error<"'main' cannot be a template">; def err_main_returns_nonint : Error<"'main' must return 'int'">; def err_main_surplus_args : Error<"too many parameters (%0) for 'main': " "must be 0, 2, or 3">; -def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">; +def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">, + InGroup<Main>; def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 " "parameter of 'main' (%select{argument count|argument array|environment|" "platform-specific data}0) must be of type %1">; @@ -303,6 +312,8 @@ def err_statically_allocated_object : Error< def err_object_cannot_be_passed_returned_by_value : Error< "interface type %1 cannot be %select{returned|passed}0 by value" "; did you forget * in %1">; +def err_parameters_retval_cannot_have_fp16_type : Error< + "%select{parameters|function return value}0 cannot have __fp16 type; did you forget * ?">; def warn_enum_value_overflow : Warning<"overflow in enumeration value">; def warn_pragma_options_align_unsupported_option : Warning< "unsupported alignment option in '#pragma options align'">; @@ -383,27 +394,75 @@ def note_undef_method_impl : Note<"method definition for %0 not found">; def note_required_for_protocol_at : Note<"required for direct or indirect protocol %0">; +def warn_conflicting_overriding_ret_types : Warning< + "conflicting return type in " + "declaration of %0: %1 vs %2">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_conflicting_ret_types : Warning< - "conflicting return type in implementation of %0: %1 vs %2">; + "conflicting return type in " + "implementation of %0: %1 vs %2">; + +def warn_conflicting_overriding_ret_type_modifiers : Warning< + "conflicting distributed object modifiers on return type " + "in declaration of %0">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_conflicting_ret_type_modifiers : Warning< "conflicting distributed object modifiers on return type " "in implementation of %0">, InGroup<DiagGroup<"distributed-object-modifiers">>; + +def warn_non_covariant_overriding_ret_types : Warning< + "conflicting return type in " + "declaration of %0: %1 vs %2">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_non_covariant_ret_types : Warning< - "conflicting return type in implementation of %0: %1 vs %2">, + "conflicting return type in " + "implementation of %0: %1 vs %2">, InGroup<DiagGroup<"method-signatures">>, DefaultIgnore; +def warn_conflicting_overriding_param_types : Warning< + "conflicting parameter types in " + "declaration of %0: %1 vs %2">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_conflicting_param_types : Warning< - "conflicting parameter types in implementation of %0: %1 vs %2">; + "conflicting parameter types in " + "implementation of %0: %1 vs %2">; def warn_conflicting_param_modifiers : Warning< "conflicting distributed object modifiers on parameter type " "in implementation of %0">, InGroup<DiagGroup<"distributed-object-modifiers">>; + +def warn_conflicting_overriding_param_modifiers : Warning< + "conflicting distributed object modifiers on parameter type " + "in declaration of %0">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + +def warn_non_contravariant_overriding_param_types : Warning< + "conflicting parameter types in " + "declaration of %0: %1 vs %2">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_non_contravariant_param_types : Warning< - "conflicting parameter types in implementation of %0: %1 vs %2">, + "conflicting parameter types in " + "implementation of %0: %1 vs %2">, InGroup<DiagGroup<"method-signatures">>, DefaultIgnore; + +def warn_conflicting_overriding_variadic :Warning< + "conflicting variadic declaration of method and its " + "implementation">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_conflicting_variadic :Warning< - "conflicting variadic declaration of method and its implementation">; + "conflicting variadic declaration of method and its " + "implementation">; + +def warn_category_method_impl_match:Warning< + "category is implementing a method which will also be implemented" + " by its primary class">, InGroup<ObjCProtocolMethodImpl>; def warn_implements_nscopying : Warning< "default assign attribute on property %0 which implements " @@ -437,12 +496,22 @@ def warn_property_attr_mismatch : Warning< def warn_objc_property_copy_missing_on_block : Warning< "'copy' attribute must be specified for the block property " "when -fobjc-gc-only is specified">; +def warn_objc_property_retain_of_block : Warning< + "retain'ed block property does not copy the block " + "- use copy attribute instead">, InGroup<ObjCRetainBlockProperty>; def warn_atomic_property_rule : Warning< - "writable atomic property %0 cannot pair a synthesized setter/getter " - "with a user defined setter/getter">; -def warn_ownin_getter_rule : Warning< + "writable atomic property %0 cannot pair a synthesized %select{getter|setter}1 " + "with a user defined %select{getter|setter}2">, + InGroup<DiagGroup<"atomic-property-with-user-defined-accessor">>; +def note_atomic_property_fixup_suggest : Note<"setter and getter must both be " + "synthesized, or both be user defined,or the property must be nonatomic">; +def warn_atomic_property_nontrivial_assign_op : Warning< + "atomic property of type %0 synthesizing setter using non-trivial assignment" + " operator">, InGroup<DiagGroup<"objc-property-atomic-setter-synthesis">>; +def warn_owning_getter_rule : Warning< "property's synthesized getter follows Cocoa naming" - " convention for returning 'owned' objects">; + " convention for returning 'owned' objects">, + InGroup<DiagGroup<"objc-property-matches-cocoa-ownership-rule">>; def warn_property_getter_owning_mismatch : Warning< "property declared as returning non-retained objects" "; getter returning retained objects">; @@ -456,6 +525,9 @@ def warn_default_atomic_custom_getter_setter : Warning< def err_use_continuation_class : Error< "illegal redeclaration of property in continuation class %0" " (attribute must be 'readwrite', while its primary must be 'readonly')">; +def warn_type_mismatch_continuation_class : Warning< + "type of property %0 in continuation class does not match " + "property type in primary class">, InGroup<ObjCContinuationPropertyType>; def err_use_continuation_class_redeclaration_readwrite : Error< "illegal redeclaration of 'readwrite' property in continuation class %0" " (perhaps you intended this to be a 'readwrite' redeclaration of a " @@ -489,7 +561,10 @@ def error_synthesize_weak_non_arc_or_gc : Error< def err_arc_perform_selector_retains : Error< "performSelector names a selector which retains the object">; def warn_arc_perform_selector_leaks : Warning< - "performSelector may cause a leak because its selector is unknown">; + "performSelector may cause a leak because its selector is unknown">, + InGroup<DiagGroup<"arc-performSelector-leaks">>; +def err_gc_weak_property_strong_type : Error< + "weak attribute declared on a __strong type property in GC mode">; def error_synthesized_ivar_yet_not_supported : Error< "instance variable synthesis not yet supported" @@ -511,6 +586,12 @@ def error_property_implemented : Error<"property %0 is already implemented">; def warn_objc_property_attr_mutually_exclusive : Warning< "property attributes '%0' and '%1' are mutually exclusive">, InGroup<ReadOnlySetterAttrs>, DefaultIgnore; +def warn_objc_missing_super_dealloc : Warning< + "method possibly missing a [super dealloc] call">, + InGroup<ObjCMissingSuperCalls>; +def warn_objc_missing_super_finalize : Warning< + "method possibly missing a [super finalize] call">, + InGroup<ObjCMissingSuperCalls>; def warn_undeclared_selector : Warning< "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore; def warn_implicit_atomic_property : Warning< @@ -539,12 +620,12 @@ def err_unexpected_friend : Error< def ext_enum_friend : ExtWarn< "enumeration type %0 cannot be a friend">; def ext_nonclass_type_friend : ExtWarn< - "non-class friend type %0 is a C++0x extension">, InGroup<CXX0x>; + "non-class friend type %0 is a C++11 extension">, InGroup<CXX11>; def err_friend_is_member : Error< "friends cannot be members of the declaring class">; def ext_unelaborated_friend_type : ExtWarn< "specify '%select{struct|union|class|enum}0' to befriend %1; accepted " - "as a C++0x extension">, InGroup<CXX0x>; + "as a C++11 extension">, InGroup<CXX11>; def err_qualified_friend_not_found : Error< "no function named %0 with type %1 was found in the specified scope">; def err_introducing_special_friend : Error< @@ -554,9 +635,15 @@ def err_tagless_friend_type_template : Error< "friend type templates must use an elaborated type">; def err_no_matching_local_friend : Error< "no matching function found in local scope">; +def err_no_matching_local_friend_suggest : Error< + "no matching function %0 found in local scope; did you mean %2">; def err_partial_specialization_friend : Error< "partial specialization cannot be declared as a friend">; - +def err_qualified_friend_def : Error< + "friend function definition cannot be qualified with '%0'">; +def err_friend_def_in_local_class : Error< + "friend function cannot be defined in a local class">; + def err_abstract_type_in_decl : Error< "%select{return|parameter|variable|field}0 type %1 is an abstract class">; def err_allocation_of_abstract_type : Error< @@ -963,7 +1050,7 @@ def warn_maybe_uninit_var_captured_by_block : Warning< "variable %0 may be uninitialized when captured by block">, InGroup<UninitializedMaybe>, DefaultIgnore; def note_var_fixit_add_initialization : Note< - "add initialization to silence this warning">; + "initialize the variable %0 to silence this warning">; def err_init_incomplete_type : Error<"initialization of incomplete type %0">; def err_temp_copy_no_viable : Error< @@ -991,11 +1078,11 @@ def err_temp_copy_deleted : Error< def err_temp_copy_incomplete : Error< "copying a temporary object of incomplete type %0">; -// C++0x decltype +// C++11 decltype def err_cannot_determine_declared_type_of_overloaded_function : Error< "cannot determine the type of an overloaded function">; -// C++0x auto +// C++11 auto def err_auto_variable_cannot_appear_in_own_initializer : Error< "variable %0 declared with 'auto' type cannot appear in its own initializer">; def err_illegal_decl_array_of_auto : Error< @@ -1028,7 +1115,7 @@ def err_auto_new_deduction_failure : Error< def err_auto_different_deductions : Error< "'auto' deduced as %0 in declaration of %1 and deduced as %2 in declaration of %3">; -// C++0x override control +// C++11 override control def override_keyword_only_allowed_on_virtual_member_functions : Error< "only virtual member functions can be marked '%0'">; def err_function_marked_override_not_overriding : Error< @@ -1036,16 +1123,16 @@ def err_function_marked_override_not_overriding : Error< def err_class_marked_final_used_as_base : Error< "base %0 is marked 'final'">; -// C++0x attributes +// C++11 attributes def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">; -// C++0x [[final]] +// C++11 [[final]] def err_final_function_overridden : Error< "declaration of %0 overrides a 'final' function">; def err_final_base : Error< "derivation from 'final' %0">; -// C++0x scoped enumerations +// C++11 scoped enumerations def err_enum_invalid_underlying : Error< "non-integral type %0 is an invalid underlying type">; def err_enumerator_too_large : Error< @@ -1066,9 +1153,9 @@ def err_only_enums_have_underlying_types : Error< def err_incomplete_type_no_underlying_type : Error< "an incomplete enumeration type has no underlying type yet">; -// C++0x delegating constructors +// C++11 delegating constructors def err_delegation_0x_only : Error< - "delegating constructors are permitted only in C++0x">; + "delegating constructors are permitted only in C++11">; def err_delegating_initializer_alone : Error< "an initializer for a delegating constructor must appear alone">; def warn_delegating_ctor_cycle : Warning< @@ -1081,7 +1168,7 @@ def note_which_delegates_to : Note< def err_delegating_codegen_not_implemented : Error< "code generation for delegating constructors not implemented">; -// C++0x range-based for loop +// C++11 range-based for loop def err_for_range_decl_must_be_var : Error< "for range declaration must declare a variable">; def err_for_range_storage_class : Error< @@ -1102,7 +1189,88 @@ def err_for_range_begin_end_types_differ : Error< def note_for_range_type : Note<"range has type %0">; def note_for_range_begin_end : Note< "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; - + +// C++11 constexpr +def err_invalid_constexpr : Error< + "%select{function parameter|typedef|non-static data member}0 " + "cannot be constexpr">; +def err_constexpr_tag : Error< + "%select{class|struct|union|enum}0 cannot be marked constexpr">; +def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">; +def err_constexpr_no_declarators : Error< + "constexpr can only be used in variable and function declarations">; +def err_invalid_constexpr_var_decl : Error< + "constexpr variable declaration must be a definition">; +def err_constexpr_var_requires_init : Error< + "declaration of constexpr variable %0 requires an initializer">; +def err_constexpr_var_requires_const_init : Error< + "constexpr variable %0 must be initialized by a constant expression">; +def err_constexpr_redecl_mismatch : Error< + "%select{non-constexpr declaration of %0 follows constexpr declaration" + "|constexpr declaration of %0 follows non-constexpr declaration}1">; +def note_constexpr_redecl_mismatch : Note< + "previous declaration was %select{not |}0marked constexpr">; +def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; +def note_constexpr_tmpl_virtual : Note<"function template instantiation is not " + "constexpr because it is virtual">; +def err_constexpr_virtual_base : Error<"constexpr constructor not allowed in " + "%select{class|struct}0 with virtual base %plural{1:class|:classes}1">; +def note_constexpr_tmpl_virtual_base : Note<"constructor template instantiation is " + "not constexpr because %select{class|struct}0 has virtual base " + "%plural{1:class|:classes}1">; +def note_non_literal_virtual_base : Note<"%select{class|struct}0 with virtual " + "base %plural{1:class|:classes}1 is not a literal type">; +def note_constexpr_virtual_base_here : Note<"virtual base class declared here">; +def err_constexpr_non_literal_return : Error< + "constexpr function's return type %0 is not a literal type">; +def note_constexpr_tmpl_non_literal_return : Note< + "function template instantiation is not constexpr because return type %0 is " + "not a literal type">; +def err_constexpr_non_literal_param : Error< + "constexpr %select{function|constructor}1's %ordinal0 parameter type %2 is " + "not a literal type">; +def note_constexpr_tmpl_non_literal_param : Note< + "%select{function|constructor}1 template instantiation is not constexpr " + "because %ordinal0 parameter type %2 is not a literal type">; +def err_constexpr_body_invalid_stmt : Error< + "statement not allowed in constexpr %select{function|constructor}0">; +def err_constexpr_type_definition : Error< + "types cannot be defined in a constexpr %select{function|constructor}0">; +def err_constexpr_vla : Error< + "variably-modified type %0 cannot be used in a constexpr " + "%select{function|constructor}1">; +def err_constexpr_var_declaration : Error< + "variables cannot be declared in a constexpr %select{function|constructor}0">; +def err_constexpr_body_no_return : Error< + "no return statement in constexpr function">; +def err_constexpr_body_multiple_return : Error< + "multiple return statements in constexpr function">; +def note_constexpr_body_previous_return : Note< + "previous return statement is here">; +def err_constexpr_function_try_block : Error< + "function try block not allowed in constexpr %select{function|constructor}0">; +def err_constexpr_union_ctor_no_init : Error< + "constexpr union constructor does not initialize any member">; +def err_constexpr_ctor_missing_init : Error< + "constexpr constructor must initialize all members">; +def note_constexpr_ctor_missing_init : Note< + "member not initialized by constructor">; +def err_constexpr_method_non_literal : Error< + "non-literal type %0 cannot have constexpr members">; +def note_non_literal_no_constexpr_ctors : Note< + "%0 is not literal because it is not an aggregate and has no constexpr " + "constructors other than copy or move constructors">; +def note_non_literal_base_class : Note< + "%0 is not literal because it has base class %1 of non-literal type">; +def note_non_literal_field : Note< + "%0 is not literal because it has data member %1 of non-literal type %2">; +def note_non_literal_user_provided_dtor : Note< + "%0 is not literal because it has a user-provided destructor">; +def note_non_literal_nontrivial_dtor : Note< + "%0 is not literal because it has a non-trivial destructor">; +def note_non_literal_mutable_field : Note< + "%0 is not literal because it has a mutable data member">; + // Objective-C++ def err_objc_decls_may_only_appear_in_global_scope : Error< "Objective-C declarations may only appear in global scope">; @@ -1119,11 +1287,8 @@ def err_attribute_wrong_number_arguments : Error< ":requires exactly %0 arguments}0">; def err_attribute_too_many_arguments : Error< "attribute takes no more than %0 argument%s0">; -def err_iboutletcollection_type : Error< - "invalid type %0 as argument of iboutletcollection attribute">; -def err_iboutletcollection_object_type : Error< - "%select{ivar|property}1 with iboutletcollection attribute must " - "have object type (invalid %0)">; +def err_attribute_too_few_arguments : Error< + "attribute takes at least %0 argument%s0">; def err_attribute_missing_parameter_name : Error< "attribute requires unquoted parameter">; def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; @@ -1131,6 +1296,10 @@ def err_attribute_bad_neon_vector_size : Error< "Neon vector size must be 64 or 128 bits">; def err_attribute_argument_not_int : Error< "'%0' attribute requires integer constant">; +def err_attribute_argument_not_class : Error< + "%0 attribute requires arguments that are class type or point to class type">; +def err_attribute_first_argument_not_int_or_bool : Error< + "%0 attribute first argument must be of int or bool type">; def err_attribute_argument_outof_range : Error< "init_priority attribute requires integer constant between " "101 and 65535 inclusive">; @@ -1186,6 +1355,8 @@ def err_attribute_address_space_too_high : Error< "address space is larger than the maximum supported (%0)">; def err_attribute_address_multiple_qualifiers : Error< "multiple address spaces specified for type">; +def err_attribute_address_function_type : Error< + "function type may not be qualified with an address space">; def err_as_qualified_auto_decl : Error< "automatic variable qualified with an address space">; def err_arg_with_address_space : Error< @@ -1196,6 +1367,8 @@ def err_attr_objc_ownership_redundant : Error< "the type %0 already has retainment attributes set on it">; def err_attribute_not_string : Error< "argument to %0 attribute was not a string literal">; +def err_only_annotate_after_access_spec : Error< + "access specifier can only have annotation attributes">; def err_attribute_section_invalid_for_target : Error< "argument to 'section' attribute is not valid for this target: %0">; def err_attribute_section_local_variable : Error< @@ -1238,13 +1411,13 @@ def warn_attribute_wrong_decl_type : Warning< "parameters and methods|functions, methods and blocks|" "classes and virtual methods|functions, methods, and parameters|" "classes|virtual methods|class members|variables|methods|" - "variables, functions and labels}1">; + "variables, functions and labels|fields and global variables}1">; def err_attribute_wrong_decl_type : Error< "%0 attribute only applies to %select{functions|unions|" "variables and functions|functions and methods|parameters|" "parameters and methods|functions, methods and blocks|" "classes and virtual methods|functions, methods, and parameters|" - "classes|virtual methods|class members|variables|methods}1">; + "classes|virtual methods|class members|variables|methods|structs}1">; def warn_function_attribute_wrong_type : Warning< "'%0' only applies to function types; type here is %1">; def warn_pointer_attribute_wrong_type : Warning< @@ -1268,6 +1441,9 @@ def err_cconv_varargs : Error< def err_regparm_mismatch : Error<"function declared with with regparm(%0) " "attribute was previously declared " "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">; +def err_returns_retained_mismatch : Error< + "function declared with the ns_returns_retained attribute " + "was previously declared without the ns_returns_retained attribute">; def err_objc_precise_lifetime_bad_type : Error< "objc_precise_lifetime only applies to retainable types; type here is %0">; def warn_objc_precise_lifetime_meaningless : Error< @@ -1276,6 +1452,11 @@ def warn_objc_precise_lifetime_meaningless : Error< def warn_label_attribute_not_unused : Warning< "The only valid attribute for labels is 'unused'">; def err_invalid_pcs : Error<"Invalid PCS type">; +def err_attribute_can_be_applied_only_to_value_decl : Error< + "%0 attribute can only be applied to value declarations">; +def warn_attribute_not_on_decl : Error< + "%0 attribute ignored when parsing type">; + // Availability attribute def warn_availability_unknown_platform : Warning< @@ -1284,6 +1465,68 @@ def warn_availability_version_ordering : Warning< "feature cannot be %select{introduced|deprecated|obsoleted}0 in %1 version " "%2 before it was %select{introduced|deprecated|obsoleted}3 in version %4; " "attribute ignored">; + +// Thread Safety Attributes +// Errors when parsing the attributes +def err_attribute_argument_out_of_range : Error< + "%0 attribute parameter %1 is out of bounds: " + "%plural{0:no parameters to index into|" + "1:can only be 1, since there is one parameter|" + ":must be between 1 and %2}2">; +def err_attribute_argument_not_lockable : Error< + "%0 attribute requires arguments whose type is annotated " + "with 'lockable' attribute">; +def err_attribute_decl_not_lockable : Error< + "%0 attribute can only be applied in a context annotated " + "with 'lockable' attribute">; +def warn_unlock_but_no_lock : Warning< + "unlocking '%0' that was not locked">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_double_lock : Warning< + "locking '%0' that is already locked">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_no_unlock : Warning< + "mutex '%0' is still locked at the end of function">, + InGroup<ThreadSafety>, DefaultIgnore; +// FIXME: improve the error message about locks not in scope +def warn_lock_at_end_of_scope : Warning< + "mutex '%0' is still locked at the end of its scope">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_expecting_lock_held_on_loop : Warning< + "expecting mutex '%0' to be locked at start of each loop">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_lock_exclusive_and_shared : Warning< + "mutex '%0' is locked exclusively and shared in the same scope">, + InGroup<ThreadSafety>, DefaultIgnore; +def note_lock_exclusive_and_shared : Note< + "the other lock of mutex '%0' is here">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_variable_requires_lock : Warning< + "%select{reading|writing}2 variable '%0' requires locking " + "%select{'%1'|'%1' exclusively}2">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_var_deref_requires_lock : Warning< + "%select{reading|writing}2 the value pointed to by '%0' requires locking " + "%select{'%1'|'%1' exclusively}2">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_variable_requires_any_lock : Warning< + "%select{reading|writing}1 variable '%0' requires locking " + "%select{any mutex|any mutex exclusively}1">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_var_deref_requires_any_lock : Warning< + "%select{reading|writing}1 the value pointed to by '%0' requires locking " + "%select{any mutex|any mutex exclusively}1">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_fun_requires_lock : Warning< + "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_fun_excludes_mutex : Warning< + "cannot call function '%0' while mutex '%1' is locked">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_cannot_resolve_lock : Warning< + "cannot resolve lock expression to a specific lockable object">, + InGroup<ThreadSafety>, DefaultIgnore; + def warn_impcast_vector_scalar : Warning< "implicit conversion turns vector to scalar: %0 to %1">, @@ -1319,13 +1562,14 @@ def warn_impcast_literal_float_to_integer : Warning< "implicit conversion turns literal floating-point number into integer: " "%0 to %1">, InGroup<DiagGroup<"literal-conversion">>, DefaultIgnore; -def note_fix_integral_float_as_integer : Note< - "this can be rewritten as an integer literal with the exact same value">; +def warn_impcast_string_literal_to_bool : Warning< + "implicit conversion turns string literal into bool: %0 to %1">, + InGroup<DiagGroup<"string-conversion">>, DefaultIgnore; def warn_impcast_different_enum_types : Warning< "implicit conversion from enumeration type %0 to different enumeration type " "%1">, InGroup<DiagGroup<"conversion">>; def warn_impcast_bool_to_null_pointer : Warning< - "initialization of pointer of type %0 to NULL from a constant boolean " + "initialization of pointer of type %0 to null from a constant boolean " "expression">, InGroup<BoolConversions>; def warn_impcast_null_pointer_to_integer : Warning< "implicit conversion of NULL constant to integer">, @@ -1398,6 +1642,11 @@ def warn_attribute_iboutlet : Warning< "%0 attribute can only be applied to instance variables or properties">; def warn_attribute_ibaction: Warning< "ibaction attribute can only be applied to Objective-C instance methods">; +def err_iboutletcollection_type : Error< + "invalid type %0 as argument of iboutletcollection attribute">; +def err_iboutlet_object_type : Error< + "%select{ivar|property}2 with %0 attribute must " + "be an object type (invalid %1)">; def err_attribute_overloadable_not_function : Error< "'overloadable' attribute can only be applied to a function">; def err_attribute_overloadable_missing : Error< @@ -1409,10 +1658,12 @@ def err_attribute_overloadable_no_prototype : Error< "'overloadable' function %0 must have a prototype">; def warn_ns_attribute_wrong_return_type : Warning< "%0 attribute only applies to %select{functions|methods}1 that " - "return %select{an Objective-C object|a pointer}2">; + "return %select{an Objective-C object|a pointer|a non-retainable pointer}2">; def warn_ns_attribute_wrong_parameter_type : Warning< "%0 attribute only applies to %select{Objective-C object|pointer}1 " "parameters">; +def err_ns_bridged_not_interface : Error< + "parameter of 'ns_bridged' attribute does not name an Objective-C class">; // Function Parameter Semantic Analysis. def err_param_with_void_type : Error<"argument may not have 'void' type">; @@ -1572,6 +1823,16 @@ def note_ovl_candidate_bad_conv_incomplete : Note<"candidate " "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 " "not viable: cannot convert argument of incomplete type %2 to %3">; +def note_ovl_candidate_bad_list_argument : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "constructor (inherited)}0%1 " + "not viable: cannot convert initializer list argument to %3">; def note_ovl_candidate_bad_overload : Note<"candidate " "%select{function|function|constructor|" "function |function |constructor |" @@ -1592,7 +1853,22 @@ def note_ovl_candidate_bad_conv : Note<"candidate " "function (the implicit move assignment operator)|" "constructor (inherited)}0%1" " not viable: no known conversion from %2 to %3 for " - "%select{%ordinal5 argument|object argument}4">; + "%select{%ordinal5 argument|object argument}4; " + "%select{|dereference the argument with *|" + "take the address of the argument with &|" + "remove *|" + "remove &}6">; +def note_ovl_candidate_bad_arc_conv : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "constructor (inherited)}0%1" + " not viable: cannot implicitly convert argument of type %2 to %3 for " + "%select{%ordinal5 argument|object argument}4 under ARC">; def note_ovl_candidate_bad_addrspace : Note<"candidate " "%select{function|function|constructor|" "function |function |constructor |" @@ -1620,15 +1896,18 @@ def note_ovl_candidate_bad_ownership : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 not viable: " "%select{%ordinal6|'this'}5 argument (%2) has " "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 ownership," " but parameter has %select{no|__unsafe_unretained|__strong|__weak|" "__autoreleasing}4 ownership">; def note_ovl_candidate_bad_cvr_this : Note<"candidate " - "%select{|function|||function||||" - "function (the implicit copy assignment operator)|}0 not viable: " + "%select{|function|||function|||||" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|}0 not viable: " "'this' argument has type %2, but method is not marked " "%select{const|restrict|const or restrict|volatile|const or volatile|" "volatile or restrict|const, volatile, or restrict}3">; @@ -1658,6 +1937,17 @@ def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate " "%select{base class pointer|superclass|base class object of type}2 %3 to " "%select{derived class pointer|subclass|derived class reference}2 %4 for " "%ordinal5 argument">; +def note_ovl_candidate_bad_target : Note< + "candidate %select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "constructor (inherited)}0 not viable: call to " + "%select{__device__|__global__|__host__|__host__ __device__}1 function from" + " %select{__device__|__global__|__host__|__host__ __device__}2 function">; def note_ambiguous_type_conversion: Note< "because of ambiguity in conversion of %0 to %1">; @@ -1694,9 +1984,13 @@ def err_ovl_no_viable_subscript : Error<"no viable overloaded operator[] for type %0">; def err_ovl_no_oper : Error<"type %0 does not provide a %select{subscript|call}1 operator">; -def err_ovl_unresolvable : - Error<"cannot resolve overloaded function %0 from context">; - +def err_ovl_unresolvable : Error< + "reference to overloaded function could not be resolved; " + "did you mean to call it%select{| with no arguments}0?">; +def err_bound_member_function : Error< + "reference to non-static member function must be called" + "%select{|; did you mean to call it with no arguments?}0">; +def note_possible_target_of_call : Note<"possible target for call">; def err_ovl_no_viable_object_call : Error< "no matching function for call to object of type %0">; @@ -1761,8 +2055,8 @@ def note_template_param_prev_default_arg : Note< def err_template_param_default_arg_missing : Error< "template parameter missing a default argument">; def ext_template_parameter_default_in_function_template : ExtWarn< - "default template arguments for a function template are a C++0x extension">, - InGroup<CXX0x>; + "default template arguments for a function template are a C++11 extension">, + InGroup<CXX11>; def err_template_parameter_default_template_member : Error< "cannot add a default template argument to the definition of a member of a " "class template">; @@ -1774,6 +2068,9 @@ def err_template_template_parm_no_parms : Error< def err_template_variable : Error<"variable %0 declared as a template">; def err_template_variable_noparams : Error< "extraneous 'template<>' in declaration of variable %0">; +def err_template_member : Error<"member %0 declared as a template">; +def err_template_member_noparams : Error< + "extraneous 'template<>' in declaration of member %0">; def err_template_tag_noparams : Error< "extraneous 'template<>' in declaration of %0 %1">; def err_template_decl_ref : Error< @@ -1895,8 +2192,8 @@ def err_template_spec_decl_out_of_scope_global : Error< def ext_template_spec_decl_out_of_scope_global : ExtWarn< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 must " - "originally be declared in the global scope; accepted as a C++0x extension">, - InGroup<CXX0x>; + "originally be declared in the global scope; accepted as a C++11 extension">, + InGroup<CXX11>; def err_template_spec_decl_out_of_scope : Error< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 must " @@ -1904,8 +2201,8 @@ def err_template_spec_decl_out_of_scope : Error< def ext_template_spec_decl_out_of_scope : ExtWarn< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 must " - "originally be declared in namespace %2; accepted as a C++0x extension">, - InGroup<CXX0x>; + "originally be declared in namespace %2; accepted as a C++11 extension">, + InGroup<CXX11>; def err_template_spec_redecl_out_of_scope : Error< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 not in a " @@ -1931,6 +2228,9 @@ def err_not_class_template_specialization : Error< "parameter}0">; def err_function_specialization_in_class : Error< "cannot specialize a function %0 within class scope">; +def ext_function_specialization_in_class : ExtWarn< + "explicit specialization of %0 within class scope is a Microsoft extension">, + InGroup<Microsoft>; def ext_explicit_specialization_storage_class : ExtWarn< "explicit specialization cannot have a storage class">; def err_explicit_specialization_inconsistent_storage_class : Error< @@ -2068,8 +2368,8 @@ def note_previous_explicit_instantiation : Note< "previous explicit instantiation is here">; def ext_explicit_instantiation_after_specialization : Extension< "explicit instantiation of %0 that occurs after an explicit " - "specialization will be ignored (C++0x extension)">, - InGroup<CXX0x>; + "specialization will be ignored (C++11 extension)">, + InGroup<CXX11>; def note_previous_template_specialization : Note< "previous template specialization is here">; def err_explicit_instantiation_enum : Error< @@ -2086,10 +2386,10 @@ def err_explicit_instantiation_must_be_global : Error< "explicit instantiation of %0 must occur at global scope">; def warn_explicit_instantiation_out_of_scope_0x : Warning< "explicit instantiation of %0 not in a namespace enclosing %1">, - InGroup<DiagGroup<"-Wc++0x-compat"> >; + InGroup<CXX11Compat>; def warn_explicit_instantiation_must_be_global_0x : Warning< "explicit instantiation of %0 must occur at global scope">, - InGroup<DiagGroup<"-Wc++0x-compat"> >; + InGroup<CXX11Compat>; def err_explicit_instantiation_requires_name : Error< "explicit instantiation declaration requires a name">; @@ -2114,6 +2414,8 @@ def note_explicit_instantiation_candidate : Note< "explicit instantiation candidate function template here %0">; def err_explicit_instantiation_inline : Error< "explicit instantiation cannot be 'inline'">; +def err_explicit_instantiation_constexpr : Error< + "explicit instantiation cannot be 'constexpr'">; def ext_explicit_instantiation_without_qualified_id : Extension< "qualifier in explicit instantiation of %q0 requires a template-id " "(a typedef is not permitted)">; @@ -2121,7 +2423,7 @@ def err_explicit_instantiation_unqualified_wrong_namespace : Error< "explicit instantiation of %q0 must occur in %1">; def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning< "explicit instantiation of %q0 must occur in %1">, - InGroup<DiagGroup<"c++0x-compat"> >; + InGroup<CXX11Compat>; def err_explicit_instantiation_undefined_member : Error< "explicit instantiation of undefined %select{member class|member function|" "static data member}0 %1 of class template %2">; @@ -2142,9 +2444,10 @@ def note_typename_refers_here : Note< def err_typename_missing : Error< "missing 'typename' prior to dependent type name '%0%1'">; def warn_typename_missing : ExtWarn< - "missing 'typename' prior to dependent type name '%0%1'">; + "missing 'typename' prior to dependent type name '%0%1'">, + InGroup<DiagGroup<"typename-missing">>; def ext_typename_outside_of_template : ExtWarn< - "'typename' occurs outside of a template">, InGroup<CXX0x>; + "'typename' occurs outside of a template">, InGroup<CXX11>; def err_typename_refers_to_using_value_decl : Error< "typename specifier refers to a dependent using declaration for a value " "%0 in %1">; @@ -2162,7 +2465,7 @@ def note_referenced_class_template : Error< def err_template_kw_missing : Error< "missing 'template' keyword prior to dependent template name '%0%1'">; def ext_template_outside_of_template : ExtWarn< - "'template' keyword outside of a template">, InGroup<CXX0x>; + "'template' keyword outside of a template">, InGroup<CXX11>; def err_non_type_template_in_nested_name_specifier : Error< "qualified name refers into a specialization of function template '%0'">; @@ -2172,7 +2475,7 @@ def note_template_declared_here : Note< "%select{function template|class template|type alias template|template template parameter}0 " "%1 declared here">; -// C++0x Variadic Templates +// C++11 Variadic Templates def err_template_param_pack_default_arg : Error< "template parameter pack cannot have a default argument">; def err_template_param_pack_must_be_last_template_parameter : Error< @@ -2240,6 +2543,9 @@ def err_unexpected_typedef : Error< def err_unexpected_namespace : Error< "unexpected namespace name %0: expected expression">; def err_undeclared_var_use : Error<"use of undeclared identifier %0">; +def warn_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 " + "found via unqualified lookup into dependent bases of class templates is a " + "Microsoft extension">, InGroup<Microsoft>; def note_dependent_var_use : Note<"must qualify identifier to find this " "declaration in dependent base class">; def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither " @@ -2265,9 +2571,11 @@ def note_unavailable_here : Note< "%select{declaration|function}0 has been explicitly marked " "%select{unavailable|deleted|deprecated}1 here">; def warn_not_enough_argument : Warning< - "not enough variable arguments in %0 declaration to fit a sentinel">; + "not enough variable arguments in %0 declaration to fit a sentinel">, + InGroup<Sentinel>; def warn_missing_sentinel : Warning < - "missing sentinel in %select{function call|method dispatch|block call}0">; + "missing sentinel in %select{function call|method dispatch|block call}0">, + InGroup<Sentinel>; def note_sentinel_here : Note< "%select{function|method|block}0 has been explicitly marked sentinel here">; def warn_missing_prototype : Warning< @@ -2410,6 +2718,8 @@ def err_at_least_one_initializer_needed_to_size_array : Error< def err_array_size_non_int : Error<"size of array has non-integer type %0">; def err_init_element_not_constant : Error< "initializer element is not a compile-time constant">; +def err_local_cant_init : Error< + "'__local' variable cannot have an initializer">; def err_block_extern_cant_init : Error< "'extern' variable cannot have an initializer">; def warn_extern_init : Warning<"'extern' variable has an initializer">; @@ -2436,10 +2746,28 @@ def warn_braces_around_scalar_init : Warning< "braces around scalar initializer">; def warn_many_braces_around_scalar_init : ExtWarn< "too many braces around scalar initializer">; +def ext_complex_component_init : Extension< + "complex initialization specifying real and imaginary components " + "is an extension">, InGroup<DiagGroup<"complex-component-init">>; def err_empty_scalar_initializer : Error<"scalar initializer cannot be empty">; def err_illegal_initializer : Error< "illegal initializer (only variables can be initialized)">; def err_illegal_initializer_type : Error<"illegal initializer type %0">; +def err_init_list_variable_narrowing : Error< + "non-constant-expression cannot be narrowed from type %0 to %1 in " + "initializer list">; +def err_init_list_constant_narrowing : Error< + "constant expression evaluates to %0 which cannot be narrowed to type %1">; +def warn_init_list_variable_narrowing : Warning< + "non-constant-expression cannot be narrowed from type %0 to %1 in " + "initializer list in C++11">, + InGroup<CXX11Narrowing>, DefaultIgnore; +def warn_init_list_constant_narrowing : Warning< + "constant expression evaluates to %0 which cannot be narrowed to type %1 in " + "C++11">, + InGroup<CXX11Narrowing>, DefaultIgnore; +def note_init_list_narrowing_override : Note< + "override this message by inserting an explicit cast">; def err_init_objc_class : Error< "cannot initialize Objective-C class type %0">; def err_implicit_empty_initializer : Error< @@ -2474,6 +2802,8 @@ def warn_unused_label : Warning<"unused label %0">, InGroup<UnusedLabel>, DefaultIgnore; def err_goto_into_protected_scope : Error<"goto into protected scope">; +def warn_goto_into_protected_scope : ExtWarn<"goto into protected scope">, + InGroup<Microsoft>; def err_switch_into_protected_scope : Error< "switch case is in protected scope">; def err_indirect_goto_without_addrlabel : Error< @@ -2563,8 +2893,8 @@ def ext_flexible_array_in_struct : Extension< "%0 may not be nested in a struct due to flexible array member">; def ext_flexible_array_in_array : Extension< "%0 may not be used as an array element due to flexible array member">; -def err_flexible_array_init_nonempty : Error< - "non-empty initialization of flexible array member inside subobject">; +def err_flexible_array_init : Error< + "initialization of flexible array member is not allowed">; def ext_flexible_array_empty_aggregate_ms : Extension< "flexible array member %0 in otherwise empty %select{struct|class}1 " "is a Microsoft extension">, InGroup<Microsoft>; @@ -2603,7 +2933,7 @@ def err_arc_objc_object_in_struct : Error< "ARC forbids Objective-C objects in structs or unions">; def err_arc_objc_property_default_assign_on_object : Error< "ARC forbids synthesizing a property of an Objective-C object " - "with unspecified storage attribute">; + "with unspecified ownership or storage attribute">; def err_arc_illegal_selector : Error< "ARC forbids use of %0 in a @selector">; def err_arc_illegal_method_def : Error< @@ -2672,10 +3002,11 @@ def err_arc_method_not_found : Error< def err_arc_receiver_forward_class : Error< "receiver %0 for class message is a forward declaration">; def err_arc_may_not_respond : Error< - "receiver type %0 for instance message does not declare a method with " - "selector %1">; + "no visible @interface for %0 declares the selector %1">; def err_arc_receiver_forward_instance : Error< "receiver type %0 for instance message is a forward declaration">; +def err_arc_collection_forward : Error< + "collection expression type %0 is a forward declaration">; def err_arc_multiple_method_decl : Error< "multiple methods named %0 found with mismatched result, " "parameter type or attributes">; @@ -2696,9 +3027,10 @@ def err_arc_strong_property_ownership : Error< "existing ivar %1 for strong property %0 may not be " "%select{|__unsafe_unretained||__weak}2">; def err_arc_assign_property_ownership : Error< - "existing ivar %1 for unsafe_unretained property %0 must be __unsafe_unretained">; + "existing ivar %1 for property %0 with %select{unsafe_unretained| assign}2 " + "attribute must be __unsafe_unretained">; def err_arc_inconsistent_property_ownership : Error< - "%select{strong|weak|unsafe_unretained}1 property %0 may not also be " + "%select{|unsafe_unretained|strong|weak}1 property %0 may not also be " "declared %select{|__unsafe_unretained|__strong|__weak|__autoreleasing}2">; def err_arc_atomic_ownership : Error< "cannot perform atomic operation on a pointer to type %0: type has " @@ -2759,6 +3091,10 @@ def err_block_with_return_type_requires_args : Error< "block with explicit return type requires argument list">; def err_func_def_incomplete_result : Error< "incomplete result type %0 in function definition">; +def err_atomic_specifier_bad_type : Error< + "_Atomic cannot be applied to " + "%select{incomplete |array |function |reference |atomic |qualified |}0type " + "%1 %select{||||||which is not trivially copyable}0">; // Expressions. def ext_sizeof_function_type : Extension< @@ -2793,8 +3129,10 @@ def warn_floatingpoint_eq : Warning< def warn_division_by_zero : Warning<"division by zero is undefined">; def warn_remainder_by_zero : Warning<"remainder by zero is undefined">; -def warn_shift_negative : Warning<"shift count is negative">; -def warn_shift_gt_typewidth : Warning<"shift count >= width of type">; +def warn_shift_negative : Warning<"shift count is negative">, + InGroup<DiagGroup<"shift-count-negative">>; +def warn_shift_gt_typewidth : Warning<"shift count >= width of type">, + InGroup<DiagGroup<"shift-count-overflow">>; def warn_shift_result_gt_typewidth : Warning< "signed shift result (%0) requires %1 bits to represent, but %2 only has " "%3 bits">, InGroup<DiagGroup<"shift-overflow">>; @@ -2820,8 +3158,12 @@ def note_precedence_conditional_silence : Note< "place parentheses around the '%0' expression to silence this warning">; def warn_logical_instead_of_bitwise : Warning< - "use of logical %0 with constant operand; switch to bitwise %1 or " - "remove constant">, InGroup<DiagGroup<"constant-logical-operand">>; + "use of logical '%0' with constant operand">, + InGroup<DiagGroup<"constant-logical-operand">>; +def note_logical_instead_of_bitwise_change_operator : Note< + "use '%0' for a bitwise operation">; +def note_logical_instead_of_bitwise_remove_constant : Note< + "remove constant to silence this warning">; def warn_bitwise_and_in_bitwise_or : Warning< "'&' within '|'">, InGroup<BitwiseOpParentheses>; @@ -2883,10 +3225,8 @@ def err_typecheck_member_reference_type : Error< def err_typecheck_member_reference_unknown : Error< "cannot refer to member %0 in %1 with '%select{.|->}2'">; def err_member_reference_needs_call : Error< - "base of member reference is %select{a function|an overloaded function}0; " - "perhaps you meant to call it%select{| with no arguments}1?">; -def note_member_ref_possible_intended_overload : Note< - "possibly valid overload here">; + "base of member reference is a function; perhaps you meant to call " + "it%select{| with no arguments}?">; def warn_subscript_is_char : Warning<"array subscript is of type 'char'">, InGroup<CharSubscript>, DefaultIgnore; @@ -2904,6 +3244,9 @@ def err_member_def_undefined_record : Error< "out-of-line definition of %0 from class %1 without definition">; def err_member_def_does_not_match : Error< "out-of-line definition of %0 does not match any declaration in %1">; +def err_member_def_does_not_match_suggest : Error< + "out-of-line definition of %0 does not match any declaration in %1; " + "did you mean %2">; def err_member_def_does_not_match_ret_type : Error< "out-of-line definition of %q0 differs from the declaration in the return type">; def err_nonstatic_member_out_of_line : Error< @@ -2922,6 +3265,12 @@ def warn_member_extra_qualification : Warning< def err_member_qualification : Error< "non-friend class member %0 cannot have a qualified name">; def note_member_def_close_match : Note<"member declaration nearly matches">; +def note_member_def_close_const_match : Note< + "member declaration does not match because " + "it %select{is|is not}0 const qualified">; +def note_member_def_close_param_match : Note< + "type of %ordinal0 parameter of member declaration does not match " + "definition (%1 vs %2)">; def err_typecheck_ivar_variable_size : Error< "instance variables must have a constant size">; def err_ivar_reference_type : Error< @@ -2938,7 +3287,8 @@ def err_typecheck_pointer_arith_void_type : Error< def err_typecheck_decl_incomplete_type : Error< "variable has incomplete type %0">; def ext_typecheck_decl_incomplete_type : ExtWarn< - "tentative definition of variable with internal linkage has incomplete non-array type %0">; + "tentative definition of variable with internal linkage has incomplete non-array type %0">, + InGroup<DiagGroup<"tentative-definition-incomplete-type">>; def err_tentative_def_incomplete_type : Error< "tentative definition has type %0 that is never completed">; def err_tentative_def_incomplete_type_arr : Error< @@ -2969,7 +3319,8 @@ def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">; def err_typecheck_sclass_func : Error<"illegal storage class on function">; def err_static_block_func : Error< "function declared in block scope cannot have 'static' storage class">; -def err_typecheck_address_of : Error<"address of %0 requested">; +def err_typecheck_address_of : Error<"address of %select{bit-field" + "|vector element|property expression|register variable}0 requested">; def ext_typecheck_addrof_void : Extension< "ISO C forbids taking the address of an expression of type 'void'">; def err_unqualified_pointer_member_function : Error< @@ -3039,9 +3390,6 @@ def err_stmtexpr_file_scope : Error< def warn_mixed_sign_comparison : Warning< "comparison of integers of different signs: %0 and %1">, InGroup<SignCompare>, DefaultIgnore; -def warn_mixed_sign_conditional : Warning< - "operands of ? are integers of different signs: %0 and %1">, - InGroup<SignCompare>, DefaultIgnore; def warn_lunsigned_always_true_comparison : Warning< "comparison of unsigned%select{| enum}2 expression %0 is always %1">, InGroup<TautologicalCompare>; @@ -3054,6 +3402,10 @@ def warn_comparison_of_mixed_enum_types : Warning< def warn_null_in_arithmetic_operation : Warning< "use of NULL in arithmetic operation">, InGroup<DiagGroup<"null-arithmetic">>; +def warn_null_in_comparison_operation : Warning< + "comparison between NULL and non-pointer " + "%select{(%1 and NULL)|(NULL and %1)}0">, + InGroup<DiagGroup<"null-arithmetic">>; def err_invalid_this_use : Error< "invalid use of 'this' outside of a nonstatic member function">; @@ -3140,7 +3492,9 @@ def error_nosetter_property_assignment : Error< "setter method is needed to assign to object using property" " assignment syntax">; def error_no_subobject_property_setting : Error< "expression is not assignable">; - +def err_qualified_objc_access : Error< + "%select{property|ivar}0 access cannot be qualified with '%1'">; + def ext_freestanding_complex : Extension< "complex numbers are an extension in a freestanding C99 implementation">; @@ -3205,10 +3559,11 @@ def err_incomplete_type_objc_at_encode : Error< def warn_setter_getter_impl_required : Warning< "property %0 requires method %1 to be defined - " - "use @synthesize, @dynamic or provide a method implementation">; + "use @synthesize, @dynamic or provide a method implementation " + "in this class implementation">; def warn_setter_getter_impl_required_in_category : Warning< "property %0 requires method %1 to be defined - " - "use @dynamic or provide a method implementation in category">; + "use @dynamic or provide a method implementation in this category">; def note_property_impl_required : Note< "implementation is here">; def note_parameter_named_here : Note< @@ -3326,8 +3681,8 @@ def err_array_size_ambiguous_conversion : Error< "enumeration type">; def ext_array_size_conversion : Extension< "implicit conversion from array size expression of type %0 to " - "%select{integral|enumeration}1 type %2 is a C++0x extension">, - InGroup<CXX0x>; + "%select{integral|enumeration}1 type %2 is a C++11 extension">, + InGroup<CXX11>; def err_address_space_qualified_new : Error< "'new' cannot allocate objects of type %0 in address space '%1'">; def err_address_space_qualified_delete : Error< @@ -3343,7 +3698,7 @@ def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete " "expression of type %0 to a pointer">; def warn_delete_incomplete : Warning< "deleting pointer to incomplete type %0 may cause undefined behaviour">; -def err_delete_incomplete_class_type : Warning< +def err_delete_incomplete_class_type : Error< "deleting incomplete class type %0; no conversions to pointer type">; def warn_delete_array_type : Warning< "'delete' applied to a pointer-to-array type %0 treated as delete[]">; @@ -3385,6 +3740,9 @@ def warn_non_virtual_dtor : Warning< def warn_delete_non_virtual_dtor : Warning< "delete called on %0 that has virtual functions but non-virtual destructor">, InGroup<DeleteNonVirtualDtor>, DefaultIgnore; +def warn_delete_abstract_non_virtual_dtor : Warning< + "delete called on %0 that is abstract but has non-virtual destructor">, + InGroup<DeleteNonVirtualDtor>; def warn_overloaded_virtual : Warning< "%q0 hides overloaded virtual %select{function|functions}1">, InGroup<OverloadedVirtual>, DefaultIgnore; @@ -3458,8 +3816,6 @@ def err_not_tag_in_scope : Error< def err_cannot_form_pointer_to_member_of_reference_type : Error< "cannot form a pointer-to-member to member %0 of reference type %1">; -def err_invalid_use_of_bound_member_func : Error< - "a bound member function may only be called">; def err_incomplete_object_call : Error< "incomplete type in call to object of type %0">; def err_incomplete_pointer_to_member_return : Error< @@ -3480,7 +3836,7 @@ def note_condition_assign_silence : Note< "place parentheses around the assignment to silence this warning">; def warn_equality_with_extra_parens : Warning<"equality comparison with " - "extraneous parentheses">, InGroup<Parentheses>; + "extraneous parentheses">, InGroup<ParenthesesOnEquality>; def note_equality_comparison_to_assign : Note< "use '=' to turn this equality comparison into an assignment">; def note_equality_comparison_silence : Note< @@ -3501,7 +3857,11 @@ def err_typecheck_convert_incompatible : Error< "%select{from incompatible type|to parameter of incompatible type|" "from a function with incompatible result type|to incompatible type|" "with an expression of incompatible type|to parameter of incompatible type|" - "to incompatible type}2 %1">; + "to incompatible type}2 %1; " + "%select{|dereference with *|" + "take the address with &|" + "remove *|" + "remove &}3">; def warn_incompatible_qualified_id : Warning< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " @@ -3514,13 +3874,21 @@ def ext_typecheck_convert_pointer_int : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" - "with an expression of type|to parameter of type|to type}2 %1">; + "with an expression of type|to parameter of type|to type}2 %1; " + "%select{|dereference with *|" + "take the address with &|" + "remove *|" + "remove &}3">; def ext_typecheck_convert_int_pointer : ExtWarn< "incompatible integer to pointer conversion " "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" - "with an expression of type|to parameter of type|to type}2 %1">; + "with an expression of type|to parameter of type|to type}2 %1; " + "%select{|dereference with *|" + "take the address with &|" + "remove *|" + "remove &}3">; def ext_typecheck_convert_pointer_void_func : Extension< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " @@ -3539,20 +3907,26 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" - "with an expression of type|to parameter of type|to type}2 %1">, - InGroup<DiagGroup<"incompatible-pointer-types">>; + "with an expression of type|to parameter of type|to type}2 %1" + "%select{|dereference with *|" + "take the address with &|" + "remove *|" + "remove &}3">, + InGroup<IncompatiblePointerTypes>; def ext_typecheck_convert_discards_qualifiers : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" "with an expression of type|to parameter of type|to type}2 %1 discards " - "qualifiers">; + "qualifiers">, + InGroup<IncompatiblePointerTypes>; def ext_nested_pointer_qualifier_mismatch : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" "with an expression of type|to parameter of type|to type}2 %1 discards " - "qualifiers in nested pointer types">; + "qualifiers in nested pointer types">, + InGroup<IncompatiblePointerTypes>; def warn_incompatible_vectors : Warning< "incompatible vector types " "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" @@ -3621,19 +3995,23 @@ def note_function_with_incomplete_return_type_declared_here : Note< def err_call_incomplete_argument : Error< "argument type %0 is incomplete">; def err_typecheck_call_too_few_args : Error< - "too few arguments to %select{function|block|method}0 call, " + "too few %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " "expected %1, have %2">; def err_typecheck_call_too_few_args_at_least : Error< - "too few arguments to %select{function|block|method}0 call, " + "too few %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " "expected at least %1, have %2">; def err_typecheck_call_too_many_args : Error< - "too many arguments to %select{function|block|method}0 call, " + "too many %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " "expected %1, have %2">; -def note_typecheck_call_too_many_args : Note< - "%0 declared here">; def err_typecheck_call_too_many_args_at_most : Error< - "too many arguments to %select{function|block|method}0 call, " + "too many %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " "expected at most %1, have %2">; +def note_callee_decl : Note< + "%0 declared here">; def warn_call_wrong_number_of_arguments : Warning< "too %select{few|many}0 arguments in call to %1">; def err_atomic_builtin_must_be_pointer : Error< @@ -3644,6 +4022,15 @@ def err_atomic_builtin_must_be_pointer_intptr : Error< def err_atomic_builtin_pointer_size : Error< "first argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte " "type (%0 invalid)">; +def err_atomic_op_needs_atomic : Error< + "first argument to atomic operation must be a pointer to _Atomic " + "type (%0 invalid)">; +def err_atomic_op_needs_atomic_int_or_ptr : Error< + "first argument to atomic operation must be a pointer to atomic " + "integer or pointer (%0 invalid)">; +def err_atomic_op_logical_needs_atomic_int : Error< + "first argument to logical atomic operation must be a pointer to atomic " + "integer (%0 invalid)">; def err_deleted_function_use : Error<"attempt to use a deleted function">; @@ -3653,6 +4040,11 @@ def err_config_scalar_return : Error< "CUDA special function 'cudaConfigureCall' must have scalar return type">; def err_kern_call_not_global_function : Error< "kernel call to non-global function %0">; +def err_global_call_not_config : Error< + "call to global function %0 not configured">; +def err_ref_bad_target : Error< + "reference to %select{__device__|__global__|__host__|__host__ __device__}0 " + "function %1 in %select{__device__|__global__|__host__|__host__ __device__}2 function">; def err_cannot_pass_objc_interface_to_vararg : Error< @@ -3696,9 +4088,11 @@ def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn< def err_cast_selector_expr : Error< "cannot type cast @selector expression">; def warn_typecheck_cond_incompatible_pointers : ExtWarn< - "pointer type mismatch (%0 and %1)">; + "pointer type mismatch (%0 and %1)">, + InGroup<DiagGroup<"pointer-type-mismatch">>; def warn_typecheck_cond_pointer_integer_mismatch : ExtWarn< - "pointer/integer type mismatch in conditional expression (%0 and %1)">; + "pointer/integer type mismatch in conditional expression (%0 and %1)">, + InGroup<DiagGroup<"conditional-type-mismatch">>; def err_typecheck_choose_expr_requires_constant : Error< "'__builtin_choose_expr' requires a constant expression">; def ext_typecheck_expression_not_constant_but_accepted : Extension< @@ -3715,6 +4109,14 @@ def warn_unused_property_expr : Warning< def warn_unused_call : Warning< "ignoring return value of function declared with %0 attribute">, InGroup<UnusedValue>; +def warn_unused_result : Warning< + "ignoring return value of function declared with warn_unused_result " + "attribute">, InGroup<DiagGroup<"unused-result">>; +def warn_unused_comparison : Warning< + "%select{equality|inequality}0 comparison result unused">, + InGroup<UnusedComparison>; +def note_inequality_comparison_to_or_assign : Note< + "use '|=' to turn this inequality comparison into an or-assignment">; def err_incomplete_type_used_in_type_trait_expr : Error< "incomplete type %0 used in type trait expression">; @@ -3798,11 +4200,18 @@ def err_not_direct_base_or_virtual : Error< def err_in_class_initializer_non_const : Error< "non-const static data member must be initialized out of line">; +def err_in_class_initializer_volatile : Error< + "static const volatile data member must be initialized out of line">; def err_in_class_initializer_bad_type : Error< "static data member of type %0 must be initialized out of line">; def ext_in_class_initializer_float_type : ExtWarn< - "in-class initializer for static data member of type %0 " - "is a C++0x extension">, InGroup<CXX0xStaticNonIntegralInitializer>; + "in-class initializer for static data member of type %0 is a GNU extension">, + InGroup<GNU>; +def note_in_class_initializer_float_type_constexpr : Note< + "use 'constexpr' specifier to silence this warning">; +def err_in_class_initializer_literal_type : Error< + "in-class initializer for static data member of type %0 requires " + "'constexpr' specifier">; def err_in_class_initializer_non_constant : Error< "in-class initializer is not a constant expression">; @@ -3941,7 +4350,13 @@ def err_literal_operator_outside_namespace : Error< // FIXME: This diagnostic sucks def err_literal_operator_params : Error< "parameter declaration for literal operator %0 is not valid">; - +def warn_user_literal_hexfloat : Warning< + "user-defined literal with suffix '%0' is preempted by C99 hexfloat " + "extension">, InGroup<UserDefinedLiterals>; +def warn_user_literal_reserved : Warning< + "user-defined literals not starting with '_' are reserved by the " + "implementation">, InGroup<UserDefinedLiterals>; + // C++ conversion functions def err_conv_function_not_member : Error< "conversion function must be a non-static member function">; @@ -3969,11 +4384,11 @@ def warn_conv_to_void_not_used : Warning< def warn_not_compound_assign : Warning< "use of unary operator that may be intended as compound assignment (%0=)">; -// C++0x explicit conversion operators +// C++11 explicit conversion operators def warn_explicit_conversion_functions : Warning< - "explicit conversion functions are a C++0x extension">, InGroup<CXX0x>; + "explicit conversion functions are a C++11 extension">, InGroup<CXX11>; -// C++0x defaulted functions +// C++11 defaulted functions def err_defaulted_default_ctor_params : Error< "an explicitly-defaulted default constructor must have no parameters">; def err_defaulted_copy_ctor_params : Error< @@ -4000,8 +4415,34 @@ def err_defaulted_copy_assign_const_param : Error< "the parameter for this explicitly-defaulted copy assignment operator is " "const, but a member or base requires it to be non-const">; def err_defaulted_copy_assign_quals : Error< - "an explicitly-defaulted copy assignment operator may not have 'const' " - "or 'volatile' qualifiers">; + "an explicitly-defaulted copy assignment operator may not have 'const', " + "'constexpr' or 'volatile' qualifiers">; +def err_defaulted_move_ctor_params : Error< + "an explicitly-defaulted move constructor must have exactly one parameter">; +def err_defaulted_move_ctor_volatile_param : Error< + "the parameter for an explicitly-defaulted move constructor may not be " + "volatile">; +def err_defaulted_move_ctor_const_param : Error< + "the parameter for an explicitly-defaulted move constructor may not be " + "const">; +def err_defaulted_move_assign_params : Error< + "an explicitly-defaulted move assignment operator must have exactly one " + "parameter">; +def err_defaulted_move_assign_return_type : Error< + "an explicitly-defaulted move assignment operator must return an unqualified " + "lvalue reference to its class type">; +def err_defaulted_move_assign_not_ref : Error< + "the parameter for an explicitly-defaulted move assignment operator must be an " + "rvalue reference type">; +def err_defaulted_move_assign_volatile_param : Error< + "the parameter for an explicitly-defaulted move assignment operator may not " + "be volatile">; +def err_defaulted_move_assign_const_param : Error< + "the parameter for an explicitly-defaulted move assignment operator may not " + "be const">; +def err_defaulted_move_assign_quals : Error< + "an explicitly-defaulted move assignment operator may not have 'const', " + "'constexpr' or 'volatile' qualifiers">; def err_incorrect_defaulted_exception_spec : Error< "exception specification of explicitly defaulted %select{default constructor|" "copy constructor|move constructor|copy assignment operator|move assignment " @@ -4011,15 +4452,20 @@ def err_out_of_line_default_deletes : Error< "defaulting this %select{default constructor|copy constructor|move " "constructor|copy assignment operator|move assignment operator|destructor}0 " "would delete it after its first declaration">; -def err_defaulted_move_unsupported : Error< - "defaulting move functions not yet supported">; +def warn_ptr_arith_precedes_bounds : Warning< + "the pointer decremented by %0 refers before the beginning of the array">, + InGroup<DiagGroup<"array-bounds-pointer-arithmetic">>, DefaultIgnore; +def warn_ptr_arith_exceeds_bounds : Warning< + "the pointer incremented by %0 refers past the end of the array (that " + "contains %1 element%s2)">, + InGroup<DiagGroup<"array-bounds-pointer-arithmetic">>, DefaultIgnore; def warn_array_index_precedes_bounds : Warning< "array index of '%0' indexes before the beginning of the array">, InGroup<DiagGroup<"array-bounds">>; def warn_array_index_exceeds_bounds : Warning< - "array index of '%0' indexes past the end of an array (that contains %1 elements)">, - InGroup<DiagGroup<"array-bounds">>; + "array index of '%0' indexes past the end of an array (that contains %1 " + "element%s2)">, InGroup<DiagGroup<"array-bounds">>; def note_array_index_out_of_bounds : Note< "array %0 declared here">; @@ -4031,7 +4477,7 @@ def warn_printf_insufficient_data_args : Warning< def warn_printf_data_arg_not_used : Warning< "data argument not used by format string">, InGroup<FormatExtraArgs>; def warn_format_invalid_conversion : Warning< - "invalid conversion specifier '%0'">, InGroup<Format>; + "invalid conversion specifier '%0'">, InGroup<FormatInvalidSpecifier>; def warn_printf_incomplete_specifier : Warning< "incomplete format specifier">, InGroup<Format>; def warn_missing_format_string : Warning< @@ -4086,20 +4532,38 @@ def warn_scanf_scanlist_incomplete : Warning< // CHECK: returning address/reference of stack memory def warn_ret_stack_addr : Warning< - "address of stack memory associated with local variable %0 returned">; + "address of stack memory associated with local variable %0 returned">, + InGroup<DiagGroup<"return-stack-address">>; def warn_ret_stack_ref : Warning< - "reference to stack memory associated with local variable %0 returned">; + "reference to stack memory associated with local variable %0 returned">, + InGroup<DiagGroup<"return-stack-address">>; def warn_ret_local_temp_addr : Warning< - "returning address of local temporary object">; + "returning address of local temporary object">, + InGroup<DiagGroup<"return-stack-address">>; def warn_ret_local_temp_ref : Warning< - "returning reference to local temporary object">; + "returning reference to local temporary object">, + InGroup<DiagGroup<"return-stack-address">>; def warn_ret_addr_label : Warning< - "returning address of label, which is local">; + "returning address of label, which is local">, + InGroup<DiagGroup<"return-stack-address">>; def err_ret_local_block : Error< "returning block that lives on the local stack">; def note_ref_var_local_bind : Note< "binding reference variable %0 here">; +// Check for initializing a member variable with the address or a reference to +// a constructor parameter. +def warn_bind_ref_member_to_parameter : Warning< + "binding reference member %0 to stack allocated parameter %1">, + InGroup<DiagGroup<"dangling-field">>; +def warn_init_ptr_member_to_parameter_addr : Warning< + "initializing pointer member %0 with the stack address of parameter %1">, + InGroup<DiagGroup<"dangling-field">>; +def warn_bind_ref_member_to_temporary : Warning< + "binding reference member %0 to a temporary value">, + InGroup<DiagGroup<"dangling-field">>; +def note_ref_or_ptr_member_declared_here : Note< + "%select{reference|pointer}0 member declared here">; // For non-floating point, expressions of the form x == x or x != x // should result in a warning, since these always evaluate to a constant. @@ -4110,7 +4574,8 @@ def warn_comparison_always : Warning< def warn_stringcompare : Warning< "result of comparison against %select{a string literal|@encode}0 is " - "unspecified (use strncmp instead)">; + "unspecified (use strncmp instead)">, + InGroup<DiagGroup<"string-compare">>; // Generic selections. def err_assoc_type_incomplete : Error< @@ -4138,13 +4603,18 @@ def err_return_in_block_expression : Error< def err_block_returning_array_function : Error< "block cannot return %select{array|function}0 type %1">; +// Builtin annotation string. +def err_builtin_annotation_not_string_constant : Error< + "__builtin_annotation requires a non wide string constant">; // CFString checking def err_cfstring_literal_not_string_constant : Error< - "CFString literal is not a string constant">; + "CFString literal is not a string constant">, + InGroup<DiagGroup<"CFString-literal">>; def warn_cfstring_truncated : Warning< "input conversion stopped due to an input byte that does not " - "belong to the input codeset UTF-8">; + "belong to the input codeset UTF-8">, + InGroup<DiagGroup<"CFString-literal">>; // Statements. def err_continue_not_in_loop : Error< @@ -4208,6 +4678,9 @@ def err_second_parameter_to_va_arg_abstract: Error< def warn_second_parameter_to_va_arg_not_pod : Warning< "second argument to 'va_arg' is of non-POD type %0">, InGroup<DiagGroup<"non-pod-varargs">>, DefaultError; +def warn_second_parameter_to_va_arg_ownership_qualified : Warning< + "second argument to 'va_arg' is of ARC ownership-qualified type %0">, + InGroup<DiagGroup<"non-pod-varargs">>, DefaultError; def warn_second_parameter_to_va_arg_never_compatible : Warning< "second argument to 'va_arg' is of promotable type %0; this va_arg has " "undefined behavior because arguments will be promoted to %1">; @@ -4306,13 +4779,20 @@ def err_c99_array_usage_cxx : Error< "C99-specific array features are not permitted in C++">; def err_double_requires_fp64 : Error< "use of type 'double' requires cl_khr_fp64 extension to be enabled">; +def err_nsconsumed_attribute_mismatch : Error< + "overriding method has mismatched ns_consumed attribute on its" + " parameter">; +def err_nsreturns_retained_attribute_mismatch : Error< + "overriding method has mismatched ns_returns_%select{not_retained|retained}0" + " attributes">; 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< - "local declaration of %0 hides instance variable">; + "local declaration of %0 hides instance variable">, + InGroup<DiagGroup<"shadow-ivar">>; def error_ivar_use_in_class_method : Error< "instance variable %0 accessed in class method">; def error_implicit_ivar_access : Error< @@ -4327,6 +4807,9 @@ def warn_attribute_method_def : Warning< def ext_typecheck_base_super : Warning< "method parameter type %0 does not match " "super class method parameter type %1">, InGroup<SuperSubClassMismatch>, DefaultIgnore; +def warn_missing_method_return_type : Warning< + "method has no return type specified; defaults to 'id'">, + InGroup<MissingMethodReturnType>, DefaultIgnore; // Spell-checking diagnostics def err_unknown_typename_suggest : Error< @@ -4377,9 +4860,12 @@ def err_sizeof_pack_no_pack_name_suggest : Error< def note_parameter_pack_here : Note<"parameter pack %0 declared here">; def err_uncasted_use_of_unknown_any : Error< - "%0 has unknown type; cast it to its declared type to use it">; + "%0 has unknown type; cast it to its declared type to use it">; def err_uncasted_call_of_unknown_any : Error< - "%0 has unknown return type; cast the call to its declared return type">; + "%0 has unknown return type; cast the call to its declared return type">; +def err_uncasted_send_to_unknown_any_method : Error< + "no known method %select{%objcinstance1|%objcclass1}0; cast the " + "message send to the method's return type">; def err_unsupported_unknown_any_decl : Error< "%0 has unknown type, which is unsupported for this kind of declaration">; def err_unsupported_unknown_any_expr : Error< @@ -4391,6 +4877,8 @@ def err_unknown_any_addrof : Error< "can only be cast to a pointer type">; def err_unknown_any_var_function_type : Error< "variable %0 with unknown type cannot be given a function type">; +def err_unknown_any_function : Error< + "function %0 with unknown type must be given a function type">; def err_filter_expression_integral : Error< "filter expression type should be an integral value not %0">; @@ -4409,14 +4897,31 @@ def warn_related_result_type_compatibility_class : Warning< def warn_related_result_type_compatibility_protocol : Warning< "protocol method is expected to return an instance of the implementing " "class, but is declared to return %0">; -def note_related_result_type_overridden : Note< +def note_related_result_type_overridden_family : Note< "overridden method is part of the '%select{|alloc|copy|init|mutableCopy|" - "new|autorelease|dealloc|release|retain|retainCount|self}0' method family">; + "new|autorelease|dealloc|finalize|release|retain|retainCount|self}0' method " + "family">; +def note_related_result_type_overridden : Note< + "overridden method returns an instance of its class type">; def note_related_result_type_inferred : Note< "%select{class|instance}0 method %1 is assumed to return an instance of " "its receiver type (%2)">; } +let CategoryName = "Modules Issue" in { +def err_module_private_follows_public : Error< + "__module_private__ declaration of %0 follows public declaration">; +def err_module_private_specialization : Error< + "%select{template|partial|member}0 specialization cannot be " + "declared __module_private__">; +def err_module_private_local : Error< + "%select{local variable|parameter|typedef}0 %1 cannot be declared " + "__module_private__">; +def err_module_private_local_class : Error< + "local %select{struct|union|class|enum}0 cannot be declared " + "__module_private__">; +} + } // end of sema component. diff --git a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h index 1324533..ea8ed9f 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_FILEMANAGER_H #include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LLVM.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -123,9 +124,9 @@ class FileManager : public llvm::RefCountedBase<FileManager> { /// \brief The virtual directories that we have allocated. For each /// virtual file (e.g. foo/bar/baz.cpp), we add all of its parent /// directories (foo/ and foo/bar/) here. - llvm::SmallVector<DirectoryEntry*, 4> VirtualDirectoryEntries; + SmallVector<DirectoryEntry*, 4> VirtualDirectoryEntries; /// \brief The virtual files that we have allocated. - llvm::SmallVector<FileEntry*, 4> VirtualFileEntries; + SmallVector<FileEntry*, 4> VirtualFileEntries; /// SeenDirEntries/SeenFileEntries - This is a cache that maps paths /// to directory/file entries (either real or virtual) we have @@ -153,7 +154,7 @@ class FileManager : public llvm::RefCountedBase<FileManager> { /// Add all ancestors of the given path (pointing to either a file /// or a directory) as virtual directories. - void addAncestorsAsVirtualDirs(llvm::StringRef Path); + void addAncestorsAsVirtualDirs(StringRef Path); public: FileManager(const FileSystemOptions &FileSystemOpts); @@ -178,41 +179,51 @@ public: /// getDirectory - Lookup, cache, and verify the specified directory /// (real or virtual). This returns NULL if the directory doesn't exist. /// - const DirectoryEntry *getDirectory(llvm::StringRef DirName); + /// \param CacheFailure If true and the file does not exist, we'll cache + /// the failure to find this file. + const DirectoryEntry *getDirectory(StringRef DirName, + bool CacheFailure = true); /// \brief Lookup, cache, and verify the specified file (real or /// virtual). This returns NULL if the file doesn't exist. /// - /// \param openFile if true and the file exists, it will be opened. - const FileEntry *getFile(llvm::StringRef Filename, bool openFile = false); + /// \param OpenFile if true and the file exists, it will be opened. + /// + /// \param CacheFailure If true and the file does not exist, we'll cache + /// the failure to find this file. + const FileEntry *getFile(StringRef Filename, bool OpenFile = false, + bool CacheFailure = true); + + /// \brief Returns the current file system options + const FileSystemOptions &getFileSystemOptions() { return FileSystemOpts; } /// \brief Retrieve a file entry for a "virtual" file that acts as /// if there were a file with the given name on disk. The file /// itself is not accessed. - const FileEntry *getVirtualFile(llvm::StringRef Filename, off_t Size, + const FileEntry *getVirtualFile(StringRef Filename, off_t Size, time_t ModificationTime); /// \brief Open the specified file as a MemoryBuffer, returning a new /// MemoryBuffer if successful, otherwise returning null. llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry, std::string *ErrorStr = 0); - llvm::MemoryBuffer *getBufferForFile(llvm::StringRef Filename, + llvm::MemoryBuffer *getBufferForFile(StringRef Filename, std::string *ErrorStr = 0); // getNoncachedStatValue - Will get the 'stat' information for the given path. // If the path is relative, it will be resolved against the WorkingDir of the // FileManager's FileSystemOptions. - bool getNoncachedStatValue(llvm::StringRef Path, struct stat &StatBuf); + bool getNoncachedStatValue(StringRef Path, struct stat &StatBuf); /// \brief If path is not absolute and FileSystemOptions set the working /// directory, the path is modified to be relative to the given /// working directory. - void FixupRelativePath(llvm::SmallVectorImpl<char> &path) const; + void FixupRelativePath(SmallVectorImpl<char> &path) const; /// \brief Produce an array mapping from the unique IDs assigned to each /// file to the corresponding FileEntry pointer. void GetUniqueIDMapping( - llvm::SmallVectorImpl<const FileEntry *> &UIDToFiles) const; + SmallVectorImpl<const FileEntry *> &UIDToFiles) const; void PrintStats() const; }; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h index bebcffd..5e48a86 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h @@ -17,6 +17,7 @@ #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/TokenKinds.h" +#include "clang/Basic/LLVM.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallString.h" @@ -49,14 +50,15 @@ namespace clang { /// set, and all tok::identifier tokens have a pointer to one of these. class IdentifierInfo { // Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a - // signed char and TokenKinds > 127 won't be handled correctly. - unsigned TokenID : 8; // Front-end token ID or tok::identifier. + // signed char and TokenKinds > 255 won't be handled correctly. + unsigned TokenID : 9; // Front-end token ID or tok::identifier. // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf). // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values // are for builtins. unsigned ObjCOrBuiltinID :11; bool HasMacro : 1; // True if there is a #define for this. bool IsExtension : 1; // True if identifier is a lang extension. + bool IsCXX11CompatKeyword : 1; // True if identifier is a keyword in C++11. bool IsPoisoned : 1; // True if identifier is poisoned. bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier". @@ -64,7 +66,7 @@ class IdentifierInfo { // file and wasn't modified since. bool RevertedTokenID : 1; // True if RevertTokenIDToIdentifier was // called. - // 6 bits left in 32-bit word. + // 5 bits left in 32-bit word. void *FETokenInfo; // Managed by the language front-end. llvm::StringMapEntry<IdentifierInfo*> *Entry; @@ -113,8 +115,8 @@ public: } /// getName - Return the actual identifier string. - llvm::StringRef getName() const { - return llvm::StringRef(getNameStart(), getLength()); + StringRef getName() const { + return StringRef(getNameStart(), getLength()); } /// hasMacroDefinition - Return true if this identifier is #defined to some @@ -198,6 +200,19 @@ public: RecomputeNeedsHandleIdentifier(); } + /// is/setIsCXX11CompatKeyword - Initialize information about whether or not + /// this language token is a keyword in C++11. This controls compatibility + /// warnings, and is only true when not parsing C++11. Once a compatibility + /// problem has been diagnosed with this keyword, the flag will be cleared. + bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; } + void setIsCXX11CompatKeyword(bool Val) { + IsCXX11CompatKeyword = Val; + if (Val) + NeedsHandleIdentifier = 1; + else + RecomputeNeedsHandleIdentifier(); + } + /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the /// Preprocessor will emit an error every time this token is used. void setIsPoisoned(bool Value = true) { @@ -251,7 +266,8 @@ private: void RecomputeNeedsHandleIdentifier() { NeedsHandleIdentifier = (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | - isExtensionToken()); + isExtensionToken() | isCXX11CompatKeyword() || + (getTokenID() == tok::kw___import_module__)); } }; @@ -299,8 +315,8 @@ public: /// advances the iterator for the following string. /// /// \returns The next string in the identifier table. If there is - /// no such string, returns an empty \c llvm::StringRef. - virtual llvm::StringRef Next() = 0; + /// no such string, returns an empty \c StringRef. + virtual StringRef Next() = 0; }; /// IdentifierInfoLookup - An abstract class used by IdentifierTable that @@ -314,7 +330,7 @@ public: /// Unlike the version in IdentifierTable, this returns a pointer instead /// of a reference. If the pointer is NULL then the IdentifierInfo cannot /// be found. - virtual IdentifierInfo* get(llvm::StringRef Name) = 0; + virtual IdentifierInfo* get(StringRef Name) = 0; /// \brief Retrieve an iterator into the set of all identifiers /// known to this identifier lookup source. @@ -376,7 +392,7 @@ public: /// get - Return the identifier token info for the specified named identifier. /// - IdentifierInfo &get(llvm::StringRef Name) { + IdentifierInfo &get(StringRef Name) { llvm::StringMapEntry<IdentifierInfo*> &Entry = HashTable.GetOrCreateValue(Name); @@ -405,9 +421,10 @@ public: return *II; } - IdentifierInfo &get(llvm::StringRef Name, tok::TokenKind TokenCode) { + IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) { IdentifierInfo &II = get(Name); II.TokenID = TokenCode; + assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large"); return II; } @@ -417,7 +434,7 @@ public: /// This is a version of get() meant for external sources that want to /// introduce or modify an identifier. If they called get(), they would /// likely end up in a recursion. - IdentifierInfo &getOwn(llvm::StringRef Name) { + IdentifierInfo &getOwn(StringRef Name) { llvm::StringMapEntry<IdentifierInfo*> &Entry = HashTable.GetOrCreateValue(Name); @@ -485,6 +502,7 @@ enum ObjCMethodFamily { // selector with the given name. OMF_autorelease, OMF_dealloc, + OMF_finalize, OMF_release, OMF_retain, OMF_retainCount, @@ -507,7 +525,7 @@ enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 }; /// selectors that take no arguments and selectors that take 1 argument, which /// accounts for 78% of all selectors in Cocoa.h. class Selector { - friend class DiagnosticInfo; + friend class Diagnostic; enum IdentifierInfoFlag { // MultiKeywordSelector = 0. @@ -595,7 +613,7 @@ public: /// /// \returns the name for this slot, which may be the empty string if no /// name was supplied. - llvm::StringRef getNameForSlot(unsigned argIndex) const; + StringRef getNameForSlot(unsigned argIndex) const; /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return /// it as an std::string. diff --git a/contrib/llvm/tools/clang/include/clang/Basic/LLVM.h b/contrib/llvm/tools/clang/include/clang/Basic/LLVM.h new file mode 100644 index 0000000..27c459d --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Basic/LLVM.h @@ -0,0 +1,53 @@ +//===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file forward declares and imports various common LLVM datatypes that +// clang wants to use unqualified. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_BASIC_LLVM_H +#define CLANG_BASIC_LLVM_H + +// This should be the only #include, force #includes of all the others on +// clients. +#include "llvm/Support/Casting.h" + +namespace llvm { + // ADT's. + class StringRef; + class Twine; + template<typename T> class ArrayRef; + template<typename T, unsigned N> class SmallVector; + template<typename T> class SmallVectorImpl; + + class raw_ostream; + // TODO: DenseMap, ... +} + + +namespace clang { + // Casting operators. + using llvm::isa; + using llvm::cast; + using llvm::dyn_cast; + using llvm::dyn_cast_or_null; + using llvm::cast_or_null; + + // ADT's. + using llvm::StringRef; + using llvm::Twine; + using llvm::ArrayRef; + using llvm::SmallVector; + using llvm::SmallVectorImpl; + + using llvm::raw_ostream; +} // end namespace clang. + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def new file mode 100644 index 0000000..c8389ab --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def @@ -0,0 +1,159 @@ +//===--- LangOptions.def - Language option database --------------- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the language options. Users of this file must +// define the LANGOPT macro to make use of this information. +// Optionally, the user may also define BENIGN_LANGOPT +// (for options that don't affect the construction of the AST in an +// incompatible way), ENUM_LANGOPT (for options that have enumeration, +// rather than unsigned, type), BENIGN_ENUM_LANGOPT (for benign +// options that have enumeration type), and VALUE_LANGOPT is a language option +// that describes a value rather than a flag. +// +//===----------------------------------------------------------------------===// +#ifndef LANGOPT +# error Define the LANGOPT macro to handle language options +#endif + +#ifndef VALUE_LANGOPT +# define VALUE_LANGOPT(Name, Bits, Default, Description) \ + LANGOPT(Name, Bits, Default, Description) +#endif + +#ifndef BENIGN_LANGOPT +# define BENIGN_LANGOPT(Name, Bits, Default, Description) \ + LANGOPT(Name, Bits, Default, Description) +#endif + +#ifndef ENUM_LANGOPT +# define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + LANGOPT(Name, Bits, Default, Description) +#endif + +#ifndef BENIGN_ENUM_LANGOPT +# define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + ENUM_LANGOPT(Name, Type, Bits, Default, Description) +#endif + +LANGOPT(C99 , 1, 0, "C99") +LANGOPT(C1X , 1, 0, "C1X") +LANGOPT(MicrosoftExt , 1, 0, "Microsoft extensions") +LANGOPT(MicrosoftMode , 1, 0, "Microsoft compatibility mode") +LANGOPT(Borland , 1, 0, "Borland extensions") +LANGOPT(CPlusPlus , 1, 0, "C++") +LANGOPT(CPlusPlus0x , 1, 0, "C++0x") +LANGOPT(ObjC1 , 1, 0, "Objective-C 1") +LANGOPT(ObjC2 , 1, 0, "Objective-C 2") +LANGOPT(ObjCNonFragileABI , 1, 0, "Objective-C modern abi") +LANGOPT(ObjCNonFragileABI2 , 1, 0, "Objective-C enhanced modern abi") +BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, + "Objective-C auto-synthesized properties") +BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1, + "Objective-C related result type inference") +LANGOPT(Trigraphs , 1, 0,"trigraphs") +LANGOPT(BCPLComment , 1, 0, "BCPL-style '//' comments") +LANGOPT(Bool , 1, 0, "bool, true, and false keywords") +BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers") +BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode") +BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions") +LANGOPT(GNUKeywords , 1, 1, "GNU keywords") +BENIGN_LANGOPT(ImplicitInt, 1, !C99 && !CPlusPlus, "C89 implicit 'int'") +LANGOPT(Digraphs , 1, 0, "digraphs") +BENIGN_LANGOPT(HexFloats , 1, C99, "C99 hexadecimal float constants") +LANGOPT(CXXOperatorNames , 1, 0, "C++ operator name keywords") +LANGOPT(AppleKext , 1, 0, "Apple kext support") +BENIGN_LANGOPT(PascalStrings, 1, 0, "Pascal string support") +LANGOPT(WritableStrings , 1, 0, "writable string support") +LANGOPT(ConstStrings , 1, 0, "const-qualified string support") +LANGOPT(LaxVectorConversions , 1, 1, "lax vector conversions") +LANGOPT(AltiVec , 1, 0, "AltiVec-style vector initializers") +LANGOPT(Exceptions , 1, 0, "exception handling") +LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions") +LANGOPT(CXXExceptions , 1, 0, "C++ exceptions") +LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling") +LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation") +LANGOPT(RTTI , 1, 1, "run-time type information") +LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout") +LANGOPT(NeXTRuntime , 1, 1, "NeXT Objective-C runtime") +LANGOPT(Freestanding, 1, 0, "freestanding implementation") +LANGOPT(FormatExtensions , 1, 0, "FreeBSD format extensions") +LANGOPT(NoBuiltin , 1, 0, "disable builtin functions") + +BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") +LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") +LANGOPT(Blocks , 1, 0, "blocks extension to C") +BENIGN_LANGOPT(EmitAllDecls , 1, 0, "support for emitting all declarations") +LANGOPT(MathErrno , 1, 1, "errno support for math functions") +BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time") + +LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro") +LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") +LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") +VALUE_LANGOPT(PackStruct , 32, 0, + "default struct packing maximum alignment") +VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") +LANGOPT(GNUInline , 1, 0, "GNU inline semantics") +LANGOPT(NoInline , 1, 0, "__NO_INLINE__ predefined macro") +LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro") + +BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") + +BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control") +LANGOPT(CharIsSigned , 1, 1, "signed char") +LANGOPT(ShortWChar , 1, 0, "unsigned short wchar_t") + +LANGOPT(ShortEnums , 1, 0, "short enum types") + +LANGOPT(OpenCL , 1, 0, "OpenCL") +LANGOPT(CUDA , 1, 0, "CUDA") + +LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators") +BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision") +BENIGN_LANGOPT(CatchUndefined , 1, 0, "catching undefined behavior at run time") +BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records") +BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables") +LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings") +BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden default visibility for inline C++ methods") +BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype") +BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support") + +BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking") +LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants") +LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math") +LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT") +LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment") +LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting") +LANGOPT(ObjCRuntimeHasWeak , 1, 0, "__weak support in the ARC runtime") +LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") + +LANGOPT(MRTD , 1, 0, "-mrtd calling convention") +BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing") +LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime") + +ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode") +ENUM_LANGOPT(VisibilityMode, Visibility, 3, DefaultVisibility, + "symbol visibility") +ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, + "stack protector mode") +ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, + "signed integer overflow handling") + +BENIGN_LANGOPT(InstantiationDepth, 32, 1024, + "maximum template instantiation depth") +BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0, + "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.") +VALUE_LANGOPT(MSCVersion, 32, 0, + "version of Microsoft Visual C/C++") + +#undef LANGOPT +#undef VALUE_LANGOPT +#undef BENIGN_LANGOPT +#undef ENUM_LANGOPT +#undef BENIGN_ENUM_LANGOPT + diff --git a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h index de2ac6a..688047f 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h @@ -23,255 +23,53 @@ namespace clang { /// enabled, which controls the dialect of C that is accepted. class LangOptions { public: - unsigned Trigraphs : 1; // Trigraphs in source files. - unsigned BCPLComment : 1; // BCPL-style '//' comments. - unsigned Bool : 1; // 'bool', 'true', 'false' keywords. - unsigned DollarIdents : 1; // '$' allowed in identifiers. - unsigned AsmPreprocessor : 1; // Preprocessor in asm mode. - unsigned GNUMode : 1; // True in gnu99 mode false in c99 mode (etc) - unsigned GNUKeywords : 1; // True if GNU-only keywords are allowed - unsigned ImplicitInt : 1; // C89 implicit 'int'. - unsigned Digraphs : 1; // C94, C99 and C++ - unsigned HexFloats : 1; // C99 Hexadecimal float constants. - unsigned C99 : 1; // C99 Support - unsigned C1X : 1; // C1X Support - unsigned Microsoft : 1; // Microsoft extensions. - unsigned Borland : 1; // Borland extensions. - unsigned CPlusPlus : 1; // C++ Support - unsigned CPlusPlus0x : 1; // C++0x Support - unsigned CXXOperatorNames : 1; // Treat C++ operator names as keywords. - - unsigned ObjC1 : 1; // Objective-C 1 support enabled. - unsigned ObjC2 : 1; // Objective-C 2 support enabled. - unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled - unsigned ObjCNonFragileABI2 : 1; // Objective-C enhanced modern abi enabled - unsigned ObjCDefaultSynthProperties : 1; // Objective-C auto-synthesized properties. - unsigned ObjCInferRelatedResultType : 1; // Infer Objective-C related return - // types - unsigned AppleKext : 1; // Allow apple kext features. - - unsigned PascalStrings : 1; // Allow Pascal strings - unsigned WritableStrings : 1; // Allow writable strings - unsigned ConstStrings : 1; // Add const qualifier to strings (-Wwrite-strings) - unsigned LaxVectorConversions : 1; - unsigned AltiVec : 1; // Support AltiVec-style vector initializers. - unsigned Exceptions : 1; // Support exception handling. - unsigned ObjCExceptions : 1; // Support Objective-C exceptions. - unsigned CXXExceptions : 1; // Support C++ exceptions. - unsigned SjLjExceptions : 1; // Use setjmp-longjump exception handling. - unsigned TraditionalCPP : 1; /// Enable some traditional CPP emulation. - unsigned RTTI : 1; // Support RTTI information. - - unsigned MSBitfields : 1; // MS-compatible structure layout - unsigned NeXTRuntime : 1; // Use NeXT runtime. - unsigned Freestanding : 1; // Freestanding implementation - unsigned FormatExtensions : 1; // FreeBSD format extensions (-fformat-extensions) - unsigned NoBuiltin : 1; // Do not use builtin functions (-fno-builtin) - - unsigned ThreadsafeStatics : 1; // Whether static initializers are protected - // by locks. - unsigned POSIXThreads : 1; // Compiling with POSIX thread support - // (-pthread) - unsigned Blocks : 1; // block extension to C - unsigned EmitAllDecls : 1; // Emit all declarations, even if - // they are unused. - unsigned MathErrno : 1; // Math functions must respect errno - // (modulo the platform support). - - unsigned HeinousExtensions : 1; // Extensions that we really don't like and - // may be ripped out at any time. - - unsigned Optimize : 1; // Whether __OPTIMIZE__ should be defined. - unsigned OptimizeSize : 1; // Whether __OPTIMIZE_SIZE__ should be - // defined. - unsigned Static : 1; // Should __STATIC__ be defined (as - // opposed to __DYNAMIC__). - unsigned PICLevel : 2; // The value for __PIC__, if non-zero. - - unsigned GNUInline : 1; // Should GNU inline semantics be - // used (instead of C99 semantics). - unsigned NoInline : 1; // Should __NO_INLINE__ be defined. - - unsigned Deprecated : 1; // Should __DEPRECATED be defined. - - unsigned ObjCGCBitmapPrint : 1; // Enable printing of gc's bitmap layout - // for __weak/__strong ivars. - - unsigned AccessControl : 1; // Whether C++ access control should - // be enabled. - unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type - unsigned ShortWChar : 1; // Force wchar_t to be unsigned short int. - - unsigned ShortEnums : 1; // The enum type will be equivalent to the - // smallest integer type with enough room. - - unsigned OpenCL : 1; // OpenCL C99 language extensions. - unsigned CUDA : 1; // CUDA C++ language extensions. - - unsigned AssumeSaneOperatorNew : 1; // Whether to add __attribute__((malloc)) - // to the declaration of C++'s new - // operators - unsigned ElideConstructors : 1; // Whether C++ copy constructors should be - // elided if possible. - unsigned CatchUndefined : 1; // Generate code to check for undefined ops. - unsigned DumpRecordLayouts : 1; /// Dump the layout of IRgen'd records. - unsigned DumpVTableLayouts : 1; /// Dump the layouts of emitted vtables. - unsigned NoConstantCFStrings : 1; // Do not do CF strings - unsigned InlineVisibilityHidden : 1; // Whether inline C++ methods have - // hidden visibility by default. - unsigned ParseUnknownAnytype: 1; /// Let the user write __unknown_anytype. - unsigned DebuggerSupport : 1; /// Do things that only make sense when - /// supporting a debugger - - unsigned SpellChecking : 1; // Whether to perform spell-checking for error - // recovery. - unsigned SinglePrecisionConstants : 1; // Whether to treat double-precision - // floating point constants as - // single precision constants. - unsigned FastRelaxedMath : 1; // OpenCL fast relaxed math (on its own, - // defines __FAST_RELAXED_MATH__). - unsigned DefaultFPContract : 1; // Default setting for FP_CONTRACT - // FIXME: This is just a temporary option, for testing purposes. - unsigned NoBitFieldTypeAlign : 1; - unsigned ObjCAutoRefCount : 1; // Objective C automated reference counting - unsigned ObjCRuntimeHasWeak : 1; // The ARC runtime supports __weak - unsigned ObjCInferRelatedReturnType : 1; // Infer Objective-C related return - // types - unsigned FakeAddressSpaceMap : 1; // Use a fake address space map, for - // testing languages such as OpenCL. - - unsigned MRTD : 1; // -mrtd calling convention - unsigned DelayedTemplateParsing : 1; // Delayed template parsing - -private: - // We declare multibit enums as unsigned because MSVC insists on making enums - // signed. Set/Query these values using accessors. - unsigned GC : 2; // Objective-C Garbage Collection modes. - unsigned SymbolVisibility : 3; // Symbol's visibility. - unsigned StackProtector : 2; // Whether stack protectors are on. - unsigned SignedOverflowBehavior : 2; // How to handle signed integer overflow. - -public: - unsigned InstantiationDepth; // Maximum template instantiation depth. - unsigned NumLargeByValueCopy; // Warn if parameter/return value is larger - // in bytes than this setting. 0 is no check. - - // Version of Microsoft Visual C/C++ we are pretending to be. This is - // temporary until we support all MS extensions used in Windows SDK and stdlib - // headers. Sets _MSC_VER. - unsigned MSCVersion; - - std::string ObjCConstantStringClass; - + typedef clang::Visibility Visibility; + enum GCMode { NonGC, GCOnly, HybridGC }; enum StackProtectorMode { SSPOff, SSPOn, SSPReq }; - + enum SignedOverflowBehaviorTy { SOB_Undefined, // Default C standard behavior. SOB_Defined, // -fwrapv SOB_Trapping // -ftrapv }; + + // Define simple language options (with no accessors). +#define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) +#include "clang/Basic/LangOptions.def" + +private: + // Define language options of enumeration type. These are private, and will + // have accessors (below). +#define LANGOPT(Name, Bits, Default, Description) +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + unsigned Name : Bits; +#include "clang/Basic/LangOptions.def" + +public: + std::string ObjCConstantStringClass; + /// The name of the handler function to be called when -ftrapv is specified. /// If none is specified, abort (GCC-compatible behaviour). std::string OverflowHandler; - LangOptions() { - Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0; - GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0; - HexFloats = 0; - ObjCAutoRefCount = 0; - ObjCRuntimeHasWeak = 0; - ObjCInferRelatedReturnType = 0; - GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0; - AppleKext = 0; - ObjCDefaultSynthProperties = 0; - ObjCInferRelatedResultType = 1; - NoConstantCFStrings = 0; InlineVisibilityHidden = 0; - C99 = C1X = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0; - CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0; - Exceptions = ObjCExceptions = CXXExceptions = SjLjExceptions = 0; - TraditionalCPP = Freestanding = NoBuiltin = 0; - MSBitfields = 0; - NeXTRuntime = 1; - RTTI = 1; - LaxVectorConversions = 1; - HeinousExtensions = 0; - AltiVec = OpenCL = CUDA = StackProtector = 0; - - SymbolVisibility = (unsigned) DefaultVisibility; - - ThreadsafeStatics = 1; - POSIXThreads = 0; - Blocks = 0; - EmitAllDecls = 0; - MathErrno = 1; - SignedOverflowBehavior = SOB_Undefined; - - AssumeSaneOperatorNew = 1; - AccessControl = 1; - ElideConstructors = 1; - - SignedOverflowBehavior = 0; - ObjCGCBitmapPrint = 0; - - InstantiationDepth = 1024; - - NumLargeByValueCopy = 0; - MSCVersion = 0; - - Optimize = 0; - OptimizeSize = 0; - - Static = 0; - PICLevel = 0; - - GNUInline = 0; - NoInline = 0; - - Deprecated = 0; - - CharIsSigned = 1; - ShortWChar = 0; - ShortEnums = 0; - CatchUndefined = 0; - DumpRecordLayouts = 0; - DumpVTableLayouts = 0; - SpellChecking = 1; - SinglePrecisionConstants = 0; - FastRelaxedMath = 0; - DefaultFPContract = 0; - NoBitFieldTypeAlign = 0; - FakeAddressSpaceMap = 0; - MRTD = 0; - DelayedTemplateParsing = 0; - ParseUnknownAnytype = DebuggerSupport = 0; - } - - GCMode getGCMode() const { return (GCMode) GC; } - void setGCMode(GCMode m) { GC = (unsigned) m; } - - StackProtectorMode getStackProtectorMode() const { - return static_cast<StackProtectorMode>(StackProtector); - } - void setStackProtectorMode(StackProtectorMode m) { - StackProtector = static_cast<unsigned>(m); - } - - Visibility getVisibilityMode() const { - return (Visibility) SymbolVisibility; - } - void setVisibilityMode(Visibility v) { SymbolVisibility = (unsigned) v; } - - SignedOverflowBehaviorTy getSignedOverflowBehavior() const { - return (SignedOverflowBehaviorTy)SignedOverflowBehavior; - } - void setSignedOverflowBehavior(SignedOverflowBehaviorTy V) { - SignedOverflowBehavior = (unsigned)V; - } + LangOptions(); + // Define accessors/mutators for language options of enumeration type. +#define LANGOPT(Name, Bits, Default, Description) +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + Type get##Name() const { return static_cast<Type>(Name); } \ + void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } +#include "clang/Basic/LangOptions.def" + bool isSignedOverflowDefined() const { return getSignedOverflowBehavior() == SOB_Defined; } + + /// \brief Reset all of the options that are not considered when building a + /// module. + void resetNonModularOptions(); }; /// Floating point control options @@ -297,6 +95,18 @@ public: } }; +/// \brief Describes the kind of translation unit being processed. +enum TranslationUnitKind { + /// \brief The translation unit is a complete translation unit. + TU_Complete, + /// \brief The translation unit is a prefix to a translation unit, and is + /// not complete. + TU_Prefix, + /// \brief The translation unit is a module. + TU_Module +}; + + /// \brief } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/MacroBuilder.h b/contrib/llvm/tools/clang/include/clang/Basic/MacroBuilder.h index 3287b30..1d0f1e8 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/MacroBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/MacroBuilder.h @@ -20,23 +20,23 @@ namespace clang { class MacroBuilder { - llvm::raw_ostream &Out; + raw_ostream &Out; public: - MacroBuilder(llvm::raw_ostream &Output) : Out(Output) {} + MacroBuilder(raw_ostream &Output) : Out(Output) {} /// Append a #define line for macro of the form "#define Name Value\n". - void defineMacro(const llvm::Twine &Name, const llvm::Twine &Value = "1") { + void defineMacro(const Twine &Name, const Twine &Value = "1") { Out << "#define " << Name << ' ' << Value << '\n'; } /// Append a #undef line for Name. Name should be of the form XXX /// and we emit "#undef XXX". - void undefineMacro(const llvm::Twine &Name) { + void undefineMacro(const Twine &Name) { Out << "#undef " << Name << '\n'; } /// Directly append Str and a newline to the underlying buffer. - void append(const llvm::Twine &Str) { + void append(const Twine &Str) { Out << Str << '\n'; } }; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h b/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h index 267ecbc..7328b1a 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h @@ -28,31 +28,31 @@ namespace io { typedef uint32_t Offset; -inline void Emit8(llvm::raw_ostream& Out, uint32_t V) { +inline void Emit8(raw_ostream& Out, uint32_t V) { Out << (unsigned char)(V); } -inline void Emit16(llvm::raw_ostream& Out, uint32_t V) { +inline void Emit16(raw_ostream& Out, uint32_t V) { Out << (unsigned char)(V); Out << (unsigned char)(V >> 8); assert((V >> 16) == 0); } -inline void Emit24(llvm::raw_ostream& Out, uint32_t V) { +inline void Emit24(raw_ostream& Out, uint32_t V) { Out << (unsigned char)(V); Out << (unsigned char)(V >> 8); Out << (unsigned char)(V >> 16); assert((V >> 24) == 0); } -inline void Emit32(llvm::raw_ostream& Out, uint32_t V) { +inline void Emit32(raw_ostream& Out, uint32_t V) { Out << (unsigned char)(V); Out << (unsigned char)(V >> 8); Out << (unsigned char)(V >> 16); Out << (unsigned char)(V >> 24); } -inline void Emit64(llvm::raw_ostream& Out, uint64_t V) { +inline void Emit64(raw_ostream& Out, uint64_t V) { Out << (unsigned char)(V); Out << (unsigned char)(V >> 8); Out << (unsigned char)(V >> 16); @@ -63,7 +63,7 @@ inline void Emit64(llvm::raw_ostream& Out, uint64_t V) { Out << (unsigned char)(V >> 56); } -inline void Pad(llvm::raw_ostream& Out, unsigned A) { +inline void Pad(raw_ostream& Out, unsigned A) { Offset off = (Offset) Out.tell(); uint32_t n = ((uintptr_t)(off+A-1) & ~(uintptr_t)(A-1)) - off; for (; n ; --n) @@ -182,12 +182,12 @@ public: InfoObj)); } - io::Offset Emit(llvm::raw_ostream &out) { + io::Offset Emit(raw_ostream &out) { Info InfoObj; return Emit(out, InfoObj); } - io::Offset Emit(llvm::raw_ostream &out, Info &InfoObj) { + io::Offset Emit(raw_ostream &out, Info &InfoObj) { using namespace clang::io; // Emit the payload of the table. @@ -464,6 +464,8 @@ public: } item_iterator item_end() { return item_iterator(); } + Info &getInfoObj() { return InfoObj; } + static OnDiskChainedHashTable* Create(const unsigned char* buckets, const unsigned char* const base, const Info &InfoObj = Info()) { diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OpenCLExtensions.def b/contrib/llvm/tools/clang/include/clang/Basic/OpenCLExtensions.def index 95cc1a9..103fa83 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OpenCLExtensions.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/OpenCLExtensions.def @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +// OpenCL 1.1. OPENCLEXT(cl_khr_fp64) OPENCLEXT(cl_khr_int64_base_atomics) OPENCLEXT(cl_khr_int64_extended_atomics) @@ -25,4 +26,7 @@ OPENCLEXT(cl_khr_local_int32_extended_atomics) OPENCLEXT(cl_khr_byte_addressable_store) OPENCLEXT(cl_khr_3d_image_writes) +// Clang Extensions. +OPENCLEXT(cl_clang_storage_class_specifiers) + #undef OPENCLEXT diff --git a/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h index 7d7c089..c6ca989 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h @@ -33,7 +33,7 @@ public: /// currently only support up to 10 arguments (%0-%9). /// A single diagnostic with more than that almost certainly has to /// be simplified anyway. - MaxArguments = 10 + MaxArguments = DiagnosticsEngine::MaxArguments }; /// NumDiagArgs - This contains the number of entries in Arguments. @@ -65,7 +65,7 @@ public: /// only support 10 ranges, could easily be extended if needed. CharSourceRange DiagRanges[10]; - enum { MaxFixItHints = 3 }; + enum { MaxFixItHints = DiagnosticsEngine::MaxFixItHints }; /// FixItHints - If valid, provides a hint with some code /// to insert, remove, or modify at a particular position. @@ -165,6 +165,8 @@ private: assert(DiagStorage->NumFixItHints < Storage::MaxFixItHints && "Too many code modification hints!"); + if (DiagStorage->NumFixItHints >= Storage::MaxFixItHints) + return; // Don't crash in release builds DiagStorage->FixItHints[DiagStorage->NumFixItHints++] = Hint; } @@ -190,12 +192,12 @@ public: *this->DiagStorage = *Other.DiagStorage; } - PartialDiagnostic(const DiagnosticInfo &Other, StorageAllocator &Allocator) + PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator) : DiagID(Other.getID()), DiagStorage(0), Allocator(&Allocator) { // Copy arguments. for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) { - if (Other.getArgKind(I) == Diagnostic::ak_std_string) + if (Other.getArgKind(I) == DiagnosticsEngine::ak_std_string) AddString(Other.getArgStdStr(I)); else AddTaggedVal(Other.getRawArg(I), Other.getArgKind(I)); @@ -230,7 +232,7 @@ public: unsigned getDiagID() const { return DiagID; } - void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const { + void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { if (!DiagStorage) DiagStorage = getStorage(); @@ -240,14 +242,14 @@ public: DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V; } - void AddString(llvm::StringRef V) const { + void AddString(StringRef V) const { if (!DiagStorage) DiagStorage = getStorage(); assert(DiagStorage->NumDiagArgs < Storage::MaxArguments && "Too many arguments to diagnostic!"); DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] - = Diagnostic::ak_std_string; + = DiagnosticsEngine::ak_std_string; DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = V; } @@ -257,12 +259,12 @@ public: // Add all arguments. for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) { - if ((Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i] - == Diagnostic::ak_std_string) + if ((DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i] + == DiagnosticsEngine::ak_std_string) DB.AddString(DiagStorage->DiagArgumentsStr[i]); else DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i], - (Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i]); + (DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]); } // Add all ranges. @@ -285,24 +287,25 @@ public: friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, unsigned I) { - PD.AddTaggedVal(I, Diagnostic::ak_uint); + PD.AddTaggedVal(I, DiagnosticsEngine::ak_uint); return PD; } friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, int I) { - PD.AddTaggedVal(I, Diagnostic::ak_sint); + PD.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return PD; } friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, const char *S) { - PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), Diagnostic::ak_c_string); + PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), + DiagnosticsEngine::ak_c_string); return PD; } friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, - llvm::StringRef S) { + StringRef S) { PD.AddString(S); return PD; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/PrettyStackTrace.h b/contrib/llvm/tools/clang/include/clang/Basic/PrettyStackTrace.h index 5a5d551..06a1264 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/PrettyStackTrace.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/PrettyStackTrace.h @@ -30,7 +30,7 @@ namespace clang { public: PrettyStackTraceLoc(SourceManager &sm, SourceLocation L, const char *Msg) : SM(sm), Loc(L), Message(Msg) {} - virtual void print(llvm::raw_ostream &OS) const; + virtual void print(raw_ostream &OS) const; }; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h index ee5f96f..154148c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SOURCELOCATION_H #define LLVM_CLANG_SOURCELOCATION_H +#include "clang/Basic/LLVM.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <utility> #include <functional> @@ -21,8 +22,6 @@ namespace llvm { class MemoryBuffer; - class raw_ostream; - class StringRef; template <typename T> struct DenseMapInfo; template <typename T> struct isPodLike; } @@ -35,8 +34,9 @@ class SourceManager; /// a source file (MemoryBuffer) along with its #include path and #line data. /// class FileID { - /// ID - Opaque identifier, 0 is "invalid". - unsigned ID; + /// ID - Opaque identifier, 0 is "invalid". >0 is this module, <-1 is + /// something loaded from another module. + int ID; public: FileID() : ID(0) {} @@ -49,49 +49,63 @@ public: bool operator>(const FileID &RHS) const { return RHS < *this; } bool operator>=(const FileID &RHS) const { return RHS <= *this; } - static FileID getSentinel() { return get(~0U); } - unsigned getHashValue() const { return ID; } + static FileID getSentinel() { return get(-1); } + unsigned getHashValue() const { return static_cast<unsigned>(ID); } private: friend class SourceManager; friend class ASTWriter; friend class ASTReader; - static FileID get(unsigned V) { + static FileID get(int V) { FileID F; F.ID = V; return F; } - unsigned getOpaqueValue() const { return ID; } + int getOpaqueValue() const { return ID; } }; -/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes -/// a full include stack, line and column number information for a position in -/// an input translation unit. +/// \brief Encodes a location in the source. The SourceManager can decode this +/// to get at the full include stack, line and column information. +/// +/// Technically, a source location is simply an offset into the manager's view +/// of the input source, which is all input buffers (including macro +/// expansions) concatenated in an effectively arbitrary order. The manager +/// actually maintains two blocks of input buffers. One, starting at offset +/// 0 and growing upwards, contains all buffers from this module. The other, +/// starting at the highest possible offset and growing downwards, contains +/// buffers of loaded modules. +/// +/// In addition, one bit of SourceLocation is used for quick access to the +/// information whether the location is in a file or a macro expansion. +/// +/// It is important that this type remains small. It is currently 32 bits wide. class SourceLocation { unsigned ID; friend class SourceManager; + friend class ASTReader; + friend class ASTWriter; enum { MacroIDBit = 1U << 31 }; public: - SourceLocation() : ID(0) {} // 0 is an invalid FileID. + SourceLocation() : ID(0) {} bool isFileID() const { return (ID & MacroIDBit) == 0; } bool isMacroID() const { return (ID & MacroIDBit) != 0; } - /// isValid - Return true if this is a valid SourceLocation object. Invalid - /// SourceLocations are often used when events have no corresponding location - /// in the source (e.g. a diagnostic is required for a command line option). + /// \brief Return true if this is a valid SourceLocation object. /// + /// Invalid SourceLocations are often used when events have no corresponding + /// location in the source (e.g. a diagnostic is required for a command line + /// option). bool isValid() const { return ID != 0; } bool isInvalid() const { return ID == 0; } private: - /// getOffset - Return the index for SourceManager's SLocEntryTable table, - /// note that this is not an index *into* it though. + /// \brief Return the offset into the manager's global input view. unsigned getOffset() const { return ID & ~MacroIDBit; } @@ -111,10 +125,10 @@ private: } public: - /// getFileLocWithOffset - Return a source location with the specified offset - /// from this file SourceLocation. - SourceLocation getFileLocWithOffset(int Offset) const { - assert(((getOffset()+Offset) & MacroIDBit) == 0 && "invalid location"); + /// \brief Return a source location with the specified offset from this + /// SourceLocation. + SourceLocation getLocWithOffset(int Offset) const { + assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow"); SourceLocation L; L.ID = ID+Offset; return L; @@ -150,7 +164,7 @@ public: return getFromRawEncoding((unsigned)(uintptr_t)Encoding); } - void print(llvm::raw_ostream &OS, const SourceManager &SM) const; + void print(raw_ostream &OS, const SourceManager &SM) const; void dump(const SourceManager &SM) const; }; @@ -261,11 +275,11 @@ public: FileID getFileID() const; - FullSourceLoc getInstantiationLoc() const; + FullSourceLoc getExpansionLoc() const; FullSourceLoc getSpellingLoc() const; - unsigned getInstantiationLineNumber(bool *Invalid = 0) const; - unsigned getInstantiationColumnNumber(bool *Invalid = 0) const; + unsigned getExpansionLineNumber(bool *Invalid = 0) const; + unsigned getExpansionColumnNumber(bool *Invalid = 0) const; unsigned getSpellingLineNumber(bool *Invalid = 0) const; unsigned getSpellingColumnNumber(bool *Invalid = 0) const; @@ -276,7 +290,7 @@ public: /// getBufferData - Return a StringRef to the source buffer data for the /// specified FileID. - llvm::StringRef getBufferData(bool *Invalid = 0) const; + StringRef getBufferData(bool *Invalid = 0) const; /// getDecomposedLoc - Decompose the specified location into a raw FileID + /// Offset pair. The first element is the FileID, the second is the @@ -326,8 +340,8 @@ public: /// PresumedLoc - This class represents an unpacked "presumed" location which /// can be presented to the user. A 'presumed' location can be modified by -/// #line and GNU line marker directives and is always the instantiation point -/// of a normal location. +/// #line and GNU line marker directives and is always the expansion point of +/// a normal location. /// /// You can get a PresumedLoc from a SourceLocation with SourceManager. class PresumedLoc { diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h index 6301f31..985ddd6 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SOURCEMANAGER_H #define LLVM_CLANG_SOURCEMANAGER_H +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/DataTypes.h" @@ -22,22 +23,37 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/MemoryBuffer.h" +#include <map> #include <vector> #include <cassert> -namespace llvm { -class StringRef; -} - namespace clang { -class Diagnostic; +class DiagnosticsEngine; class SourceManager; class FileManager; class FileEntry; class LineTableInfo; class LangOptions; - +class ASTWriter; +class ASTReader; + +/// There are three different types of locations in a file: a spelling +/// location, an expansion location, and a presumed location. +/// +/// Given an example of: +/// #define min(x, y) x < y ? x : y +/// +/// and then later on a use of min: +/// #line 17 +/// return min(a, b); +/// +/// The expansion location is the line in the source code where the macro +/// was expanded (the return statement), the spelling location is the +/// location in the source where the macro was originally defined, +/// and the presumed location is where the line directive states that +/// the line is 17, or any other line. + /// SrcMgr - Public enums and private classes that are part of the /// SourceManager implementation. /// @@ -46,7 +62,7 @@ namespace SrcMgr { /// holds normal user code, system code, or system code which is implicitly /// 'extern "C"' in C++ mode. Entire directories can be tagged with this /// (this is maintained by DirectoryLookup and friends) as can specific - /// FileIDInfos when a #pragma system_header is seen or various other cases. + /// FileInfos when a #pragma system_header is seen or various other cases. /// enum CharacteristicKind { C_User, C_System, C_ExternCSystem @@ -61,7 +77,7 @@ namespace SrcMgr { /// \brief Whether the buffer should not be freed on destruction. DoNotFreeFlag = 0x02 }; - + /// Buffer - The actual buffer containing the characters from the input /// file. This is owned by the ContentCache object. /// The bits indicate indicates whether the buffer is invalid. @@ -92,12 +108,12 @@ namespace SrcMgr { /// /// \param Diag Object through which diagnostics will be emitted if the /// buffer cannot be retrieved. - /// + /// /// \param Loc If specified, is the location that invalid file diagnostics /// will be emitted at. /// /// \param Invalid If non-NULL, will be set \c true if an error occurred. - const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag, + const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag, const SourceManager &SM, SourceLocation Loc = SourceLocation(), bool *Invalid = 0) const; @@ -109,10 +125,10 @@ namespace SrcMgr { unsigned getSize() const; /// getSizeBytesMapped - Returns the number of bytes actually mapped for - /// this ContentCache. This can be 0 if the MemBuffer was not actually - /// instantiated. + /// this ContentCache. This can be 0 if the MemBuffer was not actually + /// expanded. unsigned getSizeBytesMapped() const; - + /// Returns the kind of memory used to back the memory buffer for /// this content cache. This is used for performance analysis. llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const; @@ -122,7 +138,7 @@ namespace SrcMgr { Buffer.setPointer(B); Buffer.setInt(false); } - + /// \brief Get the underlying buffer, returning NULL if the buffer is not /// yet available. const llvm::MemoryBuffer *getRawBuffer() const { @@ -137,12 +153,12 @@ namespace SrcMgr { bool isBufferInvalid() const { return Buffer.getInt() & InvalidFlag; } - + /// \brief Determine whether the buffer should be freed. bool shouldFreeBuffer() const { return (Buffer.getInt() & DoNotFreeFlag) == 0; } - + ContentCache(const FileEntry *Ent = 0) : Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent), SourceLineCache(0), NumLines(0) {} @@ -156,14 +172,14 @@ namespace SrcMgr { /// The copy ctor does not allow copies where source object has either /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory /// is not transferred, so this is a logical error. - ContentCache(const ContentCache &RHS) - : Buffer(0, false), SourceLineCache(0) + ContentCache(const ContentCache &RHS) + : Buffer(0, false), SourceLineCache(0) { OrigEntry = RHS.OrigEntry; ContentsEntry = RHS.ContentsEntry; - assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 - && "Passed ContentCache object cannot own a buffer."); + assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 && + "Passed ContentCache object cannot own a buffer."); NumLines = RHS.NumLines; } @@ -177,8 +193,8 @@ namespace SrcMgr { /// that it represents and include stack information. /// /// Each FileInfo has include stack information, indicating where it came - /// from. This information encodes the #include chain that a token was - /// instantiated from. The main include file has an invalid IncludeLoc. + /// from. This information encodes the #include chain that a token was + /// expanded from. The main include file has an invalid IncludeLoc. /// /// FileInfos contain a "ContentCache *", with the contents of the file. /// @@ -187,16 +203,26 @@ namespace SrcMgr { /// This is an invalid SLOC for the main file (top of the #include chain). unsigned IncludeLoc; // Really a SourceLocation + /// \brief Number of FileIDs (files and macros) that were created during + /// preprocessing of this #include, including this SLocEntry. + /// Zero means the preprocessor didn't provide such info for this SLocEntry. + unsigned NumCreatedFIDs; + /// Data - This contains the ContentCache* and the bits indicating the /// characteristic of the file and whether it has #line info, all bitmangled /// together. uintptr_t Data; + + friend class clang::SourceManager; + friend class clang::ASTWriter; + friend class clang::ASTReader; public: /// get - Return a FileInfo object. static FileInfo get(SourceLocation IL, const ContentCache *Con, CharacteristicKind FileCharacter) { FileInfo X; X.IncludeLoc = IL.getRawEncoding(); + X.NumCreatedFIDs = 0; X.Data = (uintptr_t)Con; assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned"); assert((unsigned)FileCharacter < 4 && "invalid file character"); @@ -227,70 +253,68 @@ namespace SrcMgr { } }; - /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation - /// location - where the token was ultimately instantiated, and the - /// SpellingLoc - where the actual character data for the token came from. - class InstantiationInfo { - // Really these are all SourceLocations. + /// ExpansionInfo - Each ExpansionInfo encodes the expansion location - where + /// the token was ultimately expanded, and the SpellingLoc - where the actual + /// character data for the token came from. + class ExpansionInfo { + // Really these are all SourceLocations. /// SpellingLoc - Where the spelling for the token can be found. unsigned SpellingLoc; - /// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these - /// indicate the start and end of the instantiation. In object-like macros, - /// these will be the same. In a function-like macro instantiation, the - /// start will be the identifier and the end will be the ')'. Finally, in + /// ExpansionLocStart/ExpansionLocEnd - In a macro expansion, these + /// indicate the start and end of the expansion. In object-like macros, + /// these will be the same. In a function-like macro expansion, the start + /// will be the identifier and the end will be the ')'. Finally, in /// macro-argument instantitions, the end will be 'SourceLocation()', an /// invalid location. - unsigned InstantiationLocStart, InstantiationLocEnd; + unsigned ExpansionLocStart, ExpansionLocEnd; public: SourceLocation getSpellingLoc() const { return SourceLocation::getFromRawEncoding(SpellingLoc); } - SourceLocation getInstantiationLocStart() const { - return SourceLocation::getFromRawEncoding(InstantiationLocStart); + SourceLocation getExpansionLocStart() const { + return SourceLocation::getFromRawEncoding(ExpansionLocStart); } - SourceLocation getInstantiationLocEnd() const { + SourceLocation getExpansionLocEnd() const { SourceLocation EndLoc = - SourceLocation::getFromRawEncoding(InstantiationLocEnd); - return EndLoc.isInvalid() ? getInstantiationLocStart() : EndLoc; + SourceLocation::getFromRawEncoding(ExpansionLocEnd); + return EndLoc.isInvalid() ? getExpansionLocStart() : EndLoc; } - std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const { - return std::make_pair(getInstantiationLocStart(), - getInstantiationLocEnd()); + std::pair<SourceLocation,SourceLocation> getExpansionLocRange() const { + return std::make_pair(getExpansionLocStart(), getExpansionLocEnd()); } - bool isMacroArgInstantiation() const { + bool isMacroArgExpansion() const { // Note that this needs to return false for default constructed objects. - return getInstantiationLocStart().isValid() && - SourceLocation::getFromRawEncoding(InstantiationLocEnd).isInvalid(); + return getExpansionLocStart().isValid() && + SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid(); } - /// create - Return a InstantiationInfo for an expansion. ILStart and - /// ILEnd specify the instantiation range (where the macro is expanded), - /// and SL specifies the spelling location (where the characters from the - /// token come from). All three can refer to normal File SLocs or - /// instantiation locations. - static InstantiationInfo create(SourceLocation SL, - SourceLocation ILStart, - SourceLocation ILEnd) { - InstantiationInfo X; - X.SpellingLoc = SL.getRawEncoding(); - X.InstantiationLocStart = ILStart.getRawEncoding(); - X.InstantiationLocEnd = ILEnd.getRawEncoding(); + /// create - Return a ExpansionInfo for an expansion. Start and End specify + /// the expansion range (where the macro is expanded), and SpellingLoc + /// specifies the spelling location (where the characters from the token + /// come from). All three can refer to normal File SLocs or expansion + /// locations. + static ExpansionInfo create(SourceLocation SpellingLoc, + SourceLocation Start, SourceLocation End) { + ExpansionInfo X; + X.SpellingLoc = SpellingLoc.getRawEncoding(); + X.ExpansionLocStart = Start.getRawEncoding(); + X.ExpansionLocEnd = End.getRawEncoding(); return X; } - /// createForMacroArg - Return a special InstantiationInfo for the - /// expansion of a macro argument into a function-like macro's body. IL - /// specifies the instantiation location (where the macro is expanded). - /// This doesn't need to be a range because a macro is always instantiated - /// at a macro parameter reference, and macro parameters are always exactly - /// one token. SL specifies the spelling location (where the characters - /// from the token come from). IL and SL can both refer to normal File - /// SLocs or instantiation locations. + /// createForMacroArg - Return a special ExpansionInfo for the expansion of + /// a macro argument into a function-like macro's body. ExpansionLoc + /// specifies the expansion location (where the macro is expanded). This + /// doesn't need to be a range because a macro is always expanded at + /// a macro parameter reference, and macro parameters are always exactly + /// one token. SpellingLoc specifies the spelling location (where the + /// characters from the token come from). ExpansionLoc and SpellingLoc can + /// both refer to normal File SLocs or expansion locations. /// /// Given the code: /// \code @@ -298,41 +322,41 @@ namespace SrcMgr { /// F(42); /// \endcode /// - /// When expanding '\c F(42)', the '\c x' would call this with an SL - /// pointing at '\c 42' anad an IL pointing at its location in the - /// definition of '\c F'. - static InstantiationInfo createForMacroArg(SourceLocation SL, - SourceLocation IL) { + /// When expanding '\c F(42)', the '\c x' would call this with an + /// SpellingLoc pointing at '\c 42' anad an ExpansionLoc pointing at its + /// location in the definition of '\c F'. + static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc, + SourceLocation ExpansionLoc) { // We store an intentionally invalid source location for the end of the - // instantiation range to mark that this is a macro argument instantation - // rather than a normal one. - return create(SL, IL, SourceLocation()); + // expansion range to mark that this is a macro argument ion rather than + // a normal one. + return create(SpellingLoc, ExpansionLoc, SourceLocation()); } }; /// SLocEntry - This is a discriminated union of FileInfo and - /// InstantiationInfo. SourceManager keeps an array of these objects, and + /// ExpansionInfo. SourceManager keeps an array of these objects, and /// they are uniquely identified by the FileID datatype. class SLocEntry { - unsigned Offset; // low bit is set for instantiation info. + unsigned Offset; // low bit is set for expansion info. union { FileInfo File; - InstantiationInfo Instantiation; + ExpansionInfo Expansion; }; public: unsigned getOffset() const { return Offset >> 1; } - bool isInstantiation() const { return Offset & 1; } - bool isFile() const { return !isInstantiation(); } + bool isExpansion() const { return Offset & 1; } + bool isFile() const { return !isExpansion(); } const FileInfo &getFile() const { assert(isFile() && "Not a file SLocEntry!"); return File; } - const InstantiationInfo &getInstantiation() const { - assert(isInstantiation() && "Not an instantiation SLocEntry!"); - return Instantiation; + const ExpansionInfo &getExpansion() const { + assert(isExpansion() && "Not a macro expansion SLocEntry!"); + return Expansion; } static SLocEntry get(unsigned Offset, const FileInfo &FI) { @@ -342,10 +366,10 @@ namespace SrcMgr { return E; } - static SLocEntry get(unsigned Offset, const InstantiationInfo &II) { + static SLocEntry get(unsigned Offset, const ExpansionInfo &Expansion) { SLocEntry E; E.Offset = (Offset << 1) | 1; - E.Instantiation = II; + E.Expansion = Expansion; return E; } }; @@ -356,13 +380,14 @@ class ExternalSLocEntrySource { public: virtual ~ExternalSLocEntrySource(); - /// \brief Read the source location entry with index ID. + /// \brief Read the source location entry with index ID, which will always be + /// less than -1. /// /// \returns true if an error occurred that prevented the source-location /// entry from being loaded. - virtual bool ReadSLocEntry(unsigned ID) = 0; + virtual bool ReadSLocEntry(int ID) = 0; }; - + /// IsBeforeInTranslationUnitCache - This class holds the cache used by /// isBeforeInTranslationUnit. The cache structure is complex enough to be @@ -371,24 +396,28 @@ class IsBeforeInTranslationUnitCache { /// L/R QueryFID - These are the FID's of the cached query. If these match up /// with a subsequent query, the result can be reused. FileID LQueryFID, RQueryFID; - + + /// \brief True if LQueryFID was created before RQueryFID. This is used + /// to compare macro expansion locations. + bool IsLQFIDBeforeRQFID; + /// CommonFID - This is the file found in common between the two #include /// traces. It is the nearest common ancestor of the #include tree. FileID CommonFID; - + /// L/R CommonOffset - This is the offset of the previous query in CommonFID. /// Usually, this represents the location of the #include for QueryFID, but if /// LQueryFID is a parent of RQueryFID (or vise versa) then these can be a /// random token in the parent. unsigned LCommonOffset, RCommonOffset; public: - + /// isCacheValid - Return true if the currently cached values match up with /// the specified LHS/RHS query. If not, we can't use the cache. bool isCacheValid(FileID LHS, FileID RHS) const { return LQueryFID == LHS && RQueryFID == RHS; } - + /// getCachedResult - If the cache is valid, compute the result given the /// specified offsets in the LHS/RHS FID's. bool getCachedResult(unsigned LOffset, unsigned ROffset) const { @@ -396,38 +425,56 @@ public: // use the #include loc in the common file. if (LQueryFID != CommonFID) LOffset = LCommonOffset; if (RQueryFID != CommonFID) ROffset = RCommonOffset; + + // It is common for multiple macro expansions to be "included" from the same + // location (expansion location), in which case use the order of the FileIDs + // to determine which came first. This will also take care the case where + // one of the locations points at the inclusion/expansion point of the other + // in which case its FileID will come before the other. + if (LOffset == ROffset && + (LQueryFID != CommonFID || RQueryFID != CommonFID)) + return IsLQFIDBeforeRQFID; + return LOffset < ROffset; } - + // Set up a new query. - void setQueryFIDs(FileID LHS, FileID RHS) { + void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) { + assert(LHS != RHS); LQueryFID = LHS; RQueryFID = RHS; + IsLQFIDBeforeRQFID = isLFIDBeforeRFID; + } + + void clear() { + LQueryFID = RQueryFID = FileID(); + IsLQFIDBeforeRQFID = false; } - + void setCommonLoc(FileID commonFID, unsigned lCommonOffset, unsigned rCommonOffset) { CommonFID = commonFID; LCommonOffset = lCommonOffset; RCommonOffset = rCommonOffset; } - + }; -/// SourceManager - This file handles loading and caching of source files into -/// memory. This object owns the MemoryBuffer objects for all of the loaded +/// \brief This class handles loading and caching of source files into memory. +/// +/// This object owns the MemoryBuffer objects for all of the loaded /// files and assigns unique FileID's for each unique #include chain. /// /// The SourceManager can be queried for information about SourceLocation -/// objects, turning them into either spelling or instantiation locations. -/// Spelling locations represent where the bytes corresponding to a token came -/// from and instantiation locations represent where the location is in the -/// user's view. In the case of a macro expansion, for example, the spelling -/// location indicates where the expanded token came from and the instantiation -/// location specifies where it was expanded. +/// objects, turning them into either spelling or expansion locations. Spelling +/// locations represent where the bytes corresponding to a token came from and +/// expansion locations represent where the location is in the user's view. In +/// the case of a macro expansion, for example, the spelling location indicates +/// where the expanded token came from and the expansion location specifies +/// where it was expanded. class SourceManager : public llvm::RefCountedBase<SourceManager> { - /// \brief Diagnostic object. - Diagnostic &Diag; + /// \brief DiagnosticsEngine object. + DiagnosticsEngine &Diag; FileManager &FileMgr; @@ -451,16 +498,37 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> { /// as they do not refer to a file. std::vector<SrcMgr::ContentCache*> MemBufferInfos; - /// SLocEntryTable - This is an array of SLocEntry's that we have created. - /// FileID is an index into this vector. This array is sorted by the offset. - std::vector<SrcMgr::SLocEntry> SLocEntryTable; - /// NextOffset - This is the next available offset that a new SLocEntry can - /// start at. It is SLocEntryTable.back().getOffset()+size of back() entry. - unsigned NextOffset; + /// \brief The table of SLocEntries that are local to this module. + /// + /// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid + /// expansion. + std::vector<SrcMgr::SLocEntry> LocalSLocEntryTable; + + /// \brief The table of SLocEntries that are loaded from other modules. + /// + /// Negative FileIDs are indexes into this table. To get from ID to an index, + /// use (-ID - 2). + std::vector<SrcMgr::SLocEntry> LoadedSLocEntryTable; + + /// \brief The starting offset of the next local SLocEntry. + /// + /// This is LocalSLocEntryTable.back().Offset + the size of that entry. + unsigned NextLocalOffset; + + /// \brief The starting offset of the latest batch of loaded SLocEntries. + /// + /// This is LoadedSLocEntryTable.back().Offset, except that that entry might + /// not have been loaded, so that value would be unknown. + unsigned CurrentLoadedOffset; + + /// \brief The highest possible offset is 2^31-1, so CurrentLoadedOffset + /// starts at 2^31. + static const unsigned MaxLoadedOffset = 1U << 31U; - /// \brief If source location entries are being lazily loaded from - /// an external source, this vector indicates whether the Ith source - /// location entry has already been loaded from the external storage. + /// \brief A bitmap that indicates whether the entries of LoadedSLocEntryTable + /// have already been loaded from the external source. + /// + /// Same indexing as LoadedSLocEntryTable. std::vector<bool> SLocEntryLoaded; /// \brief An external source for source location entries. @@ -485,6 +553,9 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> { /// MainFileID - The file ID for the main source file of the translation unit. FileID MainFileID; + /// \brief The file ID for the precompiled preamble there is one. + FileID PreambleFileID; + // Statistics for -print-stats. mutable unsigned NumLinearScans, NumBinaryProbes; @@ -493,17 +564,23 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> { // Cache for the "fake" buffer used for error-recovery purposes. mutable llvm::MemoryBuffer *FakeBufferForRecovery; - + + /// \brief Lazily computed map of macro argument chunks to their expanded + /// source location. + typedef std::map<unsigned, SourceLocation> MacroArgsMap; + + mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap; + // SourceManager doesn't support copy construction. explicit SourceManager(const SourceManager&); void operator=(const SourceManager&); public: - SourceManager(Diagnostic &Diag, FileManager &FileMgr); + SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr); ~SourceManager(); void clearIDTables(); - Diagnostic &getDiagnostics() const { return Diag; } + DiagnosticsEngine &getDiagnostics() const { return Diag; } FileManager &getFileManager() const { return FileMgr; } @@ -513,6 +590,15 @@ public: OverridenFilesKeepOriginalName = value; } + /// createMainFileIDForMembuffer - Create the FileID for a memory buffer + /// that will represent the FileID for the main source. One example + /// of when this would be used is when the main source is read from STDIN. + FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { + assert(MainFileID.isInvalid() && "MainFileID already set!"); + MainFileID = createFileIDForMemBuffer(Buffer); + return MainFileID; + } + //===--------------------------------------------------------------------===// // MainFileID creation and querying methods. //===--------------------------------------------------------------------===// @@ -527,67 +613,56 @@ public: return MainFileID; } - /// \brief Set the file ID for the precompiled preamble, which is also the - /// main file. - void SetPreambleFileID(FileID Preamble) { - assert(MainFileID.isInvalid() && "MainFileID already set!"); - MainFileID = Preamble; + /// \brief Set the file ID for the precompiled preamble. + void setPreambleFileID(FileID Preamble) { + assert(PreambleFileID.isInvalid() && "PreambleFileID already set!"); + PreambleFileID = Preamble; } - + + /// \brief Get the file ID for the precompiled preamble if there is one. + FileID getPreambleFileID() const { return PreambleFileID; } + //===--------------------------------------------------------------------===// - // Methods to create new FileID's and instantiations. + // Methods to create new FileID's and macro expansions. //===--------------------------------------------------------------------===// /// createFileID - Create a new FileID that represents the specified file /// being #included from the specified IncludePosition. This translates NULL /// into standard input. - /// PreallocateID should be non-zero to specify which pre-allocated, - /// lazily computed source location is being filled in by this operation. FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, - unsigned PreallocatedID = 0, - unsigned Offset = 0) { + int LoadedID = 0, unsigned LoadedOffset = 0) { const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile); assert(IR && "getOrCreateContentCache() cannot return NULL"); - return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset); + return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset); } /// createFileIDForMemBuffer - Create a new FileID that represents the /// specified memory buffer. This does no caching of the buffer and takes /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once. FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer, - unsigned PreallocatedID = 0, - unsigned Offset = 0) { + int LoadedID = 0, unsigned LoadedOffset = 0) { return createFileID(createMemBufferContentCache(Buffer), SourceLocation(), - SrcMgr::C_User, PreallocatedID, Offset); + SrcMgr::C_User, LoadedID, LoadedOffset); } - /// createMainFileIDForMembuffer - Create the FileID for a memory buffer - /// that will represent the FileID for the main source. One example - /// of when this would be used is when the main source is read from STDIN. - FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { - assert(MainFileID.isInvalid() && "MainFileID already set!"); - MainFileID = createFileIDForMemBuffer(Buffer); - return MainFileID; - } - - /// createMacroArgInstantiationLoc - Return a new SourceLocation that encodes - /// the fact that a token from SpellingLoc should actually be referenced from - /// InstantiationLoc, and that it represents the instantiation of a macro - /// argument into the function-like macro body. - SourceLocation createMacroArgInstantiationLoc(SourceLocation Loc, - SourceLocation InstantiationLoc, - unsigned TokLength); + /// createMacroArgExpansionLoc - Return a new SourceLocation that encodes the + /// fact that a token from SpellingLoc should actually be referenced from + /// ExpansionLoc, and that it represents the expansion of a macro argument + /// into the function-like macro body. + SourceLocation createMacroArgExpansionLoc(SourceLocation Loc, + SourceLocation ExpansionLoc, + unsigned TokLength); - /// createInstantiationLoc - Return a new SourceLocation that encodes the fact + /// createExpansionLoc - Return a new SourceLocation that encodes the fact /// that a token from SpellingLoc should actually be referenced from - /// InstantiationLoc. - SourceLocation createInstantiationLoc(SourceLocation Loc, - SourceLocation InstantiationLocStart, - SourceLocation InstantiationLocEnd, - unsigned TokLength, - unsigned PreallocatedID = 0, - unsigned Offset = 0); + /// ExpansionLoc. + SourceLocation createExpansionLoc(SourceLocation Loc, + SourceLocation ExpansionLocStart, + SourceLocation ExpansionLocEnd, + unsigned TokLength, + int LoadedID = 0, + unsigned LoadedOffset = 0); /// \brief Retrieve the memory buffer associated with the given file. /// @@ -633,11 +708,11 @@ public: if (MyInvalid || !Entry.isFile()) { if (Invalid) *Invalid = true; - + return getFakeBufferForRecovery(); } - - return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc, + + return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc, Invalid); } @@ -647,22 +722,22 @@ public: if (MyInvalid || !Entry.isFile()) { if (Invalid) *Invalid = true; - + return getFakeBufferForRecovery(); } - return Entry.getFile().getContentCache()->getBuffer(Diag, *this, - SourceLocation(), + return Entry.getFile().getContentCache()->getBuffer(Diag, *this, + SourceLocation(), Invalid); } - + /// getFileEntryForID - Returns the FileEntry record for the provided FileID. const FileEntry *getFileEntryForID(FileID FID) const { bool MyInvalid = false; const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); if (MyInvalid || !Entry.isFile()) return 0; - + return Entry.getFile().getContentCache()->OrigEntry; } @@ -677,8 +752,30 @@ public: /// /// \param FID The file ID whose contents will be returned. /// \param Invalid If non-NULL, will be set true if an error occurred. - llvm::StringRef getBufferData(FileID FID, bool *Invalid = 0) const; + StringRef getBufferData(FileID FID, bool *Invalid = 0) const; + /// \brief Get the number of FileIDs (files and macros) that were created + /// during preprocessing of \arg FID, including it. + unsigned getNumCreatedFIDsForFileID(FileID FID) const { + bool Invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); + if (Invalid || !Entry.isFile()) + return 0; + + return Entry.getFile().NumCreatedFIDs; + } + + /// \brief Set the number of FileIDs (files and macros) that were created + /// during preprocessing of \arg FID, including it. + void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const { + bool Invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); + if (Invalid || !Entry.isFile()) + return; + + assert(Entry.getFile().NumCreatedFIDs == 0 && "Already set!"); + const_cast<SrcMgr::FileInfo &>(Entry.getFile()).NumCreatedFIDs = NumFIDs; + } //===--------------------------------------------------------------------===// // SourceLocation manipulation methods. @@ -702,34 +799,52 @@ public: /// getLocForStartOfFile - Return the source location corresponding to the /// first byte of the specified file. SourceLocation getLocForStartOfFile(FileID FID) const { - assert(FID.ID < SLocEntryTable.size() && "FileID out of range"); bool Invalid = false; const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); if (Invalid || !Entry.isFile()) return SourceLocation(); - + unsigned FileOffset = Entry.getOffset(); return SourceLocation::getFileLoc(FileOffset); } - /// getInstantiationLoc - Given a SourceLocation object, return the - /// instantiation location referenced by the ID. - SourceLocation getInstantiationLoc(SourceLocation Loc) const { + /// \brief Returns the include location if \arg FID is a #include'd file + /// otherwise it returns an invalid location. + SourceLocation getIncludeLoc(FileID FID) const { + bool Invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); + if (Invalid || !Entry.isFile()) + return SourceLocation(); + + return Entry.getFile().getIncludeLoc(); + } + + /// getExpansionLoc - Given a SourceLocation object, return the expansion + /// location referenced by the ID. + SourceLocation getExpansionLoc(SourceLocation Loc) const { // Handle the non-mapped case inline, defer to out of line code to handle - // instantiations. + // expansions. if (Loc.isFileID()) return Loc; - return getInstantiationLocSlowCase(Loc); + return getExpansionLocSlowCase(Loc); } - /// getImmediateInstantiationRange - Loc is required to be an instantiation - /// location. Return the start/end of the instantiation information. + /// \brief Given \arg Loc, if it is a macro location return the expansion + /// location or the spelling location, depending on if it comes from a + /// macro argument or not. + SourceLocation getFileLoc(SourceLocation Loc) const { + if (Loc.isFileID()) return Loc; + return getFileLocSlowCase(Loc); + } + + /// getImmediateExpansionRange - Loc is required to be an expansion location. + /// Return the start/end of the expansion information. std::pair<SourceLocation,SourceLocation> - getImmediateInstantiationRange(SourceLocation Loc) const; + getImmediateExpansionRange(SourceLocation Loc) const; - /// getInstantiationRange - Given a SourceLocation object, return the - /// range of tokens covered by the instantiation in the ultimate file. + /// getExpansionRange - Given a SourceLocation object, return the range of + /// tokens covered by the expansion the ultimate file. std::pair<SourceLocation,SourceLocation> - getInstantiationRange(SourceLocation Loc) const; + getExpansionRange(SourceLocation Loc) const; /// getSpellingLoc - Given a SourceLocation object, return the spelling @@ -737,7 +852,7 @@ public: /// that make up the lexed token can be found. SourceLocation getSpellingLoc(SourceLocation Loc) const { // Handle the non-mapped case inline, defer to out of line code to handle - // instantiations. + // expansions. if (Loc.isFileID()) return Loc; return getSpellingLocSlowCase(Loc); } @@ -756,11 +871,11 @@ public: return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset()); } - /// getDecomposedInstantiationLoc - Decompose the specified location into a - /// raw FileID + Offset pair. If the location is an instantiation record, - /// walk through it until we find the final location instantiated. + /// getDecomposedExpansionLoc - Decompose the specified location into a raw + /// FileID + Offset pair. If the location is an expansion record, walk + /// through it until we find the final location expanded. std::pair<FileID, unsigned> - getDecomposedInstantiationLoc(SourceLocation Loc) const { + getDecomposedExpansionLoc(SourceLocation Loc) const { FileID FID = getFileID(Loc); const SrcMgr::SLocEntry *E = &getSLocEntry(FID); @@ -768,11 +883,11 @@ public: if (Loc.isFileID()) return std::make_pair(FID, Offset); - return getDecomposedInstantiationLocSlowCase(E); + return getDecomposedExpansionLocSlowCase(E); } /// getDecomposedSpellingLoc - Decompose the specified location into a raw - /// FileID + Offset pair. If the location is an instantiation record, walk + /// FileID + Offset pair. If the location is an expansion record, walk /// through it until we find its spelling record. std::pair<FileID, unsigned> getDecomposedSpellingLoc(SourceLocation Loc) const { @@ -792,12 +907,55 @@ public: return getDecomposedLoc(SpellingLoc).second; } - /// isMacroArgInstantiation - This method tests whether the given source - /// location represents a macro argument's instantiation into the - /// function-like macro definition. Such source locations only appear inside - /// of the instantiation locations representing where a particular - /// function-like macro was expanded. - bool isMacroArgInstantiation(SourceLocation Loc) const; + /// isMacroArgExpansion - This method tests whether the given source location + /// represents a macro argument's expansion into the function-like macro + /// definition. Such source locations only appear inside of the expansion + /// locations representing where a particular function-like macro was + /// expanded. + bool isMacroArgExpansion(SourceLocation Loc) const; + + /// \brief Returns true if \arg Loc is inside the [\arg Start, +\arg Length) + /// chunk of the source location address space. + /// If it's true and \arg RelativeOffset is non-null, it will be set to the + /// relative offset of \arg Loc inside the chunk. + bool isInSLocAddrSpace(SourceLocation Loc, + SourceLocation Start, unsigned Length, + unsigned *RelativeOffset = 0) const { + assert(((Start.getOffset() < NextLocalOffset && + Start.getOffset()+Length <= NextLocalOffset) || + (Start.getOffset() >= CurrentLoadedOffset && + Start.getOffset()+Length < MaxLoadedOffset)) && + "Chunk is not valid SLoc address space"); + unsigned LocOffs = Loc.getOffset(); + unsigned BeginOffs = Start.getOffset(); + unsigned EndOffs = BeginOffs + Length; + if (LocOffs >= BeginOffs && LocOffs < EndOffs) { + if (RelativeOffset) + *RelativeOffset = LocOffs - BeginOffs; + return true; + } + + return false; + } + + /// \brief Return true if both \arg LHS and \arg RHS are in the local source + /// location address space or the loaded one. If it's true and + /// \arg RelativeOffset is non-null, it will be set to the offset of \arg RHS + /// relative to \arg LHS. + bool isInSameSLocAddrSpace(SourceLocation LHS, SourceLocation RHS, + int *RelativeOffset) const { + unsigned LHSOffs = LHS.getOffset(), RHSOffs = RHS.getOffset(); + bool LHSLoaded = LHSOffs >= CurrentLoadedOffset; + bool RHSLoaded = RHSOffs >= CurrentLoadedOffset; + + if (LHSLoaded == RHSLoaded) { + if (RelativeOffset) + *RelativeOffset = RHSOffs - LHSOffs; + return true; + } + + return false; + } //===--------------------------------------------------------------------===// // Queries about the code at a SourceLocation. @@ -811,14 +969,14 @@ public: /// getColumnNumber - Return the column # for the specified file position. /// This is significantly cheaper to compute than the line number. This - /// returns zero if the column number isn't known. This may only be called on - /// a file sloc, so you must choose a spelling or instantiation location + /// returns zero if the column number isn't known. This may only be called + /// on a file sloc, so you must choose a spelling or expansion location /// before calling this method. - unsigned getColumnNumber(FileID FID, unsigned FilePos, + unsigned getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const; unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid = 0) const; - unsigned getInstantiationColumnNumber(SourceLocation Loc, - bool *Invalid = 0) const; + unsigned getExpansionColumnNumber(SourceLocation Loc, + bool *Invalid = 0) const; unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid = 0) const; @@ -828,8 +986,7 @@ public: /// about to emit a diagnostic. unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const; unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const; - unsigned getInstantiationLineNumber(SourceLocation Loc, - bool *Invalid = 0) const; + unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = 0) const; unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = 0) const; /// Return the filename or buffer identifier of the buffer the location is in. @@ -852,8 +1009,8 @@ public: /// or GNU line marker directives. This provides a view on the data that a /// user should see in diagnostics, for example. /// - /// Note that a presumed location is always given as the instantiation point - /// of an instantiation location, not at the spelling location. + /// Note that a presumed location is always given as the expansion point of + /// an expansion location, not at the spelling location. /// /// \returns The presumed location of the specified SourceLocation. If the /// presumed location cannot be calculate (e.g., because \p Loc is invalid @@ -884,33 +1041,18 @@ public: return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem; } - /// \brief Given a specific chunk of a FileID (FileID with offset+length), - /// returns true if \arg Loc is inside that chunk and sets relative offset - /// (offset of \arg Loc from beginning of chunk) to \arg relativeOffset. - bool isInFileID(SourceLocation Loc, - FileID FID, unsigned offset, unsigned length, - unsigned *relativeOffset = 0) const { - assert(!FID.isInvalid()); - if (Loc.isInvalid()) - return false; - - unsigned start = getSLocEntry(FID).getOffset() + offset; - unsigned end = start + length; - -#ifndef NDEBUG - // Make sure offset/length describe a chunk inside the given FileID. - unsigned NextOffset; - if (FID.ID+1 == SLocEntryTable.size()) - NextOffset = getNextOffset(); - else - NextOffset = getSLocEntry(FID.ID+1).getOffset(); - assert(start < NextOffset); - assert(end < NextOffset); -#endif - - if (Loc.getOffset() >= start && Loc.getOffset() < end) { - if (relativeOffset) - *relativeOffset = Loc.getOffset() - start; + /// \brief The size of the SLocEnty that \arg FID represents. + unsigned getFileIDSize(FileID FID) const; + + /// \brief Given a specific FileID, returns true if \arg Loc is inside that + /// FileID chunk and sets relative offset (offset of \arg Loc from beginning + /// of FileID) to \arg relativeOffset. + bool isInFileID(SourceLocation Loc, FileID FID, + unsigned *RelativeOffset = 0) const { + unsigned Offs = Loc.getOffset(); + if (isOffsetInFileID(FID, Offs)) { + if (RelativeOffset) + *RelativeOffset = Offs - getSLocEntry(FID).getOffset(); return true; } @@ -923,7 +1065,7 @@ public: /// getLineTableFilenameID - Return the uniqued ID for the specified filename. /// - unsigned getLineTableFilenameID(llvm::StringRef Str); + unsigned getLineTableFilenameID(StringRef Str); /// AddLineNote - Add a line note to the line table for the FileID and offset /// specified by Loc. If FilenameID is -1, it is considered to be @@ -948,11 +1090,11 @@ public: size_t getContentCacheSize() const { return ContentCacheAlloc.getTotalMemory(); } - + struct MemoryBufferSizes { const size_t malloc_bytes; const size_t mmap_bytes; - + MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes) : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} }; @@ -961,6 +1103,10 @@ public: /// by heap-backed versus mmap'ed memory. MemoryBufferSizes getMemoryBufferSizes() const; + // Return the amount of memory used for various side tables and + // data structures in the SourceManager. + size_t getDataStructureSizes() const; + //===--------------------------------------------------------------------===// // Other miscellaneous methods. //===--------------------------------------------------------------------===// @@ -969,25 +1115,67 @@ public: /// /// If the source file is included multiple times, the source location will /// be based upon the first inclusion. - SourceLocation getLocation(const FileEntry *SourceFile, - unsigned Line, unsigned Col); + SourceLocation translateFileLineCol(const FileEntry *SourceFile, + unsigned Line, unsigned Col) const; + + /// \brief Get the FileID for the given file. + /// + /// If the source file is included multiple times, the FileID will be the + /// first inclusion. + FileID translateFile(const FileEntry *SourceFile) const; + + /// \brief Get the source location in \arg FID for the given line:col. + /// Returns null location if \arg FID is not a file SLocEntry. + SourceLocation translateLineCol(FileID FID, + unsigned Line, unsigned Col) const; + + /// \brief If \arg Loc points inside a function macro argument, the returned + /// location will be the macro location in which the argument was expanded. + /// If a macro argument is used multiple times, the expanded location will + /// be at the first expansion of the argument. + /// e.g. + /// MY_MACRO(foo); + /// ^ + /// Passing a file location pointing at 'foo', will yield a macro location + /// where 'foo' was expanded into. + SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const; /// \brief Determines the order of 2 source locations in the translation unit. /// /// \returns true if LHS source location comes before RHS, false otherwise. bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const; + /// \brief Comparison function class. + class LocBeforeThanCompare : public std::binary_function<SourceLocation, + SourceLocation, bool> { + SourceManager &SM; + + public: + explicit LocBeforeThanCompare(SourceManager &SM) : SM(SM) { } + + bool operator()(SourceLocation LHS, SourceLocation RHS) const { + return SM.isBeforeInTranslationUnit(LHS, RHS); + } + }; + /// \brief Determines the order of 2 source locations in the "source location /// address space". - static bool isBeforeInSourceLocationOffset(SourceLocation LHS, - SourceLocation RHS) { - return isBeforeInSourceLocationOffset(LHS, RHS.getOffset()); + bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const { + return isBeforeInSLocAddrSpace(LHS, RHS.getOffset()); } /// \brief Determines the order of a source location and a source location /// offset in the "source location address space". - static bool isBeforeInSourceLocationOffset(SourceLocation LHS, unsigned RHS) { - return LHS.getOffset() < RHS; + /// + /// Note that we always consider source locations loaded from + bool isBeforeInSLocAddrSpace(SourceLocation LHS, unsigned RHS) const { + unsigned LHSOffset = LHS.getOffset(); + bool LHSLoaded = LHSOffset >= CurrentLoadedOffset; + bool RHSLoaded = RHS >= CurrentLoadedOffset; + if (LHSLoaded == RHSLoaded) + return LHSOffset < RHS; + + return LHSLoaded; } // Iterators over FileInfos. @@ -1003,53 +1191,80 @@ public: /// void PrintStats() const; - unsigned sloc_entry_size() const { return SLocEntryTable.size(); } - - // FIXME: Exposing this is a little gross; what we want is a good way - // to iterate the entries that were not defined in an AST file (or - // any other external source). - unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); } - - const SrcMgr::SLocEntry &getSLocEntry(unsigned ID, bool *Invalid = 0) const { - assert(ID < SLocEntryTable.size() && "Invalid id"); - // If we haven't loaded this source-location entry from the external source - // yet, do so now. - if (ExternalSLocEntries && - ID < SLocEntryLoaded.size() && - !SLocEntryLoaded[ID] && - ExternalSLocEntries->ReadSLocEntry(ID) && - Invalid) - *Invalid = true; - - return SLocEntryTable[ID]; + /// \brief Get the number of local SLocEntries we have. + unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); } + + /// \brief Get a local SLocEntry. This is exposed for indexing. + const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index, + bool *Invalid = 0) const { + assert(Index < LocalSLocEntryTable.size() && "Invalid index"); + return LocalSLocEntryTable[Index]; + } + + /// \brief Get the number of loaded SLocEntries we have. + unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();} + + /// \brief Get a loaded SLocEntry. This is exposed for indexing. + const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index, bool *Invalid=0) const { + assert(Index < LoadedSLocEntryTable.size() && "Invalid index"); + if (!SLocEntryLoaded[Index]) + ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2)); + return LoadedSLocEntryTable[Index]; } const SrcMgr::SLocEntry &getSLocEntry(FileID FID, bool *Invalid = 0) const { - return getSLocEntry(FID.ID, Invalid); + return getSLocEntryByID(FID.ID); } - unsigned getNextOffset() const { return NextOffset; } + unsigned getNextLocalOffset() const { return NextLocalOffset; } + + void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) { + assert(LoadedSLocEntryTable.empty() && + "Invalidating existing loaded entries"); + ExternalSLocEntries = Source; + } - /// \brief Preallocate some number of source location entries, which - /// will be loaded as needed from the given external source. - void PreallocateSLocEntries(ExternalSLocEntrySource *Source, - unsigned NumSLocEntries, - unsigned NextOffset); + /// \brief Allocate a number of loaded SLocEntries, which will be actually + /// loaded on demand from the external source. + /// + /// NumSLocEntries will be allocated, which occupy a total of TotalSize space + /// in the global source view. The lowest ID and the base offset of the + /// entries will be returned. + std::pair<int, unsigned> + AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize); + + /// \brief Returns true if \arg Loc came from a PCH/Module. + bool isLoadedSourceLocation(SourceLocation Loc) const { + return Loc.getOffset() >= CurrentLoadedOffset; + } - /// \brief Clear out any preallocated source location entries that - /// haven't already been loaded. - void ClearPreallocatedSLocEntries(); + /// \brief Returns true if \arg Loc did not come from a PCH/Module. + bool isLocalSourceLocation(SourceLocation Loc) const { + return Loc.getOffset() < NextLocalOffset; + } private: const llvm::MemoryBuffer *getFakeBufferForRecovery() const; - /// createInstantiationLoc - Implements the common elements of storing an - /// instantiation info struct into the SLocEntry table and producing a source + /// \brief Get the entry with the given unwrapped FileID. + const SrcMgr::SLocEntry &getSLocEntryByID(int ID) const { + assert(ID != -1 && "Using FileID sentinel value"); + if (ID < 0) + return getLoadedSLocEntryByID(ID); + return getLocalSLocEntry(static_cast<unsigned>(ID)); + } + + const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID) const { + return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2)); + } + + /// createExpansionLoc - Implements the common elements of storing an + /// expansion info struct into the SLocEntry table and producing a source /// location that refers to it. - SourceLocation createInstantiationLocImpl(const SrcMgr::InstantiationInfo &II, - unsigned TokLength, - unsigned PreallocatedID = 0, - unsigned Offset = 0); + SourceLocation createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion, + unsigned TokLength, + int LoadedID = 0, + unsigned LoadedOffset = 0); /// isOffsetInFileID - Return true if the specified FileID contains the /// specified SourceLocation offset. This is a very hot method. @@ -1058,10 +1273,17 @@ private: // If the entry is after the offset, it can't contain it. if (SLocOffset < Entry.getOffset()) return false; - // If this is the last entry than it does. Otherwise, the entry after it - // has to not include it. - if (FID.ID+1 == SLocEntryTable.size()) return true; + // If this is the very last entry then it does. + if (FID.ID == -2) + return true; + + // If it is the last local entry, then it does if the location is local. + if (static_cast<unsigned>(FID.ID+1) == LocalSLocEntryTable.size()) { + return SLocOffset < NextLocalOffset; + } + // Otherwise, the entry after it has to not include it. This works for both + // local and loaded entries. return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset(); } @@ -1071,8 +1293,7 @@ private: FileID createFileID(const SrcMgr::ContentCache* File, SourceLocation IncludePos, SrcMgr::CharacteristicKind DirCharacter, - unsigned PreallocatedID = 0, - unsigned Offset = 0); + int LoadedID, unsigned LoadedOffset); const SrcMgr::ContentCache * getOrCreateContentCache(const FileEntry *SourceFile); @@ -1083,15 +1304,22 @@ private: createMemBufferContentCache(const llvm::MemoryBuffer *Buf); FileID getFileIDSlow(unsigned SLocOffset) const; + FileID getFileIDLocal(unsigned SLocOffset) const; + FileID getFileIDLoaded(unsigned SLocOffset) const; - SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const; + SourceLocation getExpansionLocSlowCase(SourceLocation Loc) const; SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; + SourceLocation getFileLocSlowCase(SourceLocation Loc) const; std::pair<FileID, unsigned> - getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E) const; + getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const; std::pair<FileID, unsigned> getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, unsigned Offset) const; + void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const; + + friend class ASTReader; + friend class ASTWriter; }; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceManagerInternals.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceManagerInternals.h index 3f5d1a3..1cb16b4 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceManagerInternals.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceManagerInternals.h @@ -84,7 +84,7 @@ class LineTableInfo { /// LineEntries - This is a map from FileIDs to a list of line entries (sorted /// by the offset they occur in the file. - std::map<unsigned, std::vector<LineEntry> > LineEntries; + std::map<int, std::vector<LineEntry> > LineEntries; public: LineTableInfo() { } @@ -97,32 +97,32 @@ public: ~LineTableInfo() {} - unsigned getLineTableFilenameID(llvm::StringRef Str); + unsigned getLineTableFilenameID(StringRef Str); const char *getFilename(unsigned ID) const { assert(ID < FilenamesByID.size() && "Invalid FilenameID"); return FilenamesByID[ID]->getKeyData(); } unsigned getNumFilenames() const { return FilenamesByID.size(); } - void AddLineNote(unsigned FID, unsigned Offset, + void AddLineNote(int FID, unsigned Offset, unsigned LineNo, int FilenameID); - void AddLineNote(unsigned FID, unsigned Offset, + void AddLineNote(int FID, unsigned Offset, unsigned LineNo, int FilenameID, unsigned EntryExit, SrcMgr::CharacteristicKind FileKind); /// FindNearestLineEntry - Find the line entry nearest to FID that is before /// it. If there is no line entry before Offset in FID, return null. - const LineEntry *FindNearestLineEntry(unsigned FID, unsigned Offset); + const LineEntry *FindNearestLineEntry(int FID, unsigned Offset); // Low-level access - typedef std::map<unsigned, std::vector<LineEntry> >::iterator iterator; + typedef std::map<int, std::vector<LineEntry> >::iterator iterator; iterator begin() { return LineEntries.begin(); } iterator end() { return LineEntries.end(); } /// \brief Add a new line entry that has already been encoded into /// the internal representation of the line table. - void AddEntry(unsigned FID, const std::vector<LineEntry> &Entries); + void AddEntry(int FID, const std::vector<LineEntry> &Entries); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h index cfce0cc..2a95d61 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h @@ -40,6 +40,7 @@ namespace clang { TST_char16, // C++0x char16_t TST_char32, // C++0x char32_t TST_int, + TST_half, // OpenCL half, ARM NEON __fp16 TST_float, TST_double, TST_bool, // _Bool @@ -57,6 +58,7 @@ namespace clang { TST_underlyingType, // __underlying_type for C++0x TST_auto, // C++0x auto TST_unknown_anytype, // __unknown_anytype extension + TST_atomic, // C1X _Atomic TST_error // erroneous type }; @@ -146,6 +148,7 @@ namespace clang { SC_PrivateExtern, // These are only legal on variables. + SC_OpenCLWorkGroupLocal, SC_Auto, SC_Register }; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td index 73996e4..7b3d776 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td @@ -78,6 +78,9 @@ def ParenListExpr : DStmt<Expr>; def VAArgExpr : DStmt<Expr>; def GenericSelectionExpr : DStmt<Expr>; +// Atomic expressions +def AtomicExpr : DStmt<Expr>; + // GNU Extensions. def AddrLabelExpr : DStmt<Expr>; def StmtExpr : DStmt<Expr>; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h index 4559cf2..a87af2f 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_BASIC_TARGETINFO_H #define LLVM_CLANG_BASIC_TARGETINFO_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -31,7 +32,7 @@ struct fltSemantics; } namespace clang { -class Diagnostic; +class DiagnosticsEngine; class LangOptions; class MacroBuilder; class SourceLocation; @@ -68,21 +69,24 @@ protected: unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; unsigned char IntWidth, IntAlign; + unsigned char HalfWidth, HalfAlign; unsigned char FloatWidth, FloatAlign; unsigned char DoubleWidth, DoubleAlign; unsigned char LongDoubleWidth, LongDoubleAlign; unsigned char LargeArrayMinWidth, LargeArrayAlign; unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; + unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; const char *DescriptionString; const char *UserLabelPrefix; const char *MCountName; - const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat; + const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, + *LongDoubleFormat; unsigned char RegParmMax, SSERegParmMax; TargetCXXABI CXXABI; const LangAS::Map *AddrSpaceMap; - mutable llvm::StringRef PlatformName; + mutable StringRef PlatformName; mutable VersionTuple PlatformMinVersion; unsigned HasAlignMac68kSupport : 1; @@ -97,7 +101,8 @@ public: /// \param Opts - The options to use to initialize the target. The target may /// modify the options to canonicalize the target feature information to match /// what the backend expects. - static TargetInfo* CreateTargetInfo(Diagnostic &Diags, TargetOptions &Opts); + static TargetInfo* CreateTargetInfo(DiagnosticsEngine &Diags, + TargetOptions &Opts); virtual ~TargetInfo(); @@ -131,6 +136,16 @@ protected: /// boundary. unsigned UseBitFieldTypeAlignment : 1; + /// Control whether zero length bitfields (e.g., int : 0;) force alignment of + /// the next bitfield. If the alignment of the zero length bitfield is + /// greater than the member that follows it, `bar', `bar' will be aligned as + /// the type of the zero-length bitfield. + unsigned UseZeroLengthBitfieldAlignment : 1; + + /// If non-zero, specifies a fixed alignment value for bitfields that follow + /// zero length bitfield, regardless of the zero length bitfield type. + unsigned ZeroLengthBitfieldBoundary; + public: IntType getSizeType() const { return SizeType; } IntType getIntMaxType() const { return IntMaxType; } @@ -211,6 +226,11 @@ public: unsigned getChar32Width() const { return getTypeWidth(Char32Type); } unsigned getChar32Align() const { return getTypeAlign(Char32Type); } + /// getHalfWidth/Align/Format - Return the size/align/format of 'half'. + unsigned getHalfWidth() const { return HalfWidth; } + unsigned getHalfAlign() const { return HalfAlign; } + const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; } + /// getFloatWidth/Align/Format - Return the size/align/format of 'float'. unsigned getFloatWidth() const { return FloatWidth; } unsigned getFloatAlign() const { return FloatAlign; } @@ -234,6 +254,14 @@ public: unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; } unsigned getLargeArrayAlign() const { return LargeArrayAlign; } + /// getMaxAtomicPromoteWidth - Return the maximum width lock-free atomic + /// operation which will ever be supported for the given target + unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; } + /// getMaxAtomicInlineWidth - Return the maximum width lock-free atomic + /// operation which can be inlined given the supported features of the + /// given target. + unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; } + /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this /// target, in bits. unsigned getIntMaxTWidth() const { @@ -261,10 +289,24 @@ public: return MCountName; } + /// useBitFieldTypeAlignment() - Check whether the alignment of bit-field + /// types is respected when laying out structures. bool useBitFieldTypeAlignment() const { return UseBitFieldTypeAlignment; } + /// useZeroLengthBitfieldAlignment() - Check whether zero length bitfields + /// should force alignment of the next member. + bool useZeroLengthBitfieldAlignment() const { + return UseZeroLengthBitfieldAlignment; + } + + /// getZeroLengthBitfieldBoundary() - Get the fixed alignment value in bits + /// for a member that follows a zero length bitfield. + unsigned getZeroLengthBitfieldBoundary() const { + return ZeroLengthBitfieldBoundary; + } + /// hasAlignMac68kSupport - Check whether this target support '#pragma options /// align=mac68k'. bool hasAlignMac68kSupport() const { @@ -306,16 +348,16 @@ public: /// isValidClobber - Returns whether the passed in string is /// a valid clobber in an inline asm statement. This is used by /// Sema. - bool isValidClobber(llvm::StringRef Name) const; + bool isValidClobber(StringRef Name) const; /// isValidGCCRegisterName - Returns whether the passed in string /// is a valid register name according to GCC. This is used by Sema for /// inline asm statements. - bool isValidGCCRegisterName(llvm::StringRef Name) const; + bool isValidGCCRegisterName(StringRef Name) const; // getNormalizedGCCRegisterName - Returns the "normalized" GCC register name. // For example, on x86 it will return "ax" when "eax" is passed in. - llvm::StringRef getNormalizedGCCRegisterName(llvm::StringRef Name) const; + StringRef getNormalizedGCCRegisterName(StringRef Name) const; struct ConstraintInfo { enum { @@ -331,7 +373,7 @@ public: std::string ConstraintStr; // constraint: "=rm" std::string Name; // Operand name: [foo] with no []'s. public: - ConstraintInfo(llvm::StringRef ConstraintStr, llvm::StringRef Name) + ConstraintInfo(StringRef ConstraintStr, StringRef Name) : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()), Name(Name.str()) {} @@ -444,7 +486,7 @@ public: /// and give good diagnostics in cases when the assembler or code generator /// would otherwise reject the section specifier. /// - virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const { + virtual std::string isValidSectionSpecifier(StringRef SR) const { return ""; } @@ -453,11 +495,9 @@ public: /// language options which change the target configuration. virtual void setForcedLangOptions(LangOptions &Opts); - /// getDefaultFeatures - Get the default set of target features for - /// the \args CPU; this should include all legal feature strings on - /// the target. - virtual void getDefaultFeatures(const std::string &CPU, - llvm::StringMap<bool> &Features) const { + /// getDefaultFeatures - Get the default set of target features for the CPU; + /// this should include all legal feature strings on the target. + virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const { } /// getABI - Get the ABI in use. @@ -473,10 +513,8 @@ public: /// setCPU - Target the specific CPU. /// /// \return - False on error (invalid CPU name). - // - // FIXME: Remove this. virtual bool setCPU(const std::string &Name) { - return true; + return false; } /// setABI - Use the specific ABI. @@ -565,7 +603,7 @@ public: /// \brief Retrieve the name of the platform as it is used in the /// availability attribute. - llvm::StringRef getPlatformName() const { return PlatformName; } + StringRef getPlatformName() const { return PlatformName; } /// \brief Retrieve the minimum desired version of the platform, to /// which the program should be compiled. diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def index 86172b8..35a881c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def @@ -89,6 +89,9 @@ PPKEYWORD(sccs) PPKEYWORD(assert) PPKEYWORD(unassert) +// Clang extensions +PPKEYWORD(__export_macro__) + //===----------------------------------------------------------------------===// // Language keywords. //===----------------------------------------------------------------------===// @@ -114,13 +117,23 @@ TOK(raw_identifier) // Used only in raw lexing mode. TOK(numeric_constant) // 0x123 // C99 6.4.4: Character Constants -TOK(char_constant) // 'a' L'b' +TOK(char_constant) // 'a' +TOK(wide_char_constant) // L'b' + +// C++0x Character Constants +TOK(utf16_char_constant) // u'a' +TOK(utf32_char_constant) // U'a' // C99 6.4.5: String Literals. TOK(string_literal) // "foo" TOK(wide_string_literal) // L"foo" TOK(angle_string_literal)// <foo> +// C++0x String Literals. +TOK(utf8_string_literal) // u8"foo" +TOK(utf16_string_literal)// u"foo" +TOK(utf32_string_literal)// U"foo" + // C99 6.4.6: Punctuators. PUNCTUATOR(l_square, "[") PUNCTUATOR(r_square, "]") @@ -236,6 +249,8 @@ KEYWORD(unsigned , KEYALL) KEYWORD(void , KEYALL) KEYWORD(volatile , KEYALL) KEYWORD(while , KEYALL) +KEYWORD(_Alignas , KEYALL) +KEYWORD(_Atomic , KEYALL) KEYWORD(_Bool , KEYNOCXX) KEYWORD(_Complex , KEYALL) KEYWORD(_Generic , KEYALL) @@ -289,6 +304,7 @@ CXX_KEYWORD_OPERATOR(xor , caret) CXX_KEYWORD_OPERATOR(xor_eq , caretequal) // C++0x keywords +KEYWORD(alignas , KEYCXX0X) KEYWORD(alignof , KEYCXX0X) KEYWORD(char16_t , KEYCXX0X) KEYWORD(char32_t , KEYCXX0X) @@ -387,6 +403,8 @@ KEYWORD(__array_extent , KEYCXX) // Apple Extension. KEYWORD(__private_extern__ , KEYALL) +KEYWORD(__import_module__ , KEYALL) +KEYWORD(__module_private__ , KEYALL) // Microsoft Extension. KEYWORD(__declspec , KEYALL) @@ -395,6 +413,7 @@ KEYWORD(__stdcall , KEYALL) KEYWORD(__fastcall , KEYALL) KEYWORD(__thiscall , KEYALL) KEYWORD(__forceinline , KEYALL) +KEYWORD(__unaligned , KEYMS) // OpenCL-specific keywords KEYWORD(__kernel , KEYOPENCL) @@ -422,6 +441,12 @@ KEYWORD(__pascal , KEYALL) KEYWORD(__vector , KEYALTIVEC) KEYWORD(__pixel , KEYALTIVEC) +// ARM NEON extensions. +ALIAS("__fp16", half , KEYALL) + +// OpenCL Extension. +KEYWORD(half , KEYOPENCL) + // Objective-C ARC keywords. KEYWORD(__bridge , KEYARC) KEYWORD(__bridge_transfer , KEYARC) @@ -455,6 +480,7 @@ ALIAS("__volatile__" , volatile , KEYALL) // Microsoft extensions which should be disabled in strict conformance mode KEYWORD(__ptr64 , KEYMS) +KEYWORD(__ptr32 , KEYMS) KEYWORD(__w64 , KEYMS) KEYWORD(__uuidof , KEYMS | KEYBORLAND) KEYWORD(__try , KEYMS | KEYBORLAND) diff --git a/contrib/llvm/tools/clang/include/clang/Basic/VersionTuple.h b/contrib/llvm/tools/clang/include/clang/Basic/VersionTuple.h index 91eb68e..30ef6641 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/VersionTuple.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/VersionTuple.h @@ -14,13 +14,10 @@ #ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H #define LLVM_CLANG_BASIC_VERSIONTUPLE_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/Optional.h" #include <string> -namespace llvm { - class raw_ostream; -} - namespace clang { /// \brief Represents a version number in the form major[.minor[.subminor]]. @@ -120,7 +117,7 @@ public: }; /// \brief Print a version number. -llvm::raw_ostream& operator<<(llvm::raw_ostream &Out, const VersionTuple &V); +raw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V); } // end namespace clang #endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/BackendUtil.h b/contrib/llvm/tools/clang/include/clang/CodeGen/BackendUtil.h index 9636d6e..135b6a9 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/BackendUtil.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/BackendUtil.h @@ -10,13 +10,14 @@ #ifndef LLVM_CLANG_CODEGEN_BACKEND_UTIL_H #define LLVM_CLANG_CODEGEN_BACKEND_UTIL_H +#include "clang/Basic/LLVM.h" + namespace llvm { class Module; - class raw_ostream; } namespace clang { - class Diagnostic; + class DiagnosticsEngine; class CodeGenOptions; class TargetOptions; class LangOptions; @@ -30,10 +31,10 @@ namespace clang { Backend_EmitObj ///< Emit native object files }; - void EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts, + void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, llvm::Module *M, - BackendAction Action, llvm::raw_ostream *OS); + BackendAction Action, raw_ostream *OS); } #endif diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h index 052c660..f1a2f6e 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h @@ -37,7 +37,7 @@ protected: virtual bool hasIRSupport() const; virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); virtual void ExecuteAction(); diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/ModuleBuilder.h b/contrib/llvm/tools/clang/include/clang/CodeGen/ModuleBuilder.h index c45ad08..38aba89 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/ModuleBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/ModuleBuilder.h @@ -23,7 +23,7 @@ namespace llvm { } namespace clang { - class Diagnostic; + class DiagnosticsEngine; class LangOptions; class CodeGenOptions; @@ -36,7 +36,7 @@ namespace clang { /// CreateLLVMCodeGen - Create a CodeGenerator instance. /// It is the responsibility of the caller to call delete on /// the allocated CodeGenerator instance. - CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags, + CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags, const std::string &ModuleName, const CodeGenOptions &CGO, llvm::LLVMContext& C); diff --git a/contrib/llvm/tools/clang/include/clang/Config/config.h.cmake b/contrib/llvm/tools/clang/include/clang/Config/config.h.cmake deleted file mode 100644 index 5f13d2f..0000000 --- a/contrib/llvm/tools/clang/include/clang/Config/config.h.cmake +++ /dev/null @@ -1,17 +0,0 @@ -/* Relative directory for resource files */ -#define CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}" - -/* 32 bit multilib directory. */ -#define CXX_INCLUDE_32BIT_DIR "${CXX_INCLUDE_32BIT_DIR}" - -/* 64 bit multilib directory. */ -#define CXX_INCLUDE_64BIT_DIR "${CXX_INCLUDE_64BIT_DIR}" - -/* Arch the libstdc++ headers. */ -#define CXX_INCLUDE_ARCH "${CXX_INCLUDE_ARCH}" - -/* Directory with the libstdc++ headers. */ -#define CXX_INCLUDE_ROOT "${CXX_INCLUDE_ROOT}" - -/* Directories clang will search for headers */ -#define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}" diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Action.h b/contrib/llvm/tools/clang/include/clang/Driver/Action.h index 4b45c98..a33c33b 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Action.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Action.h @@ -10,17 +10,9 @@ #ifndef CLANG_DRIVER_ACTION_H_ #define CLANG_DRIVER_ACTION_H_ -#include "llvm/ADT/SmallVector.h" - #include "clang/Driver/Types.h" #include "clang/Driver/Util.h" - -#include "llvm/Support/Casting.h" -using llvm::isa; -using llvm::cast; -using llvm::cast_or_null; -using llvm::dyn_cast; -using llvm::dyn_cast_or_null; +#include "llvm/ADT/SmallVector.h" namespace clang { namespace driver { @@ -52,9 +44,10 @@ public: LinkJobClass, LipoJobClass, DsymutilJobClass, + VerifyJobClass, JobClassFirst=PreprocessJobClass, - JobClassLast=DsymutilJobClass + JobClassLast=VerifyJobClass }; static const char *getClassName(ActionClass AC); @@ -222,6 +215,15 @@ public: static bool classof(const DsymutilJobAction *) { return true; } }; +class VerifyJobAction : public JobAction { +public: + VerifyJobAction(ActionList &Inputs, types::ID Type); + static bool classof(const Action *A) { + return A->getKind() == VerifyJobClass; + } + static bool classof(const VerifyJobAction *) { return true; } +}; + } // end namespace driver } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Arg.h b/contrib/llvm/tools/clang/include/clang/Driver/Arg.h index 265d6d8..e8625bb 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Arg.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Arg.h @@ -51,7 +51,7 @@ namespace driver { mutable unsigned OwnsValues : 1; /// The argument values, as C strings. - llvm::SmallVector<const char *, 2> Values; + SmallVector<const char *, 2> Values; public: Arg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0); @@ -87,11 +87,11 @@ namespace driver { return Values[N]; } - llvm::SmallVectorImpl<const char*> &getValues() { + SmallVectorImpl<const char*> &getValues() { return Values; } - bool containsValue(llvm::StringRef Value) const { + bool containsValue(StringRef Value) const { for (unsigned i = 0, e = getNumValues(); i != e; ++i) if (Values[i] == Value) return true; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h b/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h index 0fcf821..04faf64 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h @@ -10,6 +10,7 @@ #ifndef CLANG_DRIVER_ARGLIST_H_ #define CLANG_DRIVER_ARGLIST_H_ +#include "clang/Basic/LLVM.h" #include "clang/Driver/OptSpecifier.h" #include "clang/Driver/Util.h" #include "llvm/ADT/SmallVector.h" @@ -19,12 +20,8 @@ #include <string> #include <vector> -namespace llvm { - class Twine; -} - namespace clang { - class Diagnostic; + class DiagnosticsEngine; namespace driver { class Arg; @@ -34,7 +31,7 @@ namespace driver { /// arg_iterator - Iterates through arguments stored inside an ArgList. class arg_iterator { /// The current argument. - llvm::SmallVectorImpl<Arg*>::const_iterator Current; + SmallVectorImpl<Arg*>::const_iterator Current; /// The argument list we are iterating over. const ArgList &Args; @@ -58,7 +55,7 @@ namespace driver { typedef std::forward_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; - arg_iterator(llvm::SmallVectorImpl<Arg*>::const_iterator it, + arg_iterator(SmallVectorImpl<Arg*>::const_iterator it, const ArgList &_Args, OptSpecifier _Id0 = 0U, OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U) : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) { @@ -101,7 +98,7 @@ namespace driver { void operator=(const ArgList &); // DO NOT IMPLEMENT public: - typedef llvm::SmallVector<Arg*, 16> arglist_type; + typedef SmallVector<Arg*, 16> arglist_type; typedef arglist_type::iterator iterator; typedef arglist_type::const_iterator const_iterator; typedef arglist_type::reverse_iterator reverse_iterator; @@ -153,6 +150,13 @@ namespace driver { } /// @} + /// @name Arg Removal + /// @{ + + /// eraseArg - Remove any option matching \arg Id. + void eraseArg(OptSpecifier Id); + + /// @} /// @name Arg Access /// @{ @@ -195,13 +199,13 @@ namespace driver { /// @{ /// getLastArgValue - Return the value of the last argument, or a default. - llvm::StringRef getLastArgValue(OptSpecifier Id, - llvm::StringRef Default = "") const; + StringRef getLastArgValue(OptSpecifier Id, + StringRef Default = "") const; /// getLastArgValue - Return the value of the last argument as an integer, /// or a default. Emits an error if the argument is given, but non-integral. int getLastArgIntValue(OptSpecifier Id, int Default, - Diagnostic &Diags) const; + DiagnosticsEngine &Diags) const; /// getAllArgValues - Get the values of all instances of the given argument /// as strings. @@ -245,25 +249,29 @@ namespace driver { /// option id. void ClaimAllArgs(OptSpecifier Id0) const; + /// ClaimAllArgs - Claim all arguments. + /// + void ClaimAllArgs() const; + /// @} /// @name Arg Synthesis /// @{ /// MakeArgString - Construct a constant string pointer whose /// lifetime will match that of the ArgList. - virtual const char *MakeArgString(llvm::StringRef Str) const = 0; + virtual const char *MakeArgString(StringRef Str) const = 0; const char *MakeArgString(const char *Str) const { - return MakeArgString(llvm::StringRef(Str)); + return MakeArgString(StringRef(Str)); } const char *MakeArgString(std::string Str) const { - return MakeArgString(llvm::StringRef(Str)); + return MakeArgString(StringRef(Str)); } - const char *MakeArgString(const llvm::Twine &Str) const; + const char *MakeArgString(const Twine &Str) const; /// \brief Create an arg string for (\arg LHS + \arg RHS), reusing the /// string at \arg Index if possible. - const char *GetOrMakeJoinedArgString(unsigned Index, llvm::StringRef LHS, - llvm::StringRef RHS) const; + const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS, + StringRef RHS) const; /// @} }; @@ -304,10 +312,10 @@ namespace driver { public: /// MakeIndex - Get an index for the given string(s). - unsigned MakeIndex(llvm::StringRef String0) const; - unsigned MakeIndex(llvm::StringRef String0, llvm::StringRef String1) const; + unsigned MakeIndex(StringRef String0) const; + unsigned MakeIndex(StringRef String0, StringRef String1) const; - virtual const char *MakeArgString(llvm::StringRef Str) const; + virtual const char *MakeArgString(StringRef Str) const; /// @} }; @@ -346,7 +354,7 @@ namespace driver { SynthesizedArgs.push_back(A); } - virtual const char *MakeArgString(llvm::StringRef Str) const; + virtual const char *MakeArgString(StringRef Str) const; /// AddFlagArg - Construct a new FlagArg for the given option \arg Id and /// append it to the argument list. @@ -358,7 +366,7 @@ namespace driver { /// \arg Id, with the provided \arg Value and append it to the argument /// list. void AddPositionalArg(const Arg *BaseArg, const Option *Opt, - llvm::StringRef Value) { + StringRef Value) { append(MakePositionalArg(BaseArg, Opt, Value)); } @@ -367,7 +375,7 @@ namespace driver { /// \arg Id, with the provided \arg Value and append it to the argument /// list. void AddSeparateArg(const Arg *BaseArg, const Option *Opt, - llvm::StringRef Value) { + StringRef Value) { append(MakeSeparateArg(BaseArg, Opt, Value)); } @@ -375,7 +383,7 @@ namespace driver { /// AddJoinedArg - Construct a new Positional arg for the given option \arg /// Id, with the provided \arg Value and append it to the argument list. void AddJoinedArg(const Arg *BaseArg, const Option *Opt, - llvm::StringRef Value) { + StringRef Value) { append(MakeJoinedArg(BaseArg, Opt, Value)); } @@ -387,17 +395,17 @@ namespace driver { /// MakePositionalArg - Construct a new Positional arg for the /// given option \arg Id, with the provided \arg Value. Arg *MakePositionalArg(const Arg *BaseArg, const Option *Opt, - llvm::StringRef Value) const; + StringRef Value) const; /// MakeSeparateArg - Construct a new Positional arg for the /// given option \arg Id, with the provided \arg Value. Arg *MakeSeparateArg(const Arg *BaseArg, const Option *Opt, - llvm::StringRef Value) const; + StringRef Value) const; /// MakeJoinedArg - Construct a new Positional arg for the /// given option \arg Id, with the provided \arg Value. Arg *MakeJoinedArg(const Arg *BaseArg, const Option *Opt, - llvm::StringRef Value) const; + StringRef Value) const; /// @} }; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td index c72fb7d..70ce0403 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td @@ -57,6 +57,10 @@ def analyzer_output : Separate<"-analyzer-output">, def analyzer_output_EQ : Joined<"-analyzer-output=">, Alias<analyzer_output>; +def analyzer_purge : Separate<"-analyzer-purge">, + HelpText<"Source Code Analysis - Dead Symbol Removal Frequency">; +def analyzer_purge_EQ : Joined<"-analyzer-purge=">, Alias<analyzer_purge>; + def analyzer_opt_analyze_headers : Flag<"-analyzer-opt-analyze-headers">, HelpText<"Force the static analyzer to analyze functions defined in header files">; def analyzer_opt_analyze_nested_blocks : Flag<"-analyzer-opt-analyze-nested-blocks">, @@ -68,8 +72,6 @@ def analyze_function : Separate<"-analyze-function">, def analyze_function_EQ : Joined<"-analyze-function=">, Alias<analyze_function>; def analyzer_eagerly_assume : Flag<"-analyzer-eagerly-assume">, HelpText<"Eagerly assume the truth/falseness of some symbolic constraints">; -def analyzer_no_purge_dead : Flag<"-analyzer-no-purge-dead">, - HelpText<"Don't remove dead symbols, bindings, and constraints before processing a statement">; def analyzer_no_eagerly_trim_egraph : Flag<"-analyzer-no-eagerly-trim-egraph">, HelpText<"Don't eagerly remove uninteresting ExplodedNodes from the ExplodedGraph">; def trim_egraph : Flag<"-trim-egraph">, @@ -113,9 +115,10 @@ def dwarf_debug_flags : Separate<"-dwarf-debug-flags">, def fforbid_guard_variables : Flag<"-fforbid-guard-variables">, HelpText<"Emit an error if a C++ static local initializer would need a guard variable">; def g : Flag<"-g">, HelpText<"Generate source level debug information">; -def fno_dwarf2_cfi_asm : Flag<"-fno-dwarf2-cfi-asm">, HelpText<"Don't use the cfi directives">; +def fno_dwarf2_cfi_asm : Flag<"-fno-dwarf2-cfi-asm">, + HelpText<"Don't use the cfi directives">; def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">, - HelpText<"Generate runtime checks for undefined behavior.">; + HelpText<"Generate runtime checks for undefined behavior.">; def flimit_debug_info : Flag<"-flimit-debug-info">, HelpText<"Limit debug information produced to reduce size of debug binary">; def fno_common : Flag<"-fno-common">, @@ -157,6 +160,8 @@ def mdisable_fp_elim : Flag<"-mdisable-fp-elim">, HelpText<"Disable frame pointer elimination optimization">; def mfloat_abi : Separate<"-mfloat-abi">, HelpText<"The float ABI to use">; +def mno_global_merge : Flag<"-mno-global-merge">, + HelpText<"Disable merging of globals">; def mlimit_float_precision : Separate<"-mlimit-float-precision">, HelpText<"Limit float precision to the given value">; def mno_exec_stack : Flag<"-mnoexecstack">, @@ -359,6 +364,8 @@ def ast_view : Flag<"-ast-view">, HelpText<"Build ASTs and view them with GraphViz">; def print_decl_contexts : Flag<"-print-decl-contexts">, HelpText<"Print DeclContexts and their Decls">; +def emit_module : Flag<"-emit-module">, + HelpText<"Generate pre-compiled module file">; def emit_pth : Flag<"-emit-pth">, HelpText<"Generate pre-tokenized header file">; def emit_pch : Flag<"-emit-pch">, @@ -381,9 +388,6 @@ def rewrite_objc : Flag<"-rewrite-objc">, HelpText<"Rewrite ObjC into C (code rewriter example)">; def rewrite_macros : Flag<"-rewrite-macros">, HelpText<"Expand macros without full preprocessing">; - -def create_module : Flag<"-create-module">, - HelpText<"Create a module definition file">; } def arcmt_check : Flag<"-arcmt-check">, @@ -394,9 +398,10 @@ def arcmt_migrate : Flag<"-arcmt-migrate">, HelpText<"Apply modifications and produces temporary files that conform to ARC">; def arcmt_migrate_directory : Separate<"-arcmt-migrate-directory">, HelpText<"Directory for temporary files produced during ARC migration">; - -def import_module : Separate<"-import-module">, - HelpText<"Import a module definition file">; +def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">, + HelpText<"Output path for the plist report">; +def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">, + HelpText<"Emit ARC errors even if the migrator can fix them">; def working_directory : JoinedOrSeparate<"-working-directory">, HelpText<"Resolve file paths relative to the specified directory">; @@ -405,8 +410,6 @@ def working_directory_EQ : Joined<"-working-directory=">, def relocatable_pch : Flag<"-relocatable-pch">, HelpText<"Whether to build a relocatable precompiled header">; -def chained_pch : Flag<"-chained-pch">, - HelpText<"Whether to chain the new precompiled header to the old one.">; def print_stats : Flag<"-print-stats">, HelpText<"Print performance metrics and statistics">; def ftime_report : Flag<"-ftime-report">, @@ -446,7 +449,9 @@ def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, def femit_all_decls : Flag<"-femit-all-decls">, HelpText<"Emit all declarations, even if unused">; def fblocks : Flag<"-fblocks">, - HelpText<"enable the 'blocks' language feature">; + HelpText<"Enable the 'blocks' language feature">; +def fblocks_runtime_optional : Flag<"-fblocks-runtime-optional">, + HelpText<"Weakly link in the blocks runtime">; def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">; def fexceptions : Flag<"-fexceptions">, HelpText<"Enable support for exception handling">; @@ -471,7 +476,9 @@ def stdlib_EQ : Joined<"-stdlib=">, def fmath_errno : Flag<"-fmath-errno">, HelpText<"Require math functions to indicate errors by setting errno">; def fms_extensions : Flag<"-fms-extensions">, - HelpText<"Accept some non-standard constructs used in Microsoft header files ">; + HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">; +def fms_compatibility : Flag<"-fms-compatibility">, + HelpText<"Enable Microsoft compatibility mode">; def fmsc_version : Joined<"-fmsc-version=">, HelpText<"Version of the Microsoft C/C++ compiler to report in _MSC_VER (0 = don't define it (default))">; def fborland_extensions : Flag<"-fborland-extensions">, @@ -519,8 +526,8 @@ def fobjc_default_synthesize_properties : Flag<"-fobjc-default-synthesize-proper HelpText<"enable the default synthesis of Objective-C properties">; def print_ivar_layout : Flag<"-print-ivar-layout">, HelpText<"Enable Objective-C Ivar layout bitmap print trace">; -def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, - HelpText<"enable objective-c's nonfragile abi">; +def fobjc_fragile_abi : Flag<"-fobjc-fragile-abi">, + HelpText<"Use Objective-C's fragile ABI">; def fno_objc_infer_related_result_type : Flag< "-fno-objc-infer-related-result-type">, HelpText< @@ -536,6 +543,8 @@ def pic_level : Separate<"-pic-level">, HelpText<"Value for __PIC__">; def pthread : Flag<"-pthread">, HelpText<"Support POSIX threads in generated code">; +def fpack_struct : Separate<"-fpack-struct">, + HelpText<"Specify the default maximum struct packing alignment">; def fpascal_strings : Flag<"-fpascal-strings">, HelpText<"Recognize and construct Pascal-style string literals">; def fno_rtti : Flag<"-fno-rtti">, @@ -595,22 +604,41 @@ def fno_deprecated_macro : Flag<"-fno-deprecated-macro">, // Header Search Options //===----------------------------------------------------------------------===// -def nostdinc : Flag<"-nostdinc">, - HelpText<"Disable standard #include directories">; +def nostdsysteminc : Flag<"-nostdsysteminc">, + HelpText<"Disable standard system #include directories">; def nostdincxx : Flag<"-nostdinc++">, HelpText<"Disable standard #include directories for the C++ standard library">; def nobuiltininc : Flag<"-nobuiltininc">, HelpText<"Disable builtin #include directories">; +def fmodule_cache_path : Separate<"-fmodule-cache-path">, + MetaVarName<"<directory>">, + HelpText<"Specify the module cache path">; +def fdisable_module_hash : Flag<"-fdisable-module-hash">, + HelpText<"Disable the module hash">; +def fauto_module_import : Flag<"-fauto-module-import">, + HelpText<"Automatically translate #include/#import into module imports " + "when possible">; + def F : JoinedOrSeparate<"-F">, MetaVarName<"<directory>">, HelpText<"Add directory to framework include search path">; def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">, HelpText<"Add directory to include search path">; def idirafter : JoinedOrSeparate<"-idirafter">, MetaVarName<"<directory>">, HelpText<"Add directory to AFTER include search path">; +def index_header_map : Flag<"-index-header-map">, + HelpText<"Make the next included directory (-I or -F) an indexer header map">; def iquote : JoinedOrSeparate<"-iquote">, MetaVarName<"<directory>">, HelpText<"Add directory to QUOTE include search path">; +def c_isystem : JoinedOrSeparate<"-c-isystem">, MetaVarName<"<directory>">, + HelpText<"Add directory to the C SYSTEM include search path">; def cxx_isystem : JoinedOrSeparate<"-cxx-isystem">, MetaVarName<"<directory>">, HelpText<"Add directory to the C++ SYSTEM include search path">; +def objc_isystem : JoinedOrSeparate<"-objc-isystem">, + MetaVarName<"<directory>">, + HelpText<"Add directory to the ObjC SYSTEM include search path">; +def objcxx_isystem : JoinedOrSeparate<"-objcxx-isystem">, + MetaVarName<"<directory>">, + HelpText<"Add directory to the ObjC++ SYSTEM include search path">; def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"<directory>">, HelpText<"Add directory to SYSTEM include search path">; def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">,MetaVarName<"<directory>">, @@ -688,3 +716,10 @@ def cl_mad_enable : Flag<"-cl-mad-enable">, HelpText<"OpenCL only. Enable less precise MAD instructions to be generated.">; def cl_std_EQ : Joined<"-cl-std=">, HelpText<"OpenCL language standard to compile for">; + +//===----------------------------------------------------------------------===// +// CUDA Options +//===----------------------------------------------------------------------===// + +def fcuda_is_device : Flag<"-fcuda-is-device">, + HelpText<"Generate code for CUDA device">; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h index 2db712d..8c99909 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h @@ -12,12 +12,8 @@ #include "clang/Driver/Job.h" #include "clang/Driver/Util.h" - #include "llvm/ADT/DenseMap.h" - -namespace llvm { - class raw_ostream; -} +#include "llvm/Support/Path.h" namespace clang { namespace driver { @@ -60,6 +56,9 @@ class Compilation { /// Result files which should be removed on failure. ArgStringList ResultFiles; + /// Redirection for stdout, stderr, etc. + const llvm::sys::Path **Redirects; + public: Compilation(const Driver &D, const ToolChain &DefaultToolChain, InputArgList *Args, DerivedArgList *TranslatedArgs); @@ -120,7 +119,7 @@ public: /// \param J - The job to print. /// \param Terminator - A string to print at the end of the line. /// \param Quote - Should separate arguments be quoted. - void PrintJob(llvm::raw_ostream &OS, const Job &J, + void PrintJob(raw_ostream &OS, const Job &J, const char *Terminator, bool Quote) const; /// ExecuteCommand - Execute an actual command. @@ -136,6 +135,11 @@ public: /// Command which failed. /// \return The accumulated result code of the job. int ExecuteJob(const Job &J, const Command *&FailingCommand) const; + + /// initCompilationForDiagnostics - Remove stale state and suppress output + /// so compilation can be reexecuted to generate additional diagnostic + /// information (e.g., preprocessed source(s)). + void initCompilationForDiagnostics(); }; } // end namespace driver diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Driver.h b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h index b695166..6fdf6fc 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Driver.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h @@ -13,6 +13,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Driver/Phases.h" +#include "clang/Driver/Types.h" #include "clang/Driver/Util.h" #include "llvm/ADT/StringRef.h" @@ -24,13 +25,14 @@ #include <string> namespace llvm { - class raw_ostream; template<typename T> class ArrayRef; } namespace clang { namespace driver { class Action; + class Arg; class ArgList; + class Command; class Compilation; class DerivedArgList; class HostInfo; @@ -45,7 +47,7 @@ namespace driver { class Driver { OptTable *Opts; - Diagnostic &Diags; + DiagnosticsEngine &Diags; public: // Diag - Forwarding function for diagnostics. @@ -75,7 +77,7 @@ public: /// functionality. /// FIXME: This type of customization should be removed in favor of the /// universal driver when it is ready. - typedef llvm::SmallVector<std::string, 4> prefix_list; + typedef SmallVector<std::string, 4> prefix_list; prefix_list PrefixDirs; /// sysroot, if present @@ -109,6 +111,9 @@ public: /// The file to log CC_LOG_DIAGNOSTICS output to, if enabled. const char *CCLogDiagnosticsFilename; + /// A list of inputs and their types for the given arguments. + typedef SmallVector<std::pair<types::ID, const Arg*>, 16> InputList; + /// Whether the driver should follow g++ like behavior. unsigned CCCIsCXX : 1; @@ -134,6 +139,9 @@ public: /// format. unsigned CCLogDiagnostics : 1; + /// Whether the driver is generating diagnostics for debugging purposes. + unsigned CCGenDiagnostics : 1; + private: /// Name to use when invoking gcc/g++. std::string CCCGenericGCCName; @@ -172,12 +180,17 @@ private: /// arguments, after applying the standard argument translations. DerivedArgList *TranslateInputArgs(const InputArgList &Args) const; + // getFinalPhase - Determine which compilation mode we are in and record + // which option we used to determine the final phase. + phases::ID getFinalPhase(const DerivedArgList &DAL, Arg **FinalPhaseArg = 0) + const; + public: - Driver(llvm::StringRef _ClangExecutable, - llvm::StringRef _DefaultHostTriple, - llvm::StringRef _DefaultImageName, - bool IsProduction, bool CXXIsProduction, - Diagnostic &_Diags); + Driver(StringRef _ClangExecutable, + StringRef _DefaultHostTriple, + StringRef _DefaultImageName, + bool IsProduction, + DiagnosticsEngine &_Diags); ~Driver(); /// @name Accessors @@ -189,7 +202,7 @@ public: const OptTable &getOpts() const { return *Opts; } - const Diagnostic &getDiags() const { return Diags; } + const DiagnosticsEngine &getDiags() const { return Diags; } bool getCheckInputsExist() const { return CheckInputsExist; } @@ -209,7 +222,7 @@ public: return InstalledDir.c_str(); return Dir.c_str(); } - void setInstalledDir(llvm::StringRef Value) { + void setInstalledDir(StringRef Value) { InstalledDir = Value; } @@ -224,14 +237,24 @@ public: /// argument vector. A null return value does not necessarily /// indicate an error condition, the diagnostics should be queried /// to determine if an error occurred. - Compilation *BuildCompilation(llvm::ArrayRef<const char *> Args); + Compilation *BuildCompilation(ArrayRef<const char *> Args); /// @name Driver Steps /// @{ /// ParseArgStrings - Parse the given list of strings into an /// ArgList. - InputArgList *ParseArgStrings(llvm::ArrayRef<const char *> Args); + InputArgList *ParseArgStrings(ArrayRef<const char *> Args); + + /// BuildInputs - Construct the list of inputs and their types from + /// the given arguments. + /// + /// \param TC - The default host tool chain. + /// \param Args - The input arguments. + /// \param Inputs - The list to store the resulting compilation + /// inputs onto. + void BuildInputs(const ToolChain &TC, const DerivedArgList &Args, + InputList &Inputs) const; /// BuildActions - Construct the list of actions to perform for the /// given arguments, which are only done for a single architecture. @@ -240,7 +263,7 @@ public: /// \param Args - The input arguments. /// \param Actions - The list to store the resulting actions onto. void BuildActions(const ToolChain &TC, const DerivedArgList &Args, - ActionList &Actions) const; + const InputList &Inputs, ActionList &Actions) const; /// BuildUniversalActions - Construct the list of actions to perform /// for the given arguments, which may require a universal build. @@ -249,6 +272,7 @@ public: /// \param Args - The input arguments. /// \param Actions - The list to store the resulting actions onto. void BuildUniversalActions(const ToolChain &TC, const DerivedArgList &Args, + const InputList &BAInputs, ActionList &Actions) const; /// BuildJobs - Bind actions to concrete tools and translate @@ -263,7 +287,14 @@ public: /// This routine handles additional processing that must be done in addition /// to just running the subprocesses, for example reporting errors, removing /// temporary files, etc. - int ExecuteCompilation(const Compilation &C) const; + int ExecuteCompilation(const Compilation &C, + const Command *&FailingCommand) const; + + /// generateCompilationDiagnostics - Generate diagnostics information + /// including preprocessed source file(s). + /// + void generateCompilationDiagnostics(Compilation &C, + const Command *FailingCommand); /// @} /// @name Helper Methods @@ -281,7 +312,7 @@ public: void PrintOptions(const ArgList &Args) const; /// PrintVersion - Print the driver version. - void PrintVersion(const Compilation &C, llvm::raw_ostream &OS) const; + void PrintVersion(const Compilation &C, raw_ostream &OS) const; /// GetFilePath - Lookup \arg Name in the list of file search paths. /// @@ -342,11 +373,11 @@ public: const char *BaseInput, bool AtTopLevel) const; - /// GetTemporaryPath - Return the pathname of a temporary file to - /// use as part of compilation; the file will have the given suffix. + /// GetTemporaryPath - Return the pathname of a temporary file to use + /// as part of compilation; the file will have the given prefix and suffix. /// /// GCC goes to extra lengths here to be a bit more robust. - std::string GetTemporaryPath(const char *Suffix) const; + std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const; /// GetHostInfo - Construct a new host info object for the given /// host triple. diff --git a/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h index 0f9376b..844f918 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM, #define DRIVERSTART #include "clang/Basic/DiagnosticDriverKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Job.h b/contrib/llvm/tools/clang/include/clang/Driver/Job.h index d2767d1..367955f 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Job.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Job.h @@ -12,13 +12,7 @@ #include "clang/Driver/Util.h" #include "llvm/ADT/SmallVector.h" - -#include "llvm/Support/Casting.h" -using llvm::isa; -using llvm::cast; -using llvm::cast_or_null; -using llvm::dyn_cast; -using llvm::dyn_cast_or_null; +#include "clang/Basic/LLVM.h" namespace clang { namespace driver { @@ -88,7 +82,7 @@ public: /// JobList - A sequence of jobs to perform. class JobList : public Job { public: - typedef llvm::SmallVector<Job*, 4> list_type; + typedef SmallVector<Job*, 4> list_type; typedef list_type::size_type size_type; typedef list_type::iterator iterator; typedef list_type::const_iterator const_iterator; @@ -103,6 +97,9 @@ public: /// Add a job to the list (taking ownership). void addJob(Job *J) { Jobs.push_back(J); } + /// Clear the job list. + void clear(); + const list_type &getJobs() const { return Jobs; } size_type size() const { return Jobs.size(); } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h b/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h index 3befe1d..abd224d 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h @@ -10,12 +10,8 @@ #ifndef CLANG_DRIVER_OPTTABLE_H #define CLANG_DRIVER_OPTTABLE_H +#include "clang/Basic/LLVM.h" #include "clang/Driver/OptSpecifier.h" -#include <cassert> - -namespace llvm { - class raw_ostream; -} namespace clang { namespace driver { @@ -181,7 +177,7 @@ namespace options { /// \param Name - The name to use in the usage line. /// \param Title - The title to use in the usage line. /// \param ShowHidden - Whether help-hidden arguments should be shown. - void PrintHelp(llvm::raw_ostream &OS, const char *Name, + void PrintHelp(raw_ostream &OS, const char *Name, const char *Title, bool ShowHidden = false) const; }; } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Option.h b/contrib/llvm/tools/clang/include/clang/Driver/Option.h index 9dfa461..8243f6d 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Option.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Option.h @@ -12,12 +12,7 @@ #include "clang/Driver/OptSpecifier.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/Casting.h" -using llvm::isa; -using llvm::cast; -using llvm::cast_or_null; -using llvm::dyn_cast; -using llvm::dyn_cast_or_null; +#include "clang/Basic/LLVM.h" namespace clang { namespace driver { @@ -65,7 +60,7 @@ namespace driver { OptSpecifier ID; /// The option name. - llvm::StringRef Name; + StringRef Name; /// Group this option is a member of, if any. const OptionGroup *Group; @@ -104,7 +99,7 @@ namespace driver { unsigned getID() const { return ID.getID(); } OptionClass getKind() const { return Kind; } - llvm::StringRef getName() const { return Name; } + StringRef getName() const { return Name; } const OptionGroup *getGroup() const { return Group; } const Option *getAlias() const { return Alias; } @@ -144,7 +139,7 @@ namespace driver { /// getRenderName - Return the name to use when rendering this /// option. - llvm::StringRef getRenderName() const { + StringRef getRenderName() const { return getUnaliasedOption()->getName(); } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.td b/contrib/llvm/tools/clang/include/clang/Driver/Options.td index 14fd971..5b91c19 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.td @@ -122,6 +122,10 @@ def ccc_arcmt_migrate : Separate<"-ccc-arcmt-migrate">, CCCDriverOpt, HelpText<"Apply modifications and produces temporary files that conform to ARC">; def ccc_arcmt_migrate_EQ : Joined<"-ccc-arcmt-migrate=">, CCCDriverOpt, Alias<ccc_arcmt_migrate>; +def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">, + HelpText<"Output path for the plist report">; +def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">, + HelpText<"Emit ARC errors even if the migrator can fix them">; // Make sure all other -ccc- options are rejected. def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>; @@ -130,6 +134,9 @@ def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>; def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>, HelpText<"Print the commands to run for this compilation">; +// The '--' option is here for the sake of compatibility with gcc, but is +// being ignored by the driver. +def _DASH_DASH : Flag<"--">, Flags<[DriverOption]>; def A : JoinedOrSeparate<"-A">; def B : JoinedOrSeparate<"-B">; def CC : Flag<"-CC">; @@ -316,7 +323,7 @@ def fno_gnu89_inline : Flag<"-fno-gnu89-inline">, Group<f_Group>; def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>; def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">; def filelist : Separate<"-filelist">, Flags<[LinkerInput]>; -def findirect_virtual_calls : Flag<"-findirect-virtual-calls">, Group<f_Group>; +def findirect_virtual_calls : Flag<"-findirect-virtual-calls">, Alias<fapple_kext>; def finline_functions : Flag<"-finline-functions">, Group<clang_ignored_f_Group>; def finline : Flag<"-finline">, Group<clang_ignored_f_Group>; def finstrument_functions : Flag<"-finstrument-functions">, Group<f_Group>; @@ -334,8 +341,14 @@ def fmath_errno : Flag<"-fmath-errno">, Group<f_Group>; def fmerge_all_constants : Flag<"-fmerge-all-constants">, Group<f_Group>; def fmessage_length_EQ : Joined<"-fmessage-length=">, Group<f_Group>; def fms_extensions : Flag<"-fms-extensions">, Group<f_Group>; +def fms_compatibility : Flag<"-fms-compatibility">, Group<f_Group>; def fmsc_version : Joined<"-fmsc-version=">, Group<f_Group>; def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">, Group<f_Group>; +def fmodule_cache_path : Separate<"-fmodule-cache-path">, Group<i_Group>, + Flags<[NoForward]>; +def fauto_module_import : Flag <"-fauto-module-import">, Group<f_Group>, + Flags<[NoForward]>; + def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>; def fmudflap : Flag<"-fmudflap">, Group<f_Group>; def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>; @@ -371,6 +384,7 @@ def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, Group<f_Gr def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>; def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>; def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>; +def fno_ms_compatibility : Flag<"-fno-ms-compatibility">, Group<f_Group>; def fno_delayed_template_parsing : Flag<"-fno-delayed-template-parsing">, Group<f_Group>; def fno_objc_default_synthesize_properties : Flag<"-fno-objc-default-synthesize-properties">, Group<f_Group>; @@ -427,6 +441,9 @@ def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">; def force__flat__namespace : Flag<"-force_flat_namespace">; def force__load : Separate<"-force_load">; def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>; +def fpack_struct : Flag<"-fpack-struct">, Group<f_Group>; +def fno_pack_struct : Flag<"-fno-pack-struct">, Group<f_Group>; +def fpack_struct_EQ : Joined<"-fpack-struct=">, Group<f_Group>; def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>; def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>; def fpic : Flag<"-fpic">, Group<f_Group>; @@ -467,7 +484,7 @@ def Wlarger_than_ : Joined<"-Wlarger-than-">, Alias<Wlarger_than>; def Wframe_larger_than : Separate<"-Wframe-larger-than">, Group<clang_ignored_f_Group>; def Wframe_larger_than_EQ : Joined<"-Wframe-larger-than=">, Alias<Wframe_larger_than>; -def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>; +def fterminated_vtables : Flag<"-fterminated-vtables">, Alias<fapple_kext>; def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>; def ftime_report : Flag<"-ftime-report">, Group<f_Group>; def ftrapv : Flag<"-ftrapv">, Group<f_Group>; @@ -497,6 +514,7 @@ def gused : Joined<"-gused">, Group<g_Group>; def g_Flag : Flag<"-g">, Group<g_Group>; def g_Joined : Joined<"-g">, Group<g_Group>; def headerpad__max__install__names : Joined<"-headerpad_max_install_names">; +def index_header_map : Flag<"-index-header-map">; def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>; def iframework : JoinedOrSeparate<"-iframework">, Group<clang_i_Group>; def imacros : JoinedOrSeparate<"-imacros">, Group<clang_i_Group>; @@ -529,6 +547,7 @@ def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>, Flags<[NoArgum def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>; def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>; def mfpu_EQ : Joined<"-mfpu=">, Group<m_Group>; +def mglobal_merge : Flag<"-mglobal-merge">, Group<m_Group>; def mhard_float : Flag<"-mhard-float">, Group<m_Group>; def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>; def mios_version_min_EQ : Joined<"-mios-version-min=">, Alias<miphoneos_version_min_EQ>; @@ -543,6 +562,7 @@ def mmmx : Flag<"-mmmx">, Group<m_x86_Features_Group>; def mno_3dnowa : Flag<"-mno-3dnowa">, Group<m_x86_Features_Group>; def mno_3dnow : Flag<"-mno-3dnow">, Group<m_x86_Features_Group>; def mno_constant_cfstrings : Flag<"-mno-constant-cfstrings">, Group<m_Group>; +def mno_global_merge : Flag<"-mno-global-merge">, Group<m_Group>; def mno_mmx : Flag<"-mno-mmx">, Group<m_x86_Features_Group>; def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group<m_Group>; def mno_red_zone : Flag<"-mno-red-zone">, Group<m_Group>; @@ -605,6 +625,7 @@ def noprebind : Flag<"-noprebind">; def noseglinkedit : Flag<"-noseglinkedit">; def nostartfiles : Flag<"-nostartfiles">; def nostdinc : Flag<"-nostdinc">; +def nostdlibinc : Flag<"-nostdlibinc">; def nostdincxx : Flag<"-nostdinc++">; def nostdlib : Flag<"-nostdlib">; def object : Flag<"-object">; @@ -689,6 +710,8 @@ def u : JoinedOrSeparate<"-u">, Group<u_Group>; def use_gold_plugin : Flag<"-use-gold-plugin">; def v : Flag<"-v">, HelpText<"Show commands to run and use verbose output">; +def verify : Flag<"-verify">, Flags<[DriverOption]>, + HelpText<"Verify output using a verifier.">; def weak_l : Joined<"-weak-l">, Flags<[LinkerInput]>; def weak__framework : Separate<"-weak_framework">, Flags<[LinkerInput]>; def weak__library : Separate<"-weak_library">, Flags<[LinkerInput]>; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Tool.h b/contrib/llvm/tools/clang/include/clang/Driver/Tool.h index c30fa4c..378b516 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Tool.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Tool.h @@ -10,9 +10,7 @@ #ifndef CLANG_DRIVER_TOOL_H_ #define CLANG_DRIVER_TOOL_H_ -namespace llvm { - template<typename T, unsigned N> class SmallVector; -} +#include "clang/Basic/LLVM.h" namespace clang { namespace driver { @@ -23,7 +21,7 @@ namespace driver { class JobAction; class ToolChain; - typedef llvm::SmallVector<InputInfo, 4> InputInfoList; + typedef SmallVector<InputInfo, 4> InputInfoList; /// Tool - Information on a specific compilation tool. class Tool { diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h index 4836d3f..a5d51ca 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h @@ -32,7 +32,7 @@ namespace driver { /// ToolChain - Access to tools for a single platform. class ToolChain { public: - typedef llvm::SmallVector<std::string, 4> path_list; + typedef SmallVector<std::string, 4> path_list; enum CXXStdlibType { CST_Libcxx, @@ -63,9 +63,9 @@ public: const llvm::Triple &getTriple() const { return Triple; } llvm::Triple::ArchType getArch() const { return Triple.getArch(); } - llvm::StringRef getArchName() const { return Triple.getArchName(); } - llvm::StringRef getPlatform() const { return Triple.getVendorName(); } - llvm::StringRef getOS() const { return Triple.getOSName(); } + StringRef getArchName() const { return Triple.getArchName(); } + StringRef getPlatform() const { return Triple.getVendorName(); } + StringRef getOS() const { return Triple.getOSName(); } std::string getTripleString() const { return Triple.getTriple(); @@ -139,7 +139,9 @@ public: /// GetDefaultStackProtectorLevel - Get the default stack protector level for /// this tool chain (0=off, 1=on, 2=all). - virtual unsigned GetDefaultStackProtectorLevel() const { return 0; } + virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const { + return 0; + } /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables /// by default. @@ -169,21 +171,30 @@ public: /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking /// command line arguments into account. - virtual std::string ComputeLLVMTriple(const ArgList &Args) const; + virtual std::string ComputeLLVMTriple(const ArgList &Args, + types::ID InputType = types::TY_INVALID) const; /// ComputeEffectiveClangTriple - Return the Clang triple to use for this /// target, which may take into account the command line arguments. For /// example, on Darwin the -mmacosx-version-min= command line argument (which /// sets the deployment target) determines the version in the triple passed to /// Clang. - virtual std::string ComputeEffectiveClangTriple(const ArgList &Args) const; + virtual std::string ComputeEffectiveClangTriple(const ArgList &Args, + types::ID InputType = types::TY_INVALID) const; /// configureObjCRuntime - Configure the known properties of the /// Objective-C runtime for this platform. /// - /// FIXME: this doesn't really belong here. + /// FIXME: this really belongs on some sort of DeploymentTarget abstraction virtual void configureObjCRuntime(ObjCRuntime &runtime) const; + /// hasBlocksRuntime - Given that the user is compiling with + /// -fblocks, does this tool chain guarantee the existence of a + /// blocks runtime? + /// + /// FIXME: this really belongs on some sort of DeploymentTarget abstraction + virtual bool hasBlocksRuntime() const { return true; } + // GetCXXStdlibType - Determine the C++ standard library type to use with the // given compilation arguments. virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Types.def b/contrib/llvm/tools/clang/include/clang/Driver/Types.def index f09a1dc..8449d63 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Types.def +++ b/contrib/llvm/tools/clang/include/clang/Driver/Types.def @@ -44,15 +44,18 @@ TYPE("c", C, PP_C, 0, "u") TYPE("cl", CL, PP_C, 0, "u") TYPE("cuda", CUDA, PP_CXX, 0, "u") TYPE("objective-c-cpp-output", PP_ObjC, INVALID, "mi", "u") +TYPE("objc-cpp-output", PP_ObjC_Alias, INVALID, "mi", "u") TYPE("objective-c", ObjC, PP_ObjC, 0, "u") TYPE("c++-cpp-output", PP_CXX, INVALID, "ii", "u") TYPE("c++", CXX, PP_CXX, 0, "u") TYPE("objective-c++-cpp-output", PP_ObjCXX, INVALID, "mii", "u") +TYPE("objc++-cpp-output", PP_ObjCXX_Alias, INVALID, "mii", "u") TYPE("objective-c++", ObjCXX, PP_ObjCXX, 0, "u") // C family input files to precompile. TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", "p") TYPE("c-header", CHeader, PP_CHeader, 0, "pu") +TYPE("cl-header", CLHeader, PP_CHeader, 0, "pu") TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID, "mi", "p") TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, 0, "pu") TYPE("c++-header-cpp-output", PP_CXXHeader, INVALID, "ii", "p") diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Util.h b/contrib/llvm/tools/clang/include/clang/Driver/Util.h index 52f268d..65aef4b 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Util.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Util.h @@ -10,19 +10,17 @@ #ifndef CLANG_DRIVER_UTIL_H_ #define CLANG_DRIVER_UTIL_H_ -namespace llvm { - template<typename T, unsigned N> class SmallVector; -} +#include "clang/Basic/LLVM.h" namespace clang { namespace driver { class Action; /// ArgStringList - Type used for constructing argv lists for subprocesses. - typedef llvm::SmallVector<const char*, 16> ArgStringList; + typedef SmallVector<const char*, 16> ArgStringList; /// ActionList - Type used for lists of actions. - typedef llvm::SmallVector<Action*, 3> ActionList; + typedef SmallVector<Action*, 3> ActionList; } // end namespace driver } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h index 3c05834..cef9509 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h @@ -14,15 +14,16 @@ #ifndef DRIVER_ASTCONSUMERS_H #define DRIVER_ASTCONSUMERS_H +#include "clang/Basic/LLVM.h" + namespace llvm { - class raw_ostream; namespace sys { class Path; } } namespace clang { class ASTConsumer; class CodeGenOptions; -class Diagnostic; +class DiagnosticsEngine; class FileManager; class LangOptions; class Preprocessor; @@ -32,7 +33,7 @@ class TargetOptions; // original C code. The output is intended to be in a format such that // clang could re-parse the output back into the same AST, but the // implementation is still incomplete. -ASTConsumer *CreateASTPrinter(llvm::raw_ostream *OS); +ASTConsumer *CreateASTPrinter(raw_ostream *OS); // AST dumper: dumps the raw AST in human-readable form to stderr; this is // intended for debugging. @@ -40,7 +41,7 @@ ASTConsumer *CreateASTDumper(); // AST XML-dumper: dumps out the AST to stderr in a very detailed XML // format; this is intended for particularly intense debugging. -ASTConsumer *CreateASTDumperXML(llvm::raw_ostream &OS); +ASTConsumer *CreateASTDumperXML(raw_ostream &OS); // Graphical AST viewer: for each function definition, creates a graph of // the AST and displays it with the graph viewer "dotty". Also outputs diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h index 58a60a1..471476a 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h @@ -18,6 +18,7 @@ #include "clang/Serialization/ASTBitCodes.h" #include "clang/Sema/Sema.h" #include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Lex/ModuleLoader.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" @@ -41,10 +42,11 @@ namespace llvm { namespace clang { class ASTContext; +class ASTReader; class CodeCompleteConsumer; class CompilerInvocation; class Decl; -class Diagnostic; +class DiagnosticsEngine; class FileEntry; class FileManager; class HeaderSearch; @@ -65,19 +67,15 @@ class GlobalCodeCompletionAllocator /// \brief Utility class for loading a ASTContext from an AST file. /// -class ASTUnit { -public: - typedef std::map<FileID, std::vector<PreprocessedEntity *> > - PreprocessedEntitiesByFileMap; - +class ASTUnit : public ModuleLoader { private: - llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics; - llvm::IntrusiveRefCntPtr<FileManager> FileMgr; - llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr; - llvm::OwningPtr<HeaderSearch> HeaderInfo; - llvm::IntrusiveRefCntPtr<TargetInfo> Target; - llvm::IntrusiveRefCntPtr<Preprocessor> PP; - llvm::IntrusiveRefCntPtr<ASTContext> Ctx; + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; + llvm::IntrusiveRefCntPtr<FileManager> FileMgr; + llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr; + llvm::OwningPtr<HeaderSearch> HeaderInfo; + llvm::IntrusiveRefCntPtr<TargetInfo> Target; + llvm::IntrusiveRefCntPtr<Preprocessor> PP; + llvm::IntrusiveRefCntPtr<ASTContext> Ctx; FileSystemOptions FileSystemOpts; @@ -111,8 +109,8 @@ private: /// \brief Track whether the main file was loaded from an AST or not. bool MainFileIsAST; - /// \brief Whether this AST represents a complete translation unit. - bool CompleteTranslationUnit; + /// \brief What kind of translation unit this AST represents. + TranslationUnitKind TUKind; /// \brief Whether we should time each operation. bool WantTiming; @@ -128,14 +126,6 @@ private: // source. In the long term we should make the Index library use efficient and // more scalable search mechanisms. std::vector<Decl*> TopLevelDecls; - - /// \brief The list of preprocessed entities which appeared when the ASTUnit - /// was loaded. - /// - /// FIXME: This is just an optimization hack to avoid deserializing large - /// parts of a PCH file while performing a walk or search. In the long term, - /// we should provide more scalable search mechanisms. - std::vector<PreprocessedEntity *> PreprocessedEntities; /// The name of the original source file used to generate this ASTUnit. std::string OriginalSourceFile; @@ -143,9 +133,12 @@ private: // Critical optimization when using clang_getCursor(). ASTLocation LastLoc; + /// \brief The set of diagnostics produced when creating the preamble. + SmallVector<StoredDiagnostic, 4> PreambleDiagnostics; + /// \brief The set of diagnostics produced when creating this /// translation unit. - llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics; + SmallVector<StoredDiagnostic, 4> StoredDiagnostics; /// \brief The number of stored diagnostics that come from the driver /// itself. @@ -156,27 +149,8 @@ private: /// \brief Temporary files that should be removed when the ASTUnit is /// destroyed. - llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles; - - /// \brief A mapping from file IDs to the set of preprocessed entities - /// stored in that file. - /// - /// FIXME: This is just an optimization hack to avoid searching through - /// many preprocessed entities during cursor traversal in the CIndex library. - /// Ideally, we would just be able to perform a binary search within the - /// list of preprocessed entities. - PreprocessedEntitiesByFileMap PreprocessedEntitiesByFile; + SmallVector<llvm::sys::Path, 4> TemporaryFiles; - /// \brief Simple hack to allow us to assert that ASTUnit is not being - /// used concurrently, which is not supported. - /// - /// Clients should create instances of the ConcurrencyCheck class whenever - /// using the ASTUnit in a way that isn't intended to be concurrent, which is - /// just about any usage. - unsigned int ConcurrencyCheckValue; - static const unsigned int CheckLocked = 28573289; - static const unsigned int CheckUnlocked = 9803453; - /// \brief Counter that determines when we want to try building a /// precompiled preamble. /// @@ -191,9 +165,53 @@ private: /// \brief The file in which the precompiled preamble is stored. std::string PreambleFile; +public: + class PreambleData { + const FileEntry *File; + std::vector<char> Buffer; + mutable unsigned NumLines; + + public: + PreambleData() : File(0), NumLines(0) { } + + void assign(const FileEntry *F, const char *begin, const char *end) { + File = F; + Buffer.assign(begin, end); + NumLines = 0; + } + + void clear() { Buffer.clear(); File = 0; NumLines = 0; } + + size_t size() const { return Buffer.size(); } + bool empty() const { return Buffer.empty(); } + + const char *getBufferStart() const { return &Buffer[0]; } + + unsigned getNumLines() const { + if (NumLines) + return NumLines; + countLines(); + return NumLines; + } + + SourceRange getSourceRange(const SourceManager &SM) const { + SourceLocation FileLoc = SM.getLocForStartOfFile(SM.getPreambleFileID()); + return SourceRange(FileLoc, FileLoc.getLocWithOffset(size()-1)); + } + + private: + void countLines() const; + }; + + const PreambleData &getPreambleData() const { + return Preamble; + } + +private: + /// \brief The contents of the preamble that has been precompiled to /// \c PreambleFile. - std::vector<char> Preamble; + PreambleData Preamble; /// \brief Whether the preamble ends at the start of a new line. /// @@ -224,27 +242,15 @@ private: /// \brief The number of warnings that occurred while parsing the preamble. /// - /// This value will be used to restore the state of the \c Diagnostic object - /// when re-using the precompiled preamble. Note that only the + /// This value will be used to restore the state of the \c DiagnosticsEngine + /// object when re-using the precompiled preamble. Note that only the /// number of warnings matters, since we will not save the preamble /// when any errors are present. unsigned NumWarningsInPreamble; - /// \brief The number of diagnostics that were stored when parsing - /// the precompiled preamble. - /// - /// This value is used to determine how many of the stored - /// diagnostics should be retained when reparsing in the presence of - /// a precompiled preamble. - unsigned NumStoredDiagnosticsInPreamble; - /// \brief A list of the serialization ID numbers for each of the top-level /// declarations parsed within the precompiled preamble. std::vector<serialization::DeclID> TopLevelDeclsInPreamble; - - /// \brief A list of the offsets into the precompiled preamble which - /// correspond to preprocessed entities. - std::vector<uint64_t> PreprocessedEntitiesInPreamble; /// \brief Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults; @@ -252,11 +258,19 @@ private: /// \brief Whether we want to include nested macro expansions in the /// detailed preprocessing record. bool NestedMacroExpansions; - - static void ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags, + + /// \brief The language options used when we load an AST file. + LangOptions ASTFileLangOpts; + + static void ConfigureDiags(llvm::IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, const char **ArgBegin, const char **ArgEnd, ASTUnit &AST, bool CaptureDiagnostics); + void TranslateStoredDiagnostics(ASTReader *MMan, StringRef ModName, + SourceManager &SrcMan, + const SmallVectorImpl<StoredDiagnostic> &Diags, + SmallVectorImpl<StoredDiagnostic> &Out); + public: /// \brief A cached code-completion result, which may be introduced in one of /// many different contexts. @@ -309,10 +323,24 @@ public: return CachedCompletionAllocator; } + /// \brief Retrieve the allocator used to cache global code completions. + /// Creates the allocator if it doesn't already exist. + llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> + getCursorCompletionAllocator() { + if (!CursorCompletionAllocator.getPtr()) { + CursorCompletionAllocator = new GlobalCodeCompletionAllocator; + } + return CursorCompletionAllocator; + } + private: /// \brief Allocator used to store cached code completions. llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> CachedCompletionAllocator; + + /// \brief Allocator used to store code completions for arbitrary cursors. + llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> + CursorCompletionAllocator; /// \brief The set of cached code-completion results. std::vector<CachedCodeCompletionResult> CachedCompletionResults; @@ -367,23 +395,38 @@ private: bool AllowRebuild = true, unsigned MaxLines = 0); void RealizeTopLevelDeclsFromPreamble(); - void RealizePreprocessedEntitiesFromPreamble(); + /// \brief Allows us to assert that ASTUnit is not being used concurrently, + /// which is not supported. + /// + /// Clients should create instances of the ConcurrencyCheck class whenever + /// using the ASTUnit in a way that isn't intended to be concurrent, which is + /// just about any usage. + /// Becomes a noop in release mode; only useful for debug mode checking. + class ConcurrencyState { + void *Mutex; // a llvm::sys::MutexImpl in debug; + + public: + ConcurrencyState(); + ~ConcurrencyState(); + + void start(); + void finish(); + }; + ConcurrencyState ConcurrencyCheckValue; + public: class ConcurrencyCheck { - volatile ASTUnit &Self; + ASTUnit &Self; public: explicit ConcurrencyCheck(ASTUnit &Self) : Self(Self) { - assert(Self.ConcurrencyCheckValue == CheckUnlocked && - "Concurrent access to ASTUnit!"); - Self.ConcurrencyCheckValue = CheckLocked; + Self.ConcurrencyCheckValue.start(); } - ~ConcurrencyCheck() { - Self.ConcurrencyCheckValue = CheckUnlocked; + Self.ConcurrencyCheckValue.finish(); } }; friend class ConcurrencyCheck; @@ -395,8 +438,8 @@ public: bool isUnsafeToFree() const { return UnsafeToFree; } void setUnsafeToFree(bool Value) { UnsafeToFree = Value; } - const Diagnostic &getDiagnostics() const { return *Diagnostics; } - Diagnostic &getDiagnostics() { return *Diagnostics; } + const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; } + DiagnosticsEngine &getDiagnostics() { return *Diagnostics; } const SourceManager &getSourceManager() const { return *SourceMgr; } SourceManager &getSourceManager() { return *SourceMgr; } @@ -407,6 +450,8 @@ public: const ASTContext &getASTContext() const { return *Ctx; } ASTContext &getASTContext() { return *Ctx; } + void setASTContext(ASTContext *ctx) { Ctx = ctx; } + bool hasSema() const { return TheSema; } Sema &getSema() const { assert(TheSema && "ASTUnit does not have a Sema object!"); @@ -419,7 +464,6 @@ public: const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } const std::string &getOriginalSourceFileName(); - const std::string &getASTFileName(); /// \brief Add a temporary file that the ASTUnit depends on. /// @@ -433,15 +477,11 @@ public: bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; } void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; } - /// \brief Retrieve the maximum PCH level of declarations that a - /// traversal of the translation unit should consider. - unsigned getMaxPCHLevel() const; - void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; } ASTLocation getLastASTLocation() const { return LastLoc; } - llvm::StringRef getMainFileName() const; + StringRef getMainFileName() const; typedef std::vector<Decl *>::iterator top_level_iterator; @@ -484,22 +524,38 @@ public: /// /// Note: This is used internally by the top-level tracking action unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; } - - typedef std::vector<PreprocessedEntity *>::iterator pp_entity_iterator; - - pp_entity_iterator pp_entity_begin(); - pp_entity_iterator pp_entity_end(); - - /// \brief Add a new preprocessed entity that's stored at the given offset - /// in the precompiled preamble. - void addPreprocessedEntityFromPreamble(uint64_t Offset) { - PreprocessedEntitiesInPreamble.push_back(Offset); + + /// \brief Get the source location for the given file:line:col triplet. + /// + /// The difference with SourceManager::getLocation is that this method checks + /// whether the requested location points inside the precompiled preamble + /// in which case the returned source location will be a "loaded" one. + SourceLocation getLocation(const FileEntry *File, + unsigned Line, unsigned Col) const; + + /// \brief Get the source location for the given file:offset pair. + SourceLocation getLocation(const FileEntry *File, unsigned Offset) const; + + /// \brief If \arg Loc is a loaded location from the preamble, returns + /// the corresponding local location of the main file, otherwise it returns + /// \arg Loc. + SourceLocation mapLocationFromPreamble(SourceLocation Loc); + + /// \brief If \arg Loc is a local location of the main file but inside the + /// preamble chunk, returns the corresponding loaded location from the + /// preamble, otherwise it returns \arg Loc. + SourceLocation mapLocationToPreamble(SourceLocation Loc); + + /// \brief \see mapLocationFromPreamble. + SourceRange mapRangeFromPreamble(SourceRange R) { + return SourceRange(mapLocationFromPreamble(R.getBegin()), + mapLocationFromPreamble(R.getEnd())); } - - /// \brief Retrieve the mapping from File IDs to the preprocessed entities - /// within that file. - PreprocessedEntitiesByFileMap &getPreprocessedEntitiesByFile() { - return PreprocessedEntitiesByFile; + + /// \brief \see mapLocationToPreamble. + SourceRange mapRangeToPreamble(SourceRange R) { + return SourceRange(mapLocationToPreamble(R.getBegin()), + mapLocationToPreamble(R.getEnd())); } // Retrieve the diagnostics associated with this AST @@ -512,7 +568,7 @@ public: } unsigned stored_diag_size() const { return StoredDiagnostics.size(); } - llvm::SmallVector<StoredDiagnostic, 4> &getStoredDiagnostics() { + SmallVector<StoredDiagnostic, 4> &getStoredDiagnostics() { return StoredDiagnostics; } @@ -531,14 +587,11 @@ public: return CachedCompletionResults.size(); } - llvm::MemoryBuffer *getBufferForFile(llvm::StringRef Filename, + llvm::MemoryBuffer *getBufferForFile(StringRef Filename, std::string *ErrorStr = 0); - /// \brief Whether this AST represents a complete translation unit. - /// - /// If false, this AST is only a partial translation unit, e.g., one - /// that might still be used as a precompiled header or preamble. - bool isCompleteTranslationUnit() const { return CompleteTranslationUnit; } + /// \brief Determine what kind of translation unit this AST represents. + TranslationUnitKind getTranslationUnitKind() const { return TUKind; } typedef llvm::PointerUnion<const char *, const llvm::MemoryBuffer *> FilenameOrMemBuf; @@ -548,7 +601,7 @@ public: /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation. static ASTUnit *create(CompilerInvocation *CI, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags); + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags); /// \brief Create a ASTUnit from an AST file. /// @@ -559,7 +612,7 @@ public: /// /// \returns - The initialized ASTUnit or null if the AST failed to load. static ASTUnit *LoadFromASTFile(const std::string &Filename, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags, + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls = false, RemappedFile *RemappedFiles = 0, @@ -590,9 +643,13 @@ public: /// /// \param Action - The ASTFrontendAction to invoke. Its ownership is not /// transfered. + /// + /// \param Unit - optionally an already created ASTUnit. Its ownership is not + /// transfered. static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags, - ASTFrontendAction *Action = 0); + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + ASTFrontendAction *Action = 0, + ASTUnit *Unit = 0); /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a /// CompilerInvocation object. @@ -606,11 +663,11 @@ public: // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we // shouldn't need to specify them at construction time. static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags, + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, bool PrecompilePreamble = false, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, bool NestedMacroExpansions = true); @@ -630,18 +687,16 @@ public: // shouldn't need to specify them at construction time. static ASTUnit *LoadFromCommandLine(const char **ArgBegin, const char **ArgEnd, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags, - llvm::StringRef ResourceFilesPath, + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + StringRef ResourceFilesPath, bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, RemappedFile *RemappedFiles = 0, unsigned NumRemappedFiles = 0, bool RemappedFilesKeepOriginalName = true, bool PrecompilePreamble = false, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, - bool CXXPrecompilePreamble = false, - bool CXXChainedPCH = false, bool NestedMacroExpansions = true); /// \brief Reparse the source files using the same command-line options that @@ -669,24 +724,31 @@ public: /// /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and /// OwnedBuffers parameters are all disgusting hacks. They will go away. - void CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column, + void CodeComplete(StringRef File, unsigned Line, unsigned Column, RemappedFile *RemappedFiles, unsigned NumRemappedFiles, bool IncludeMacros, bool IncludeCodePatterns, CodeCompleteConsumer &Consumer, - Diagnostic &Diag, LangOptions &LangOpts, + DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr, FileManager &FileMgr, - llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, - llvm::SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers); + SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, + SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers); /// \brief Save this translation unit to a file with the given name. /// /// \returns An indication of whether the save was successful or not. - CXSaveError Save(llvm::StringRef File); + CXSaveError Save(StringRef File); /// \brief Serialize this translation unit with the given output stream. /// /// \returns True if an error occurred, false otherwise. - bool serialize(llvm::raw_ostream &OS); + bool serialize(raw_ostream &OS); + + virtual ModuleKey loadModule(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc) { + // ASTUnit doesn't know how to load modules (not that this matters). + return 0; + } }; } // namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def b/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def index f055549..010f889 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def +++ b/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def @@ -15,9 +15,7 @@ #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) #endif -ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store", CreateBasicStoreManager) ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateRegionStoreManager) -ANALYSIS_STORE(FlatStore, "flat", "Use flat analyzer store", CreateFlatStoreManager) #ifndef ANALYSIS_CONSTRAINTS #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) @@ -30,13 +28,21 @@ ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of conc #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) #endif -ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticClient, false) -ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticClient, true) -ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticClient, true) -ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticClient, true) +ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer, false) +ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer, true) +ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer, true) +ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer, true) + +#ifndef ANALYSIS_PURGE +#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) +#endif + +ANALYSIS_PURGE(PurgeStmt, "statement", "Purge symbols, bindings, and constraints before every statement") +ANALYSIS_PURGE(PurgeBlock, "block", "Purge symbols, bindings, and constraints before every basic block") +ANALYSIS_PURGE(PurgeNone, "none", "Do not purge symbols, bindings, or constraints") #undef ANALYSIS_STORE #undef ANALYSIS_CONSTRAINTS #undef ANALYSIS_DIAGNOSTICS -#undef ANALYSIS_STORE +#undef ANALYSIS_PURGE diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/AnalyzerOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/AnalyzerOptions.h index ea9f5e3..3565a51 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/AnalyzerOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/AnalyzerOptions.h @@ -20,7 +20,7 @@ namespace clang { class ASTConsumer; -class Diagnostic; +class DiagnosticsEngine; class Preprocessor; class LangOptions; @@ -53,6 +53,13 @@ enum AnalysisDiagClients { NUM_ANALYSIS_DIAG_CLIENTS }; +/// AnalysisPurgeModes - Set of available strategies for dead symbol removal. +enum AnalysisPurgeMode { +#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME, +#include "clang/Frontend/Analyses.def" +NumPurgeModes +}; + class AnalyzerOptions { public: /// \brief Pair of checker name and enable/disable. @@ -60,6 +67,7 @@ public: AnalysisStores AnalysisStoreOpt; AnalysisConstraints AnalysisConstraintsOpt; AnalysisDiagClients AnalysisDiagOpt; + AnalysisPurgeMode AnalysisPurgeOpt; std::string AnalyzeSpecificFunction; unsigned MaxNodes; unsigned MaxLoop; @@ -68,7 +76,6 @@ public: unsigned AnalyzerDisplayProgress : 1; unsigned AnalyzeNestedBlocks : 1; unsigned EagerlyAssume : 1; - unsigned PurgeDead : 1; unsigned TrimGraph : 1; unsigned VisualizeEGDot : 1; unsigned VisualizeEGUbi : 1; @@ -80,15 +87,15 @@ public: public: AnalyzerOptions() { - AnalysisStoreOpt = BasicStoreModel; + AnalysisStoreOpt = RegionStoreModel; AnalysisConstraintsOpt = RangeConstraintsModel; AnalysisDiagOpt = PD_HTML; + AnalysisPurgeOpt = PurgeStmt; ShowCheckerHelp = 0; AnalyzeAll = 0; AnalyzerDisplayProgress = 0; AnalyzeNestedBlocks = 0; EagerlyAssume = 0; - PurgeDead = 1; TrimGraph = 0; VisualizeEGDot = 0; VisualizeEGUbi = 0; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticClient.h b/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h index 70f2190..f20cf6f 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticClient.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h @@ -1,4 +1,4 @@ -//===--- ChainedDiagnosticClient.h - Chain Diagnostic Clients ---*- C++ -*-===// +//===- ChainedDiagnosticConsumer.h - Chain Diagnostic Clients ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H -#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H +#ifndef LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H +#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/OwningPtr.h" @@ -16,17 +16,17 @@ namespace clang { class LangOptions; -/// ChainedDiagnosticClient - Chain two diagnostic clients so that diagnostics +/// ChainedDiagnosticConsumer - Chain two diagnostic clients so that diagnostics /// go to the first client and then the second. The first diagnostic client /// should be the "primary" client, and will be used for computing whether the /// diagnostics should be included in counts. -class ChainedDiagnosticClient : public DiagnosticClient { - llvm::OwningPtr<DiagnosticClient> Primary; - llvm::OwningPtr<DiagnosticClient> Secondary; +class ChainedDiagnosticConsumer : public DiagnosticConsumer { + llvm::OwningPtr<DiagnosticConsumer> Primary; + llvm::OwningPtr<DiagnosticConsumer> Secondary; public: - ChainedDiagnosticClient(DiagnosticClient *_Primary, - DiagnosticClient *_Secondary) { + ChainedDiagnosticConsumer(DiagnosticConsumer *_Primary, + DiagnosticConsumer *_Secondary) { Primary.reset(_Primary); Secondary.reset(_Secondary); } @@ -46,14 +46,20 @@ public: return Primary->IncludeInDiagnosticCounts(); } - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info) { + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) { // Default implementation (Warnings/errors count). - DiagnosticClient::HandleDiagnostic(DiagLevel, Info); + DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info); Primary->HandleDiagnostic(DiagLevel, Info); Secondary->HandleDiagnostic(DiagLevel, Info); } + + DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { + return new ChainedDiagnosticConsumer(Primary->clone(Diags), + Secondary->clone(Diags)); + } + }; } // end namspace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h index 5d040b4..4874c17 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h @@ -37,6 +37,7 @@ public: unsigned AsmVerbose : 1; /// -dA, -fverbose-asm. unsigned ObjCAutoRefCountExceptions : 1; /// Whether ARC should be EH-safe. + unsigned CUDAIsDevice : 1; /// Set when compiling for CUDA device. unsigned CXAAtExit : 1; /// Use __cxa_atexit for calling destructors. unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker /// aliases to base ctors when possible. @@ -71,6 +72,7 @@ public: unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled. unsigned NoDwarf2CFIAsm : 1; /// Set when -fno-dwarf2-cfi-asm is enabled. unsigned NoExecStack : 1; /// Set when -Wa,--noexecstack is enabled. + unsigned NoGlobalMerge : 1; /// Set when -mno-global-merge is enabled. unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled. unsigned NoInfsFPMath : 1; /// Assume FP arguments, results not +-Inf. unsigned NoNaNsFPMath : 1; /// Assume FP arguments, results not NaN. @@ -142,6 +144,7 @@ public: public: CodeGenOptions() { AsmVerbose = 0; + CUDAIsDevice = 0; CXAAtExit = 1; CXXCtorDtorAliases = 0; DataSections = 0; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h b/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h index 8911cfa..c01f91d 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H #define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H +#include "clang/Basic/LLVM.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" @@ -29,10 +30,10 @@ struct ParsedSourceLocation { public: /// Construct a parsed source location from a string; the Filename is empty on /// error. - static ParsedSourceLocation FromString(llvm::StringRef Str) { + static ParsedSourceLocation FromString(StringRef Str) { ParsedSourceLocation PSL; - std::pair<llvm::StringRef, llvm::StringRef> ColSplit = Str.rsplit(':'); - std::pair<llvm::StringRef, llvm::StringRef> LineSplit = + std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':'); + std::pair<StringRef, StringRef> LineSplit = ColSplit.first.rsplit(':'); // If both tail splits were valid integers, return success. diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h index 004c889..8817740 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ #include "clang/Frontend/CompilerInvocation.h" +#include "clang/Lex/ModuleLoader.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/OwningPtr.h" @@ -19,7 +20,6 @@ #include <string> namespace llvm { -class raw_ostream; class raw_fd_ostream; class Timer; } @@ -27,13 +27,13 @@ class Timer; namespace clang { class ASTContext; class ASTConsumer; +class ASTReader; class CodeCompleteConsumer; -class Diagnostic; -class DiagnosticClient; +class DiagnosticsEngine; +class DiagnosticConsumer; class ExternalASTSource; class FileManager; class FrontendAction; -class ASTReader; class Preprocessor; class Sema; class SourceManager; @@ -57,12 +57,12 @@ class TargetInfo; /// in to the compiler instance for everything. When possible, utility functions /// come in two forms; a short form that reuses the CompilerInstance objects, /// and a long form that takes explicit instances of any required objects. -class CompilerInstance { +class CompilerInstance : public ModuleLoader { /// The options used in this compiler instance. llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation; /// The diagnostics engine instance. - llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics; + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; /// The target being compiled for. llvm::IntrusiveRefCntPtr<TargetInfo> Target; @@ -88,9 +88,12 @@ class CompilerInstance { /// \brief The semantic analysis object. llvm::OwningPtr<Sema> TheSema; - /// The frontend timer + /// \brief The frontend timer llvm::OwningPtr<llvm::Timer> FrontendTimer; + /// \brief Non-owning reference to the ASTReader, if one exists. + ASTReader *ModuleManager; + /// \brief Holds information about the output file. /// /// If TempFilename is not empty we must rename it to Filename at the end. @@ -99,10 +102,10 @@ class CompilerInstance { struct OutputFile { std::string Filename; std::string TempFilename; - llvm::raw_ostream *OS; + raw_ostream *OS; OutputFile(const std::string &filename, const std::string &tempFilename, - llvm::raw_ostream *os) + raw_ostream *os) : Filename(filename), TempFilename(tempFilename), OS(os) { } }; @@ -249,15 +252,15 @@ public: bool hasDiagnostics() const { return Diagnostics != 0; } /// Get the current diagnostics engine. - Diagnostic &getDiagnostics() const { + DiagnosticsEngine &getDiagnostics() const { assert(Diagnostics && "Compiler instance has no diagnostics!"); return *Diagnostics; } /// setDiagnostics - Replace the current diagnostics engine. - void setDiagnostics(Diagnostic *Value); + void setDiagnostics(DiagnosticsEngine *Value); - DiagnosticClient &getDiagnosticClient() const { + DiagnosticConsumer &getDiagnosticClient() const { assert(Diagnostics && Diagnostics->getClient() && "Compiler instance has no diagnostic client!"); return *Diagnostics->getClient(); @@ -388,6 +391,12 @@ public: Sema *takeSema() { return TheSema.take(); } /// } + /// @name Module Management + /// { + + ASTReader *getModuleManager() const { return ModuleManager; } + + /// } /// @name Code Completion /// { @@ -446,38 +455,48 @@ public: /// allocating one if one is not provided. /// /// \param Client If non-NULL, a diagnostic client that will be - /// attached to (and, then, owned by) the Diagnostic inside this AST + /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST /// unit. + /// + /// \param ShouldOwnClient If Client is non-NULL, specifies whether + /// the diagnostic object should take ownership of the client. + /// + /// \param ShouldCloneClient If Client is non-NULL, specifies whether that + /// client should be cloned. void createDiagnostics(int Argc, const char* const *Argv, - DiagnosticClient *Client = 0); + DiagnosticConsumer *Client = 0, + bool ShouldOwnClient = true, + bool ShouldCloneClient = true); - /// Create a Diagnostic object with a the TextDiagnosticPrinter. + /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. /// /// The \arg Argc and \arg Argv arguments are used only for logging purposes, /// when the diagnostic options indicate that the compiler should output /// logging information. /// /// If no diagnostic client is provided, this creates a - /// DiagnosticClient that is owned by the returned diagnostic + /// DiagnosticConsumer that is owned by the returned diagnostic /// object, if using directly the caller is responsible for - /// releasing the returned Diagnostic's client eventually. + /// releasing the returned DiagnosticsEngine's client eventually. /// /// \param Opts - The diagnostic options; note that the created text /// diagnostic object contains a reference to these options and its lifetime /// must extend past that of the diagnostic engine. /// /// \param Client If non-NULL, a diagnostic client that will be - /// attached to (and, then, owned by) the returned Diagnostic + /// attached to (and, then, owned by) the returned DiagnosticsEngine /// object. /// /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be /// used by some diagnostics printers (for logging purposes only). /// /// \return The new object on success, or null on failure. - static llvm::IntrusiveRefCntPtr<Diagnostic> + static llvm::IntrusiveRefCntPtr<DiagnosticsEngine> createDiagnostics(const DiagnosticOptions &Opts, int Argc, const char* const *Argv, - DiagnosticClient *Client = 0, + DiagnosticConsumer *Client = 0, + bool ShouldOwnClient = true, + bool ShouldCloneClient = true, const CodeGenOptions *CodeGenOpts = 0); /// Create the file manager and replace any existing one with it. @@ -490,26 +509,12 @@ public: /// and replace any existing one with it. void createPreprocessor(); - /// Create a Preprocessor object. - /// - /// Note that this also creates a new HeaderSearch object which will be owned - /// by the resulting Preprocessor. - /// - /// \return The new object on success, or null on failure. - static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &, - const PreprocessorOptions &, - const HeaderSearchOptions &, - const DependencyOutputOptions &, - const TargetInfo &, - const FrontendOptions &, - SourceManager &, FileManager &); - /// Create the AST context. void createASTContext(); /// Create an external AST source to read a PCH file and attach it to the AST /// context. - void createPCHExternalASTSource(llvm::StringRef Path, + void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation, bool DisableStatCache, void *DeserializationListener); @@ -518,7 +523,7 @@ public: /// /// \return - The new object on success, or null on failure. static ExternalASTSource * - createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot, + createPCHExternalASTSource(StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, bool DisableStatCache, Preprocessor &PP, ASTContext &Context, @@ -537,10 +542,10 @@ public: unsigned Line, unsigned Column, bool ShowMacros, bool ShowCodePatterns, bool ShowGlobals, - llvm::raw_ostream &OS); + raw_ostream &OS); /// \brief Create the Sema object to be used for parsing. - void createSema(bool CompleteTranslationUnit, + void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer); /// Create the frontend timer and replace any existing one with it. @@ -551,25 +556,27 @@ public: /// /// \return - Null on error. llvm::raw_fd_ostream * - createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "", - llvm::StringRef Extension = ""); + createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "", + StringRef Extension = ""); /// Create a new output file and add it to the list of tracked output files, /// optionally deriving the output path name. /// /// \return - Null on error. llvm::raw_fd_ostream * - createOutputFile(llvm::StringRef OutputPath, + createOutputFile(StringRef OutputPath, bool Binary = true, bool RemoveFileOnSignal = true, - llvm::StringRef BaseInput = "", - llvm::StringRef Extension = ""); + StringRef BaseInput = "", + StringRef Extension = "", + bool UseTemporary = false); /// Create a new output file, optionally deriving the output path name. /// /// If \arg OutputPath is empty, then createOutputFile will derive an output /// path location as \arg BaseInput, with any suffix removed, and \arg - /// Extension appended. If OutputPath is not stdout createOutputFile will - /// create a new temporary file that must be renamed to OutputPath in the end. + /// Extension appended. If OutputPath is not stdout and \arg UseTemporary + /// is true, createOutputFile will create a new temporary file that must be + /// renamed to OutputPath in the end. /// /// \param OutputPath - If given, the path to the output file. /// \param Error [out] - On failure, the error message. @@ -580,15 +587,18 @@ public: /// \param RemoveFileOnSignal - Whether the file should be registered with /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for /// multithreaded use, as the underlying signal mechanism is not reentrant + /// \param UseTemporary - Create a new temporary file that must be renamed to + /// OutputPath in the end /// \param ResultPathName [out] - If given, the result path name will be /// stored here on success. /// \param TempPathName [out] - If given, the temporary file path name /// will be stored here on success. static llvm::raw_fd_ostream * - createOutputFile(llvm::StringRef OutputPath, std::string &Error, + createOutputFile(StringRef OutputPath, std::string &Error, bool Binary = true, bool RemoveFileOnSignal = true, - llvm::StringRef BaseInput = "", - llvm::StringRef Extension = "", + StringRef BaseInput = "", + StringRef Extension = "", + bool UseTemporary = false, std::string *ResultPathName = 0, std::string *TempPathName = 0); @@ -600,19 +610,23 @@ public: /// as the main file. /// /// \return True on success. - bool InitializeSourceManager(llvm::StringRef InputFile); + bool InitializeSourceManager(StringRef InputFile); /// InitializeSourceManager - Initialize the source manager to set InputFile /// as the main file. /// /// \return True on success. - static bool InitializeSourceManager(llvm::StringRef InputFile, - Diagnostic &Diags, + static bool InitializeSourceManager(StringRef InputFile, + DiagnosticsEngine &Diags, FileManager &FileMgr, SourceManager &SourceMgr, const FrontendOptions &Opts); /// } + + virtual ModuleKey loadModule(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h index e18f3fe..47c7031 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h @@ -28,13 +28,9 @@ #include <string> #include <vector> -namespace llvm { - template<typename T> class SmallVectorImpl; -} - namespace clang { -class Diagnostic; +class DiagnosticsEngine; /// CompilerInvocation - Helper class for holding the data necessary to invoke /// the compiler. @@ -92,7 +88,7 @@ public: static void CreateFromArgs(CompilerInvocation &Res, const char* const *ArgBegin, const char* const *ArgEnd, - Diagnostic &Diags); + DiagnosticsEngine &Diags); /// GetBuiltinIncludePath - Get the directory where the compiler headers /// reside, relative to the compiler binary (found by the passed in @@ -127,6 +123,10 @@ public: static void setLangDefaults(LangOptions &Opts, InputKind IK, LangStandard::Kind LangStd = LangStandard::lang_unspecified); + /// \brief Retrieve a module hash string that is suitable for uniquely + /// identifying the conditions under which the module was built. + std::string getModuleHash() const; + /// @} /// @name Option Subgroups /// @{ diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h index 5ae8eb3..319abeb 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h @@ -43,7 +43,7 @@ public: unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences. unsigned ShowOverloads : 1; /// Overload candidates to show. Values from - /// Diagnostic::OverloadsShown + /// DiagnosticsEngine::OverloadsShown unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected /// diagnostics, indicated by markers in the /// input source file. @@ -82,7 +82,7 @@ public: PedanticErrors = 0; ShowCarets = 1; ShowColors = 0; - ShowOverloads = Diagnostic::Ovl_All; + ShowOverloads = DiagnosticsEngine::Ovl_All; ShowColumn = 1; ShowFixits = 1; ShowLocation = 1; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h index f335475..f85cc7e 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h @@ -10,15 +10,13 @@ #ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/OwningPtr.h" #include <string> #include <vector> -namespace llvm { - class raw_ostream; -} - namespace clang { class ASTConsumer; class ASTMergeAction; @@ -55,7 +53,7 @@ class FrontendAction { private: ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); protected: /// @name Implementation Action Interface @@ -76,7 +74,7 @@ protected: /// /// \return The new AST consumer, or 0 on failure. virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile) = 0; + StringRef InFile) = 0; /// \brief Callback before starting processing a single input, giving the /// opportunity to modify the CompilerInvocation or do some other action @@ -92,7 +90,7 @@ protected: /// \return True on success; on failure \see ExecutionAction() and /// EndSourceFileAction() will not be called. virtual bool BeginSourceFileAction(CompilerInstance &CI, - llvm::StringRef Filename) { + StringRef Filename) { return true; } @@ -152,7 +150,7 @@ public: return CurrentASTUnit.take(); } - void setCurrentFile(llvm::StringRef Value, InputKind Kind, ASTUnit *AST = 0); + void setCurrentFile(StringRef Value, InputKind Kind, ASTUnit *AST = 0); /// @} /// @name Supported Modes @@ -163,9 +161,8 @@ public: /// file inputs. virtual bool usesPreprocessorOnly() const = 0; - /// usesCompleteTranslationUnit - For AST based actions, should the - /// translation unit be completed? - virtual bool usesCompleteTranslationUnit() { return true; } + /// \brief For AST-based actions, the kind of translation unit we're handling. + virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } /// hasPCHSupport - Does this action support use with PCH? virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); } @@ -205,7 +202,7 @@ public: /// /// \return True on success; the compilation of this file should be aborted /// and neither Execute nor EndSourceFile should be called. - bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename, + bool BeginSourceFile(CompilerInstance &CI, StringRef Filename, InputKind Kind); /// Execute - Set the source managers main input file, and run the action. @@ -236,7 +233,7 @@ public: class PluginASTAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile) = 0; + StringRef InFile) = 0; public: /// ParseArgs - Parse the given plugin command line arguments. @@ -256,7 +253,7 @@ protected: /// CreateASTConsumer - Provide a default implementation which returns aborts, /// this method should never be called by FrontendAction clients. virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); public: virtual bool usesPreprocessorOnly() const { return true; } @@ -272,10 +269,10 @@ class WrapperFrontendAction : public FrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); virtual bool BeginInvocation(CompilerInstance &CI); virtual bool BeginSourceFileAction(CompilerInstance &CI, - llvm::StringRef Filename); + StringRef Filename); virtual void ExecuteAction(); virtual void EndSourceFileAction(); @@ -285,7 +282,7 @@ public: WrapperFrontendAction(FrontendAction *WrappedAction); virtual bool usesPreprocessorOnly() const; - virtual bool usesCompleteTranslationUnit(); + virtual TranslationUnitKind getTranslationUnitKind(); virtual bool hasPCHSupport() const; virtual bool hasASTFileSupport() const; virtual bool hasIRSupport() const; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h index b409ad1..72a3d90 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h @@ -24,7 +24,7 @@ class InitOnlyAction : public FrontendAction { virtual void ExecuteAction(); virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); public: // Don't claim to only use the preprocessor, we want to follow the AST path, @@ -39,59 +39,65 @@ public: class ASTPrintAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); }; class ASTDumpAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); }; class ASTDumpXMLAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); }; class ASTViewAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); }; class DeclContextPrintAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); }; class GeneratePCHAction : public ASTFrontendAction { + bool MakeModule; + protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); - virtual bool usesCompleteTranslationUnit() { return false; } + virtual TranslationUnitKind getTranslationUnitKind() { + return MakeModule? TU_Module : TU_Prefix; + } virtual bool hasASTFileSupport() const { return false; } public: + /// \brief Create a new action + explicit GeneratePCHAction(bool MakeModule) : MakeModule(MakeModule) { } + /// \brief Compute the AST consumer arguments that will be used to /// create the PCHGenerator instance returned by CreateASTConsumer. /// /// \returns true if an error occurred, false otherwise. static bool ComputeASTConsumerArguments(CompilerInstance &CI, - llvm::StringRef InFile, + StringRef InFile, std::string &Sysroot, std::string &OutputFile, - llvm::raw_ostream *&OS, - bool &Chaining); + raw_ostream *&OS); }; class SyntaxOnlyAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); public: virtual bool hasCodeCompletionSupport() const { return true; } @@ -114,10 +120,10 @@ class ASTMergeAction : public FrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); virtual bool BeginSourceFileAction(CompilerInstance &CI, - llvm::StringRef Filename); + StringRef Filename); virtual void ExecuteAction(); virtual void EndSourceFileAction(); @@ -128,7 +134,7 @@ public: virtual ~ASTMergeAction(); virtual bool usesPreprocessorOnly() const; - virtual bool usesCompleteTranslationUnit(); + virtual TranslationUnitKind getTranslationUnitKind(); virtual bool hasPCHSupport() const; virtual bool hasASTFileSupport() const; virtual bool hasCodeCompletionSupport() const; @@ -137,7 +143,7 @@ public: class PrintPreambleAction : public FrontendAction { protected: void ExecuteAction(); - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &, llvm::StringRef) { + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) { return 0; } diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h index 3e9508c..21cd2c6 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM, #define FRONTENDSTART #include "clang/Basic/DiagnosticFrontendKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h index 225a955..fa6d044 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h @@ -24,7 +24,6 @@ namespace frontend { ASTDumpXML, ///< Parse ASTs and dump them in XML. ASTPrint, ///< Parse ASTs and print them. ASTView, ///< Parse ASTs and view them in Graphviz. - CreateModule, ///< Create module definition DumpRawTokens, ///< Dump out raw tokens. DumpTokens, ///< Dump out preprocessed tokens. EmitAssembly, ///< Emit a .s file. @@ -35,6 +34,7 @@ namespace frontend { EmitCodeGenOnly, ///< Generate machine code, but don't emit anything. EmitObj, ///< Emit a .o file. FixIt, ///< Parse and apply any fixits to the source. + GenerateModule, ///< Generate pre-compiled module. GeneratePCH, ///< Generate pre-compiled header. GeneratePTH, ///< Generate pre-tokenized header. InitOnly, ///< Only execute frontend initialization. @@ -58,9 +58,6 @@ public: unsigned RelocatablePCH : 1; ///< When generating PCH files, /// instruct the AST writer to create /// relocatable PCH files. - unsigned ChainedPCH : 1; ///< When generating PCH files, - /// instruct the AST writer to create - /// chained PCH files. unsigned ShowHelp : 1; ///< Show the -help text. unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion /// results. @@ -75,6 +72,8 @@ public: unsigned ShowVersion : 1; ///< Show the -version text. unsigned FixWhatYouCan : 1; ///< Apply fixes even if there are /// unfixable errors. + unsigned ARCMTMigrateEmitARCErrors : 1; /// Emit ARC errors even if the + /// migrator can fix them enum { ARCMT_None, @@ -84,6 +83,7 @@ public: } ARCMTAction; std::string ARCMTMigrateDir; + std::string ARCMTMigrateReportOut; /// The input files and their types. std::vector<std::pair<InputKind, std::string> > Inputs; @@ -118,9 +118,6 @@ public: /// \brief The list of AST files to merge. std::vector<std::string> ASTMergeFiles; - /// \brief The list of modules to import. - std::vector<std::string> Modules; - /// \brief A list of arguments to forward to LLVM's option processing; this /// should only be used for debugging and experimental features. std::vector<std::string> LLVMArgs; @@ -131,7 +128,6 @@ public: ProgramAction = frontend::ParseSyntaxOnly; ActionName = ""; RelocatablePCH = 0; - ChainedPCH = 0; ShowHelp = 0; ShowMacrosInCodeCompletion = 0; ShowCodePatternsInCodeCompletion = 0; @@ -140,6 +136,7 @@ public: ShowTimers = 0; ShowVersion = 0; ARCMTAction = ARCMT_None; + ARCMTMigrateEmitARCErrors = 0; } /// getInputKindForExtension - Return the appropriate input kind for a file @@ -147,7 +144,7 @@ public: /// /// \return The input kind for the extension, or IK_None if the extension is /// not recognized. - static InputKind getInputKindForExtension(llvm::StringRef Extension); + static InputKind getInputKindForExtension(StringRef Extension); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h index 0347f98..92790e9 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h @@ -23,8 +23,13 @@ namespace frontend { enum IncludeDirGroup { Quoted = 0, ///< '#include ""' paths, added by'gcc -iquote'. Angled, ///< Paths for '#include <>' added by '-I'. + IndexHeaderMap, ///< Like Angled, but marks header maps used when + /// building frameworks. System, ///< Like Angled, but marks system directories. + CSystem, ///< Like System, but only used for C. CXXSystem, ///< Like System, but only used for C++. + ObjCSystem, ///< Like System, but only used for ObjC. + ObjCXXSystem, ///< Like System, but only used for ObjC++. After ///< Like System, but searched after the system directories. }; } @@ -44,7 +49,7 @@ public: /// path. unsigned IgnoreSysRoot : 1; - Entry(llvm::StringRef path, frontend::IncludeDirGroup group, + Entry(StringRef path, frontend::IncludeDirGroup group, bool isUserSupplied, bool isFramework, bool ignoreSysRoot) : Path(path), Group(group), IsUserSupplied(isUserSupplied), IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot) {} @@ -57,27 +62,24 @@ public: /// User specified include entries. std::vector<Entry> UserEntries; - /// A (system-path) delimited list of include paths to be added from the - /// environment following the user specified includes (but prior to builtin - /// and standard includes). This is parsed in the same manner as the CPATH - /// environment variable for gcc. - std::string EnvIncPath; - - /// Per-language environmental include paths, see \see EnvIncPath. - std::string CEnvIncPath; - std::string ObjCEnvIncPath; - std::string CXXEnvIncPath; - std::string ObjCXXEnvIncPath; - /// The directory which holds the compiler resource files (builtin includes, /// etc.). std::string ResourceDir; + /// \brief The directory used for the module cache. + std::string ModuleCachePath; + + /// \brief Whether we should disable the use of the hash string within the + /// module cache. + /// + /// Note: Only used for testing! + unsigned DisableModuleHash : 1; + /// Include the compiler builtin includes. unsigned UseBuiltinIncludes : 1; /// Include the system standard include search directories. - unsigned UseStandardIncludes : 1; + unsigned UseStandardSystemIncludes : 1; /// Include the system standard C++ library include search directories. unsigned UseStandardCXXIncludes : 1; @@ -89,13 +91,13 @@ public: unsigned Verbose : 1; public: - HeaderSearchOptions(llvm::StringRef _Sysroot = "/") - : Sysroot(_Sysroot), UseBuiltinIncludes(true), - UseStandardIncludes(true), UseStandardCXXIncludes(true), UseLibcxx(false), - Verbose(false) {} + HeaderSearchOptions(StringRef _Sysroot = "/") + : Sysroot(_Sysroot), DisableModuleHash(0), UseBuiltinIncludes(true), + UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), + UseLibcxx(false), Verbose(false) {} /// AddPath - Add the \arg Path path to the specified \arg Group list. - void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group, + void AddPath(StringRef Path, frontend::IncludeDirGroup Group, bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot) { UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework, IgnoreSysRoot)); diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h index ea37bdd..de2800c 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h @@ -10,6 +10,7 @@ #ifndef LLVM_CLANG_FRONTEND_LANGSTANDARD_H #define LLVM_CLANG_FRONTEND_LANGSTANDARD_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" namespace clang { @@ -83,7 +84,7 @@ public: bool hasImplicitInt() const { return Flags & frontend::ImplicitInt; } static const LangStandard &getLangStandardForKind(Kind K); - static const LangStandard *getLangStandardForName(llvm::StringRef Name); + static const LangStandard *getLangStandardForName(StringRef Name); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def index 6055ad5..c82290b 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def @@ -37,6 +37,9 @@ LANGSTANDARD(c94, "iso9899:199409", LANGSTANDARD(gnu89, "gnu89", "ISO C 1990 with GNU extensions", BCPLComment | C89 | Digraphs | GNUMode | ImplicitInt) +LANGSTANDARD(gnu90, "gnu90", + "ISO C 1990 with GNU extensions", + BCPLComment | C89 | Digraphs | GNUMode | ImplicitInt) // C99-ish modes LANGSTANDARD(c99, "c99", @@ -75,15 +78,24 @@ LANGSTANDARD(gnu1x, "gnu1x", LANGSTANDARD(cxx98, "c++98", "ISO C++ 1998 with amendments", BCPLComment | CPlusPlus | Digraphs) +LANGSTANDARD(cxx03, "c++03", + "ISO C++ 1998 with amendments", + BCPLComment | CPlusPlus | Digraphs) LANGSTANDARD(gnucxx98, "gnu++98", - "ISO C++ 1998 with " "amendments and GNU extensions", + "ISO C++ 1998 with amendments and GNU extensions", BCPLComment | CPlusPlus | Digraphs | GNUMode) LANGSTANDARD(cxx0x, "c++0x", - "Upcoming ISO C++ 200x with amendments", + "ISO C++ 2011 with amendments", + BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs) +LANGSTANDARD(cxx11, "c++11", + "ISO C++ 2011 with amendments", BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs) LANGSTANDARD(gnucxx0x, "gnu++0x", - "Upcoming ISO C++ 200x with amendments and GNU extensions", + "ISO C++ 2011 with amendments and GNU extensions", + BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode) +LANGSTANDARD(gnucxx11, "gnu++11", + "ISO C++ 2011 with amendments and GNU extensions", BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode) // OpenCL diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h index b6fc23c..4de15f2 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h @@ -19,7 +19,7 @@ namespace clang { class DiagnosticOptions; class LangOptions; -class LogDiagnosticPrinter : public DiagnosticClient { +class LogDiagnosticPrinter : public DiagnosticConsumer { struct DiagEntry { /// The primary message line of the diagnostic. std::string Message; @@ -37,10 +37,10 @@ class LogDiagnosticPrinter : public DiagnosticClient { unsigned DiagnosticID; /// The level of the diagnostic. - Diagnostic::Level DiagnosticLevel; + DiagnosticsEngine::Level DiagnosticLevel; }; - llvm::raw_ostream &OS; + raw_ostream &OS; const LangOptions *LangOpts; const DiagnosticOptions *DiagOpts; @@ -48,17 +48,17 @@ class LogDiagnosticPrinter : public DiagnosticClient { FullSourceLoc LastLoc; unsigned OwnsOutputStream : 1; - llvm::SmallVector<DiagEntry, 8> Entries; + SmallVector<DiagEntry, 8> Entries; std::string MainFilename; std::string DwarfDebugFlags; public: - LogDiagnosticPrinter(llvm::raw_ostream &OS, const DiagnosticOptions &Diags, + LogDiagnosticPrinter(raw_ostream &OS, const DiagnosticOptions &Diags, bool OwnsOutputStream = false); virtual ~LogDiagnosticPrinter(); - void setDwarfDebugFlags(llvm::StringRef Value) { + void setDwarfDebugFlags(StringRef Value) { DwarfDebugFlags = Value; } @@ -68,8 +68,10 @@ public: void EndSourceFile(); - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info); + + DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h index 2e16c97..0ee8cb3 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h @@ -50,6 +50,10 @@ public: /// record of all macro definitions and /// expansions. + /// \brief Whether we should automatically translate #include or #import + /// operations into module imports when possible. + unsigned AutoModuleImport : 1; + /// \brief Whether the detailed preprocessing record includes nested macro /// expansions. unsigned DetailedRecordIncludesNestedMacroExpansions : 1; @@ -117,6 +121,14 @@ public: /// by providing appropriate definitions to retrofit the standard library /// with support for lifetime-qualified pointers. ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary; + + /// \brief The path of modules being build, which is used to detect + /// cycles in the module dependency graph as modules are being built. + /// + /// There is no way to set this value from the command line. If we ever need + /// to do so (e.g., if on-demand module construction moves out-of-process), + /// we can add a cc1-level option to do so. + SmallVector<std::string, 2> ModuleBuildPath; typedef std::vector<std::pair<std::string, std::string> >::iterator remapped_file_iterator; @@ -154,6 +166,7 @@ public: public: PreprocessorOptions() : UsePredefines(true), DetailedRecord(false), + AutoModuleImport(false), DetailedRecordIncludesNestedMacroExpansions(true), DisablePCHValidation(false), DisableStatCache(false), DumpDeserializedPCHDecls(false), @@ -162,13 +175,13 @@ public: RetainRemappedFileBuffers(false), ObjCXXARCStandardLibrary(ARCXX_nolib) { } - void addMacroDef(llvm::StringRef Name) { + void addMacroDef(StringRef Name) { Macros.push_back(std::make_pair(Name, false)); } - void addMacroUndef(llvm::StringRef Name) { + void addMacroUndef(StringRef Name) { Macros.push_back(std::make_pair(Name, true)); } - void addRemappedFile(llvm::StringRef From, llvm::StringRef To) { + void addRemappedFile(StringRef From, StringRef To) { RemappedFiles.push_back(std::make_pair(From, To)); } @@ -176,7 +189,7 @@ public: return RemappedFiles.erase(Remapped); } - void addRemappedFile(llvm::StringRef From, const llvm::MemoryBuffer * To) { + void addRemappedFile(StringRef From, const llvm::MemoryBuffer * To) { RemappedFileBuffers.push_back(std::make_pair(From, To)); } @@ -189,6 +202,21 @@ public: RemappedFiles.clear(); RemappedFileBuffers.clear(); } + + /// \brief Reset any options that are not considered when building a + /// module. + void resetNonModularOptions() { + Includes.clear(); + MacroIncludes.clear(); + ChainedIncludes.clear(); + DumpDeserializedPCHDecls = false; + ImplicitPCHInclude.clear(); + ImplicitPTHInclude.clear(); + TokenCache.clear(); + RetainRemappedFileBuffers = true; + PrecompiledPreambleBytes.first = 0; + PrecompiledPreambleBytes.second = 0; + } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h index 380a1dd..6f1c0e8 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h @@ -22,7 +22,7 @@ namespace clang { class Preprocessor; class SourceManager; -class TextDiagnosticBuffer : public DiagnosticClient { +class TextDiagnosticBuffer : public DiagnosticConsumer { public: typedef std::vector<std::pair<SourceLocation, std::string> > DiagList; typedef DiagList::iterator iterator; @@ -39,12 +39,14 @@ public: const_iterator note_begin() const { return Notes.begin(); } const_iterator note_end() const { return Notes.end(); } - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info); /// FlushDiagnostics - Flush the buffered diagnostics to an given /// diagnostic engine. - void FlushDiagnostics(Diagnostic &Diags) const; + void FlushDiagnostics(DiagnosticsEngine &Diags) const; + + virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } // end namspace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h index 79a9916..22fa18b 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h @@ -22,8 +22,8 @@ namespace clang { class DiagnosticOptions; class LangOptions; -class TextDiagnosticPrinter : public DiagnosticClient { - llvm::raw_ostream &OS; +class TextDiagnosticPrinter : public DiagnosticConsumer { + raw_ostream &OS; const LangOptions *LangOpts; const DiagnosticOptions *DiagOpts; @@ -36,7 +36,7 @@ class TextDiagnosticPrinter : public DiagnosticClient { std::string Prefix; public: - TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags, + TextDiagnosticPrinter(raw_ostream &os, const DiagnosticOptions &diags, bool OwnsOutputStream = false); virtual ~TextDiagnosticPrinter(); @@ -53,26 +53,19 @@ public: LangOpts = 0; } - void PrintIncludeStack(Diagnostic::Level Level, SourceLocation Loc, + void PrintIncludeStack(DiagnosticsEngine::Level Level, SourceLocation Loc, const SourceManager &SM); - void HighlightRange(const CharSourceRange &R, - const SourceManager &SrcMgr, - unsigned LineNo, FileID FID, - std::string &CaretLine, - const std::string &SourceLine); + virtual void HandleDiagnostic(DiagnosticsEngine::Level Level, + const Diagnostic &Info); - virtual void HandleDiagnostic(Diagnostic::Level Level, - const DiagnosticInfo &Info); + DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; private: - void EmitCaretDiagnostic(SourceLocation Loc, CharSourceRange *Ranges, - unsigned NumRanges, const SourceManager &SM, - const FixItHint *Hints, - unsigned NumHints, unsigned Columns, - unsigned OnMacroInst, unsigned MacroSkipStart, - unsigned MacroSkipEnd); - + void EmitDiagnosticLoc(DiagnosticsEngine::Level Level, + const Diagnostic &Info, + const SourceManager &SM, + PresumedLoc PLoc); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h index 93d2c7d..929beb0 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h @@ -31,7 +31,7 @@ class CompilerInstance; class CompilerInvocation; class Decl; class DependencyOutputOptions; -class Diagnostic; +class DiagnosticsEngine; class DiagnosticOptions; class FileManager; class HeaderSearch; @@ -48,7 +48,7 @@ class FrontendOptions; /// Normalize \arg File for use in a user defined #include directive (in the /// predefines buffer). -std::string NormalizeDashIncludePath(llvm::StringRef File, +std::string NormalizeDashIncludePath(StringRef File, FileManager &FileMgr); /// Apply the header search options to get given HeaderSearch object. @@ -66,10 +66,10 @@ void InitializePreprocessor(Preprocessor &PP, /// ProcessWarningOptions - Initialize the diagnostic client and process the /// warning options specified on the command line. -void ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts); +void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts); /// DoPrintPreprocessedInput - Implement -E mode. -void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS, +void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS, const PreprocessorOutputOptions &Opts); /// AttachDependencyFileGen - Create a dependency file generator, and attach @@ -87,7 +87,7 @@ void AttachDependencyFileGen(Preprocessor &PP, /// \param OutputPath - If non-empty, a path to write the header include /// information to, instead of writing to stderr. void AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders = false, - llvm::StringRef OutputPath = "", + StringRef OutputPath = "", bool ShowDepth = true); /// CacheTokens - Cache tokens for use with PCH. Note that this requires @@ -100,9 +100,9 @@ void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS); /// \return A CompilerInvocation, or 0 if none was built for the given /// argument vector. CompilerInvocation * -createInvocationFromCommandLine(llvm::ArrayRef<const char *> Args, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags = - llvm::IntrusiveRefCntPtr<Diagnostic>()); +createInvocationFromCommandLine(ArrayRef<const char *> Args, + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags = + llvm::IntrusiveRefCntPtr<DiagnosticsEngine>()); } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticsClient.h b/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h index 793cedd..28dc9de 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticsClient.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h @@ -1,4 +1,4 @@ -//===-- VerifyDiagnosticsClient.h - Verifying Diagnostic Client -*- C++ -*-===// +//===- VerifyDiagnosticConsumer.h - Verifying Diagnostic Client -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,12 +15,12 @@ namespace clang { -class Diagnostic; +class DiagnosticsEngine; class TextDiagnosticBuffer; -/// VerifyDiagnosticsClient - Create a diagnostic client which will use markers -/// in the input source to check that all the emitted diagnostics match those -/// expected. +/// VerifyDiagnosticConsumer - Create a diagnostic client which will use +/// markers in the input source to check that all the emitted diagnostics match +/// those expected. /// /// USING THE DIAGNOSTIC CHECKER: /// @@ -62,31 +62,34 @@ class TextDiagnosticBuffer; /// // expected-error-re {{variable has has type 'struct (.*)'}} /// // expected-error-re {{variable has has type 'struct[[:space:]](.*)'}} /// -class VerifyDiagnosticsClient : public DiagnosticClient { +class VerifyDiagnosticConsumer: public DiagnosticConsumer { public: - Diagnostic &Diags; - llvm::OwningPtr<DiagnosticClient> PrimaryClient; + DiagnosticsEngine &Diags; + DiagnosticConsumer *PrimaryClient; + bool OwnsPrimaryClient; llvm::OwningPtr<TextDiagnosticBuffer> Buffer; Preprocessor *CurrentPreprocessor; private: + FileID FirstErrorFID; // FileID of first diagnostic void CheckDiagnostics(); public: /// Create a new verifying diagnostic client, which will issue errors to \arg - /// PrimaryClient when a diagnostic does not match what is expected (as - /// indicated in the source file). The verifying diagnostic client takes - /// ownership of \arg PrimaryClient. - VerifyDiagnosticsClient(Diagnostic &Diags, DiagnosticClient *PrimaryClient); - ~VerifyDiagnosticsClient(); + /// the currently-attached diagnostic client when a diagnostic does not match + /// what is expected (as indicated in the source file). + VerifyDiagnosticConsumer(DiagnosticsEngine &Diags); + ~VerifyDiagnosticConsumer(); virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP); virtual void EndSourceFile(); - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info); + + virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } // end namspace clang diff --git a/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h b/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h index fc18dae..7b66e7e 100644 --- a/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h +++ b/contrib/llvm/tools/clang/include/clang/Index/ASTLocation.h @@ -17,10 +17,6 @@ #include "clang/AST/TypeLoc.h" #include "llvm/ADT/PointerIntPair.h" -namespace llvm { - class raw_ostream; -} - namespace clang { class Decl; class Stmt; @@ -150,7 +146,7 @@ public: SourceRange getSourceRange() const; - void print(llvm::raw_ostream &OS) const; + void print(raw_ostream &OS) const; }; /// \brief Like ASTLocation but also contains the TranslationUnit that the diff --git a/contrib/llvm/tools/clang/include/clang/Index/CallGraph.h b/contrib/llvm/tools/clang/include/clang/Index/CallGraph.h index 336bf47..38baf0f 100644 --- a/contrib/llvm/tools/clang/include/clang/Index/CallGraph.h +++ b/contrib/llvm/tools/clang/include/clang/Index/CallGraph.h @@ -94,7 +94,7 @@ public: Decl *getDecl(CallGraphNode *Node); - void print(llvm::raw_ostream &os); + void print(raw_ostream &os); void dump(); void ViewCallGraph() const; diff --git a/contrib/llvm/tools/clang/include/clang/Index/Entity.h b/contrib/llvm/tools/clang/include/clang/Index/Entity.h index 9863963..d104458 100644 --- a/contrib/llvm/tools/clang/include/clang/Index/Entity.h +++ b/contrib/llvm/tools/clang/include/clang/Index/Entity.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_INDEX_ENTITY_H #define LLVM_CLANG_INDEX_ENTITY_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" @@ -73,7 +74,7 @@ public: static Entity get(Decl *D, Program &Prog); /// \brief Get an Entity associated with a name in the global namespace. - static Entity get(llvm::StringRef Name, Program &Prog); + static Entity get(StringRef Name, Program &Prog); /// \brief true if the Entity is not visible outside the trasnlation unit. bool isInternalToTU() const { diff --git a/contrib/llvm/tools/clang/include/clang/Index/Handlers.h b/contrib/llvm/tools/clang/include/clang/Index/Handlers.h index 655aef9..1e017f8 100644 --- a/contrib/llvm/tools/clang/include/clang/Index/Handlers.h +++ b/contrib/llvm/tools/clang/include/clang/Index/Handlers.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_INDEX_HANDLERS_H #define LLVM_CLANG_INDEX_HANDLERS_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/SmallVector.h" namespace clang { @@ -61,7 +62,7 @@ public: template <typename handler_type> class Storing : public handler_type { typedef typename handler_type::receiving_type receiving_type; - typedef llvm::SmallVector<receiving_type, 8> StoreTy; + typedef SmallVector<receiving_type, 8> StoreTy; StoreTy Store; public: diff --git a/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h b/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h index 0099d63..ba5d48d 100644 --- a/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h +++ b/contrib/llvm/tools/clang/include/clang/Index/TranslationUnit.h @@ -16,7 +16,7 @@ namespace clang { class ASTContext; - class Diagnostic; + class DiagnosticsEngine; class Preprocessor; namespace idx { @@ -29,7 +29,7 @@ public: virtual ~TranslationUnit(); virtual ASTContext &getASTContext() = 0; virtual Preprocessor &getPreprocessor() = 0; - virtual Diagnostic &getDiagnostic() = 0; + virtual DiagnosticsEngine &getDiagnostic() = 0; virtual DeclReferenceMap &getDeclReferenceMap() = 0; virtual SelectorMap &getSelectorMap() = 0; }; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/CodeCompletionHandler.h b/contrib/llvm/tools/clang/include/clang/Lex/CodeCompletionHandler.h index d28a3aa..d876776 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/CodeCompletionHandler.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/CodeCompletionHandler.h @@ -52,6 +52,10 @@ public: /// \brief Callback invoked when performing code completion inside a /// function-like macro argument. + /// + /// There will be another callback invocation after the macro arguments are + /// parsed, so this callback should generally be used to note that the next + /// callback is invoked inside a macro argument. virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned ArgumentIndex) { } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h b/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h index 1ee6953..f7da61b 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h @@ -14,12 +14,9 @@ #ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H #define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" -namespace llvm { - class StringRef; - template <typename T> class SmallVectorImpl; -} namespace clang { class HeaderMap; class DirectoryEntry; @@ -59,21 +56,27 @@ private: /// LookupType - This indicates whether this DirectoryLookup object is a /// normal directory, a framework, or a headermap. unsigned LookupType : 2; + + /// \brief Whether this is a header map used when building a framework. + unsigned IsIndexHeaderMap : 1; + public: /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of /// 'dir'. DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT, bool isUser, bool isFramework) - : DirCharacteristic(DT), UserSupplied(isUser), - LookupType(isFramework ? LT_Framework : LT_NormalDir) { + : DirCharacteristic(DT), UserSupplied(isUser), + LookupType(isFramework ? LT_Framework : LT_NormalDir), + IsIndexHeaderMap(false) { u.Dir = dir; } /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of /// 'map'. DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT, - bool isUser) - : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap) { + bool isUser, bool isIndexHeaderMap) + : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap), + IsIndexHeaderMap(isIndexHeaderMap) { u.Map = map; } @@ -119,7 +122,11 @@ public: /// bool isUserSupplied() const { return UserSupplied; } - + /// \brief Whether this header map is building a framework or not. + bool isIndexHeaderMap() const { + return isHeaderMap() && IsIndexHeaderMap; + } + /// LookupFile - Lookup the specified file in this search path, returning it /// if it exists or returning null if not. /// @@ -133,15 +140,25 @@ public: /// \param RelativePath If not NULL, will be set to the path relative to /// SearchPath at which the file was found. This only differs from the /// Filename for framework includes. - const FileEntry *LookupFile(llvm::StringRef Filename, HeaderSearch &HS, - llvm::SmallVectorImpl<char> *SearchPath, - llvm::SmallVectorImpl<char> *RelativePath) const; + /// + /// \param BuildingModule The name of the module we're currently building. + /// + /// \param SuggestedModule If non-null, and the file found is semantically + /// part of a known module, this will be set to the name of the module that + /// could be imported instead of preprocessing/parsing the file found. + const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS, + SmallVectorImpl<char> *SearchPath, + SmallVectorImpl<char> *RelativePath, + StringRef BuildingModule, + StringRef *SuggestedModule) const; private: const FileEntry *DoFrameworkLookup( - llvm::StringRef Filename, HeaderSearch &HS, - llvm::SmallVectorImpl<char> *SearchPath, - llvm::SmallVectorImpl<char> *RelativePath) const; + StringRef Filename, HeaderSearch &HS, + SmallVectorImpl<char> *SearchPath, + SmallVectorImpl<char> *RelativePath, + StringRef BuildingModule, + StringRef *SuggestedModule) const; }; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h index e333840..08bc5b6 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h @@ -14,10 +14,10 @@ #ifndef LLVM_CLANG_LEX_HEADERMAP_H #define LLVM_CLANG_LEX_HEADERMAP_H +#include "clang/Basic/LLVM.h" + namespace llvm { class MemoryBuffer; - class StringRef; - template <typename T> class SmallVectorImpl; } namespace clang { class FileEntry; @@ -52,7 +52,7 @@ public: /// raw path at which the file was found in the file system. For example, /// for a search path ".." and a filename "../file.h" this would be /// "../../file.h". - const FileEntry *LookupFile(llvm::StringRef Filename, FileManager &FM) const; + const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const; /// getFileName - Return the filename of the headermap. const char *getFileName() const; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h index 5e36d8e..84d59f7 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h @@ -16,6 +16,8 @@ #include "clang/Lex/DirectoryLookup.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/Allocator.h" #include <vector> namespace clang { @@ -47,6 +49,15 @@ struct HeaderFileInfo { /// "resolved", meaning that it was loaded from the external source. unsigned Resolved : 1; + /// \brief Whether this is a header inside a framework that is currently + /// being built. + /// + /// When a framework is being built, the headers have not yet been placed + /// into the appropriate framework subdirectories, and therefore are + /// provided via a header map. This bit indicates when this is one of + /// those framework headers. + unsigned IndexHeaderMapHeader : 1; + /// NumIncludes - This is the number of times the file has been included /// already. unsigned short NumIncludes; @@ -68,10 +79,14 @@ struct HeaderFileInfo { /// external storage. const IdentifierInfo *ControllingMacro; + /// \brief If this header came from a framework include, this is the name + /// of the framework. + StringRef Framework; + HeaderFileInfo() : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), - External(false), Resolved(false), NumIncludes(0), ControllingMacroID(0), - ControllingMacro(0) {} + External(false), Resolved(false), IndexHeaderMapHeader(false), + NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {} /// \brief Retrieve the controlling macro for this header file, if /// any. @@ -114,6 +129,12 @@ class HeaderSearch { unsigned SystemDirIdx; bool NoCurDirSearch; + /// \brief The path to the module cache. + std::string ModuleCachePath; + + /// \brief The name of the module we're building. + std::string BuildingModule; + /// FileInfo - This contains all of the preprocessor-specific data about files /// that are included. The vector is indexed by the FileEntry's UID. /// @@ -125,17 +146,23 @@ class HeaderSearch { /// and this value doesn't match the current query, the cache has to be /// ignored. The second value is the entry in SearchDirs that satisfied the /// query. - llvm::StringMap<std::pair<unsigned, unsigned> > LookupFileCache; + llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator> + LookupFileCache; /// FrameworkMap - This is a collection mapping a framework or subframework /// name like "Carbon" to the Carbon.framework directory. - llvm::StringMap<const DirectoryEntry *> FrameworkMap; + llvm::StringMap<const DirectoryEntry *, llvm::BumpPtrAllocator> + FrameworkMap; /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing /// headermaps. This vector owns the headermap. std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps; + /// \brief Uniqued set of framework names, which is used to track which + /// headers were included as framework headers. + llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames; + /// \brief Entity used to resolve the identifier IDs of controlling /// macros into IdentifierInfo pointers, as needed. ExternalIdentifierLookup *ExternalLookup; @@ -172,6 +199,13 @@ public: //LookupFileCache.clear(); } + /// \brief Set the path to the module cache and the name of the module + /// we're building + void configureModules(StringRef CachePath, StringRef BuildingModule) { + ModuleCachePath = CachePath; + this->BuildingModule = BuildingModule; + } + /// ClearFileInfo - Forget everything we know about headers so far. void ClearFileInfo() { FileInfo.clear(); @@ -211,12 +245,17 @@ public: /// \param RelativePath If non-null, will be set to the path relative to /// SearchPath at which the file was found. This only differs from the /// Filename for framework includes. - const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled, + /// + /// \param SuggestedModule If non-null, and the file found is semantically + /// part of a known module, this will be set to the name of the module that + /// could be imported instead of preprocessing/parsing the file found. + const FileEntry *LookupFile(StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, const FileEntry *CurFileEnt, - llvm::SmallVectorImpl<char> *SearchPath, - llvm::SmallVectorImpl<char> *RelativePath); + SmallVectorImpl<char> *SearchPath, + SmallVectorImpl<char> *RelativePath, + StringRef *SuggestedModule); /// LookupSubframeworkHeader - Look up a subframework for the specified /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from @@ -224,15 +263,15 @@ public: /// is a subframework within Carbon.framework. If so, return the FileEntry /// for the designated file, otherwise return null. const FileEntry *LookupSubframeworkHeader( - llvm::StringRef Filename, + StringRef Filename, const FileEntry *RelativeFileEnt, - llvm::SmallVectorImpl<char> *SearchPath, - llvm::SmallVectorImpl<char> *RelativePath); + SmallVectorImpl<char> *SearchPath, + SmallVectorImpl<char> *RelativePath); /// LookupFrameworkCache - Look up the specified framework name in our /// framework cache, returning the DirectoryEntry it is in if we know, /// otherwise, return null. - const DirectoryEntry *&LookupFrameworkCache(llvm::StringRef FWName) { + const DirectoryEntry *&LookupFrameworkCache(StringRef FWName) { return FrameworkMap.GetOrCreateValue(FWName).getValue(); } @@ -287,6 +326,23 @@ public: /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. const HeaderMap *CreateHeaderMap(const FileEntry *FE); + /// \brief Search in the module cache path for a module with the given + /// name. + /// + /// \param If non-NULL, will be set to the module file name we expected to + /// find (regardless of whether it was actually found or not). + /// + /// \param UmbrellaHeader If non-NULL, and no module was found in the module + /// cache, this routine will search in the framework paths to determine + /// whether a module can be built from an umbrella header. If so, the pointee + /// will be set to the path of the umbrella header. + /// + /// \returns A file describing the named module, if available, or NULL to + /// indicate that the module could not be found. + const FileEntry *lookupModule(StringRef ModuleName, + std::string *ModuleFileName = 0, + std::string *UmbrellaHeader = 0); + void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator; @@ -322,7 +378,13 @@ public: } search_dir_iterator system_dir_end() const { return SearchDirs.end(); } + /// \brief Retrieve a uniqued framework name. + StringRef getUniqueFrameworkName(StringRef Framework); + void PrintStats(); + + size_t getTotalMemory() const; + private: /// getFileInfo - Return the HeaderFileInfo structure for the specified diff --git a/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h index 7d2eb89..f454e23 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM, #define LEXSTART #include "clang/Basic/DiagnosticLexKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h b/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h index f429762..e01427f 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h @@ -21,11 +21,24 @@ #include <cassert> namespace clang { -class Diagnostic; +class DiagnosticsEngine; class SourceManager; class Preprocessor; class DiagnosticBuilder; +/// ConflictMarkerKind - Kinds of conflict marker which the lexer might be +/// recovering from. +enum ConflictMarkerKind { + /// Not within a conflict marker. + CMK_None, + /// A normal or diff3 conflict marker, initiated by at least 7 <s, + /// separated by at least 7 =s or |s, and terminated by at least 7 >s. + CMK_Normal, + /// A Perforce-style conflict marker, initiated by 4 >s, separated by 4 =s, + /// and terminated by 4 <s. + CMK_Perforce +}; + /// Lexer - This provides a simple interface that turns a text buffer into a /// stream of tokens. This provides no support for file reading or buffering, /// or buffering/seeking of tokens, only forward lexing is supported. It relies @@ -37,8 +50,7 @@ class Lexer : public PreprocessorLexer { const char *BufferEnd; // End of the buffer. SourceLocation FileLoc; // Location for start of file. LangOptions Features; // Features enabled by this language (cache). - bool Is_PragmaLexer : 1; // True if lexer for _Pragma handling. - bool IsInConflictMarker : 1; // True if in a VCS conflict marker '<<<<<<<' + bool Is_PragmaLexer; // True if lexer for _Pragma handling. //===--------------------------------------------------------------------===// // Context-specific lexing flags set by the preprocessor. @@ -66,6 +78,9 @@ class Lexer : public PreprocessorLexer { // line" flag set on it. bool IsAtStartOfLine; + // CurrentConflictMarkerState - The kind of conflict marker we are handling. + ConflictMarkerKind CurrentConflictMarkerState; + Lexer(const Lexer&); // DO NOT IMPLEMENT void operator=(const Lexer&); // DO NOT IMPLEMENT friend class Preprocessor; @@ -208,7 +223,7 @@ public: /// Stringify - Convert the specified string into a C string by escaping '\' /// and " characters. This does not add surrounding ""'s to the string. - static void Stringify(llvm::SmallVectorImpl<char> &Str); + static void Stringify(SmallVectorImpl<char> &Str); /// getSpelling - This method is used to get the spelling of a token into a @@ -244,8 +259,8 @@ public: /// This method lexes at the expansion depth of the given /// location and does not jump to the expansion or spelling /// location. - static llvm::StringRef getSpelling(SourceLocation loc, - llvm::SmallVectorImpl<char> &buffer, + static StringRef getSpelling(SourceLocation loc, + SmallVectorImpl<char> &buffer, const SourceManager &SourceMgr, const LangOptions &Features, bool *invalid = 0); @@ -322,7 +337,8 @@ public: /// of the file begins along with a boolean value indicating whether /// the preamble ends at the beginning of a new line. static std::pair<unsigned, bool> - ComputePreamble(const llvm::MemoryBuffer *Buffer, unsigned MaxLines = 0); + ComputePreamble(const llvm::MemoryBuffer *Buffer, const LangOptions &Features, + unsigned MaxLines = 0); //===--------------------------------------------------------------------===// // Internal implementation interfaces. @@ -456,6 +472,18 @@ public: /// them), skip over them and return the first non-escaped-newline found, /// otherwise return P. static const char *SkipEscapedNewLines(const char *P); + + /// \brief Checks that the given token is the first token that occurs after + /// the given location (this excludes comments and whitespace). Returns the + /// location immediately after the specified token. If the token is not found + /// or the location is inside a macro, the returned source location will be + /// invalid. + static SourceLocation findLocationAfterToken(SourceLocation loc, + tok::TokenKind TKind, + const SourceManager &SM, + const LangOptions &LangOpts, + bool SkipTrailingWhitespaceAndNewLine); + private: /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a @@ -471,9 +499,13 @@ private: // Helper functions to lex the remainder of a token of the specific type. void LexIdentifier (Token &Result, const char *CurPtr); void LexNumericConstant (Token &Result, const char *CurPtr); - void LexStringLiteral (Token &Result, const char *CurPtr,bool Wide); + void LexStringLiteral (Token &Result, const char *CurPtr, + tok::TokenKind Kind); + void LexRawStringLiteral (Token &Result, const char *CurPtr, + tok::TokenKind Kind); void LexAngledStringLiteral(Token &Result, const char *CurPtr); - void LexCharConstant (Token &Result, const char *CurPtr); + void LexCharConstant (Token &Result, const char *CurPtr, + tok::TokenKind Kind); bool LexEndOfFile (Token &Result, const char *CurPtr); bool SkipWhitespace (Token &Result, const char *CurPtr); @@ -483,6 +515,9 @@ private: bool IsStartOfConflictMarker(const char *CurPtr); bool HandleEndOfConflictMarker(const char *CurPtr); + + bool isCodeCompletionPoint(const char *CurPtr) const; + void cutOffLexing() { BufferPtr = BufferEnd; } }; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h b/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h index 0dbcd6d..b33092c 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h @@ -15,14 +15,16 @@ #ifndef CLANG_LITERALSUPPORT_H #define CLANG_LITERALSUPPORT_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/DataTypes.h" +#include "clang/Basic/TokenKinds.h" #include <cctype> namespace clang { -class Diagnostic; +class DiagnosticsEngine; class Preprocessor; class Token; class SourceLocation; @@ -123,15 +125,19 @@ private: /// character literal. class CharLiteralParser { uint64_t Value; - bool IsWide; + tok::TokenKind Kind; bool IsMultiChar; bool HadError; public: CharLiteralParser(const char *begin, const char *end, - SourceLocation Loc, Preprocessor &PP); + SourceLocation Loc, Preprocessor &PP, + tok::TokenKind kind); bool hadError() const { return HadError; } - bool isWide() const { return IsWide; } + bool isAscii() const { return Kind == tok::char_constant; } + bool isWide() const { return Kind == tok::wide_char_constant; } + bool isUTF16() const { return Kind == tok::utf16_char_constant; } + bool isUTF32() const { return Kind == tok::utf32_char_constant; } bool isMultiChar() const { return IsMultiChar; } uint64_t getValue() const { return Value; } }; @@ -143,11 +149,12 @@ class StringLiteralParser { const SourceManager &SM; const LangOptions &Features; const TargetInfo &Target; - Diagnostic *Diags; + DiagnosticsEngine *Diags; unsigned MaxTokenLength; unsigned SizeBound; - unsigned wchar_tByteWidth; + unsigned CharByteWidth; + tok::TokenKind Kind; llvm::SmallString<512> ResultBuf; char *ResultPtr; // cursor public: @@ -155,27 +162,24 @@ public: Preprocessor &PP, bool Complain = true); StringLiteralParser(const Token *StringToks, unsigned NumStringToks, const SourceManager &sm, const LangOptions &features, - const TargetInfo &target, Diagnostic *diags = 0) + const TargetInfo &target, DiagnosticsEngine *diags = 0) : SM(sm), Features(features), Target(target), Diags(diags), - MaxTokenLength(0), SizeBound(0), wchar_tByteWidth(0), - ResultPtr(ResultBuf.data()), hadError(false), AnyWide(false), Pascal(false) { + MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown), + ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) { init(StringToks, NumStringToks); } bool hadError; - bool AnyWide; bool Pascal; - llvm::StringRef GetString() const { - return llvm::StringRef(ResultBuf.data(), GetStringLength()); + StringRef GetString() const { + return StringRef(ResultBuf.data(), GetStringLength()); } unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); } unsigned GetNumStringChars() const { - if (AnyWide) - return GetStringLength() / wchar_tByteWidth; - return GetStringLength(); + return GetStringLength() / CharByteWidth; } /// getOffsetOfStringByte - This function returns the offset of the /// specified byte of the string data represented by Token. This handles @@ -184,9 +188,16 @@ public: /// If the Diagnostics pointer is non-null, then this will do semantic /// checking of the string literal and emit errors and warnings. unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const; - + + bool isAscii() { return Kind == tok::string_literal; } + bool isWide() { return Kind == tok::wide_string_literal; } + bool isUTF8() { return Kind == tok::utf8_string_literal; } + bool isUTF16() { return Kind == tok::utf16_string_literal; } + bool isUTF32() { return Kind == tok::utf32_string_literal; } + private: void init(const Token *StringToks, unsigned NumStringToks); + void CopyStringFragment(StringRef Fragment); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h index 9e9d7cf..b381e0f 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h @@ -39,9 +39,14 @@ class MacroInfo { IdentifierInfo **ArgumentList; unsigned NumArguments; + /// \brief The location at which this macro was exported from its module. + /// + /// If invalid, this macro has not been explicitly exported. + SourceLocation ExportLocation; + /// ReplacementTokens - This is the list of tokens that the macro is defined /// to. - llvm::SmallVector<Token, 8> ReplacementTokens; + SmallVector<Token, 8> ReplacementTokens; /// \brief Length in characters of the macro definition. mutable unsigned DefinitionLength; @@ -68,6 +73,9 @@ class MacroInfo { /// IsFromAST - True if this macro was loaded from an AST file. bool IsFromAST : 1; + /// \brief Whether this macro changed after it was loaded from an AST file. + bool ChangedAfterLoad : 1; + private: //===--------------------------------------------------------------------===// // State that changes as the macro is used. @@ -209,6 +217,14 @@ public: /// setIsFromAST - Set whether this macro was loaded from an AST file. void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; } + /// \brief Determine whether this macro has changed since it was loaded from + /// an AST file. + bool hasChangedAfterLoad() const { return ChangedAfterLoad; } + + /// \brief Note whether this macro has changed after it was loaded from an + /// AST file. + void setChangedAfterLoad(bool CAL = true) { ChangedAfterLoad = CAL; } + /// isUsed - Return false if this macro is defined in the main file and has /// not yet been used. bool isUsed() const { return IsUsed; } @@ -235,7 +251,7 @@ public: return ReplacementTokens[Tok]; } - typedef llvm::SmallVector<Token, 8>::const_iterator tokens_iterator; + typedef SmallVector<Token, 8>::const_iterator tokens_iterator; tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); } tokens_iterator tokens_end() const { return ReplacementTokens.end(); } bool tokens_empty() const { return ReplacementTokens.empty(); } @@ -262,6 +278,19 @@ public: IsDisabled = true; } + /// \brief Set the export location for this macro. + void setExportLocation(SourceLocation ExportLoc) { + ExportLocation = ExportLoc; + } + + /// \brief Determine whether this macro was explicitly exported from its + /// module. + bool isExported() const { return ExportLocation.isValid(); } + + /// \brief Determine the location where this macro was explicitly exported + /// from its module. + SourceLocation getExportLocation() { return ExportLocation; } + private: unsigned getDefinitionLengthSlow(SourceManager &SM) const; }; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/ModuleLoader.h b/contrib/llvm/tools/clang/include/clang/Lex/ModuleLoader.h new file mode 100644 index 0000000..72ec0e3 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Lex/ModuleLoader.h @@ -0,0 +1,55 @@ +//===--- ModuleLoader.h - Module Loader Interface ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ModuleLoader interface, which is responsible for +// loading named modules. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LEX_MODULE_LOADER_H +#define LLVM_CLANG_LEX_MODULE_LOADER_H + +#include "clang/Basic/SourceLocation.h" + +namespace clang { + +class IdentifierInfo; + +/// \brief An opaque key that is used to describe the module and can be +/// interpreted by the module loader itself. +typedef void *ModuleKey; + +/// \brief Abstract interface for a module loader. +/// +/// This abstract interface describes a module loader, which is responsible +/// for resolving a module name (e.g., "std") to an actual module file, and +/// then loading that module. +class ModuleLoader { +public: + virtual ~ModuleLoader(); + + /// \brief Attempt to load the given module. + /// + /// This routine attempts to load the module described by the given + /// parameters. + /// + /// \param ImportLoc The location of the 'import' keyword. + /// \param ModuleName The name of the module to be loaded. + /// \param ModuleNameLoc The location of the module name. + /// + /// \returns If successful, a non-NULL module key describing this module. + /// Otherwise, returns NULL to indicate that the module could not be + /// loaded. + virtual ModuleKey loadModule(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc) = 0; +}; + +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h index a794815..1fc1a05 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h @@ -42,8 +42,11 @@ public: /// EnteringFile indicates whether this is because we are entering a new /// #include'd file (when true) or whether we're exiting one because we ran /// off the end (when false). + /// + /// \param PrevFID the file that was exited if \arg Reason is ExitFile. virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType) { + SrcMgr::CharacteristicKind FileType, + FileID PrevFID = FileID()) { } /// FileSkipped - This callback is invoked whenever a source file is @@ -90,12 +93,12 @@ public: /// file was found. This is equal to FileName except for framework includes. virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, - llvm::StringRef FileName, + StringRef FileName, bool IsAngled, const FileEntry *File, SourceLocation EndLoc, - llvm::StringRef SearchPath, - llvm::StringRef RelativePath) { + StringRef SearchPath, + StringRef RelativePath) { } /// EndOfMainFile - This callback is invoked when the end of the main file is @@ -122,31 +125,32 @@ public: /// \param Loc The location of the message directive. /// \param str The text of the message directive. /// - virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) { + virtual void PragmaMessage(SourceLocation Loc, StringRef Str) { } /// PragmaDiagnosticPush - This callback is invoked when a /// #pragma gcc dianostic push directive is read. virtual void PragmaDiagnosticPush(SourceLocation Loc, - llvm::StringRef Namespace) { + StringRef Namespace) { } /// PragmaDiagnosticPop - This callback is invoked when a /// #pragma gcc dianostic pop directive is read. virtual void PragmaDiagnosticPop(SourceLocation Loc, - llvm::StringRef Namespace) { + StringRef Namespace) { } /// PragmaDiagnostic - This callback is invoked when a /// #pragma gcc dianostic directive is read. - virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace, - diag::Mapping mapping, llvm::StringRef Str) { + virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, + diag::Mapping mapping, StringRef Str) { } /// MacroExpands - This is called by /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is /// found. - virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) { + virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI, + SourceRange Range) { } /// MacroDefined - This hook is called whenever a macro definition is seen. @@ -157,6 +161,16 @@ public: /// MI is released immediately following this callback. virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) { } + + /// Defined - This hook is called whenever the 'defined' operator is seen. + virtual void Defined(const Token &MacroNameTok) { + } + + /// SourceRangeSkipped - This hook is called when a source range is skipped. + /// \param Range The SourceRange that was skipped. The range begins at the + /// #if/#else directive and ends after the #endif/#else directive. + virtual void SourceRangeSkipped(SourceRange Range) { + } /// If -- This hook is called whenever an #if is seen. /// \param Range The SourceRange of the expression being tested. @@ -204,9 +218,10 @@ public: } virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType) { - First->FileChanged(Loc, Reason, FileType); - Second->FileChanged(Loc, Reason, FileType); + SrcMgr::CharacteristicKind FileType, + FileID PrevFID) { + First->FileChanged(Loc, Reason, FileType, PrevFID); + Second->FileChanged(Loc, Reason, FileType, PrevFID); } virtual void FileSkipped(const FileEntry &ParentFile, @@ -218,12 +233,12 @@ public: virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, - llvm::StringRef FileName, + StringRef FileName, bool IsAngled, const FileEntry *File, SourceLocation EndLoc, - llvm::StringRef SearchPath, - llvm::StringRef RelativePath) { + StringRef SearchPath, + StringRef RelativePath) { First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, EndLoc, SearchPath, RelativePath); Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, @@ -246,32 +261,33 @@ public: Second->PragmaComment(Loc, Kind, Str); } - virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) { + virtual void PragmaMessage(SourceLocation Loc, StringRef Str) { First->PragmaMessage(Loc, Str); Second->PragmaMessage(Loc, Str); } virtual void PragmaDiagnosticPush(SourceLocation Loc, - llvm::StringRef Namespace) { + StringRef Namespace) { First->PragmaDiagnosticPush(Loc, Namespace); Second->PragmaDiagnosticPush(Loc, Namespace); } virtual void PragmaDiagnosticPop(SourceLocation Loc, - llvm::StringRef Namespace) { + StringRef Namespace) { First->PragmaDiagnosticPop(Loc, Namespace); Second->PragmaDiagnosticPop(Loc, Namespace); } - virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace, - diag::Mapping mapping, llvm::StringRef Str) { + virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, + diag::Mapping mapping, StringRef Str) { First->PragmaDiagnostic(Loc, Namespace, mapping, Str); Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); } - virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) { - First->MacroExpands(MacroNameTok, MI); - Second->MacroExpands(MacroNameTok, MI); + virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI, + SourceRange Range) { + First->MacroExpands(MacroNameTok, MI, Range); + Second->MacroExpands(MacroNameTok, MI, Range); } virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { @@ -284,6 +300,16 @@ public: Second->MacroUndefined(MacroNameTok, MI); } + virtual void Defined(const Token &MacroNameTok) { + First->Defined(MacroNameTok); + Second->Defined(MacroNameTok); + } + + virtual void SourceRangeSkipped(SourceRange Range) { + First->SourceRangeSkipped(Range); + Second->SourceRangeSkipped(Range); + } + /// If -- This hook is called whenever an #if is seen. virtual void If(SourceRange Range) { First->If(Range); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h b/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h index 094b7ef..25a4903 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h @@ -30,7 +30,7 @@ namespace clang { class FileEntry; class PTHLexer; -class Diagnostic; +class DiagnosticsEngine; class FileSystemStatCache; class PTHManager : public IdentifierInfoLookup { @@ -115,11 +115,11 @@ public: /// Unlike the version in IdentifierTable, this returns a pointer instead /// of a reference. If the pointer is NULL then the IdentifierInfo cannot /// be found. - IdentifierInfo *get(llvm::StringRef Name); + IdentifierInfo *get(StringRef Name); /// Create - This method creates PTHManager objects. The 'file' argument /// is the name of the PTH file. This method returns NULL upon failure. - static PTHManager *Create(const std::string& file, Diagnostic &Diags); + static PTHManager *Create(const std::string& file, DiagnosticsEngine &Diags); void setPreprocessor(Preprocessor *pp) { PP = pp; } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h b/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h index c6ab35c..4868811 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_PRAGMA_H #define LLVM_CLANG_PRAGMA_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include <cassert> @@ -58,11 +59,11 @@ namespace clang { class PragmaHandler { std::string Name; public: - explicit PragmaHandler(llvm::StringRef name) : Name(name) {} + explicit PragmaHandler(StringRef name) : Name(name) {} PragmaHandler() {} virtual ~PragmaHandler(); - llvm::StringRef getName() const { return Name; } + StringRef getName() const { return Name; } virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstToken) = 0; @@ -91,14 +92,14 @@ class PragmaNamespace : public PragmaHandler { /// llvm::StringMap<PragmaHandler*> Handlers; public: - explicit PragmaNamespace(llvm::StringRef Name) : PragmaHandler(Name) {} + explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {} virtual ~PragmaNamespace(); /// FindHandler - Check to see if there is already a handler for the /// specified name. If not, return the handler for the null name if it /// exists, otherwise return null. If IgnoreNull is true (the default) then /// the null handler isn't returned on failure to match. - PragmaHandler *FindHandler(llvm::StringRef Name, + PragmaHandler *FindHandler(StringRef Name, bool IgnoreNull = true) const; /// AddPragma - Add a pragma to this namespace. diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h index b38303a..53da19e 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h @@ -16,6 +16,7 @@ #include "clang/Lex/PPCallbacks.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" #include <vector> @@ -43,14 +44,14 @@ namespace clang { public: /// \brief The kind of preprocessed entity an object describes. enum EntityKind { + /// \brief Indicates a problem trying to load the preprocessed entity. + InvalidKind, + /// \brief A macro expansion. MacroExpansionKind, - /// \brief A preprocessing directive whose kind is not specified. - /// - /// This kind will be used for any preprocessing directive that does not - /// have a more specific kind within the \c DirectiveKind enumeration. - PreprocessingDirectiveKind, + /// \defgroup Preprocessing directives + /// @{ /// \brief A macro definition. MacroDefinitionKind, @@ -59,7 +60,9 @@ namespace clang { /// #import, or \c #include_next. InclusionDirectiveKind, - FirstPreprocessingDirective = PreprocessingDirectiveKind, + /// @} + + FirstPreprocessingDirective = MacroDefinitionKind, LastPreprocessingDirective = InclusionDirectiveKind }; @@ -73,7 +76,9 @@ namespace clang { protected: PreprocessedEntity(EntityKind Kind, SourceRange Range) : Kind(Kind), Range(Range) { } - + + friend class PreprocessingRecord; + public: /// \brief Retrieve the kind of preprocessed entity stored in this object. EntityKind getKind() const { return Kind; } @@ -81,7 +86,11 @@ namespace clang { /// \brief Retrieve the source range that covers this entire preprocessed /// entity. SourceRange getSourceRange() const { return Range; } - + + /// \brief Returns true if there was a problem loading the preprocessed + /// entity. + bool isInvalid() const { return Kind == InvalidKind; } + // Implement isa/cast/dyncast/etc. static bool classof(const PreprocessedEntity *) { return true; } @@ -110,34 +119,6 @@ namespace clang { void operator delete(void* data) throw(); }; - /// \brief Records the location of a macro expansion. - class MacroExpansion : public PreprocessedEntity { - /// \brief The name of the macro being expanded. - IdentifierInfo *Name; - - /// \brief The definition of this macro. - MacroDefinition *Definition; - - public: - MacroExpansion(IdentifierInfo *Name, SourceRange Range, - MacroDefinition *Definition) - : PreprocessedEntity(MacroExpansionKind, Range), Name(Name), - Definition(Definition) { } - - /// \brief The name of the macro being expanded. - IdentifierInfo *getName() const { return Name; } - - /// \brief The definition of the macro being expanded. - MacroDefinition *getDefinition() const { return Definition; } - - // Implement isa/cast/dyncast/etc. - static bool classof(const PreprocessedEntity *PE) { - return PE->getKind() == MacroExpansionKind; - } - static bool classof(const MacroExpansion *) { return true; } - - }; - /// \brief Records the presence of a preprocessor directive. class PreprocessingDirective : public PreprocessedEntity { public: @@ -156,21 +137,16 @@ namespace clang { class MacroDefinition : public PreprocessingDirective { /// \brief The name of the macro being defined. const IdentifierInfo *Name; - - /// \brief The location of the macro name in the macro definition. - SourceLocation Location; public: - explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location, - SourceRange Range) - : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name), - Location(Location) { } + explicit MacroDefinition(const IdentifierInfo *Name, SourceRange Range) + : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) { } /// \brief Retrieve the name of the macro being defined. const IdentifierInfo *getName() const { return Name; } /// \brief Retrieve the location of the macro name in the definition. - SourceLocation getLocation() const { return Location; } + SourceLocation getLocation() const { return getSourceRange().getBegin(); } // Implement isa/cast/dyncast/etc. static bool classof(const PreprocessedEntity *PE) { @@ -178,6 +154,44 @@ namespace clang { } static bool classof(const MacroDefinition *) { return true; } }; + + /// \brief Records the location of a macro expansion. + class MacroExpansion : public PreprocessedEntity { + /// \brief The definition of this macro or the name of the macro if it is + /// a builtin macro. + llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef; + + public: + MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range) + : PreprocessedEntity(MacroExpansionKind, Range), + NameOrDef(BuiltinName) { } + + MacroExpansion(MacroDefinition *Definition, SourceRange Range) + : PreprocessedEntity(MacroExpansionKind, Range), + NameOrDef(Definition) { } + + /// \brief True if it is a builtin macro. + bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); } + + /// \brief The name of the macro being expanded. + const IdentifierInfo *getName() const { + if (MacroDefinition *Def = getDefinition()) + return Def->getName(); + return NameOrDef.get<IdentifierInfo*>(); + } + + /// \brief The definition of the macro being expanded. May return null if + /// this is a builtin macro. + MacroDefinition *getDefinition() const { + return NameOrDef.dyn_cast<MacroDefinition *>(); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const PreprocessedEntity *PE) { + return PE->getKind() == MacroExpansionKind; + } + static bool classof(const MacroExpansion *) { return true; } + }; /// \brief Record the location of an inclusion directive, such as an /// \c #include or \c #import statement. @@ -199,7 +213,7 @@ namespace clang { private: /// \brief The name of the file that was included, as written in /// the source. - llvm::StringRef FileName; + StringRef FileName; /// \brief Whether the file name was in quotation marks; otherwise, it was /// in angle brackets. @@ -215,14 +229,14 @@ namespace clang { public: InclusionDirective(PreprocessingRecord &PPRec, - InclusionKind Kind, llvm::StringRef FileName, + InclusionKind Kind, StringRef FileName, bool InQuotes, const FileEntry *File, SourceRange Range); /// \brief Determine what kind of inclusion directive this is. InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); } /// \brief Retrieve the included file name as it was written in the source. - llvm::StringRef getFileName() const { return FileName; } + StringRef getFileName() const { return FileName; } /// \brief Determine whether the included file name was written in quotes; /// otherwise, it was written in angle brackets. @@ -245,19 +259,24 @@ namespace clang { public: virtual ~ExternalPreprocessingRecordSource(); - /// \brief Read any preallocated preprocessed entities from the external - /// source. - virtual void ReadPreprocessedEntities() = 0; - - /// \brief Read the preprocessed entity at the given offset. - virtual PreprocessedEntity * - ReadPreprocessedEntityAtOffset(uint64_t Offset) = 0; + /// \brief Read a preallocated preprocessed entity from the external source. + /// + /// \returns null if an error occurred that prevented the preprocessed + /// entity from being loaded. + virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0; + + /// \brief Returns a pair of [Begin, End) indices of preallocated + /// preprocessed entities that \arg Range encompasses. + virtual std::pair<unsigned, unsigned> + findPreprocessedEntitiesInRange(SourceRange Range) = 0; }; /// \brief A record of the steps taken while preprocessing a source file, /// including the various preprocessing directives processed, macros /// expanded, etc. class PreprocessingRecord : public PPCallbacks { + SourceManager &SourceMgr; + /// \brief Whether we should include nested macro expansions in /// the preprocessing record. bool IncludeNestedMacroExpansions; @@ -269,24 +288,64 @@ namespace clang { /// were seen. std::vector<PreprocessedEntity *> PreprocessedEntities; + /// \brief The set of preprocessed entities in this record that have been + /// loaded from external sources. + /// + /// The entries in this vector are loaded lazily from the external source, + /// and are referenced by the iterator using negative indices. + std::vector<PreprocessedEntity *> LoadedPreprocessedEntities; + + /// \brief Global (loaded or local) ID for a preprocessed entity. + /// Negative values are used to indicate preprocessed entities + /// loaded from the external source while non-negative values are used to + /// indicate preprocessed entities introduced by the current preprocessor. + /// If M is the number of loaded preprocessed entities, value -M + /// corresponds to element 0 in the loaded entities vector, position -M+1 + /// corresponds to element 1 in the loaded entities vector, etc. + typedef int PPEntityID; + + PPEntityID getPPEntityID(unsigned Index, bool isLoaded) const { + return isLoaded ? PPEntityID(Index) - LoadedPreprocessedEntities.size() + : Index; + } + /// \brief Mapping from MacroInfo structures to their definitions. - llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions; + llvm::DenseMap<const MacroInfo *, PPEntityID> MacroDefinitions; /// \brief External source of preprocessed entities. ExternalPreprocessingRecordSource *ExternalSource; + + /// \brief Retrieve the preprocessed entity at the given ID. + PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID); + + /// \brief Retrieve the loaded preprocessed entity at the given index. + PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index); - /// \brief The number of preallocated entities (that are known to the - /// external source). - unsigned NumPreallocatedEntities; - - /// \brief Whether we have already loaded all of the preallocated entities. - mutable bool LoadedPreallocatedEntities; - - void MaybeLoadPreallocatedEntities() const ; + /// \brief Determine the number of preprocessed entities that were + /// loaded (or can be loaded) from an external source. + unsigned getNumLoadedPreprocessedEntities() const { + return LoadedPreprocessedEntities.size(); + } + + /// \brief Returns a pair of [Begin, End) indices of local preprocessed + /// entities that \arg Range encompasses. + std::pair<unsigned, unsigned> + findLocalPreprocessedEntitiesInRange(SourceRange Range) const; + unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const; + unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const; + + /// \brief Allocate space for a new set of loaded preprocessed entities. + /// + /// \returns The index into the set of loaded preprocessed entities, which + /// corresponds to the first newly-allocated entity. + unsigned allocateLoadedEntities(unsigned NumEntities); + + /// \brief Register a new macro definition. + void RegisterMacroDefinition(MacroInfo *Macro, PPEntityID PPID); public: - /// \brief Construct - explicit PreprocessingRecord(bool IncludeNestedMacroExpansions); + /// \brief Construct a new preprocessing record. + PreprocessingRecord(SourceManager &SM, bool IncludeNestedMacroExpansions); /// \brief Allocate memory in the preprocessing record. void *Allocate(unsigned Size, unsigned Align = 8) { @@ -295,64 +354,180 @@ namespace clang { /// \brief Deallocate memory in the preprocessing record. void Deallocate(void *Ptr) { } - - size_t getTotalMemory() const { - return BumpAlloc.getTotalMemory(); - } - + + size_t getTotalMemory() const; + + SourceManager &getSourceManager() const { return SourceMgr; } + // Iteration over the preprocessed entities. - typedef std::vector<PreprocessedEntity *>::iterator iterator; - typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator; - iterator begin(bool OnlyLocalEntities = false); - iterator end(bool OnlyLocalEntities = false); - const_iterator begin(bool OnlyLocalEntities = false) const; - const_iterator end(bool OnlyLocalEntities = false) const; + class iterator { + PreprocessingRecord *Self; + + /// \brief Position within the preprocessed entity sequence. + /// + /// In a complete iteration, the Position field walks the range [-M, N), + /// where negative values are used to indicate preprocessed entities + /// loaded from the external source while non-negative values are used to + /// indicate preprocessed entities introduced by the current preprocessor. + /// However, to provide iteration in source order (for, e.g., chained + /// precompiled headers), dereferencing the iterator flips the negative + /// values (corresponding to loaded entities), so that position -M + /// corresponds to element 0 in the loaded entities vector, position -M+1 + /// corresponds to element 1 in the loaded entities vector, etc. This + /// gives us a reasonably efficient, source-order walk. + PPEntityID Position; + + public: + typedef PreprocessedEntity *value_type; + typedef value_type& reference; + typedef value_type* pointer; + typedef std::random_access_iterator_tag iterator_category; + typedef int difference_type; + + iterator() : Self(0), Position(0) { } + + iterator(PreprocessingRecord *Self, int Position) + : Self(Self), Position(Position) { } + + value_type operator*() const { + return Self->getPreprocessedEntity(Position); + } + + value_type operator[](difference_type D) { + return *(*this + D); + } + + iterator &operator++() { + ++Position; + return *this; + } + + iterator operator++(int) { + iterator Prev(*this); + ++Position; + return Prev; + } + + iterator &operator--() { + --Position; + return *this; + } + + iterator operator--(int) { + iterator Prev(*this); + --Position; + return Prev; + } + + friend bool operator==(const iterator &X, const iterator &Y) { + return X.Position == Y.Position; + } + + friend bool operator!=(const iterator &X, const iterator &Y) { + return X.Position != Y.Position; + } + + friend bool operator<(const iterator &X, const iterator &Y) { + return X.Position < Y.Position; + } + + friend bool operator>(const iterator &X, const iterator &Y) { + return X.Position > Y.Position; + } + + friend bool operator<=(const iterator &X, const iterator &Y) { + return X.Position < Y.Position; + } + + friend bool operator>=(const iterator &X, const iterator &Y) { + return X.Position > Y.Position; + } + + friend iterator& operator+=(iterator &X, difference_type D) { + X.Position += D; + return X; + } + + friend iterator& operator-=(iterator &X, difference_type D) { + X.Position -= D; + return X; + } + + friend iterator operator+(iterator X, difference_type D) { + X.Position += D; + return X; + } + + friend iterator operator+(difference_type D, iterator X) { + X.Position += D; + return X; + } + + friend difference_type operator-(const iterator &X, const iterator &Y) { + return X.Position - Y.Position; + } + + friend iterator operator-(iterator X, difference_type D) { + X.Position -= D; + return X; + } + }; + friend class iterator; + + /// \brief Begin iterator for all preprocessed entities. + iterator begin() { + return iterator(this, -(int)LoadedPreprocessedEntities.size()); + } + + /// \brief End iterator for all preprocessed entities. + iterator end() { + return iterator(this, PreprocessedEntities.size()); + } + + /// \brief Begin iterator for local, non-loaded, preprocessed entities. + iterator local_begin() { + return iterator(this, 0); + } + + /// \brief End iterator for local, non-loaded, preprocessed entities. + iterator local_end() { + return iterator(this, PreprocessedEntities.size()); + } + + /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities + /// that source range \arg R encompasses. + std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R); /// \brief Add a new preprocessed entity to this record. void addPreprocessedEntity(PreprocessedEntity *Entity); /// \brief Set the external source for preprocessed entities. - void SetExternalSource(ExternalPreprocessingRecordSource &Source, - unsigned NumPreallocatedEntities); + void SetExternalSource(ExternalPreprocessingRecordSource &Source); /// \brief Retrieve the external source for preprocessed entities. ExternalPreprocessingRecordSource *getExternalSource() const { return ExternalSource; } - unsigned getNumPreallocatedEntities() const { - return NumPreallocatedEntities; - } - - /// \brief Set the preallocated entry at the given index to the given - /// preprocessed entity. - void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity); - - /// \brief Register a new macro definition. - void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD); - - /// \brief Retrieve the preprocessed entity at the given index. - PreprocessedEntity *getPreprocessedEntity(unsigned Index) { - assert(Index < PreprocessedEntities.size() && - "Out-of-bounds preprocessed entity"); - return PreprocessedEntities[Index]; - } - /// \brief Retrieve the macro definition that corresponds to the given /// \c MacroInfo. MacroDefinition *findMacroDefinition(const MacroInfo *MI); - - virtual void MacroExpands(const Token &Id, const MacroInfo* MI); + + virtual void MacroExpands(const Token &Id, const MacroInfo* MI, + SourceRange Range); virtual void MacroDefined(const Token &Id, const MacroInfo *MI); virtual void MacroUndefined(const Token &Id, const MacroInfo *MI); virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, - llvm::StringRef FileName, + StringRef FileName, bool IsAngled, const FileEntry *File, SourceLocation EndLoc, - llvm::StringRef SearchPath, - llvm::StringRef RelativePath); + StringRef SearchPath, + StringRef RelativePath); + + friend class ASTReader; + friend class ASTWriter; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h index f6f3205..8b77433 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h @@ -49,6 +49,7 @@ class PPCallbacks; class CodeCompletionHandler; class DirectoryLookup; class PreprocessingRecord; +class ModuleLoader; /// Preprocessor - This object engages in a tight little dance with the lexer to /// efficiently preprocess tokens. Lexers know only about tokens within a @@ -56,17 +57,19 @@ class PreprocessingRecord; /// like the #include stack, token expansion, etc. /// class Preprocessor : public llvm::RefCountedBase<Preprocessor> { - Diagnostic *Diags; - LangOptions Features; - const TargetInfo &Target; + DiagnosticsEngine *Diags; + LangOptions &Features; + const TargetInfo *Target; FileManager &FileMgr; SourceManager &SourceMgr; ScratchBuffer *ScratchBuf; HeaderSearch &HeaderInfo; + ModuleLoader &TheModuleLoader; /// \brief External source of macros. ExternalPreprocessorSource *ExternalSource; + /// PTH - An optional PTHManager object used for getting tokens from /// a token cache rather than lexing the original source file. llvm::OwningPtr<PTHManager> PTH; @@ -90,6 +93,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { IdentifierInfo *Ident__has_attribute; // __has_attribute IdentifierInfo *Ident__has_include; // __has_include IdentifierInfo *Ident__has_include_next; // __has_include_next + IdentifierInfo *Ident__has_warning; // __has_warning SourceLocation DATELoc, TIMELoc; unsigned CounterValue; // Next __COUNTER__ value. @@ -102,7 +106,9 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { // State that is set before the preprocessor begins. bool KeepComments : 1; bool KeepMacroComments : 1; - + bool SuppressIncludeNotFoundError : 1; + bool AutoModuleImport : 1; + // State that changes while the preprocessor runs: bool InMacroArgs : 1; // True if parsing fn macro invocation args. @@ -145,6 +151,29 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// \brief The file that we're performing code-completion for, if any. const FileEntry *CodeCompletionFile; + /// \brief The offset in file for the code-completion point. + unsigned CodeCompletionOffset; + + /// \brief The location for the code-completion point. This gets instantiated + /// when the CodeCompletionFile gets #include'ed for preprocessing. + SourceLocation CodeCompletionLoc; + + /// \brief The start location for the file of the code-completion point. + /// This gets instantiated when the CodeCompletionFile gets #include'ed + /// for preprocessing. + SourceLocation CodeCompletionFileLoc; + + /// \brief The source location of the __import_module__ keyword we just + /// lexed, if any. + SourceLocation ModuleImportLoc; + + /// \brief The source location of the currently-active + /// #pragma clang arc_cf_code_audited begin. + SourceLocation PragmaARCCFCodeAuditedLoc; + + /// \brief True if we hit the code-completion point. + bool CodeCompletionReached; + /// \brief The number of bytes that we will initially skip when entering the /// main file, which is used when loading a precompiled preamble, along /// with a flag that indicates whether skipping this number of bytes will @@ -165,7 +194,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// if not expanding a macro. This is an alias for either CurLexer or /// CurPTHLexer. PreprocessorLexer *CurPPLexer; - + /// CurLookup - The DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. This allows us to /// implement #include_next and find directory-specific properties. @@ -175,20 +204,31 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// expanding a macro. One of CurLexer and CurTokenLexer must be null. llvm::OwningPtr<TokenLexer> CurTokenLexer; + /// \brief The kind of lexer we're currently working with. + enum CurLexerKind { + CLK_Lexer, + CLK_PTHLexer, + CLK_TokenLexer, + CLK_CachingLexer, + CLK_LexAfterModuleImport + } CurLexerKind; + /// IncludeMacroStack - This keeps track of the stack of files currently /// #included, and macros currently being expanded from, not counting /// CurLexer/CurTokenLexer. struct IncludeStackInfo { + enum CurLexerKind CurLexerKind; Lexer *TheLexer; PTHLexer *ThePTHLexer; PreprocessorLexer *ThePPLexer; TokenLexer *TheTokenLexer; const DirectoryLookup *TheDirLookup; - IncludeStackInfo(Lexer *L, PTHLexer* P, PreprocessorLexer* PPL, + IncludeStackInfo(enum CurLexerKind K, Lexer *L, PTHLexer* P, + PreprocessorLexer* PPL, TokenLexer* TL, const DirectoryLookup *D) - : TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL), TheTokenLexer(TL), - TheDirLookup(D) {} + : CurLexerKind(K), TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL), + TheTokenLexer(TL), TheDirLookup(D) {} }; std::vector<IncludeStackInfo> IncludeMacroStack; @@ -220,10 +260,6 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// previous macro value. llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo; - /// \brief Expansion source location for the last macro that expanded - /// to no tokens. - SourceLocation LastEmptyMacroExpansionLoc; - // Various statistics we track for performance analysis. unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma; unsigned NumIf, NumElse, NumEndif; @@ -246,7 +282,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// Works like a stack; a TokenLexer adds the macro expanded tokens that is /// going to lex in the cache and when it finishes the tokens are removed /// from the end of the cache. - llvm::SmallVector<Token, 16> MacroExpandedTokens; + SmallVector<Token, 16> MacroExpandedTokens; std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack; /// \brief A record of the macro definitions and expansions that @@ -257,7 +293,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { PreprocessingRecord *Record; private: // Cached tokens state. - typedef llvm::SmallVector<Token, 1> CachedTokensTy; + typedef SmallVector<Token, 1> CachedTokensTy; /// CachedTokens - Cached tokens are stored here when we do backtracking or /// lookahead. They are "lexed" by the CachingLex() method. @@ -291,19 +327,27 @@ private: // Cached tokens state. MacroInfo *getInfoForMacro(IdentifierInfo *II) const; public: - Preprocessor(Diagnostic &diags, const LangOptions &opts, - const TargetInfo &target, + Preprocessor(DiagnosticsEngine &diags, LangOptions &opts, + const TargetInfo *target, SourceManager &SM, HeaderSearch &Headers, + ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup = 0, - bool OwnsHeaderSearch = false); + bool OwnsHeaderSearch = false, + bool DelayInitialization = false); ~Preprocessor(); - Diagnostic &getDiagnostics() const { return *Diags; } - void setDiagnostics(Diagnostic &D) { Diags = &D; } + /// \brief Initialize the preprocessor, if the constructor did not already + /// perform the initialization. + /// + /// \param Target Information about the target. + void Initialize(const TargetInfo &Target); + + DiagnosticsEngine &getDiagnostics() const { return *Diags; } + void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; } const LangOptions &getLangOptions() const { return Features; } - const TargetInfo &getTargetInfo() const { return Target; } + const TargetInfo &getTargetInfo() const { return *Target; } FileManager &getFileManager() const { return FileMgr; } SourceManager &getSourceManager() const { return SourceMgr; } HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; } @@ -325,6 +369,9 @@ public: return ExternalSource; } + /// \brief Retrieve the module loader associated with this preprocessor. + ModuleLoader &getModuleLoader() const { return TheModuleLoader; } + /// SetCommentRetentionState - Control whether or not the preprocessor retains /// comments in output. void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) { @@ -334,6 +381,19 @@ public: bool getCommentRetentionState() const { return KeepComments; } + void SetSuppressIncludeNotFoundError(bool Suppress) { + SuppressIncludeNotFoundError = Suppress; + } + + bool GetSuppressIncludeNotFoundError() { + return SuppressIncludeNotFoundError; + } + + /// \brief Specify whether automatic module imports are enabled. + void setAutoModuleImport(bool AutoModuleImport = true) { + this->AutoModuleImport = AutoModuleImport; + } + /// isCurrentLexer - Return true if we are lexing directly from the specified /// lexer. bool isCurrentLexer(const PreprocessorLexer *L) const { @@ -380,12 +440,6 @@ public: macro_iterator macro_begin(bool IncludeExternalMacros = true) const; macro_iterator macro_end(bool IncludeExternalMacros = true) const; - /// \brief Expansion source location for the last macro that expanded - /// to no tokens. - SourceLocation getLastEmptyMacroExpansionLoc() const { - return LastEmptyMacroExpansionLoc; - } - const std::string &getPredefines() const { return Predefines; } /// setPredefines - Set the predefines for this Preprocessor. These /// predefines are automatically injected when parsing the main file. @@ -397,25 +451,25 @@ public: /// pointers is preferred unless the identifier is already available as a /// string (this avoids allocation and copying of memory to construct an /// std::string). - IdentifierInfo *getIdentifierInfo(llvm::StringRef Name) const { + IdentifierInfo *getIdentifierInfo(StringRef Name) const { return &Identifiers.get(Name); } /// AddPragmaHandler - Add the specified pragma handler to the preprocessor. /// If 'Namespace' is non-null, then it is a token required to exist on the /// pragma line before the pragma string starts, e.g. "STDC" or "GCC". - void AddPragmaHandler(llvm::StringRef Namespace, PragmaHandler *Handler); + void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler); void AddPragmaHandler(PragmaHandler *Handler) { - AddPragmaHandler(llvm::StringRef(), Handler); + AddPragmaHandler(StringRef(), Handler); } /// RemovePragmaHandler - Remove the specific pragma handler from /// the preprocessor. If \arg Namespace is non-null, then it should /// be the namespace that \arg Handler was added to. It is an error /// to remove a handler that has not been registered. - void RemovePragmaHandler(llvm::StringRef Namespace, PragmaHandler *Handler); + void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler); void RemovePragmaHandler(PragmaHandler *Handler) { - RemovePragmaHandler(llvm::StringRef(), Handler); + RemovePragmaHandler(StringRef(), Handler); } /// \brief Add the specified comment handler to the preprocessor. @@ -524,16 +578,17 @@ public: /// Lex - To lex a token from the preprocessor, just pull a token from the /// current lexer or macro object. void Lex(Token &Result) { - if (CurLexer) - CurLexer->Lex(Result); - else if (CurPTHLexer) - CurPTHLexer->Lex(Result); - else if (CurTokenLexer) - CurTokenLexer->Lex(Result); - else - CachingLex(Result); + switch (CurLexerKind) { + case CLK_Lexer: CurLexer->Lex(Result); break; + case CLK_PTHLexer: CurPTHLexer->Lex(Result); break; + case CLK_TokenLexer: CurTokenLexer->Lex(Result); break; + case CLK_CachingLexer: CachingLex(Result); break; + case CLK_LexAfterModuleImport: LexAfterModuleImport(Result); break; + } } + void LexAfterModuleImport(Token &Result); + /// LexNonComment - Lex a token. If it's a comment, keep lexing until we get /// something not a comment. This is useful in -E -C mode where comments /// would foul up preprocessor directive handling. @@ -556,6 +611,14 @@ public: DisableMacroExpansion = OldVal; } + /// LexUnexpandedNonComment - Like LexNonComment, but this disables macro + /// expansion of identifier tokens. + void LexUnexpandedNonComment(Token &Result) { + do + LexUnexpandedToken(Result); + while (Result.getKind() == tok::comment); + } + /// LookAhead - This peeks ahead N tokens and returns that token without /// consuming any tokens. LookAhead(0) returns the next token that would be /// returned by Lex(), LookAhead(1) returns the token after it, etc. This @@ -635,13 +698,46 @@ public: bool SetCodeCompletionPoint(const FileEntry *File, unsigned Line, unsigned Column); - /// \brief Determine if this source location refers into the file - /// for which we are performing code completion. - bool isCodeCompletionFile(SourceLocation FileLoc) const; - /// \brief Determine if we are performing code completion. bool isCodeCompletionEnabled() const { return CodeCompletionFile != 0; } + /// \brief Returns the location of the code-completion point. + /// Returns an invalid location if code-completion is not enabled or the file + /// containing the code-completion point has not been lexed yet. + SourceLocation getCodeCompletionLoc() const { return CodeCompletionLoc; } + + /// \brief Returns the start location of the file of code-completion point. + /// Returns an invalid location if code-completion is not enabled or the file + /// containing the code-completion point has not been lexed yet. + SourceLocation getCodeCompletionFileLoc() const { + return CodeCompletionFileLoc; + } + + /// \brief Returns true if code-completion is enabled and we have hit the + /// code-completion point. + bool isCodeCompletionReached() const { return CodeCompletionReached; } + + /// \brief Note that we hit the code-completion point. + void setCodeCompletionReached() { + assert(isCodeCompletionEnabled() && "Code-completion not enabled!"); + CodeCompletionReached = true; + // Silence any diagnostics that occur after we hit the code-completion. + getDiagnostics().setSuppressAllDiagnostics(true); + } + + /// \brief The location of the currently-active #pragma clang + /// arc_cf_code_audited begin. Returns an invalid location if there + /// is no such pragma active. + SourceLocation getPragmaARCCFCodeAuditedLoc() const { + return PragmaARCCFCodeAuditedLoc; + } + + /// \brief Set the location of the currently-active #pragma clang + /// arc_cf_code_audited begin. An invalid location ends the pragma. + void setPragmaARCCFCodeAuditedLoc(SourceLocation Loc) { + PragmaARCCFCodeAuditedLoc = Loc; + } + /// \brief Instruct the preprocessor to skip part of the main /// the main source file. /// @@ -657,11 +753,11 @@ public: /// Diag - Forwarding function for diagnostics. This emits a diagnostic at /// the specified Token's location, translating the token's start /// position in the current buffer into a SourcePosition object for rendering. - DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { + DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const { return Diags->Report(Loc, DiagID); } - DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) { + DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const { return Diags->Report(Tok.getLocation(), DiagID); } @@ -672,8 +768,8 @@ public: /// \param buffer A buffer which will be used only if the token requires /// "cleaning", e.g. if it contains trigraphs or escaped newlines /// \param invalid If non-null, will be set \c true if an error occurs. - llvm::StringRef getSpelling(SourceLocation loc, - llvm::SmallVectorImpl<char> &buffer, + StringRef getSpelling(SourceLocation loc, + SmallVectorImpl<char> &buffer, bool *invalid = 0) const { return Lexer::getSpelling(loc, buffer, SourceMgr, Features, invalid); } @@ -707,8 +803,8 @@ public: /// 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, + StringRef getSpelling(const Token &Tok, + SmallVectorImpl<char> &Buffer, bool *Invalid = 0) const; /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant @@ -731,8 +827,9 @@ public: /// CreateString - Plop the specified string into a scratch buffer and set the /// specified token's location and length to it. If specified, the source /// location provides a location of the expansion point of the token. - void CreateString(const char *Buf, unsigned Len, - Token &Tok, SourceLocation SourceLoc = SourceLocation()); + void CreateString(const char *Buf, unsigned Len, Token &Tok, + SourceLocation ExpansionLocStart = SourceLocation(), + SourceLocation ExpansionLocEnd = SourceLocation()); /// \brief Computes the source location just past the end of the /// token at this source location. @@ -892,16 +989,17 @@ public: /// caller is expected to provide a buffer that is large enough to hold the /// spelling of the filename, but is also expected to handle the case when /// this method decides to use a different buffer. - bool GetIncludeFilenameSpelling(SourceLocation Loc,llvm::StringRef &Filename); + bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Filename); /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, /// return null on failure. isAngled indicates whether the file reference is /// for system #include's or not (i.e. using <> instead of ""). - const FileEntry *LookupFile(llvm::StringRef Filename, + const FileEntry *LookupFile(StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, - llvm::SmallVectorImpl<char> *SearchPath, - llvm::SmallVectorImpl<char> *RelativePath); + SmallVectorImpl<char> *SearchPath, + SmallVectorImpl<char> *RelativePath, + StringRef *SuggestedModule); /// GetCurLookup - The DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. This allows us to @@ -932,7 +1030,8 @@ public: private: void PushIncludeMacroStack() { - IncludeMacroStack.push_back(IncludeStackInfo(CurLexer.take(), + IncludeMacroStack.push_back(IncludeStackInfo(CurLexerKind, + CurLexer.take(), CurPTHLexer.take(), CurPPLexer, CurTokenLexer.take(), @@ -946,6 +1045,7 @@ private: CurPPLexer = IncludeMacroStack.back().ThePPLexer; CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer); CurDirLookup = IncludeMacroStack.back().TheDirLookup; + CurLexerKind = IncludeMacroStack.back().CurLexerKind; IncludeMacroStack.pop_back(); } @@ -976,7 +1076,8 @@ private: /// already seen one so a #else directive is a duplicate. When this returns, /// the caller can lex the first valid token. void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc, - bool FoundNonSkipPortion, bool FoundElse); + bool FoundNonSkipPortion, bool FoundElse, + SourceLocation ElseLoc = SourceLocation()); /// PTHSkipExcludedConditionalBlock - A fast PTH version of /// SkipExcludedConditionalBlock. @@ -1006,7 +1107,7 @@ private: /// going to lex in the cache and when it finishes the tokens are removed /// from the end of the cache. Token *cacheMacroExpandedTokens(TokenLexer *tokLexer, - llvm::ArrayRef<Token> tokens); + ArrayRef<Token> tokens); void removeCachedMacroExpandedTokensOfLastLexer(); friend void TokenLexer::ExpandFunctionArguments(); @@ -1081,7 +1182,8 @@ private: void HandleDigitDirective(Token &Tok); void HandleUserDiagnosticDirective(Token &Tok, bool isWarning); void HandleIdentSCCSDirective(Token &Tok); - + void HandleMacroExportDirective(Token &Tok); + // File inclusion. void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok, diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h index 7bf041d..e2e30bf 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h @@ -30,6 +30,9 @@ protected: /// The SourceManager FileID corresponding to the file being lexed. const FileID FID; + /// \brief Number of SLocEntries before lexing the file. + unsigned InitialNumSLocEntries; + //===--------------------------------------------------------------------===// // Context-specific lexing flags set by the preprocessor. //===--------------------------------------------------------------------===// @@ -61,18 +64,16 @@ protected: /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks /// we are currently in. - llvm::SmallVector<PPConditionalInfo, 4> ConditionalStack; + SmallVector<PPConditionalInfo, 4> ConditionalStack; PreprocessorLexer(const PreprocessorLexer&); // DO NOT IMPLEMENT void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT friend class Preprocessor; - PreprocessorLexer(Preprocessor *pp, FileID fid) - : PP(pp), FID(fid), ParsingPreprocessorDirective(false), - ParsingFilename(false), LexingRawMode(false) {} + PreprocessorLexer(Preprocessor *pp, FileID fid); PreprocessorLexer() - : PP(0), + : PP(0), InitialNumSLocEntries(0), ParsingPreprocessorDirective(false), ParsingFilename(false), LexingRawMode(false) {} @@ -151,13 +152,18 @@ public: return FID; } + /// \brief Number of SLocEntries before lexing the file. + unsigned getInitialNumSLocEntries() const { + return InitialNumSLocEntries; + } + /// getFileEntry - Return the FileEntry corresponding to this FileID. Like /// getFileID(), this only works for lexers with attached preprocessors. const FileEntry *getFileEntry() const; /// \brief Iterator that traverses the current stack of preprocessor /// conditional directives (#if/#ifdef/#ifndef). - typedef llvm::SmallVectorImpl<PPConditionalInfo>::const_iterator + typedef SmallVectorImpl<PPConditionalInfo>::const_iterator conditional_iterator; conditional_iterator conditional_begin() const { diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Token.h b/contrib/llvm/tools/clang/include/clang/Lex/Token.h index 9cf11d9..e6dd160 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Token.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Token.h @@ -96,7 +96,10 @@ public: /// constant, string, etc. bool isLiteral() const { return is(tok::numeric_constant) || is(tok::char_constant) || - is(tok::string_literal) || is(tok::wide_string_literal) || + is(tok::wide_char_constant) || is(tok::utf16_char_constant) || + is(tok::utf32_char_constant) || is(tok::string_literal) || + is(tok::wide_string_literal) || is(tok::utf8_string_literal) || + is(tok::utf16_string_literal) || is(tok::utf32_string_literal) || is(tok::angle_string_literal); } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/TokenConcatenation.h b/contrib/llvm/tools/clang/include/clang/Lex/TokenConcatenation.h index 094990a..551300f 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/TokenConcatenation.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/TokenConcatenation.h @@ -63,12 +63,9 @@ namespace clang { const Token &Tok) const; private: - /// StartsWithL - Return true if the spelling of this token starts with 'L'. - bool StartsWithL(const Token &Tok) const; - - /// IsIdentifierL - Return true if the spelling of this token is literally - /// 'L'. - bool IsIdentifierL(const Token &Tok) const; + /// IsIdentifierStringPrefix - Return true if the spelling of the token + /// is literally 'L', 'u', 'U', or 'u8'. + bool IsIdentifierStringPrefix(const Token &Tok) const; }; } // end clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h index 45ff8a0..1330ad5 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h @@ -71,8 +71,10 @@ class TokenLexer { /// "source location address space". unsigned MacroStartSLocOffset; - /// \brief FileID/offset of the start of the macro definition. - std::pair<FileID, unsigned> MacroDefStartInfo; + /// \brief Location of the macro definition. + SourceLocation MacroDefStart; + /// \brief Length of the macro definition. + unsigned MacroDefLength; /// Lexical information about the expansion point of the macro: the identifier /// that the macro expanded from had these properties. @@ -169,7 +171,15 @@ private: /// \brief If \arg loc is a FileID and points inside the current macro /// definition, returns the appropriate source location pointing at the /// macro expansion source location entry. - SourceLocation getMacroExpansionLocation(SourceLocation loc) const; + SourceLocation getExpansionLocForMacroDefLoc(SourceLocation loc) const; + + /// \brief Creates SLocEntries and updates the locations of macro argument + /// tokens to their new expanded locations. + /// + /// \param ArgIdSpellLoc the location of the macro argument id inside the + /// macro definition. + void updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc, + Token *begin_tokens, Token *end_tokens); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Parse/ParseAST.h b/contrib/llvm/tools/clang/include/clang/Parse/ParseAST.h index 0d37e21..7253870 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/ParseAST.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/ParseAST.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_PARSE_PARSEAST_H #define LLVM_CLANG_PARSE_PARSEAST_H +#include "clang/Basic/LangOptions.h" + namespace clang { class Preprocessor; class ASTConsumer; @@ -27,15 +29,13 @@ namespace clang { /// This operation inserts the parsed decls into the translation /// unit held by Ctx. /// - /// \param CompleteTranslationUnit When true, the parsed file is - /// considered to be a complete translation unit, and any - /// end-of-translation-unit wrapup will be performed. + /// \param TUKind The kind of translation unit being parsed. /// /// \param CompletionConsumer If given, an object to consume code completion /// results. void ParseAST(Preprocessor &pp, ASTConsumer *C, ASTContext &Ctx, bool PrintStats = false, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, CodeCompleteConsumer *CompletionConsumer = 0); /// \brief Parse the main file known to the preprocessor, producing an diff --git a/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h index c50ac92..0e76c61 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM, #define PARSESTART #include "clang/Basic/DiagnosticParseKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h index 8f49dda..0046f88 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h @@ -22,6 +22,7 @@ #include "clang/Sema/DeclSpec.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallVector.h" #include <stack> namespace clang { @@ -42,7 +43,7 @@ class PrettyStackTraceParserEntry : public llvm::PrettyStackTraceEntry { const Parser &P; public: PrettyStackTraceParserEntry(const Parser &p) : P(p) {} - virtual void print(llvm::raw_ostream &OS) const; + virtual void print(raw_ostream &OS) const; }; /// PrecedenceLevels - These are precedences for the binary/ternary @@ -98,7 +99,7 @@ class Parser : public CodeCompletionHandler { /// in the file. Sema &Actions; - Diagnostic &Diags; + DiagnosticsEngine &Diags; /// ScopeCache - Cache scopes to reduce malloc traffic. enum { ScopeCacheSize = 16 }; @@ -120,6 +121,9 @@ class Parser : public CodeCompletionHandler { IdentifierInfo *Ident_vector; IdentifierInfo *Ident_pixel; + /// Objective-C contextual keywords. + mutable IdentifierInfo *Ident_instancetype; + /// \brief Identifier for "introduced". IdentifierInfo *Ident_introduced; @@ -186,19 +190,15 @@ public: const Token &getCurToken() const { return Tok; } Scope *getCurScope() const { return Actions.getCurScope(); } + + Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); } // Type forwarding. All of these are statically 'void*', but they may all be // different actual classes based on the actions in place. - typedef Expr ExprTy; - typedef Stmt StmtTy; typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; - typedef CXXBaseSpecifier BaseTy; - typedef CXXCtorInitializer MemInitTy; - typedef NestedNameSpecifier CXXScopeTy; - typedef TemplateParameterList TemplateParamsTy; typedef OpaquePtr<TemplateName> TemplateTy; - typedef llvm::SmallVector<TemplateParameterList *, 4> TemplateParameterLists; + typedef SmallVector<TemplateParameterList *, 4> TemplateParameterLists; typedef clang::ExprResult ExprResult; typedef clang::StmtResult StmtResult; @@ -265,7 +265,10 @@ private: /// bool isTokenStringLiteral() const { return Tok.getKind() == tok::string_literal || - Tok.getKind() == tok::wide_string_literal; + Tok.getKind() == tok::wide_string_literal || + Tok.getKind() == tok::utf8_string_literal || + Tok.getKind() == tok::utf16_string_literal || + Tok.getKind() == tok::utf32_string_literal; } /// \brief Returns true if the current token is a '=' or '==' and @@ -281,11 +284,10 @@ private: assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() && !isTokenBrace() && "Should consume special tokens with Consume*Token"); - if (Tok.is(tok::code_completion)) { - CodeCompletionRecovery(); - return ConsumeCodeCompletionToken(); - } - + + if (Tok.is(tok::code_completion)) + return handleUnexpectedCodeCompletionToken(); + PrevTokLocation = Tok.getLocation(); PP.Lex(Tok); return PrevTokLocation; @@ -371,10 +373,20 @@ private: return PrevTokLocation; } - ///\ brief When we are consuming a code-completion token within having + ///\ brief When we are consuming a code-completion token without having /// matched specific position in the grammar, provide code-completion results /// based on context. - void CodeCompletionRecovery(); + /// + /// \returns the source location of the code-completion token. + SourceLocation handleUnexpectedCodeCompletionToken(); + + /// \brief Abruptly cut off parsing; mainly used when we have reached the + /// code-completion point. + void cutOffParsing() { + PP.setCodeCompletionReached(); + // Cut off parsing by acting as if we reached the end-of-file. + Tok.setKind(tok::eof); + } /// \brief Handle the annotation token produced for #pragma unused(...) void HandlePragmaUnused(); @@ -397,6 +409,84 @@ private: return PP.LookAhead(0); } + /// \brief Tracks information about the current nesting depth of + /// opening delimiters of each kind. + class DelimiterTracker { + private: + friend class Parser; + + unsigned Paren, Brace, Square, Less, LLLess; + unsigned& get(tok::TokenKind t) { + switch (t) { + default: llvm_unreachable("Unexpected balanced token"); + case tok::l_brace: return Brace; + case tok::l_paren: return Paren; + case tok::l_square: return Square; + case tok::less: return Less; + case tok::lesslessless: return LLLess; + } + } + + void push(tok::TokenKind t) { + get(t)++; + } + + void pop(tok::TokenKind t) { + get(t)--; + } + + unsigned getDepth(tok::TokenKind t) { + return get(t); + } + + public: + DelimiterTracker() : Paren(0), Brace(0), Square(0), Less(0), LLLess(0) { } + }; + + /// \brief RAII class that helps handle the parsing of an open/close delimiter + /// pair, such as braces { ... } or parentheses ( ... ). + class BalancedDelimiterTracker { + tok::TokenKind Kind, Close; + Parser& P; + bool Cleanup; + const unsigned MaxDepth; + SourceLocation LOpen, LClose; + + void assignClosingDelimiter() { + switch (Kind) { + default: llvm_unreachable("Unexpected balanced token"); + case tok::l_brace: Close = tok::r_brace; break; + case tok::l_paren: Close = tok::r_paren; break; + case tok::l_square: Close = tok::r_square; break; + case tok::less: Close = tok::greater; break; + case tok::lesslessless: Close = tok::greatergreatergreater; break; + } + } + + public: + BalancedDelimiterTracker(Parser& p, tok::TokenKind k) + : Kind(k), P(p), Cleanup(false), MaxDepth(256) { + assignClosingDelimiter(); + } + + ~BalancedDelimiterTracker() { + if (Cleanup) + P.QuantityTracker.pop(Kind); + } + + SourceLocation getOpenLocation() const { return LOpen; } + SourceLocation getCloseLocation() const { return LClose; } + SourceRange getRange() const { return SourceRange(LOpen, LClose); } + + bool consumeOpen(); + bool expectAndConsume(unsigned DiagID, + const char *Msg = "", + tok::TokenKind SkipToTok = tok::unknown); + bool consumeClose(); + }; + + DelimiterTracker QuantityTracker; + /// getTypeAnnotation - Read a parsed type out of an annotation token. static ParsedType getTypeAnnotation(Token &Tok) { return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue()); @@ -424,7 +514,10 @@ private: Tok.setAnnotationValue(ER.get()); } - bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false); + // If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to + // find a type name by attempting typo correction. + bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false, + bool NeedType = false); bool TryAnnotateCXXScopeToken(bool EnteringContext = false); /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens, @@ -498,9 +591,23 @@ private: } }; - - SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok, - SourceLocation LHSLoc); + /// ObjCDeclContextSwitch - An object used to switch context from + /// an objective-c decl context to its enclosing decl context and + /// back. + class ObjCDeclContextSwitch { + Parser &P; + Decl *DC; + public: + explicit ObjCDeclContextSwitch(Parser &p) : P(p), + DC(p.getObjCDeclContext()) { + if (DC) + P.Actions.ActOnObjCTemporaryExitContainerContext(); + } + ~ObjCDeclContextSwitch() { + if (DC) + P.Actions.ActOnObjCReenterContainerContext(); + } + }; /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the /// input. If so, it is consumed and false is returned. @@ -630,6 +737,7 @@ private: virtual void ParseLexedMethodDeclarations(); virtual void ParseLexedMemberInitializers(); virtual void ParseLexedMethodDefs(); + virtual void ParseLexedAttributes(); }; /// Inner node of the LateParsedDeclaration tree that parses @@ -642,12 +750,39 @@ private: virtual void ParseLexedMethodDeclarations(); virtual void ParseLexedMemberInitializers(); virtual void ParseLexedMethodDefs(); + virtual void ParseLexedAttributes(); private: Parser *Self; ParsingClass *Class; }; + /// Contains the lexed tokens of an attribute with arguments that + /// may reference member variables and so need to be parsed at the + /// end of the class declaration after parsing all other member + /// member declarations. + /// FIXME: Perhaps we should change the name of LateParsedDeclaration to + /// LateParsedTokens. + struct LateParsedAttribute : public LateParsedDeclaration { + Parser *Self; + CachedTokens Toks; + IdentifierInfo &AttrName; + SourceLocation AttrNameLoc; + Decl *D; + + explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name, + SourceLocation Loc) + : Self(P), AttrName(Name), AttrNameLoc(Loc), D(0) {} + + virtual void ParseLexedAttributes(); + + void setDecl(Decl *Dec) { D = Dec; } + }; + + /// A list of late parsed attributes. Used by ParseGNUAttributes. + typedef llvm::SmallVector<LateParsedAttribute*, 2> LateParsedAttrList; + + /// Contains the lexed tokens of a member function definition /// which needs to be parsed at the end of the class declaration /// after parsing all other member declarations. @@ -711,7 +846,7 @@ private: /// have a default argument, but all of the parameters of the /// method will be stored so that they can be reintroduced into /// scope at the appropriate times. - llvm::SmallVector<LateParsedDefaultArgument, 8> DefaultArgs; + SmallVector<LateParsedDefaultArgument, 8> DefaultArgs; }; /// LateParsedMemberInitializer - An initializer for a non-static class data @@ -738,7 +873,7 @@ private: /// parsed until after the definition is completed (C++ [class.mem]p2), /// the method declarations and possibly attached inline definitions /// will be stored here with the tokens that will be parsed to create those entities. - typedef llvm::SmallVector<LateParsedDeclaration*, 2> LateParsedDeclarationsContainer; + typedef SmallVector<LateParsedDeclaration*, 2> LateParsedDeclarationsContainer; /// \brief Representation of a class that has been parsed, including /// any member function declarations or definitions that need to be @@ -990,16 +1125,21 @@ private: void DeallocateParsedClasses(ParsingClass *Class); void PopParsingClass(Sema::ParsingClassState); - Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, + Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, AttributeList *AccessAttrs, + ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, const VirtSpecifiers& VS, ExprResult& Init); void ParseCXXNonStaticMemberInitializer(Decl *VarD); + void ParseLexedAttributes(ParsingClass &Class); + void ParseLexedAttribute(LateParsedAttribute &LA); void ParseLexedMethodDeclarations(ParsingClass &Class); void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM); void ParseLexedMethodDefs(ParsingClass &Class); void ParseLexedMethodDef(LexedMethod &LM); void ParseLexedMemberInitializers(ParsingClass &Class); void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI); + Decl *ParseLexedObjCMethodDefs(LexedMethod &LM); + bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks); bool ConsumeAndStoreUntil(tok::TokenKind T1, CachedTokens &Toks, bool StopAtSemi = true, @@ -1038,29 +1178,31 @@ private: ExprResult ParseAsmStringLiteral(); // Objective-C External Declarations - Decl *ParseObjCAtDirectives(); - Decl *ParseObjCAtClassDeclaration(SourceLocation atLoc); + Parser::DeclGroupPtrTy ParseObjCAtDirectives(); + Parser::DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); Decl *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, ParsedAttributes &prefixAttrs); void ParseObjCClassInstanceVariables(Decl *interfaceDecl, tok::ObjCKeywordKind visibility, SourceLocation atLoc); - bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Decl *> &P, - llvm::SmallVectorImpl<SourceLocation> &PLocs, + bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P, + SmallVectorImpl<SourceLocation> &PLocs, bool WarnOnDeclarations, SourceLocation &LAngleLoc, SourceLocation &EndProtoLoc); bool ParseObjCProtocolQualifiers(DeclSpec &DS); - void ParseObjCInterfaceDeclList(Decl *interfaceDecl, - tok::ObjCKeywordKind contextKey); + void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, + Decl *CDecl); Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc, ParsedAttributes &prefixAttrs); Decl *ObjCImpDecl; - llvm::SmallVector<Decl *, 4> PendingObjCImpDecl; + SmallVector<Decl *, 4> PendingObjCImpDecl; + typedef SmallVector<LexedMethod*, 2> LateParsedObjCMethodContainer; + LateParsedObjCMethodContainer LateParsedObjCMethods; Decl *ParseObjCAtImplementationDeclaration(SourceLocation atLoc); - Decl *ParseObjCAtEndDeclaration(SourceRange atEnd); + DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd); Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc); Decl *ParseObjCPropertySynthesize(SourceLocation atLoc); Decl *ParseObjCPropertyDynamic(SourceLocation atLoc); @@ -1075,22 +1217,16 @@ private: bool isTokIdentifier_in() const; - /// \brief The context in which we are parsing an Objective-C type name. - enum ObjCTypeNameContext { - OTN_ResultType, - OTN_ParameterType - }; - - ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, ObjCTypeNameContext Context); + ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, Declarator::TheContext Ctx, + ParsedAttributes *ParamAttrs); void ParseObjCMethodRequirement(); - Decl *ParseObjCMethodPrototype(Decl *classOrCat, + Decl *ParseObjCMethodPrototype( tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword, bool MethodDefinition = true); Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType, - Decl *classDecl, tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword, bool MethodDefinition=true); - void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl); + void ParseObjCPropertyAttribute(ObjCDeclSpec &DS); Decl *ParseObjCMethodDefinition(); @@ -1134,12 +1270,12 @@ private: ParsedType &CastTy, SourceRange &CastRange); - typedef llvm::SmallVector<Expr*, 20> ExprListTy; - typedef llvm::SmallVector<SourceLocation, 20> CommaLocsTy; + typedef SmallVector<Expr*, 20> ExprListTy; + typedef SmallVector<SourceLocation, 20> CommaLocsTy; /// ParseExpressionList - Used for C/C++ (argument-)expression-list. - bool ParseExpressionList(llvm::SmallVectorImpl<Expr*> &Exprs, - llvm::SmallVectorImpl<SourceLocation> &CommaLocs, + bool ParseExpressionList(SmallVectorImpl<Expr*> &Exprs, + SmallVectorImpl<SourceLocation> &CommaLocs, void (Sema::*Completer)(Scope *S, Expr *Data, Expr **Args, @@ -1160,10 +1296,8 @@ private: SourceLocation &RParenLoc); ExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, - ParsedType &CastTy, - SourceLocation LParenLoc, - SourceLocation &RParenLoc); - + ParsedType &CastTy, + BalancedDelimiterTracker &Tracker); ExprResult ParseCompoundLiteralExpression(ParsedType Ty, SourceLocation LParenLoc, SourceLocation RParenLoc); @@ -1176,6 +1310,10 @@ private: // C++ Expressions ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false); + void CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectTypePtr, + bool EnteringContext, IdentifierInfo &II, + CXXScopeSpec &SS); + bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext, @@ -1183,6 +1321,17 @@ private: bool IsTypename = false); //===--------------------------------------------------------------------===// + // C++0x 5.1.2: Lambda expressions + + // [...] () -> type {...} + ExprResult ParseLambdaExpression(); + ExprResult TryParseLambdaExpression(); + llvm::Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro); + bool TryParseLambdaIntroducer(LambdaIntroducer &Intro); + ExprResult ParseLambdaExpressionAfterIntroducer( + LambdaIntroducer &Intro); + + //===--------------------------------------------------------------------===// // C++ 5.2p1: C++ Casts ExprResult ParseCXXCasts(); @@ -1211,19 +1360,19 @@ private: ExceptionSpecificationType MaybeParseExceptionSpecification( SourceRange &SpecificationRange, - llvm::SmallVectorImpl<ParsedType> &DynamicExceptions, - llvm::SmallVectorImpl<SourceRange> &DynamicExceptionRanges, + SmallVectorImpl<ParsedType> &DynamicExceptions, + SmallVectorImpl<SourceRange> &DynamicExceptionRanges, ExprResult &NoexceptExpr); // EndLoc is filled with the location of the last token of the specification. ExceptionSpecificationType ParseDynamicExceptionSpecification( SourceRange &SpecificationRange, - llvm::SmallVectorImpl<ParsedType> &Exceptions, - llvm::SmallVectorImpl<SourceRange> &Ranges); + SmallVectorImpl<ParsedType> &Exceptions, + SmallVectorImpl<SourceRange> &Ranges); //===--------------------------------------------------------------------===// // C++0x 8: Function declaration trailing-return-type - TypeResult ParseTrailingReturnType(); + TypeResult ParseTrailingReturnType(SourceRange &Range); //===--------------------------------------------------------------------===// // C++ 2.13.5: C++ Boolean Literals @@ -1244,7 +1393,7 @@ private: //===--------------------------------------------------------------------===// // C++ 5.3.4 and 5.3.5: C++ new and delete - bool ParseExpressionListOrTypeId(llvm::SmallVectorImpl<Expr*> &Exprs, + bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr*> &Exprs, Declarator &D); void ParseDirectNewDeclarator(Declarator &D); ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start); @@ -1332,15 +1481,15 @@ private: StmtResult ParseBreakStatement(ParsedAttributes &Attr); StmtResult ParseReturnStatement(ParsedAttributes &Attr); StmtResult ParseAsmStatement(bool &msAsm); - StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc); + StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc); bool ParseMicrosoftIfExistsCondition(bool& Result); void ParseMicrosoftIfExistsStatement(StmtVector &Stmts); void ParseMicrosoftIfExistsExternalDeclaration(); void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, AccessSpecifier& CurAS); -bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, - llvm::SmallVectorImpl<ExprTy *> &Constraints, - llvm::SmallVectorImpl<ExprTy *> &Exprs); + bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, + SmallVectorImpl<Expr *> &Constraints, + SmallVectorImpl<Expr *> &Exprs); //===--------------------------------------------------------------------===// // C++ 6: Statements and Blocks @@ -1431,8 +1580,8 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none); - void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, - ObjCTypeNameContext Context); + void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, + Declarator::TheContext Context); void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), @@ -1607,7 +1756,6 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, TypeResult ParseTypeName(SourceRange *Range = 0, Declarator::TheContext Context = Declarator::TypeNameContext, - ObjCDeclSpec *objcQuals = 0, AccessSpecifier AS = AS_none, Decl **OwnedType = 0); void ParseBlockId(); @@ -1618,21 +1766,28 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, } void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs); - void MaybeParseGNUAttributes(Declarator &D) { + void MaybeParseGNUAttributes(Declarator &D, + LateParsedAttrList *LateAttrs = 0) { if (Tok.is(tok::kw___attribute)) { ParsedAttributes attrs(AttrFactory); SourceLocation endLoc; - ParseGNUAttributes(attrs, &endLoc); + ParseGNUAttributes(attrs, &endLoc, LateAttrs); D.takeAttributes(attrs, endLoc); } } void MaybeParseGNUAttributes(ParsedAttributes &attrs, - SourceLocation *endLoc = 0) { + SourceLocation *endLoc = 0, + LateParsedAttrList *LateAttrs = 0) { if (Tok.is(tok::kw___attribute)) - ParseGNUAttributes(attrs, endLoc); + ParseGNUAttributes(attrs, endLoc, LateAttrs); } void ParseGNUAttributes(ParsedAttributes &attrs, - SourceLocation *endLoc = 0); + SourceLocation *endLoc = 0, + LateParsedAttrList *LateAttrs = 0); + void ParseGNUAttributeArgs(IdentifierInfo *AttrName, + SourceLocation AttrNameLoc, + ParsedAttributes &Attrs, + SourceLocation *EndLoc); void MaybeParseCXX0XAttributes(Declarator &D) { if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) { @@ -1655,12 +1810,15 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) ParseCXX0XAttributes(attrs, endLoc); } + + void ParseCXX0XAttributeSpecifier(ParsedAttributes &attrs, + SourceLocation *EndLoc = 0); void ParseCXX0XAttributes(ParsedAttributesWithRange &attrs, SourceLocation *EndLoc = 0); void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs, SourceLocation *endLoc = 0) { - if (getLang().Microsoft && Tok.is(tok::l_square)) + if (getLang().MicrosoftExt && Tok.is(tok::l_square)) ParseMicrosoftAttributes(attrs, endLoc); } void ParseMicrosoftAttributes(ParsedAttributes &attrs, @@ -1677,11 +1835,21 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, ParsedAttributes &attrs, SourceLocation *endLoc); + bool IsThreadSafetyAttribute(llvm::StringRef AttrName); + void ParseThreadSafetyAttribute(IdentifierInfo &AttrName, + SourceLocation AttrNameLoc, + ParsedAttributes &Attrs, + SourceLocation *EndLoc); + + void ParseTypeofSpecifier(DeclSpec &DS); void ParseDecltypeSpecifier(DeclSpec &DS); void ParseUnderlyingTypeSpecifier(DeclSpec &DS); - - ExprResult ParseCXX0XAlignArgument(SourceLocation Start); + void ParseAtomicSpecifier(DeclSpec &DS); + + ExprResult ParseAlignArgument(SourceLocation Start); + void ParseAlignmentSpecifier(ParsedAttributes &Attrs, + SourceLocation *endLoc = 0); VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const; void ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS); @@ -1732,17 +1900,18 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, bool CXX0XAttributesAllowed = true); void ParseDirectDeclarator(Declarator &D); void ParseParenDeclarator(Declarator &D); - void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, + void ParseFunctionDeclarator(Declarator &D, ParsedAttributes &attrs, + BalancedDelimiterTracker &Tracker, bool RequiresArg = false); bool isFunctionDeclaratorIdentifierList(); void ParseFunctionDeclaratorIdentifierList( Declarator &D, - llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo); + SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo); void ParseParameterDeclarationClause( Declarator &D, ParsedAttributes &attrs, - llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo, + SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo, SourceLocation &EllipsisLoc); void ParseBracketDeclarator(Declarator &D); @@ -1758,8 +1927,8 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, std::vector<IdentifierInfo*>& Ident, std::vector<SourceLocation>& NamespaceLoc, unsigned int index, SourceLocation& InlineLoc, - SourceLocation& LBrace, ParsedAttributes& attrs, - SourceLocation& RBraceLoc); + ParsedAttributes& attrs, + BalancedDelimiterTracker &Tracker); Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context); Decl *ParseUsingDirectiveOrDeclaration(unsigned Context, const ParsedTemplateInfo &TemplateInfo, @@ -1793,7 +1962,7 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, Decl *TagDecl); ExprResult ParseCXXMemberInitializer(bool IsFunction, SourceLocation &EqualLoc); - void ParseCXXClassMemberDeclaration(AccessSpecifier AS, + void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), ParsingDeclRAIIObject *DiagsFromTParams = 0); void ParseConstructorInitializer(Decl *ConstructorDecl); @@ -1829,30 +1998,33 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, // C++ 14.1: Template Parameters [temp.param] Decl *ParseDeclarationStartingWithTemplate(unsigned Context, - SourceLocation &DeclEnd, - AccessSpecifier AS = AS_none); + SourceLocation &DeclEnd, + AccessSpecifier AS = AS_none, + AttributeList *AccessAttrs = 0); Decl *ParseTemplateDeclarationOrSpecialization(unsigned Context, - SourceLocation &DeclEnd, - AccessSpecifier AS); + SourceLocation &DeclEnd, + AccessSpecifier AS, + AttributeList *AccessAttrs); Decl *ParseSingleDeclarationAfterTemplate( unsigned Context, const ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd, - AccessSpecifier AS=AS_none); + AccessSpecifier AS=AS_none, + AttributeList *AccessAttrs = 0); bool ParseTemplateParameters(unsigned Depth, - llvm::SmallVectorImpl<Decl*> &TemplateParams, + SmallVectorImpl<Decl*> &TemplateParams, SourceLocation &LAngleLoc, SourceLocation &RAngleLoc); bool ParseTemplateParameterList(unsigned Depth, - llvm::SmallVectorImpl<Decl*> &TemplateParams); + SmallVectorImpl<Decl*> &TemplateParams); bool isStartOfTemplateTypeParameter(); Decl *ParseTemplateParameter(unsigned Depth, unsigned Position); Decl *ParseTypeParameter(unsigned Depth, unsigned Position); Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position); Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position); // C++ 14.3: Template arguments [temp.arg] - typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList; + typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList; bool ParseTemplateIdAfterTemplateName(TemplateTy Template, SourceLocation TemplateNameLoc, @@ -1877,6 +2049,10 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, SourceLocation &DeclEnd); //===--------------------------------------------------------------------===// + // Modules + DeclGroupPtrTy ParseModuleImport(); + + //===--------------------------------------------------------------------===// // GNU G++: Type Traits [Type-Traits.html in the GCC manual] ExprResult ParseUnaryTypeTrait(); ExprResult ParseBinaryTypeTrait(); diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/ASTConsumers.h b/contrib/llvm/tools/clang/include/clang/Rewrite/ASTConsumers.h index b7f6427..7a636e5 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/ASTConsumers.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/ASTConsumers.h @@ -14,29 +14,27 @@ #ifndef REWRITE_ASTCONSUMERS_H #define REWRITE_ASTCONSUMERS_H +#include "clang/Basic/LLVM.h" #include <string> -namespace llvm { - class raw_ostream; -} namespace clang { class ASTConsumer; -class Diagnostic; +class DiagnosticsEngine; class LangOptions; class Preprocessor; // ObjC rewriter: attempts to rewrite ObjC constructs into pure C code. // This is considered experimental, and only works with Apple's ObjC runtime. ASTConsumer *CreateObjCRewriter(const std::string &InFile, - llvm::raw_ostream *OS, - Diagnostic &Diags, + raw_ostream *OS, + DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning); /// 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, +ASTConsumer *CreateHTMLPrinter(raw_ostream *OS, Preprocessor &PP, bool SyntaxHighlight = true, bool HighlightMacros = true); diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/FixItRewriter.h b/contrib/llvm/tools/clang/include/clang/Rewrite/FixItRewriter.h index bab9962..bf7e791 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/FixItRewriter.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/FixItRewriter.h @@ -19,8 +19,6 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Rewrite/Rewriter.h" -namespace llvm { class raw_ostream; } - namespace clang { class SourceManager; @@ -38,9 +36,9 @@ public: bool FixWhatYouCan; }; -class FixItRewriter : public DiagnosticClient { +class FixItRewriter : public DiagnosticConsumer { /// \brief The diagnostics machinery. - Diagnostic &Diags; + DiagnosticsEngine &Diags; /// \brief The rewriter used to perform the various code /// modifications. @@ -48,7 +46,7 @@ class FixItRewriter : public DiagnosticClient { /// \brief The diagnostic client that performs the actual formatting /// of error messages. - DiagnosticClient *Client; + DiagnosticConsumer *Client; /// \brief Turn an input path into an output path. NULL implies overwriting /// the original. @@ -61,7 +59,7 @@ public: typedef Rewriter::buffer_iterator iterator; /// \brief Initialize a new fix-it rewriter. - FixItRewriter(Diagnostic &Diags, SourceManager &SourceMgr, + FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr, const LangOptions &LangOpts, FixItOptions *FixItOpts); /// \brief Destroy the fix-it rewriter. @@ -79,7 +77,7 @@ public: /// \brief Write a single modified source file. /// /// \returns true if there was an error, false otherwise. - bool WriteFixedFile(FileID ID, llvm::raw_ostream &OS); + bool WriteFixedFile(FileID ID, raw_ostream &OS); /// \brief Write the modified source files. /// @@ -88,17 +86,19 @@ public: /// IncludeInDiagnosticCounts - This method (whose default implementation /// returns true) indicates whether the diagnostics handled by this - /// DiagnosticClient should be included in the number of diagnostics - /// reported by Diagnostic. + /// DiagnosticConsumer should be included in the number of diagnostics + /// reported by DiagnosticsEngine. virtual bool IncludeInDiagnosticCounts() const; /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or /// capturing it to a log as needed. - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info); /// \brief Emit a diagnostic via the adapted diagnostic client. void Diag(SourceLocation Loc, unsigned DiagID); + + DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/FrontendActions.h b/contrib/llvm/tools/clang/include/clang/Rewrite/FrontendActions.h index 6b33183..f7aeefa 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/FrontendActions.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/FrontendActions.h @@ -23,7 +23,7 @@ class FixItOptions; class HTMLPrintAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); }; class FixItAction : public ASTFrontendAction { @@ -32,10 +32,10 @@ protected: llvm::OwningPtr<FixItOptions> FixItOpts; virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); virtual bool BeginSourceFileAction(CompilerInstance &CI, - llvm::StringRef Filename); + StringRef Filename); virtual void EndSourceFileAction(); @@ -49,7 +49,7 @@ public: class RewriteObjCAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); }; class RewriteMacrosAction : public PreprocessorFrontendAction { diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h index 676744a..f1358a0 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h @@ -23,8 +23,6 @@ #include <map> #include <string> -namespace llvm { class raw_ostream; } - namespace clang { class LangOptions; class Rewriter; @@ -54,7 +52,7 @@ public: iterator end() const { return Buffer.end(); } unsigned size() const { return Buffer.size(); } - llvm::raw_ostream &write(llvm::raw_ostream &) const; + raw_ostream &write(raw_ostream &) const; /// RemoveText - Remove the specified text. void RemoveText(unsigned OrigOffset, unsigned Size, @@ -64,7 +62,7 @@ public: /// the buffer is specified relative to the original SourceBuffer. The /// text is inserted after the specified location. /// - void InsertText(unsigned OrigOffset, llvm::StringRef Str, + void InsertText(unsigned OrigOffset, StringRef Str, bool InsertAfter = true); @@ -72,14 +70,14 @@ public: /// offset in the buffer is specified relative to the original /// SourceBuffer. The text is inserted before the specified location. This is /// method is the same as InsertText with "InsertAfter == false". - void InsertTextBefore(unsigned OrigOffset, llvm::StringRef Str) { + void InsertTextBefore(unsigned OrigOffset, StringRef Str) { InsertText(OrigOffset, Str, false); } /// InsertTextAfter - Insert some text at the specified point, where the /// offset in the buffer is specified relative to the original SourceBuffer. /// The text is inserted after the specified location. - void InsertTextAfter(unsigned OrigOffset, llvm::StringRef Str) { + void InsertTextAfter(unsigned OrigOffset, StringRef Str) { InsertText(OrigOffset, Str); } @@ -87,7 +85,7 @@ public: /// buffer with a new string. This is effectively a combined "remove/insert" /// operation. void ReplaceText(unsigned OrigOffset, unsigned OrigLength, - llvm::StringRef NewStr); + StringRef NewStr); private: // Methods only usable by Rewriter. @@ -156,8 +154,8 @@ public: SourceMgr = &SM; LangOpts = &LO; } - SourceManager &getSourceMgr() { return *SourceMgr; } - const LangOptions &getLangOpts() { return *LangOpts; } + SourceManager &getSourceMgr() const { return *SourceMgr; } + const LangOptions &getLangOpts() const { return *LangOpts; } /// isRewritable - Return true if this location is a raw file location, which /// is rewritable. Locations from macros, etc are not rewritable. @@ -186,7 +184,7 @@ public: /// /// \param indentNewLines if true new lines in the string are indented /// using the indentation of the source line in position \arg Loc. - bool InsertText(SourceLocation Loc, llvm::StringRef Str, + bool InsertText(SourceLocation Loc, StringRef Str, bool InsertAfter = true, bool indentNewLines = false); /// InsertTextAfter - Insert the specified string at the specified location in @@ -194,20 +192,20 @@ public: /// the input location was not rewritable, false otherwise. Text is /// inserted after any other text that has been previously inserted /// at the some point (the default behavior for InsertText). - bool InsertTextAfter(SourceLocation Loc, llvm::StringRef Str) { + bool InsertTextAfter(SourceLocation Loc, StringRef Str) { return InsertText(Loc, Str); } /// \brief Insert the specified string after the token in the /// specified location. - bool InsertTextAfterToken(SourceLocation Loc, llvm::StringRef Str); + bool InsertTextAfterToken(SourceLocation Loc, StringRef Str); /// InsertText - Insert the specified string at the specified location in the /// original buffer. This method returns true (and does nothing) if the input /// location was not rewritable, false otherwise. Text is /// inserted before any other text that has been previously inserted /// at the some point. - bool InsertTextBefore(SourceLocation Loc, llvm::StringRef Str) { + bool InsertTextBefore(SourceLocation Loc, StringRef Str) { return InsertText(Loc, Str, false); } @@ -230,12 +228,12 @@ public: /// buffer with a new string. This is effectively a combined "remove/insert" /// operation. bool ReplaceText(SourceLocation Start, unsigned OrigLength, - llvm::StringRef NewStr); + StringRef NewStr); /// ReplaceText - This method replaces a range of characters in the input /// buffer with a new string. This is effectively a combined "remove/insert" /// operation. - bool ReplaceText(SourceRange range, llvm::StringRef NewStr) { + bool ReplaceText(SourceRange range, StringRef NewStr) { return ReplaceText(range.getBegin(), getRangeSize(range), NewStr); } diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriters.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriters.h index 669cf8c..203b9bc 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriters.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriters.h @@ -14,17 +14,16 @@ #ifndef LLVM_CLANG_REWRITE_REWRITERS_H #define LLVM_CLANG_REWRITE_REWRITERS_H -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/raw_ostream.h" +#include "clang/Basic/LLVM.h" namespace clang { class Preprocessor; /// RewriteMacrosInInput - Implement -rewrite-macros mode. -void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS); +void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS); /// DoRewriteTest - A simple test for the TokenRewriter class. -void DoRewriteTest(Preprocessor &PP, llvm::raw_ostream* OS); +void DoRewriteTest(Preprocessor &PP, raw_ostream *OS); } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Sema/AnalysisBasedWarnings.h b/contrib/llvm/tools/clang/include/clang/Sema/AnalysisBasedWarnings.h index 8e781cd..eeac973 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/AnalysisBasedWarnings.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/AnalysisBasedWarnings.h @@ -37,6 +37,7 @@ public: // The warnings to run. unsigned enableCheckFallThrough : 1; unsigned enableCheckUnreachable : 1; + unsigned enableThreadSafetyAnalysis : 1; public: Policy(); void disableCheckFallThrough() { enableCheckFallThrough = 0; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h b/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h index 5d2d6c2..bcacf7a 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h @@ -56,7 +56,7 @@ private: IdentifierInfo *AttrName; IdentifierInfo *ScopeName; IdentifierInfo *ParmName; - SourceLocation AttrLoc; + SourceRange AttrRange; SourceLocation ScopeLoc; SourceLocation ParmLoc; @@ -73,6 +73,9 @@ private: /// True if already diagnosed as invalid. mutable unsigned Invalid : 1; + /// True if this attribute was used as a type attribute. + mutable unsigned UsedAsTypeAttr : 1; + /// True if this has the extra information associated with an /// availability attribute. unsigned IsAvailability : 1; @@ -114,21 +117,22 @@ private: size_t allocated_size() const; - AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc, + AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, bool declspec, bool cxx0x) : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc), + AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), NumArgs(numArgs), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false), - IsAvailability(false), NextInPosition(0), NextInPool(0) { + UsedAsTypeAttr(false), IsAvailability(false), + NextInPosition(0), NextInPool(0) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); AttrKind = getKind(getName()); } - AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc, + AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, const AvailabilityChange &introduced, @@ -137,10 +141,10 @@ private: SourceLocation unavailable, bool declspec, bool cxx0x) : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc), + AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), - Invalid(false), IsAvailability(true), UnavailableLoc(unavailable), - NextInPosition(0), NextInPool(0) { + Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), + UnavailableLoc(unavailable), NextInPosition(0), NextInPool(0) { new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); @@ -152,6 +156,8 @@ private: public: enum Kind { // Please keep this list alphabetized. + AT_acquired_after, + AT_acquired_before, AT_address_space, AT_alias, AT_aligned, @@ -164,10 +170,12 @@ public: AT_blocks, AT_carries_dependency, AT_cdecl, + AT_cf_audited_transfer, // Clang-specific. AT_cf_consumed, // Clang-specific. AT_cf_returns_autoreleased, // Clang-specific. AT_cf_returns_not_retained, // Clang-specific. AT_cf_returns_retained, // Clang-specific. + AT_cf_unknown_transfer, // Clang-specific. AT_cleanup, AT_common, AT_const, @@ -178,18 +186,26 @@ public: AT_device, AT_dllexport, AT_dllimport, + AT_exclusive_lock_function, + AT_exclusive_locks_required, + AT_exclusive_trylock_function, AT_ext_vector_type, AT_fastcall, AT_format, AT_format_arg, AT_global, AT_gnu_inline, + AT_guarded_by, + AT_guarded_var, AT_host, AT_IBAction, // Clang-specific. AT_IBOutlet, // Clang-specific. AT_IBOutletCollection, // Clang-specific. AT_init_priority, AT_launch_bounds, + AT_lock_returned, + AT_lockable, + AT_locks_excluded, AT_malloc, AT_may_alias, AT_mode, @@ -198,12 +214,14 @@ public: AT_neon_polyvector_type, // Clang-specific. AT_neon_vector_type, // Clang-specific. AT_no_instrument_function, + AT_no_thread_safety_analysis, AT_nocommon, AT_nodebug, AT_noinline, AT_nonnull, AT_noreturn, AT_nothrow, + AT_ns_bridged, // Clang-specific. AT_ns_consumed, // Clang-specific. AT_ns_consumes_self, // Clang-specific. AT_ns_returns_autoreleased, // Clang-specific. @@ -215,6 +233,7 @@ public: AT_objc_method_family, AT_objc_ownership, // Clang-specific. AT_objc_precise_lifetime, // Clang-specific. + AT_objc_returns_inner_pointer, // Clang-specific. AT_opencl_image_access, // OpenCL-specific. AT_opencl_kernel_function, // OpenCL-specific. AT_overloadable, // Clang-specific. @@ -224,16 +243,23 @@ public: AT_packed, AT_pascal, AT_pcs, // ARM specific + AT_pt_guarded_by, + AT_pt_guarded_var, AT_pure, AT_regparm, AT_reqd_wg_size, + AT_scoped_lockable, AT_section, AT_sentinel, AT_shared, + AT_shared_lock_function, + AT_shared_locks_required, + AT_shared_trylock_function, AT_stdcall, AT_thiscall, AT_transparent_union, AT_unavailable, + AT_unlock_function, AT_unused, AT_used, AT_uuid, @@ -244,12 +270,14 @@ public: AT_weak, AT_weak_import, AT_weakref, + AT_returns_twice, IgnoredAttribute, UnknownAttribute }; IdentifierInfo *getName() const { return AttrName; } - SourceLocation getLoc() const { return AttrLoc; } + SourceLocation getLoc() const { return AttrRange.getBegin(); } + SourceRange getRange() const { return AttrRange; } bool hasScope() const { return ScopeName; } IdentifierInfo *getScopeName() const { return ScopeName; } @@ -264,6 +292,9 @@ public: bool isInvalid() const { return Invalid; } void setInvalid(bool b = true) const { Invalid = b; } + bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } + void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } + Kind getKind() const { return Kind(AttrKind); } static Kind getKind(const IdentifierInfo *Name); @@ -373,7 +404,7 @@ private: /// Free lists. The index is determined by the following formula: /// (size - sizeof(AttributeList)) / sizeof(void*) - llvm::SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists; + SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists; // The following are the private interface used by AttributePool. friend class AttributePool; @@ -440,21 +471,21 @@ public: if (Head) Factory.reclaimPool(Head); } - AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc, + AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, bool declspec = false, bool cxx0x = false) { void *memory = allocate(sizeof(AttributeList) + numArgs * sizeof(Expr*)); - return add(new (memory) AttributeList(attrName, attrLoc, + return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, args, numArgs, declspec, cxx0x)); } - AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc, + AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, const AvailabilityChange &introduced, @@ -463,7 +494,7 @@ public: SourceLocation unavailable, bool declspec = false, bool cxx0x = false) { void *memory = allocate(AttributeFactory::AvailabilityAllocSize); - return add(new (memory) AttributeList(attrName, attrLoc, + return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, introduced, deprecated, obsoleted, @@ -566,19 +597,19 @@ public: AttributeList *&getListRef() { return list; } - AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc, + AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, bool declspec = false, bool cxx0x = false) { AttributeList *attr = - pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc, + pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, args, numArgs, declspec, cxx0x); add(attr); return attr; } - AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc, + AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, const AvailabilityChange &introduced, @@ -587,7 +618,7 @@ public: SourceLocation unavailable, bool declspec = false, bool cxx0x = false) { AttributeList *attr = - pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc, + pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, introduced, deprecated, obsoleted, unavailable, declspec, cxx0x); add(attr); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/CXXFieldCollector.h b/contrib/llvm/tools/clang/include/clang/Sema/CXXFieldCollector.h index 63c6ee3..6f3c0b4 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/CXXFieldCollector.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/CXXFieldCollector.h @@ -26,12 +26,12 @@ class CXXFieldCollector { /// Fields - Contains all FieldDecls collected during parsing of a C++ /// class. When a nested class is entered, its fields are appended to the /// fields of its parent class, when it is exited its fields are removed. - llvm::SmallVector<FieldDecl*, 32> Fields; + SmallVector<FieldDecl*, 32> Fields; /// FieldCount - Each entry represents the number of fields collected during /// the parsing of a C++ class. When a nested class is entered, a new field /// count is pushed, when it is exited, the field count is popped. - llvm::SmallVector<size_t, 4> FieldCount; + SmallVector<size_t, 4> FieldCount; // Example: // diff --git a/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h index 74b0105..9e2d60d 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -21,11 +21,6 @@ #include "clang-c/Index.h" #include <string> -namespace llvm { - class raw_ostream; - class Twine; -} - namespace clang { class Decl; @@ -136,7 +131,7 @@ QualType getDeclUsageType(ASTContext &C, NamedDecl *ND); /// /// \param PreferredTypeIsPointer Whether the preferred type for the context /// of this macro is a pointer type. -unsigned getMacroUsagePriority(llvm::StringRef MacroName, +unsigned getMacroUsagePriority(StringRef MacroName, const LangOptions &LangOpts, bool PreferredTypeIsPointer = false); @@ -253,9 +248,9 @@ public: CCC_ObjCInstanceMessage, /// \brief Code completion where an Objective-C class message is expected. CCC_ObjCClassMessage, - /// \brief Code completion where a superclass of an Objective-C class is + /// \brief Code completion where the name of an Objective-C class is /// expected. - CCC_ObjCSuperclass, + CCC_ObjCInterfaceName, /// \brief Code completion where an Objective-C category name is expected. CCC_ObjCCategoryName, /// \brief An unknown context, in which we are recovering from a parsing @@ -273,14 +268,26 @@ private: /// \brief The type of the base object in a member access expression. QualType BaseType; + /// \brief The identifiers for Objective-C selector parts. + IdentifierInfo **SelIdents; + + /// \brief The number of Objective-C selector parts. + unsigned NumSelIdents; + public: /// \brief Construct a new code-completion context of the given kind. - CodeCompletionContext(enum Kind Kind) : Kind(Kind) { } + CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(NULL), + NumSelIdents(0) { } /// \brief Construct a new code-completion context of the given kind. - CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind) { + CodeCompletionContext(enum Kind Kind, QualType T, + IdentifierInfo **SelIdents = NULL, + unsigned NumSelIdents = 0) : Kind(Kind), + SelIdents(SelIdents), + NumSelIdents(NumSelIdents) { if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess || - Kind == CCC_ObjCPropertyAccess) + Kind == CCC_ObjCPropertyAccess || Kind == CCC_ObjCClassMessage || + Kind == CCC_ObjCInstanceMessage) BaseType = T; else PreferredType = T; @@ -297,6 +304,12 @@ public: /// \brief Retrieve the type of the base object in a member-access /// expression. QualType getBaseType() const { return BaseType; } + + /// \brief Retrieve the Objective-C selector identifiers. + IdentifierInfo **getSelIdents() const { return SelIdents; } + + /// \brief Retrieve the number of Objective-C selector identifiers. + unsigned getNumSelIdents() const { return NumSelIdents; } /// \brief Determines whether we want C++ constructors as results within this /// context. @@ -415,19 +428,23 @@ public: private: /// \brief The number of chunks stored in this string. - unsigned NumChunks; + unsigned NumChunks : 16; + /// \brief The number of annotations for this code-completion result. + unsigned NumAnnotations : 16; + /// \brief The priority of this code-completion string. unsigned Priority : 30; /// \brief The availability of this code-completion result. unsigned Availability : 2; - + CodeCompletionString(const CodeCompletionString &); // DO NOT IMPLEMENT CodeCompletionString &operator=(const CodeCompletionString &); // DITTO CodeCompletionString(const Chunk *Chunks, unsigned NumChunks, - unsigned Priority, CXAvailabilityKind Availability); + unsigned Priority, CXAvailabilityKind Availability, + const char **Annotations, unsigned NumAnnotations); ~CodeCompletionString() { } friend class CodeCompletionBuilder; @@ -451,8 +468,14 @@ public: /// \brief Retrieve the priority of this code completion result. unsigned getPriority() const { return Priority; } - /// \brief Reteirve the availability of this code completion result. + /// \brief Retrieve the availability of this code completion result. unsigned getAvailability() const { return Availability; } + + /// \brief Retrieve the number of annotations for this code completion result. + unsigned getAnnotationCount() const; + + /// \brief Retrieve the annotation string specified by \c AnnotationNr. + const char *getAnnotation(unsigned AnnotationNr) const; /// \brief Retrieve a string representation of the code completion string, /// which is mainly useful for debugging. @@ -463,19 +486,19 @@ public: class CodeCompletionAllocator : public llvm::BumpPtrAllocator { public: /// \brief Copy the given string into this allocator. - const char *CopyString(llvm::StringRef String); + const char *CopyString(StringRef String); /// \brief Copy the given string into this allocator. - const char *CopyString(llvm::Twine String); + const char *CopyString(Twine String); // \brief Copy the given string into this allocator. const char *CopyString(const char *String) { - return CopyString(llvm::StringRef(String)); + return CopyString(StringRef(String)); } /// \brief Copy the given string into this allocator. const char *CopyString(const std::string &String) { - return CopyString(llvm::StringRef(String)); + return CopyString(StringRef(String)); } }; @@ -490,7 +513,9 @@ private: CXAvailabilityKind Availability; /// \brief The chunks stored in this string. - llvm::SmallVector<Chunk, 4> Chunks; + SmallVector<Chunk, 4> Chunks; + + SmallVector<const char *, 2> Annotations; public: CodeCompletionBuilder(CodeCompletionAllocator &Allocator) @@ -547,6 +572,8 @@ public: /// \brief Add a new chunk. void AddChunk(Chunk C) { Chunks.push_back(C); } + + void AddAnnotation(const char *A) { Annotations.push_back(A); } }; /// \brief Captures a result of code completion. @@ -619,14 +646,15 @@ public: /// \brief Build a result that refers to a declaration. CodeCompletionResult(NamedDecl *Declaration, NestedNameSpecifier *Qualifier = 0, - bool QualifierIsInformative = false) + bool QualifierIsInformative = false, + bool Accessible = true) : Kind(RK_Declaration), Declaration(Declaration), Priority(getPriorityFromDecl(Declaration)), Availability(CXAvailability_Available), StartParameter(0), Hidden(false), QualifierIsInformative(QualifierIsInformative), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(Qualifier) { - computeCursorKindAndAvailability(); + computeCursorKindAndAvailability(Accessible); } /// \brief Build a result that refers to a keyword or symbol. @@ -688,7 +716,7 @@ public: static unsigned getPriorityFromDecl(NamedDecl *ND); private: - void computeCursorKindAndAvailability(); + void computeCursorKindAndAvailability(bool Accessible = true); }; bool operator<(const CodeCompletionResult &X, const CodeCompletionResult &Y); @@ -709,7 +737,7 @@ inline bool operator>=(const CodeCompletionResult &X, } -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, +raw_ostream &operator<<(raw_ostream &OS, const CodeCompletionString &CCS); /// \brief Abstract interface for a consumer of code-completion @@ -850,7 +878,7 @@ public: /// receives in a simple format. class PrintingCodeCompleteConsumer : public CodeCompleteConsumer { /// \brief The raw output stream. - llvm::raw_ostream &OS; + raw_ostream &OS; CodeCompletionAllocator Allocator; @@ -859,7 +887,7 @@ public: /// results to the given raw output stream. PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns, bool IncludeGlobals, - llvm::raw_ostream &OS) + raw_ostream &OS) : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals, false), OS(OS) {} diff --git a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h index a666499..3260a70 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h @@ -34,7 +34,7 @@ namespace clang { class ASTContext; class TypeLoc; class LangOptions; - class Diagnostic; + class DiagnosticsEngine; class IdentifierInfo; class NamespaceAliasDecl; class NamespaceDecl; @@ -42,6 +42,7 @@ namespace clang { class NestedNameSpecifierLoc; class ObjCDeclSpec; class Preprocessor; + class Sema; class Declarator; struct TemplateIdAnnotation; @@ -242,6 +243,7 @@ public: static const TST TST_char16 = clang::TST_char16; static const TST TST_char32 = clang::TST_char32; static const TST TST_int = clang::TST_int; + static const TST TST_half = clang::TST_half; static const TST TST_float = clang::TST_float; static const TST TST_double = clang::TST_double; static const TST TST_bool = clang::TST_bool; @@ -259,6 +261,7 @@ public: static const TST TST_underlyingType = clang::TST_underlyingType; static const TST TST_auto = clang::TST_auto; static const TST TST_unknown_anytype = clang::TST_unknown_anytype; + static const TST TST_atomic = clang::TST_atomic; static const TST TST_error = clang::TST_error; // type-qualifiers @@ -345,7 +348,7 @@ private: SourceRange TypeofParensRange; SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; - SourceLocation FriendLoc, ConstexprLoc; + SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; WrittenBuiltinSpecs writtenBS; void SaveWrittenBuiltinSpecs(); @@ -355,7 +358,7 @@ private: static bool isTypeRep(TST T) { return (T == TST_typename || T == TST_typeofType || - T == TST_underlyingType); + T == TST_underlyingType || T == TST_atomic); } static bool isExprRep(TST T) { return (T == TST_typeofExpr || T == TST_decltype); @@ -381,7 +384,7 @@ public: TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false), - TypeQualifiers(TSS_unspecified), + TypeQualifiers(TQ_unspecified), FS_inline_specified(false), FS_virtual_specified(false), FS_explicit_specified(false), @@ -537,8 +540,8 @@ public: /// /// TODO: use a more general approach that still allows these /// diagnostics to be ignored when desired. - bool SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const LangOptions &Lang); + bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID); bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec, @@ -592,13 +595,17 @@ public: bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); - + bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID); bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); bool isFriendSpecified() const { return Friend_specified; } SourceLocation getFriendSpecLoc() const { return FriendLoc; } + bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); } + SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; } + bool isConstexprSpecified() const { return Constexpr_specified; } SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; } @@ -657,7 +664,7 @@ public: /// Finish - This does final analysis of the declspec, issuing diagnostics for /// things like "_Imaginary" (lacking an FP type). After calling this method, /// DeclSpec is guaranteed self-consistent, even if an error occurred. - void Finish(Diagnostic &D, Preprocessor &PP); + void Finish(DiagnosticsEngine &D, Preprocessor &PP); const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { return writtenBS; @@ -732,6 +739,7 @@ public: const IdentifierInfo *getSetterName() const { return SetterName; } IdentifierInfo *getSetterName() { return SetterName; } void setSetterName(IdentifierInfo *name) { SetterName = name; } + private: // FIXME: These two are unrelated and mutially exclusive. So perhaps // we can put them in a union to reflect their mutual exclusiveness @@ -961,7 +969,7 @@ public: /// CachedTokens - A set of tokens that has been cached for later /// parsing. -typedef llvm::SmallVector<Token, 4> CachedTokens; +typedef SmallVector<Token, 4> CachedTokens; /// DeclaratorChunk - One instance of this struct is used for each type in a /// declarator that is parsed. @@ -1222,7 +1230,7 @@ struct DeclaratorChunk { void destroy() { switch (Kind) { - default: assert(0 && "Unknown decl type!"); + default: llvm_unreachable("Unknown decl type!"); case DeclaratorChunk::Function: return Fun.destroy(); case DeclaratorChunk::Pointer: return Ptr.destroy(); case DeclaratorChunk::BlockPointer: return Cls.destroy(); @@ -1364,7 +1372,8 @@ public: enum TheContext { FileContext, // File scope declaration. PrototypeContext, // Within a function prototype. - ObjCPrototypeContext,// Within a method prototype. + ObjCResultContext, // An ObjC method result type. + ObjCParameterContext,// An ObjC method parameter type. KNRTypeListContext, // K&R type definition list for formals. TypeNameContext, // Abstract declarator for types. MemberContext, // Struct/Union field. @@ -1395,7 +1404,7 @@ private: /// parsed. This is pushed from the identifier out, which means that element /// #0 will be the most closely bound to the identifier, and /// DeclTypeInfo.back() will be the least closely bound. - llvm::SmallVector<DeclaratorChunk, 8> DeclTypeInfo; + SmallVector<DeclaratorChunk, 8> DeclTypeInfo; /// InvalidType - Set by Sema::GetTypeForDeclarator(). bool InvalidType : 1; @@ -1403,6 +1412,12 @@ private: /// GroupingParens - Set by Parser::ParseParenDeclarator(). bool GroupingParens : 1; + /// FunctionDefinition - Is this Declarator for a function or member defintion + bool FunctionDefinition : 1; + + // Redeclaration - Is this Declarator is a redeclaration. + bool Redeclaration : 1; + /// Attrs - Attributes. ParsedAttributes Attrs; @@ -1428,8 +1443,9 @@ public: Declarator(const DeclSpec &ds, TheContext C) : DS(ds), Range(ds.getSourceRange()), Context(C), InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error), - GroupingParens(false), Attrs(ds.getAttributePool().getFactory()), - AsmLabel(0), InlineParamsUsed(false), Extension(false) { + GroupingParens(false), FunctionDefinition(false), Redeclaration(false), + Attrs(ds.getAttributePool().getFactory()), AsmLabel(0), + InlineParamsUsed(false), Extension(false) { } ~Declarator() { @@ -1462,7 +1478,9 @@ public: TheContext getContext() const { return Context; } bool isPrototypeContext() const { - return (Context == PrototypeContext || Context == ObjCPrototypeContext); + return (Context == PrototypeContext || + Context == ObjCParameterContext || + Context == ObjCResultContext); } /// getSourceRange - Get the source range that spans this declarator. @@ -1522,7 +1540,8 @@ public: case AliasDeclContext: case AliasTemplateContext: case PrototypeContext: - case ObjCPrototypeContext: + case ObjCParameterContext: + case ObjCResultContext: case TemplateParamContext: case CXXNewContext: case CXXCatchContext: @@ -1555,7 +1574,8 @@ public: case CXXNewContext: case AliasDeclContext: case AliasTemplateContext: - case ObjCPrototypeContext: + case ObjCParameterContext: + case ObjCResultContext: case BlockLiteralContext: case TemplateTypeArgContext: return false; @@ -1578,7 +1598,8 @@ public: case MemberContext: case ConditionContext: case PrototypeContext: - case ObjCPrototypeContext: + case ObjCParameterContext: + case ObjCResultContext: case TemplateParamContext: case CXXCatchContext: case ObjCCatchContext: @@ -1783,6 +1804,12 @@ public: bool hasEllipsis() const { return EllipsisLoc.isValid(); } SourceLocation getEllipsisLoc() const { return EllipsisLoc; } void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; } + + void setFunctionDefinition(bool Val) { FunctionDefinition = Val; } + bool isFunctionDefinition() const { return FunctionDefinition; } + + void setRedeclaration(bool Val) { Redeclaration = Val; } + bool isRedeclaration() const { return Redeclaration; } }; /// FieldDeclarator - This little struct is used to capture information about @@ -1828,6 +1855,53 @@ private: SourceLocation LastLocation; }; +/// LambdaCaptureDefault - The default, if any, capture method for a +/// lambda expression. +enum LambdaCaptureDefault { + LCD_None, + LCD_ByCopy, + LCD_ByRef +}; + +/// LambdaCaptureKind - The different capture forms in a lambda +/// introducer: 'this' or a copied or referenced variable. +enum LambdaCaptureKind { + LCK_This, + LCK_ByCopy, + LCK_ByRef +}; + +/// LambdaCapture - An individual capture in a lambda introducer. +struct LambdaCapture { + LambdaCaptureKind Kind; + SourceLocation Loc; + IdentifierInfo* Id; + + LambdaCapture(LambdaCaptureKind Kind, + SourceLocation Loc, + IdentifierInfo* Id = 0) + : Kind(Kind), Loc(Loc), Id(Id) + {} +}; + +/// LambdaIntroducer - Represents a complete lambda introducer. +struct LambdaIntroducer { + SourceRange Range; + LambdaCaptureDefault Default; + llvm::SmallVector<LambdaCapture, 4> Captures; + + LambdaIntroducer() + : Default(LCD_None) {} + + /// addCapture - Append a capture in a lambda introducer. + void addCapture(LambdaCaptureKind Kind, + SourceLocation Loc, + IdentifierInfo* Id = 0) { + Captures.push_back(LambdaCapture(Kind, Loc, Id)); + } + +}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h index 8ab9382..dd2603d 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h @@ -123,7 +123,7 @@ public: static DelayedDiagnostic makeDeprecation(SourceLocation Loc, const NamedDecl *D, - llvm::StringRef Msg); + StringRef Msg); static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity) { @@ -163,9 +163,9 @@ public: return DeprecationData.Decl; } - llvm::StringRef getDeprecationMessage() const { + StringRef getDeprecationMessage() const { assert(Kind == Deprecation && "Not a deprecation diagnostic."); - return llvm::StringRef(DeprecationData.Message, + return StringRef(DeprecationData.Message, DeprecationData.MessageLen); } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Designator.h b/contrib/llvm/tools/clang/include/clang/Sema/Designator.h index 6fe7ab2..fe01f4d 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Designator.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Designator.h @@ -185,7 +185,7 @@ class Designation { unsigned InitIndex; /// Designators - The actual designators for this initializer. - llvm::SmallVector<Designator, 2> Designators; + SmallVector<Designator, 2> Designators; Designation(unsigned Idx) : InitIndex(Idx) {} public: diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h index 072e1b5..7b83625 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h @@ -14,15 +14,30 @@ #define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H #include "clang/AST/ExternalASTSource.h" +#include "clang/Sema/Weak.h" #include <utility> namespace clang { +class CXXConstructorDecl; +class CXXRecordDecl; +class DeclaratorDecl; +class LookupResult; struct ObjCMethodList; -class Sema; class Scope; -class LookupResult; - +class Sema; +class TypedefNameDecl; +class ValueDecl; +class VarDecl; + +/// \brief A simple structure that captures a vtable use for the purposes of +/// the \c ExternalSemaSource. +struct ExternalVTableUse { + CXXRecordDecl *Record; + SourceLocation Location; + bool DefinitionRequired; +}; + /// \brief An abstract interface that should be implemented by /// external AST sources that also provide information for semantic /// analysis. @@ -52,7 +67,7 @@ public: /// \brief Load the set of namespaces that are known to the external source, /// which will be used during typo correction. virtual void ReadKnownNamespaces( - llvm::SmallVectorImpl<NamespaceDecl *> &Namespaces); + SmallVectorImpl<NamespaceDecl *> &Namespaces); /// \brief Do last resort, unqualified lookup on a LookupResult that /// Sema cannot find. @@ -64,12 +79,107 @@ public: /// \return true to tell Sema to recover using the LookupResult. virtual bool LookupUnqualified(LookupResult &R, Scope *S) { return false; } + /// \brief Read the set of tentative definitions known to the external Sema + /// source. + /// + /// The external source should append its own tentative definitions to the + /// given vector of tentative definitions. Note that this routine may be + /// invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + virtual void ReadTentativeDefinitions( + SmallVectorImpl<VarDecl *> &TentativeDefs) {} + + /// \brief Read the set of unused file-scope declarations known to the + /// external Sema source. + /// + /// The external source should append its own unused, filed-scope to the + /// given vector of declarations. Note that this routine may be + /// invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + virtual void ReadUnusedFileScopedDecls( + SmallVectorImpl<const DeclaratorDecl *> &Decls) {} + + /// \brief Read the set of delegating constructors known to the + /// external Sema source. + /// + /// The external source should append its own delegating constructors to the + /// given vector of declarations. Note that this routine may be + /// invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + virtual void ReadDelegatingConstructors( + SmallVectorImpl<CXXConstructorDecl *> &Decls) {} + + /// \brief Read the set of ext_vector type declarations known to the + /// external Sema source. + /// + /// The external source should append its own ext_vector type declarations to + /// the given vector of declarations. Note that this routine may be + /// invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {} + + /// \brief Read the set of dynamic classes known to the external Sema source. + /// + /// The external source should append its own dynamic classes to + /// the given vector of declarations. Note that this routine may be + /// invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {} + + /// \brief Read the set of locally-scoped external declarations known to the + /// external Sema source. + /// + /// The external source should append its own locally-scoped external + /// declarations to the given vector of declarations. Note that this routine + /// may be invoked multiple times; the external source should take care not + /// to introduce the same declarations repeatedly. + virtual void ReadLocallyScopedExternalDecls( + SmallVectorImpl<NamedDecl *> &Decls) {} + + /// \brief Read the set of referenced selectors known to the + /// external Sema source. + /// + /// The external source should append its own referenced selectors to the + /// given vector of selectors. Note that this routine + /// may be invoked multiple times; the external source should take care not + /// to introduce the same selectors repeatedly. + virtual void ReadReferencedSelectors( + SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {} + + /// \brief Read the set of weak, undeclared identifiers known to the + /// external Sema source. + /// + /// The external source should append its own weak, undeclared identifiers to + /// the given vector. Note that this routine may be invoked multiple times; + /// the external source should take care not to introduce the same identifiers + /// repeatedly. + virtual void ReadWeakUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) {} + + /// \brief Read the set of used vtables known to the external Sema source. + /// + /// The external source should append its own used vtables to the given + /// vector. Note that this routine may be invoked multiple times; the external + /// source should take care not to introduce the same vtables repeatedly. + virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {} + + /// \brief Read the set of pending instantiations known to the external + /// Sema source. + /// + /// The external source should append its own pending instantiations to the + /// given vector. Note that this routine may be invoked multiple times; the + /// external source should take care not to introduce the same instantiations + /// repeatedly. + virtual void ReadPendingInstantiations( + SmallVectorImpl<std::pair<ValueDecl *, + SourceLocation> > &Pending) {} + // isa/cast/dyn_cast support static bool classof(const ExternalASTSource *Source) { return Source->SemaSource; } static bool classof(const ExternalSemaSource *) { return true; } -}; +}; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Sema/IdentifierResolver.h b/contrib/llvm/tools/clang/include/clang/Sema/IdentifierResolver.h index 8d79fc0..85d8ad2 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/IdentifierResolver.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/IdentifierResolver.h @@ -37,7 +37,7 @@ class IdentifierResolver { /// decl with that declaration name is shadowed in some scope. class IdDeclInfo { public: - typedef llvm::SmallVector<NamedDecl*, 2> DeclsTy; + typedef SmallVector<NamedDecl*, 2> DeclsTy; inline DeclsTy::iterator decls_begin() { return Decls.begin(); } inline DeclsTy::iterator decls_end() { return Decls.end(); } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h b/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h index df6138c..e69bebd 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h @@ -22,10 +22,6 @@ #include "llvm/ADT/SmallVector.h" #include <cassert> -namespace llvm { - class raw_ostream; -} - namespace clang { class CXXBaseSpecifier; @@ -71,7 +67,10 @@ public: EK_VectorElement, /// \brief The entity being initialized is a field of block descriptor for /// the copied-in c++ object. - EK_BlockElement + EK_BlockElement, + /// \brief The entity being initialized is the real or imaginary part of a + /// complex number. + EK_ComplexElement }; private: @@ -115,8 +114,9 @@ private: /// virtual base. uintptr_t Base; - /// \brief When Kind == EK_ArrayElement or EK_VectorElement, the - /// index of the array or vector element being initialized. + /// \brief When Kind == EK_ArrayElement, EK_VectorElement, or + /// EK_ComplexElement, the index of the array or vector element being + /// initialized. unsigned Index; }; @@ -313,7 +313,8 @@ public: /// \brief If this is already the initializer for an array or vector /// element, sets the element index. void setElementIndex(unsigned Index) { - assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement); + assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement || + EK_ComplexElement); this->Index = Index; } }; @@ -525,8 +526,10 @@ public: SK_QualificationConversionLValue, /// \brief Perform an implicit conversion sequence. SK_ConversionSequence, - /// \brief Perform list-initialization + /// \brief Perform list-initialization without a constructor SK_ListInitialization, + /// \brief Perform list-initialization with a constructor. + SK_ListConstructorCall, /// \brief Perform initialization via a constructor. SK_ConstructorInitialization, /// \brief Zero-initialize the object @@ -562,20 +565,24 @@ public: /// \brief When Kind == SK_ResolvedOverloadedFunction or Kind == /// SK_UserConversion, the function that the expression should be /// resolved to or the conversion function to call, respectively. + /// When Kind == SK_ConstructorInitialization or SK_ListConstruction, + /// the constructor to be called. /// - /// Always a FunctionDecl. + /// Always a FunctionDecl, plus a Boolean flag telling if it was + /// selected from an overloaded set having size greater than 1. /// For conversion decls, the naming class is the source type. /// For construct decls, the naming class is the target type. struct { + bool HadMultipleCandidates; FunctionDecl *Function; DeclAccessPair FoundDecl; } Function; - + /// \brief When Kind = SK_ConversionSequence, the implicit conversion /// sequence ImplicitConversionSequence *ICS; }; - + void Destroy(); }; @@ -584,7 +591,7 @@ private: enum SequenceKind SequenceKind; /// \brief Steps taken by this initialization. - llvm::SmallVector<Step, 4> Steps; + SmallVector<Step, 4> Steps; public: /// \brief Describes why initialization failed. @@ -633,11 +640,13 @@ public: /// \brief Default-initialization of a 'const' object. FK_DefaultInitOfConst, /// \brief Initialization of an incomplete type. - FK_Incomplete + FK_Incomplete, + /// \brief List initialization failed at some point. + FK_ListInitializationFailed }; private: - /// \brief The reason why initialization failued. + /// \brief The reason why initialization failed. FailureKind Failure; /// \brief The failed result of overload resolution. @@ -722,7 +731,7 @@ public: /// \brief Determine whether the initialization sequence is invalid. bool Failed() const { return SequenceKind == FailedSequence; } - typedef llvm::SmallVector<Step, 4>::const_iterator step_iterator; + typedef SmallVector<Step, 4>::const_iterator step_iterator; step_iterator step_begin() const { return Steps.begin(); } step_iterator step_end() const { return Steps.end(); } @@ -736,7 +745,18 @@ public: /// \brief Determine whether this initialization is direct call to a /// constructor. bool isConstructorInitialization() const; - + + /// \brief Returns whether the last step in this initialization sequence is a + /// narrowing conversion, defined by C++0x [dcl.init.list]p7. + /// + /// If this function returns true, *isInitializerConstant will be set to + /// describe whether *Initializer was a constant expression. If + /// *isInitializerConstant is set to true, *ConstantValue will be set to the + /// evaluated value of *Initializer. + bool endsWithNarrowing(ASTContext &Ctx, const Expr *Initializer, + bool *isInitializerConstant, + APValue *ConstantValue) const; + /// \brief Add a new step in the initialization that resolves the address /// of an overloaded function to a specific function declaration. /// @@ -792,7 +812,7 @@ public: void AddConversionSequenceStep(const ImplicitConversionSequence &ICS, QualType T); - /// \brief Add a list-initialiation step + /// \brief Add a list-initialiation step. void AddListInitializationStep(QualType T); /// \brief Add a constructor-initialization step. @@ -857,7 +877,7 @@ public: /// \brief Dump a representation of this initialization sequence to /// the given stream, for debugging purposes. - void dump(llvm::raw_ostream &OS) const; + void dump(raw_ostream &OS) const; /// \brief Dump a representation of this initialization sequence to /// standard error, for debugging purposes. diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h b/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h index dceed4e..6630bb2 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h @@ -268,7 +268,19 @@ public: /// \brief Tests whether the given declaration is acceptable. bool isAcceptableDecl(NamedDecl *D) const { - return D->isInIdentifierNamespace(IDNS); + if (!D->isInIdentifierNamespace(IDNS)) + return false; + + // So long as this declaration is not module-private or was parsed as + // part of this translation unit (i.e., in the module), we're allowed to + // find it. + if (!D->isModulePrivate() || !D->isFromASTFile()) + return true; + + // FIXME: We should be allowed to refer to a module-private name from + // within the same module, e.g., during template instantiation. + // This requires us know which module a particular declaration came from. + return false; } /// \brief Returns the identifier namespace mask for this lookup. @@ -282,18 +294,6 @@ public: return NamingClass != 0; } - /// \brief Set whether the name lookup is triggered by a - /// using declaration. - void setUsingDeclaration(bool U) { - UsingDeclaration = U; - } - - /// \brief Returns whether the name lookup is triggered by a - /// using declaration. - bool isUsingDeclaration() const { - return UsingDeclaration; - } - /// \brief Returns the 'naming class' for this lookup, i.e. the /// class which was looked into to find these results. /// @@ -468,7 +468,7 @@ public: configure(); } - void print(llvm::raw_ostream &); + void print(raw_ostream &); /// Suppress the diagnostics that would normally fire because of this /// lookup. This happens during (e.g.) redeclaration lookups. @@ -615,10 +615,6 @@ private: bool HideTags; bool Diagnose; - - /// \brief True if the lookup is triggered by a using declaration. - /// Necessary to handle a MSVC bug. - bool UsingDeclaration; }; /// \brief Consumes visible declarations found when searching for @@ -640,9 +636,11 @@ private: /// \param Hiding a declaration that hides the declaration \p ND, /// or NULL if no such declaration exists. /// + /// \param Ctx the original context from which the lookup started. + /// /// \param InBaseClass whether this declaration was found in base /// class of the context we searched. - virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, + virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, bool InBaseClass) = 0; }; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/MultiInitializer.h b/contrib/llvm/tools/clang/include/clang/Sema/MultiInitializer.h new file mode 100644 index 0000000..c44e393 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Sema/MultiInitializer.h @@ -0,0 +1,72 @@ +//===--- MultiInitializer.h - Initializer expression group ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MultiInitializer class, which can represent a list +// initializer or a parentheses-wrapped group of expressions in a C++ member +// initializer. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_MULTIINITIALIZER_H +#define LLVM_CLANG_SEMA_MULTIINITIALIZER_H + +#include "clang/Sema/Ownership.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/PointerUnion.h" + +namespace clang { + class ASTContext; + class Expr; + class InitializationKind; + class InitializedEntity; + class InitListExpr; + class Sema; + +class MultiInitializer { + llvm::PointerUnion<Expr*, Expr**> InitListOrExpressions; + unsigned NumInitializers; + SourceLocation LParenLoc; + SourceLocation RParenLoc; + + InitListExpr *getInitList() const; + Expr **getExpressions() const { return InitListOrExpressions.get<Expr**>(); } + +public: + MultiInitializer(Expr* InitList) + : InitListOrExpressions(InitList) + {} + + MultiInitializer(SourceLocation LParenLoc, Expr **Exprs, unsigned NumInits, + SourceLocation RParenLoc) + : InitListOrExpressions(Exprs), NumInitializers(NumInits), + LParenLoc(LParenLoc), RParenLoc(RParenLoc) + {} + + bool isInitializerList() const { return InitListOrExpressions.is<Expr*>(); } + + SourceLocation getStartLoc() const; + SourceLocation getEndLoc() const; + + typedef Expr **iterator; + iterator begin() const; + iterator end() const; + + bool isTypeDependent() const; + + bool DiagnoseUnexpandedParameterPack(Sema &SemaRef) const; + + // Return the InitListExpr or create a ParenListExpr. + Expr *CreateInitExpr(ASTContext &Ctx, QualType T) const; + + ExprResult PerformInit(Sema &SemaRef, InitializedEntity Entity, + InitializationKind Kind) const; +}; +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Overload.h b/contrib/llvm/tools/clang/include/clang/Sema/Overload.h index 32d4cbd..dbc0926 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Overload.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Overload.h @@ -21,6 +21,7 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/AST/UnresolvedSet.h" +#include "clang/Sema/SemaFixItUtils.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -243,7 +244,12 @@ namespace clang { // a gcc code gen. bug which causes a crash in a test. Putting it here seems // to work around the crash. bool EllipsisConversion : 1; - + + /// HadMultipleCandidates - When this is true, it means that the + /// conversion function was resolved from an overloaded set having + /// size greater than 1. + bool HadMultipleCandidates : 1; + /// After - Represents the standard conversion that occurs after /// the actual user-defined conversion. StandardConversionSequence After; @@ -255,14 +261,14 @@ namespace clang { /// \brief The declaration that we found via name lookup, which might be /// the same as \c ConversionFunction or it might be a using declaration /// that refers to \c ConversionFunction. - NamedDecl *FoundConversionFunction; + DeclAccessPair FoundConversionFunction; void DebugPrint() const; }; /// Represents an ambiguous user-defined conversion sequence. struct AmbiguousConversionSequence { - typedef llvm::SmallVector<FunctionDecl*, 4> ConversionSet; + typedef SmallVector<FunctionDecl*, 4> ConversionSet; void *FromTypePtr; void *ToTypePtr; @@ -463,6 +469,7 @@ namespace clang { bool isEllipsis() const { return getKind() == EllipsisConversion; } bool isAmbiguous() const { return getKind() == AmbiguousConversion; } bool isUserDefined() const { return getKind() == UserDefinedConversion; } + bool isFailure() const { return isBad() || isAmbiguous(); } /// Determines whether this conversion sequence has been /// initialized. Most operations should never need to query @@ -525,7 +532,12 @@ namespace clang { /// This conversion function template specialization candidate is not /// viable because the final conversion was not an exact match. - ovl_fail_final_conversion_not_exact + ovl_fail_final_conversion_not_exact, + + /// (CUDA) This candidate was not viable because the callee + /// was not accessible from the caller's target (i.e. host->device, + /// global->host, device->host). + ovl_fail_bad_target }; /// OverloadCandidate - A single candidate in an overload set (C++ 13.3). @@ -554,7 +566,10 @@ namespace clang { /// Conversions - The conversion sequences used to convert the /// function arguments to the function parameters. - llvm::SmallVector<ImplicitConversionSequence, 4> Conversions; + SmallVector<ImplicitConversionSequence, 4> Conversions; + + /// The FixIt hints which can be used to fix the Bad candidate. + ConversionFixItGenerator Fix; /// Viable - True to indicate that this overload candidate is viable. bool Viable; @@ -624,19 +639,32 @@ namespace clang { /// hasAmbiguousConversion - Returns whether this overload /// candidate requires an ambiguous conversion or not. bool hasAmbiguousConversion() const { - for (llvm::SmallVectorImpl<ImplicitConversionSequence>::const_iterator + for (SmallVectorImpl<ImplicitConversionSequence>::const_iterator I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { if (!I->isInitialized()) return false; if (I->isAmbiguous()) return true; } return false; } + + bool TryToFixBadConversion(unsigned Idx, Sema &S) { + bool CanFix = Fix.tryToFixConversion( + Conversions[Idx].Bad.FromExpr, + Conversions[Idx].Bad.getFromType(), + Conversions[Idx].Bad.getToType(), S); + + // If at least one conversion fails, the candidate cannot be fixed. + if (!CanFix) + Fix.clear(); + + return CanFix; + } }; /// OverloadCandidateSet - A set of overload candidates, used in C++ /// overload resolution (C++ 13.3). - class OverloadCandidateSet : public llvm::SmallVector<OverloadCandidate, 16> { - typedef llvm::SmallVector<OverloadCandidate, 16> inherited; + class OverloadCandidateSet : public SmallVector<OverloadCandidate, 16> { + typedef SmallVector<OverloadCandidate, 16> inherited; llvm::SmallPtrSet<Decl *, 16> Functions; SourceLocation Loc; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h b/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h index cef93fe..fb9e368d 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H #define LLVM_CLANG_SEMA_OWNERSHIP_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/PointerIntPair.h" @@ -368,7 +369,7 @@ namespace clang { /// \brief A small vector that owns a set of AST nodes. template <class PtrTy, unsigned N = 8> - class ASTOwningVector : public llvm::SmallVector<PtrTy, N> { + class ASTOwningVector : public SmallVector<PtrTy, N> { ASTOwningVector(ASTOwningVector &); // do not implement ASTOwningVector &operator=(ASTOwningVector &); // do not implement diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h b/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h index 1f572e5..735a26b 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h @@ -114,7 +114,7 @@ namespace clang { KindType Kind; /// \brief The actual template argument representation, which may be - /// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an + /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an /// expression), or an ActionBase::TemplateTy (for a template). void *Arg; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/PrettyDeclStackTrace.h b/contrib/llvm/tools/clang/include/clang/Sema/PrettyDeclStackTrace.h index b78a1c0..a31312c 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/PrettyDeclStackTrace.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/PrettyDeclStackTrace.h @@ -38,7 +38,7 @@ public: PrettyDeclStackTraceEntry(Sema &S, Decl *D, SourceLocation Loc, const char *Msg) : S(S), TheDecl(D), Loc(Loc), Message(Msg) {} - virtual void print(llvm::raw_ostream &OS) const; + virtual void print(raw_ostream &OS) const; }; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Scope.h b/contrib/llvm/tools/clang/include/clang/Sema/Scope.h index 95d2978..cff8b33 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Scope.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Scope.h @@ -149,14 +149,14 @@ private: /// maintained by the Action implementation. void *Entity; - typedef llvm::SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy; + typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy; UsingDirectivesTy UsingDirectives; /// \brief Used to determine if errors occurred in this scope. DiagnosticErrorTrap ErrorTrap; public: - Scope(Scope *Parent, unsigned ScopeFlags, Diagnostic &Diag) + Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag) : ErrorTrap(Diag) { Init(Parent, ScopeFlags); } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h index 51297ae..9ef6d3c 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h @@ -66,17 +66,17 @@ public: /// SwitchStack - This is the current set of active switch statements in the /// block. - llvm::SmallVector<SwitchStmt*, 8> SwitchStack; + SmallVector<SwitchStmt*, 8> SwitchStack; /// \brief The list of return statements that occur within the function or /// block, if there is any chance of applying the named return value /// optimization. - llvm::SmallVector<ReturnStmt*, 4> Returns; + SmallVector<ReturnStmt*, 4> Returns; /// \brief A list of PartialDiagnostics created but delayed within the /// current function scope. These diagnostics are vetted for reachability /// prior to being emitted. - llvm::SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; + SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; void setHasBranchIntoScope() { HasBranchIntoScope = true; @@ -95,7 +95,7 @@ public: (HasBranchProtectedScope && HasBranchIntoScope); } - FunctionScopeInfo(Diagnostic &Diag) + FunctionScopeInfo(DiagnosticsEngine &Diag) : IsBlockInfo(false), HasBranchProtectedScope(false), HasBranchIntoScope(false), @@ -132,12 +132,12 @@ public: llvm::DenseMap<VarDecl*, unsigned> CaptureMap; /// Captures - The captured variables. - llvm::SmallVector<BlockDecl::Capture, 4> Captures; + SmallVector<BlockDecl::Capture, 4> Captures; /// CapturesCXXThis - Whether this block captures 'this'. bool CapturesCXXThis; - BlockScopeInfo(Diagnostic &Diag, Scope *BlockScope, BlockDecl *Block) + BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) : FunctionScopeInfo(Diag), TheDecl(Block), TheScope(BlockScope), CapturesCXXThis(false) { diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h index 263c1bd..22d5db2 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h @@ -20,8 +20,11 @@ #include "clang/Sema/IdentifierResolver.h" #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/ExternalSemaSource.h" #include "clang/Sema/LocInfoType.h" +#include "clang/Sema/MultiInitializer.h" #include "clang/Sema/TypoCorrection.h" +#include "clang/Sema/Weak.h" #include "clang/AST/Expr.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" @@ -30,6 +33,7 @@ #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" #include "clang/Basic/ExpressionTraits.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -54,7 +58,7 @@ namespace clang { class BlockDecl; class CXXBasePath; class CXXBasePaths; - typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; + typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; class CXXConstructorDecl; class CXXConversionDecl; class CXXDestructorDecl; @@ -175,13 +179,6 @@ public: typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; typedef OpaquePtr<TemplateName> TemplateTy; typedef OpaquePtr<QualType> TypeTy; - typedef Attr AttrTy; - typedef CXXBaseSpecifier BaseTy; - typedef CXXCtorInitializer MemInitTy; - typedef Expr ExprTy; - typedef Stmt StmtTy; - typedef TemplateParameterList TemplateParamsTy; - typedef NestedNameSpecifier CXXScopeTy; OpenCLOptions OpenCLFeatures; FPOptions FPFeatures; @@ -190,7 +187,7 @@ public: Preprocessor &PP; ASTContext &Context; ASTConsumer &Consumer; - Diagnostic &Diags; + DiagnosticsEngine &Diags; SourceManager &SourceMgr; /// \brief Flag indicating whether or not to collect detailed statistics. @@ -205,6 +202,10 @@ public: /// CurContext - This is the current declaration context of parsing. DeclContext *CurContext; + /// \brief Generally null except when we temporarily switch decl contexts, + /// like in \see ActOnObjCTemporaryExitContainerContext. + DeclContext *OriginalLexicalContext; + /// VAListTagName - The declaration name corresponding to __va_list_tag. /// This is used as part of a hack to omit that class from ADL results. DeclarationName VAListTagName; @@ -228,16 +229,20 @@ public: /// This array is never empty. Clients should ignore the first /// element, which is used to cache a single FunctionScopeInfo /// that's used to parse every top-level function. - llvm::SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes; + SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes; /// ExprTemporaries - This is the stack of temporaries that are created by /// the current full expression. - llvm::SmallVector<CXXTemporary*, 8> ExprTemporaries; + SmallVector<CXXTemporary*, 8> ExprTemporaries; + + typedef LazyVector<TypedefNameDecl *, ExternalSemaSource, + &ExternalSemaSource::ReadExtVectorDecls, 2, 2> + ExtVectorDeclsType; /// ExtVectorDecls - This is a list all the extended vector types. This allows /// us to associate a raw vector type with one of the ext_vector type names. /// This is only necessary for issuing pretty diagnostics. - llvm::SmallVector<TypedefNameDecl*, 24> ExtVectorDecls; + ExtVectorDeclsType ExtVectorDecls; /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes. llvm::OwningPtr<CXXFieldCollector> FieldCollector; @@ -279,22 +284,38 @@ public: /// we find this declaration of "foo" and complain that it is /// not visible. llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternalDecls; + + /// \brief Look for a locally scoped external declaration by the given name. + llvm::DenseMap<DeclarationName, NamedDecl *>::iterator + findLocallyScopedExternalDecl(DeclarationName Name); + + typedef LazyVector<VarDecl *, ExternalSemaSource, + &ExternalSemaSource::ReadTentativeDefinitions, 2, 2> + TentativeDefinitionsType; /// \brief All the tentative definitions encountered in the TU. - llvm::SmallVector<VarDecl *, 2> TentativeDefinitions; + TentativeDefinitionsType TentativeDefinitions; + typedef LazyVector<const DeclaratorDecl *, ExternalSemaSource, + &ExternalSemaSource::ReadUnusedFileScopedDecls, 2, 2> + UnusedFileScopedDeclsType; + /// \brief The set of file scoped decls seen so far that have not been used /// and must warn if not used. Only contains the first declaration. - llvm::SmallVector<const DeclaratorDecl*, 4> UnusedFileScopedDecls; + UnusedFileScopedDeclsType UnusedFileScopedDecls; + + typedef LazyVector<CXXConstructorDecl *, ExternalSemaSource, + &ExternalSemaSource::ReadDelegatingConstructors, 2, 2> + DelegatingCtorDeclsType; /// \brief All the delegating constructors seen so far in the file, used for /// cycle detection at the end of the TU. - llvm::SmallVector<CXXConstructorDecl*, 4> DelegatingCtorDecls; + DelegatingCtorDeclsType DelegatingCtorDecls; /// \brief All the overriding destructors seen during a class definition /// (there could be multiple due to nested classes) that had their exception /// spec checks delayed, plus the overridden destructor. - llvm::SmallVector<std::pair<const CXXDestructorDecl*, + SmallVector<std::pair<const CXXDestructorDecl*, const CXXDestructorDecl*>, 2> DelayedDestructorExceptionSpecChecks; @@ -431,32 +452,17 @@ public: /// WeakUndeclaredIdentifiers - Identifiers contained in /// #pragma weak before declared. rare. may alias another /// identifier, declared or undeclared - class WeakInfo { - IdentifierInfo *alias; // alias (optional) - SourceLocation loc; // for diagnostics - bool used; // identifier later declared? - public: - WeakInfo() - : alias(0), loc(SourceLocation()), used(false) {} - WeakInfo(IdentifierInfo *Alias, SourceLocation Loc) - : alias(Alias), loc(Loc), used(false) {} - inline IdentifierInfo * getAlias() const { return alias; } - inline SourceLocation getLocation() const { return loc; } - void setUsed(bool Used=true) { used = Used; } - inline bool getUsed() { return used; } - bool operator==(WeakInfo RHS) const { - return alias == RHS.getAlias() && loc == RHS.getLocation(); - } - bool operator!=(WeakInfo RHS) const { return !(*this == RHS); } - }; llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers; + /// \brief Load weak undeclared identifiers from the external source. + void LoadExternalWeakUndeclaredIdentifiers(); + /// WeakTopLevelDecl - Translation-unit scoped declarations generated by /// #pragma weak during processing of other Decls. /// I couldn't figure out a clean way to generate these in-line, so /// we store them here and handle separately -- which is a hack. /// It would be best to refactor this. - llvm::SmallVector<Decl*,2> WeakTopLevelDecl; + SmallVector<Decl*,2> WeakTopLevelDecl; IdentifierResolver IdResolver; @@ -482,13 +488,21 @@ public: /// have been declared. bool GlobalNewDeleteDeclared; + + /// A flag that is set when parsing a -dealloc method and no [super dealloc] + /// call was found yet. + bool ObjCShouldCallSuperDealloc; + /// A flag that is set when parsing a -finalize method and no [super finalize] + /// call was found yet. + bool ObjCShouldCallSuperFinalize; + /// \brief The set of declarations that have been referenced within /// a potentially evaluated expression. - typedef llvm::SmallVector<std::pair<SourceLocation, Decl *>, 10> + typedef SmallVector<std::pair<SourceLocation, Decl *>, 10> PotentiallyReferencedDecls; /// \brief A set of diagnostics that may be emitted. - typedef llvm::SmallVector<std::pair<SourceLocation, PartialDiagnostic>, 10> + typedef SmallVector<std::pair<SourceLocation, PartialDiagnostic>, 10> PotentiallyEmittedDiagnostics; /// \brief Describes how the expressions currently being parsed are @@ -578,7 +592,7 @@ public: }; /// A stack of expression evaluation contexts. - llvm::SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; + SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; /// SpecialMemberOverloadResult - The overloading result for a special member /// function. @@ -618,23 +632,21 @@ public: /// for C++ records. llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache; - /// \brief Whether the code handled by Sema should be considered a - /// complete translation unit or not. + /// \brief The kind of translation unit we are processing. /// - /// When true (which is generally the case), Sema will perform + /// When we're processing a complete translation unit, Sema will perform /// end-of-translation-unit semantic tasks (such as creating /// initializers for tentative definitions in C) once parsing has - /// completed. This flag will be false when building PCH files, - /// since a PCH file is by definition not a complete translation - /// unit. - bool CompleteTranslationUnit; + /// completed. Modules and precompiled headers perform different kinds of + /// checks. + TranslationUnitKind TUKind; llvm::BumpPtrAllocator BumpAlloc; /// \brief The number of SFINAE diagnostics that have been trapped. unsigned NumSFINAEErrors; - typedef llvm::DenseMap<ParmVarDecl *, llvm::SmallVector<ParmVarDecl *, 1> > + typedef llvm::DenseMap<ParmVarDecl *, SmallVector<ParmVarDecl *, 1> > UnparsedDefaultArgInstantiationsMap; /// \brief A mapping from parameters with unparsed default arguments to the @@ -673,7 +685,7 @@ public: bool isSelfExpr(Expr *RExpr); public: Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, CodeCompleteConsumer *CompletionConsumer = 0); ~Sema(); @@ -685,7 +697,7 @@ public: OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; } FPOptions &getFPOptions() { return FPFeatures; } - Diagnostic &getDiagnostics() const { return Diags; } + DiagnosticsEngine &getDiagnostics() const { return Diags; } SourceManager &getSourceManager() const { return SourceMgr; } const TargetAttributesSema &getTargetAttributesSema() const; Preprocessor &getPreprocessor() const { return PP; } @@ -727,7 +739,7 @@ public: /// \brief Build a partial diagnostic. PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h - bool findMacroSpelling(SourceLocation &loc, llvm::StringRef name); + bool findMacroSpelling(SourceLocation &loc, StringRef name); ExprResult Owned(Expr* E) { return E; } ExprResult Owned(ExprResult R) { return R; } @@ -754,7 +766,7 @@ public: sema::BlockScopeInfo *getCurBlock(); /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls - llvm::SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; } + SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; } //===--------------------------------------------------------------------===// // Type Analysis / Processing: SemaType.cpp. @@ -785,6 +797,7 @@ public: QualType BuildBlockPointerType(QualType T, SourceLocation Loc, DeclarationName Entity); QualType BuildParenType(QualType T); + QualType BuildAtomicType(QualType T, SourceLocation Loc); TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S); TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); @@ -819,6 +832,10 @@ public: TypeResult ActOnTypeName(Scope *S, Declarator &D); + /// \brief The parser has parsed the context-sensitive type 'instancetype' + /// in an Objective-C message declaration. Return the appropriate type. + ParsedType ActOnObjCInstanceType(SourceLocation Loc); + bool RequireCompleteType(SourceLocation Loc, QualType T, const PartialDiagnostic &PD, std::pair<SourceLocation, PartialDiagnostic> Note); @@ -830,6 +847,9 @@ public: std::pair<SourceLocation, PartialDiagnostic> Note); + bool RequireLiteralType(SourceLocation Loc, QualType T, + const PartialDiagnostic &PD, + bool AllowIncompleteType = false); QualType getElaboratedType(ElaboratedTypeKeyword Keyword, const CXXScopeSpec &SS, QualType T); @@ -853,9 +873,10 @@ public: bool isClassName = false, bool HasTrailingDot = false, ParsedType ObjectType = ParsedType(), - bool WantNontrivialTypeSourceInfo = false); + bool WantNontrivialTypeSourceInfo = false, + IdentifierInfo **CorrectedII = 0); TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); - bool isMicrosoftMissingTypename(const CXXScopeSpec *SS); + bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S); bool DiagnoseUnknownTypeName(const IdentifierInfo &II, SourceLocation IILoc, Scope *S, @@ -966,8 +987,7 @@ public: Decl *ActOnDeclarator(Scope *S, Declarator &D); Decl *HandleDeclarator(Scope *S, Declarator &D, - MultiTemplateParamsArg TemplateParameterLists, - bool IsFunctionDefinition); + MultiTemplateParamsArg TemplateParameterLists); void RegisterLocallyScopedExternCDecl(NamedDecl *ND, const LookupResult &Previous, Scope *S); @@ -978,31 +998,46 @@ public: void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D); NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, - QualType R, TypeSourceInfo *TInfo, - LookupResult &Previous, bool &Redeclaration); + TypeSourceInfo *TInfo, + LookupResult &Previous); NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D, LookupResult &Previous, bool &Redeclaration); NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, - QualType R, TypeSourceInfo *TInfo, + TypeSourceInfo *TInfo, LookupResult &Previous, - MultiTemplateParamsArg TemplateParamLists, - bool &Redeclaration); - void CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous, - bool &Redeclaration); + MultiTemplateParamsArg TemplateParamLists); + // Returns true if the variable declaration is a redeclaration + bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckCompleteVariableDeclaration(VarDecl *var); NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, - QualType R, TypeSourceInfo *TInfo, + TypeSourceInfo *TInfo, LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists, - bool IsFunctionDefinition, - bool &Redeclaration); + bool &AddToScope); bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); + + /// \brief The kind of constexpr declaration checking we are performing. + /// + /// The kind affects which diagnostics (if any) are emitted if the function + /// does not satisfy the requirements of a constexpr function declaration. + enum CheckConstexprKind { + /// \brief Check a constexpr function declaration, and produce errors if it + /// does not satisfy the requirements. + CCK_Declaration, + /// \brief Check a constexpr function template instantiation. + CCK_Instantiation, + /// \brief Produce notes explaining why an instantiation was not constexpr. + CCK_NoteNonConstexprInstantiation + }; + bool CheckConstexprFunctionDecl(const FunctionDecl *FD, CheckConstexprKind CCK); + bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body); + void DiagnoseHiddenVirtualMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); - void CheckFunctionDeclaration(Scope *S, + // Returns true if the function declaration is a redeclaration + bool CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, LookupResult &Previous, - bool IsExplicitSpecialization, - bool &Redeclaration); - void CheckMain(FunctionDecl *FD); + bool IsExplicitSpecialization); + void CheckMain(FunctionDecl *FD, const DeclSpec &D); Decl *ActOnParamDeclarator(Scope *S, Declarator &D); ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, @@ -1021,6 +1056,7 @@ public: bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); + void CheckSelfReference(Decl *OrigDecl, Expr *E); void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, bool TypeMayContainAuto); void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto); @@ -1041,9 +1077,14 @@ public: Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D); void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); + void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation); + /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an + /// attribute for which parsing is delayed. + void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs); + /// \brief Diagnose any unused parameters in the given sequence of /// ParmVarDecl pointers. void DiagnoseUnusedParameters(ParmVarDecl * const *Begin, @@ -1062,6 +1103,26 @@ public: SourceLocation AsmLoc, SourceLocation RParenLoc); + /// \brief The parser has processed a module import declaration. + /// + /// \param ImportLoc The location of the '__import_module__' keyword. + /// + /// \param ModuleName The name of the module. + /// + /// \param ModuleNameLoc The location of the module name. + DeclResult ActOnModuleImport(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc); + + /// \brief Diagnose that \p New is a module-private redeclaration of + /// \p Old. + void diagnoseModulePrivateRedeclaration(NamedDecl *New, NamedDecl *Old, + SourceLocation ModulePrivateKeyword + = SourceLocation()); + + /// \brief Retrieve a suitable printing policy. + PrintingPolicy getPrintingPolicy() const; + /// Scope actions. void ActOnPopScope(SourceLocation Loc, Scope *S); void ActOnTranslationUnitScope(Scope *S); @@ -1097,6 +1158,7 @@ public: SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, AccessSpecifier AS, + SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, bool ScopedEnum, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType); @@ -1118,7 +1180,7 @@ public: void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, IdentifierInfo *ClassName, - llvm::SmallVectorImpl<Decl *> &Decls); + SmallVectorImpl<Decl *> &Decls); Decl *ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth); @@ -1146,15 +1208,15 @@ public: bool CheckNontrivialField(FieldDecl *FD); void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem); CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD); - void ActOnLastBitfield(SourceLocation DeclStart, Decl *IntfDecl, - llvm::SmallVectorImpl<Decl *> &AllIvarDecls); - Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, Decl *IntfDecl, + void ActOnLastBitfield(SourceLocation DeclStart, + SmallVectorImpl<Decl *> &AllIvarDecls); + Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth, tok::ObjCKeywordKind visibility); // This is used for both record definitions and ObjC interface declarations. void ActOnFields(Scope* S, SourceLocation RecLoc, Decl *TagDecl, - Decl **Fields, unsigned NumFields, + llvm::ArrayRef<Decl *> Fields, SourceLocation LBrac, SourceLocation RBrac, AttributeList *AttrList); @@ -1163,6 +1225,8 @@ public: /// struct, or union). void ActOnTagStartDefinition(Scope *S, Decl *TagDecl); + Decl *ActOnObjCContainerStartDefinition(Decl *IDecl); + /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a /// C++ record definition's base-specifiers clause and are starting its /// member declarations. @@ -1175,6 +1239,15 @@ public: void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, SourceLocation RBraceLoc); + void ActOnObjCContainerFinishDefinition(); + + /// \brief Invoked when we must temporarily exit the objective-c container + /// scope for parsing/looking-up C constructs. + /// + /// Must be followed by a call to \see ActOnObjCReenterContainerContext + void ActOnObjCTemporaryExitContainerContext(); + void ActOnObjCReenterContainerContext(); + /// ActOnTagDefinitionError - Invoked when there was an unrecoverable /// error parsing the definition of a tag. void ActOnTagDefinitionError(Scope *S, Decl *TagDecl); @@ -1205,6 +1278,10 @@ public: void EnterDeclaratorContext(Scope *S, DeclContext *DC); void ExitDeclaratorContext(Scope *S); + /// Push the parameters of D, which must be a function, into scope. + void ActOnReenterFunctionContext(Scope* S, Decl* D); + void ActOnExitFunctionContext() { PopDeclContext(); } + DeclContext *getFunctionLevelDeclContext(); /// getCurFunctionDecl - If inside of a function body, this returns a pointer @@ -1314,6 +1391,7 @@ public: bool FunctionArgTypesAreEqual(const FunctionProtoType *OldType, const FunctionProtoType *NewType); + CastKind PrepareCastToObjCObjectPointer(ExprResult &E); bool CheckPointerConversion(Expr *From, QualType ToType, CastKind &Kind, CXXCastPath& BasePath, @@ -1337,19 +1415,20 @@ public: QualType ResultType, Expr *Value, bool AllowNRVO = true); - + bool CanPerformCopyInitialization(const InitializedEntity &Entity, ExprResult Init); ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, - ExprResult Init); + ExprResult Init, + bool TopLevelOfInitList = false); ExprResult PerformObjectArgumentInitialization(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, CXXMethodDecl *Method); ExprResult PerformContextuallyConvertToBool(Expr *From); - ExprResult PerformContextuallyConvertToObjCId(Expr *From); + ExprResult PerformContextuallyConvertToObjCPointer(Expr *From); ExprResult ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE, @@ -1475,8 +1554,9 @@ public: bool Complain = false, DeclAccessPair* Found = 0); - ExprResult ResolveAndFixSingleFunctionTemplateSpecialization( - Expr *SrcExpr, bool DoFunctionPointerConverion = false, + bool ResolveAndFixSingleFunctionTemplateSpecialization( + ExprResult &SrcExpr, + bool DoFunctionPointerConverion = false, bool Complain = false, const SourceRange& OpRangeForComplaining = SourceRange(), QualType DestTypeForComplaining = QualType(), @@ -1678,6 +1758,9 @@ public: CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, bool RValueThis, unsigned ThisQuals, bool *ConstParam = 0); + CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class); + CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, bool RValueThis, + unsigned ThisQuals); CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); void ArgumentDependentLookup(DeclarationName Name, bool Operator, @@ -1755,6 +1838,10 @@ public: bool NonInheritable = true, bool Inheritable = true); void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL, bool NonInheritable = true, bool Inheritable = true); + bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, + const AttributeList *AttrList); + + void checkUnusedDeclAttributes(Declarator &D); bool CheckRegparmAttr(const AttributeList &attr, unsigned &value); bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC); @@ -1762,15 +1849,26 @@ public: void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method, bool &IncompleteImpl, unsigned DiagID); - void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod, + void WarnConflictingTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl); + + void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, + ObjCMethodDecl *Overridden, + bool IsProtocolMethodDecl); + + /// WarnExactTypedMethods - This routine issues a warning if method + /// implementation declaration matches exactly that of its declaration. + void WarnExactTypedMethods(ObjCMethodDecl *Method, + ObjCMethodDecl *MethodDecl, + bool IsProtocolMethodDecl); bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl, ObjCInterfaceDecl *IDecl); typedef llvm::DenseSet<Selector, llvm::DenseMapInfo<Selector> > SelectorSet; - + typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap; + /// CheckProtocolMethodDefs - This routine checks unimplemented /// methods declared in protocol, and those referenced by it. /// \param IDecl - Used for checking for methods which may have been @@ -1788,14 +1886,6 @@ public: ObjCIvarDecl **Fields, unsigned nIvars, SourceLocation Loc); - /// \brief Determine whether we can synthesize a provisional ivar for the - /// given name. - ObjCPropertyDecl *canSynthesizeProvisionalIvar(IdentifierInfo *II); - - /// \brief Determine whether we can synthesize a provisional ivar for the - /// given property. - bool canSynthesizeProvisionalIvar(ObjCPropertyDecl *Property); - /// ImplMethodsVsClassMethods - This is main routine to warn if any method /// remains unimplemented in the class or category @implementation. void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, @@ -1812,6 +1902,7 @@ public: /// properties which must be synthesized in class's @implementation. void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl, ObjCInterfaceDecl *IDecl); + void DefaultSynthesizeProperties(Scope *S, Decl *D); /// CollectImmediateProperties - This routine collects all properties in /// the class and its conforming protocols; but not those it its super class. @@ -1828,7 +1919,6 @@ public: /// Called by ActOnProperty to handle @property declarations in //// class extensions. Decl *HandlePropertyInClassExtension(Scope *S, - ObjCCategoryDecl *CDecl, SourceLocation AtLoc, FieldDeclarator &FD, Selector GetterSel, @@ -1885,7 +1975,13 @@ public: ObjCImplDecl* IMPDecl, ObjCContainerDecl* IDecl, bool &IncompleteImpl, - bool ImmediateClass); + bool ImmediateClass, + bool WarnExactMatch=false); + + /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in + /// category matches with those implemented in its primary class and + /// warns each time an exact match is found. + void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP); private: /// AddMethodToGlobalPool - Add an instance or factory method to the global @@ -1912,6 +2008,10 @@ public: AddMethodToGlobalPool(Method, impl, /*instance*/false); } + /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global + /// pool. + void AddAnyMethodToGlobalPool(Decl *D); + /// LookupInstanceMethodInGlobalPool - Returns the method and warns if /// there are multiple signatures. ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, @@ -1937,7 +2037,7 @@ public: /// CollectIvarsToConstructOrDestruct - Collect those ivars which require /// initialization. void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, - llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars); + SmallVectorImpl<ObjCIvarDecl*> &Ivars); //===--------------------------------------------------------------------===// // Statement Parsing Callbacks: SemaStmt.cpp. @@ -1978,7 +2078,7 @@ public: StmtResult ActOnExprStmt(FullExprArg Expr); StmtResult ActOnNullStmt(SourceLocation SemiLoc, - SourceLocation LeadingEmptyMacroLoc = SourceLocation()); + bool HasLeadingEmptyMacro = false); StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, MultiStmtArg Elts, bool isStmtExpr); @@ -2022,6 +2122,8 @@ public: FullExprArg Third, SourceLocation RParenLoc, Stmt *Body); + ExprResult ActOnObjCForCollectionOperand(SourceLocation forLoc, + Expr *collection); StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, SourceLocation LParenLoc, Stmt *First, Expr *Second, @@ -2083,6 +2185,8 @@ public: StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw); StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, Scope *CurScope); + ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, + Expr *operand); StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, Stmt *SynchBody); @@ -2141,19 +2245,20 @@ public: DelayedDiagnostics.popContext(state); } - void EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, + void EmitDeprecationWarning(NamedDecl *D, StringRef Message, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass=0); void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); bool makeUnavailableInSystemHeader(SourceLocation loc, - llvm::StringRef message); + StringRef message); //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. - bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, + bool CanUseDecl(NamedDecl *D); + bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass=0); std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD); bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, @@ -2172,12 +2277,16 @@ public: void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); void MarkDeclarationsReferencedInExpr(Expr *E); + /// \brief Try to recover by turning the given expression into a + /// call. Returns true if recovery was attempted or an error was + /// emitted; this may also leave the ExprResult invalid. + bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, + bool ForceComplain = false, + bool (*IsPlausibleResult)(QualType) = 0); + /// \brief Figure out if an expression could be turned into a call. bool isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads); - /// \brief Give notes for a set of overloads. - void NoteOverloads(const UnresolvedSetImpl &Overloads, - const SourceLocation FinalNoteLoc); /// \brief Conditionally issue a diagnostic based on the current /// evaluation context. @@ -2186,17 +2295,13 @@ public: /// the function body is parsed, and then do a basic reachability analysis to /// determine if the statement is reachable. If it is unreachable, the /// diagnostic will not be emitted. - bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *stmt, + bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD); // Primary Expressions. SourceRange getExprRange(Expr *E) const; - - ObjCIvarDecl *SynthesizeProvisionalIvar(LookupResult &Lookup, - IdentifierInfo *II, - SourceLocation NameLoc); - ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, UnqualifiedId &Name, + ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand); void DecomposeUnqualifiedId(const UnqualifiedId &Id, @@ -2205,9 +2310,12 @@ public: const TemplateArgumentListInfo *&TemplateArgs); bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - CorrectTypoContext CTC = CTC_Unknown); + CorrectTypoContext CTC = CTC_Unknown, + TemplateArgumentListInfo *ExplicitTemplateArgs = 0, + Expr **Args = 0, unsigned NumArgs = 0); - ExprResult LookupInObjCMethod(LookupResult &R, Scope *S, IdentifierInfo *II, + ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, + IdentifierInfo *II, bool AllowBuiltinCreation=false); ExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS, @@ -2248,29 +2356,30 @@ public: ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, - bool ADL); + bool NeedsADL); ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D); ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); - ExprResult ActOnNumericConstant(const Token &); - ExprResult ActOnCharacterConstant(const Token &); - ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *Val); + ExprResult ActOnNumericConstant(const Token &Tok); + ExprResult ActOnCharacterConstant(const Token &Tok); + ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E); ExprResult ActOnParenOrParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val); /// ActOnStringLiteral - The specified tokens were lexed as pasted string /// fragments (e.g. "foo" "bar" L"baz"). - ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks); + ExprResult ActOnStringLiteral(const Token *StringToks, + unsigned NumStringToks); ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, - MultiTypeArg Types, - MultiExprArg Exprs); + MultiTypeArg ArgTypes, + MultiExprArg ArgExprs); ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, @@ -2281,13 +2390,13 @@ public: // Binary/Unary Operators. 'Tok' is the token for the operator. ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, - Expr *InputArg); + Expr *InputExpr); ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, - UnaryOperatorKind Opc, Expr *input); + UnaryOperatorKind Opc, Expr *Input); ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input); - ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *T, + ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, SourceRange R); @@ -2296,15 +2405,15 @@ public: ExprResult ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, - bool isType, void *TyOrEx, + bool IsType, void *TyOrEx, const SourceRange &ArgRange); ExprResult CheckPlaceholderExpr(Expr *E); bool CheckVecStepExpr(Expr *E); bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind); - bool CheckUnaryExprOrTypeTraitOperand(QualType type, SourceLocation OpLoc, - SourceRange R, + bool CheckUnaryExprOrTypeTraitOperand(QualType ExprType, SourceLocation OpLoc, + SourceRange ExprRange, UnaryExprOrTypeTrait ExprKind); ExprResult ActOnSizeofParameterPackExpr(Scope *S, SourceLocation OpLoc, @@ -2364,30 +2473,34 @@ public: FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr **Args, unsigned NumArgs, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + bool ExecConfig = false); /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. /// This provides the location of the left/right parens and a list of comma /// locations. ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, - MultiExprArg Args, SourceLocation RParenLoc, - Expr *ExecConfig = 0); + MultiExprArg ArgExprs, SourceLocation RParenLoc, + Expr *ExecConfig = 0, bool IsExecConfig = false); ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation RParenLoc, - Expr *ExecConfig = 0); + Expr *Config = 0, + bool IsExecConfig = false); ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, - MultiExprArg ExecConfig, SourceLocation GGGLoc); + MultiExprArg ExecConfig, + SourceLocation GGGLoc); ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, Declarator &D, ParsedType &Ty, - SourceLocation RParenLoc, Expr *Op); + SourceLocation RParenLoc, Expr *CastExpr); ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op); + CastKind PrepareScalarCast(ExprResult &src, QualType destType); /// \brief Build an altivec or OpenCL literal. ExprResult BuildVectorLiteral(SourceLocation LParenLoc, @@ -2399,16 +2512,16 @@ public: ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc, - Expr *Op); + Expr *InitExpr); ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc, - Expr *InitExpr); + Expr *LiteralExpr); - ExprResult ActOnInitList(SourceLocation LParenLoc, - MultiExprArg InitList, - SourceLocation RParenLoc); + ExprResult ActOnInitList(SourceLocation LBraceLoc, + MultiExprArg InitArgList, + SourceLocation RBraceLoc); ExprResult ActOnDesignatedInitializer(Designation &Desig, SourceLocation Loc, @@ -2416,21 +2529,21 @@ public: ExprResult Init); ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, - tok::TokenKind Kind, Expr *LHS, Expr *RHS); + tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr); ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, - BinaryOperatorKind Opc, Expr *lhs, Expr *rhs); - ExprResult CreateBuiltinBinOp(SourceLocation TokLoc, - BinaryOperatorKind Opc, Expr *lhs, Expr *rhs); + BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr); + ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, + Expr *LHSExpr, Expr *RHSExpr); /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null /// in the case of a the GNU conditional expr extension. ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, - Expr *Cond, Expr *LHS, Expr *RHS); + Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr); /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo". ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, - LabelDecl *LD); + LabelDecl *TheDecl); ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc); // "({..})" @@ -2441,7 +2554,7 @@ public: bool isBrackets; // true if [expr], false if .ident union { IdentifierInfo *IdentInfo; - ExprTy *E; + Expr *E; } U; }; @@ -2454,28 +2567,26 @@ public: ExprResult ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc, SourceLocation TypeLoc, - ParsedType Arg1, + ParsedType ParsedArgTy, OffsetOfComponent *CompPtr, unsigned NumComponents, SourceLocation RParenLoc); // __builtin_choose_expr(constExpr, expr1, expr2) ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, - Expr *cond, Expr *expr1, - Expr *expr2, SourceLocation RPLoc); + Expr *CondExpr, Expr *LHSExpr, + Expr *RHSExpr, SourceLocation RPLoc); // __builtin_va_arg(expr, type) - ExprResult ActOnVAArg(SourceLocation BuiltinLoc, - Expr *expr, ParsedType type, + ExprResult ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty, SourceLocation RPLoc); - ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, - Expr *expr, TypeSourceInfo *TInfo, - SourceLocation RPLoc); + ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, + TypeSourceInfo *TInfo, SourceLocation RPLoc); // __null ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc); - bool CheckCaseExpression(Expr *expr); + bool CheckCaseExpression(Expr *E); bool CheckMicrosoftIfExistsSymbol(CXXScopeSpec &SS, UnqualifiedId &Name); @@ -2495,13 +2606,13 @@ public: /// ActOnBlockStmtExpr - This is called when the body of a block statement /// literal was successfully completed. ^(int x){...} - ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, - Stmt *Body, Scope *CurScope); + ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, + Scope *CurScope); //===---------------------------- OpenCL Features -----------------------===// /// __builtin_astype(...) - ExprResult ActOnAsTypeExpr(Expr *expr, ParsedType DestTy, + ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc); @@ -2594,7 +2705,8 @@ public: /// and sets it as the initializer for the the passed in VarDecl. bool InitializeVarWithConstructor(VarDecl *VD, CXXConstructorDecl *Constructor, - MultiExprArg Exprs); + MultiExprArg Exprs, + bool HadMultipleCandidates); /// BuildCXXConstructExpr - Creates a complete call to a constructor, /// including handling of its default argument expressions. @@ -2603,16 +2715,16 @@ public: ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, CXXConstructorDecl *Constructor, MultiExprArg Exprs, - bool RequiresZeroInit, unsigned ConstructKind, - SourceRange ParenRange); + bool HadMultipleCandidates, bool RequiresZeroInit, + unsigned ConstructKind, SourceRange ParenRange); // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if // the constructor can be elidable? ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, CXXConstructorDecl *Constructor, bool Elidable, - MultiExprArg Exprs, bool RequiresZeroInit, - unsigned ConstructKind, + MultiExprArg Exprs, bool HadMultipleCandidates, + bool RequiresZeroInit, unsigned ConstructKind, SourceRange ParenRange); /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating @@ -2645,7 +2757,7 @@ public: // any other specification (even 'none', to keep this rule simple). ExceptionSpecificationType ComputedEST; llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen; - llvm::SmallVector<QualType, 4> Exceptions; + SmallVector<QualType, 4> Exceptions; void ClearExceptions() { ExceptionsSeen.clear(); @@ -2710,23 +2822,33 @@ public: std::pair<ImplicitExceptionSpecification, bool> ComputeDefaultedCopyAssignmentExceptionSpecAndConst(CXXRecordDecl *ClassDecl); + /// \brief Determine what sort of exception specification a defaulted move + /// constructor of a class will have. + ImplicitExceptionSpecification + ComputeDefaultedMoveCtorExceptionSpec(CXXRecordDecl *ClassDecl); + + /// \brief Determine what sort of exception specification a defaulted move + /// assignment operator of a class will have. + ImplicitExceptionSpecification + ComputeDefaultedMoveAssignmentExceptionSpec(CXXRecordDecl *ClassDecl); + /// \brief Determine what sort of exception specification a defaulted /// destructor of a class will have. ImplicitExceptionSpecification ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl); - /// \brief Determine if a defaulted default constructor ought to be - /// deleted. - bool ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD); - - /// \brief Determine if a defaulted copy constructor ought to be - /// deleted. - bool ShouldDeleteCopyConstructor(CXXConstructorDecl *CD); + /// \brief Determine if a special member function should have a deleted + /// definition when it is defaulted. + bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM); /// \brief Determine if a defaulted copy assignment operator ought to be /// deleted. bool ShouldDeleteCopyAssignmentOperator(CXXMethodDecl *MD); + /// \brief Determine if a defaulted move assignment operator ought to be + /// deleted. + bool ShouldDeleteMoveAssignmentOperator(CXXMethodDecl *MD); + /// \brief Determine if a defaulted destructor ought to be deleted. bool ShouldDeleteDestructor(CXXDestructorDecl *DD); @@ -2772,9 +2894,6 @@ public: /// \brief Declare the implicit copy constructor for the given class. /// - /// \param S The scope of the class, which may be NULL if this is a - /// template instantiation. - /// /// \param ClassDecl The class declaration into which the implicit /// copy constructor will be added. /// @@ -2786,21 +2905,45 @@ public: void DefineImplicitCopyConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor); - /// \brief Declare the implicit copy assignment operator for the given class. + /// \brief Declare the implicit move constructor for the given class. /// - /// \param S The scope of the class, which may be NULL if this is a - /// template instantiation. + /// \param ClassDecl The Class declaration into which the implicit + /// move constructor will be added. + /// + /// \returns The implicitly-declared move constructor, or NULL if it wasn't + /// declared. + CXXConstructorDecl *DeclareImplicitMoveConstructor(CXXRecordDecl *ClassDecl); + + /// DefineImplicitMoveConstructor - Checks for feasibility of + /// defining this constructor as the move constructor. + void DefineImplicitMoveConstructor(SourceLocation CurrentLocation, + CXXConstructorDecl *Constructor); + + /// \brief Declare the implicit copy assignment operator for the given class. /// /// \param ClassDecl The class declaration into which the implicit - /// copy-assignment operator will be added. + /// copy assignment operator will be added. /// /// \returns The implicitly-declared copy assignment operator. CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl); - /// \brief Defined an implicitly-declared copy assignment operator. + /// \brief Defines an implicitly-declared copy assignment operator. void DefineImplicitCopyAssignment(SourceLocation CurrentLocation, CXXMethodDecl *MethodDecl); + /// \brief Declare the implicit move assignment operator for the given class. + /// + /// \param ClassDecl The Class declaration into which the implicit + /// move assignment operator will be added. + /// + /// \returns The implicitly-declared move assignment operator, or NULL if it + /// wasn't declared. + CXXMethodDecl *DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl); + + /// \brief Defines an implicitly-declared move assignment operator. + void DefineImplicitMoveAssignment(SourceLocation CurrentLocation, + CXXMethodDecl *MethodDecl); + /// \brief Force the declaration of any implicitly-declared members of this /// class. void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class); @@ -3231,7 +3374,8 @@ public: TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc); ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl, - CXXMethodDecl *Method); + CXXMethodDecl *Method, + bool HadMultipleCandidates); ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, @@ -3259,7 +3403,7 @@ public: Decl *ActOnStartLinkageSpecification(Scope *S, SourceLocation ExternLoc, SourceLocation LangLoc, - llvm::StringRef Lang, + StringRef Lang, SourceLocation LBraceLoc); Decl *ActOnFinishLinkageSpecification(Scope *S, Decl *LinkageSpec, @@ -3272,16 +3416,16 @@ public: bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS = 0); - Decl *ActOnAccessSpecifier(AccessSpecifier Access, - SourceLocation ASLoc, - SourceLocation ColonLoc); + bool ActOnAccessSpecifier(AccessSpecifier Access, + SourceLocation ASLoc, + SourceLocation ColonLoc, + AttributeList *Attrs = 0); Decl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, Expr *BitfieldWidth, const VirtSpecifiers &VS, - Expr *Init, bool HasDeferredInit, - bool IsDefinition); + bool HasDeferredInit); void ActOnCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc, Expr *Init); @@ -3296,24 +3440,37 @@ public: SourceLocation RParenLoc, SourceLocation EllipsisLoc); - MemInitResult BuildMemberInitializer(ValueDecl *Member, Expr **Args, - unsigned NumArgs, SourceLocation IdLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc); + MemInitResult ActOnMemInitializer(Decl *ConstructorD, + Scope *S, + CXXScopeSpec &SS, + IdentifierInfo *MemberOrBase, + ParsedType TemplateTypeTy, + SourceLocation IdLoc, + Expr *InitList, + SourceLocation EllipsisLoc); + + MemInitResult BuildMemInitializer(Decl *ConstructorD, + Scope *S, + CXXScopeSpec &SS, + IdentifierInfo *MemberOrBase, + ParsedType TemplateTypeTy, + SourceLocation IdLoc, + const MultiInitializer &Init, + SourceLocation EllipsisLoc); + + MemInitResult BuildMemberInitializer(ValueDecl *Member, + const MultiInitializer &Args, + SourceLocation IdLoc); MemInitResult BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, - Expr **Args, unsigned NumArgs, - SourceLocation LParenLoc, - SourceLocation RParenLoc, + const MultiInitializer &Args, CXXRecordDecl *ClassDecl, SourceLocation EllipsisLoc); MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo, - Expr **Args, unsigned NumArgs, + const MultiInitializer &Args, SourceLocation BaseLoc, - SourceLocation RParenLoc, - SourceLocation LParenLoc, CXXRecordDecl *ClassDecl); bool SetDelegatingInitializer(CXXConstructorDecl *Constructor, @@ -3339,7 +3496,7 @@ public: /// \brief The list of vtables that are required but have not yet been /// materialized. - llvm::SmallVector<VTableUse, 16> VTableUses; + SmallVector<VTableUse, 16> VTableUses; /// \brief The set of classes whose vtables have been used within /// this translation unit, and a bit that will be true if the vtable is @@ -3347,9 +3504,16 @@ public: /// by code generation). llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed; + /// \brief Load any externally-stored vtable uses. + void LoadExternalVTableUses(); + + typedef LazyVector<CXXRecordDecl *, ExternalSemaSource, + &ExternalSemaSource::ReadDynamicClasses, 2, 2> + DynamicClassesType; + /// \brief A list of all of the dynamic classes in this translation /// unit. - llvm::SmallVector<CXXRecordDecl *, 16> DynamicClasses; + DynamicClassesType DynamicClasses; /// \brief Note that the vtable for the given class was used at the /// given location. @@ -3372,7 +3536,8 @@ public: void ActOnMemInitializers(Decl *ConstructorDecl, SourceLocation ColonLoc, - MemInitTy **MemInits, unsigned NumMemInits, + CXXCtorInitializer **MemInits, + unsigned NumMemInits, bool AnyErrors); void CheckCompletedCXXClass(CXXRecordDecl *Record); @@ -3401,9 +3566,9 @@ public: FriendDecl *CheckFriendTypeDecl(SourceLocation FriendLoc, TypeSourceInfo *TSInfo); Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, + MultiTemplateParamsArg TemplateParams); + Decl *ActOnFriendFunctionDecl(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParams); - Decl *ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition, - MultiTemplateParamsArg TemplateParams); QualType CheckConstructorDeclarator(Declarator &D, QualType R, StorageClass& SC); @@ -3419,6 +3584,8 @@ public: void CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *Ctor); void CheckExplicitlyDefaultedCopyConstructor(CXXConstructorDecl *Ctor); void CheckExplicitlyDefaultedCopyAssignment(CXXMethodDecl *Method); + void CheckExplicitlyDefaultedMoveConstructor(CXXConstructorDecl *Ctor); + void CheckExplicitlyDefaultedMoveAssignment(CXXMethodDecl *Method); void CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *Dtor); //===--------------------------------------------------------------------===// @@ -3441,7 +3608,8 @@ public: bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, unsigned NumBases); - void ActOnBaseSpecifiers(Decl *ClassDecl, BaseTy **Bases, unsigned NumBases); + void ActOnBaseSpecifiers(Decl *ClassDecl, CXXBaseSpecifier **Bases, + unsigned NumBases); bool IsDerivedFrom(QualType Derived, QualType Base); bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths); @@ -3538,6 +3706,7 @@ public: bool ForceCheck = false, bool ForceUnprivileged = false); void CheckLookupAccess(const LookupResult &R); + bool IsSimplyAccessible(NamedDecl *decl, CXXRecordDecl *Class); void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -3626,7 +3795,7 @@ public: Expr *DefaultArg); Decl *ActOnTemplateTemplateParameter(Scope *S, SourceLocation TmpLoc, - TemplateParamsTy *Params, + TemplateParameterList *Params, SourceLocation EllipsisLoc, IdentifierInfo *ParamName, SourceLocation ParamNameLoc, @@ -3635,7 +3804,7 @@ public: SourceLocation EqualLoc, ParsedTemplateArgument DefaultArg); - TemplateParamsTy * + TemplateParameterList * ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, @@ -3672,7 +3841,8 @@ public: IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, TemplateParameterList *TemplateParams, - AccessSpecifier AS, + AccessSpecifier AS, + SourceLocation ModulePrivateLoc, unsigned NumOuterTemplateParamLists, TemplateParameterList **OuterTemplateParamLists); @@ -3726,6 +3896,7 @@ public: DeclResult ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, + SourceLocation ModulePrivateLoc, CXXScopeSpec &SS, TemplateTy Template, SourceLocation TemplateNameLoc, @@ -3795,7 +3966,7 @@ public: SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, - llvm::SmallVectorImpl<TemplateArgument> &Converted); + SmallVectorImpl<TemplateArgument> &Converted); /// \brief Specifies the context in which a particular template /// argument is being checked. @@ -3819,7 +3990,7 @@ public: SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, - llvm::SmallVectorImpl<TemplateArgument> &Converted, + SmallVectorImpl<TemplateArgument> &Converted, CheckTemplateArgumentKind CTAK = CTAK_Specified); /// \brief Check that the given template arguments can be be provided to @@ -3847,11 +4018,11 @@ public: SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, - llvm::SmallVectorImpl<TemplateArgument> &Converted); + SmallVectorImpl<TemplateArgument> &Converted); bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, const TemplateArgumentLoc &Arg, - llvm::SmallVectorImpl<TemplateArgument> &Converted); + SmallVectorImpl<TemplateArgument> &Converted); bool CheckTemplateArgument(TemplateTypeParmDecl *Param, TypeSourceInfo *Arg); @@ -3963,7 +4134,9 @@ public: bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS); ExprResult RebuildExprInCurrentInstantiation(Expr *E); - + bool RebuildTemplateParamsInCurrentInstantiation( + TemplateParameterList *Params); + std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args); @@ -4103,7 +4276,7 @@ public: /// \param Arg The template argument that will be traversed to find /// unexpanded parameter packs. void collectUnexpandedParameterPacks(TemplateArgument Arg, - llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); + SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); /// \brief Collect the set of unexpanded parameter packs within the given /// template argument. @@ -4111,7 +4284,7 @@ public: /// \param Arg The template argument that will be traversed to find /// unexpanded parameter packs. void collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, - llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); + SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); /// \brief Collect the set of unexpanded parameter packs within the given /// type. @@ -4119,7 +4292,7 @@ public: /// \param T The type that will be traversed to find /// unexpanded parameter packs. void collectUnexpandedParameterPacks(QualType T, - llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); + SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); /// \brief Collect the set of unexpanded parameter packs within the given /// type. @@ -4127,7 +4300,7 @@ public: /// \param TL The type that will be traversed to find /// unexpanded parameter packs. void collectUnexpandedParameterPacks(TypeLoc TL, - llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); + SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); /// \brief Invoked when parsing a template argument followed by an /// ellipsis, which creates a pack expansion. @@ -4219,8 +4392,7 @@ public: /// must be set. bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, - const UnexpandedParameterPack *Unexpanded, - unsigned NumUnexpanded, + llvm::ArrayRef<UnexpandedParameterPack> Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, @@ -4312,8 +4484,8 @@ public: TemplateDeductionResult SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo &ExplicitTemplateArgs, - llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced, - llvm::SmallVectorImpl<QualType> &ParamTypes, + SmallVectorImpl<DeducedTemplateArgument> &Deduced, + SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType, sema::TemplateDeductionInfo &Info); @@ -4333,11 +4505,11 @@ public: TemplateDeductionResult FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, - llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced, + SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, - llvm::SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = 0); + SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = 0); TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, @@ -4392,9 +4564,9 @@ public: void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, bool OnlyDeduced, unsigned Depth, - llvm::SmallVectorImpl<bool> &Used); + SmallVectorImpl<bool> &Used); void MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate, - llvm::SmallVectorImpl<bool> &Deduced); + SmallVectorImpl<bool> &Deduced); //===--------------------------------------------------------------------===// // C++ Template Instantiation @@ -4523,7 +4695,7 @@ public: /// requires another template instantiation, additional /// instantiations are pushed onto the stack up to a /// user-configurable limit LangOptions::InstantiationDepth. - llvm::SmallVector<ActiveTemplateInstantiation, 16> + SmallVector<ActiveTemplateInstantiation, 16> ActiveTemplateInstantiations; /// \brief Whether we are in a SFINAE context that is not associated with @@ -4580,14 +4752,14 @@ public: /// /// The top of this stack is used by a fixit instantiating unresolved /// function calls to fix the AST to match the textual change it prints. - llvm::SmallVector<CallExpr *, 8> CallsUndergoingInstantiation; + SmallVector<CallExpr *, 8> CallsUndergoingInstantiation; /// \brief For each declaration that involved template argument deduction, the /// set of diagnostics that were suppressed during that template argument /// deduction. /// /// FIXME: Serialize this structure to the AST file. - llvm::DenseMap<Decl *, llvm::SmallVector<PartialDiagnosticAt, 1> > + llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> > SuppressedDiagnostics; /// \brief A stack object to be created when performing template @@ -4691,7 +4863,7 @@ public: }; void PrintInstantiationStack(); - + /// \brief Determines whether we are currently in a context where /// template argument substitution failures are not considered /// errors. @@ -4805,8 +4977,8 @@ public: bool SubstParmTypes(SourceLocation Loc, ParmVarDecl **Params, unsigned NumParams, const MultiLevelTemplateArgumentList &TemplateArgs, - llvm::SmallVectorImpl<QualType> &ParamTypes, - llvm::SmallVectorImpl<ParmVarDecl *> *OutParams = 0); + SmallVectorImpl<QualType> &ParamTypes, + SmallVectorImpl<ParmVarDecl *> *OutParams = 0); ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -4827,7 +4999,7 @@ public: /// \returns true if an error occurred, false otherwise. bool SubstExprs(Expr **Exprs, unsigned NumExprs, bool IsCall, const MultiLevelTemplateArgumentList &TemplateArgs, - llvm::SmallVectorImpl<Expr *> &Outputs); + SmallVectorImpl<Expr *> &Outputs); StmtResult SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -4894,6 +5066,11 @@ public: void InstantiateMemInitializers(CXXConstructorDecl *New, const CXXConstructorDecl *Tmpl, const MultiLevelTemplateArgumentList &TemplateArgs); + bool InstantiateInitializer(Expr *Init, + const MultiLevelTemplateArgumentList &TemplateArgs, + SourceLocation &LParenLoc, + ASTOwningVector<Expr*> &NewArgs, + SourceLocation &RParenLoc); NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -4952,7 +5129,7 @@ public: IdentifierInfo *CatName, SourceLocation CatLoc); - Decl *ActOnForwardClassDeclaration(SourceLocation Loc, + DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, unsigned NumElts); @@ -4965,7 +5142,7 @@ public: void FindProtocolDeclaration(bool WarnOnDeclarations, const IdentifierLocPair *ProtocolId, unsigned NumProtocols, - llvm::SmallVectorImpl<Decl *> &Protocols); + SmallVectorImpl<Decl *> &Protocols); /// Ensure attributes are consistent with type. /// \param [in, out] Attributes The attributes to check; they will @@ -5003,7 +5180,7 @@ public: void MatchOneProtocolPropertiesInClass(Decl *CDecl, ObjCProtocolDecl *PDecl); - void ActOnAtEnd(Scope *S, SourceRange AtEnd, Decl *classDecl, + void ActOnAtEnd(Scope *S, SourceRange AtEnd, Decl **allMethods = 0, unsigned allNum = 0, Decl **allProperties = 0, unsigned pNum = 0, DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0); @@ -5011,7 +5188,6 @@ public: Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, - Decl *ClassCategory, bool *OverridingProperty, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC = 0); @@ -5019,7 +5195,7 @@ public: Decl *ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, - bool ImplKind,Decl *ClassImplDecl, + bool ImplKind, IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, SourceLocation PropertyIvarLoc); @@ -5050,8 +5226,8 @@ public: SourceLocation BeginLoc, // location of the + or -. SourceLocation EndLoc, // location of the ; or {. tok::TokenKind MethodType, - Decl *ClassDecl, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, - SourceLocation SelectorStartLoc, Selector Sel, + ObjCDeclSpec &ReturnQT, ParsedType ReturnType, + ArrayRef<SourceLocation> SelectorLocs, Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). ObjCArgInfo *ArgInfo, @@ -5112,7 +5288,7 @@ public: ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, - SourceLocation SelectorLoc, + ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args); @@ -5122,7 +5298,7 @@ public: Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, - SourceLocation SelectorLoc, + ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args); @@ -5130,7 +5306,7 @@ public: ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, - SourceLocation SelectorLoc, + ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args); @@ -5140,7 +5316,7 @@ public: Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, - SourceLocation SelectorLoc, + ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args); @@ -5148,7 +5324,7 @@ public: Expr *Receiver, Selector Sel, SourceLocation LBracLoc, - SourceLocation SelectorLoc, + ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args); @@ -5170,9 +5346,7 @@ public: /// \brief Check whether the given new method is a valid override of the /// given overridden method, and set any properties that should be inherited. - /// - /// \returns True if an error occurred. - bool CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, + void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, const ObjCMethodDecl *Overridden, bool IsImplementation); @@ -5226,7 +5400,8 @@ public: void ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType, SourceLocation PragmaLoc); - NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II); + NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, + SourceLocation Loc); void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W); /// ActOnPragmaWeakID - Called on well formed #pragma weak ident. @@ -5270,13 +5445,14 @@ public: /// FreeVisContext - Deallocate and null out VisContext. void FreeVisContext(); - /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. - void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E); - void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *T); + /// AddCFAuditedAttribute - Check whether we're currently within + /// '#pragma clang arc_cf_code_audited' and, if so, consider adding + /// the appropriate attribute. + void AddCFAuditedAttribute(Decl *D); - /// CastCategory - Get the correct forwarded implicit cast result category - /// from the inner expression. - ExprValueKind CastCategory(Expr *E); + /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. + void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E); + void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T); /// \brief The kind of conversion being performed. enum CheckedConversionKind { @@ -5348,7 +5524,7 @@ public: const FunctionProtoType *Proto, unsigned FirstProtoArg, Expr **Args, unsigned NumArgs, - llvm::SmallVector<Expr *, 8> &AllArgs, + SmallVector<Expr *, 8> &AllArgs, VariadicCallType CallType = VariadicDoesNotApply); // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but @@ -5361,8 +5537,8 @@ public: // operators (C99 6.3.1.8). If both operands aren't arithmetic, this // routine returns the first non-arithmetic type found. The client is // responsible for emitting appropriate error diagnostics. - QualType UsualArithmeticConversions(ExprResult &lExpr, ExprResult &rExpr, - bool isCompAssign = false); + QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, + bool IsCompAssign = false); /// AssignConvertType - All of the 'assignment' semantic checks return this /// enum to indicate whether the assignment was allowed. These checks are @@ -5449,23 +5625,26 @@ public: /// argument passing, variable initialization, and function return values. /// C99 6.5.16. AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, - QualType lhs, QualType rhs); + QualType LHSType, + QualType RHSType); /// Check assignment constraints and prepare for a conversion of the /// RHS to the LHS type. - AssignConvertType CheckAssignmentConstraints(QualType lhs, ExprResult &rhs, + AssignConvertType CheckAssignmentConstraints(QualType LHSType, + ExprResult &RHS, CastKind &Kind); // CheckSingleAssignmentConstraints - Currently used by // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking, // this routine performs the default function/array converions. - AssignConvertType CheckSingleAssignmentConstraints(QualType lhs, - ExprResult &rExprRes); + AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, + ExprResult &RHS, + bool Diagnose = true); // \brief If the lhs type is a transparent union, check whether we // can initialize the transparent union with the given expression. - AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs, - ExprResult &rExpr); + AssignConvertType CheckTransparentUnionArgumentConstraints(QualType ArgType, + ExprResult &RHS); bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType); @@ -5473,11 +5652,13 @@ public: ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, - bool AllowExplicit = false); + bool AllowExplicit = false, + bool Diagnose = true); ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit, - ImplicitConversionSequence& ICS); + ImplicitConversionSequence& ICS, + bool Diagnose = true); ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence& ICS, AssignmentAction Action, @@ -5492,41 +5673,47 @@ public: /// or a null QualType (indicating an error diagnostic was issued). /// type checking binary operators (subroutines of CreateBuiltinBinOp). - QualType InvalidOperands(SourceLocation l, ExprResult &lex, ExprResult &rex); + QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS, + ExprResult &RHS); QualType CheckPointerToMemberOperands( // C++ 5.5 - ExprResult &lex, ExprResult &rex, ExprValueKind &VK, + ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, SourceLocation OpLoc, bool isIndirect); QualType CheckMultiplyDivideOperands( // C99 6.5.5 - ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign, - bool isDivide); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign, + bool IsDivide); QualType CheckRemainderOperands( // C99 6.5.5 - ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign = false); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + bool IsCompAssign = false); QualType CheckAdditionOperands( // C99 6.5.6 - ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, QualType* CompLHSTy = 0); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + QualType* CompLHSTy = 0); QualType CheckSubtractionOperands( // C99 6.5.6 - ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, QualType* CompLHSTy = 0); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + QualType* CompLHSTy = 0); QualType CheckShiftOperands( // C99 6.5.7 - ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc, - bool isCompAssign = false); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, + bool IsCompAssign = false); QualType CheckCompareOperands( // C99 6.5.8/9 - ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc, + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned OpaqueOpc, bool isRelational); QualType CheckBitwiseOperands( // C99 6.5.[10...12] - ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign = false); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + bool IsCompAssign = false); QualType CheckLogicalOperands( // C99 6.5.[13,14] - ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc); // CheckAssignmentOperands is used for both simple and compound assignment. // For simple assignment, pass both expressions and a null converted type. // For compound assignment, pass both expressions and the converted type. QualType CheckAssignmentOperands( // C99 6.5.16.[1,2] - Expr *lex, ExprResult &rex, SourceLocation OpLoc, QualType convertedType); + Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType); - void ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS, QualType& LHSTy); + void ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS, + QualType& LHSTy); ExprResult ConvertPropertyForRValue(Expr *E); QualType CheckConditionalOperands( // C99 6.5.15 - ExprResult &cond, ExprResult &lhs, ExprResult &rhs, - ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); + ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, + ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc); QualType CXXCheckConditionalOperands( // C++ 5.16 ExprResult &cond, ExprResult &lhs, ExprResult &rhs, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); @@ -5542,20 +5729,18 @@ public: } QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, - SourceLocation questionLoc); + SourceLocation QuestionLoc); - bool DiagnoseConditionalForNull(Expr *LHS, Expr *RHS, + bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr, SourceLocation QuestionLoc); /// type checking for vector binary operators. - QualType CheckVectorOperands(ExprResult &lex, ExprResult &rex, - SourceLocation Loc, bool isCompAssign); - QualType CheckVectorCompareOperands(ExprResult &lex, ExprResult &rx, - SourceLocation l, bool isRel); + QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc, bool IsCompAssign); + QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc, bool isRelational); /// type checking declaration initializers (C99 6.7.8) - bool CheckInitList(const InitializedEntity &Entity, - InitListExpr *&InitList, QualType &DeclType); bool CheckForConstantInitializer(Expr *e, QualType t); // type checking C++ declaration initializers (C++ [dcl.init]). @@ -5587,16 +5772,9 @@ public: bool &ObjCConversion, bool &ObjCLifetimeConversion); - /// CheckCastTypes - Check type constraints for casting between types under - /// C semantics, or forward to CXXCheckCStyleCast in C++. - ExprResult CheckCastTypes(SourceLocation CastStartLoc, SourceRange TyRange, - QualType CastTy, Expr *CastExpr, CastKind &Kind, - ExprValueKind &VK, CXXCastPath &BasePath, - bool FunctionalStyle = false); - - ExprResult checkUnknownAnyCast(SourceRange TyRange, QualType castType, - Expr *castExpr, CastKind &castKind, - ExprValueKind &valueKind, CXXCastPath &BasePath); + ExprResult checkUnknownAnyCast(SourceRange TypeRange, QualType CastType, + Expr *CastExpr, CastKind &CastKind, + ExprValueKind &VK, CXXCastPath &Path); // CheckVectorCast - check type constraints for vectors. // Since vectors are an extension, there are no C standard reference for this. @@ -5610,19 +5788,14 @@ public: // We allow casting between vectors and integer datatypes of the same size, // or vectors and the element type of that vector. // returns the cast expr - ExprResult CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *CastExpr, + ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr, CastKind &Kind); - /// CXXCheckCStyleCast - Check constraints of a C-style or function-style - /// cast under C++ semantics. - ExprResult CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, - Expr *CastExpr, CastKind &Kind, - CXXCastPath &BasePath, bool FunctionalStyle); - - /// \brief Checks for valid expressions which can be cast to an ObjC - /// pointer without needing a bridge cast. - bool ValidObjCARCNoBridgeCastExpr(Expr *&Exp, QualType castType); - + ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, + SourceLocation LParenLoc, + Expr *CastExpr, + SourceLocation RParenLoc); + /// \brief Checks for invalid conversions and casts between /// retainable pointers and other pointer kinds. void CheckObjCARCConversion(SourceRange castRange, QualType castType, @@ -5674,10 +5847,10 @@ public: /// \param Loc - A location associated with the condition, e.g. the /// 'if' keyword. /// \return true iff there were any errors - ExprResult CheckBooleanCondition(Expr *CondExpr, SourceLocation Loc); + ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc); ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, - Expr *SubExpr); + Expr *SubExpr); /// DiagnoseAssignmentAsCondition - Given that an expression is /// being used as a boolean condition, warn if it's an assignment. @@ -5685,7 +5858,7 @@ public: /// \brief Redundant parentheses over an equality comparison can indicate /// that the user intended an assignment used as condition. - void DiagnoseEqualityWithExtraParens(ParenExpr *parenE); + void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE); /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid. ExprResult CheckCXXBooleanCondition(Expr *CondExpr); @@ -5715,6 +5888,23 @@ public: QualType FieldTy, const Expr *BitWidth, bool *ZeroWidth = 0); + enum CUDAFunctionTarget { + CFT_Device, + CFT_Global, + CFT_Host, + CFT_HostDevice + }; + + CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D); + + bool CheckCUDATarget(CUDAFunctionTarget CallerTarget, + CUDAFunctionTarget CalleeTarget); + + bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee) { + return CheckCUDATarget(IdentifyCUDATarget(Caller), + IdentifyCUDATarget(Callee)); + } + /// \name Code completion //@{ /// \brief Describes the context in which code completion occurs. @@ -5782,6 +5972,7 @@ public: void CodeCompleteCall(Scope *S, Expr *Fn, Expr **Args, unsigned NumArgs); void CodeCompleteInitializer(Scope *S, Decl *D); void CodeCompleteReturn(Scope *S); + void CodeCompleteAfterIf(Scope *S); void CodeCompleteAssignmentRHS(Scope *S, Expr *LHS); void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, @@ -5795,14 +5986,13 @@ public: CXXCtorInitializer** Initializers, unsigned NumInitializers); - void CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl, - bool InInterface); + void CodeCompleteObjCAtDirective(Scope *S); void CodeCompleteObjCAtVisibility(Scope *S); void CodeCompleteObjCAtStatement(Scope *S); void CodeCompleteObjCAtExpression(Scope *S); void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS); - void CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl); - void CodeCompleteObjCPropertySetter(Scope *S, Decl *ClassDecl); + void CodeCompleteObjCPropertyGetter(Scope *S); + void CodeCompleteObjCPropertySetter(Scope *S); void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, bool IsParameter); void CodeCompleteObjCMessageReceiver(Scope *S); @@ -5815,7 +6005,7 @@ public: unsigned NumSelIdents, bool AtArgumentExpression, bool IsSuper = false); - void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, + void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, IdentifierInfo **SelIdents, unsigned NumSelIdents, bool AtArgumentExpression, @@ -5839,14 +6029,12 @@ public: void CodeCompleteObjCImplementationCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc); - void CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl); + void CodeCompleteObjCPropertyDefinition(Scope *S); void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, - IdentifierInfo *PropertyName, - Decl *ObjCImpDecl); + IdentifierInfo *PropertyName); void CodeCompleteObjCMethodDecl(Scope *S, bool IsInstanceMethod, - ParsedType ReturnType, - Decl *IDecl); + ParsedType ReturnType); void CodeCompleteObjCMethodDeclSelector(Scope *S, bool IsInstanceMethod, bool AtParameterName, @@ -5863,7 +6051,7 @@ public: unsigned Argument); void CodeCompleteNaturalLanguage(); void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, - llvm::SmallVectorImpl<CodeCompletionResult> &Results); + SmallVectorImpl<CodeCompletionResult> &Results); //@} //===--------------------------------------------------------------------===// @@ -5874,6 +6062,8 @@ public: unsigned ByteNo) const; private: + void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, + bool isSubscript=false, bool AllowOnePastEnd=true); void CheckArrayAccess(const Expr *E); bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall); bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall); @@ -5897,6 +6087,8 @@ private: bool SemaBuiltinObjectSize(CallExpr *TheCall); bool SemaBuiltinLongjmp(CallExpr *TheCall); ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult); + ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult, + AtomicExpr::AtomicOp Op); bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result); @@ -5918,20 +6110,28 @@ private: bool isPrintf); /// \brief Enumeration used to describe which of the memory setting or copying - /// functions is being checked by \c CheckMemsetcpymoveArguments(). + /// functions is being checked by \c CheckMemaccessArguments(). enum CheckedMemoryFunction { CMF_Memset, CMF_Memcpy, - CMF_Memmove + CMF_Memmove, + CMF_Memcmp, + CMF_Strncpy, + CMF_Strncmp, + CMF_Strncasecmp, + CMF_Strncat, + CMF_Strndup }; - void CheckMemsetcpymoveArguments(const CallExpr *Call, - CheckedMemoryFunction CMF, - IdentifierInfo *FnName); + void CheckMemaccessArguments(const CallExpr *Call, CheckedMemoryFunction CMF, + IdentifierInfo *FnName); + + void CheckStrlcpycatArguments(const CallExpr *Call, + IdentifierInfo *FnName); void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc); - void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex); + void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS); void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field, @@ -5958,6 +6158,14 @@ public: /// itself and in routines directly invoked from the parser and *never* from /// template substitution or instantiation. Scope *getCurScope() const { return CurScope; } + + Decl *getObjCDeclContext() const; + + DeclContext *getCurLexicalContext() const { + return OriginalLexicalContext ? OriginalLexicalContext : CurContext; + } + + AvailabilityResult getCurContextAvailability() const; }; /// \brief RAII object that enters a new expression evaluation context. diff --git a/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h index 83c0999..2c4bf4b 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY,BRIEF,FULL) ENUM, #define SEMASTART #include "clang/Basic/DiagnosticSemaKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Sema/SemaFixItUtils.h b/contrib/llvm/tools/clang/include/clang/Sema/SemaFixItUtils.h new file mode 100644 index 0000000..0c1bba5 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Sema/SemaFixItUtils.h @@ -0,0 +1,91 @@ +//===--- SemaFixItUtils.h - Sema FixIts -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines helper classes for generation of Sema FixItHints. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_SEMA_FIXITUTILS_H +#define LLVM_CLANG_SEMA_FIXITUTILS_H + +#include "clang/AST/Expr.h" + +namespace clang { + +enum OverloadFixItKind { + OFIK_Undefined = 0, + OFIK_Dereference, + OFIK_TakeAddress, + OFIK_RemoveDereference, + OFIK_RemoveTakeAddress +}; + +class Sema; + +/// The class facilities generation and storage of conversion FixIts. Hints for +/// new conversions are added using TryToFixConversion method. The default type +/// conversion checker can be reset. +struct ConversionFixItGenerator { + /// Performs a simple check to see if From type can be converted to To type. + static bool compareTypesSimple(CanQualType From, + CanQualType To, + Sema &S, + SourceLocation Loc, + ExprValueKind FromVK); + + /// The list of Hints generated so far. + SmallVector<FixItHint, 1> Hints; + + /// The number of Conversions fixed. This can be different from the size + /// of the Hints vector since we allow multiple FixIts per conversion. + unsigned NumConversionsFixed; + + /// The type of fix applied. If multiple conversions are fixed, corresponds + /// to the kid of the very first conversion. + OverloadFixItKind Kind; + + typedef bool (*TypeComparisonFuncTy) (const CanQualType FromTy, + const CanQualType ToTy, + Sema &S, + SourceLocation Loc, + ExprValueKind FromVK); + /// The type comparison function used to decide if expression FromExpr of + /// type FromTy can be converted to ToTy. For example, one could check if + /// an implicit conversion exists. Returns true if comparison exists. + TypeComparisonFuncTy CompareTypes; + + ConversionFixItGenerator(TypeComparisonFuncTy Foo): NumConversionsFixed(0), + Kind(OFIK_Undefined), + CompareTypes(Foo) {} + + ConversionFixItGenerator(): NumConversionsFixed(0), + Kind(OFIK_Undefined), + CompareTypes(compareTypesSimple) {} + + /// Resets the default conversion checker method. + void setConversionChecker(TypeComparisonFuncTy Foo) { + CompareTypes = Foo; + } + + /// If possible, generates and stores a fix for the given conversion. + bool tryToFixConversion(const Expr *FromExpr, + const QualType FromQTy, const QualType ToQTy, + Sema &S); + + void clear() { + Hints.clear(); + NumConversionsFixed = 0; + } + + bool isNull() { + return (NumConversionsFixed == 0); + } +}; + +} // endof namespace clang +#endif // LLVM_CLANG_SEMA_FIXITUTILS_H diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Template.h b/contrib/llvm/tools/clang/include/clang/Sema/Template.h index a257772..78f50fa 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Template.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Template.h @@ -45,7 +45,7 @@ namespace clang { private: /// \brief The template argument lists, stored from the innermost template /// argument list (first) to the outermost template argument list (last). - llvm::SmallVector<ArgList, 4> TemplateArgumentLists; + SmallVector<ArgList, 4> TemplateArgumentLists; public: /// \brief Construct an empty set of template argument lists. @@ -178,7 +178,7 @@ namespace clang { class LocalInstantiationScope { public: /// \brief A set of declarations. - typedef llvm::SmallVector<Decl *, 4> DeclArgumentPack; + typedef SmallVector<Decl *, 4> DeclArgumentPack; private: /// \brief Reference to the semantic analysis that is performing @@ -210,7 +210,7 @@ namespace clang { LocalDeclsMap LocalDecls; /// \brief The set of argument packs we've allocated. - llvm::SmallVector<DeclArgumentPack *, 1> ArgumentPacks; + SmallVector<DeclArgumentPack *, 1> ArgumentPacks; /// \brief The outer scope, which contains local variable /// definitions from some other instantiation (that may not be @@ -318,7 +318,7 @@ namespace clang { /// \brief A list of out-of-line class template partial /// specializations that will need to be instantiated after the /// enclosing class's instantiation is complete. - llvm::SmallVector<std::pair<ClassTemplateDecl *, + SmallVector<std::pair<ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>, 4> OutOfLinePartialSpecs; @@ -350,7 +350,8 @@ namespace clang { TemplateParameterList *TemplateParams = 0); Decl *VisitCXXRecordDecl(CXXRecordDecl *D); Decl *VisitCXXMethodDecl(CXXMethodDecl *D, - TemplateParameterList *TemplateParams = 0); + TemplateParameterList *TemplateParams = 0, + bool IsClassScopeSpecialization = false); Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D); Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); Decl *VisitCXXConversionDecl(CXXConversionDecl *D); @@ -367,11 +368,13 @@ namespace clang { Decl *VisitUsingShadowDecl(UsingShadowDecl *D); Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); + Decl *VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D); // Base case. FIXME: Remove once we can instantiate everything. Decl *VisitDecl(Decl *D) { unsigned DiagID = SemaRef.getDiagnostics().getCustomDiagID( - Diagnostic::Error, + DiagnosticsEngine::Error, "cannot instantiate %0 yet"); SemaRef.Diag(D->getLocation(), DiagID) << D->getDeclKindName(); @@ -380,7 +383,7 @@ namespace clang { } typedef - llvm::SmallVectorImpl<std::pair<ClassTemplateDecl *, + SmallVectorImpl<std::pair<ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *> > ::iterator delayed_partial_spec_iterator; @@ -403,7 +406,7 @@ namespace clang { // Helper functions for instantiating methods. TypeSourceInfo *SubstFunctionType(FunctionDecl *D, - llvm::SmallVectorImpl<ParmVarDecl *> &Params); + SmallVectorImpl<ParmVarDecl *> &Params); bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h b/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h index c666979..690129a 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h @@ -41,7 +41,7 @@ class TemplateDeductionInfo { /// \brief Warnings (and follow-on notes) that were suppressed due to /// SFINAE while performing template argument deduction. - llvm::SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; + SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; // do not implement these TemplateDeductionInfo(const TemplateDeductionInfo&); @@ -81,7 +81,7 @@ public: } /// \brief Iterator over the set of suppressed diagnostics. - typedef llvm::SmallVectorImpl<PartialDiagnosticAt>::const_iterator + typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator diag_iterator; /// \brief Returns an iterator at the beginning of the sequence of suppressed diff --git a/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h b/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h index 9965953..9537c30 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_SEMA_TYPOCORRECTION_H #include "clang/AST/DeclCXX.h" +#include "llvm/ADT/SmallVector.h" namespace clang { @@ -23,29 +24,31 @@ namespace clang { class TypoCorrection { public: TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl, - NestedNameSpecifier *NNS=NULL, unsigned distance=0) + NestedNameSpecifier *NNS=0, unsigned distance=0) : CorrectionName(Name), CorrectionNameSpec(NNS), - CorrectionDecl(NameDecl), - EditDistance(distance) {} + EditDistance(distance) { + if (NameDecl) + CorrectionDecls.push_back(NameDecl); + } - TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS=NULL, + TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS=0, unsigned distance=0) : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS), - CorrectionDecl(Name), - EditDistance(distance) {} + EditDistance(distance) { + if (Name) + CorrectionDecls.push_back(Name); + } - TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS=NULL, + TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS=0, unsigned distance=0) : CorrectionName(Name), CorrectionNameSpec(NNS), - CorrectionDecl(NULL), - EditDistance(distance) {} + EditDistance(distance) {} TypoCorrection() - : CorrectionName(), CorrectionNameSpec(NULL), CorrectionDecl(NULL), - EditDistance(0) {} + : CorrectionNameSpec(0), EditDistance(0) {} /// \brief Gets the DeclarationName of the typo correction DeclarationName getCorrection() const { return CorrectionName; } @@ -66,37 +69,69 @@ public: /// \brief Gets the pointer to the declaration of the typo correction NamedDecl* getCorrectionDecl() const { - return isKeyword() ? NULL : CorrectionDecl; + return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : 0; } template <class DeclClass> DeclClass *getCorrectionDeclAs() const { return dyn_cast_or_null<DeclClass>(getCorrectionDecl()); } + /// \brief Clears the list of NamedDecls before adding the new one. void setCorrectionDecl(NamedDecl *CDecl) { - CorrectionDecl = CDecl; - if (!CorrectionName) - CorrectionName = CDecl->getDeclName(); + CorrectionDecls.clear(); + addCorrectionDecl(CDecl); } + /// \brief Add the given NamedDecl to the list of NamedDecls that are the + /// declarations associated with the DeclarationName of this TypoCorrection + void addCorrectionDecl(NamedDecl *CDecl); + std::string getAsString(const LangOptions &LO) const; std::string getQuoted(const LangOptions &LO) const { return "'" + getAsString(LO) + "'"; } + /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName operator bool() const { return bool(CorrectionName); } - static inline NamedDecl *KeywordDecl() { return (NamedDecl*)-1; } - bool isKeyword() const { return CorrectionDecl == KeywordDecl(); } + /// \brief Mark this TypoCorrection as being a keyword. + /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be + /// added to the list of the correction's NamedDecl pointers, NULL is added + /// as the only element in the list to mark this TypoCorrection as a keyword. + void makeKeyword() { + CorrectionDecls.clear(); + CorrectionDecls.push_back(0); + } + + // Check if this TypoCorrection is a keyword by checking if the first + // item in CorrectionDecls is NULL. + bool isKeyword() const { + return !CorrectionDecls.empty() && + CorrectionDecls.front() == 0; + } // Returns true if the correction either is a keyword or has a known decl. - bool isResolved() const { return CorrectionDecl != NULL; } + bool isResolved() const { return !CorrectionDecls.empty(); } + + bool isOverloaded() const { + return CorrectionDecls.size() > 1; + } + + typedef llvm::SmallVector<NamedDecl*, 1>::iterator decl_iterator; + decl_iterator begin() { + return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); + } + decl_iterator end() { return CorrectionDecls.end(); } private: + bool hasCorrectionDecl() const { + return (!isKeyword() && !CorrectionDecls.empty()); + } + // Results. DeclarationName CorrectionName; NestedNameSpecifier *CorrectionNameSpec; - NamedDecl *CorrectionDecl; + llvm::SmallVector<NamedDecl*, 1> CorrectionDecls; unsigned EditDistance; }; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Weak.h b/contrib/llvm/tools/clang/include/clang/Sema/Weak.h new file mode 100644 index 0000000..d36b970 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Sema/Weak.h @@ -0,0 +1,46 @@ +//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the WeakInfo class, which is used to store +// information about the target of a #pragma weak directive. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_WEAK_H +#define LLVM_CLANG_SEMA_WEAK_H + +#include "clang/Basic/SourceLocation.h" + +namespace clang { + +class IdentifierInfo; + +/// \brief Captures information about a #pragma weak directive. +class WeakInfo { + IdentifierInfo *alias; // alias (optional) + SourceLocation loc; // for diagnostics + bool used; // identifier later declared? +public: + WeakInfo() + : alias(0), loc(SourceLocation()), used(false) {} + WeakInfo(IdentifierInfo *Alias, SourceLocation Loc) + : alias(Alias), loc(Loc), used(false) {} + inline IdentifierInfo * getAlias() const { return alias; } + inline SourceLocation getLocation() const { return loc; } + void setUsed(bool Used=true) { used = Used; } + inline bool getUsed() { return used; } + bool operator==(WeakInfo RHS) const { + return alias == RHS.getAlias() && loc == RHS.getLocation(); + } + bool operator!=(WeakInfo RHS) const { return !(*this == RHS); } +}; + +} // end namespace clang + +#endif // LLVM_CLANG_SEMA_WEAK_H diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h index 11b8bed..dc4d05c 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h @@ -47,16 +47,28 @@ namespace clang { /// should be increased. const unsigned VERSION_MINOR = 0; + /// \brief An ID number that refers to an identifier in an AST file. + /// + /// The ID numbers of identifiers are consecutive (in order of discovery) + /// and start at 1. 0 is reserved for NULL. + typedef uint32_t IdentifierID; + /// \brief An ID number that refers to a declaration in an AST file. /// /// The ID numbers of declarations are consecutive (in order of - /// discovery) and start at 2. 0 is reserved for NULL, and 1 is - /// reserved for the translation unit declaration. + /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. + /// At the start of a chain of precompiled headers, declaration ID 1 is + /// used for the translation unit declaration. typedef uint32_t DeclID; /// \brief a Decl::Kind/DeclID pair. typedef std::pair<uint32_t, DeclID> KindDeclIDPair; + // FIXME: Turn these into classes so we can have some type safety when + // we go from local ID to global and vice-versa. + typedef DeclID LocalDeclID; + typedef DeclID GlobalDeclID; + /// \brief An ID number that refers to a type in an AST file. /// /// The ID of a type is partitioned into two parts: the lower @@ -78,9 +90,15 @@ namespace clang { uint32_t getIndex() const { return Idx; } TypeID asTypeID(unsigned FastQuals) const { + if (Idx == uint32_t(-1)) + return TypeID(-1); + return (Idx << Qualifiers::FastWidth) | FastQuals; } static TypeIdx fromTypeID(TypeID ID) { + if (ID == TypeID(-1)) + return TypeIdx(-1); + return TypeIdx(ID >> Qualifiers::FastWidth); } }; @@ -103,31 +121,44 @@ namespace clang { } }; - /// \brief Map that provides the ID numbers of each type within the - /// output stream, plus those deserialized from a chained PCH. - /// - /// The ID numbers of types are consecutive (in order of discovery) - /// and start at 1. 0 is reserved for NULL. When types are actually - /// stored in the stream, the ID number is shifted by 2 bits to - /// allow for the const/volatile qualifiers. - /// - /// Keys in the map never have const/volatile qualifiers. - typedef llvm::DenseMap<QualType, TypeIdx, UnsafeQualTypeDenseMapInfo> - TypeIdxMap; - /// \brief An ID number that refers to an identifier in an AST file. typedef uint32_t IdentID; - /// \brief An ID number that refers to a macro in an AST file. - typedef uint32_t MacroID; - + /// \brief The number of predefined identifier IDs. + const unsigned int NUM_PREDEF_IDENT_IDS = 1; + /// \brief An ID number that refers to an ObjC selctor in an AST file. typedef uint32_t SelectorID; + /// \brief The number of predefined selector IDs. + const unsigned int NUM_PREDEF_SELECTOR_IDS = 1; + /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an /// AST file. typedef uint32_t CXXBaseSpecifiersID; + /// \brief An ID number that refers to an entity in the detailed + /// preprocessing record. + typedef uint32_t PreprocessedEntityID; + + /// \brief Source range/offset of a preprocessed entity. + struct PPEntityOffset { + /// \brief Raw source location of beginning of range. + unsigned Begin; + /// \brief Raw source location of end of range. + unsigned End; + /// \brief Offset in the AST file. + uint32_t BitOffset; + + PPEntityOffset(SourceRange R, uint32_t BitOffset) + : Begin(R.getBegin().getRawEncoding()), + End(R.getEnd().getRawEncoding()), + BitOffset(BitOffset) { } + }; + + /// \brief The number of predefined preprocessed entity IDs. + const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1; + /// \brief Describes the various kinds of blocks that occur within /// an AST file. enum BlockIDs { @@ -290,9 +321,9 @@ namespace clang { /// \brief Record code for the array of unused file scoped decls. UNUSED_FILESCOPED_DECLS = 22, - /// \brief Record code for the table of offsets to macro definition - /// entries in the preprocessing record. - MACRO_DEFINITION_OFFSETS = 23, + /// \brief Record code for the table of offsets to entries in the + /// preprocessing record. + PPD_ENTITIES_OFFSETS = 23, /// \brief Record code for the array of VTable uses. VTABLE_USES = 24, @@ -300,9 +331,9 @@ namespace clang { /// \brief Record code for the array of dynamic classes. DYNAMIC_CLASSES = 25, - /// \brief Record code for the chained AST metadata, including the - /// AST file version and the name of the PCH this depends on. - CHAINED_METADATA = 26, + /// \brief Record code for the list of other AST files imported by + /// this AST file. + IMPORTS = 26, /// \brief Record code for referenced selector pool. REFERENCED_SELECTOR_POOL = 27, @@ -375,8 +406,21 @@ namespace clang { /// \brief Record code for the set of known namespaces, which are used /// for typo correction. - KNOWN_NAMESPACES = 46 + KNOWN_NAMESPACES = 46, + /// \brief Record code for the remapping information used to relate + /// loaded modules to the various offsets and IDs(e.g., source location + /// offests, declaration and type IDs) that are used in that module to + /// refer to other modules. + MODULE_OFFSET_MAP = 47, + + /// \brief Record code for the source manager line table information, + /// which stores information about #line directives. + SOURCE_MANAGER_LINE_TABLE = 48, + + /// \brief Record code for ObjC categories in a module that are chained to + /// an interface. + OBJC_CHAINED_CATEGORIES }; /// \brief Record types used within a source manager block. @@ -393,10 +437,7 @@ namespace clang { SM_SLOC_BUFFER_BLOB = 3, /// \brief Describes a source location entry (SLocEntry) for a /// macro expansion. - SM_SLOC_EXPANSION_ENTRY = 4, - /// \brief Describes the SourceManager's line table, with - /// information about #line directives. - SM_LINE_TABLE = 5 + SM_SLOC_EXPANSION_ENTRY = 4 }; /// \brief Record types used within a preprocessor block. @@ -507,7 +548,13 @@ namespace clang { /// \brief The 'unknown any' placeholder type. PREDEF_TYPE_UNKNOWN_ANY = 29, /// \brief The placeholder type for bound member functions. - PREDEF_TYPE_BOUND_MEMBER = 30 + PREDEF_TYPE_BOUND_MEMBER = 30, + /// \brief The "auto" deduction type. + PREDEF_TYPE_AUTO_DEDUCT = 31, + /// \brief The "auto &&" deduction type. + PREDEF_TYPE_AUTO_RREF_DEDUCT = 32, + /// \brief The OpenCL 'half' / ARM NEON __fp16 type. + PREDEF_TYPE_HALF_ID = 33 }; /// \brief The number of predefined type IDs that are reserved for @@ -602,7 +649,9 @@ namespace clang { /// \brief A AutoType record. TYPE_AUTO = 38, /// \brief A UnaryTransformType record. - TYPE_UNARY_TRANSFORM = 39 + TYPE_UNARY_TRANSFORM = 39, + /// \brief An AtomicType record. + TYPE_ATOMIC = 40 }; /// \brief The type IDs for special types constructed by semantic @@ -613,44 +662,65 @@ namespace clang { enum SpecialTypeIDs { /// \brief __builtin_va_list SPECIAL_TYPE_BUILTIN_VA_LIST = 0, - /// \brief Objective-C "id" type - SPECIAL_TYPE_OBJC_ID = 1, - /// \brief Objective-C selector type - SPECIAL_TYPE_OBJC_SELECTOR = 2, /// \brief Objective-C Protocol type - SPECIAL_TYPE_OBJC_PROTOCOL = 3, - /// \brief Objective-C Class type - SPECIAL_TYPE_OBJC_CLASS = 4, + SPECIAL_TYPE_OBJC_PROTOCOL = 1, /// \brief CFConstantString type - SPECIAL_TYPE_CF_CONSTANT_STRING = 5, - /// \brief Objective-C fast enumeration state type - SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE = 6, + SPECIAL_TYPE_CF_CONSTANT_STRING = 2, /// \brief C FILE typedef type - SPECIAL_TYPE_FILE = 7, + SPECIAL_TYPE_FILE = 3, /// \brief C jmp_buf typedef type - SPECIAL_TYPE_jmp_buf = 8, + SPECIAL_TYPE_jmp_buf = 4, /// \brief C sigjmp_buf typedef type - SPECIAL_TYPE_sigjmp_buf = 9, + SPECIAL_TYPE_sigjmp_buf = 5, /// \brief Objective-C "id" redefinition type - SPECIAL_TYPE_OBJC_ID_REDEFINITION = 10, + SPECIAL_TYPE_OBJC_ID_REDEFINITION = 6, /// \brief Objective-C "Class" redefinition type - SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 11, - /// \brief Block descriptor type for Blocks CodeGen - SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12, - /// \brief Block extedned descriptor type for Blocks CodeGen - SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13, + SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 7, /// \brief Objective-C "SEL" redefinition type - SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 14, - /// \brief NSConstantString type - SPECIAL_TYPE_NS_CONSTANT_STRING = 15, - /// \brief Whether __[u]int128_t identifier is installed. - SPECIAL_TYPE_INT128_INSTALLED = 16, - /// \brief Cached "auto" deduction type. - SPECIAL_TYPE_AUTO_DEDUCT = 17, - /// \brief Cached "auto &&" deduction type. - SPECIAL_TYPE_AUTO_RREF_DEDUCT = 18 + SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 8 }; + + /// \brief The number of special type IDs. + const unsigned NumSpecialTypeIDs = 0; + /// \brief Predefined declaration IDs. + /// + /// These declaration IDs correspond to predefined declarations in the AST + /// context, such as the NULL declaration ID. Such declarations are never + /// actually serialized, since they will be built by the AST context when + /// it is created. + enum PredefinedDeclIDs { + /// \brief The NULL declaration. + PREDEF_DECL_NULL_ID = 0, + + /// \brief The translation unit. + PREDEF_DECL_TRANSLATION_UNIT_ID = 1, + + /// \brief The Objective-C 'id' type. + PREDEF_DECL_OBJC_ID_ID = 2, + + /// \brief The Objective-C 'SEL' type. + PREDEF_DECL_OBJC_SEL_ID = 3, + + /// \brief The Objective-C 'Class' type. + PREDEF_DECL_OBJC_CLASS_ID = 4, + + /// \brief The signed 128-bit integer type. + PREDEF_DECL_INT_128_ID = 5, + + /// \brief The unsigned 128-bit integer type. + PREDEF_DECL_UNSIGNED_INT_128_ID = 6, + + /// \brief The internal 'instancetype' typedef. + PREDEF_DECL_OBJC_INSTANCETYPE_ID = 7 + }; + + /// \brief The number of declaration IDs that are predefined. + /// + /// For more information about predefined declarations, see the + /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. + const unsigned int NUM_PREDEF_DECL_IDS = 8; + /// \brief Record codes for each kind of declaration. /// /// These constants describe the declaration records that can occur within @@ -658,10 +728,8 @@ namespace clang { /// constant describes a record for a specific declaration class /// in the AST. enum DeclCode { - /// \brief A TranslationUnitDecl record. - DECL_TRANSLATION_UNIT = 50, /// \brief A TypedefDecl record. - DECL_TYPEDEF, + DECL_TYPEDEF = 51, /// \brief A TypeAliasDecl record. DECL_TYPEALIAS, /// \brief An EnumDecl record. @@ -786,7 +854,10 @@ namespace clang { DECL_INDIRECTFIELD, /// \brief A NonTypeTemplateParmDecl record that stores an expanded /// non-type template parameter pack. - DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK + DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK, + /// \brief A ClassScopeFunctionSpecializationDecl record a class scope + /// function specialization. (Microsoft extension). + DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION }; /// \brief Record codes for each kind of statement or expression. @@ -904,7 +975,9 @@ namespace clang { EXPR_BLOCK_DECL_REF, /// \brief A GenericSelectionExpr record. EXPR_GENERIC_SELECTION, - + /// \brief An AtomicExpr record. + EXPR_ATOMIC, + // Objective-C /// \brief An ObjCStringLiteral record. diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTDeserializationListener.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTDeserializationListener.h index f8cdebe..588fe0e 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTDeserializationListener.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTDeserializationListener.h @@ -45,7 +45,7 @@ public: /// \brief A selector was read from the AST file. virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) { } /// \brief A macro definition was read from the AST file. - virtual void MacroDefinitionRead(serialization::MacroID, + virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinition *MD) { } }; diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h index 9e210c3..996a134 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h @@ -15,6 +15,9 @@ #define LLVM_CLANG_FRONTEND_AST_READER_H #include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Serialization/Module.h" +#include "clang/Serialization/ModuleManager.h" #include "clang/Sema/ExternalSemaSource.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/DeclObjC.h" @@ -23,6 +26,8 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/APFloat.h" @@ -31,6 +36,7 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/DataTypes.h" #include <deque> @@ -49,6 +55,7 @@ class AddrLabelExpr; class ASTConsumer; class ASTContext; class ASTIdentifierIterator; +class ASTUnit; // FIXME: Layering violation and egregious hack. class Attr; class Decl; class DeclContext; @@ -64,10 +71,10 @@ class Preprocessor; class Sema; class SwitchCase; class ASTDeserializationListener; +class ASTWriter; class ASTReader; class ASTDeclReader; class ASTStmtReader; -class ASTIdentifierLookupTrait; class TypeLocReader; struct HeaderFileInfo; class VersionTuple; @@ -77,9 +84,9 @@ struct PCHPredefinesBlock { FileID BufferID; /// \brief This predefines buffer in a PCH file. - llvm::StringRef Data; + StringRef Data; }; -typedef llvm::SmallVector<PCHPredefinesBlock, 2> PCHPredefinesBlocks; +typedef SmallVector<PCHPredefinesBlock, 2> PCHPredefinesBlocks; /// \brief Abstract interface for callback invocations by the ASTReader. /// @@ -101,7 +108,7 @@ public: /// \brief Receives the target triple. /// /// \returns true to indicate the target triple is invalid or false otherwise. - virtual bool ReadTargetTriple(llvm::StringRef Triple) { + virtual bool ReadTargetTriple(StringRef Triple) { return false; } @@ -117,7 +124,7 @@ public: /// /// \returns true to indicate the predefines are invalid or false otherwise. virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, - llvm::StringRef OriginalFileName, + StringRef OriginalFileName, std::string &SuggestedPredefines, FileManager &FileMgr) { return false; @@ -143,9 +150,9 @@ public: : PP(PP), Reader(Reader), NumHeaderInfos(0) {} virtual bool ReadLanguageOptions(const LangOptions &LangOpts); - virtual bool ReadTargetTriple(llvm::StringRef Triple); + virtual bool ReadTargetTriple(StringRef Triple); virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, - llvm::StringRef OriginalFileName, + StringRef OriginalFileName, std::string &SuggestedPredefines, FileManager &FileMgr); virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID); @@ -155,6 +162,16 @@ private: void Error(const char *Msg); }; +namespace serialization { + +class ReadMethodPoolVisitor; + +namespace reader { + class ASTIdentifierLookupTrait; +} + +} // end namespace serialization + /// \brief Reads an AST files chain containing the contents of a translation /// unit. /// @@ -179,18 +196,24 @@ class ASTReader public: enum ASTReadResult { Success, Failure, IgnorePCH }; /// \brief Types of AST files. - enum ASTFileType { - Module, ///< File is a module proper. - PCH, ///< File is a PCH file treated as such. - Preamble, ///< File is a PCH file treated as the preamble. - MainFile ///< File is a PCH file treated as the actual main file. - }; friend class PCHValidator; friend class ASTDeclReader; friend class ASTStmtReader; friend class ASTIdentifierIterator; - friend class ASTIdentifierLookupTrait; + friend class serialization::reader::ASTIdentifierLookupTrait; friend class TypeLocReader; + friend class ASTWriter; + friend class ASTUnit; // ASTUnit needs to remap source locations. + friend class serialization::ReadMethodPoolVisitor; + + typedef serialization::Module Module; + typedef serialization::ModuleKind ModuleKind; + typedef serialization::ModuleManager ModuleManager; + + typedef ModuleManager::ModuleIterator ModuleIterator; + typedef ModuleManager::ModuleConstIterator ModuleConstIterator; + typedef ModuleManager::ModuleReverseIterator ModuleReverseIterator; + private: /// \brief The receiver of some callbacks invoked by ASTReader. llvm::OwningPtr<ASTReaderListener> Listener; @@ -200,250 +223,50 @@ private: SourceManager &SourceMgr; FileManager &FileMgr; - Diagnostic &Diags; - + DiagnosticsEngine &Diags; + /// \brief The semantic analysis object that will be processing the /// AST files and the translation unit that uses it. Sema *SemaObj; /// \brief The preprocessor that will be loading the source file. - Preprocessor *PP; + Preprocessor &PP; /// \brief The AST context into which we'll read the AST files. - ASTContext *Context; + ASTContext &Context; /// \brief The AST consumer. ASTConsumer *Consumer; - /// \brief AST buffers for chained PCHs created and stored in memory. - /// First (not depending on another) PCH in chain is in front. - std::vector<llvm::MemoryBuffer *> ASTBuffers; - - /// \brief Information that is needed for every module. - struct PerFileData { - PerFileData(ASTFileType Ty); - ~PerFileData(); - - // === General information === - - /// \brief The type of this AST file. - ASTFileType Type; - - /// \brief The file name of the AST file. - std::string FileName; - - /// \brief The memory buffer that stores the data associated with - /// this AST file. - llvm::OwningPtr<llvm::MemoryBuffer> Buffer; - - /// \brief The size of this file, in bits. - uint64_t SizeInBits; - - /// \brief The bitstream reader from which we'll read the AST file. - llvm::BitstreamReader StreamFile; - - /// \brief The main bitstream cursor for the main block. - llvm::BitstreamCursor Stream; - - // === Source Locations === - - /// \brief Cursor used to read source location entries. - llvm::BitstreamCursor SLocEntryCursor; - - /// \brief The number of source location entries in this AST file. - unsigned LocalNumSLocEntries; - - /// \brief Offsets for all of the source location entries in the - /// AST file. - const uint32_t *SLocOffsets; - - /// \brief The number of source location file entries in this AST file. - unsigned LocalNumSLocFileEntries; - - /// \brief Offsets for all of the source location file entries in the - /// AST file. - const uint32_t *SLocFileOffsets; - - /// \brief The entire size of this module's source location offset range. - unsigned LocalSLocSize; - - // === Identifiers === - - /// \brief The number of identifiers in this AST file. - unsigned LocalNumIdentifiers; - - /// \brief Offsets into the identifier table data. - /// - /// This array is indexed by the identifier ID (-1), and provides - /// the offset into IdentifierTableData where the string data is - /// stored. - const uint32_t *IdentifierOffsets; - - /// \brief Actual data for the on-disk hash table of identifiers. - /// - /// This pointer points into a memory buffer, where the on-disk hash - /// table for identifiers actually lives. - const char *IdentifierTableData; - - /// \brief A pointer to an on-disk hash table of opaque type - /// IdentifierHashTable. - void *IdentifierLookupTable; - - // === Macros === - - /// \brief The cursor to the start of the preprocessor block, which stores - /// all of the macro definitions. - llvm::BitstreamCursor MacroCursor; - - /// \brief The offset of the start of the set of defined macros. - uint64_t MacroStartOffset; - - // === Detailed PreprocessingRecord === - - /// \brief The cursor to the start of the (optional) detailed preprocessing - /// record block. - llvm::BitstreamCursor PreprocessorDetailCursor; - - /// \brief The offset of the start of the preprocessor detail cursor. - uint64_t PreprocessorDetailStartOffset; - - /// \brief The number of macro definitions in this file. - unsigned LocalNumMacroDefinitions; - - /// \brief Offsets of all of the macro definitions in the preprocessing - /// record in the AST file. - const uint32_t *MacroDefinitionOffsets; - - // === Header search information === - - /// \brief The number of local HeaderFileInfo structures. - unsigned LocalNumHeaderFileInfos; - - /// \brief Actual data for the on-disk hash table of header file - /// information. - /// - /// This pointer points into a memory buffer, where the on-disk hash - /// table for header file information actually lives. - const char *HeaderFileInfoTableData; - - /// \brief The on-disk hash table that contains information about each of - /// the header files. - void *HeaderFileInfoTable; - - // === Selectors === - - /// \brief The number of selectors new to this file. - /// - /// This is the number of entries in SelectorOffsets. - unsigned LocalNumSelectors; - - /// \brief Offsets into the selector lookup table's data array - /// where each selector resides. - const uint32_t *SelectorOffsets; - - /// \brief A pointer to the character data that comprises the selector table - /// - /// The SelectorOffsets table refers into this memory. - const unsigned char *SelectorLookupTableData; - - /// \brief A pointer to an on-disk hash table of opaque type - /// ASTSelectorLookupTable. - /// - /// This hash table provides the IDs of all selectors, and the associated - /// instance and factory methods. - void *SelectorLookupTable; - - /// \brief Method selectors used in a @selector expression. Used for - /// implementation of -Wselector. - llvm::SmallVector<uint64_t, 64> ReferencedSelectorsData; - - // === Declarations === - - /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It - /// has read all the abbreviations at the start of the block and is ready to - /// jump around with these in context. - llvm::BitstreamCursor DeclsCursor; - - /// \brief The number of declarations in this AST file. - unsigned LocalNumDecls; - - /// \brief Offset of each declaration within the bitstream, indexed - /// by the declaration ID (-1). - const uint32_t *DeclOffsets; - - /// \brief A snapshot of the pending instantiations in the chain. - /// - /// This record tracks the instantiations that Sema has to perform at the - /// end of the TU. It consists of a pair of values for every pending - /// instantiation where the first value is the ID of the decl and the second - /// is the instantiation location. - llvm::SmallVector<uint64_t, 64> PendingInstantiations; - - /// \brief The number of C++ base specifier sets in this AST file. - unsigned LocalNumCXXBaseSpecifiers; - - /// \brief Offset of each C++ base specifier set within the bitstream, - /// indexed by the C++ base specifier set ID (-1). - const uint32_t *CXXBaseSpecifiersOffsets; - - // === Types === - - /// \brief The number of types in this AST file. - unsigned LocalNumTypes; - - /// \brief Offset of each type within the bitstream, indexed by the - /// type ID, or the representation of a Type*. - const uint32_t *TypeOffsets; + /// \brief The module manager which manages modules and their dependencies + ModuleManager ModuleMgr; - // === Miscellaneous === + /// \brief A map of global bit offsets to the module that stores entities + /// at those bit offsets. + ContinuousRangeMap<uint64_t, Module*, 4> GlobalBitOffsetsMap; - /// \brief The AST stat cache installed for this file, if any. - /// - /// The dynamic type of this stat cache is always ASTStatCache - void *StatCache; - - /// \brief The number of preallocated preprocessing entities in the - /// preprocessing record. - unsigned NumPreallocatedPreprocessingEntities; - - /// \brief The next module in source order. - PerFileData *NextInSource; - - /// \brief All the modules that loaded this one. Can contain NULL for - /// directly loaded modules. - llvm::SmallVector<PerFileData *, 1> Loaders; - }; - - /// \brief All loaded modules, indexed by name. - llvm::StringMap<PerFileData*> Modules; - - /// \brief The first module in source order. - PerFileData *FirstInSource; - - /// \brief The chain of AST files. The first entry is the one named by the - /// user, the last one is the one that doesn't depend on anything further. - /// That is, the entry I was created with -include-pch I+1. - llvm::SmallVector<PerFileData*, 2> Chain; - - /// \brief SLocEntries that we're going to preload. - llvm::SmallVector<uint64_t, 64> PreloadSLocEntries; + /// \brief A map of negated SLocEntryIDs to the modules containing them. + ContinuousRangeMap<unsigned, Module*, 64> GlobalSLocEntryMap; + typedef ContinuousRangeMap<unsigned, Module*, 64> GlobalSLocOffsetMapType; + + /// \brief A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset) + /// SourceLocation offsets to the modules containing them. + GlobalSLocOffsetMapType GlobalSLocOffsetMap; + /// \brief Types that have already been loaded from the chain. /// /// When the pointer at index I is non-NULL, the type with /// ID = (I + 1) << FastQual::Width has already been loaded std::vector<QualType> TypesLoaded; - /// \brief Map that provides the ID numbers of each type within the - /// output stream, plus those deserialized from a chained PCH. - /// - /// The ID numbers of types are consecutive (in order of discovery) - /// and start at 1. 0 is reserved for NULL. When types are actually - /// stored in the stream, the ID number is shifted by 2 bits to - /// allow for the const/volatile qualifiers. - /// - /// Keys in the map never have const/volatile qualifiers. - serialization::TypeIdxMap TypeIdxs; + typedef ContinuousRangeMap<serialization::TypeID, Module *, 4> + GlobalTypeMapType; + + /// \brief Mapping from global type IDs to the module in which the + /// type resides along with the offset that should be added to the + /// global type ID to produce a local ID. + GlobalTypeMapType GlobalTypeMap; /// \brief Declarations that have already been loaded from the chain. /// @@ -451,50 +274,41 @@ private: /// = I + 1 has already been loaded. std::vector<Decl *> DeclsLoaded; - typedef std::pair<PerFileData *, uint64_t> FileOffset; - typedef llvm::SmallVector<FileOffset, 2> FileOffsetsTy; + typedef ContinuousRangeMap<serialization::DeclID, Module *, 4> + GlobalDeclMapType; + + /// \brief Mapping from global declaration IDs to the module in which the + /// declaration resides. + GlobalDeclMapType GlobalDeclMap; + + typedef std::pair<Module *, uint64_t> FileOffset; + typedef SmallVector<FileOffset, 2> FileOffsetsTy; typedef llvm::DenseMap<serialization::DeclID, FileOffsetsTy> DeclUpdateOffsetsMap; + /// \brief Declarations that have modifications residing in a later file /// in the chain. DeclUpdateOffsetsMap DeclUpdateOffsets; typedef llvm::DenseMap<serialization::DeclID, - std::pair<PerFileData *, uint64_t> > + std::pair<Module *, uint64_t> > DeclReplacementMap; /// \brief Declarations that have been replaced in a later file in the chain. DeclReplacementMap ReplacedDecls; - /// \brief Information about the contents of a DeclContext. - struct DeclContextInfo { - void *NameLookupTableData; // a ASTDeclContextNameLookupTable. - const serialization::KindDeclIDPair *LexicalDecls; - unsigned NumLexicalDecls; - }; - // In a full chain, there could be multiple updates to every decl context, - // so this is a vector. However, typically a chain is only two elements long, - // with only one file containing updates, so there will be only one update - // per decl context. - typedef llvm::SmallVector<DeclContextInfo, 1> DeclContextInfos; - typedef llvm::DenseMap<const DeclContext *, DeclContextInfos> - DeclContextOffsetsMap; // Updates for visible decls can occur for other contexts than just the // TU, and when we read those update records, the actual context will not // be available yet (unless it's the TU), so have this pending map using the // ID as a key. It will be realized when the context is actually loaded. - typedef llvm::SmallVector<void *, 1> DeclContextVisibleUpdates; + typedef SmallVector<std::pair<void *, Module*>, 1> DeclContextVisibleUpdates; typedef llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates> DeclContextVisibleUpdatesPending; - /// \brief Offsets of the lexical and visible declarations for each - /// DeclContext. - DeclContextOffsetsMap DeclContextOffsets; - /// \brief Updates to the visible declarations of declaration contexts that /// haven't been loaded yet. DeclContextVisibleUpdatesPending PendingVisibleUpdates; - typedef llvm::SmallVector<CXXRecordDecl *, 4> ForwardRefs; + typedef SmallVector<CXXRecordDecl *, 4> ForwardRefs; typedef llvm::DenseMap<const CXXRecordDecl *, ForwardRefs> PendingForwardRefsMap; /// \brief Forward references that have a definition but the definition decl @@ -508,10 +322,15 @@ private: /// most recent declarations in another AST file. FirstLatestDeclIDMap FirstLatestDeclIDs; + /// \brief Set of ObjC interfaces that have categories chained to them in + /// other modules. + llvm::DenseSet<serialization::GlobalDeclID> ObjCChainedCategoriesInterfaces; + /// \brief Read the records that describe the contents of declcontexts. - bool ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, + bool ReadDeclContextStorage(Module &M, + llvm::BitstreamCursor &Cursor, const std::pair<uint64_t, uint64_t> &Offsets, - DeclContextInfo &Info); + serialization::DeclContextInfo &Info); /// \brief A vector containing identifiers that have already been /// loaded. @@ -521,21 +340,42 @@ private: /// been loaded. std::vector<IdentifierInfo *> IdentifiersLoaded; + typedef ContinuousRangeMap<serialization::IdentID, Module *, 4> + GlobalIdentifierMapType; + + /// \brief Mapping from global identifer IDs to the module in which the + /// identifier resides along with the offset that should be added to the + /// global identifier ID to produce a local ID. + GlobalIdentifierMapType GlobalIdentifierMap; + /// \brief A vector containing selectors that have already been loaded. /// /// This vector is indexed by the Selector ID (-1). NULL selector /// entries indicate that the particular selector ID has not yet /// been loaded. - llvm::SmallVector<Selector, 16> SelectorsLoaded; + SmallVector<Selector, 16> SelectorsLoaded; - /// \brief The macro definitions we have already loaded. - llvm::SmallVector<MacroDefinition *, 16> MacroDefinitionsLoaded; + typedef ContinuousRangeMap<serialization::SelectorID, Module *, 4> + GlobalSelectorMapType; + + /// \brief Mapping from global selector IDs to the module in which the + /// selector resides along with the offset that should be added to the + /// global selector ID to produce a local ID. + GlobalSelectorMapType GlobalSelectorMap; /// \brief Mapping from identifiers that represent macros whose definitions /// have not yet been deserialized to the global offset where the macro /// record resides. llvm::DenseMap<IdentifierInfo *, uint64_t> UnreadMacroRecordOffsets; - + + typedef ContinuousRangeMap<unsigned, Module *, 4> + GlobalPreprocessedEntityMapType; + + /// \brief Mapping from global preprocessing entity IDs to the module in + /// which the preprocessed entity resides along with the offset that should be + /// added to the global preprocessing entitiy ID to produce a local ID. + GlobalPreprocessedEntityMapType GlobalPreprocessedEntityMap; + /// \name CodeGen-relevant special data /// \brief Fields containing data that is relevant to CodeGen. //@{ @@ -546,44 +386,56 @@ private: /// This contains the data loaded from all EXTERNAL_DEFINITIONS blocks in the /// chain. The referenced declarations are deserialized and passed to the /// consumer eagerly. - llvm::SmallVector<uint64_t, 16> ExternalDefinitions; + SmallVector<uint64_t, 16> ExternalDefinitions; /// \brief The IDs of all tentative definitions stored in the the chain. /// /// Sema keeps track of all tentative definitions in a TU because it has to /// complete them and pass them on to CodeGen. Thus, tentative definitions in /// the PCH chain must be eagerly deserialized. - llvm::SmallVector<uint64_t, 16> TentativeDefinitions; + SmallVector<uint64_t, 16> TentativeDefinitions; /// \brief The IDs of all CXXRecordDecls stored in the chain whose VTables are /// used. /// /// CodeGen has to emit VTables for these records, so they have to be eagerly /// deserialized. - llvm::SmallVector<uint64_t, 64> VTableUses; + SmallVector<uint64_t, 64> VTableUses; + + /// \brief A snapshot of the pending instantiations in the chain. + /// + /// This record tracks the instantiations that Sema has to perform at the + /// end of the TU. It consists of a pair of values for every pending + /// instantiation where the first value is the ID of the decl and the second + /// is the instantiation location. + SmallVector<uint64_t, 64> PendingInstantiations; //@} - /// \name Diagnostic-relevant special data + /// \name DiagnosticsEngine-relevant special data /// \brief Fields containing data that is used for generating diagnostics //@{ /// \brief A snapshot of Sema's unused file-scoped variable tracking, for /// generating warnings. - llvm::SmallVector<uint64_t, 16> UnusedFileScopedDecls; + SmallVector<uint64_t, 16> UnusedFileScopedDecls; /// \brief A list of all the delegating constructors we've seen, to diagnose /// cycles. - llvm::SmallVector<uint64_t, 4> DelegatingCtorDecls; + SmallVector<uint64_t, 4> DelegatingCtorDecls; + + /// \brief Method selectors used in a @selector expression. Used for + /// implementation of -Wselector. + SmallVector<uint64_t, 64> ReferencedSelectorsData; /// \brief A snapshot of Sema's weak undeclared identifier tracking, for /// generating warnings. - llvm::SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers; + SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers; /// \brief The IDs of type aliases for ext_vectors that exist in the chain. /// /// Used by Sema for finding sugared names for ext_vectors in diagnostics. - llvm::SmallVector<uint64_t, 4> ExtVectorDecls; + SmallVector<uint64_t, 4> ExtVectorDecls; //@} @@ -595,44 +447,41 @@ private: /// /// Sema tracks these to validate that the types are consistent across all /// local external declarations. - llvm::SmallVector<uint64_t, 16> LocallyScopedExternalDecls; + SmallVector<uint64_t, 16> LocallyScopedExternalDecls; /// \brief The IDs of all dynamic class declarations in the chain. /// /// Sema tracks these because it checks for the key functions being defined /// at the end of the TU, in which case it directs CodeGen to emit the VTable. - llvm::SmallVector<uint64_t, 16> DynamicClasses; + SmallVector<uint64_t, 16> DynamicClasses; /// \brief The IDs of the declarations Sema stores directly. /// /// Sema tracks a few important decls, such as namespace std, directly. - llvm::SmallVector<uint64_t, 4> SemaDeclRefs; + SmallVector<uint64_t, 4> SemaDeclRefs; /// \brief The IDs of the types ASTContext stores directly. /// /// The AST context tracks a few important types, such as va_list, directly. - llvm::SmallVector<uint64_t, 16> SpecialTypes; + SmallVector<uint64_t, 16> SpecialTypes; /// \brief The IDs of CUDA-specific declarations ASTContext stores directly. /// /// The AST context tracks a few important decls, currently cudaConfigureCall, /// directly. - llvm::SmallVector<uint64_t, 2> CUDASpecialDeclRefs; + SmallVector<uint64_t, 2> CUDASpecialDeclRefs; /// \brief The floating point pragma option settings. - llvm::SmallVector<uint64_t, 1> FPPragmaOptions; + SmallVector<uint64_t, 1> FPPragmaOptions; /// \brief The OpenCL extension settings. - llvm::SmallVector<uint64_t, 1> OpenCLExtensions; + SmallVector<uint64_t, 1> OpenCLExtensions; /// \brief A list of the namespaces we've seen. - llvm::SmallVector<uint64_t, 4> KnownNamespaces; + SmallVector<uint64_t, 4> KnownNamespaces; //@} - /// \brief Diagnostic IDs and their mappings that the user changed. - llvm::SmallVector<uint64_t, 8> PragmaDiagMappings; - /// \brief The original file name that was used to build the primary AST file, /// which may have been modified for relocatable-pch support. std::string OriginalFileName; @@ -657,7 +506,7 @@ private: /// \brief The system include root to be used when loading the /// precompiled header. - const char *isysroot; + std::string isysroot; /// \brief Whether to disable the normal validation performed on precompiled /// headers when they are loaded. @@ -686,9 +535,6 @@ private: /// \brief The number of source location entries in the chain. unsigned TotalNumSLocEntries; - /// \brief The next offset for a SLocEntry after everything in this reader. - unsigned NextSLocOffset; - /// \brief The number of statements (and expressions) de-serialized /// from the chain. unsigned NumStatementsRead; @@ -722,14 +568,20 @@ private: /// Number of visible decl contexts read/total. unsigned NumVisibleDeclContextsRead, TotalVisibleDeclContexts; + /// Total size of modules, in bits, currently loaded + uint64_t TotalModulesSizeInBits; + /// \brief Number of Decl/types that are currently deserializing. unsigned NumCurrentElementsDeserializing; + /// Number of CXX base specifiers currently loaded + unsigned NumCXXBaseSpecifiersLoaded; + /// \brief An IdentifierInfo that has been loaded but whose top-level /// declarations of the same name have not (yet) been loaded. struct PendingIdentifierInfo { IdentifierInfo *II; - llvm::SmallVector<uint32_t, 4> DeclIDs; + SmallVector<uint32_t, 4> DeclIDs; }; /// \brief The set of identifiers that were read while the AST reader was @@ -755,7 +607,7 @@ private: void loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID); /// \brief When reading a Stmt tree, Stmt operands are placed in this stack. - llvm::SmallVector<Stmt *, 16> StmtStack; + SmallVector<Stmt *, 16> StmtStack; /// \brief What kind of records we are reading. enum ReadingKind { @@ -797,36 +649,59 @@ private: std::string SuggestedPredefines; /// \brief Reads a statement from the specified cursor. - Stmt *ReadStmtFromStream(PerFileData &F); + Stmt *ReadStmtFromStream(Module &F); /// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take /// into account all the necessary relocations. - const FileEntry *getFileEntry(llvm::StringRef filename); + const FileEntry *getFileEntry(StringRef filename); void MaybeAddSystemRootToFilename(std::string &Filename); - ASTReadResult ReadASTCore(llvm::StringRef FileName, ASTFileType Type); - ASTReadResult ReadASTBlock(PerFileData &F); + ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, + Module *ImportedBy); + ASTReadResult ReadASTBlock(Module &F); bool CheckPredefinesBuffers(); - bool ParseLineTable(PerFileData &F, llvm::SmallVectorImpl<uint64_t> &Record); - ASTReadResult ReadSourceManagerBlock(PerFileData &F); - ASTReadResult ReadSLocEntryRecord(unsigned ID); - PerFileData *SLocCursorForID(unsigned ID); - SourceLocation getImportLocation(PerFileData *F); - bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record); + bool ParseLineTable(Module &F, SmallVectorImpl<uint64_t> &Record); + ASTReadResult ReadSourceManagerBlock(Module &F); + ASTReadResult ReadSLocEntryRecord(int ID); + llvm::BitstreamCursor &SLocCursorForID(int ID); + SourceLocation getImportLocation(Module *F); + bool ParseLanguageOptions(const SmallVectorImpl<uint64_t> &Record); struct RecordLocation { - RecordLocation(PerFileData *M, uint64_t O) + RecordLocation(Module *M, uint64_t O) : F(M), Offset(O) {} - PerFileData *F; + Module *F; uint64_t Offset; }; - QualType ReadTypeRecord(unsigned Index); + QualType readTypeRecord(unsigned Index); RecordLocation TypeCursorForIndex(unsigned Index); void LoadedDecl(unsigned Index, Decl *D); - Decl *ReadDeclRecord(unsigned Index, serialization::DeclID ID); - RecordLocation DeclCursorForIndex(unsigned Index, serialization::DeclID ID); + Decl *ReadDeclRecord(serialization::DeclID ID); + RecordLocation DeclCursorForID(serialization::DeclID ID); + void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D); + void loadObjCChainedCategories(serialization::GlobalDeclID ID, + ObjCInterfaceDecl *D); + + RecordLocation getLocalBitOffset(uint64_t GlobalOffset); + uint64_t getGlobalBitOffset(Module &M, uint32_t LocalOffset); + + /// \brief Returns the first preprocessed entity ID that ends after \arg BLoc. + serialization::PreprocessedEntityID + findBeginPreprocessedEntity(SourceLocation BLoc) const; + + /// \brief Returns the first preprocessed entity ID that begins after \arg ELoc. + serialization::PreprocessedEntityID + findEndPreprocessedEntity(SourceLocation ELoc) const; + + /// \brief \arg SLocMapI points at a chunk of a module that contains no + /// preprocessed entities or the entities it contains are not the ones we are + /// looking for. Find the next module that contains entities and return the ID + /// of the first entry. + serialization::PreprocessedEntityID + findNextPreprocessedEntity( + GlobalSLocOffsetMapType::const_iterator SLocMapI) const; void PassInterestingDeclsToConsumer(); @@ -834,14 +709,14 @@ private: /// /// This routine should only be used for fatal errors that have to /// do with non-routine failures (e.g., corrupted AST file). - void Error(llvm::StringRef Msg); - void Error(unsigned DiagID, llvm::StringRef Arg1 = llvm::StringRef(), - llvm::StringRef Arg2 = llvm::StringRef()); + void Error(StringRef Msg); + void Error(unsigned DiagID, StringRef Arg1 = StringRef(), + StringRef Arg2 = StringRef()); ASTReader(const ASTReader&); // do not implement ASTReader &operator=(const ASTReader &); // do not implement public: - typedef llvm::SmallVector<uint64_t, 64> RecordData; + typedef SmallVector<uint64_t, 64> RecordData; /// \brief Load the AST file and validate its contents against the given /// Preprocessor. @@ -865,46 +740,19 @@ public: /// help when an AST file is being used in cases where the /// underlying files in the file system may have changed, but /// parsing should still continue. - ASTReader(Preprocessor &PP, ASTContext *Context, const char *isysroot = 0, + ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "", bool DisableValidation = false, bool DisableStatCache = false); - /// \brief Load the AST file without using any pre-initialized Preprocessor. - /// - /// The necessary information to initialize a Preprocessor later can be - /// obtained by setting a ASTReaderListener. - /// - /// \param SourceMgr the source manager into which the AST file will be loaded - /// - /// \param FileMgr the file manager into which the AST file will be loaded. - /// - /// \param Diags the diagnostics system to use for reporting errors and - /// warnings relevant to loading the AST file. - /// - /// \param isysroot If non-NULL, the system include path specified by the - /// user. This is only used with relocatable PCH files. If non-NULL, - /// a relocatable PCH file will use the default path "/". - /// - /// \param DisableValidation If true, the AST reader will suppress most - /// of its regular consistency checking, allowing the use of precompiled - /// headers that cannot be determined to be compatible. - /// - /// \param DisableStatCache If true, the AST reader will ignore the - /// stat cache in the AST files. This performance pessimization can - /// help when an AST file is being used in cases where the - /// underlying files in the file system may have changed, but - /// parsing should still continue. - ASTReader(SourceManager &SourceMgr, FileManager &FileMgr, - Diagnostic &Diags, const char *isysroot = 0, - bool DisableValidation = false, bool DisableStatCache = false); ~ASTReader(); - /// \brief Load the precompiled header designated by the given file - /// name. - ASTReadResult ReadAST(const std::string &FileName, ASTFileType Type); + SourceManager &getSourceManager() const { return SourceMgr; } + + /// \brief Load the AST file designated by the given file name. + ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type); /// \brief Checks that no file that is stored in PCH is out-of-sync with /// the actual file in the file system. - ASTReadResult validateFileEntries(); + ASTReadResult validateFileEntries(Module &M); /// \brief Set the AST callbacks listener. void setListener(ASTReaderListener *listener) { @@ -914,22 +762,20 @@ public: /// \brief Set the AST deserialization listener. void setDeserializationListener(ASTDeserializationListener *Listener); - /// \brief Set the Preprocessor to use. - void setPreprocessor(Preprocessor &pp); + /// \brief Initializes the ASTContext + void InitializeContext(); - /// \brief Sets and initializes the given Context. - void InitializeContext(ASTContext &Context); - - /// \brief Set AST buffers for chained PCHs created and stored in memory. - /// First (not depending on another) PCH in chain is first in array. - void setASTMemoryBuffers(llvm::MemoryBuffer **bufs, unsigned numBufs) { - ASTBuffers.clear(); - ASTBuffers.insert(ASTBuffers.begin(), bufs, bufs + numBufs); + /// \brief Add in-memory (virtual file) buffer. + void addInMemoryBuffer(StringRef &FileName, llvm::MemoryBuffer *Buffer) { + ModuleMgr.addInMemoryBuffer(FileName, Buffer); } - /// \brief Retrieve the name of the named (primary) AST file - const std::string &getFileName() const { return Chain[0]->FileName; } + /// \brief Retrieve the module manager. + ModuleManager &getModuleManager() { return ModuleMgr; } + /// \brief Retrieve the preprocessor. + Preprocessor &getPreprocessor() const { return PP; } + /// \brief Retrieve the name of the original source file name const std::string &getOriginalSourceFile() { return OriginalFileName; } @@ -937,34 +783,34 @@ public: /// the AST file, without actually loading the AST file. static std::string getOriginalSourceFile(const std::string &ASTFileName, FileManager &FileMgr, - Diagnostic &Diags); + DiagnosticsEngine &Diags); /// \brief Returns the suggested contents of the predefines buffer, /// which contains a (typically-empty) subset of the predefines /// build prior to including the precompiled header. const std::string &getSuggestedPredefines() { return SuggestedPredefines; } - - /// \brief Read preprocessed entities into the preprocessing record. - virtual void ReadPreprocessedEntities(); - /// \brief Read the preprocessed entity at the given offset. - virtual PreprocessedEntity *ReadPreprocessedEntityAtOffset(uint64_t Offset); + /// \brief Read a preallocated preprocessed entity from the external source. + /// + /// \returns null if an error occurred that prevented the preprocessed + /// entity from being loaded. + virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index); + + /// \brief Returns a pair of [Begin, End) indices of preallocated + /// preprocessed entities that \arg Range encompasses. + virtual std::pair<unsigned, unsigned> + findPreprocessedEntitiesInRange(SourceRange Range); /// \brief Read the header file information for the given file entry. virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE); - void ReadPragmaDiagnosticMappings(Diagnostic &Diag); + void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag); /// \brief Returns the number of source locations found in the chain. unsigned getTotalNumSLocs() const { return TotalNumSLocEntries; } - /// \brief Returns the next SLocEntry offset after the chain. - unsigned getNextSLocOffset() const { - return NextSLocOffset; - } - /// \brief Returns the number of identifiers found in the chain. unsigned getTotalNumIdentifiers() const { return static_cast<unsigned>(IdentifiersLoaded.size()); @@ -985,54 +831,110 @@ public: return static_cast<unsigned>(SelectorsLoaded.size()); } - /// \brief Returns the number of macro definitions found in the chain. - unsigned getTotalNumMacroDefinitions() const { - return static_cast<unsigned>(MacroDefinitionsLoaded.size()); + /// \brief Returns the number of preprocessed entities known to the AST + /// reader. + unsigned getTotalNumPreprocessedEntities() const { + unsigned Result = 0; + for (ModuleConstIterator I = ModuleMgr.begin(), + E = ModuleMgr.end(); I != E; ++I) { + Result += (*I)->NumPreprocessedEntities; + } + + return Result; } /// \brief Returns the number of C++ base specifiers found in the chain. - unsigned getTotalNumCXXBaseSpecifiers() const; + unsigned getTotalNumCXXBaseSpecifiers() const { + return NumCXXBaseSpecifiersLoaded; + } /// \brief Reads a TemplateArgumentLocInfo appropriate for the /// given TemplateArgument kind. TemplateArgumentLocInfo - GetTemplateArgumentLocInfo(PerFileData &F, TemplateArgument::ArgKind Kind, + GetTemplateArgumentLocInfo(Module &F, TemplateArgument::ArgKind Kind, const RecordData &Record, unsigned &Idx); /// \brief Reads a TemplateArgumentLoc. TemplateArgumentLoc - ReadTemplateArgumentLoc(PerFileData &F, + ReadTemplateArgumentLoc(Module &F, const RecordData &Record, unsigned &Idx); /// \brief Reads a declarator info from the given record. - TypeSourceInfo *GetTypeSourceInfo(PerFileData &F, + TypeSourceInfo *GetTypeSourceInfo(Module &F, const RecordData &Record, unsigned &Idx); - /// \brief Resolve and return the translation unit declaration. - TranslationUnitDecl *GetTranslationUnitDecl(); - /// \brief Resolve a type ID into a type, potentially building a new /// type. QualType GetType(serialization::TypeID ID); - /// \brief Returns the type ID associated with the given type. - /// If the type didn't come from the AST file the ID that is returned is - /// marked as "doesn't exist in AST". - serialization::TypeID GetTypeID(QualType T) const; - - /// \brief Returns the type index associated with the given type. - /// If the type didn't come from the AST file the index that is returned is - /// marked as "doesn't exist in AST". - serialization::TypeIdx GetTypeIdx(QualType T) const; + /// \brief Resolve a local type ID within a given AST file into a type. + QualType getLocalType(Module &F, unsigned LocalID); + + /// \brief Map a local type ID within a given AST file into a global type ID. + serialization::TypeID getGlobalTypeID(Module &F, unsigned LocalID) const; + + /// \brief Read a type from the current position in the given record, which + /// was read from the given AST file. + QualType readType(Module &F, const RecordData &Record, unsigned &Idx) { + if (Idx >= Record.size()) + return QualType(); + + return getLocalType(F, Record[Idx++]); + } + + /// \brief Map from a local declaration ID within a given module to a + /// global declaration ID. + serialization::DeclID getGlobalDeclID(Module &F, unsigned LocalID) const; + /// \brief Returns true if global DeclID \arg ID originated from module + /// \arg M. + bool isDeclIDFromModule(serialization::GlobalDeclID ID, Module &M) const; + /// \brief Resolve a declaration ID into a declaration, potentially /// building a new declaration. Decl *GetDecl(serialization::DeclID ID); virtual Decl *GetExternalDecl(uint32_t ID); - /// \brief Resolve a CXXBaseSpecifiers ID into an offset into the chain - /// of loaded AST files. - uint64_t GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID); + /// \brief Reads a declaration with the given local ID in the given module. + Decl *GetLocalDecl(Module &F, uint32_t LocalID) { + return GetDecl(getGlobalDeclID(F, LocalID)); + } + + /// \brief Reads a declaration with the given local ID in the given module. + /// + /// \returns The requested declaration, casted to the given return type. + template<typename T> + T *GetLocalDeclAs(Module &F, uint32_t LocalID) { + return cast_or_null<T>(GetLocalDecl(F, LocalID)); + } + + /// \brief Reads a declaration ID from the given position in a record in the + /// given module. + /// + /// \returns The declaration ID read from the record, adjusted to a global ID. + serialization::DeclID ReadDeclID(Module &F, const RecordData &Record, + unsigned &Idx); + + /// \brief Reads a declaration from the given position in a record in the + /// given module. + Decl *ReadDecl(Module &F, const RecordData &R, unsigned &I) { + return GetDecl(ReadDeclID(F, R, I)); + } + + /// \brief Reads a declaration from the given position in a record in the + /// given module. + /// + /// \returns The declaration read from this location, casted to the given + /// result type. + template<typename T> + T *ReadDeclAs(Module &F, const RecordData &R, unsigned &I) { + return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I))); + } + + /// \brief Read a CXXBaseSpecifiers ID form the given record and + /// return its global bit offset. + uint64_t readCXXBaseSpecifiers(Module &M, const RecordData &Record, + unsigned &Idx); virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); @@ -1055,8 +957,6 @@ public: FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); - virtual void MaterializeVisibleDecls(const DeclContext *DC); - /// \brief Read all of the declarations lexically stored in a /// declaration context. /// @@ -1072,7 +972,7 @@ public: /// declarations for this declaration context. virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), - llvm::SmallVectorImpl<Decl*> &Decls); + SmallVectorImpl<Decl*> &Decls); /// \brief Notify ASTReader that we started deserialization of /// a decl or type so until FinishedDeserializing is called there may be @@ -1093,6 +993,9 @@ public: /// \brief Print some statistics about AST usage. virtual void PrintStats(); + /// \brief Dump information about the AST reader to standard error. + void dump(); + /// Return the amount of memory used by memory buffers, breaking down /// by heap-backed versus mmap'ed memory. virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const; @@ -1112,7 +1015,7 @@ public: /// declarations will be deserialized and introduced into the declaration /// chain of the identifier. virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd); - IdentifierInfo *get(llvm::StringRef Name) { + IdentifierInfo *get(StringRef Name) { return get(Name.begin(), Name.end()); } @@ -1131,14 +1034,42 @@ public: /// \brief Load the set of namespaces that are known to the external source, /// which will be used during typo correction. virtual void ReadKnownNamespaces( - llvm::SmallVectorImpl<NamespaceDecl *> &Namespaces); + SmallVectorImpl<NamespaceDecl *> &Namespaces); + + virtual void ReadTentativeDefinitions( + SmallVectorImpl<VarDecl *> &TentativeDefs); + + virtual void ReadUnusedFileScopedDecls( + SmallVectorImpl<const DeclaratorDecl *> &Decls); + + virtual void ReadDelegatingConstructors( + SmallVectorImpl<CXXConstructorDecl *> &Decls); + + virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls); + + virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls); + + virtual void ReadLocallyScopedExternalDecls( + SmallVectorImpl<NamedDecl *> &Decls); + + virtual void ReadReferencedSelectors( + SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels); + + virtual void ReadWeakUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI); + + virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables); + + virtual void ReadPendingInstantiations( + SmallVectorImpl<std::pair<ValueDecl *, + SourceLocation> > &Pending); /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); void SetIdentifierInfo(unsigned ID, IdentifierInfo *II); void SetGloballyVisibleDecls(IdentifierInfo *II, - const llvm::SmallVectorImpl<uint32_t> &DeclIDs, + const SmallVectorImpl<uint32_t> &DeclIDs, bool Nonrecursive = false); /// \brief Report a diagnostic. @@ -1147,92 +1078,112 @@ public: /// \brief Report a diagnostic. DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); - IdentifierInfo *DecodeIdentifierInfo(unsigned Idx); + IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID); - IdentifierInfo *GetIdentifierInfo(const RecordData &Record, unsigned &Idx) { - return DecodeIdentifierInfo(Record[Idx++]); + IdentifierInfo *GetIdentifierInfo(Module &M, const RecordData &Record, + unsigned &Idx) { + return DecodeIdentifierInfo(getGlobalIdentifierID(M, Record[Idx++])); } - virtual IdentifierInfo *GetIdentifier(unsigned ID) { + virtual IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) { return DecodeIdentifierInfo(ID); } + IdentifierInfo *getLocalIdentifier(Module &M, unsigned LocalID); + + serialization::IdentifierID getGlobalIdentifierID(Module &M, + unsigned LocalID); + /// \brief Read the source location entry with index ID. - virtual bool ReadSLocEntry(unsigned ID); + virtual bool ReadSLocEntry(int ID); + + /// \brief Retrieve a selector from the given module with its local ID + /// number. + Selector getLocalSelector(Module &M, unsigned LocalID); - Selector DecodeSelector(unsigned Idx); + Selector DecodeSelector(serialization::SelectorID Idx); - virtual Selector GetExternalSelector(uint32_t ID); + virtual Selector GetExternalSelector(serialization::SelectorID ID); uint32_t GetNumExternalSelectors(); - Selector GetSelector(const RecordData &Record, unsigned &Idx) { - return DecodeSelector(Record[Idx++]); + Selector ReadSelector(Module &M, const RecordData &Record, unsigned &Idx) { + return getLocalSelector(M, Record[Idx++]); } + + /// \brief Retrieve the global selector ID that corresponds to this + /// the local selector ID in a given module. + serialization::SelectorID getGlobalSelectorID(Module &F, + unsigned LocalID) const; /// \brief Read a declaration name. - DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx); - void ReadDeclarationNameLoc(PerFileData &F, + DeclarationName ReadDeclarationName(Module &F, + const RecordData &Record, unsigned &Idx); + void ReadDeclarationNameLoc(Module &F, DeclarationNameLoc &DNLoc, DeclarationName Name, const RecordData &Record, unsigned &Idx); - void ReadDeclarationNameInfo(PerFileData &F, DeclarationNameInfo &NameInfo, + void ReadDeclarationNameInfo(Module &F, DeclarationNameInfo &NameInfo, const RecordData &Record, unsigned &Idx); - void ReadQualifierInfo(PerFileData &F, QualifierInfo &Info, + void ReadQualifierInfo(Module &F, QualifierInfo &Info, const RecordData &Record, unsigned &Idx); - NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record, + NestedNameSpecifier *ReadNestedNameSpecifier(Module &F, + const RecordData &Record, unsigned &Idx); - NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(PerFileData &F, + NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(Module &F, const RecordData &Record, unsigned &Idx); /// \brief Read a template name. - TemplateName ReadTemplateName(PerFileData &F, const RecordData &Record, + TemplateName ReadTemplateName(Module &F, const RecordData &Record, unsigned &Idx); /// \brief Read a template argument. - TemplateArgument ReadTemplateArgument(PerFileData &F, + TemplateArgument ReadTemplateArgument(Module &F, const RecordData &Record,unsigned &Idx); /// \brief Read a template parameter list. - TemplateParameterList *ReadTemplateParameterList(PerFileData &F, + TemplateParameterList *ReadTemplateParameterList(Module &F, const RecordData &Record, unsigned &Idx); /// \brief Read a template argument array. void - ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs, - PerFileData &F, const RecordData &Record, + ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs, + Module &F, const RecordData &Record, unsigned &Idx); /// \brief Read a UnresolvedSet structure. - void ReadUnresolvedSet(UnresolvedSetImpl &Set, + void ReadUnresolvedSet(Module &F, UnresolvedSetImpl &Set, const RecordData &Record, unsigned &Idx); /// \brief Read a C++ base specifier. - CXXBaseSpecifier ReadCXXBaseSpecifier(PerFileData &F, + CXXBaseSpecifier ReadCXXBaseSpecifier(Module &F, const RecordData &Record,unsigned &Idx); /// \brief Read a CXXCtorInitializer array. std::pair<CXXCtorInitializer **, unsigned> - ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record, + ReadCXXCtorInitializers(Module &F, const RecordData &Record, unsigned &Idx); /// \brief Read a source location from raw form. - SourceLocation ReadSourceLocation(PerFileData &Module, unsigned Raw) { - (void)Module; // No remapping yet - return SourceLocation::getFromRawEncoding(Raw); + SourceLocation ReadSourceLocation(Module &Module, unsigned Raw) const { + SourceLocation Loc = SourceLocation::getFromRawEncoding(Raw); + assert(Module.SLocRemap.find(Loc.getOffset()) != Module.SLocRemap.end() && + "Cannot find offset to remap."); + int Remap = Module.SLocRemap.find(Loc.getOffset())->second; + return Loc.getLocWithOffset(Remap); } /// \brief Read a source location. - SourceLocation ReadSourceLocation(PerFileData &Module, + SourceLocation ReadSourceLocation(Module &Module, const RecordData &Record, unsigned& Idx) { return ReadSourceLocation(Module, Record[Idx++]); } /// \brief Read a source range. - SourceRange ReadSourceRange(PerFileData &F, + SourceRange ReadSourceRange(Module &F, const RecordData &Record, unsigned& Idx); /// \brief Read an integral value @@ -1250,17 +1201,18 @@ public: /// \brief Read a version tuple. VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx); - CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx); + CXXTemporary *ReadCXXTemporary(Module &F, const RecordData &Record, + unsigned &Idx); /// \brief Reads attributes from the current stream position. - void ReadAttributes(PerFileData &F, AttrVec &Attrs, + void ReadAttributes(Module &F, AttrVec &Attrs, const RecordData &Record, unsigned &Idx); /// \brief Reads a statement. - Stmt *ReadStmt(PerFileData &F); + Stmt *ReadStmt(Module &F); /// \brief Reads an expression. - Expr *ReadExpr(PerFileData &F); + Expr *ReadExpr(Module &F); /// \brief Reads a sub-statement operand during statement reading. Stmt *ReadSubStmt() { @@ -1276,15 +1228,16 @@ public: Expr *ReadSubExpr(); /// \brief Reads the macro record located at the given offset. - PreprocessedEntity *ReadMacroRecord(PerFileData &F, uint64_t Offset); - - /// \brief Reads the preprocessed entity located at the current stream - /// position. - PreprocessedEntity *LoadPreprocessedEntity(PerFileData &F); + void ReadMacroRecord(Module &F, uint64_t Offset); + /// \brief Determine the global preprocessed entity ID that corresponds to + /// the given local ID within the given module. + serialization::PreprocessedEntityID + getGlobalPreprocessedEntityID(Module &M, unsigned LocalID) const; + /// \brief Note that the identifier is a macro whose record will be loaded /// from the given AST file at the given (file-local) offset. - void SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F, + void SetIdentifierIsMacro(IdentifierInfo *II, Module &F, uint64_t Offset); /// \brief Read the set of macros defined by this external macro source. @@ -1297,16 +1250,13 @@ public: /// into the unread macro record offsets table. void LoadMacroDefinition( llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos); - - /// \brief Retrieve the macro definition with the given ID. - MacroDefinition *getMacroDefinition(serialization::MacroID ID); - + /// \brief Retrieve the AST context that this AST reader supplements. - ASTContext *getContext() { return Context; } + ASTContext &getContext() { return Context; } // \brief Contains declarations that were loaded before we have // access to a Sema object. - llvm::SmallVector<NamedDecl *, 16> PreloadedDecls; + SmallVector<NamedDecl *, 16> PreloadedDecls; /// \brief Retrieve the semantic analysis object used to analyze the /// translation unit in which the precompiled header is being diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTSerializationListener.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTSerializationListener.h deleted file mode 100644 index 0c62e0b..0000000 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTSerializationListener.h +++ /dev/null @@ -1,44 +0,0 @@ -//===- ASTSerializationListener.h - Decl/Type PCH Write Events -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ASTSerializationListener class, which is notified -// by the ASTWriter when an entity is serialized. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_FRONTEND_AST_SERIALIZATION_LISTENER_H -#define LLVM_CLANG_FRONTEND_AST_SERIALIZATION_LISTENER_H - -#include "llvm/Support/DataTypes.h" - -namespace clang { - -class PreprocessedEntity; - -/// \brief Listener object that receives callbacks when certain kinds of -/// entities are serialized. -class ASTSerializationListener { -public: - virtual ~ASTSerializationListener(); - - /// \brief Callback invoked whenever a preprocessed entity is serialized. - /// - /// This callback will only occur when the translation unit was created with - /// a detailed preprocessing record. - /// - /// \param Entity The entity that has been serialized. - /// - /// \param Offset The offset (in bits) of this entity in the resulting - /// AST file. - virtual void SerializedPreprocessedEntity(PreprocessedEntity *Entity, - uint64_t Offset) = 0; -}; - -} - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h index 18e1501..7a49e48 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h @@ -38,7 +38,6 @@ namespace llvm { namespace clang { class ASTContext; -class ASTSerializationListener; class NestedNameSpecifier; class CXXBaseSpecifier; class CXXCtorInitializer; @@ -67,20 +66,36 @@ class VersionTuple; class ASTWriter : public ASTDeserializationListener, public ASTMutationListener { public: - typedef llvm::SmallVector<uint64_t, 64> RecordData; - typedef llvm::SmallVectorImpl<uint64_t> RecordDataImpl; + typedef SmallVector<uint64_t, 64> RecordData; + typedef SmallVectorImpl<uint64_t> RecordDataImpl; friend class ASTDeclWriter; private: + /// \brief Map that provides the ID numbers of each type within the + /// output stream, plus those deserialized from a chained PCH. + /// + /// The ID numbers of types are consecutive (in order of discovery) + /// and start at 1. 0 is reserved for NULL. When types are actually + /// stored in the stream, the ID number is shifted by 2 bits to + /// allow for the const/volatile qualifiers. + /// + /// Keys in the map never have const/volatile qualifiers. + typedef llvm::DenseMap<QualType, serialization::TypeIdx, + serialization::UnsafeQualTypeDenseMapInfo> + TypeIdxMap; + /// \brief The bitstream writer used to emit this precompiled header. llvm::BitstreamWriter &Stream; + /// \brief The ASTContext we're writing. + ASTContext *Context; + /// \brief The reader of existing AST files, if we're chaining. ASTReader *Chain; - - /// \brief A listener object that receives notifications when certain - /// entities are serialized. - ASTSerializationListener *SerializationListener; + + /// \brief Indicates when the AST writing is actively performing + /// serialization, rather than just queueing updates. + bool WritingAST; /// \brief Stores a declaration or a type to be written to the AST file. class DeclOrType { @@ -142,7 +157,7 @@ private: /// allow for the const/volatile qualifiers. /// /// Keys in the map never have const/volatile qualifiers. - serialization::TypeIdxMap TypeIdxs; + TypeIdxMap TypeIdxs; /// \brief Offset of each type in the bitstream, indexed by /// the type's ID. @@ -189,23 +204,13 @@ private: /// \brief The set of identifiers that had macro definitions at some point. std::vector<const IdentifierInfo *> DeserializedMacroNames; - - /// \brief The first ID number we can use for our own macro definitions. - serialization::MacroID FirstMacroID; - - /// \brief The decl ID that will be assigned to the next new macro definition. - serialization::MacroID NextMacroID; /// \brief Mapping from macro definitions (as they occur in the preprocessing /// record) to the macro IDs. - llvm::DenseMap<const MacroDefinition *, serialization::MacroID> + llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID> MacroDefinitions; - - /// \brief Mapping from the macro definition indices in \c MacroDefinitions - /// to the corresponding offsets within the preprocessor block. - std::vector<uint32_t> MacroDefinitionOffsets; - typedef llvm::SmallVector<uint64_t, 2> UpdateRecord; + typedef SmallVector<uint64_t, 2> UpdateRecord; typedef llvm::DenseMap<const Decl *, UpdateRecord> DeclUpdateMap; /// \brief Mapping from declarations that came from a chained PCH to the /// record containing modifications to them. @@ -228,7 +233,7 @@ private: /// headers. The declarations themselves are stored as declaration /// IDs, since they will be written out to an EXTERNAL_DEFINITIONS /// record. - llvm::SmallVector<uint64_t, 16> ExternalDefinitions; + SmallVector<uint64_t, 16> ExternalDefinitions; /// \brief DeclContexts that have received extensions since their serialized /// form. @@ -242,22 +247,39 @@ private: /// \brief Decls that will be replaced in the current dependent AST file. DeclsToRewriteTy DeclsToRewrite; + struct ChainedObjCCategoriesData { + /// \brief The interface in the imported module. + const ObjCInterfaceDecl *Interface; + /// \brief The local tail category ID that got chained to the imported + /// interface. + const ObjCCategoryDecl *TailCategory; + + /// \brief ID corresponding to \c Interface. + serialization::DeclID InterfaceID; + + /// \brief ID corresponding to TailCategoryID. + serialization::DeclID TailCategoryID; + }; + /// \brief ObjC categories that got chained to an interface imported from + /// another module. + SmallVector<ChainedObjCCategoriesData, 16> LocalChainedObjCCategories; + /// \brief Decls that have been replaced in the current dependent AST file. /// /// When a decl changes fundamentally after being deserialized (this shouldn't /// happen, but the ObjC AST nodes are designed this way), it will be /// serialized again. In this case, it is registered here, so that the reader /// knows to read the updated version. - llvm::SmallVector<std::pair<serialization::DeclID, uint64_t>, 16> + SmallVector<std::pair<serialization::DeclID, uint64_t>, 16> ReplacedDecls; /// \brief Statements that we've encountered while serializing a /// declaration or type. - llvm::SmallVector<Stmt *, 16> StmtsToEmit; + SmallVector<Stmt *, 16> StmtsToEmit; /// \brief Statements collection to use for ASTWriter::AddStmt(). /// It will point to StmtsToEmit unless it is overriden. - llvm::SmallVector<Stmt *, 16> *CollectedStmts; + SmallVector<Stmt *, 16> *CollectedStmts; /// \brief Mapping from SwitchCase statements to IDs. std::map<SwitchCase *, unsigned> SwitchCaseIDs; @@ -280,7 +302,7 @@ private: unsigned NumVisibleDeclContexts; /// \brief The offset of each CXXBaseSpecifier set within the AST. - llvm::SmallVector<uint32_t, 4> CXXBaseSpecifiersOffsets; + SmallVector<uint32_t, 4> CXXBaseSpecifiersOffsets; /// \brief The first ID number we can use for our own base specifiers. serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID; @@ -306,23 +328,23 @@ private: /// \brief Queue of C++ base specifiers to be written to the AST file, /// in the order they should be written. - llvm::SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite; + SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite; /// \brief Write the given subexpression to the bitstream. void WriteSubStmt(Stmt *S); void WriteBlockInfoBlock(); - void WriteMetadata(ASTContext &Context, const char *isysroot, + void WriteMetadata(ASTContext &Context, StringRef isysroot, const std::string &OutputFile); void WriteLanguageOptions(const LangOptions &LangOpts); void WriteStatCache(MemorizeStatCalls &StatCalls); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP, - const char* isysroot); - void WritePreprocessor(const Preprocessor &PP); - void WriteHeaderSearch(HeaderSearch &HS, const char* isysroot); + StringRef isysroot); + void WritePreprocessor(const Preprocessor &PP, bool IsModule); + void WriteHeaderSearch(HeaderSearch &HS, StringRef isysroot); void WritePreprocessorDetail(PreprocessingRecord &PPRec); - void WritePragmaDiagnosticMappings(const Diagnostic &Diag); + void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag); void WriteCXXBaseSpecifiersOffsets(); void WriteType(QualType T); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); @@ -330,10 +352,13 @@ private: void WriteTypeDeclOffsets(); void WriteSelectors(Sema &SemaRef); void WriteReferencedSelectorsPool(Sema &SemaRef); - void WriteIdentifierTable(Preprocessor &PP); + void WriteIdentifierTable(Preprocessor &PP, bool IsModule); void WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record); + void ResolveDeclUpdatesBlocks(); void WriteDeclUpdatesBlocks(); void WriteDeclReplacementsBlock(); + void ResolveChainedObjCCategories(); + void WriteChainedObjCCategories(); void WriteDeclContextVisibleUpdate(const DeclContext *DC); void WriteFPPragmaOptions(const FPOptions &Opts); void WriteOpenCLExtensions(Sema &SemaRef); @@ -356,20 +381,13 @@ private: void WriteDecl(ASTContext &Context, Decl *D); void WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, - const char* isysroot, const std::string &OutputFile); - void WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, - const char* isysroot); + StringRef isysroot, const std::string &OutputFile, + bool IsModule); public: /// \brief Create a new precompiled header writer that outputs to /// the given bitstream. ASTWriter(llvm::BitstreamWriter &Stream); - - /// \brief Set the listener that will receive notification of serialization - /// events. - void SetSerializationListener(ASTSerializationListener *Listener) { - SerializationListener = Listener; - } /// \brief Write a precompiled header for the given semantic analysis. /// @@ -379,14 +397,14 @@ public: /// \param StatCalls the object that cached all of the stat() calls made while /// searching for source files and headers. /// - /// \param isysroot if non-NULL, write a relocatable PCH file whose headers - /// are relative to the given system root. + /// \param IsModule Whether we're writing a module (otherwise, we're writing a + /// precompiled header). /// - /// \param PPRec Record of the preprocessing actions that occurred while - /// preprocessing this file, e.g., macro expansions + /// \param isysroot if non-empty, write a relocatable file whose headers + /// are relative to the given system root. void WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, const std::string &OutputFile, - const char* isysroot); + bool IsModule, StringRef isysroot); /// \brief Emit a source location. void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record); @@ -432,10 +450,6 @@ public: "Identifier does not name a macro"); return MacroOffsets[II]; } - - /// \brief Retrieve the ID number corresponding to the given macro - /// definition. - serialization::MacroID getMacroDefinitionID(MacroDefinition *MD); /// \brief Emit a reference to a type. void AddTypeRef(QualType T, RecordDataImpl &Record); @@ -447,7 +461,7 @@ public: serialization::TypeID getTypeID(QualType T) const; /// \brief Force a type to be emitted and get its index. - serialization::TypeIdx GetOrCreateTypeIdx(QualType T); + serialization::TypeIdx GetOrCreateTypeIdx( QualType T); /// \brief Determine the type index of an already-emitted type. serialization::TypeIdx getTypeIdx(QualType T) const; @@ -523,7 +537,7 @@ public: void AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record); /// \brief Add a string to the given record. - void AddString(llvm::StringRef Str, RecordDataImpl &Record); + void AddString(StringRef Str, RecordDataImpl &Record); /// \brief Add a version tuple to the given record void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record); @@ -597,7 +611,8 @@ public: void TypeRead(serialization::TypeIdx Idx, QualType T); void DeclRead(serialization::DeclID ID, const Decl *D); void SelectorRead(serialization::SelectorID ID, Selector Sel); - void MacroDefinitionRead(serialization::MacroID ID, MacroDefinition *MD); + void MacroDefinitionRead(serialization::PreprocessedEntityID ID, + MacroDefinition *MD); // ASTMutationListener implementation. virtual void CompletedTagDefinition(const TagDecl *D); @@ -609,6 +624,8 @@ public: const FunctionDecl *D); virtual void CompletedImplicitDefinition(const FunctionDecl *D); virtual void StaticDataMemberInstantiated(const VarDecl *D); + virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, + const ObjCInterfaceDecl *IFD); }; /// \brief AST and semantic-analysis consumer that generates a @@ -616,26 +633,27 @@ public: class PCHGenerator : public SemaConsumer { const Preprocessor &PP; std::string OutputFile; - const char *isysroot; - llvm::raw_ostream *Out; + bool IsModule; + std::string isysroot; + raw_ostream *Out; Sema *SemaPtr; MemorizeStatCalls *StatCalls; // owned by the FileManager std::vector<unsigned char> Buffer; llvm::BitstreamWriter Stream; ASTWriter Writer; - bool Chaining; protected: ASTWriter &getWriter() { return Writer; } const ASTWriter &getWriter() const { return Writer; } public: - PCHGenerator(const Preprocessor &PP, const std::string &OutputFile, bool Chaining, - const char *isysroot, llvm::raw_ostream *Out); + PCHGenerator(const Preprocessor &PP, StringRef OutputFile, + bool IsModule, + StringRef isysroot, raw_ostream *Out); + ~PCHGenerator(); virtual void InitializeSema(Sema &S) { SemaPtr = &S; } virtual void HandleTranslationUnit(ASTContext &Ctx); virtual ASTMutationListener *GetASTMutationListener(); - virtual ASTSerializationListener *GetASTSerializationListener(); virtual ASTDeserializationListener *GetASTDeserializationListener(); }; diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ChainedIncludesSource.h b/contrib/llvm/tools/clang/include/clang/Serialization/ChainedIncludesSource.h index f547902..620dbdf 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ChainedIncludesSource.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ChainedIncludesSource.h @@ -46,10 +46,9 @@ protected: virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); virtual DeclContextLookupResult FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); - virtual void MaterializeVisibleDecls(const DeclContext *DC); virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), - llvm::SmallVectorImpl<Decl*> &Result); + SmallVectorImpl<Decl*> &Result); virtual void CompleteType(TagDecl *Tag); virtual void CompleteType(ObjCInterfaceDecl *Class); virtual void StartedDeserializing(); diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ContinuousRangeMap.h b/contrib/llvm/tools/clang/include/clang/Serialization/ContinuousRangeMap.h new file mode 100644 index 0000000..7f78320 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ContinuousRangeMap.h @@ -0,0 +1,120 @@ +//===--- ContinuousRangeMap.h - Map with int range as key -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ContinuousRangeMap class, which is a highly +// specialized container used by serialization. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H +#define LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H + +#include "llvm/ADT/SmallVector.h" +#include <algorithm> +#include <utility> + +namespace clang { + +/// \brief A map from continuous integer ranges to some value, with a very +/// specialized interface. +/// +/// CRM maps from integer ranges to values. The ranges are continuous, i.e. +/// where one ends, the next one begins. So if the map contains the stops I0-3, +/// the first range is from I0 to I1, the second from I1 to I2, the third from +/// I2 to I3 and the last from I3 to infinity. +/// +/// Ranges must be inserted in order. Inserting a new stop I4 into the map will +/// shrink the fourth range to I3 to I4 and add the new range I4 to inf. +template <typename Int, typename V, unsigned InitialCapacity> +class ContinuousRangeMap { +public: + typedef std::pair<Int, V> value_type; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef value_type *pointer; + typedef const value_type *const_pointer; + +private: + typedef SmallVector<value_type, InitialCapacity> Representation; + Representation Rep; + + struct Compare { + bool operator ()(const_reference L, Int R) const { + return L.first < R; + } + bool operator ()(Int L, const_reference R) const { + return L < R.first; + } + bool operator ()(Int L, Int R) const { + return L < R; + } + bool operator ()(const_reference L, const_reference R) const { + return L.first < R.first; + } + }; + +public: + void insert(const value_type &Val) { + if (!Rep.empty() && Rep.back() == Val) + return; + + assert((Rep.empty() || Rep.back().first < Val.first) && + "Must insert keys in order."); + Rep.push_back(Val); + } + + typedef typename Representation::iterator iterator; + typedef typename Representation::const_iterator const_iterator; + + iterator begin() { return Rep.begin(); } + iterator end() { return Rep.end(); } + const_iterator begin() const { return Rep.begin(); } + const_iterator end() const { return Rep.end(); } + + iterator find(Int K) { + iterator I = std::upper_bound(Rep.begin(), Rep.end(), K, Compare()); + // I points to the first entry with a key > K, which is the range that + // follows the one containing K. + if (I == Rep.begin()) + return Rep.end(); + --I; + return I; + } + const_iterator find(Int K) const { + return const_cast<ContinuousRangeMap*>(this)->find(K); + } + + reference back() { return Rep.back(); } + const_reference back() const { return Rep.back(); } + + /// \brief An object that helps properly build a continuous range map + /// from a set of values. + class Builder { + ContinuousRangeMap &Self; + + Builder(const Builder&); // DO NOT IMPLEMENT + Builder &operator=(const Builder&); // DO NOT IMPLEMENT + + public: + explicit Builder(ContinuousRangeMap &Self) : Self(Self) { } + + ~Builder() { + std::sort(Self.Rep.begin(), Self.Rep.end(), Compare()); + } + + void insert(const value_type &Val) { + Self.Rep.push_back(Val); + } + }; + friend class Builder; +}; + +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/Module.h b/contrib/llvm/tools/clang/include/clang/Serialization/Module.h new file mode 100644 index 0000000..42b5a58 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Serialization/Module.h @@ -0,0 +1,319 @@ +//===--- Module.h - Module description --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the Module class, which describes a module that has +// been loaded from an AST file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H +#define LLVM_CLANG_SERIALIZATION_MODULE_H + +#include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include <string> + +namespace clang { + +class DeclContext; + +namespace serialization { + +/// \brief Specifies the kind of module that has been loaded. +enum ModuleKind { + MK_Module, ///< File is a module proper. + MK_PCH, ///< File is a PCH file treated as such. + MK_Preamble, ///< File is a PCH file treated as the preamble. + MK_MainFile ///< File is a PCH file treated as the actual main file. +}; + +/// \brief Information about the contents of a DeclContext. +struct DeclContextInfo { + DeclContextInfo() + : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {} + + void *NameLookupTableData; // an ASTDeclContextNameLookupTable. + const KindDeclIDPair *LexicalDecls; + unsigned NumLexicalDecls; +}; + +/// \brief Information about a module that has been loaded by the ASTReader. +/// +/// Each instance of the Module class corresponds to a single AST file, which +/// may be a precompiled header, precompiled preamble, a module, or an AST file +/// of some sort loaded as the main file, all of which are specific formulations of +/// the general notion of a "module". A module may depend on any number of +/// other modules. +class Module { +public: + Module(ModuleKind Kind); + ~Module(); + + // === General information === + + /// \brief The type of this module. + ModuleKind Kind; + + /// \brief The file name of the module file. + std::string FileName; + + /// \brief Whether this module has been directly imported by the + /// user. + bool DirectlyImported; + + /// \brief The memory buffer that stores the data associated with + /// this AST file. + llvm::OwningPtr<llvm::MemoryBuffer> Buffer; + + /// \brief The size of this file, in bits. + uint64_t SizeInBits; + + /// \brief The global bit offset (or base) of this module + uint64_t GlobalBitOffset; + + /// \brief The bitstream reader from which we'll read the AST file. + llvm::BitstreamReader StreamFile; + + /// \brief The main bitstream cursor for the main block. + llvm::BitstreamCursor Stream; + + /// \brief The source location where this module was first imported. + SourceLocation ImportLoc; + + /// \brief The first source location in this module. + SourceLocation FirstLoc; + + // === Source Locations === + + /// \brief Cursor used to read source location entries. + llvm::BitstreamCursor SLocEntryCursor; + + /// \brief The number of source location entries in this AST file. + unsigned LocalNumSLocEntries; + + /// \brief The base ID in the source manager's view of this module. + int SLocEntryBaseID; + + /// \brief The base offset in the source manager's view of this module. + unsigned SLocEntryBaseOffset; + + /// \brief Offsets for all of the source location entries in the + /// AST file. + const uint32_t *SLocEntryOffsets; + + /// \brief SLocEntries that we're going to preload. + SmallVector<uint64_t, 4> PreloadSLocEntries; + + /// \brief The number of source location file entries in this AST file. + unsigned LocalNumSLocFileEntries; + + /// \brief Offsets for all of the source location file entries in the + /// AST file. + const uint32_t *SLocFileOffsets; + + /// \brief Remapping table for source locations in this module. + ContinuousRangeMap<uint32_t, int, 2> SLocRemap; + + // === Identifiers === + + /// \brief The number of identifiers in this AST file. + unsigned LocalNumIdentifiers; + + /// \brief Offsets into the identifier table data. + /// + /// This array is indexed by the identifier ID (-1), and provides + /// the offset into IdentifierTableData where the string data is + /// stored. + const uint32_t *IdentifierOffsets; + + /// \brief Base identifier ID for identifiers local to this module. + serialization::IdentID BaseIdentifierID; + + /// \brief Remapping table for identifier IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap; + + /// \brief Actual data for the on-disk hash table of identifiers. + /// + /// This pointer points into a memory buffer, where the on-disk hash + /// table for identifiers actually lives. + const char *IdentifierTableData; + + /// \brief A pointer to an on-disk hash table of opaque type + /// IdentifierHashTable. + void *IdentifierLookupTable; + + // === Macros === + + /// \brief The cursor to the start of the preprocessor block, which stores + /// all of the macro definitions. + llvm::BitstreamCursor MacroCursor; + + /// \brief The offset of the start of the set of defined macros. + uint64_t MacroStartOffset; + + // === Detailed PreprocessingRecord === + + /// \brief The cursor to the start of the (optional) detailed preprocessing + /// record block. + llvm::BitstreamCursor PreprocessorDetailCursor; + + /// \brief The offset of the start of the preprocessor detail cursor. + uint64_t PreprocessorDetailStartOffset; + + /// \brief Base preprocessed entity ID for preprocessed entities local to + /// this module. + serialization::PreprocessedEntityID BasePreprocessedEntityID; + + /// \brief Remapping table for preprocessed entity IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap; + + const PPEntityOffset *PreprocessedEntityOffsets; + unsigned NumPreprocessedEntities; + + // === Header search information === + + /// \brief The number of local HeaderFileInfo structures. + unsigned LocalNumHeaderFileInfos; + + /// \brief Actual data for the on-disk hash table of header file + /// information. + /// + /// This pointer points into a memory buffer, where the on-disk hash + /// table for header file information actually lives. + const char *HeaderFileInfoTableData; + + /// \brief The on-disk hash table that contains information about each of + /// the header files. + void *HeaderFileInfoTable; + + /// \brief Actual data for the list of framework names used in the header + /// search information. + const char *HeaderFileFrameworkStrings; + + // === Selectors === + + /// \brief The number of selectors new to this file. + /// + /// This is the number of entries in SelectorOffsets. + unsigned LocalNumSelectors; + + /// \brief Offsets into the selector lookup table's data array + /// where each selector resides. + const uint32_t *SelectorOffsets; + + /// \brief Base selector ID for selectors local to this module. + serialization::SelectorID BaseSelectorID; + + /// \brief Remapping table for selector IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> SelectorRemap; + + /// \brief A pointer to the character data that comprises the selector table + /// + /// The SelectorOffsets table refers into this memory. + const unsigned char *SelectorLookupTableData; + + /// \brief A pointer to an on-disk hash table of opaque type + /// ASTSelectorLookupTable. + /// + /// This hash table provides the IDs of all selectors, and the associated + /// instance and factory methods. + void *SelectorLookupTable; + + // === Declarations === + + /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It + /// has read all the abbreviations at the start of the block and is ready to + /// jump around with these in context. + llvm::BitstreamCursor DeclsCursor; + + /// \brief The number of declarations in this AST file. + unsigned LocalNumDecls; + + /// \brief Offset of each declaration within the bitstream, indexed + /// by the declaration ID (-1). + const uint32_t *DeclOffsets; + + /// \brief Base declaration ID for declarations local to this module. + serialization::DeclID BaseDeclID; + + /// \brief Remapping table for declaration IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> DeclRemap; + + /// \brief The number of C++ base specifier sets in this AST file. + unsigned LocalNumCXXBaseSpecifiers; + + /// \brief Offset of each C++ base specifier set within the bitstream, + /// indexed by the C++ base specifier set ID (-1). + const uint32_t *CXXBaseSpecifiersOffsets; + + typedef llvm::DenseMap<const DeclContext *, DeclContextInfo> + DeclContextInfosMap; + + /// \brief Information about the lexical and visible declarations + /// for each DeclContext. + DeclContextInfosMap DeclContextInfos; + + typedef llvm::DenseMap<serialization::GlobalDeclID, + std::pair<serialization::LocalDeclID, serialization::LocalDeclID> > + ChainedObjCCategoriesMap; + /// \brief ObjC categories that got chained to an interface from another + /// module. + /// Key is the ID of the interface. + /// Value is a pair of linked category DeclIDs (head category, tail category). + ChainedObjCCategoriesMap ChainedObjCCategories; + + // === Types === + + /// \brief The number of types in this AST file. + unsigned LocalNumTypes; + + /// \brief Offset of each type within the bitstream, indexed by the + /// type ID, or the representation of a Type*. + const uint32_t *TypeOffsets; + + /// \brief Base type ID for types local to this module as represented in + /// the global type ID space. + serialization::TypeID BaseTypeIndex; + + /// \brief Remapping table for type IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> TypeRemap; + + // === Miscellaneous === + + /// \brief Diagnostic IDs and their mappings that the user changed. + SmallVector<uint64_t, 8> PragmaDiagMappings; + + /// \brief The AST stat cache installed for this file, if any. + /// + /// The dynamic type of this stat cache is always ASTStatCache + void *StatCache; + + /// \brief List of modules which depend on this module + llvm::SetVector<Module *> ImportedBy; + + /// \brief List of modules which this module depends on + llvm::SetVector<Module *> Imports; + + /// \brief Determine whether this module was directly imported at + /// any point during translation. + bool isDirectlyImported() const { return DirectlyImported; } + + /// \brief Dump debugging output for this module. + void dump(); +}; + +} // end namespace serialization + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h new file mode 100644 index 0000000..f86915a --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h @@ -0,0 +1,156 @@ +//===--- ModuleManager.cpp - Module Manager ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ModuleManager class, which manages a set of loaded +// modules for the ASTReader. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H +#define LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H + +#include "clang/Serialization/Module.h" +#include "clang/Basic/FileManager.h" +#include "llvm/ADT/DenseMap.h" + +namespace clang { + +namespace serialization { + +/// \brief Manages the set of modules loaded by an AST reader. +class ModuleManager { + /// \brief The chain of AST files. The first entry is the one named by the + /// user, the last one is the one that doesn't depend on anything further. + llvm::SmallVector<Module*, 2> Chain; + + /// \brief All loaded modules, indexed by name. + llvm::DenseMap<const FileEntry *, Module *> Modules; + + /// \brief FileManager that handles translating between filenames and + /// FileEntry *. + FileManager FileMgr; + + /// \brief A lookup of in-memory (virtual file) buffers + llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers; + +public: + typedef SmallVector<Module*, 2>::iterator ModuleIterator; + typedef SmallVector<Module*, 2>::const_iterator ModuleConstIterator; + typedef SmallVector<Module*, 2>::reverse_iterator ModuleReverseIterator; + typedef std::pair<uint32_t, StringRef> ModuleOffset; + + ModuleManager(const FileSystemOptions &FSO); + ~ModuleManager(); + + /// \brief Forward iterator to traverse all loaded modules. This is reverse + /// source-order. + ModuleIterator begin() { return Chain.begin(); } + /// \brief Forward iterator end-point to traverse all loaded modules + ModuleIterator end() { return Chain.end(); } + + /// \brief Const forward iterator to traverse all loaded modules. This is + /// in reverse source-order. + ModuleConstIterator begin() const { return Chain.begin(); } + /// \brief Const forward iterator end-point to traverse all loaded modules + ModuleConstIterator end() const { return Chain.end(); } + + /// \brief Reverse iterator to traverse all loaded modules. This is in + /// source order. + ModuleReverseIterator rbegin() { return Chain.rbegin(); } + /// \brief Reverse iterator end-point to traverse all loaded modules. + ModuleReverseIterator rend() { return Chain.rend(); } + + /// \brief Returns the primary module associated with the manager, that is, + /// the first module loaded + Module &getPrimaryModule() { return *Chain[0]; } + + /// \brief Returns the primary module associated with the manager, that is, + /// the first module loaded. + Module &getPrimaryModule() const { return *Chain[0]; } + + /// \brief Returns the module associated with the given index + Module &operator[](unsigned Index) const { return *Chain[Index]; } + + /// \brief Returns the module associated with the given name + Module *lookup(StringRef Name); + + /// \brief Returns the in-memory (virtual file) buffer with the given name + llvm::MemoryBuffer *lookupBuffer(StringRef Name); + + /// \brief Number of modules loaded + unsigned size() const { return Chain.size(); } + /// \brief Attempts to create a new module and add it to the list of known + /// modules. + /// + /// \param FileName The file name of the module to be loaded. + /// + /// \param Type The kind of module being loaded. + /// + /// \param ImportedBy The module that is importing this module, or NULL if + /// this module is imported directly by the user. + /// + /// \param ErrorStr Will be set to a non-empty string if any errors occurred + /// while trying to load the module. + /// + /// \return A pointer to the module that corresponds to this file name, + /// and a boolean indicating whether the module was newly added. + std::pair<Module *, bool> + addModule(StringRef FileName, ModuleKind Type, Module *ImportedBy, + std::string &ErrorStr); + + /// \brief Add an in-memory buffer the list of known buffers + void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer); + + /// \brief Visit each of the modules. + /// + /// This routine visits each of the modules, starting with the + /// "root" modules that no other loaded modules depend on, and + /// proceeding to the leaf modules, visiting each module only once + /// during the traversal. + /// + /// This traversal is intended to support various "lookup" + /// operations that can find data in any of the loaded modules. + /// + /// \param Visitor A visitor function that will be invoked with each + /// module and the given user data pointer. The return value must be + /// convertible to bool; when false, the visitation continues to + /// modules that the current module depends on. When true, the + /// visitation skips any modules that the current module depends on. + /// + /// \param UserData User data associated with the visitor object, which + /// will be passed along to the visitor. + void visit(bool (*Visitor)(Module &M, void *UserData), void *UserData); + + /// \brief Visit each of the modules with a depth-first traversal. + /// + /// This routine visits each of the modules known to the module + /// manager using a depth-first search, starting with the first + /// loaded module. The traversal invokes the callback both before + /// traversing the children (preorder traversal) and after + /// traversing the children (postorder traversal). + /// + /// \param Visitor A visitor function that will be invoked with each + /// module and given a \c Preorder flag that indicates whether we're + /// visiting the module before or after visiting its children. The + /// visitor may return true at any time to abort the depth-first + /// visitation. + /// + /// \param UserData User data ssociated with the visitor object, + /// which will be passed along to the user. + void visitDepthFirst(bool (*Visitor)(Module &M, bool Preorder, + void *UserData), + void *UserData); + + /// \brief View the graphviz representation of the module graph. + void viewGraph(); +}; + +} } // end namespace clang::serialization + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h new file mode 100644 index 0000000..cf0a30a --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h @@ -0,0 +1,22 @@ +//===--- ClangCheckers.h - Provides builtin checkers ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H +#define LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H + +namespace clang { +namespace ento { +class CheckerRegistry; + +void registerBuiltinCheckers(CheckerRegistry ®istry); + +} // end namespace ento +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h index 2a3d43e..eee38e9 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h @@ -16,33 +16,13 @@ #define LLVM_CLANG_GR_LOCALCHECKERS_H namespace clang { - -class CFG; -class Decl; -class Diagnostic; -class ASTContext; -class LangOptions; -class ParentMap; -class LiveVariables; -class ObjCImplementationDecl; -class LangOptions; -class TranslationUnitDecl; - namespace ento { -class PathDiagnosticClient; -class TransferFuncs; -class BugType; -class BugReporter; class ExprEngine; -TransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled, - const LangOptions& lopts); - void RegisterCallInliner(ExprEngine &Eng); -} // end GR namespace - +} // end namespace ento } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 3acbcd6..bfb7ef8 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file defines BugReporter, a utility class for generating -// PathDiagnostics for analyses based on GRState. +// PathDiagnostics for analyses based on ProgramState. // //===----------------------------------------------------------------------===// @@ -16,7 +16,9 @@ #define LLVM_CLANG_GR_BUGREPORTER #include "clang/Basic/SourceLocation.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h" +#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableList.h" #include "llvm/ADT/ImmutableSet.h" @@ -26,121 +28,138 @@ namespace clang { class ASTContext; -class Diagnostic; +class DiagnosticsEngine; class Stmt; class ParentMap; namespace ento { class PathDiagnostic; -class PathDiagnosticPiece; -class PathDiagnosticClient; class ExplodedNode; class ExplodedGraph; +class BugReport; class BugReporter; class BugReporterContext; class ExprEngine; -class GRState; class BugType; //===----------------------------------------------------------------------===// // Interface for individual bug reports. //===----------------------------------------------------------------------===// -class BugReporterVisitor : public llvm::FoldingSetNode { +/// This class provides an interface through which checkers can create +/// individual bug reports. +class BugReport { public: - virtual ~BugReporterVisitor(); - virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N, - const ExplodedNode* PrevN, - BugReporterContext& BRC) = 0; + class NodeResolver { + public: + virtual ~NodeResolver() {} + virtual const ExplodedNode* + getOriginalNode(const ExplodedNode *N) = 0; + }; - virtual bool isOwnedByReporterContext() { return true; } - virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0; -}; + typedef const SourceRange *ranges_iterator; + typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator; + typedef SmallVector<StringRef, 2> ExtraTextList; -// FIXME: Combine this with RangedBugReport and remove RangedBugReport. -class BugReport : public BugReporterVisitor { protected: + friend class BugReporter; + friend class BugReportEquivClass; + BugType& BT; std::string ShortDescription; std::string Description; + PathDiagnosticLocation Location; const ExplodedNode *ErrorNode; - mutable SourceRange R; - -protected: - friend class BugReporter; - friend class BugReportEquivClass; + SmallVector<SourceRange, 4> Ranges; + ExtraTextList ExtraText; - virtual void Profile(llvm::FoldingSetNodeID& hash) const { - hash.AddPointer(&BT); - hash.AddInteger(getLocation().getRawEncoding()); - hash.AddString(Description); - } + // Not the most efficient data structure, but we use an ImmutableList for the + // Callbacks because it is safe to make additions to list during iteration. + llvm::ImmutableList<BugReporterVisitor*>::Factory F; + llvm::ImmutableList<BugReporterVisitor*> Callbacks; + llvm::FoldingSet<BugReporterVisitor> CallbacksSet; public: - class NodeResolver { - public: - virtual ~NodeResolver() {} - virtual const ExplodedNode* - getOriginalNode(const ExplodedNode* N) = 0; - }; - - BugReport(BugType& bt, llvm::StringRef desc, const ExplodedNode *errornode) - : BT(bt), Description(desc), ErrorNode(errornode) {} + BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode) + : BT(bt), Description(desc), ErrorNode(errornode), + Callbacks(F.getEmptyList()) {} - BugReport(BugType& bt, llvm::StringRef shortDesc, llvm::StringRef desc, + BugReport(BugType& bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errornode) - : BT(bt), ShortDescription(shortDesc), Description(desc), - ErrorNode(errornode) {} + : BT(bt), ShortDescription(shortDesc), Description(desc), + ErrorNode(errornode), Callbacks(F.getEmptyList()) {} - virtual ~BugReport(); + BugReport(BugType& bt, StringRef desc, PathDiagnosticLocation l) + : BT(bt), Description(desc), Location(l), ErrorNode(0), + Callbacks(F.getEmptyList()) {} - virtual bool isOwnedByReporterContext() { return false; } + virtual ~BugReport(); const BugType& getBugType() const { return BT; } BugType& getBugType() { return BT; } - // FIXME: Perhaps this should be moved into a subclass? - const ExplodedNode* getErrorNode() const { return ErrorNode; } - - // FIXME: Do we need this? Maybe getLocation() should return a ProgramPoint - // object. - // FIXME: If we do need it, we can probably just make it private to - // BugReporter. - const Stmt* getStmt() const; + const ExplodedNode *getErrorNode() const { return ErrorNode; } - const llvm::StringRef getDescription() const { return Description; } + const StringRef getDescription() const { return Description; } - const llvm::StringRef getShortDescription() const { + const StringRef getShortDescription() const { return ShortDescription.empty() ? Description : ShortDescription; } - // FIXME: Is this needed? - virtual std::pair<const char**,const char**> getExtraDescriptiveText() { - return std::make_pair((const char**)0,(const char**)0); + /// \brief This allows for addition of meta data to the diagnostic. + /// + /// Currently, only the HTMLDiagnosticClient knows how to display it. + void addExtraText(StringRef S) { + ExtraText.push_back(S); } - // FIXME: Perhaps move this into a subclass. - virtual PathDiagnosticPiece* getEndPath(BugReporterContext& BRC, - const ExplodedNode* N); + virtual const ExtraTextList &getExtraText() { + return ExtraText; + } - /// getLocation - Return the "definitive" location of the reported bug. + /// \brief Return the "definitive" location of the reported bug. + /// /// While a bug can span an entire path, usually there is a specific /// location that can be used to identify where the key issue occurred. /// This location is used by clients rendering diagnostics. - virtual SourceLocation getLocation() const; + virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const; - typedef const SourceRange *ranges_iterator; + const Stmt *getStmt() const; + + /// \brief Add a range to a bug report. + /// + /// Ranges are used to highlight regions of interest in the source code. + /// They should be at the same source code line as the BugReport location. + /// By default, the source range of the statement corresponding to the error + /// node will be used; add a single invalid range to specify absence of + /// ranges. + void addRange(SourceRange R) { + assert((R.isValid() || Ranges.empty()) && "Invalid range can only be used " + "to specify that the report does not have a range."); + Ranges.push_back(R); + } - /// getRanges - Returns the source ranges associated with this bug. - virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const; + /// \brief Get the SourceRanges associated with the report. + virtual std::pair<ranges_iterator, ranges_iterator> getRanges(); - virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N, - const ExplodedNode* PrevN, - BugReporterContext& BR); + /// \brief Add custom or predefined bug report visitors to this report. + /// + /// The visitors should be used when the default trace is not sufficient. + /// For example, they allow constructing a more elaborate trace. + /// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(), + /// registerFindLastStore(), registerNilReceiverVisitor(), and + /// registerVarDeclsLastStore(). + void addVisitor(BugReporterVisitor *visitor); - virtual void registerInitialVisitors(BugReporterContext& BRC, - const ExplodedNode* N) {} + /// Iterators through the custom diagnostic visitors. + visitor_iterator visitor_begin() { return Callbacks.begin(); } + visitor_iterator visitor_end() { return Callbacks.end(); } + + /// Profile to identify equivalent bug reports for error report coalescing. + /// Reports are uniqued to ensure that we do not emit multiple diagnostics + /// for each bug. + virtual void Profile(llvm::FoldingSetNodeID& hash) const; }; //===----------------------------------------------------------------------===// @@ -148,7 +167,7 @@ public: //===----------------------------------------------------------------------===// class BugReportEquivClass : public llvm::FoldingSetNode { - // List of *owned* BugReport objects. + /// List of *owned* BugReport objects. std::list<BugReport*> Reports; friend class BugReporter; @@ -166,9 +185,9 @@ public: std::list<BugReport*>::iterator impl; public: iterator(std::list<BugReport*>::iterator i) : impl(i) {} - iterator& operator++() { ++impl; return *this; } - bool operator==(const iterator& I) const { return I.impl == impl; } - bool operator!=(const iterator& I) const { return I.impl != impl; } + iterator &operator++() { ++impl; return *this; } + bool operator==(const iterator &I) const { return I.impl == impl; } + bool operator!=(const iterator &I) const { return I.impl != impl; } BugReport* operator*() const { return *impl; } BugReport* operator->() const { return *impl; } }; @@ -177,9 +196,9 @@ public: std::list<BugReport*>::const_iterator impl; public: const_iterator(std::list<BugReport*>::const_iterator i) : impl(i) {} - const_iterator& operator++() { ++impl; return *this; } - bool operator==(const const_iterator& I) const { return I.impl == impl; } - bool operator!=(const const_iterator& I) const { return I.impl != impl; } + const_iterator &operator++() { ++impl; return *this; } + bool operator==(const const_iterator &I) const { return I.impl == impl; } + bool operator!=(const const_iterator &I) const { return I.impl != impl; } const BugReport* operator*() const { return *impl; } const BugReport* operator->() const { return *impl; } }; @@ -191,78 +210,6 @@ public: const_iterator end() const { return const_iterator(Reports.end()); } }; - -//===----------------------------------------------------------------------===// -// Specialized subclasses of BugReport. -//===----------------------------------------------------------------------===// - -// FIXME: Collapse this with the default BugReport class. -class RangedBugReport : public BugReport { - llvm::SmallVector<SourceRange, 4> Ranges; -public: - RangedBugReport(BugType& D, llvm::StringRef description, - ExplodedNode *errornode) - : BugReport(D, description, errornode) {} - - RangedBugReport(BugType& D, llvm::StringRef shortDescription, - llvm::StringRef description, ExplodedNode *errornode) - : BugReport(D, shortDescription, description, errornode) {} - - ~RangedBugReport(); - - // FIXME: Move this out of line. - void addRange(SourceRange R) { - assert(R.isValid()); - Ranges.push_back(R); - } - - virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const { - return std::make_pair(Ranges.begin(), Ranges.end()); - } - - virtual void Profile(llvm::FoldingSetNodeID& hash) const { - BugReport::Profile(hash); - for (llvm::SmallVectorImpl<SourceRange>::const_iterator I = - Ranges.begin(), E = Ranges.end(); I != E; ++I) { - const SourceRange range = *I; - if (!range.isValid()) - continue; - hash.AddInteger(range.getBegin().getRawEncoding()); - hash.AddInteger(range.getEnd().getRawEncoding()); - } - } -}; - -class EnhancedBugReport : public RangedBugReport { -public: - typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data, - const ExplodedNode *N); - -private: - typedef std::vector<std::pair<VisitorCreator, const void*> > Creators; - Creators creators; - -public: - EnhancedBugReport(BugType& D, llvm::StringRef description, - ExplodedNode *errornode) - : RangedBugReport(D, description, errornode) {} - - EnhancedBugReport(BugType& D, llvm::StringRef shortDescription, - llvm::StringRef description, ExplodedNode *errornode) - : RangedBugReport(D, shortDescription, description, errornode) {} - - ~EnhancedBugReport() {} - - void registerInitialVisitors(BugReporterContext& BRC, const ExplodedNode* N) { - for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I) - I->first(BRC, I->second, N); - } - - void addVisitorCreator(VisitorCreator creator, const void *data) { - creators.push_back(std::make_pair(creator, data)); - } -}; - //===----------------------------------------------------------------------===// // BugReporter and friends. //===----------------------------------------------------------------------===// @@ -270,12 +217,15 @@ public: class BugReporterData { public: virtual ~BugReporterData(); - virtual Diagnostic& getDiagnostic() = 0; - virtual PathDiagnosticClient* getPathDiagnosticClient() = 0; - virtual ASTContext& getASTContext() = 0; + virtual DiagnosticsEngine& getDiagnostic() = 0; + virtual PathDiagnosticConsumer* getPathDiagnosticConsumer() = 0; + virtual ASTContext &getASTContext() = 0; virtual SourceManager& getSourceManager() = 0; }; +/// BugReporter is a utility class for generating PathDiagnostics for analysis. +/// It collects the BugReports and BugTypes and knows how to generate +/// and flush the corresponding diagnostics. class BugReporter { public: enum Kind { BaseBRKind, GRBugReporterKind }; @@ -288,9 +238,13 @@ private: const Kind kind; BugReporterData& D; + /// Generate and flush the diagnostics for the given bug report. void FlushReport(BugReportEquivClass& EQ); + /// The set of bug reports tracked by the BugReporter. llvm::FoldingSet<BugReportEquivClass> EQClasses; + /// A vector of BugReports for tracking the allocated pointers and cleanup. + std::vector<BugReportEquivClass *> EQClassesVector; protected: BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k), @@ -301,63 +255,71 @@ public: D(d) {} virtual ~BugReporter(); + /// \brief Generate and flush diagnostics for all bug reports. void FlushReports(); Kind getKind() const { return kind; } - Diagnostic& getDiagnostic() { + DiagnosticsEngine& getDiagnostic() { return D.getDiagnostic(); } - PathDiagnosticClient* getPathDiagnosticClient() { - return D.getPathDiagnosticClient(); + PathDiagnosticConsumer* getPathDiagnosticConsumer() { + return D.getPathDiagnosticConsumer(); } + /// \brief Iterator over the set of BugTypes tracked by the BugReporter. typedef BugTypesTy::iterator iterator; iterator begin() { return BugTypes.begin(); } iterator end() { return BugTypes.end(); } + /// \brief Iterator over the set of BugReports tracked by the BugReporter. typedef llvm::FoldingSet<BugReportEquivClass>::iterator EQClasses_iterator; EQClasses_iterator EQClasses_begin() { return EQClasses.begin(); } EQClasses_iterator EQClasses_end() { return EQClasses.end(); } - ASTContext& getContext() { return D.getASTContext(); } + ASTContext &getContext() { return D.getASTContext(); } SourceManager& getSourceManager() { return D.getSourceManager(); } virtual void GeneratePathDiagnostic(PathDiagnostic& pathDiagnostic, - llvm::SmallVectorImpl<BugReport *> &bugReports) {} + SmallVectorImpl<BugReport *> &bugReports) {} void Register(BugType *BT); + /// \brief Add the given report to the set of reports tracked by BugReporter. + /// + /// The reports are usually generated by the checkers. Further, they are + /// folded based on the profile value, which is done to coalesce similar + /// reports. void EmitReport(BugReport *R); - void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr, - SourceLocation Loc, + void EmitBasicReport(StringRef BugName, StringRef BugStr, + PathDiagnosticLocation Loc, SourceRange* RangeBeg, unsigned NumRanges); - void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory, - llvm::StringRef BugStr, SourceLocation Loc, + void EmitBasicReport(StringRef BugName, StringRef BugCategory, + StringRef BugStr, PathDiagnosticLocation Loc, SourceRange* RangeBeg, unsigned NumRanges); - void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr, - SourceLocation Loc) { + void EmitBasicReport(StringRef BugName, StringRef BugStr, + PathDiagnosticLocation Loc) { EmitBasicReport(BugName, BugStr, Loc, 0, 0); } - void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory, - llvm::StringRef BugStr, SourceLocation Loc) { + void EmitBasicReport(StringRef BugName, StringRef BugCategory, + StringRef BugStr, PathDiagnosticLocation Loc) { EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0); } - void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr, - SourceLocation Loc, SourceRange R) { + void EmitBasicReport(StringRef BugName, StringRef BugStr, + PathDiagnosticLocation Loc, SourceRange R) { EmitBasicReport(BugName, BugStr, Loc, &R, 1); } - void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef Category, - llvm::StringRef BugStr, SourceLocation Loc, + void EmitBasicReport(StringRef BugName, StringRef Category, + StringRef BugStr, PathDiagnosticLocation Loc, SourceRange R) { EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1); } @@ -369,7 +331,7 @@ private: /// \brief Returns a BugType that is associated with the given name and /// category. - BugType *getBugTypeForName(llvm::StringRef name, llvm::StringRef category); + BugType *getBugTypeForName(StringRef name, StringRef category); }; // FIXME: Get rid of GRBugReporter. It's the wrong abstraction. @@ -392,10 +354,10 @@ public: /// getStateManager - Return the state manager used by the analysis /// engine. - GRStateManager &getStateManager(); + ProgramStateManager &getStateManager(); virtual void GeneratePathDiagnostic(PathDiagnostic &pathDiagnostic, - llvm::SmallVectorImpl<BugReport*> &bugReports); + SmallVectorImpl<BugReport*> &bugReports); void addNotableSymbol(SymbolRef Sym) { NotableSymbols.insert(Sym); @@ -413,20 +375,10 @@ public: class BugReporterContext { GRBugReporter &BR; - // Not the most efficient data structure, but we use an ImmutableList for the - // Callbacks because it is safe to make additions to list during iteration. - llvm::ImmutableList<BugReporterVisitor*>::Factory F; - llvm::ImmutableList<BugReporterVisitor*> Callbacks; - llvm::FoldingSet<BugReporterVisitor> CallbacksSet; public: - BugReporterContext(GRBugReporter& br) : BR(br), Callbacks(F.getEmptyList()) {} - virtual ~BugReporterContext(); - - void addVisitor(BugReporterVisitor* visitor); + BugReporterContext(GRBugReporter& br) : BR(br) {} - typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator; - visitor_iterator visitor_begin() { return Callbacks.begin(); } - visitor_iterator visitor_end() { return Callbacks.end(); } + virtual ~BugReporterContext() {} GRBugReporter& getBugReporter() { return BR; } @@ -442,7 +394,7 @@ public: return BR.isNotable(Sym); } - GRStateManager& getStateManager() { + ProgramStateManager& getStateManager() { return BR.getStateManager(); } @@ -450,7 +402,7 @@ public: return getStateManager().getSValBuilder(); } - ASTContext& getASTContext() { + ASTContext &getASTContext() { return BR.getContext(); } @@ -461,50 +413,6 @@ public: virtual BugReport::NodeResolver& getNodeResolver() = 0; }; -class DiagBugReport : public RangedBugReport { - std::list<std::string> Strs; - FullSourceLoc L; -public: - DiagBugReport(BugType& D, llvm::StringRef desc, FullSourceLoc l) : - RangedBugReport(D, desc, 0), L(l) {} - - virtual ~DiagBugReport() {} - - // FIXME: Move out-of-line (virtual function). - SourceLocation getLocation() const { return L; } - - void addString(llvm::StringRef s) { Strs.push_back(s); } - - typedef std::list<std::string>::const_iterator str_iterator; - str_iterator str_begin() const { return Strs.begin(); } - str_iterator str_end() const { return Strs.end(); } -}; - -//===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// - -namespace bugreporter { - -const Stmt *GetDerefExpr(const ExplodedNode *N); -const Stmt *GetDenomExpr(const ExplodedNode *N); -const Stmt *GetCalleeExpr(const ExplodedNode *N); -const Stmt *GetRetValExpr(const ExplodedNode *N); - -void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt, - const ExplodedNode* N); - -void registerFindLastStore(BugReporterContext& BRC, const void *memregion, - const ExplodedNode *N); - -void registerNilReceiverVisitor(BugReporterContext &BRC); - -void registerVarDeclsLastStore(BugReporterContext &BRC, const void *stmt, - const ExplodedNode *N); - -} // end namespace clang::bugreporter - -//===----------------------------------------------------------------------===// - } // end GR namespace } // end clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h new file mode 100644 index 0000000..41c0a3a --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -0,0 +1,183 @@ +//===--- BugReporterVisitor.h - Generate PathDiagnostics -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares BugReporterVisitors, which are used to generate enhanced +// diagnostic traces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_GR_BUGREPORTERVISITOR +#define LLVM_CLANG_GR_BUGREPORTERVISITOR + +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/FoldingSet.h" + +namespace clang { + +namespace ento { + +class BugReport; +class BugReporterContext; +class ExplodedNode; +class MemRegion; +class PathDiagnosticPiece; + +class BugReporterVisitor : public llvm::FoldingSetNode { +public: + virtual ~BugReporterVisitor(); + + /// \brief Return a diagnostic piece which should be associated with the + /// given node. + /// + /// The last parameter can be used to register a new visitor with the given + /// BugReport while processing a node. + virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR) = 0; + + /// \brief Provide custom definition for the final diagnostic piece on the + /// path - the piece, which is displayed before the path is expanded. + /// + /// If returns NULL the default implementation will be used. + /// Also note that at most one visitor of a BugReport should generate a + /// non-NULL end of path diagnostic piece. + virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC, + const ExplodedNode *N, + BugReport &BR); + + virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0; + + /// \brief Generates the default final diagnostic piece. + static PathDiagnosticPiece *getDefaultEndPath(BugReporterContext &BRC, + const ExplodedNode *N, + BugReport &BR); + +}; + +class FindLastStoreBRVisitor : public BugReporterVisitor { + const MemRegion *R; + SVal V; + bool satisfied; + const ExplodedNode *StoreSite; + +public: + /// \brief Convenience method to create a visitor given only the MemRegion. + /// Returns NULL if the visitor cannot be created. For example, when the + /// corresponding value is unknown. + static BugReporterVisitor *createVisitorObject(const ExplodedNode *N, + const MemRegion *R); + + /// Creates a visitor for every VarDecl inside a Stmt and registers it with + /// the BugReport. + static void registerStatementVarDecls(BugReport &BR, const Stmt *S); + + FindLastStoreBRVisitor(SVal v, const MemRegion *r) + : R(r), V(v), satisfied(false), StoreSite(0) { + assert (!V.isUnknown() && "Cannot track unknown value."); + + // TODO: Does it make sense to allow undef values here? + // (If not, also see UndefCapturedBlockVarChecker)? + } + + void Profile(llvm::FoldingSetNodeID &ID) const; + + PathDiagnosticPiece *VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR); +}; + +class TrackConstraintBRVisitor : public BugReporterVisitor { + DefinedSVal Constraint; + const bool Assumption; + bool isSatisfied; + +public: + TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption) + : Constraint(constraint), Assumption(assumption), isSatisfied(false) {} + + void Profile(llvm::FoldingSetNodeID &ID) const; + + PathDiagnosticPiece *VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR); +}; + +class NilReceiverBRVisitor : public BugReporterVisitor { +public: + void Profile(llvm::FoldingSetNodeID &ID) const { + static int x = 0; + ID.AddPointer(&x); + } + + PathDiagnosticPiece *VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR); +}; + +/// Visitor that tries to report interesting diagnostics from conditions. +class ConditionBRVisitor : public BugReporterVisitor { +public: + void Profile(llvm::FoldingSetNodeID &ID) const { + static int x = 0; + ID.AddPointer(&x); + } + + virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, + const ExplodedNode *Prev, + BugReporterContext &BRC, + BugReport &BR); + + PathDiagnosticPiece *VisitTerminator(const Stmt *Term, + const ExplodedNode *N, + const CFGBlock *srcBlk, + const CFGBlock *dstBlk, + BugReporterContext &BRC); + + PathDiagnosticPiece *VisitTrueTest(const Expr *Cond, + bool tookTrue, + BugReporterContext &BRC, + const LocationContext *LC); + + PathDiagnosticPiece *VisitTrueTest(const Expr *Cond, + const DeclRefExpr *DR, + const bool tookTrue, + BugReporterContext &BRC, + const LocationContext *LC); + + PathDiagnosticPiece *VisitTrueTest(const Expr *Cond, + const BinaryOperator *BExpr, + const bool tookTrue, + BugReporterContext &BRC, + const LocationContext *LC); + + bool patternMatch(const Expr *Ex, + llvm::raw_ostream &Out, + BugReporterContext &BRC); +}; + +namespace bugreporter { + +BugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N, + const Stmt *S); + +const Stmt *GetDerefExpr(const ExplodedNode *N); +const Stmt *GetDenomExpr(const ExplodedNode *N); +const Stmt *GetCalleeExpr(const ExplodedNode *N); +const Stmt *GetRetValExpr(const ExplodedNode *N); + +} // end namespace clang +} // end namespace ento +} // end namespace bugreporter + + +#endif //LLVM_CLANG_GR__BUGREPORTERVISITOR diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index 7b9bb03..78067cd 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h @@ -14,7 +14,6 @@ #ifndef LLVM_CLANG_ANALYSIS_BUGTYPE #define LLVM_CLANG_ANALYSIS_BUGTYPE -#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "llvm/ADT/FoldingSet.h" #include <string> @@ -22,6 +21,7 @@ namespace clang { namespace ento { +class BugReporter; class ExplodedNode; class ExprEngine; @@ -31,13 +31,13 @@ private: const std::string Category; bool SuppressonSink; public: - BugType(llvm::StringRef name, llvm::StringRef cat) + BugType(StringRef name, StringRef cat) : Name(name), Category(cat), SuppressonSink(false) {} virtual ~BugType(); // FIXME: Should these be made strings as well? - llvm::StringRef getName() const { return Name; } - llvm::StringRef getCategory() const { return Category; } + StringRef getName() const { return Name; } + StringRef getCategory() const { return Category; } /// isSuppressOnSink - Returns true if bug reports associated with this bug /// type should be suppressed if the end node of the report is post-dominated @@ -57,7 +57,7 @@ public: BuiltinBug(const char *name) : BugType(name, "Logic error"), desc(name) {} - llvm::StringRef getDescription() const { return desc; } + StringRef getDescription() const { return desc; } }; } // end GR namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index 6d53c09..406be3c 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -16,6 +16,7 @@ #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/PointerUnion.h" #include <deque> #include <iterator> #include <string> @@ -23,42 +24,55 @@ namespace clang { +class AnalysisContext; +class BinaryOperator; +class CompoundStmt; class Decl; +class LocationContext; +class MemberExpr; +class ParentMap; +class ProgramPoint; class SourceManager; class Stmt; namespace ento { +class ExplodedNode; + //===----------------------------------------------------------------------===// // High-level interface for handlers of path-sensitive diagnostics. //===----------------------------------------------------------------------===// class PathDiagnostic; -class PathDiagnosticClient : public DiagnosticClient { +class PathDiagnosticConsumer { public: - PathDiagnosticClient() {} + PathDiagnosticConsumer() {} - virtual ~PathDiagnosticClient() {} + virtual ~PathDiagnosticConsumer() {} virtual void - FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade = 0) = 0; + FlushDiagnostics(SmallVectorImpl<std::string> *FilesMade = 0) = 0; - void FlushDiagnostics(llvm::SmallVectorImpl<std::string> &FilesMade) { + void FlushDiagnostics(SmallVectorImpl<std::string> &FilesMade) { FlushDiagnostics(&FilesMade); } - virtual llvm::StringRef getName() const = 0; + virtual StringRef getName() const = 0; - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); - virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0; + void HandlePathDiagnostic(const PathDiagnostic* D); enum PathGenerationScheme { Minimal, Extensive }; virtual PathGenerationScheme getGenerationScheme() const { return Minimal; } virtual bool supportsLogicalOpControlFlow() const { return false; } virtual bool supportsAllBlockEdges() const { return false; } virtual bool useVerboseDescription() const { return true; } + +protected: + /// The actual logic for handling path diagnostics, as implemented + /// by subclasses of PathDiagnosticConsumer. + virtual void HandlePathDiagnosticImpl(const PathDiagnostic* D) = 0; + }; //===----------------------------------------------------------------------===// @@ -67,60 +81,143 @@ public: class PathDiagnosticRange : public SourceRange { public: - const bool isPoint; + bool isPoint; PathDiagnosticRange(const SourceRange &R, bool isP = false) : SourceRange(R), isPoint(isP) {} + + PathDiagnosticRange() : isPoint(false) {} }; +typedef llvm::PointerUnion<const LocationContext*, AnalysisContext*> + LocationOrAnalysisContext; + class PathDiagnosticLocation { private: enum Kind { RangeK, SingleLocK, StmtK, DeclK } K; - SourceRange R; const Stmt *S; const Decl *D; const SourceManager *SM; + FullSourceLoc Loc; + PathDiagnosticRange Range; + + PathDiagnosticLocation(SourceLocation L, const SourceManager &sm, + Kind kind) + : K(kind), S(0), D(0), SM(&sm), + Loc(genLocation(L)), Range(genRange()) { + assert(Loc.isValid()); + assert(Range.isValid()); + } + + FullSourceLoc + genLocation(SourceLocation L = SourceLocation(), + LocationOrAnalysisContext LAC = (AnalysisContext*)0) const; + + PathDiagnosticRange + genRange(LocationOrAnalysisContext LAC = (AnalysisContext*)0) const; + public: + /// Create an invalid location. PathDiagnosticLocation() : K(SingleLocK), S(0), D(0), SM(0) {} - PathDiagnosticLocation(FullSourceLoc L) - : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()) {} + /// Create a location corresponding to the given statement. + PathDiagnosticLocation(const Stmt *s, + const SourceManager &sm, + LocationOrAnalysisContext lac) + : K(StmtK), S(s), D(0), SM(&sm), + Loc(genLocation(SourceLocation(), lac)), + Range(genRange(lac)) { + assert(Loc.isValid()); + assert(Range.isValid()); + } - PathDiagnosticLocation(const Stmt *s, const SourceManager &sm) - : K(StmtK), S(s), D(0), SM(&sm) {} + /// Create a location corresponding to the given declaration. + PathDiagnosticLocation(const Decl *d, const SourceManager &sm) + : K(DeclK), S(0), D(d), SM(&sm), + Loc(genLocation()), Range(genRange()) { + assert(Loc.isValid()); + assert(Range.isValid()); + } - PathDiagnosticLocation(SourceRange r, const SourceManager &sm) - : K(RangeK), R(r), S(0), D(0), SM(&sm) {} + /// Create a location corresponding to the given declaration. + static PathDiagnosticLocation create(const Decl *D, + const SourceManager &SM) { + return PathDiagnosticLocation(D, SM); + } - PathDiagnosticLocation(const Decl *d, const SourceManager &sm) - : K(DeclK), S(0), D(d), SM(&sm) {} + /// Create a location for the beginning of the declaration. + static PathDiagnosticLocation createBegin(const Decl *D, + const SourceManager &SM); + + /// Create a location for the beginning of the statement. + static PathDiagnosticLocation createBegin(const Stmt *S, + const SourceManager &SM, + const LocationOrAnalysisContext LAC); + + /// Create the location for the operator of the binary expression. + /// Assumes the statement has a valid location. + static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO, + const SourceManager &SM); + + /// For member expressions, return the location of the '.' or '->'. + /// Assumes the statement has a valid location. + static PathDiagnosticLocation createMemberLoc(const MemberExpr *ME, + const SourceManager &SM); + + /// Create a location for the beginning of the compound statement. + /// Assumes the statement has a valid location. + static PathDiagnosticLocation createBeginBrace(const CompoundStmt *CS, + const SourceManager &SM); + + /// Create a location for the end of the compound statement. + /// Assumes the statement has a valid location. + static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS, + const SourceManager &SM); + + /// Create a location for the beginning of the enclosing declaration body. + /// Defaults to the beginning of the first statement in the declaration body. + static PathDiagnosticLocation createDeclBegin(const LocationContext *LC, + const SourceManager &SM); + + /// Constructs a location for the end of the enclosing declaration body. + /// Defaults to the end of brace. + static PathDiagnosticLocation createDeclEnd(const LocationContext *LC, + const SourceManager &SM); + + /// Create a location corresponding to the given valid ExplodedNode. + static PathDiagnosticLocation create(const ProgramPoint& P, + const SourceManager &SMng); + + /// Create a location corresponding to the next valid ExplodedNode as end + /// of path location. + static PathDiagnosticLocation createEndOfPath(const ExplodedNode* N, + const SourceManager &SM); + + /// Convert the given location into a single kind location. + static PathDiagnosticLocation createSingleLocation( + const PathDiagnosticLocation &PDL); bool operator==(const PathDiagnosticLocation &X) const { - return K == X.K && R == X.R && S == X.S && D == X.D; + return K == X.K && Loc == X.Loc && Range == X.Range; } bool operator!=(const PathDiagnosticLocation &X) const { - return K != X.K || R != X.R || S != X.S || D != X.D;; - } - - PathDiagnosticLocation& operator=(const PathDiagnosticLocation &X) { - K = X.K; - R = X.R; - S = X.S; - D = X.D; - SM = X.SM; - return *this; + return !(*this == X); } bool isValid() const { return SM != 0; } - const SourceManager& getSourceManager() const { assert(isValid());return *SM;} + FullSourceLoc asLocation() const { + return Loc; + } + + PathDiagnosticRange asRange() const { + return Range; + } - FullSourceLoc asLocation() const; - PathDiagnosticRange asRange() const; const Stmt *asStmt() const { assert(isValid()); return S; } const Decl *asDecl() const { assert(isValid()); return D; } @@ -181,7 +278,7 @@ private: PathDiagnosticPiece& operator=(const PathDiagnosticPiece &P); protected: - PathDiagnosticPiece(llvm::StringRef s, Kind k, DisplayHint hint = Below); + PathDiagnosticPiece(StringRef s, Kind k, DisplayHint hint = Below); PathDiagnosticPiece(Kind k, DisplayHint hint = Below); @@ -191,7 +288,7 @@ public: const std::string& getString() const { return str; } /// getDisplayHint - Return a hint indicating where the diagnostic should - /// be displayed by the PathDiagnosticClient. + /// be displayed by the PathDiagnosticConsumer. DisplayHint getDisplayHint() const { return Hint; } virtual PathDiagnosticLocation getLocation() const = 0; @@ -199,9 +296,15 @@ public: Kind getKind() const { return kind; } - void addRange(SourceRange R) { ranges.push_back(R); } + void addRange(SourceRange R) { + if (!R.isValid()) + return; + ranges.push_back(R); + } void addRange(SourceLocation B, SourceLocation E) { + if (!B.isValid() || !E.isValid()) + return; ranges.push_back(SourceRange(B,E)); } @@ -230,7 +333,7 @@ public: : &FixItHints[0] + FixItHints.size(); } - static inline bool classof(const PathDiagnosticPiece* P) { + static inline bool classof(const PathDiagnosticPiece *P) { return true; } @@ -242,11 +345,11 @@ private: PathDiagnosticLocation Pos; public: PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos, - llvm::StringRef s, + StringRef s, PathDiagnosticPiece::Kind k, bool addPosRange = true) : PathDiagnosticPiece(s, k), Pos(pos) { - assert(Pos.asLocation().isValid() && + assert(Pos.isValid() && Pos.asLocation().isValid() && "PathDiagnosticSpotPiece's must have a valid location."); if (addPosRange && Pos.hasRange()) addRange(Pos.asRange()); } @@ -261,12 +364,12 @@ class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece { public: PathDiagnosticEventPiece(const PathDiagnosticLocation &pos, - llvm::StringRef s, bool addPosRange = true) + StringRef s, bool addPosRange = true) : PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {} ~PathDiagnosticEventPiece(); - static inline bool classof(const PathDiagnosticPiece* P) { + static inline bool classof(const PathDiagnosticPiece *P) { return P->getKind() == Event; } }; @@ -276,7 +379,7 @@ class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece { public: PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos, const PathDiagnosticLocation &endPos, - llvm::StringRef s) + StringRef s) : PathDiagnosticPiece(s, ControlFlow) { LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos)); } @@ -320,7 +423,7 @@ public: const_iterator begin() const { return LPairs.begin(); } const_iterator end() const { return LPairs.end(); } - static inline bool classof(const PathDiagnosticPiece* P) { + static inline bool classof(const PathDiagnosticPiece *P) { return P->getKind() == ControlFlow; } @@ -337,7 +440,7 @@ public: bool containsEvent() const; - void push_back(PathDiagnosticPiece* P) { SubPieces.push_back(P); } + void push_back(PathDiagnosticPiece *P) { SubPieces.push_back(P); } typedef std::vector<PathDiagnosticPiece*>::iterator iterator; iterator begin() { return SubPieces.begin(); } @@ -352,7 +455,7 @@ public: const_iterator begin() const { return SubPieces.begin(); } const_iterator end() const { return SubPieces.end(); } - static inline bool classof(const PathDiagnosticPiece* P) { + static inline bool classof(const PathDiagnosticPiece *P) { return P->getKind() == Macro; } @@ -373,42 +476,42 @@ class PathDiagnostic : public llvm::FoldingSetNode { public: PathDiagnostic(); - PathDiagnostic(llvm::StringRef bugtype, llvm::StringRef desc, - llvm::StringRef category); + PathDiagnostic(StringRef bugtype, StringRef desc, + StringRef category); ~PathDiagnostic(); - llvm::StringRef getDescription() const { return Desc; } - llvm::StringRef getBugType() const { return BugType; } - llvm::StringRef getCategory() const { return Category; } + StringRef getDescription() const { return Desc; } + StringRef getBugType() const { return BugType; } + StringRef getCategory() const { return Category; } typedef std::deque<std::string>::const_iterator meta_iterator; meta_iterator meta_begin() const { return OtherDesc.begin(); } meta_iterator meta_end() const { return OtherDesc.end(); } - void addMeta(llvm::StringRef s) { OtherDesc.push_back(s); } + void addMeta(StringRef s) { OtherDesc.push_back(s); } PathDiagnosticLocation getLocation() const { assert(Size > 0 && "getLocation() requires a non-empty PathDiagnostic."); return rbegin()->getLocation(); } - void push_front(PathDiagnosticPiece* piece) { + void push_front(PathDiagnosticPiece *piece) { assert(piece); path.push_front(piece); ++Size; } - void push_back(PathDiagnosticPiece* piece) { + void push_back(PathDiagnosticPiece *piece) { assert(piece); path.push_back(piece); ++Size; } - PathDiagnosticPiece* back() { + PathDiagnosticPiece *back() { return path.back(); } - const PathDiagnosticPiece* back() const { + const PathDiagnosticPiece *back() const { return path.back(); } @@ -433,14 +536,14 @@ public: public: iterator(const ImplTy& i) : I(i) {} - bool operator==(const iterator& X) const { return I == X.I; } - bool operator!=(const iterator& X) const { return I != X.I; } + bool operator==(const iterator &X) const { return I == X.I; } + bool operator!=(const iterator &X) const { return I != X.I; } PathDiagnosticPiece& operator*() const { return **I; } - PathDiagnosticPiece* operator->() const { return *I; } + PathDiagnosticPiece *operator->() const { return *I; } - iterator& operator++() { ++I; return *this; } - iterator& operator--() { --I; return *this; } + iterator &operator++() { ++I; return *this; } + iterator &operator--() { --I; return *this; } }; class const_iterator { @@ -459,14 +562,14 @@ public: public: const_iterator(const ImplTy& i) : I(i) {} - bool operator==(const const_iterator& X) const { return I == X.I; } - bool operator!=(const const_iterator& X) const { return I != X.I; } + bool operator==(const const_iterator &X) const { return I == X.I; } + bool operator!=(const const_iterator &X) const { return I != X.I; } reference operator*() const { return **I; } pointer operator->() const { return *I; } - const_iterator& operator++() { ++I; return *this; } - const_iterator& operator--() { --I; return *this; } + const_iterator &operator++() { ++I; return *this; } + const_iterator &operator--() { --I; return *this; } }; typedef std::reverse_iterator<iterator> reverse_iterator; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h index eb38bd8..1e4edeb 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SA_CORE_CHECKER #define LLVM_CLANG_SA_CORE_CHECKER +#include "clang/Analysis/ProgramPoint.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/Support/Casting.h" @@ -151,9 +152,10 @@ public: class Location { template <typename CHECKER> - static void _checkLocation(void *checker, const SVal &location, bool isLoad, + static void _checkLocation(void *checker, + const SVal &location, bool isLoad, const Stmt *S, CheckerContext &C) { - ((const CHECKER *)checker)->checkLocation(location, isLoad, C); + ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C); } public: @@ -166,9 +168,10 @@ public: class Bind { template <typename CHECKER> - static void _checkBind(void *checker, const SVal &location, const SVal &val, + static void _checkBind(void *checker, + const SVal &location, const SVal &val, const Stmt *S, CheckerContext &C) { - ((const CHECKER *)checker)->checkBind(location, val, C); + ((const CHECKER *)checker)->checkBind(location, val, S, C); } public: @@ -227,7 +230,7 @@ public: class LiveSymbols { template <typename CHECKER> - static void _checkLiveSymbols(void *checker, const GRState *state, + static void _checkLiveSymbols(void *checker, const ProgramState *state, SymbolReaper &SR) { ((const CHECKER *)checker)->checkLiveSymbols(state, SR); } @@ -257,15 +260,18 @@ public: class RegionChanges { template <typename CHECKER> - static const GRState *_checkRegionChanges(void *checker, const GRState *state, - const StoreManager::InvalidatedSymbols *invalidated, - const MemRegion * const *Begin, - const MemRegion * const *End) { + static const ProgramState * + _checkRegionChanges(void *checker, + const ProgramState *state, + const StoreManager::InvalidatedSymbols *invalidated, + ArrayRef<const MemRegion *> Explicits, + ArrayRef<const MemRegion *> Regions) { return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated, - Begin, End); + Explicits, Regions); } template <typename CHECKER> - static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) { + static bool _wantsRegionChangeUpdate(void *checker, + const ProgramState *state) { return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state); } @@ -300,8 +306,10 @@ namespace eval { class Assume { template <typename CHECKER> - static const GRState *_evalAssume(void *checker, const GRState *state, - const SVal &cond, bool assumption) { + static const ProgramState *_evalAssume(void *checker, + const ProgramState *state, + const SVal &cond, + bool assumption) { return ((const CHECKER *)checker)->evalAssume(state, cond, assumption); } @@ -327,38 +335,73 @@ public: } }; +class InlineCall { + template <typename CHECKER> + static bool _inlineCall(void *checker, const CallExpr *CE, + ExprEngine &Eng, + ExplodedNode *Pred, + ExplodedNodeSet &Dst) { + return ((const CHECKER *)checker)->inlineCall(CE, Eng, Pred, Dst); + } + +public: + template <typename CHECKER> + static void _register(CHECKER *checker, CheckerManager &mgr) { + mgr._registerForInlineCall( + CheckerManager::InlineCallFunc(checker, _inlineCall<CHECKER>)); + } +}; + } // end eval namespace +class CheckerBase : public ProgramPointTag { +public: + StringRef getTagDescription() const; + + /// See CheckerManager::runCheckersForPrintState. + virtual void printState(raw_ostream &Out, const ProgramState *State, + const char *NL, const char *Sep) const { } +}; + template <typename CHECK1, typename CHECK2=check::_VoidCheck, typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck, typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck, typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck, typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck, - typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck> + typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck, + typename CHECK13=check::_VoidCheck,typename CHECK14=check::_VoidCheck, + typename CHECK15=check::_VoidCheck,typename CHECK16=check::_VoidCheck> class Checker; template <> class Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, - check::_VoidCheck, check::_VoidCheck, check::_VoidCheck> { + check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, + check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, + check::_VoidCheck> + : public CheckerBase +{ public: static void _register(void *checker, CheckerManager &mgr) { } }; template <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4, typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8, - typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12> + typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12, + typename CHECK13,typename CHECK14,typename CHECK15,typename CHECK16> class Checker : public CHECK1, public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8, - CHECK9, CHECK10, CHECK11, CHECK12> { + CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,CHECK14,CHECK15, + CHECK16> { public: template <typename CHECKER> static void _register(CHECKER *checker, CheckerManager &mgr) { CHECK1::_register(checker, mgr); - Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8, CHECK9, - CHECK10, CHECK11,CHECK12>::_register(checker, mgr); + Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8, + CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,CHECK14,CHECK15, + CHECK16>::_register(checker, mgr); } }; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index 45d38fb..e3e4c49 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -27,6 +27,7 @@ namespace clang { class CallExpr; namespace ento { + class CheckerBase; class ExprEngine; class AnalysisManager; class BugReporter; @@ -36,7 +37,7 @@ namespace ento { class ExplodedNode; class ExplodedNodeSet; class ExplodedGraph; - class GRState; + class ProgramState; class EndOfFunctionNodeBuilder; class BranchNodeBuilder; class MemRegion; @@ -55,8 +56,8 @@ class CheckerFn<RET(P1, P2, P3, P4)> { typedef RET (*Func)(void *, P1, P2, P3, P4); Func Fn; public: - void *Checker; - CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } + CheckerBase *Checker; + CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return Fn(Checker, p1, p2, p3, p4); } @@ -67,8 +68,8 @@ class CheckerFn<RET(P1, P2, P3)> { typedef RET (*Func)(void *, P1, P2, P3); Func Fn; public: - void *Checker; - CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } + CheckerBase *Checker; + CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } }; @@ -77,8 +78,8 @@ class CheckerFn<RET(P1, P2)> { typedef RET (*Func)(void *, P1, P2); Func Fn; public: - void *Checker; - CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } + CheckerBase *Checker; + CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } }; @@ -87,8 +88,8 @@ class CheckerFn<RET(P1)> { typedef RET (*Func)(void *, P1); Func Fn; public: - void *Checker; - CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } + CheckerBase *Checker; + CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } RET operator()(P1 p1) const { return Fn(Checker, p1); } }; @@ -97,8 +98,8 @@ class CheckerFn<RET()> { typedef RET (*Func)(void *); Func Fn; public: - void *Checker; - CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } + CheckerBase *Checker; + CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } RET operator()() const { return Fn(Checker); } }; @@ -115,8 +116,8 @@ public: const LangOptions &getLangOptions() const { return LangOpts; } - typedef void *CheckerRef; - typedef void *CheckerTag; + typedef CheckerBase *CheckerRef; + typedef const void *CheckerTag; typedef CheckerFn<void ()> CheckerDtor; //===----------------------------------------------------------------------===// @@ -157,6 +158,11 @@ public: //===----------------------------------------------------------------------===// /// \brief Run checkers for pre-visiting Stmts. + /// + /// The notification is performed for every explored CFGElement, which does + /// not include the control flow statements such as IfStmt. + /// + /// \sa runCheckersForBranchCondition, runCheckersForPostStmt void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, @@ -165,6 +171,11 @@ public: } /// \brief Run checkers for post-visiting Stmts. + /// + /// The notification is performed for every explored CFGElement, which does + /// not include the control flow statements such as IfStmt. + /// + /// \sa runCheckersForBranchCondition, runCheckersForPreStmt void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, @@ -224,27 +235,43 @@ public: BranchNodeBuilder &B, ExprEngine &Eng); /// \brief Run checkers for live symbols. - void runCheckersForLiveSymbols(const GRState *state, + /// + /// Allows modifying SymbolReaper object. For example, checkers can explicitly + /// register symbols of interest as live. These symbols will not be marked + /// dead and removed. + void runCheckersForLiveSymbols(const ProgramState *state, SymbolReaper &SymReaper); /// \brief Run checkers for dead symbols. + /// + /// Notifies checkers when symbols become dead. For example, this allows + /// checkers to aggressively clean up/reduce the checker state and produce + /// precise diagnostics. void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng); /// \brief True if at least one checker wants to check region changes. - bool wantsRegionChangeUpdate(const GRState *state); + bool wantsRegionChangeUpdate(const ProgramState *state); /// \brief Run checkers for region changes. - const GRState * - runCheckersForRegionChanges(const GRState *state, + /// + /// This corresponds to the check::RegionChanges callback. + /// \param state The current program state. + /// \param invalidated A set of all symbols potentially touched by the change. + /// \param ExplicitRegions The regions explicitly requested for invalidation. + /// For example, in the case of a function call, these would be arguments. + /// \param Regions The transitive closure of accessible regions, + /// i.e. all regions that may have been touched by this change. + const ProgramState * + runCheckersForRegionChanges(const ProgramState *state, const StoreManager::InvalidatedSymbols *invalidated, - const MemRegion * const *Begin, - const MemRegion * const *End); + ArrayRef<const MemRegion *> ExplicitRegions, + ArrayRef<const MemRegion *> Regions); /// \brief Run checkers for handling assumptions on symbolic values. - const GRState *runCheckersForEvalAssume(const GRState *state, + const ProgramState *runCheckersForEvalAssume(const ProgramState *state, SVal Cond, bool Assumption); /// \brief Run checkers for evaluating a call. @@ -254,10 +281,21 @@ public: GraphExpander *defaultEval = 0); /// \brief Run checkers for the entire Translation Unit. - void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl* TU, + void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, AnalysisManager &mgr, BugReporter &BR); + /// \brief Run checkers for debug-printing a ProgramState. + /// + /// Unlike most other callbacks, any checker can simply implement the virtual + /// method CheckerBase::printState if it has custom data to print. + /// \param Out The output stream + /// \param State The state being printed + /// \param NL The preferred representation of a newline. + /// \param Sep The preferred separator between different kinds of data. + void runCheckersForPrintState(raw_ostream &Out, const ProgramState *State, + const char *NL, const char *Sep); + //===----------------------------------------------------------------------===// // Internal registration functions for AST traversing. //===----------------------------------------------------------------------===// @@ -282,11 +320,13 @@ public: typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)> CheckObjCMessageFunc; - typedef CheckerFn<void (const SVal &location, bool isLoad, CheckerContext &)> + typedef CheckerFn<void (const SVal &location, bool isLoad, const Stmt *S, + CheckerContext &)> CheckLocationFunc; - typedef CheckerFn<void (const SVal &location, const SVal &val, - CheckerContext &)> CheckBindFunc; + typedef CheckerFn<void (const SVal &location, const SVal &val, + const Stmt *S, CheckerContext &)> + CheckBindFunc; typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)> CheckEndAnalysisFunc; @@ -300,23 +340,28 @@ public: typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> CheckDeadSymbolsFunc; - typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc; + typedef CheckerFn<void (const ProgramState *,SymbolReaper &)> CheckLiveSymbolsFunc; - typedef CheckerFn<const GRState * (const GRState *, + typedef CheckerFn<const ProgramState * (const ProgramState *, const StoreManager::InvalidatedSymbols *symbols, - const MemRegion * const *begin, - const MemRegion * const *end)> + ArrayRef<const MemRegion *> ExplicitRegions, + ArrayRef<const MemRegion *> Regions)> CheckRegionChangesFunc; - typedef CheckerFn<bool (const GRState *)> WantsRegionChangeUpdateFunc; + typedef CheckerFn<bool (const ProgramState *)> WantsRegionChangeUpdateFunc; - typedef CheckerFn<const GRState * (const GRState *, - const SVal &cond, bool assumption)> + typedef CheckerFn<const ProgramState * (const ProgramState *, + const SVal &cond, bool assumption)> EvalAssumeFunc; typedef CheckerFn<bool (const CallExpr *, CheckerContext &)> EvalCallFunc; + typedef CheckerFn<bool (const CallExpr *, ExprEngine &Eng, + ExplodedNode *Pred, + ExplodedNodeSet &Dst)> + InlineCallFunc; + typedef CheckerFn<void (const TranslationUnitDecl *, AnalysisManager&, BugReporter &)> CheckEndOfTranslationUnit; @@ -351,6 +396,8 @@ public: void _registerForEvalCall(EvalCallFunc checkfn); + void _registerForInlineCall(InlineCallFunc checkfn); + void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); //===----------------------------------------------------------------------===// @@ -405,7 +452,7 @@ private: std::vector<CheckDeclFunc> BodyCheckers; - typedef llvm::SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; + typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; CachedDeclCheckersMapTy CachedDeclCheckersMap; @@ -439,7 +486,7 @@ private: }; friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; - typedef llvm::SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; + typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> CachedStmtCheckersMapTy; CachedStmtCheckersMapTy CachedStmtCheckersMap; @@ -473,10 +520,12 @@ private: std::vector<EvalCallFunc> EvalCallCheckers; + std::vector<InlineCallFunc> InlineCallCheckers; + std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers; struct EventInfo { - llvm::SmallVector<CheckEventFunc, 4> Checkers; + SmallVector<CheckEventFunc, 4> Checkers; bool HasDispatcher; EventInfo() : HasDispatcher(false) { } }; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h new file mode 100644 index 0000000..6ce5b3c --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h @@ -0,0 +1,43 @@ +//===--- CheckerOptInfo.h - Specifies which checkers to use -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H +#define LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H + +#include "clang/Basic/LLVM.h" + +namespace clang { +namespace ento { + +/// Represents a request to include or exclude a checker or package from a +/// specific analysis run. +/// +/// \sa CheckerRegistry::initializeManager +class CheckerOptInfo { + StringRef Name; + bool Enable; + bool Claimed; + +public: + CheckerOptInfo(StringRef name, bool enable) + : Name(name), Enable(enable), Claimed(false) { } + + StringRef getName() const { return Name; } + bool isEnabled() const { return Enable; } + bool isDisabled() const { return !isEnabled(); } + + bool isClaimed() const { return Claimed; } + bool isUnclaimed() const { return !isClaimed(); } + void claim() { Claimed = true; } +}; + +} // end namespace ento +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerProvider.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerProvider.h deleted file mode 100644 index b8aaaa1..0000000 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerProvider.h +++ /dev/null @@ -1,58 +0,0 @@ -//===--- CheckerProvider.h - Static Analyzer Checkers Provider --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Defines the Static Analyzer Checker Provider. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SA_CORE_CHECKERPROVIDER_H -#define LLVM_CLANG_SA_CORE_CHECKERPROVIDER_H - -#include "llvm/ADT/StringRef.h" - -namespace llvm { - class raw_ostream; -} - -namespace clang { - -namespace ento { - class CheckerManager; - -class CheckerOptInfo { - const char *Name; - bool Enable; - bool Claimed; - -public: - CheckerOptInfo(const char *name, bool enable) - : Name(name), Enable(enable), Claimed(false) { } - - const char *getName() const { return Name; } - bool isEnabled() const { return Enable; } - bool isDisabled() const { return !isEnabled(); } - - bool isClaimed() const { return Claimed; } - bool isUnclaimed() const { return !isClaimed(); } - void claim() { Claimed = true; } -}; - -class CheckerProvider { -public: - virtual ~CheckerProvider(); - virtual void registerCheckers(CheckerManager &checkerMgr, - CheckerOptInfo *checkOpts, unsigned numCheckOpts) = 0; - virtual void printHelp(llvm::raw_ostream &OS) = 0; -}; - -} // end ento namespace - -} // end clang namespace - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h new file mode 100644 index 0000000..b59c14d --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h @@ -0,0 +1,132 @@ +//===--- CheckerRegistry.h - Maintains all available checkers ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H +#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H + +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/Basic/LLVM.h" +#include <vector> + +// FIXME: move this information to an HTML file in docs/. +// At the very least, a checker plugin is a dynamic library that exports +// clang_analyzerAPIVersionString. This should be defined as follows: +// +// extern "C" +// const char clang_analyzerAPIVersionString[] = +// CLANG_ANALYZER_API_VERSION_STRING; +// +// This is used to check whether the current version of the analyzer is known to +// be incompatible with a plugin. Plugins with incompatible version strings, +// or without a version string at all, will not be loaded. +// +// To add a custom checker to the analyzer, the plugin must also define the +// function clang_registerCheckers. For example: +// +// extern "C" +// void clang_registerCheckers (CheckerRegistry ®istry) { +// registry.addChecker<MainCallChecker>("example.MainCallChecker", +// "Disallows calls to functions called main"); +// } +// +// The first method argument is the full name of the checker, including its +// enclosing package. By convention, the registered name of a checker is the +// name of the associated class (the template argument). +// The second method argument is a short human-readable description of the +// checker. +// +// The clang_registerCheckers function may add any number of checkers to the +// registry. If any checkers require additional initialization, use the three- +// argument form of CheckerRegistry::addChecker. +// +// To load a checker plugin, specify the full path to the dynamic library as +// the argument to the -load option in the cc1 frontend. You can then enable +// your custom checker using the -analyzer-checker: +// +// clang -cc1 -load </path/to/plugin.dylib> -analyze +// -analyzer-checker=<example.MainCallChecker> +// +// For a complete working example, see examples/analyzer-plugin. + + +namespace clang { +namespace ento { + +#ifndef CLANG_ANALYZER_API_VERSION_STRING +// FIXME: The Clang version string is not particularly granular; +// the analyzer infrastructure can change a lot between releases. +// Unfortunately, this string has to be statically embedded in each plugin, +// so we can't just use the functions defined in Version.h. +#include "clang/Basic/Version.h" +#define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING +#endif + +class CheckerOptInfo; + +/// Manages a set of available checkers for running a static analysis. +/// The checkers are organized into packages by full name, where including +/// a package will recursively include all subpackages and checkers within it. +/// For example, the checker "core.builtin.NoReturnFunctionChecker" will be +/// included if initializeManager() is called with an option of "core", +/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". +class CheckerRegistry { +public: + /// Initialization functions perform any necessary setup for a checker. + /// They should include a call to CheckerManager::registerChecker. + typedef void (*InitializationFunction)(CheckerManager &); + struct CheckerInfo { + InitializationFunction Initialize; + StringRef FullName; + StringRef Desc; + + CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc) + : Initialize(fn), FullName(name), Desc(desc) {} + }; + + typedef std::vector<CheckerInfo> CheckerInfoList; + +private: + template <typename T> + static void initializeManager(CheckerManager &mgr) { + mgr.registerChecker<T>(); + } + +public: + /// Adds a checker to the registry. Use this non-templated overload when your + /// checker requires custom initialization. + void addChecker(InitializationFunction fn, StringRef fullName, + StringRef desc); + + /// Adds a checker to the registry. Use this templated overload when your + /// checker does not require any custom initialization. + template <class T> + void addChecker(StringRef fullName, StringRef desc) { + addChecker(&initializeManager<T>, fullName, desc); + } + + /// Initializes a CheckerManager by calling the initialization functions for + /// all checkers specified by the given CheckerOptInfo list. The order of this + /// list is significant; later options can be used to reverse earlier ones. + /// This can be used to exclude certain checkers in an included package. + void initializeManager(CheckerManager &mgr, + SmallVectorImpl<CheckerOptInfo> &opts) const; + + /// Prints the name and description of all checkers in this registry. + /// This output is not intended to be machine-parseable. + void printHelp(raw_ostream &out, size_t maxNameChars = 30) const ; + +private: + mutable CheckerInfoList Checkers; + mutable llvm::StringMap<size_t> Packages; +}; + +} // end namespace ento +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticClients.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h index d02228f..d1f5a7d 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticClients.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h @@ -22,18 +22,18 @@ class Preprocessor; namespace ento { -class PathDiagnosticClient; +class PathDiagnosticConsumer; -PathDiagnosticClient* -createHTMLDiagnosticClient(const std::string& prefix, const Preprocessor &PP); +PathDiagnosticConsumer* +createHTMLDiagnosticConsumer(const std::string& prefix, const Preprocessor &PP); -PathDiagnosticClient* -createPlistDiagnosticClient(const std::string& prefix, const Preprocessor &PP, - PathDiagnosticClient *SubPD = 0); +PathDiagnosticConsumer* +createPlistDiagnosticConsumer(const std::string& prefix, const Preprocessor &PP, + PathDiagnosticConsumer *SubPD = 0); -PathDiagnosticClient* -createTextPathDiagnosticClient(const std::string& prefix, - const Preprocessor &PP); +PathDiagnosticConsumer* +createTextPathDiagnosticConsumer(const std::string& prefix, + const Preprocessor &PP); } // end GR namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index 1ba038e..6c93f59 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_GR_ANALYSISMANAGER_H #include "clang/Analysis/AnalysisContext.h" +#include "clang/Frontend/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" @@ -34,10 +35,10 @@ class AnalysisManager : public BugReporterData { LocationContextManager LocCtxMgr; ASTContext &Ctx; - Diagnostic &Diags; + DiagnosticsEngine &Diags; const LangOptions &LangInfo; - llvm::OwningPtr<PathDiagnosticClient> PD; + llvm::OwningPtr<PathDiagnosticConsumer> PD; // Configurable components creators. StoreManagerCreator CreateStoreMgr; @@ -60,7 +61,7 @@ class AnalysisManager : public BugReporterData { bool VisualizeEGDot; bool VisualizeEGUbi; - bool PurgeDead; + AnalysisPurgeMode PurgeDead; /// EargerlyAssume - A flag indicating how the engine should handle // expressions such as: 'x = (y != 0)'. When this flag is true then @@ -75,27 +76,24 @@ class AnalysisManager : public BugReporterData { bool EagerlyTrimEGraph; public: - AnalysisManager(ASTContext &ctx, Diagnostic &diags, - const LangOptions &lang, PathDiagnosticClient *pd, + AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, + const LangOptions &lang, PathDiagnosticConsumer *pd, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, idx::Indexer *idxer, unsigned maxnodes, unsigned maxvisit, - bool vizdot, bool vizubi, bool purge, bool eager, bool trim, + bool vizdot, bool vizubi, AnalysisPurgeMode purge, + bool eager, bool trim, bool inlinecall, bool useUnoptimizedCFG, bool addImplicitDtors, bool addInitializers, - bool eagerlyTrimEGraph) - - : AnaCtxMgr(useUnoptimizedCFG, addImplicitDtors, addInitializers), - Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), - CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), - CheckerMgr(checkerMgr), Idxer(idxer), - AScope(ScopeDecl), MaxNodes(maxnodes), MaxVisit(maxvisit), - VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), - EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall), - EagerlyTrimEGraph(eagerlyTrimEGraph) {} - + bool eagerlyTrimEGraph); + + /// Construct a clone of the given AnalysisManager with the given ASTContext + /// and DiagnosticsEngine. + AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, + AnalysisManager &ParentAM); + ~AnalysisManager() { FlushDiagnostics(); } void ClearContexts() { @@ -127,7 +125,7 @@ public: return getASTContext().getSourceManager(); } - virtual Diagnostic &getDiagnostic() { + virtual DiagnosticsEngine &getDiagnostic() { return Diags; } @@ -135,7 +133,7 @@ public: return LangInfo; } - virtual PathDiagnosticClient *getPathDiagnosticClient() { + virtual PathDiagnosticConsumer *getPathDiagnosticConsumer() { return PD.get(); } @@ -160,7 +158,7 @@ public: bool shouldTrimGraph() const { return TrimGraph; } - bool shouldPurgeDead() const { return PurgeDead; } + AnalysisPurgeMode getPurgeMode() const { return PurgeDead; } bool shouldEagerlyAssume() const { return EagerlyAssume; } @@ -174,8 +172,9 @@ public: return AnaCtxMgr.getContext(D)->getCFG(); } - LiveVariables *getLiveVariables(Decl const *D) { - return AnaCtxMgr.getContext(D)->getLiveVariables(); + template <typename T> + T *getAnalysis(Decl const *D) { + return AnaCtxMgr.getContext(D)->getAnalysis<T>(); } ParentMap &getParentMap(Decl const *D) { diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index 69495be..42a1537 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -27,7 +27,7 @@ namespace clang { namespace ento { - class GRState; +class ProgramState; class CompoundValData : public llvm::FoldingSetNode { QualType T; @@ -49,17 +49,17 @@ public: class LazyCompoundValData : public llvm::FoldingSetNode { StoreRef store; - const TypedRegion *region; + const TypedValueRegion *region; public: - LazyCompoundValData(const StoreRef &st, const TypedRegion *r) + LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r) : store(st), region(r) {} const void *getStore() const { return store.getStore(); } - const TypedRegion *getRegion() const { return region; } + const TypedValueRegion *getRegion() const { return region; } static void Profile(llvm::FoldingSetNodeID& ID, const StoreRef &store, - const TypedRegion *region); + const TypedValueRegion *region); void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); } }; @@ -68,25 +68,25 @@ class BasicValueFactory { typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> > APSIntSetTy; - ASTContext& Ctx; + ASTContext &Ctx; llvm::BumpPtrAllocator& BPAlloc; APSIntSetTy APSIntSet; - void* PersistentSVals; - void* PersistentSValPairs; + void * PersistentSVals; + void * PersistentSValPairs; llvm::ImmutableList<SVal>::Factory SValListFactory; llvm::FoldingSet<CompoundValData> CompoundValDataSet; llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet; public: - BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc) + BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator& Alloc) : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0), SValListFactory(Alloc) {} ~BasicValueFactory(); - ASTContext& getContext() const { return Ctx; } + ASTContext &getContext() const { return Ctx; } const llvm::APSInt& getValue(const llvm::APSInt& X); const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned); @@ -176,7 +176,7 @@ public: llvm::ImmutableList<SVal> Vals); const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store, - const TypedRegion *region); + const TypedValueRegion *region); llvm::ImmutableList<SVal> getEmptySValList() { return SValListFactory.getEmptyList(); diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h index 7d0fdfb..2483a79 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h @@ -26,10 +26,13 @@ class StackFrameContext; namespace ento { +/// \class BlockCounter +/// \brief An abstract data type used to count the number of times a given +/// block has been visited along a path analyzed by CoreEngine. class BlockCounter { - void* Data; + void *Data; - BlockCounter(void* D) : Data(D) {} + BlockCounter(void *D) : Data(D) {} public: BlockCounter() : Data(0) {} @@ -38,7 +41,7 @@ public: unsigned BlockID) const; class Factory { - void* F; + void *F; public: Factory(llvm::BumpPtrAllocator& Alloc); ~Factory(); diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 4429c6b..1f14787 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -28,26 +28,29 @@ class CheckerContext { ExprEngine &Eng; ExplodedNode *Pred; SaveAndRestore<bool> OldSink; - const void *checkerTag; - SaveAndRestore<ProgramPoint::Kind> OldPointKind; SaveOr OldHasGen; - const GRState *ST; - const Stmt *statement; + const ProgramPoint Location; + const ProgramState *ST; const unsigned size; public: bool *respondsToCallback; public: - CheckerContext(ExplodedNodeSet &dst, StmtNodeBuilder &builder, - ExprEngine &eng, ExplodedNode *pred, - const void *tag, ProgramPoint::Kind K, + CheckerContext(ExplodedNodeSet &dst, + StmtNodeBuilder &builder, + ExprEngine &eng, + ExplodedNode *pred, + const ProgramPoint &loc, bool *respondsToCB = 0, - const Stmt *stmt = 0, const GRState *st = 0) - : Dst(dst), B(builder), Eng(eng), Pred(pred), + const ProgramState *st = 0) + : Dst(dst), + B(builder), + Eng(eng), + Pred(pred), OldSink(B.BuildSinks), - checkerTag(tag), - OldPointKind(B.PointKind, K), OldHasGen(B.hasGeneratedNode), - ST(st), statement(stmt), size(Dst.size()), + Location(loc), + ST(st), + size(Dst.size()), respondsToCallback(respondsToCB) {} ~CheckerContext(); @@ -69,10 +72,12 @@ public: } ExplodedNodeSet &getNodeSet() { return Dst; } - StmtNodeBuilder &getNodeBuilder() { return B; } ExplodedNode *&getPredecessor() { return Pred; } - const GRState *getState() { return ST ? ST : B.GetState(Pred); } - const Stmt *getStmt() const { return statement; } + const ProgramState *getState() { return ST ? ST : Pred->getState(); } + + /// \brief Returns the number of times the current block has been visited + /// along the analyzed path. + unsigned getCurrentBlockCount() {return B.getCurrentBlockCount();} ASTContext &getASTContext() { return Eng.getContext(); @@ -90,64 +95,58 @@ public: return Eng.getSValBuilder(); } - ExplodedNode *generateNode(bool autoTransition = true) { - assert(statement && "Only transitions with statements currently supported"); - ExplodedNode *N = generateNodeImpl(statement, getState(), false, - checkerTag); - if (N && autoTransition) - Dst.Add(N); - return N; + SymbolManager &getSymbolManager() { + return getSValBuilder().getSymbolManager(); } - - ExplodedNode *generateNode(const Stmt *stmt, const GRState *state, - bool autoTransition = true, const void *tag = 0) { - assert(state); - ExplodedNode *N = generateNodeImpl(stmt, state, false, - tag ? tag : checkerTag); - if (N && autoTransition) - addTransition(N); - return N; + + bool isObjCGCEnabled() { + return Eng.isObjCGCEnabled(); } - ExplodedNode *generateNode(const GRState *state, ExplodedNode *pred, + /// \brief Generate a default checker node (containing checker tag but no + /// checker state changes). + ExplodedNode *generateNode(bool autoTransition = true) { + return generateNode(getState(), autoTransition); + } + + /// \brief Generate a new checker node with the given predecessor. + /// Allows checkers to generate a chain of nodes. + ExplodedNode *generateNode(const ProgramState *state, + ExplodedNode *pred, + const ProgramPointTag *tag = 0, bool autoTransition = true) { - assert(statement && "Only transitions with statements currently supported"); - ExplodedNode *N = generateNodeImpl(statement, state, pred, false); + ExplodedNode *N = generateNodeImpl(state, false, pred, tag); if (N && autoTransition) addTransition(N); return N; } - ExplodedNode *generateNode(const GRState *state, bool autoTransition = true, - const void *tag = 0) { - assert(statement && "Only transitions with statements currently supported"); - ExplodedNode *N = generateNodeImpl(statement, state, false, - tag ? tag : checkerTag); + /// \brief Generate a new checker node. + ExplodedNode *generateNode(const ProgramState *state, + bool autoTransition = true, + const ProgramPointTag *tag = 0) { + ExplodedNode *N = generateNodeImpl(state, false, 0, tag); if (N && autoTransition) addTransition(N); return N; } - ExplodedNode *generateSink(const Stmt *stmt, const GRState *state = 0) { - return generateNodeImpl(stmt, state ? state : getState(), true, - checkerTag); - } - - ExplodedNode *generateSink(const GRState *state = 0) { - assert(statement && "Only transitions with statements currently supported"); - return generateNodeImpl(statement, state ? state : getState(), true, - checkerTag); + /// \brief Generate a sink node. Generating sink stops exploration of the + /// given path. + ExplodedNode *generateSink(const ProgramState *state = 0) { + return generateNodeImpl(state ? state : getState(), true); } void addTransition(ExplodedNode *node) { Dst.Add(node); } - void addTransition(const GRState *state, const void *tag = 0) { + void addTransition(const ProgramState *state, + const ProgramPointTag *tag = 0) { 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))) + if (state != getState() || (ST && ST != Pred->getState())) // state is new or equals to ST. generateNode(state, true, tag); else @@ -163,17 +162,14 @@ public: } private: - ExplodedNode *generateNodeImpl(const Stmt* stmt, const GRState *state, - bool markAsSink, const void *tag) { - ExplodedNode *node = B.generateNode(stmt, state, Pred, tag); - if (markAsSink && node) - node->markAsSink(); - return node; - } - - ExplodedNode *generateNodeImpl(const Stmt* stmt, const GRState *state, - ExplodedNode *pred, bool markAsSink) { - ExplodedNode *node = B.generateNode(stmt, state, pred, checkerTag); + ExplodedNode *generateNodeImpl(const ProgramState *state, + bool markAsSink, + ExplodedNode *pred = 0, + const ProgramPointTag *tag = 0) { + + ExplodedNode *node = B.generateNode(tag ? Location.withTag(tag) : Location, + state, + pred ? pred : Pred); if (markAsSink && node) node->markAsSink(); return node; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h index 199b41a..3f6ddde 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -14,8 +14,8 @@ #ifndef LLVM_CLANG_GR_CONSTRAINT_MANAGER_H #define LLVM_CLANG_GR_CONSTRAINT_MANAGER_H -// FIXME: Typedef LiveSymbolsTy/DeadSymbolsTy at a more appropriate place. -#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" namespace llvm { class APSInt; @@ -25,36 +25,40 @@ namespace clang { namespace ento { -class GRState; -class GRStateManager; +class ProgramState; +class ProgramStateManager; class SubEngine; -class SVal; class ConstraintManager { public: virtual ~ConstraintManager(); - virtual const GRState *assume(const GRState *state, DefinedSVal Cond, - bool Assumption) = 0; + virtual const ProgramState *assume(const ProgramState *state, + DefinedSVal Cond, + bool Assumption) = 0; - std::pair<const GRState*, const GRState*> assumeDual(const GRState *state, - DefinedSVal Cond) { + std::pair<const ProgramState*, const ProgramState*> + assumeDual(const ProgramState *state, DefinedSVal Cond) + { return std::make_pair(assume(state, Cond, true), assume(state, Cond, false)); } - virtual const llvm::APSInt* getSymVal(const GRState *state, + virtual const llvm::APSInt* getSymVal(const ProgramState *state, SymbolRef sym) const = 0; - virtual bool isEqual(const GRState *state, SymbolRef sym, + virtual bool isEqual(const ProgramState *state, + SymbolRef sym, const llvm::APSInt& V) const = 0; - virtual const GRState *removeDeadBindings(const GRState *state, - SymbolReaper& SymReaper) = 0; + virtual const ProgramState *removeDeadBindings(const ProgramState *state, + SymbolReaper& SymReaper) = 0; - virtual void print(const GRState *state, llvm::raw_ostream& Out, - const char* nl, const char *sep) = 0; + virtual void print(const ProgramState *state, + raw_ostream &Out, + const char* nl, + const char *sep) = 0; - virtual void EndPath(const GRState *state) {} + virtual void EndPath(const ProgramState *state) {} /// canReasonAbout - Not all ConstraintManagers can accurately reason about /// all SVal values. This method returns true if the ConstraintManager can @@ -64,9 +68,9 @@ public: virtual bool canReasonAbout(SVal X) const = 0; }; -ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr, +ConstraintManager* CreateBasicConstraintManager(ProgramStateManager& statemgr, SubEngine &subengine); -ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr, +ConstraintManager* CreateRangeConstraintManager(ProgramStateManager& statemgr, SubEngine &subengine); } // end GR namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 2c1d07c..131d39e 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -19,11 +19,12 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h" #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" #include "llvm/ADT/OwningPtr.h" namespace clang { +class ProgramPointTag; + namespace ento { //===----------------------------------------------------------------------===// @@ -77,16 +78,17 @@ private: /// usually because it could not reason about something. BlocksAborted blocksAborted; - void generateNode(const ProgramPoint& Loc, const GRState* State, - ExplodedNode* Pred); + void generateNode(const ProgramPoint &Loc, + const ProgramState *State, + ExplodedNode *Pred); - void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred); - void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred); - void HandleBlockExit(const CFGBlock* B, ExplodedNode* Pred); - void HandlePostStmt(const CFGBlock* B, unsigned StmtIdx, ExplodedNode *Pred); + void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred); + void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred); + void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred); + void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred); - void HandleBranch(const Stmt* Cond, const Stmt* Term, const CFGBlock* B, - ExplodedNode* Pred); + void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B, + ExplodedNode *Pred); void HandleCallEnter(const CallEnter &L, const CFGBlock *Block, unsigned Index, ExplodedNode *Pred); void HandleCallExit(const CallExit &L, ExplodedNode *Pred); @@ -124,9 +126,10 @@ public: /// ExecuteWorkList - Run the worklist algorithm for a maximum number of /// steps. Returns true if there is still simulation state on the worklist. bool ExecuteWorkList(const LocationContext *L, unsigned Steps, - const GRState *InitState); - void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, - const GRState *InitState, + const ProgramState *InitState); + void ExecuteWorkListWithInitialState(const LocationContext *L, + unsigned Steps, + const ProgramState *InitState, ExplodedNodeSet &Dst); // Functions for external checking of whether we have unfinished work @@ -160,41 +163,36 @@ public: class StmtNodeBuilder { CoreEngine& Eng; - const CFGBlock& B; + const CFGBlock &B; const unsigned Idx; - ExplodedNode* Pred; - GRStateManager& Mgr; + ExplodedNode *Pred; + public: bool PurgingDeadSymbols; bool BuildSinks; bool hasGeneratedNode; ProgramPoint::Kind PointKind; - const void *Tag; - - const GRState* CleanedState; - + const ProgramPointTag *Tag; typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy; DeferredTy Deferred; - void GenerateAutoTransition(ExplodedNode* N); + void GenerateAutoTransition(ExplodedNode *N); public: - StmtNodeBuilder(const CFGBlock* b, unsigned idx, ExplodedNode* N, - CoreEngine* e, GRStateManager &mgr); + StmtNodeBuilder(const CFGBlock *b, + unsigned idx, + ExplodedNode *N, + CoreEngine* e); ~StmtNodeBuilder(); - ExplodedNode* getPredecessor() const { return Pred; } + ExplodedNode *getPredecessor() const { return Pred; } // FIXME: This should not be exposed. WorkList *getWorkList() { return Eng.WList; } - void SetCleanedState(const GRState* St) { - CleanedState = St; - } - BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();} unsigned getCurrentBlockCount() const { @@ -203,14 +201,11 @@ public: B.getBlockID()); } - ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) { - hasGeneratedNode = true; - return generateNodeInternal(PP, St, Pred); - } - - ExplodedNode* generateNode(const Stmt *S, const GRState *St, - ExplodedNode *Pred, ProgramPoint::Kind K, - const void *tag = 0) { + ExplodedNode *generateNode(const Stmt *S, + const ProgramState *St, + ExplodedNode *Pred, + ProgramPoint::Kind K, + const ProgramPointTag *tag = 0) { hasGeneratedNode = true; if (PurgingDeadSymbols) @@ -219,59 +214,65 @@ public: return generateNodeInternal(S, St, Pred, K, tag ? tag : Tag); } - ExplodedNode* generateNode(const Stmt *S, const GRState *St, - ExplodedNode *Pred, const void *tag = 0) { + ExplodedNode *generateNode(const Stmt *S, + const ProgramState *St, + ExplodedNode *Pred, + const ProgramPointTag *tag = 0) { return generateNode(S, St, Pred, PointKind, tag); } - ExplodedNode *generateNode(const ProgramPoint &PP, const GRState* State, - ExplodedNode* Pred) { + ExplodedNode *generateNode(const ProgramPoint &PP, + const ProgramState *State, + ExplodedNode *Pred) { hasGeneratedNode = true; return generateNodeInternal(PP, State, Pred); } ExplodedNode* - generateNodeInternal(const ProgramPoint &PP, const GRState* State, - ExplodedNode* Pred); + generateNodeInternal(const ProgramPoint &PP, + const ProgramState *State, + ExplodedNode *Pred); ExplodedNode* - generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred, - ProgramPoint::Kind K = ProgramPoint::PostStmtKind, - const void *tag = 0); + generateNodeInternal(const Stmt *S, + const ProgramState *State, + ExplodedNode *Pred, + ProgramPoint::Kind K, + const ProgramPointTag *tag = 0); /// getStmt - Return the current block-level expression associated with /// this builder. - const Stmt* getStmt() const { + const Stmt *getStmt() const { const CFGStmt *CS = B[Idx].getAs<CFGStmt>(); return CS ? CS->getStmt() : 0; } /// getBlock - Return the CFGBlock associated with the block-level expression /// of this builder. - const CFGBlock* getBlock() const { return &B; } + const CFGBlock *getBlock() const { return &B; } unsigned getIndex() const { return Idx; } - const GRState* GetState(ExplodedNode* Pred) const { - if (Pred == getPredecessor()) - return CleanedState; - else - return Pred->getState(); - } - - ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S, - ExplodedNode* Pred, const GRState* St) { + ExplodedNode *MakeNode(ExplodedNodeSet &Dst, + const Stmt *S, + ExplodedNode *Pred, + const ProgramState *St) { return MakeNode(Dst, S, Pred, St, PointKind); } - ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,ExplodedNode* Pred, - const GRState* St, ProgramPoint::Kind K); + ExplodedNode *MakeNode(ExplodedNodeSet &Dst, + const Stmt *S, + ExplodedNode *Pred, + const ProgramState *St, + ProgramPoint::Kind K); - ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, const Stmt* S, - ExplodedNode* Pred, const GRState* St) { + ExplodedNode *MakeSinkNode(ExplodedNodeSet &Dst, + const Stmt *S, + ExplodedNode *Pred, + const ProgramState *St) { bool Tmp = BuildSinks; BuildSinks = true; - ExplodedNode* N = MakeNode(Dst, S, Pred, St); + ExplodedNode *N = MakeNode(Dst, S, Pred, St); BuildSinks = Tmp; return N; } @@ -279,12 +280,12 @@ public: class BranchNodeBuilder { CoreEngine& Eng; - const CFGBlock* Src; - const CFGBlock* DstT; - const CFGBlock* DstF; - ExplodedNode* Pred; + const CFGBlock *Src; + const CFGBlock *DstT; + const CFGBlock *DstF; + ExplodedNode *Pred; - typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy; + typedef SmallVector<ExplodedNode*,3> DeferredTy; DeferredTy Deferred; bool GeneratedTrue; @@ -293,25 +294,27 @@ class BranchNodeBuilder { bool InFeasibleFalse; public: - BranchNodeBuilder(const CFGBlock* src, const CFGBlock* dstT, - const CFGBlock* dstF, ExplodedNode* pred, CoreEngine* e) + BranchNodeBuilder(const CFGBlock *src, const CFGBlock *dstT, + const CFGBlock *dstF, ExplodedNode *pred, CoreEngine* e) : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred), GeneratedTrue(false), GeneratedFalse(false), InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {} ~BranchNodeBuilder(); - ExplodedNode* getPredecessor() const { return Pred; } + ExplodedNode *getPredecessor() const { return Pred; } const ExplodedGraph& getGraph() const { return *Eng.G; } BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();} - ExplodedNode* generateNode(const Stmt *Condition, const GRState* State); + /// This function generates a new ExplodedNode but not a new + /// branch(block edge). + ExplodedNode *generateNode(const Stmt *Condition, const ProgramState *State); - ExplodedNode* generateNode(const GRState* State, bool branch); + ExplodedNode *generateNode(const ProgramState *State, bool branch); - const CFGBlock* getTargetBlock(bool branch) const { + const CFGBlock *getTargetBlock(bool branch) const { return branch ? DstT : DstF; } @@ -326,21 +329,21 @@ public: return branch ? !InFeasibleTrue : !InFeasibleFalse; } - const GRState* getState() const { + const ProgramState *getState() const { return getPredecessor()->getState(); } }; class IndirectGotoNodeBuilder { CoreEngine& Eng; - const CFGBlock* Src; - const CFGBlock& DispatchBlock; - const Expr* E; - ExplodedNode* Pred; + const CFGBlock *Src; + const CFGBlock &DispatchBlock; + const Expr *E; + ExplodedNode *Pred; public: - IndirectGotoNodeBuilder(ExplodedNode* pred, const CFGBlock* src, - const Expr* e, const CFGBlock* dispatch, CoreEngine* eng) + IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, + const Expr *e, const CFGBlock *dispatch, CoreEngine* eng) : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {} class iterator { @@ -350,8 +353,8 @@ public: iterator(CFGBlock::const_succ_iterator i) : I(i) {} public: - iterator& operator++() { ++I; return *this; } - bool operator!=(const iterator& X) const { return I != X.I; } + iterator &operator++() { ++I; return *this; } + bool operator!=(const iterator &X) const { return I != X.I; } const LabelDecl *getLabel() const { return llvm::cast<LabelStmt>((*I)->getLabel())->getDecl(); @@ -365,23 +368,24 @@ public: iterator begin() { return iterator(DispatchBlock.succ_begin()); } iterator end() { return iterator(DispatchBlock.succ_end()); } - ExplodedNode* generateNode(const iterator& I, const GRState* State, + ExplodedNode *generateNode(const iterator &I, + const ProgramState *State, bool isSink = false); - const Expr* getTarget() const { return E; } + const Expr *getTarget() const { return E; } - const GRState* getState() const { return Pred->State; } + const ProgramState *getState() const { return Pred->State; } }; class SwitchNodeBuilder { CoreEngine& Eng; - const CFGBlock* Src; - const Expr* Condition; - ExplodedNode* Pred; + const CFGBlock *Src; + const Expr *Condition; + ExplodedNode *Pred; public: - SwitchNodeBuilder(ExplodedNode* pred, const CFGBlock* src, - const Expr* condition, CoreEngine* eng) + SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src, + const Expr *condition, CoreEngine* eng) : Eng(*eng), Src(src), Condition(condition), Pred(pred) {} class iterator { @@ -391,15 +395,15 @@ public: iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {} public: - iterator& operator++() { ++I; return *this; } + iterator &operator++() { ++I; return *this; } bool operator!=(const iterator &X) const { return I != X.I; } bool operator==(const iterator &X) const { return I == X.I; } - const CaseStmt* getCase() const { + const CaseStmt *getCase() const { return llvm::cast<CaseStmt>((*I)->getLabel()); } - const CFGBlock* getBlock() const { + const CFGBlock *getBlock() const { return *I; } }; @@ -411,14 +415,15 @@ public: return llvm::cast<SwitchStmt>(Src->getTerminator()); } - ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State); + ExplodedNode *generateCaseStmtNode(const iterator &I, + const ProgramState *State); - ExplodedNode* generateDefaultCaseNode(const GRState* State, + ExplodedNode *generateDefaultCaseNode(const ProgramState *State, bool isSink = false); - const Expr* getCondition() const { return Condition; } + const Expr *getCondition() const { return Condition; } - const GRState* getState() const { return Pred->State; } + const ProgramState *getState() const { return Pred->State; } }; class GenericNodeBuilderImpl { @@ -426,10 +431,12 @@ protected: CoreEngine &engine; ExplodedNode *pred; ProgramPoint pp; - llvm::SmallVector<ExplodedNode*, 2> sinksGenerated; + SmallVector<ExplodedNode*, 2> sinksGenerated; - ExplodedNode *generateNodeImpl(const GRState *state, ExplodedNode *pred, - ProgramPoint programPoint, bool asSink); + ExplodedNode *generateNodeImpl(const ProgramState *state, + ExplodedNode *pred, + ProgramPoint programPoint, + bool asSink); GenericNodeBuilderImpl(CoreEngine &eng, ExplodedNode *pr, ProgramPoint p) : engine(eng), pred(pr), pp(p), hasGeneratedNode(false) {} @@ -439,13 +446,13 @@ public: WorkList &getWorkList() { return *engine.WList; } - ExplodedNode* getPredecessor() const { return pred; } + ExplodedNode *getPredecessor() const { return pred; } BlockCounter getBlockCounter() const { return engine.WList->getBlockCounter(); } - const llvm::SmallVectorImpl<ExplodedNode*> &sinks() const { + const SmallVectorImpl<ExplodedNode*> &sinks() const { return sinksGenerated; } }; @@ -456,8 +463,8 @@ public: GenericNodeBuilder(CoreEngine &eng, ExplodedNode *pr, const PP_T &p) : GenericNodeBuilderImpl(eng, pr, p) {} - ExplodedNode *generateNode(const GRState *state, ExplodedNode *pred, - const void *tag, bool asSink) { + ExplodedNode *generateNode(const ProgramState *state, ExplodedNode *pred, + const ProgramPointTag *tag, bool asSink) { return generateNodeImpl(state, pred, cast<PP_T>(pp).withTag(tag), asSink); } @@ -467,27 +474,27 @@ public: class EndOfFunctionNodeBuilder { CoreEngine &Eng; - const CFGBlock& B; - ExplodedNode* Pred; - void *Tag; + const CFGBlock &B; + ExplodedNode *Pred; + const ProgramPointTag *Tag; public: bool hasGeneratedNode; public: - EndOfFunctionNodeBuilder(const CFGBlock* b, ExplodedNode* N, CoreEngine* e, - void *checkerTag = 0) - : Eng(*e), B(*b), Pred(N), Tag(checkerTag), hasGeneratedNode(false) {} + EndOfFunctionNodeBuilder(const CFGBlock *b, ExplodedNode *N, CoreEngine* e, + const ProgramPointTag *tag = 0) + : Eng(*e), B(*b), Pred(N), Tag(tag), hasGeneratedNode(false) {} ~EndOfFunctionNodeBuilder(); - EndOfFunctionNodeBuilder withCheckerTag(void *tag) { + EndOfFunctionNodeBuilder withCheckerTag(const ProgramPointTag *tag) { return EndOfFunctionNodeBuilder(&B, Pred, &Eng, tag); } WorkList &getWorkList() { return *Eng.WList; } - ExplodedNode* getPredecessor() const { return Pred; } + ExplodedNode *getPredecessor() const { return Pred; } BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter(); @@ -499,14 +506,15 @@ public: B.getBlockID()); } - ExplodedNode* generateNode(const GRState* State, ExplodedNode *P = 0, - const void *tag = 0); + ExplodedNode *generateNode(const ProgramState *State, + ExplodedNode *P = 0, + const ProgramPointTag *tag = 0); - void GenerateCallExitNode(const GRState *state); + void GenerateCallExitNode(const ProgramState *state); - const CFGBlock* getBlock() const { return &B; } + const CFGBlock *getBlock() const { return &B; } - const GRState* getState() const { + const ProgramState *getState() const { return getPredecessor()->getState(); } }; @@ -535,7 +543,7 @@ public: const CFGBlock *blk, unsigned idx) : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {} - const GRState *getState() const { return Pred->getState(); } + const ProgramState *getState() const { return Pred->getState(); } const LocationContext *getLocationContext() const { return Pred->getLocationContext(); @@ -549,7 +557,7 @@ public: unsigned getIndex() const { return Index; } - void generateNode(const GRState *state); + void generateNode(const ProgramState *state); }; class CallExitNodeBuilder { @@ -562,9 +570,9 @@ public: const ExplodedNode *getPredecessor() const { return Pred; } - const GRState *getState() const { return Pred->getState(); } + const ProgramState *getState() const { return Pred->getState(); } - void generateNode(const GRState *state); + void generateNode(const ProgramState *state); }; } // end GR namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h index 193056e..2463e23 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h @@ -14,7 +14,6 @@ #ifndef LLVM_CLANG_GR_ENVIRONMENT_H #define LLVM_CLANG_GR_ENVIRONMENT_H -#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/ADT/ImmutableMap.h" @@ -43,7 +42,7 @@ private: Environment(BindingsTy eb) : ExprBindings(eb) {} - SVal lookupExpr(const Stmt* E) const; + SVal lookupExpr(const Stmt *E) const; public: typedef BindingsTy::iterator iterator; @@ -53,7 +52,7 @@ public: /// getSVal - Fetches the current binding of the expression in the /// Environment. - SVal getSVal(const Stmt* Ex, SValBuilder& svalBuilder, + SVal getSVal(const Stmt *Ex, SValBuilder& svalBuilder, bool useOnlyDirectBindings = false) const; /// Profile - Profile the contents of an Environment object for use @@ -96,8 +95,7 @@ public: SVal V); Environment removeDeadBindings(Environment Env, - SymbolReaper &SymReaper, const GRState *ST, - llvm::SmallVectorImpl<const MemRegion*>& RegionRoots); + SymbolReaper &SymReaper, const ProgramState *ST); }; } // end GR namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index e5d6876..fdfed3d 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -31,7 +31,7 @@ #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/Support/Casting.h" #include "clang/Analysis/Support/BumpVector.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" namespace clang { @@ -67,7 +67,7 @@ class ExplodedNode : public llvm::FoldingSetNode { return P & 0x1; } - void* getPtr() const { + void *getPtr() const { assert (!getFlag()); return reinterpret_cast<void*>(P & ~Mask); } @@ -87,7 +87,7 @@ class ExplodedNode : public llvm::FoldingSetNode { bool empty() const { return (P & ~Mask) == 0; } - void addNode(ExplodedNode* N, ExplodedGraph &G); + void addNode(ExplodedNode *N, ExplodedGraph &G); void replaceNode(ExplodedNode *node); @@ -106,7 +106,7 @@ class ExplodedNode : public llvm::FoldingSetNode { const ProgramPoint Location; /// State - The state associated with this node. - const GRState* State; + const ProgramState *State; /// Preds - The predecessors of this node. NodeGroup Preds; @@ -116,13 +116,13 @@ class ExplodedNode : public llvm::FoldingSetNode { public: - explicit ExplodedNode(const ProgramPoint& loc, const GRState* state) + explicit ExplodedNode(const ProgramPoint &loc, const ProgramState *state) : Location(loc), State(state) { - const_cast<GRState*>(State)->incrementReferenceCount(); + const_cast<ProgramState*>(State)->incrementReferenceCount(); } ~ExplodedNode() { - const_cast<GRState*>(State)->decrementReferenceCount(); + const_cast<ProgramState*>(State)->decrementReferenceCount(); } /// getLocation - Returns the edge associated with the given node. @@ -138,17 +138,18 @@ public: ParentMap &getParentMap() const {return getLocationContext()->getParentMap();} - LiveVariables &getLiveVariables() const { - return *getLocationContext()->getLiveVariables(); + template <typename T> + T &getAnalysis() const { + return *getLocationContext()->getAnalysis<T>(); } - const GRState* getState() const { return State; } + const ProgramState *getState() const { return State; } template <typename T> const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); } static void Profile(llvm::FoldingSetNodeID &ID, - const ProgramPoint& Loc, const GRState* state) { + const ProgramPoint &Loc, const ProgramState *state) { ID.Add(Loc); ID.AddPointer(state); } @@ -159,7 +160,7 @@ public: /// addPredeccessor - Adds a predecessor to the current node, and /// in tandem add this node as a successor of the other node. - void addPredecessor(ExplodedNode* V, ExplodedGraph &G); + void addPredecessor(ExplodedNode *V, ExplodedGraph &G); unsigned succ_size() const { return Succs.size(); } unsigned pred_size() const { return Preds.size(); } @@ -169,11 +170,11 @@ public: bool isSink() const { return Succs.getFlag(); } void markAsSink() { Succs.setFlag(); } - ExplodedNode* getFirstPred() { + ExplodedNode *getFirstPred() { return pred_empty() ? NULL : *(pred_begin()); } - const ExplodedNode* getFirstPred() const { + const ExplodedNode *getFirstPred() const { return const_cast<ExplodedNode*>(this)->getFirstPred(); } @@ -210,7 +211,7 @@ public: class Auditor { public: virtual ~Auditor(); - virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst) = 0; + virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) = 0; }; static void SetAuditor(Auditor* A); @@ -226,7 +227,7 @@ class InterExplodedGraphMap { friend class ExplodedGraph; public: - ExplodedNode* getMappedNode(const ExplodedNode* N) const; + ExplodedNode *getMappedNode(const ExplodedNode *N) const; InterExplodedGraphMap() {} virtual ~InterExplodedGraphMap() {} @@ -237,8 +238,8 @@ protected: friend class CoreEngine; // Type definitions. - typedef llvm::SmallVector<ExplodedNode*,2> RootsTy; - typedef llvm::SmallVector<ExplodedNode*,10> EndNodesTy; + typedef SmallVector<ExplodedNode*,2> RootsTy; + typedef SmallVector<ExplodedNode*,10> EndNodesTy; /// Roots - The roots of the simulation graph. Usually there will be only /// one, but clients are free to establish multiple subgraphs within a single @@ -275,7 +276,7 @@ public: /// this pair exists, it is created. IsNew is set to true if /// the node was freshly created. - ExplodedNode* getNode(const ProgramPoint& L, const GRState *State, + ExplodedNode *getNode(const ProgramPoint &L, const ProgramState *State, bool* IsNew = 0); ExplodedGraph* MakeEmptyGraph() const { @@ -283,13 +284,13 @@ public: } /// addRoot - Add an untyped node to the set of roots. - ExplodedNode* addRoot(ExplodedNode* V) { + ExplodedNode *addRoot(ExplodedNode *V) { Roots.push_back(V); return V; } /// addEndOfPath - Add an untyped node to the set of EOP nodes. - ExplodedNode* addEndOfPath(ExplodedNode* V) { + ExplodedNode *addEndOfPath(ExplodedNode *V) { EndNodes.push_back(V); return V; } @@ -368,18 +369,18 @@ class ExplodedNodeSet { ImplTy Impl; public: - ExplodedNodeSet(ExplodedNode* N) { + ExplodedNodeSet(ExplodedNode *N) { assert (N && !static_cast<ExplodedNode*>(N)->isSink()); Impl.insert(N); } ExplodedNodeSet() {} - inline void Add(ExplodedNode* N) { + inline void Add(ExplodedNode *N) { if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N); } - ExplodedNodeSet& operator=(const ExplodedNodeSet &X) { + ExplodedNodeSet &operator=(const ExplodedNodeSet &X) { Impl = X.Impl; return *this; } diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index d24036c..9bc470f 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -19,9 +19,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/AST/Type.h" #include "clang/AST/ExprObjC.h" @@ -35,6 +33,8 @@ class ObjCForCollectionStmt; namespace ento { class AnalysisManager; +class CallOrObjCMessage; +class ObjCMessage; class ExprEngine : public SubEngine { AnalysisManager &AMgr; @@ -49,7 +49,7 @@ class ExprEngine : public SubEngine { StmtNodeBuilder* Builder; /// StateMgr - Object that manages the data for all created states. - GRStateManager StateMgr; + ProgramStateManager StateMgr; /// SymMgr - Object that manages the symbol information. SymbolManager& SymMgr; @@ -58,31 +58,32 @@ class ExprEngine : public SubEngine { SValBuilder &svalBuilder; /// EntryNode - The immediate predecessor node. - ExplodedNode* EntryNode; + ExplodedNode *EntryNode; /// CleanedState - The state for EntryNode "cleaned" of all dead /// variables and symbols (as determined by a liveness analysis). - const GRState* CleanedState; + const ProgramState *CleanedState; /// currentStmt - The current block-level statement. - const Stmt* currentStmt; + const Stmt *currentStmt; - // Obj-C Class Identifiers. + /// Obj-C Class Identifiers. IdentifierInfo* NSExceptionII; - // Obj-C Selectors. + /// Obj-C Selectors. Selector* NSExceptionInstanceRaiseSelectors; Selector RaiseSel; + + /// Whether or not GC is enabled in this analysis. + bool ObjCGCEnabled; /// The BugReporter associated with this engine. It is important that /// this object be placed at the very end of member variables so that its /// destructor is called before the rest of the ExprEngine is destroyed. GRBugReporter BR; - - llvm::OwningPtr<TransferFuncs> TF; public: - ExprEngine(AnalysisManager &mgr, TransferFuncs *tf); + ExprEngine(AnalysisManager &mgr, bool gcEnabled); ~ExprEngine(); @@ -94,13 +95,13 @@ public: /// of the function are added into the Dst set, which represent the exit /// state of the function call. void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, - const GRState *InitState, + const ProgramState *InitState, ExplodedNodeSet &Dst) { Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); } /// getContext - Return the ASTContext associated with this analysis. - ASTContext& getContext() const { return AMgr.getASTContext(); } + ASTContext &getContext() const { return AMgr.getASTContext(); } virtual AnalysisManager &getAnalysisManager() { return AMgr; } @@ -110,14 +111,11 @@ public: SValBuilder &getSValBuilder() { return svalBuilder; } - TransferFuncs& getTF() { return *TF; } - BugReporter& getBugReporter() { return BR; } StmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; } - // FIXME: Remove once TransferFuncs is no longer referenced. - void setTransferFunction(TransferFuncs* tf); + bool isObjCGCEnabled() { return ObjCGCEnabled; } /// ViewGraph - Visualize the ExplodedGraph created by executing the /// simulation. @@ -127,7 +125,7 @@ public: /// getInitialState - Return the initial state used for the root vertex /// in the ExplodedGraph. - const GRState* getInitialState(const LocationContext *InitLoc); + const ProgramState *getInitialState(const LocationContext *InitLoc); ExplodedGraph& getGraph() { return G; } const ExplodedGraph& getGraph() const { return G; } @@ -155,7 +153,7 @@ public: /// ProcessBranch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a branch condition. - void processBranch(const Stmt* Condition, const Stmt* Term, + void processBranch(const Stmt *Condition, const Stmt *Term, BranchNodeBuilder& builder); /// processIndirectGoto - Called by CoreEngine. Used to generate successor @@ -181,21 +179,25 @@ public: /// evalAssume - Callback function invoked by the ConstraintManager when /// making assumptions about state values. - const GRState *processAssume(const GRState *state, SVal cond,bool assumption); + const ProgramState *processAssume(const ProgramState *state, SVal cond,bool assumption); - /// wantsRegionChangeUpdate - Called by GRStateManager to determine if a + /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a /// region change should trigger a processRegionChanges update. - bool wantsRegionChangeUpdate(const GRState* state); + bool wantsRegionChangeUpdate(const ProgramState *state); - /// processRegionChanges - Called by GRStateManager whenever a change is made + /// processRegionChanges - Called by ProgramStateManager whenever a change is made /// to the store. Used to update checkers that track region values. - const GRState * - processRegionChanges(const GRState *state, + const ProgramState * + processRegionChanges(const ProgramState *state, const StoreManager::InvalidatedSymbols *invalidated, - const MemRegion * const *Begin, - const MemRegion * const *End); + ArrayRef<const MemRegion *> ExplicitRegions, + ArrayRef<const MemRegion *> Regions); - virtual GRStateManager& getStateManager() { return StateMgr; } + /// printState - Called by ProgramStateManager to print checker-specific data. + void printState(raw_ostream &Out, const ProgramState *State, + const char *NL, const char *Sep); + + virtual ProgramStateManager& getStateManager() { return StateMgr; } StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } @@ -222,124 +224,109 @@ public: const CoreEngine &getCoreEngine() const { return Engine; } -protected: - const GRState* GetState(ExplodedNode* N) { - return N == EntryNode ? CleanedState : N->getState(); - } - public: - ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S, - ExplodedNode* Pred, const GRState* St, + ExplodedNode *MakeNode(ExplodedNodeSet &Dst, const Stmt *S, + ExplodedNode *Pred, const ProgramState *St, ProgramPoint::Kind K = ProgramPoint::PostStmtKind, - const void *tag = 0); + const ProgramPointTag *tag = 0); /// Visit - Transfer function logic for all statements. Dispatches to /// other functions that handle specific kinds of statements. - void Visit(const Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst); + void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitArraySubscriptExpr - Transfer function for array accesses. - void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr* Ex, - ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex, + ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitAsmStmt - Transfer function logic for inline asm. - void VisitAsmStmt(const AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst); + void VisitAsmStmt(const AsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst); - void VisitAsmStmtHelperOutputs(const AsmStmt* A, + void VisitAsmStmtHelperOutputs(const AsmStmt *A, AsmStmt::const_outputs_iterator I, AsmStmt::const_outputs_iterator E, - ExplodedNode* Pred, ExplodedNodeSet& Dst); + ExplodedNode *Pred, ExplodedNodeSet &Dst); - void VisitAsmStmtHelperInputs(const AsmStmt* A, + void VisitAsmStmtHelperInputs(const AsmStmt *A, AsmStmt::const_inputs_iterator I, AsmStmt::const_inputs_iterator E, - ExplodedNode* Pred, ExplodedNodeSet& Dst); + ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitBlockExpr - Transfer function logic for BlockExprs. void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitBinaryOperator - Transfer function logic for binary operators. - void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitCall - Transfer function for function calls. - void VisitCallExpr(const CallExpr* CE, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitCast - Transfer function logic for all casts (implicit and explicit). void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. - void VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL, - ExplodedNode* Pred, ExplodedNodeSet& Dst); + void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, + ExplodedNode *Pred, ExplodedNodeSet &Dst); /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs. - void VisitCommonDeclRefExpr(const Expr* DR, const NamedDecl *D, - ExplodedNode* Pred, ExplodedNodeSet& Dst); + void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, + ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitDeclStmt - Transfer function logic for DeclStmts. - void VisitDeclStmt(const DeclStmt* DS, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose - void VisitGuardedExpr(const Expr* Ex, const Expr* L, const Expr* R, - ExplodedNode* Pred, ExplodedNodeSet& Dst); + void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, + ExplodedNode *Pred, ExplodedNodeSet &Dst); - void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitLogicalExpr - Transfer function logic for '&&', '||' - void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitMemberExpr - Transfer function for member expressions. - void VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// Transfer function logic for ObjCAtSynchronizedStmts. void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); - void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E, - ExplodedNode *Pred, ExplodedNodeSet &Dst); - /// Transfer function logic for computing the lvalue of an Objective-C ivar. - void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr* DR, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitObjCForCollectionStmt - Transfer function logic for /// ObjCForCollectionStmt. - void VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S, - ExplodedNode* Pred, ExplodedNodeSet& Dst); + void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, + ExplodedNode *Pred, ExplodedNodeSet &Dst); - void VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S, - ExplodedNode* Pred, - ExplodedNodeSet& Dst, SVal ElementV); - - /// VisitObjCMessageExpr - Transfer function for ObjC message expressions. - void VisitObjCMessageExpr(const ObjCMessageExpr* ME, ExplodedNode* Pred, - ExplodedNodeSet& Dst); - void VisitObjCMessage(const ObjCMessage &msg, ExplodedNodeSet &Src, - ExplodedNodeSet& Dst); + void VisitObjCMessage(const ObjCMessage &msg, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitReturnStmt - Transfer function logic for return statements. - void VisitReturnStmt(const ReturnStmt* R, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitOffsetOfExpr - Transfer function for offsetof. - void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof. - void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr* Ex, - ExplodedNode* Pred, ExplodedNodeSet& Dst); + void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, + ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitUnaryOperator - Transfer function logic for unary operators. - void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred, - ExplodedNodeSet& Dst); + void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, + ExplodedNodeSet &Dst); void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet & Dst); @@ -366,7 +353,8 @@ public: ExplodedNodeSet &Dst); /// Create a C++ temporary object for an rvalue. - void CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred, + void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, + ExplodedNode *Pred, ExplodedNodeSet &Dst); /// Synthesize CXXThisRegion. @@ -389,8 +377,11 @@ public: /// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) /// with those assumptions. - void evalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, + void evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex); + + std::pair<const ProgramPointTag *, const ProgramPointTag*> + getEagerlyAssumeTags(); SVal evalMinus(SVal X) { return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X; @@ -402,36 +393,36 @@ public: public: - SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op, + SVal evalBinOp(const ProgramState *state, BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) { return svalBuilder.evalBinOpNN(state, op, L, R, T); } - SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op, + SVal evalBinOp(const ProgramState *state, BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) { return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R; } - SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op, + SVal evalBinOp(const ProgramState *ST, BinaryOperator::Opcode Op, SVal LHS, SVal RHS, QualType T) { return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); } protected: - void evalObjCMessage(ExplodedNodeSet& Dst, const ObjCMessage &msg, - ExplodedNode* Pred, const GRState *state) { - assert (Builder && "StmtNodeBuilder must be defined."); - getTF().evalObjCMessage(Dst, *this, *Builder, msg, Pred, state); - } + void evalObjCMessage(ExplodedNodeSet &Dst, const ObjCMessage &msg, + ExplodedNode *Pred, const ProgramState *state); + + const ProgramState *invalidateArguments(const ProgramState *State, + const CallOrObjCMessage &Call, + const LocationContext *LC); - const GRState* MarkBranch(const GRState* St, const Stmt* Terminator, + const ProgramState *MarkBranch(const ProgramState *St, const Stmt *Terminator, bool branchTaken); /// evalBind - Handle the semantics of binding a value to a specific location. /// This method is used by evalStore, VisitDeclStmt, and others. - void evalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred, - const GRState* St, SVal location, SVal Val, - bool atDeclInit = false); + void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, + SVal location, SVal Val, bool atDeclInit = false); public: // FIXME: 'tag' should be removed, and a LocationContext should be used @@ -440,25 +431,25 @@ public: // be the same as Pred->state, and when 'location' may not be the // same as state->getLValue(Ex). /// Simulate a read of the result of Ex. - void evalLoad(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred, - const GRState* St, SVal location, const void *tag = 0, + void evalLoad(ExplodedNodeSet &Dst, const Expr *Ex, ExplodedNode *Pred, + const ProgramState *St, SVal location, const ProgramPointTag *tag = 0, QualType LoadTy = QualType()); // FIXME: 'tag' should be removed, and a LocationContext should be used // instead. - void evalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE, - ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val, - const void *tag = 0); + void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, + ExplodedNode *Pred, const ProgramState *St, SVal TargetLV, SVal Val, + const ProgramPointTag *tag = 0); private: - void evalLoadCommon(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred, - const GRState* St, SVal location, const void *tag, + void evalLoadCommon(ExplodedNodeSet &Dst, const Expr *Ex, ExplodedNode *Pred, + const ProgramState *St, SVal location, const ProgramPointTag *tag, QualType LoadTy); // FIXME: 'tag' should be removed, and a LocationContext should be used // instead. - void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred, - const GRState* St, SVal location, - const void *tag, bool isLoad); + void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode *Pred, + const ProgramState *St, SVal location, + const ProgramPointTag *tag, bool isLoad); bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred); diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngineBuilders.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngineBuilders.h index 18e39d9..89b47dc 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngineBuilders.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngineBuilders.h @@ -25,9 +25,9 @@ class StmtNodeBuilderRef { ExplodedNodeSet &Dst; StmtNodeBuilder &B; ExprEngine& Eng; - ExplodedNode* Pred; - const GRState* state; - const Stmt* stmt; + ExplodedNode *Pred; + const ProgramState *state; + const Stmt *stmt; const unsigned OldSize; const bool AutoCreateNode; SaveAndRestore<bool> OldSink; @@ -42,9 +42,9 @@ private: StmtNodeBuilderRef(ExplodedNodeSet &dst, StmtNodeBuilder &builder, ExprEngine& eng, - ExplodedNode* pred, - const GRState *st, - const Stmt* s, bool auto_create_node) + ExplodedNode *pred, + const ProgramState *st, + const Stmt *s, bool auto_create_node) : Dst(dst), B(builder), Eng(eng), Pred(pred), state(st), stmt(s), OldSize(Dst.size()), AutoCreateNode(auto_create_node), OldSink(B.BuildSinks), OldHasGen(B.hasGeneratedNode) {} @@ -62,13 +62,13 @@ public: } } - const GRState *getState() { return state; } + const ProgramState *getState() { return state; } - GRStateManager& getStateManager() { + ProgramStateManager& getStateManager() { return Eng.getStateManager(); } - ExplodedNode* MakeNode(const GRState* state) { + ExplodedNode *MakeNode(const ProgramState *state) { return B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state); } }; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index db7a930..c9941fe 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -19,15 +19,14 @@ #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/ADT/FoldingSet.h" #include <string> namespace llvm { class BumpPtrAllocator; -class raw_ostream; } namespace clang { @@ -83,12 +82,13 @@ public: // Untyped regions. SymbolicRegionKind, AllocaRegionKind, + BlockDataRegionKind, // Typed regions. BEG_TYPED_REGIONS, FunctionTextRegionKind = BEG_TYPED_REGIONS, BlockTextRegionKind, - BlockDataRegionKind, - CompoundLiteralRegionKind, + BEG_TYPED_VALUE_REGIONS, + CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS, CXXThisRegionKind, StringRegionKind, ElementRegionKind, @@ -100,6 +100,7 @@ public: END_DECL_REGIONS = ObjCIvarRegionKind, CXXTempObjectRegionKind, CXXBaseObjectRegionKind, + END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind, END_TYPED_REGIONS = CXXBaseObjectRegionKind }; @@ -136,7 +137,7 @@ public: /// Compute the offset within the top level memory object. RegionOffset getAsOffset() const; - virtual void dumpToStream(llvm::raw_ostream& os) const; + virtual void dumpToStream(raw_ostream &os) const; void dump() const; @@ -197,7 +198,7 @@ class StaticGlobalSpaceRegion : public GlobalsSpaceRegion { public: void Profile(llvm::FoldingSetNodeID &ID) const; - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; const CodeTextRegion *getCodeRegion() const { return CR; } @@ -214,7 +215,7 @@ class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { public: - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; static bool classof(const MemRegion *R) { return R->getKind() == NonStaticGlobalSpaceRegionKind; @@ -323,14 +324,14 @@ class AllocaRegion : public SubRegion { protected: unsigned Cnt; // Block counter. Used to distinguish different pieces of // memory allocated by alloca at the same call site. - const Expr* Ex; + const Expr *Ex; - AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion *superRegion) + AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion) : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} public: - const Expr* getExpr() const { return Ex; } + const Expr *getExpr() const { return Ex; } bool isBoundable() const { return true; } @@ -338,10 +339,10 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex, + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, unsigned Cnt, const MemRegion *superRegion); - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; static bool classof(const MemRegion* R) { return R->getKind() == AllocaRegionKind; @@ -354,6 +355,26 @@ protected: TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} public: + virtual QualType getLocationType() const = 0; + + QualType getDesugaredLocationType(ASTContext &Context) const { + return getLocationType().getDesugaredType(Context); + } + + bool isBoundable() const { return true; } + + static bool classof(const MemRegion* R) { + unsigned k = R->getKind(); + return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS; + } +}; + +/// TypedValueRegion - An abstract class representing regions having a typed value. +class TypedValueRegion : public TypedRegion { +protected: + TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {} + +public: virtual QualType getValueType() const = 0; virtual QualType getLocationType() const { @@ -370,15 +391,9 @@ public: return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; } - QualType getDesugaredLocationType(ASTContext &Context) const { - return getLocationType().getDesugaredType(Context); - } - - bool isBoundable() const { return true; } - static bool classof(const MemRegion* R) { unsigned k = R->getKind(); - return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS; + return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; } }; @@ -387,11 +402,6 @@ class CodeTextRegion : public TypedRegion { protected: CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {} public: - QualType getValueType() const { - assert(0 && "Do not get the object type of a CodeTextRegion."); - return QualType(); - } - bool isBoundable() const { return false; } static bool classof(const MemRegion* R) { @@ -404,7 +414,7 @@ public: class FunctionTextRegion : public CodeTextRegion { const FunctionDecl *FD; public: - FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg) + FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg) : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {} QualType getLocationType() const { @@ -415,7 +425,7 @@ public: return FD; } - virtual void dumpToStream(llvm::raw_ostream& os) const; + virtual void dumpToStream(raw_ostream &os) const; void Profile(llvm::FoldingSetNodeID& ID) const; @@ -456,7 +466,7 @@ public: AnalysisContext *getAnalysisContext() const { return AC; } - virtual void dumpToStream(llvm::raw_ostream& os) const; + virtual void dumpToStream(raw_ostream &os) const; void Profile(llvm::FoldingSetNodeID& ID) const; @@ -509,7 +519,7 @@ public: bool operator!=(const referenced_vars_iterator &I) const { return I.R != R; } - referenced_vars_iterator& operator++() { + referenced_vars_iterator &operator++() { ++R; return *this; } @@ -518,7 +528,7 @@ public: referenced_vars_iterator referenced_vars_begin() const; referenced_vars_iterator referenced_vars_end() const; - virtual void dumpToStream(llvm::raw_ostream& os) const; + virtual void dumpToStream(raw_ostream &os) const; void Profile(llvm::FoldingSetNodeID& ID) const; @@ -559,7 +569,7 @@ public: SymbolRef sym, const MemRegion* superRegion); - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; static bool classof(const MemRegion* R) { return R->getKind() == SymbolicRegionKind; @@ -567,13 +577,13 @@ public: }; /// StringRegion - Region associated with a StringLiteral. -class StringRegion : public TypedRegion { +class StringRegion : public TypedValueRegion { friend class MemRegionManager; const StringLiteral* Str; protected: StringRegion(const StringLiteral* str, const MemRegion* sreg) - : TypedRegion(sreg, StringRegionKind), Str(str) {} + : TypedValueRegion(sreg, StringRegionKind), Str(str) {} static void ProfileRegion(llvm::FoldingSetNodeID& ID, const StringLiteral* Str, @@ -595,7 +605,7 @@ public: ProfileRegion(ID, Str, superRegion); } - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; static bool classof(const MemRegion* R) { return R->getKind() == StringRegionKind; @@ -605,16 +615,16 @@ public: /// CompoundLiteralRegion - A memory region representing a compound literal. /// Compound literals are essentially temporaries that are stack allocated /// or in the global constant pool. -class CompoundLiteralRegion : public TypedRegion { +class CompoundLiteralRegion : public TypedValueRegion { private: friend class MemRegionManager; - const CompoundLiteralExpr* CL; + const CompoundLiteralExpr *CL; - CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg) - : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} + CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg) + : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} static void ProfileRegion(llvm::FoldingSetNodeID& ID, - const CompoundLiteralExpr* CL, + const CompoundLiteralExpr *CL, const MemRegion* superRegion); public: QualType getValueType() const { @@ -625,27 +635,27 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const; - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; - const CompoundLiteralExpr* getLiteralExpr() const { return CL; } + const CompoundLiteralExpr *getLiteralExpr() const { return CL; } static bool classof(const MemRegion* R) { return R->getKind() == CompoundLiteralRegionKind; } }; -class DeclRegion : public TypedRegion { +class DeclRegion : public TypedValueRegion { protected: - const Decl* D; + const Decl *D; - DeclRegion(const Decl* d, const MemRegion* sReg, Kind k) - : TypedRegion(sReg, k), D(d) {} + DeclRegion(const Decl *d, const MemRegion* sReg, Kind k) + : TypedValueRegion(sReg, k), D(d) {} - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D, + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, const MemRegion* superRegion, Kind k); public: - const Decl* getDecl() const { return D; } + const Decl *getDecl() const { return D; } void Profile(llvm::FoldingSetNodeID& ID) const; DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; @@ -660,10 +670,10 @@ class VarRegion : public DeclRegion { friend class MemRegionManager; // Constructors and private methods. - VarRegion(const VarDecl* vd, const MemRegion* sReg) + VarRegion(const VarDecl *vd, const MemRegion* sReg) : DeclRegion(vd, sReg, VarRegionKind) {} - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD, + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD, const MemRegion *superRegion) { DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); } @@ -680,7 +690,7 @@ public: return getDecl()->getType(); } - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; static bool classof(const MemRegion* R) { return R->getKind() == VarRegionKind; @@ -690,11 +700,11 @@ public: /// CXXThisRegion - Represents the region for the implicit 'this' parameter /// in a call to a C++ method. This region doesn't represent the object /// referred to by 'this', but rather 'this' itself. -class CXXThisRegion : public TypedRegion { +class CXXThisRegion : public TypedValueRegion { friend class MemRegionManager; CXXThisRegion(const PointerType *thisPointerTy, const MemRegion *sReg) - : TypedRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} + : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} static void ProfileRegion(llvm::FoldingSetNodeID &ID, const PointerType *PT, @@ -707,7 +717,7 @@ public: return QualType(ThisPointerTy, 0); } - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; static bool classof(const MemRegion* R) { return R->getKind() == CXXThisRegionKind; @@ -720,14 +730,14 @@ private: class FieldRegion : public DeclRegion { friend class MemRegionManager; - FieldRegion(const FieldDecl* fd, const MemRegion* sReg) + FieldRegion(const FieldDecl *fd, const MemRegion* sReg) : DeclRegion(fd, sReg, FieldRegionKind) {} public: - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; - const FieldDecl* getDecl() const { return cast<FieldDecl>(D); } + const FieldDecl *getDecl() const { return cast<FieldDecl>(D); } QualType getValueType() const { // FIXME: We can cache this if needed. @@ -736,7 +746,7 @@ public: DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD, + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, const MemRegion* superRegion) { DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); } @@ -750,19 +760,19 @@ class ObjCIvarRegion : public DeclRegion { friend class MemRegionManager; - ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg) + ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg) : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {} - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl* ivd, + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, const MemRegion* superRegion) { DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind); } public: - const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); } + const ObjCIvarDecl *getDecl() const { return cast<ObjCIvarDecl>(D); } QualType getValueType() const { return getDecl()->getType(); } - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; static bool classof(const MemRegion* R) { return R->getKind() == ObjCIvarRegionKind; @@ -789,18 +799,18 @@ public: CharUnits getOffset() const { return Offset; } const MemRegion *getRegion() const { return Region; } - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; void dump() const; }; -class ElementRegion : public TypedRegion { +class ElementRegion : public TypedValueRegion { friend class MemRegionManager; QualType ElementType; NonLoc Index; ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg) - : TypedRegion(sReg, ElementRegionKind), + : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType), Index(Idx) { assert((!isa<nonloc::ConcreteInt>(&Idx) || cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) && @@ -824,7 +834,7 @@ public: /// Compute the offset within the array. The array might also be a subobject. RegionRawOffset getAsArrayOffset() const; - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; void Profile(llvm::FoldingSetNodeID& ID) const; @@ -834,23 +844,25 @@ public: }; // C++ temporary object associated with an expression. -class CXXTempObjectRegion : public TypedRegion { +class CXXTempObjectRegion : public TypedValueRegion { friend class MemRegionManager; Expr const *Ex; CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) - : TypedRegion(sReg, CXXTempObjectRegionKind), Ex(E) {} + : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {} static void ProfileRegion(llvm::FoldingSetNodeID &ID, Expr const *E, const MemRegion *sReg); public: + const Expr *getExpr() const { return Ex; } + QualType getValueType() const { return Ex->getType(); } - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; void Profile(llvm::FoldingSetNodeID &ID) const; @@ -861,13 +873,13 @@ public: // CXXBaseObjectRegion represents a base object within a C++ object. It is // identified by the base class declaration and the region of its parent object. -class CXXBaseObjectRegion : public TypedRegion { +class CXXBaseObjectRegion : public TypedValueRegion { friend class MemRegionManager; const CXXRecordDecl *decl; CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg) - : TypedRegion(sReg, CXXBaseObjectRegionKind), decl(d) {} + : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {} static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *decl, const MemRegion *sReg); @@ -877,7 +889,7 @@ public: QualType getValueType() const; - void dumpToStream(llvm::raw_ostream& os) const; + void dumpToStream(raw_ostream &os) const; void Profile(llvm::FoldingSetNodeID &ID) const; @@ -951,13 +963,13 @@ public: const MemSpaceRegion *getCodeRegion(); /// getAllocaRegion - Retrieve a region associated with a call to alloca(). - const AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt, + const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt, const LocationContext *LC); /// getCompoundLiteralRegion - Retrieve the region associated with a /// given CompoundLiteral. const CompoundLiteralRegion* - getCompoundLiteralRegion(const CompoundLiteralExpr* CL, + getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const LocationContext *LC); /// getCXXThisRegion - Retrieve the [artificial] region associated with the @@ -994,7 +1006,7 @@ public: /// a specified FieldDecl. 'superRegion' corresponds to the containing /// memory region (which typically represents the memory representing /// a structure or class). - const FieldRegion *getFieldRegion(const FieldDecl* fd, + const FieldRegion *getFieldRegion(const FieldDecl *fd, const MemRegion* superRegion); const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, @@ -1006,7 +1018,7 @@ public: /// a specified Objective-c instance variable. 'superRegion' corresponds /// to the containing region (which typically represents the Objective-C /// object). - const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd, + const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* superRegion); const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, @@ -1069,7 +1081,7 @@ private: // Out-of-line member definitions. //===----------------------------------------------------------------------===// -inline ASTContext& MemRegion::getContext() const { +inline ASTContext &MemRegion::getContext() const { return getMemRegionManager()->getContext(); } @@ -1082,7 +1094,7 @@ inline ASTContext& MemRegion::getContext() const { //===----------------------------------------------------------------------===// namespace llvm { -static inline raw_ostream& operator<<(raw_ostream& os, +static inline raw_ostream &operator<<(raw_ostream &os, const clang::ento::MemRegion* R) { R->dumpToStream(os); return os; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h index 734024c..add3479 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h @@ -16,8 +16,10 @@ #define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_OBJCMESSAGE #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/ExprCXX.h" +#include "llvm/ADT/PointerUnion.h" namespace clang { namespace ento { @@ -86,6 +88,21 @@ public: return 0; } + SVal getInstanceReceiverSVal(const ProgramState *State, + const LocationContext *LC) const { + assert(isValid() && "This ObjCMessage is uninitialized!"); + if (!isInstanceMessage()) + return UndefinedVal(); + if (const Expr *Ex = getInstanceReceiver()) + return State->getSValAsScalarOrLoc(Ex); + + // An instance message with no expression means we are sending to super. + // In this case the object reference is the same as 'self'. + const ImplicitParamDecl *SelfDecl = LC->getSelfDecl(); + assert(SelfDecl && "No message receiver Expr, but not in an ObjC method"); + return State->getSVal(State->getRegion(SelfDecl, LC)); + } + bool isInstanceMessage() const { assert(isValid() && "This ObjCMessage is uninitialized!"); if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE)) @@ -96,7 +113,7 @@ public: } const ObjCMethodDecl *getMethodDecl() const; - + const ObjCInterfaceDecl *getReceiverInterface() const; SourceLocation getSuperLoc() const { @@ -106,45 +123,63 @@ public: return cast<ObjCPropertyRefExpr>(MsgOrPropE)->getReceiverLocation(); } - SourceRange getSourceRange() const { - assert(isValid() && "This ObjCMessage is uninitialized!"); + const Expr *getMsgOrPropExpr() const { + assert(isValid() && "This ObjCMessage is uninitialized!"); + return MsgOrPropE; + } + + SourceRange getSourceRange() const { + assert(isValid() && "This ObjCMessage is uninitialized!"); return MsgOrPropE->getSourceRange(); } - unsigned getNumArgs() const { - assert(isValid() && "This ObjCMessage is uninitialized!"); - if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE)) - return msgE->getNumArgs(); - return isPropertySetter() ? 1 : 0; - } - - SVal getArgSVal(unsigned i, const GRState *state) const { - assert(isValid() && "This ObjCMessage is uninitialized!"); - assert(i < getNumArgs() && "Invalid index for argument"); - if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE)) - return state->getSVal(msgE->getArg(i)); - assert(isPropertySetter()); - return SetterArgV; - } - - QualType getArgType(unsigned i) const { - assert(isValid() && "This ObjCMessage is uninitialized!"); - assert(i < getNumArgs() && "Invalid index for argument"); - if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE)) - return msgE->getArg(i)->getType(); - assert(isPropertySetter()); - return cast<ObjCPropertyRefExpr>(MsgOrPropE)->getType(); - } - - const Expr *getArgExpr(unsigned i) const; - - SourceRange getArgSourceRange(unsigned i) const { - assert(isValid() && "This ObjCMessage is uninitialized!"); - assert(i < getNumArgs() && "Invalid index for argument"); - if (const Expr *argE = getArgExpr(i)) - return argE->getSourceRange(); - return OriginE->getSourceRange(); - } + unsigned getNumArgs() const { + assert(isValid() && "This ObjCMessage is uninitialized!"); + if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE)) + return msgE->getNumArgs(); + return isPropertySetter() ? 1 : 0; + } + + SVal getArgSVal(unsigned i, const ProgramState *state) const { + assert(isValid() && "This ObjCMessage is uninitialized!"); + assert(i < getNumArgs() && "Invalid index for argument"); + if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE)) + return state->getSVal(msgE->getArg(i)); + assert(isPropertySetter()); + return SetterArgV; + } + + QualType getArgType(unsigned i) const { + assert(isValid() && "This ObjCMessage is uninitialized!"); + assert(i < getNumArgs() && "Invalid index for argument"); + if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE)) + return msgE->getArg(i)->getType(); + assert(isPropertySetter()); + return cast<ObjCPropertyRefExpr>(MsgOrPropE)->getType(); + } + + const Expr *getArgExpr(unsigned i) const; + + SourceRange getArgSourceRange(unsigned i) const { + assert(isValid() && "This ObjCMessage is uninitialized!"); + assert(i < getNumArgs() && "Invalid index for argument"); + if (const Expr *argE = getArgExpr(i)) + return argE->getSourceRange(); + return OriginE->getSourceRange(); + } + + SourceRange getReceiverSourceRange() const { + assert(isValid() && "This ObjCMessage is uninitialized!"); + if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE)) + return msgE->getReceiverRange(); + + const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE); + if (propE->isObjectReceiver()) + return propE->getBase()->getSourceRange(); + + // FIXME: This isn't a range. + return propE->getReceiverLocation(); + } }; class ObjCPropertyGetter : public ObjCMessage { @@ -165,58 +200,89 @@ public: } }; -/// \brief Common wrapper for a call expression or an ObjC message, mainly to -/// provide a common interface for handling their arguments. +/// \brief Common wrapper for a call expression, ObjC message, or C++ +/// constructor, mainly to provide a common interface for their arguments. class CallOrObjCMessage { - const CallExpr *CallE; + llvm::PointerUnion<const CallExpr *, const CXXConstructExpr *> CallE; ObjCMessage Msg; - const GRState *State; + const ProgramState *State; public: - CallOrObjCMessage(const CallExpr *callE, const GRState *state) + CallOrObjCMessage(const CallExpr *callE, const ProgramState *state) : CallE(callE), State(state) {} - CallOrObjCMessage(const ObjCMessage &msg, const GRState *state) - : CallE(0), Msg(msg), State(state) {} + CallOrObjCMessage(const CXXConstructExpr *consE, const ProgramState *state) + : CallE(consE), State(state) {} + CallOrObjCMessage(const ObjCMessage &msg, const ProgramState *state) + : CallE((CallExpr *)0), Msg(msg), State(state) {} QualType getResultType(ASTContext &ctx) const; bool isFunctionCall() const { - return (bool) CallE; + return CallE && CallE.is<const CallExpr *>(); } - + + bool isCXXConstructExpr() const { + return CallE && CallE.is<const CXXConstructExpr *>(); + } + + bool isObjCMessage() const { + return !CallE; + } + bool isCXXCall() const { - return CallE && isa<CXXMemberCallExpr>(CallE); + const CallExpr *ActualCallE = CallE.dyn_cast<const CallExpr *>(); + return ActualCallE && isa<CXXMemberCallExpr>(ActualCallE); + } + + const Expr *getOriginExpr() const { + if (!CallE) + return Msg.getOriginExpr(); + if (const CXXConstructExpr *Ctor = + CallE.dyn_cast<const CXXConstructExpr *>()) + return Ctor; + return CallE.get<const CallExpr *>(); } SVal getFunctionCallee() const; SVal getCXXCallee() const; + SVal getInstanceMessageReceiver(const LocationContext *LC) const; unsigned getNumArgs() const { - if (CallE) return CallE->getNumArgs(); - return Msg.getNumArgs(); + if (!CallE) + return Msg.getNumArgs(); + if (const CXXConstructExpr *Ctor = + CallE.dyn_cast<const CXXConstructExpr *>()) + return Ctor->getNumArgs(); + return CallE.get<const CallExpr *>()->getNumArgs(); } SVal getArgSVal(unsigned i) const { assert(i < getNumArgs()); - if (CallE) - return State->getSVal(CallE->getArg(i)); - return Msg.getArgSVal(i, State); + if (!CallE) + return Msg.getArgSVal(i, State); + return State->getSVal(getArg(i)); } - SVal getArgSValAsScalarOrLoc(unsigned i) const; - const Expr *getArg(unsigned i) const { assert(i < getNumArgs()); - if (CallE) - return CallE->getArg(i); - return Msg.getArgExpr(i); + if (!CallE) + return Msg.getArgExpr(i); + if (const CXXConstructExpr *Ctor = + CallE.dyn_cast<const CXXConstructExpr *>()) + return Ctor->getArg(i); + return CallE.get<const CallExpr *>()->getArg(i); } SourceRange getArgSourceRange(unsigned i) const { assert(i < getNumArgs()); if (CallE) - return CallE->getArg(i)->getSourceRange(); + return getArg(i)->getSourceRange(); return Msg.getArgSourceRange(i); } + + SourceRange getReceiverSourceRange() const { + assert(isObjCMessage()); + return Msg.getReceiverSourceRange(); + } }; } diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index 0d61d0e..edae06e 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -1,4 +1,4 @@ -//== GRState.h - Path-sensitive "State" for tracking values -----*- C++ -*--==// +//== ProgramState.h - Path-sensitive "State" for tracking values -*- C++ -*--=// // // The LLVM Compiler Infrastructure // @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// // -// This file defines SymbolRef, ExprBindKey, and GRState*. +// This file defines SymbolRef, ExprBindKey, and ProgramState*. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_GR_VALUESTATE_H #define LLVM_CLANG_GR_VALUESTATE_H +#include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" @@ -21,12 +22,10 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableMap.h" -#include "llvm/Support/Casting.h" namespace llvm { class APSInt; class BumpPtrAllocator; -class raw_ostream; } namespace clang { @@ -34,30 +33,31 @@ class ASTContext; namespace ento { -class GRStateManager; +class ProgramStateManager; -typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&, +typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&, SubEngine&); -typedef StoreManager* (*StoreManagerCreator)(GRStateManager&); +typedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&); //===----------------------------------------------------------------------===// -// GRStateTrait - Traits used by the Generic Data Map of a GRState. +// ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState. //===----------------------------------------------------------------------===// -template <typename T> struct GRStatePartialTrait; +template <typename T> struct ProgramStatePartialTrait; -template <typename T> struct GRStateTrait { +template <typename T> struct ProgramStateTrait { typedef typename T::data_type data_type; - static inline void* GDMIndex() { return &T::TagInt; } - static inline void* MakeVoidPtr(data_type D) { return (void*) D; } - static inline data_type MakeData(void* const* P) { + static inline void *GDMIndex() { return &T::TagInt; } + static inline void *MakeVoidPtr(data_type D) { return (void*) D; } + static inline data_type MakeData(void *const* P) { return P ? (data_type) *P : (data_type) 0; } }; -class GRStateManager; +class ProgramStateManager; -/// GRState - This class encapsulates: +/// \class ProgramState +/// ProgramState - This class encapsulates: /// /// 1. A mapping from expressions to values (Environment) /// 2. A mapping from locations to values (Store) @@ -65,47 +65,47 @@ class GRStateManager; /// /// Together these represent the "abstract state" of a program. /// -/// GRState is intended to be used as a functional object; that is, +/// ProgramState is intended to be used as a functional object; that is, /// once it is created and made "persistent" in a FoldingSet, its /// values will never change. -class GRState : public llvm::FoldingSetNode { +class ProgramState : public llvm::FoldingSetNode { public: typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy; typedef llvm::ImmutableMap<void*, void*> GenericDataMap; private: - void operator=(const GRState& R) const; // Do not implement. + void operator=(const ProgramState& R) const; // Do not implement. - friend class GRStateManager; + friend class ProgramStateManager; friend class ExplodedGraph; friend class ExplodedNode; - GRStateManager *stateMgr; + ProgramStateManager *stateMgr; Environment Env; // Maps a Stmt to its current SVal. Store store; // Maps a location to its current value. GenericDataMap GDM; // Custom data stored by a client of this class. unsigned refCount; - /// makeWithStore - Return a GRState with the same values as the current + /// makeWithStore - Return a ProgramState with the same values as the current /// state with the exception of using the specified Store. - const GRState *makeWithStore(const StoreRef &store) const; + const ProgramState *makeWithStore(const StoreRef &store) const; void setStore(const StoreRef &storeRef); public: - /// This ctor is used when creating the first GRState object. - GRState(GRStateManager *mgr, const Environment& env, + /// This ctor is used when creating the first ProgramState object. + ProgramState(ProgramStateManager *mgr, const Environment& env, StoreRef st, GenericDataMap gdm); /// Copy ctor - We must explicitly define this or else the "Next" ptr /// in FoldingSetNode will also get copied. - GRState(const GRState& RHS); + ProgramState(const ProgramState &RHS); - ~GRState(); + ~ProgramState(); - /// Return the GRStateManager associated with this state. - GRStateManager &getStateManager() const { return *stateMgr; } + /// Return the ProgramStateManager associated with this state. + ProgramStateManager &getStateManager() const { return *stateMgr; } /// Return true if this state is referenced by a persistent ExplodedNode. bool referencedByExplodedNode() const { return refCount > 0; } @@ -124,10 +124,10 @@ public: void setGDM(GenericDataMap gdm) { GDM = gdm; } - /// Profile - Profile the contents of a GRState object for use in a - /// FoldingSet. Two GRState objects are considered equal if they + /// Profile - Profile the contents of a ProgramState object for use in a + /// FoldingSet. Two ProgramState objects are considered equal if they /// have the same Environment, Store, and GenericDataMap. - static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) { + static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) { V->Env.Profile(ID); ID.AddPointer(V->store); V->GDM.Profile(ID); @@ -146,44 +146,41 @@ public: // Constraints on values. //==---------------------------------------------------------------------==// // - // Each GRState records constraints on symbolic values. These constraints - // are managed using the ConstraintManager associated with a GRStateManager. + // Each ProgramState records constraints on symbolic values. These constraints + // are managed using the ConstraintManager associated with a ProgramStateManager. // As constraints gradually accrue on symbolic values, added constraints // may conflict and indicate that a state is infeasible (as no real values // could satisfy all the constraints). This is the principal mechanism - // for modeling path-sensitivity in ExprEngine/GRState. + // for modeling path-sensitivity in ExprEngine/ProgramState. // // Various "assume" methods form the interface for adding constraints to // symbolic values. A call to 'assume' indicates an assumption being placed // on one or symbolic values. 'assume' methods take the following inputs: // - // (1) A GRState object representing the current state. + // (1) A ProgramState object representing the current state. // // (2) The assumed constraint (which is specific to a given "assume" method). // // (3) A binary value "Assumption" that indicates whether the constraint is // assumed to be true or false. // - // The output of "assume*" is a new GRState object with the added constraints. + // The output of "assume*" is a new ProgramState object with the added constraints. // If no new state is feasible, NULL is returned. // - const GRState *assume(DefinedOrUnknownSVal cond, bool assumption) const; + const ProgramState *assume(DefinedOrUnknownSVal cond, bool assumption) const; /// This method assumes both "true" and "false" for 'cond', and /// returns both corresponding states. It's shorthand for doing /// 'assume' twice. - std::pair<const GRState*, const GRState*> + std::pair<const ProgramState*, const ProgramState*> assume(DefinedOrUnknownSVal cond) const; - const GRState *assumeInBound(DefinedOrUnknownSVal idx, + const ProgramState *assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound, bool assumption) const; - //==---------------------------------------------------------------------==// - // Utility methods for getting regions. - //==---------------------------------------------------------------------==// - + /// Utility method for getting regions. const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const; //==---------------------------------------------------------------------==// @@ -192,52 +189,42 @@ public: /// BindCompoundLiteral - Return the state that has the bindings currently /// in this state plus the bindings for the CompoundLiteral. - const GRState *bindCompoundLiteral(const CompoundLiteralExpr* CL, + const ProgramState *bindCompoundLiteral(const CompoundLiteralExpr *CL, const LocationContext *LC, SVal V) const; /// Create a new state by binding the value 'V' to the statement 'S' in the /// state's environment. - const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const; + const ProgramState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const; /// Create a new state by binding the value 'V' and location 'locaton' to the /// statement 'S' in the state's environment. - const GRState *bindExprAndLocation(const Stmt *S, SVal location, SVal V) + const ProgramState *bindExprAndLocation(const Stmt *S, SVal location, SVal V) const; - const GRState *bindDecl(const VarRegion *VR, SVal V) const; + const ProgramState *bindDecl(const VarRegion *VR, SVal V) const; - const GRState *bindDeclWithNoInit(const VarRegion *VR) const; + const ProgramState *bindDeclWithNoInit(const VarRegion *VR) const; - const GRState *bindLoc(Loc location, SVal V) const; + const ProgramState *bindLoc(Loc location, SVal V) const; - const GRState *bindLoc(SVal location, SVal V) const; + const ProgramState *bindLoc(SVal location, SVal V) const; - const GRState *bindDefault(SVal loc, SVal V) const; + const ProgramState *bindDefault(SVal loc, SVal V) const; - const GRState *unbindLoc(Loc LV) const; - - /// invalidateRegion - Returns the state with bindings for the given region - /// cleared from the store. See invalidateRegions. - const GRState *invalidateRegion(const MemRegion *R, - const Expr *E, unsigned BlockCount, - StoreManager::InvalidatedSymbols *IS = NULL) - const { - return invalidateRegions(&R, &R+1, E, BlockCount, IS, false); - } + const ProgramState *unbindLoc(Loc LV) const; /// invalidateRegions - Returns the state with bindings for the given regions /// cleared from the store. The regions are provided as a continuous array /// from Begin to End. Optionally invalidates global regions as well. - const GRState *invalidateRegions(const MemRegion * const *Begin, - const MemRegion * const *End, + const ProgramState *invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E, unsigned BlockCount, - StoreManager::InvalidatedSymbols *IS, - bool invalidateGlobals) const; + StoreManager::InvalidatedSymbols *IS = 0, + bool invalidateGlobals = false) const; /// enterStackFrame - Returns the state for entry to the given stack frame, /// preserving the current state. - const GRState *enterStackFrame(const StackFrameContext *frame) const; + const ProgramState *enterStackFrame(const StackFrameContext *frame) const; /// Get the lvalue for a variable reference. Loc getLValue(const VarDecl *D, const LocationContext *LC) const; @@ -260,7 +247,7 @@ public: const llvm::APSInt *getSymVal(SymbolRef sym) const; /// Returns the SVal bound to the statement 'S' in the state's environment. - SVal getSVal(const Stmt* S, bool useOnlyDirectBindings = false) const; + SVal getSVal(const Stmt *S, bool useOnlyDirectBindings = false) const; SVal getSValAsScalarOrLoc(const Stmt *Ex) const; @@ -273,11 +260,22 @@ public: SVal getSValAsScalarOrLoc(const MemRegion *R) const; + /// \brief Visits the symbols reachable from the given SVal using the provided + /// SymbolVisitor. + /// + /// This is a convenience API. Consider using ScanReachableSymbols class + /// directly when making multiple scans on the same state with the same + /// visitor to avoid repeated initialization cost. + /// \sa ScanReachableSymbols bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const; + /// \brief Visits the symbols reachable from the SVals in the given range + /// using the provided SymbolVisitor. bool scanReachableSymbols(const SVal *I, const SVal *E, SymbolVisitor &visitor) const; + /// \brief Visits the symbols reachable from the regions in the given + /// MemRegions range using the provided SymbolVisitor. bool scanReachableSymbols(const MemRegion * const *I, const MemRegion * const *E, SymbolVisitor &visitor) const; @@ -294,70 +292,62 @@ public: // Accessing the Generic Data Map (GDM). //==---------------------------------------------------------------------==// - void* const* FindGDM(void* K) const; + void *const* FindGDM(void *K) const; template<typename T> - const GRState *add(typename GRStateTrait<T>::key_type K) const; + const ProgramState *add(typename ProgramStateTrait<T>::key_type K) const; template <typename T> - typename GRStateTrait<T>::data_type + typename ProgramStateTrait<T>::data_type get() const { - return GRStateTrait<T>::MakeData(FindGDM(GRStateTrait<T>::GDMIndex())); + return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex())); } template<typename T> - typename GRStateTrait<T>::lookup_type - get(typename GRStateTrait<T>::key_type key) const { - void* const* d = FindGDM(GRStateTrait<T>::GDMIndex()); - return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key); + typename ProgramStateTrait<T>::lookup_type + get(typename ProgramStateTrait<T>::key_type key) const { + void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex()); + return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key); } template <typename T> - typename GRStateTrait<T>::context_type get_context() const; + typename ProgramStateTrait<T>::context_type get_context() const; template<typename T> - const GRState *remove(typename GRStateTrait<T>::key_type K) const; + const ProgramState *remove(typename ProgramStateTrait<T>::key_type K) const; template<typename T> - const GRState *remove(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) const; + const ProgramState *remove(typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::context_type C) const; template <typename T> - const GRState *remove() const; + const ProgramState *remove() const; template<typename T> - const GRState *set(typename GRStateTrait<T>::data_type D) const; + const ProgramState *set(typename ProgramStateTrait<T>::data_type D) const; template<typename T> - const GRState *set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E) const; + const ProgramState *set(typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::value_type E) const; template<typename T> - const GRState *set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E, - typename GRStateTrait<T>::context_type C) const; + const ProgramState *set(typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::value_type E, + typename ProgramStateTrait<T>::context_type C) const; template<typename T> - bool contains(typename GRStateTrait<T>::key_type key) const { - void* const* d = FindGDM(GRStateTrait<T>::GDMIndex()); - return GRStateTrait<T>::Contains(GRStateTrait<T>::MakeData(d), key); + bool contains(typename ProgramStateTrait<T>::key_type key) const { + void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex()); + return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key); } - // State pretty-printing. - class Printer { - public: - virtual ~Printer() {} - virtual void Print(llvm::raw_ostream& Out, const GRState* state, - const char* nl, const char* sep) = 0; - }; - // Pretty-printing. - void print(llvm::raw_ostream& Out, CFG &C, const char *nl = "\n", + void print(raw_ostream &Out, CFG &C, const char *nl = "\n", const char *sep = "") const; void printStdErr(CFG &C) const; - void printDOT(llvm::raw_ostream& Out, CFG &C) const; + void printDOT(raw_ostream &Out, CFG &C) const; private: /// Increments the number of times this state is referenced by ExplodeNodes. @@ -369,20 +359,20 @@ private: --refCount; } - const GRState *invalidateRegionsImpl(const MemRegion * const *Begin, - const MemRegion * const *End, - const Expr *E, unsigned BlockCount, - StoreManager::InvalidatedSymbols &IS, - bool invalidateGlobals) const; + const ProgramState * + invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions, + const Expr *E, unsigned BlockCount, + StoreManager::InvalidatedSymbols &IS, + bool invalidateGlobals) const; }; -class GRStateSet { - typedef llvm::SmallPtrSet<const GRState*,5> ImplTy; +class ProgramStateSet { + typedef llvm::SmallPtrSet<const ProgramState*,5> ImplTy; ImplTy Impl; public: - GRStateSet() {} + ProgramStateSet() {} - inline void Add(const GRState* St) { + inline void Add(const ProgramState *St) { Impl.insert(St); } @@ -395,11 +385,11 @@ public: inline iterator end() const { return Impl.end(); } class AutoPopulate { - GRStateSet& S; + ProgramStateSet &S; unsigned StartSize; - const GRState* St; + const ProgramState *St; public: - AutoPopulate(GRStateSet& s, const GRState* st) + AutoPopulate(ProgramStateSet &s, const ProgramState *st) : S(s), StartSize(S.size()), St(st) {} ~AutoPopulate() { @@ -410,12 +400,11 @@ public: }; //===----------------------------------------------------------------------===// -// GRStateManager - Factory object for GRStates. +// ProgramStateManager - Factory object for ProgramStates. //===----------------------------------------------------------------------===// -class GRStateManager { - friend class GRState; - friend class ExprEngine; // FIXME: Remove. +class ProgramStateManager { + friend class ProgramState; private: /// Eng - The SubEngine that owns this state manager. SubEngine *Eng; /* Can be null. */ @@ -424,18 +413,14 @@ private: llvm::OwningPtr<StoreManager> StoreMgr; llvm::OwningPtr<ConstraintManager> ConstraintMgr; - GRState::GenericDataMap::Factory GDMFactory; + ProgramState::GenericDataMap::Factory GDMFactory; typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy; GDMContextsTy GDMContexts; - /// Printers - A set of printer objects used for pretty-printing a GRState. - /// GRStateManager owns these objects. - std::vector<GRState::Printer*> Printers; - /// StateSet - FoldingSet containing all the states created for analyzing /// a particular function. This is used to unique states. - llvm::FoldingSet<GRState> StateSet; + llvm::FoldingSet<ProgramState> StateSet; /// Object that manages the data for all created SVals. llvm::OwningPtr<SValBuilder> svalBuilder; @@ -443,15 +428,15 @@ private: /// A BumpPtrAllocator to allocate states. llvm::BumpPtrAllocator &Alloc; - /// A vector of recently allocated GRStates that can potentially be + /// A vector of recently allocated ProgramStates that can potentially be /// reused. - std::vector<GRState *> recentlyAllocatedStates; + std::vector<ProgramState *> recentlyAllocatedStates; - /// A vector of GRStates that we can reuse. - std::vector<GRState *> freeStates; + /// A vector of ProgramStates that we can reuse. + std::vector<ProgramState *> freeStates; public: - GRStateManager(ASTContext& Ctx, + ProgramStateManager(ASTContext &Ctx, StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator& alloc, @@ -465,7 +450,7 @@ public: ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng)); } - GRStateManager(ASTContext& Ctx, + ProgramStateManager(ASTContext &Ctx, StoreManagerCreator CreateStoreManager, ConstraintManager* ConstraintManagerPtr, llvm::BumpPtrAllocator& alloc) @@ -478,9 +463,9 @@ public: ConstraintMgr.reset(ConstraintManagerPtr); } - ~GRStateManager(); + ~ProgramStateManager(); - const GRState *getInitialState(const LocationContext *InitLoc); + const ProgramState *getInitialState(const LocationContext *InitLoc); ASTContext &getContext() { return svalBuilder->getContext(); } const ASTContext &getContext() const { return svalBuilder->getContext(); } @@ -516,13 +501,13 @@ public: ConstraintManager& getConstraintManager() { return *ConstraintMgr; } SubEngine* getOwningEngine() { return Eng; } - const GRState* removeDeadBindings(const GRState* St, + const ProgramState *removeDeadBindings(const ProgramState *St, const StackFrameContext *LCtx, SymbolReaper& SymReaper); /// Marshal a new state for the callee in another translation unit. /// 'state' is owned by the caller's engine. - const GRState *MarshalState(const GRState *state, const StackFrameContext *L); + const ProgramState *MarshalState(const ProgramState *state, const StackFrameContext *L); public: @@ -531,18 +516,28 @@ public: } // Methods that manipulate the GDM. - const GRState* addGDM(const GRState* St, void* Key, void* Data); - const GRState *removeGDM(const GRState *state, void *Key); + const ProgramState *addGDM(const ProgramState *St, void *Key, void *Data); + const ProgramState *removeGDM(const ProgramState *state, void *Key); // Methods that query & manipulate the Store. - void iterBindings(const GRState* state, StoreManager::BindingsHandler& F) { + void iterBindings(const ProgramState *state, StoreManager::BindingsHandler& F) { StoreMgr->iterBindings(state->getStore(), F); } - const GRState* getPersistentState(GRState& Impl); - - /// Periodically called by ExprEngine to recycle GRStates that were + const ProgramState *getPersistentState(ProgramState &Impl); + const ProgramState *getPersistentStateWithGDM(const ProgramState *FromState, + const ProgramState *GDMState); + + bool haveEqualEnvironments(const ProgramState * S1, const ProgramState * S2) { + return S1->Env == S2->Env; + } + + bool haveEqualStores(const ProgramState * S1, const ProgramState * S2) { + return S1->store == S2->store; + } + + /// Periodically called by ExprEngine to recycle ProgramStates that were /// created but never used for creating an ExplodedNode. void recycleUnusedStates(); @@ -550,9 +545,9 @@ public: // Generic Data Map methods. //==---------------------------------------------------------------------==// // - // GRStateManager and GRState support a "generic data map" that allows - // different clients of GRState objects to embed arbitrary data within a - // GRState object. The generic data map is essentially an immutable map + // ProgramStateManager and ProgramState support a "generic data map" that allows + // different clients of ProgramState objects to embed arbitrary data within a + // ProgramState object. The generic data map is essentially an immutable map // from a "tag" (that acts as the "key" for a client) and opaque values. // Tags/keys and values are simply void* values. The typical way that clients // generate unique tags are by taking the address of a static variable. @@ -560,82 +555,82 @@ public: // the data pointer are immutable (and thus are essentially purely functional // data). // - // The templated methods below use the GRStateTrait<T> class + // The templated methods below use the ProgramStateTrait<T> class // to resolve keys into the GDM and to return data values to clients. // // Trait based GDM dispatch. template <typename T> - const GRState* set(const GRState* st, typename GRStateTrait<T>::data_type D) { - return addGDM(st, GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::MakeVoidPtr(D)); + const ProgramState *set(const ProgramState *st, typename ProgramStateTrait<T>::data_type D) { + return addGDM(st, ProgramStateTrait<T>::GDMIndex(), + ProgramStateTrait<T>::MakeVoidPtr(D)); } template<typename T> - const GRState* set(const GRState* st, - typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type V, - typename GRStateTrait<T>::context_type C) { + const ProgramState *set(const ProgramState *st, + typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::value_type V, + typename ProgramStateTrait<T>::context_type C) { - return addGDM(st, GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C))); + return addGDM(st, ProgramStateTrait<T>::GDMIndex(), + ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C))); } template <typename T> - const GRState* add(const GRState* st, - typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) { - return addGDM(st, GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Add(st->get<T>(), K, C))); + const ProgramState *add(const ProgramState *st, + typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::context_type C) { + return addGDM(st, ProgramStateTrait<T>::GDMIndex(), + ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C))); } template <typename T> - const GRState* remove(const GRState* st, - typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) { + const ProgramState *remove(const ProgramState *st, + typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::context_type C) { - return addGDM(st, GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C))); + return addGDM(st, ProgramStateTrait<T>::GDMIndex(), + ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C))); } template <typename T> - const GRState *remove(const GRState *st) { - return removeGDM(st, GRStateTrait<T>::GDMIndex()); + const ProgramState *remove(const ProgramState *st) { + return removeGDM(st, ProgramStateTrait<T>::GDMIndex()); } - void* FindGDMContext(void* index, - void* (*CreateContext)(llvm::BumpPtrAllocator&), + void *FindGDMContext(void *index, + void *(*CreateContext)(llvm::BumpPtrAllocator&), void (*DeleteContext)(void*)); template <typename T> - typename GRStateTrait<T>::context_type get_context() { - void* p = FindGDMContext(GRStateTrait<T>::GDMIndex(), - GRStateTrait<T>::CreateContext, - GRStateTrait<T>::DeleteContext); + typename ProgramStateTrait<T>::context_type get_context() { + void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(), + ProgramStateTrait<T>::CreateContext, + ProgramStateTrait<T>::DeleteContext); - return GRStateTrait<T>::MakeContext(p); + return ProgramStateTrait<T>::MakeContext(p); } - const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) { + const llvm::APSInt* getSymVal(const ProgramState *St, SymbolRef sym) { return ConstraintMgr->getSymVal(St, sym); } - void EndPath(const GRState* St) { + void EndPath(const ProgramState *St) { ConstraintMgr->EndPath(St); } }; //===----------------------------------------------------------------------===// -// Out-of-line method definitions for GRState. +// Out-of-line method definitions for ProgramState. //===----------------------------------------------------------------------===// -inline const VarRegion* GRState::getRegion(const VarDecl *D, +inline const VarRegion* ProgramState::getRegion(const VarDecl *D, const LocationContext *LC) const { return getStateManager().getRegionManager().getVarRegion(D, LC); } -inline const GRState *GRState::assume(DefinedOrUnknownSVal Cond, +inline const ProgramState *ProgramState::assume(DefinedOrUnknownSVal Cond, bool Assumption) const { if (Cond.isUnknown()) return this; @@ -644,8 +639,8 @@ inline const GRState *GRState::assume(DefinedOrUnknownSVal Cond, Assumption); } -inline std::pair<const GRState*, const GRState*> -GRState::assume(DefinedOrUnknownSVal Cond) const { +inline std::pair<const ProgramState*, const ProgramState*> +ProgramState::assume(DefinedOrUnknownSVal Cond) const { if (Cond.isUnknown()) return std::make_pair(this, this); @@ -653,48 +648,48 @@ GRState::assume(DefinedOrUnknownSVal Cond) const { cast<DefinedSVal>(Cond)); } -inline const GRState *GRState::bindLoc(SVal LV, SVal V) const { +inline const ProgramState *ProgramState::bindLoc(SVal LV, SVal V) const { return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V); } -inline Loc GRState::getLValue(const VarDecl* VD, +inline Loc ProgramState::getLValue(const VarDecl *VD, const LocationContext *LC) const { return getStateManager().StoreMgr->getLValueVar(VD, LC); } -inline Loc GRState::getLValue(const StringLiteral *literal) const { +inline Loc ProgramState::getLValue(const StringLiteral *literal) const { return getStateManager().StoreMgr->getLValueString(literal); } -inline Loc GRState::getLValue(const CompoundLiteralExpr *literal, +inline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal, const LocationContext *LC) const { return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC); } -inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const { +inline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const { return getStateManager().StoreMgr->getLValueIvar(D, Base); } -inline SVal GRState::getLValue(const FieldDecl* D, SVal Base) const { +inline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const { return getStateManager().StoreMgr->getLValueField(D, Base); } -inline SVal GRState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{ +inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{ if (NonLoc *N = dyn_cast<NonLoc>(&Idx)) return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base); return UnknownVal(); } -inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const { +inline const llvm::APSInt *ProgramState::getSymVal(SymbolRef sym) const { return getStateManager().getSymVal(this, sym); } -inline SVal GRState::getSVal(const Stmt* Ex, bool useOnlyDirectBindings) const{ +inline SVal ProgramState::getSVal(const Stmt *Ex, bool useOnlyDirectBindings) const{ return Env.getSVal(Ex, *getStateManager().svalBuilder, - useOnlyDirectBindings); + useOnlyDirectBindings); } -inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const { +inline SVal ProgramState::getSValAsScalarOrLoc(const Stmt *S) const { if (const Expr *Ex = dyn_cast<Expr>(S)) { QualType T = Ex->getType(); if (Ex->isLValue() || Loc::isLocType(T) || T->isIntegerType()) @@ -704,88 +699,114 @@ inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const { return UnknownVal(); } -inline SVal GRState::getRawSVal(Loc LV, QualType T) const { +inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const { return getStateManager().StoreMgr->Retrieve(getStore(), LV, T); } -inline SVal GRState::getSVal(const MemRegion* R) const { +inline SVal ProgramState::getSVal(const MemRegion* R) const { return getStateManager().StoreMgr->Retrieve(getStore(), loc::MemRegionVal(R)); } -inline BasicValueFactory &GRState::getBasicVals() const { +inline BasicValueFactory &ProgramState::getBasicVals() const { return getStateManager().getBasicVals(); } -inline SymbolManager &GRState::getSymbolManager() const { +inline SymbolManager &ProgramState::getSymbolManager() const { return getStateManager().getSymbolManager(); } template<typename T> -const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const { +const ProgramState *ProgramState::add(typename ProgramStateTrait<T>::key_type K) const { return getStateManager().add<T>(this, K, get_context<T>()); } template <typename T> -typename GRStateTrait<T>::context_type GRState::get_context() const { +typename ProgramStateTrait<T>::context_type ProgramState::get_context() const { return getStateManager().get_context<T>(); } template<typename T> -const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const { +const ProgramState *ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const { return getStateManager().remove<T>(this, K, get_context<T>()); } template<typename T> -const GRState *GRState::remove(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::context_type C) const { +const ProgramState *ProgramState::remove(typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::context_type C) const { return getStateManager().remove<T>(this, K, C); } template <typename T> -const GRState *GRState::remove() const { +const ProgramState *ProgramState::remove() const { return getStateManager().remove<T>(this); } template<typename T> -const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const { +const ProgramState *ProgramState::set(typename ProgramStateTrait<T>::data_type D) const { return getStateManager().set<T>(this, D); } template<typename T> -const GRState *GRState::set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E) const { +const ProgramState *ProgramState::set(typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::value_type E) const { return getStateManager().set<T>(this, K, E, get_context<T>()); } template<typename T> -const GRState *GRState::set(typename GRStateTrait<T>::key_type K, - typename GRStateTrait<T>::value_type E, - typename GRStateTrait<T>::context_type C) const { +const ProgramState *ProgramState::set(typename ProgramStateTrait<T>::key_type K, + typename ProgramStateTrait<T>::value_type E, + typename ProgramStateTrait<T>::context_type C) const { return getStateManager().set<T>(this, K, E, C); } template <typename CB> -CB GRState::scanReachableSymbols(SVal val) const { +CB ProgramState::scanReachableSymbols(SVal val) const { CB cb(this); scanReachableSymbols(val, cb); return cb; } template <typename CB> -CB GRState::scanReachableSymbols(const SVal *beg, const SVal *end) const { +CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const { CB cb(this); scanReachableSymbols(beg, end, cb); return cb; } template <typename CB> -CB GRState::scanReachableSymbols(const MemRegion * const *beg, +CB ProgramState::scanReachableSymbols(const MemRegion * const *beg, const MemRegion * const *end) const { CB cb(this); scanReachableSymbols(beg, end, cb); return cb; } +/// \class ScanReachableSymbols +/// A Utility class that allows to visit the reachable symbols using a custom +/// SymbolVisitor. +class ScanReachableSymbols : public SubRegionMap::Visitor { + typedef llvm::DenseMap<const void*, unsigned> VisitedItems; + + VisitedItems visited; + const ProgramState *state; + SymbolVisitor &visitor; + llvm::OwningPtr<SubRegionMap> SRM; +public: + + ScanReachableSymbols(const ProgramState *st, SymbolVisitor& v) + : state(st), visitor(v) {} + + bool scan(nonloc::CompoundVal val); + bool scan(SVal val); + bool scan(const MemRegion *R); + bool scan(const SymExpr *sym); + + // From SubRegionMap::Visitor. + bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) { + return scan(SubRegion); + } +}; + } // end GR namespace } // end clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h index de7b868..b80d494 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h @@ -1,4 +1,4 @@ -//==- GRStateTrait.h - Partial implementations of GRStateTrait -----*- C++ -*-// +//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ -*- // // The LLVM Compiler Infrastructure // @@ -8,14 +8,15 @@ //===----------------------------------------------------------------------===// // // This file defines partial implementations of template specializations of -// the class GRStateTrait<>. GRStateTrait<> is used by GRState to implement -// set/get methods for mapulating a GRState's generic data map. +// the class ProgramStateTrait<>. ProgramStateTrait<> is used by ProgramState +// to implement set/get methods for mapulating a ProgramState's +// generic data map. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_GR_GRSTATETRAIT_H -#define LLVM_CLANG_GR_GRSTATETRAIT_H +#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H +#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H namespace llvm { class BumpPtrAllocator; @@ -28,22 +29,22 @@ namespace llvm { namespace clang { namespace ento { - template <typename T> struct GRStatePartialTrait; + template <typename T> struct ProgramStatePartialTrait; // Partial-specialization for ImmutableMap. template <typename Key, typename Data, typename Info> - struct GRStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > { + struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > { typedef llvm::ImmutableMap<Key,Data,Info> data_type; typedef typename data_type::Factory& context_type; typedef Key key_type; typedef Data value_type; typedef const value_type* lookup_type; - static inline data_type MakeData(void* const* p) { + static inline data_type MakeData(void *const* p) { return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); } - static inline void* MakeVoidPtr(data_type B) { + static inline void *MakeVoidPtr(data_type B) { return B.getRoot(); } static lookup_type Lookup(data_type B, key_type K) { @@ -57,15 +58,15 @@ namespace ento { return F.remove(B, K); } - static inline context_type MakeContext(void* p) { + static inline context_type MakeContext(void *p) { return *((typename data_type::Factory*) p); } - static void* CreateContext(llvm::BumpPtrAllocator& Alloc) { + static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { return new typename data_type::Factory(Alloc); } - static void DeleteContext(void* Ctx) { + static void DeleteContext(void *Ctx) { delete (typename data_type::Factory*) Ctx; } }; @@ -74,16 +75,16 @@ namespace ento { // Partial-specialization for ImmutableSet. template <typename Key, typename Info> - struct GRStatePartialTrait< llvm::ImmutableSet<Key,Info> > { + struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > { typedef llvm::ImmutableSet<Key,Info> data_type; typedef typename data_type::Factory& context_type; typedef Key key_type; - static inline data_type MakeData(void* const* p) { + static inline data_type MakeData(void *const* p) { return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0); } - static inline void* MakeVoidPtr(data_type B) { + static inline void *MakeVoidPtr(data_type B) { return B.getRoot(); } @@ -99,15 +100,15 @@ namespace ento { return B.contains(K); } - static inline context_type MakeContext(void* p) { + static inline context_type MakeContext(void *p) { return *((typename data_type::Factory*) p); } - static void* CreateContext(llvm::BumpPtrAllocator& Alloc) { + static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { return new typename data_type::Factory(Alloc); } - static void DeleteContext(void* Ctx) { + static void DeleteContext(void *Ctx) { delete (typename data_type::Factory*) Ctx; } }; @@ -115,7 +116,7 @@ namespace ento { // Partial-specialization for ImmutableList. template <typename T> - struct GRStatePartialTrait< llvm::ImmutableList<T> > { + struct ProgramStatePartialTrait< llvm::ImmutableList<T> > { typedef llvm::ImmutableList<T> data_type; typedef T key_type; typedef typename data_type::Factory& context_type; @@ -128,33 +129,33 @@ namespace ento { return L.contains(K); } - static inline data_type MakeData(void* const* p) { + static inline data_type MakeData(void *const* p) { return p ? data_type((const llvm::ImmutableListImpl<T>*) *p) : data_type(0); } - static inline void* MakeVoidPtr(data_type D) { + static inline void *MakeVoidPtr(data_type D) { return (void*) D.getInternalPointer(); } - static inline context_type MakeContext(void* p) { + static inline context_type MakeContext(void *p) { return *((typename data_type::Factory*) p); } - static void* CreateContext(llvm::BumpPtrAllocator& Alloc) { + static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { return new typename data_type::Factory(Alloc); } - static void DeleteContext(void* Ctx) { + static void DeleteContext(void *Ctx) { delete (typename data_type::Factory*) Ctx; } }; // Partial specialization for bool. - template <> struct GRStatePartialTrait<bool> { + template <> struct ProgramStatePartialTrait<bool> { typedef bool data_type; - static inline data_type MakeData(void* const* p) { + static inline data_type MakeData(void *const* p) { return p ? (data_type) (uintptr_t) *p : data_type(); } @@ -164,10 +165,10 @@ namespace ento { }; // Partial specialization for unsigned. - template <> struct GRStatePartialTrait<unsigned> { + template <> struct ProgramStatePartialTrait<unsigned> { typedef unsigned data_type; - static inline data_type MakeData(void* const* p) { + static inline data_type MakeData(void *const* p) { return p ? (data_type) (uintptr_t) *p : data_type(); } diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index 65eabea..17233e1 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -25,7 +25,7 @@ namespace clang { namespace ento { -class GRState; +class ProgramState; class SValBuilder { protected: @@ -40,7 +40,7 @@ protected: /// Manages the creation of memory regions. MemRegionManager MemMgr; - GRStateManager &StateMgr; + ProgramStateManager &StateMgr; /// The scalar type to use for array indices. const QualType ArrayIndexTy; @@ -56,7 +56,7 @@ public: public: SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, - GRStateManager &stateMgr) + ProgramStateManager &stateMgr) : Context(context), BasicVals(context, alloc), SymMgr(context, BasicVals, alloc), MemMgr(context, alloc), @@ -72,29 +72,29 @@ public: virtual SVal evalComplement(NonLoc val) = 0; - virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode op, + virtual SVal evalBinOpNN(const ProgramState *state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy) = 0; - virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode op, + virtual SVal evalBinOpLL(const ProgramState *state, BinaryOperator::Opcode op, Loc lhs, Loc rhs, QualType resultTy) = 0; - virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode op, + virtual SVal evalBinOpLN(const ProgramState *state, BinaryOperator::Opcode op, Loc lhs, NonLoc rhs, QualType resultTy) = 0; /// getKnownValue - evaluates a given SVal. If the SVal has only one possible /// (integer) value, that value is returned. Otherwise, returns NULL. - virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal val) = 0; + virtual const llvm::APSInt *getKnownValue(const ProgramState *state, SVal val) = 0; - SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op, + SVal evalBinOp(const ProgramState *state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type); - DefinedOrUnknownSVal evalEQ(const GRState *state, DefinedOrUnknownSVal lhs, + DefinedOrUnknownSVal evalEQ(const ProgramState *state, DefinedOrUnknownSVal lhs, DefinedOrUnknownSVal rhs); ASTContext &getContext() { return Context; } const ASTContext &getContext() const { return Context; } - GRStateManager &getStateManager() { return StateMgr; } + ProgramStateManager &getStateManager() { return StateMgr; } QualType getConditionType() const { return getContext().IntTy; @@ -115,14 +115,14 @@ public: // Forwarding methods to SymbolManager. - const SymbolConjured* getConjuredSymbol(const Stmt* stmt, QualType type, + const SymbolConjured* getConjuredSymbol(const Stmt *stmt, QualType type, unsigned visitCount, - const void* symbolTag = 0) { + const void *symbolTag = 0) { return SymMgr.getConjuredSymbol(stmt, type, visitCount, symbolTag); } - const SymbolConjured* getConjuredSymbol(const Expr* expr, unsigned visitCount, - const void* symbolTag = 0) { + const SymbolConjured* getConjuredSymbol(const Expr *expr, unsigned visitCount, + const void *symbolTag = 0) { return SymMgr.getConjuredSymbol(expr, visitCount, symbolTag); } @@ -130,7 +130,7 @@ public: DefinedOrUnknownSVal makeZeroVal(QualType type); /// getRegionValueSymbolVal - make a unique symbol for value of region. - DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *region); + DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region); DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag, const Expr *expr, unsigned count); @@ -139,7 +139,7 @@ public: unsigned count); DefinedOrUnknownSVal getDerivedRegionValueSymbolVal( - SymbolRef parentSymbol, const TypedRegion *region); + SymbolRef parentSymbol, const TypedValueRegion *region); DefinedSVal getMetadataSymbolVal( const void *symbolTag, const MemRegion *region, @@ -154,7 +154,8 @@ public: return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals)); } - NonLoc makeLazyCompoundVal(const StoreRef &store, const TypedRegion *region) { + NonLoc makeLazyCompoundVal(const StoreRef &store, + const TypedValueRegion *region) { return nonloc::LazyCompoundVal( BasicVals.getLazyCompoundValData(store, region)); } @@ -254,7 +255,7 @@ public: SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, - GRStateManager &stateMgr); + ProgramStateManager &stateMgr); } // end GR namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 0d43079..5827b00 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -15,14 +15,10 @@ #ifndef LLVM_CLANG_GR_RVALUE_H #define LLVM_CLANG_GR_RVALUE_H +#include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" -#include "llvm/Support/Casting.h" #include "llvm/ADT/ImmutableList.h" -namespace llvm { - class raw_ostream; -} - //==------------------------------------------------------------------------==// // Base SVal types. //==------------------------------------------------------------------------==// @@ -33,12 +29,12 @@ namespace ento { class CompoundValData; class LazyCompoundValData; -class GRState; +class ProgramState; class BasicValueFactory; class MemRegion; class TypedRegion; class MemRegionManager; -class GRStateManager; +class ProgramStateManager; class SValBuilder; /// SVal - This represents a symbolic expression, which can be either @@ -57,16 +53,16 @@ public: enum { BaseBits = 2, BaseMask = 0x3 }; protected: - const void* Data; + const void *Data; /// The lowest 2 bits are a BaseKind (0 -- 3). /// The higher bits are an unsigned "kind" value. unsigned Kind; - explicit SVal(const void* d, bool isLoc, unsigned ValKind) + explicit SVal(const void *d, bool isLoc, unsigned ValKind) : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {} - explicit SVal(BaseKind k, const void* D = NULL) + explicit SVal(BaseKind k, const void *D = NULL) : Data(D), Kind(k) {} public: @@ -74,7 +70,7 @@ public: ~SVal() {} /// BufferTy - A temporary buffer to hold a set of SVals. - typedef llvm::SmallVector<SVal,5> BufferTy; + typedef SmallVector<SVal,5> BufferTy; inline unsigned getRawKind() const { return Kind; } inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); } @@ -123,7 +119,7 @@ public: /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl. /// Otherwise return 0. - const FunctionDecl* getAsFunctionDecl() const; + const FunctionDecl *getAsFunctionDecl() const; /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and /// wraps a symbol, return that SymbolRef. Otherwise return NULL. @@ -142,22 +138,22 @@ public: const MemRegion *getAsRegion() const; - void dumpToStream(llvm::raw_ostream& OS) const; + void dumpToStream(raw_ostream &OS) const; void dump() const; // Iterators. class symbol_iterator { - llvm::SmallVector<const SymExpr*, 5> itr; + SmallVector<const SymExpr*, 5> itr; void expand(); public: symbol_iterator() {} - symbol_iterator(const SymExpr* SE); + symbol_iterator(const SymExpr *SE); - symbol_iterator& operator++(); + symbol_iterator &operator++(); SymbolRef operator*(); - bool operator==(const symbol_iterator& X) const; - bool operator!=(const symbol_iterator& X) const; + bool operator==(const symbol_iterator &X) const; + bool operator!=(const symbol_iterator &X) const; }; symbol_iterator symbol_begin() const { @@ -178,13 +174,13 @@ public: class UndefinedVal : public SVal { public: UndefinedVal() : SVal(UndefinedKind) {} - UndefinedVal(const void* D) : SVal(UndefinedKind, D) {} + UndefinedVal(const void *D) : SVal(UndefinedKind, D) {} static inline bool classof(const SVal* V) { return V->getBaseKind() == UndefinedKind; } - const void* getData() const { return Data; } + const void *getData() const { return Data; } }; class DefinedOrUnknownSVal : public SVal { @@ -195,7 +191,7 @@ private: bool isValid() const; protected: - explicit DefinedOrUnknownSVal(const void* d, bool isLoc, unsigned ValKind) + explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind) : SVal(d, isLoc, ValKind) {} explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL) @@ -225,7 +221,7 @@ private: bool isUnknownOrUndef() const; bool isValid() const; protected: - explicit DefinedSVal(const void* d, bool isLoc, unsigned ValKind) + explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind) : DefinedOrUnknownSVal(d, isLoc, ValKind) {} public: // Implement isa<T> support. @@ -236,11 +232,11 @@ public: class NonLoc : public DefinedSVal { protected: - explicit NonLoc(unsigned SubKind, const void* d) + explicit NonLoc(unsigned SubKind, const void *d) : DefinedSVal(d, false, SubKind) {} public: - void dumpToStream(llvm::raw_ostream& Out) const; + void dumpToStream(raw_ostream &Out) const; // Implement isa<T> support. static inline bool classof(const SVal* V) { @@ -250,11 +246,11 @@ public: class Loc : public DefinedSVal { protected: - explicit Loc(unsigned SubKind, const void* D) + explicit Loc(unsigned SubKind, const void *D) : DefinedSVal(const_cast<void*>(D), true, SubKind) {} public: - void dumpToStream(llvm::raw_ostream& Out) const; + void dumpToStream(raw_ostream &Out) const; Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {} @@ -533,7 +529,7 @@ public: } // end clang namespace namespace llvm { -static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os, +static inline raw_ostream &operator<<(raw_ostream &os, clang::ento::SVal V) { V.dumpToStream(os); return os; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index cdbdf64..a688d7f 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -29,20 +29,20 @@ class StackFrameContext; namespace ento { -class GRState; -class GRStateManager; +class ProgramState; +class ProgramStateManager; class SubRegionMap; class StoreManager { protected: SValBuilder &svalBuilder; - GRStateManager &StateMgr; + ProgramStateManager &StateMgr; /// MRMgr - Manages region objects associated with this StoreManager. MemRegionManager &MRMgr; ASTContext &Ctx; - StoreManager(GRStateManager &stateMgr); + StoreManager(ProgramStateManager &stateMgr); public: virtual ~StoreManager() {} @@ -60,7 +60,7 @@ public: /// \param[in] state The analysis state. /// \param[in] loc The symbolic memory location. /// \param[in] val The value to bind to location \c loc. - /// \return A pointer to a GRState object that contains the same bindings as + /// \return A pointer to a ProgramState object that contains the same bindings as /// \c state with the addition of having the value specified by \c val bound /// to the location given for \c loc. virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0; @@ -73,7 +73,7 @@ public: /// for the compound literal and 'BegInit' and 'EndInit' represent an /// array of initializer values. virtual StoreRef BindCompoundLiteral(Store store, - const CompoundLiteralExpr* cl, + const CompoundLiteralExpr *cl, const LocationContext *LC, SVal v) = 0; /// getInitialStore - Returns the initial "empty" store representing the @@ -97,16 +97,16 @@ public: return svalBuilder.makeLoc(MRMgr.getStringRegion(S)); } - Loc getLValueCompoundLiteral(const CompoundLiteralExpr* CL, + Loc getLValueCompoundLiteral(const CompoundLiteralExpr *CL, const LocationContext *LC) { return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC)); } - virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) { + virtual SVal getLValueIvar(const ObjCIvarDecl *decl, SVal base) { return getLValueFieldOrIvar(decl, base); } - virtual SVal getLValueField(const FieldDecl* D, SVal Base) { + virtual SVal getLValueField(const FieldDecl *D, SVal Base) { return getLValueFieldOrIvar(D, Base); } @@ -114,7 +114,7 @@ public: // FIXME: This should soon be eliminated altogether; clients should deal with // region extents directly. - virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state, + virtual DefinedOrUnknownSVal getSizeInElements(const ProgramState *state, const MemRegion *region, QualType EleTy) { return UnknownVal(); @@ -130,12 +130,12 @@ public: } class CastResult { - const GRState *state; + const ProgramState *state; const MemRegion *region; public: - const GRState *getState() const { return state; } + const ProgramState *getState() const { return state; } const MemRegion* getRegion() const { return region; } - CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){} + CastResult(const ProgramState *s, const MemRegion* r = 0) : state(s), region(r){} }; const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T); @@ -146,13 +146,15 @@ public: const MemRegion *castRegion(const MemRegion *region, QualType CastToTy); virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, - SymbolReaper& SymReaper, - llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; + SymbolReaper& SymReaper) = 0; virtual StoreRef BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0; virtual StoreRef BindDeclWithNoInit(Store store, const VarRegion *VR) = 0; + virtual bool includedInBindings(Store store, + const MemRegion *region) const = 0; + /// If the StoreManager supports it, increment the reference count of /// the specified Store object. virtual void incrementReferenceCount(Store store) {} @@ -163,7 +165,7 @@ public: virtual void decrementReferenceCount(Store store) {} typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols; - typedef llvm::SmallVector<const MemRegion *, 8> InvalidatedRegions; + typedef SmallVector<const MemRegion *, 8> InvalidatedRegions; /// invalidateRegions - Clears out the specified regions from the store, /// marking their values as unknown. Depending on the store, this may also @@ -185,19 +187,18 @@ public: /// even if they do not currently have bindings. Pass \c NULL if this /// information will not be used. virtual StoreRef invalidateRegions(Store store, - const MemRegion * const *Begin, - const MemRegion * const *End, + ArrayRef<const MemRegion *> Regions, const Expr *E, unsigned Count, InvalidatedSymbols &IS, bool invalidateGlobals, - InvalidatedRegions *Regions) = 0; + InvalidatedRegions *Invalidated) = 0; /// enterStackFrame - Let the StoreManager to do something when execution /// engine is about to execute into a callee. - virtual StoreRef enterStackFrame(const GRState *state, + virtual StoreRef enterStackFrame(const ProgramState *state, const StackFrameContext *frame); - virtual void print(Store store, llvm::raw_ostream& Out, + virtual void print(Store store, raw_ostream &Out, const char* nl, const char *sep) = 0; class BindingsHandler { @@ -217,11 +218,11 @@ protected: /// CastRetrievedVal - Used by subclasses of StoreManager to implement /// implicit casts that arise from loads from regions that are reinterpreted /// as another region. - SVal CastRetrievedVal(SVal val, const TypedRegion *region, QualType castTy, - bool performTestOnly = true); + SVal CastRetrievedVal(SVal val, const TypedValueRegion *region, + QualType castTy, bool performTestOnly = true); private: - SVal getLValueFieldOrIvar(const Decl* decl, SVal base); + SVal getLValueFieldOrIvar(const Decl *decl, SVal base); }; @@ -269,11 +270,9 @@ public: virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0; }; -// FIXME: Do we need to pass GRStateManager anymore? -StoreManager *CreateBasicStoreManager(GRStateManager& StMgr); -StoreManager *CreateRegionStoreManager(GRStateManager& StMgr); -StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr); -StoreManager *CreateFlatStoreManager(GRStateManager &StMgr); +// FIXME: Do we need to pass ProgramStateManager anymore? +StoreManager *CreateRegionStoreManager(ProgramStateManager& StMgr); +StoreManager *CreateFieldsOnlyRegionStoreManager(ProgramStateManager& StMgr); } // end GR namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h index 0662ead..d5ba003 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h @@ -23,7 +23,7 @@ namespace ento { /// locations to values. At a high-level, it represents the symbolic /// memory model. Different subclasses of StoreManager may choose /// different types to represent the locations and values. -typedef const void* Store; +typedef const void *Store; class StoreManager; @@ -44,6 +44,7 @@ public: ~StoreRef(); Store getStore() const { return store; } + const StoreManager &getStoreManager() const { return mgr; } }; }} diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h index 1f6ea3d..ae212bc 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h @@ -30,8 +30,8 @@ template <typename PP> class GenericNodeBuilder; class AnalysisManager; class ExplodedNodeSet; class ExplodedNode; -class GRState; -class GRStateManager; +class ProgramState; +class ProgramStateManager; class BlockCounter; class StmtNodeBuilder; class BranchNodeBuilder; @@ -46,11 +46,11 @@ class SubEngine { public: virtual ~SubEngine() {} - virtual const GRState* getInitialState(const LocationContext *InitLoc) = 0; + virtual const ProgramState *getInitialState(const LocationContext *InitLoc) = 0; virtual AnalysisManager &getAnalysisManager() = 0; - virtual GRStateManager &getStateManager() = 0; + virtual ProgramStateManager &getStateManager() = 0; /// Called by CoreEngine. Used to generate new successor /// nodes by processing the 'effects' of a block-level statement. @@ -64,7 +64,7 @@ public: /// Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a branch condition. - virtual void processBranch(const Stmt* Condition, const Stmt* Term, + virtual void processBranch(const Stmt *Condition, const Stmt *Term, BranchNodeBuilder& builder) = 0; /// Called by CoreEngine. Used to generate successor @@ -87,28 +87,32 @@ public: /// Called by ConstraintManager. Used to call checker-specific /// logic for handling assumptions on symbolic values. - virtual const GRState* processAssume(const GRState *state, + virtual const ProgramState *processAssume(const ProgramState *state, SVal cond, bool assumption) = 0; - /// wantsRegionChangeUpdate - Called by GRStateManager to determine if a + /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a /// region change should trigger a processRegionChanges update. - virtual bool wantsRegionChangeUpdate(const GRState* state) = 0; + virtual bool wantsRegionChangeUpdate(const ProgramState *state) = 0; - /// processRegionChanges - Called by GRStateManager whenever a change is made + /// processRegionChanges - Called by ProgramStateManager whenever a change is made /// to the store. Used to update checkers that track region values. - virtual const GRState * - processRegionChanges(const GRState *state, + virtual const ProgramState * + processRegionChanges(const ProgramState *state, const StoreManager::InvalidatedSymbols *invalidated, - const MemRegion* const *Begin, - const MemRegion* const *End) = 0; + ArrayRef<const MemRegion *> ExplicitRegions, + ArrayRef<const MemRegion *> Regions) = 0; - inline const GRState * - processRegionChange(const GRState* state, + inline const ProgramState * + processRegionChange(const ProgramState *state, const MemRegion* MR) { - return processRegionChanges(state, 0, &MR, &MR+1); + return processRegionChanges(state, 0, MR, MR); } + /// printState - Called by ProgramStateManager to print checker-specific data. + virtual void printState(raw_ostream &Out, const ProgramState *State, + const char *NL, const char *Sep) = 0; + /// Called by CoreEngine when the analysis worklist is either empty or the // maximum number of analysis steps have been reached. virtual void processEndWorklist(bool hasWorkRemaining) = 0; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index ad173bb..0d6e18e 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -18,13 +18,15 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/Analysis/AnalysisContext.h" +#include "clang/Basic/LLVM.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" #include "llvm/Support/DataTypes.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/DenseMap.h" namespace llvm { class BumpPtrAllocator; -class raw_ostream; } namespace clang { @@ -35,15 +37,15 @@ namespace ento { class BasicValueFactory; class MemRegion; class SubRegion; - class TypedRegion; + class TypedValueRegion; class VarRegion; class SymExpr : public llvm::FoldingSetNode { public: - enum Kind { BEGIN_SYMBOLS, - RegionValueKind, ConjuredKind, DerivedKind, ExtentKind, + enum Kind { RegionValueKind, ConjuredKind, DerivedKind, ExtentKind, MetadataKind, - END_SYMBOLS, + BEGIN_SYMBOLS = RegionValueKind, + END_SYMBOLS = MetadataKind, SymIntKind, SymSymKind }; private: Kind K; @@ -58,7 +60,7 @@ public: void dump() const; - virtual void dumpToStream(llvm::raw_ostream &os) const = 0; + virtual void dumpToStream(raw_ostream &os) const = 0; virtual QualType getType(ASTContext&) const = 0; virtual void Profile(llvm::FoldingSetNodeID& profile) = 0; @@ -82,25 +84,26 @@ public: SymbolID getSymbolID() const { return Sym; } // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr *SE) { Kind k = SE->getKind(); - return k > BEGIN_SYMBOLS && k < END_SYMBOLS; + return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS; } }; typedef const SymbolData* SymbolRef; +typedef llvm::SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy; -// A symbol representing the value of a MemRegion. +/// A symbol representing the value of a MemRegion. class SymbolRegionValue : public SymbolData { - const TypedRegion *R; + const TypedValueRegion *R; public: - SymbolRegionValue(SymbolID sym, const TypedRegion *r) + SymbolRegionValue(SymbolID sym, const TypedValueRegion *r) : SymbolData(RegionValueKind, sym), R(r) {} - const TypedRegion* getRegion() const { return R; } + const TypedValueRegion* getRegion() const { return R; } - static void Profile(llvm::FoldingSetNodeID& profile, const TypedRegion* R) { + static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) { profile.AddInteger((unsigned) RegionValueKind); profile.AddPointer(R); } @@ -109,39 +112,39 @@ public: Profile(profile, R); } - void dumpToStream(llvm::raw_ostream &os) const; + void dumpToStream(raw_ostream &os) const; QualType getType(ASTContext&) const; // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr *SE) { return SE->getKind() == RegionValueKind; } }; -// A symbol representing the result of an expression. +/// A symbol representing the result of an expression. class SymbolConjured : public SymbolData { - const Stmt* S; + const Stmt *S; QualType T; unsigned Count; - const void* SymbolTag; + const void *SymbolTag; public: - SymbolConjured(SymbolID sym, const Stmt* s, QualType t, unsigned count, - const void* symbolTag) + SymbolConjured(SymbolID sym, const Stmt *s, QualType t, unsigned count, + const void *symbolTag) : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count), SymbolTag(symbolTag) {} - const Stmt* getStmt() const { return S; } + const Stmt *getStmt() const { return S; } unsigned getCount() const { return Count; } - const void* getTag() const { return SymbolTag; } + const void *getTag() const { return SymbolTag; } QualType getType(ASTContext&) const; - void dumpToStream(llvm::raw_ostream &os) const; + void dumpToStream(raw_ostream &os) const; - static void Profile(llvm::FoldingSetNodeID& profile, const Stmt* S, - QualType T, unsigned Count, const void* SymbolTag) { + static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S, + QualType T, unsigned Count, const void *SymbolTag) { profile.AddInteger((unsigned) ConjuredKind); profile.AddPointer(S); profile.Add(T); @@ -154,30 +157,30 @@ public: } // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr *SE) { return SE->getKind() == ConjuredKind; } }; -// A symbol representing the value of a MemRegion whose parent region has -// symbolic value. +/// A symbol representing the value of a MemRegion whose parent region has +/// symbolic value. class SymbolDerived : public SymbolData { SymbolRef parentSymbol; - const TypedRegion *R; + const TypedValueRegion *R; public: - SymbolDerived(SymbolID sym, SymbolRef parent, const TypedRegion *r) + SymbolDerived(SymbolID sym, SymbolRef parent, const TypedValueRegion *r) : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {} SymbolRef getParentSymbol() const { return parentSymbol; } - const TypedRegion *getRegion() const { return R; } + const TypedValueRegion *getRegion() const { return R; } QualType getType(ASTContext&) const; - void dumpToStream(llvm::raw_ostream &os) const; + void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, - const TypedRegion *r) { + const TypedValueRegion *r) { profile.AddInteger((unsigned) DerivedKind); profile.AddPointer(r); profile.AddPointer(parent); @@ -188,7 +191,7 @@ public: } // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr *SE) { return SE->getKind() == DerivedKind; } }; @@ -207,7 +210,7 @@ public: QualType getType(ASTContext&) const; - void dumpToStream(llvm::raw_ostream &os) const; + void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) { profile.AddInteger((unsigned) ExtentKind); @@ -219,7 +222,7 @@ public: } // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr *SE) { return SE->getKind() == ExtentKind; } }; @@ -230,23 +233,23 @@ public: /// Intended for use by checkers. class SymbolMetadata : public SymbolData { const MemRegion* R; - const Stmt* S; + const Stmt *S; QualType T; unsigned Count; - const void* Tag; + const void *Tag; public: - SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt* s, QualType t, - unsigned count, const void* tag) + SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t, + unsigned count, const void *tag) : SymbolData(MetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {} const MemRegion *getRegion() const { return R; } - const Stmt* getStmt() const { return S; } + const Stmt *getStmt() const { return S; } unsigned getCount() const { return Count; } - const void* getTag() const { return Tag; } + const void *getTag() const { return Tag; } QualType getType(ASTContext&) const; - void dumpToStream(llvm::raw_ostream &os) const; + void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R, const Stmt *S, QualType T, unsigned Count, @@ -264,12 +267,12 @@ public: } // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr *SE) { return SE->getKind() == MetadataKind; } }; -// SymIntExpr - Represents symbolic expression like 'x' + 3. +/// SymIntExpr - Represents symbolic expression like 'x' + 3. class SymIntExpr : public SymExpr { const SymExpr *LHS; BinaryOperator::Opcode Op; @@ -283,11 +286,11 @@ public: // FIXME: We probably need to make this out-of-line to avoid redundant // generation of virtual functions. - QualType getType(ASTContext& C) const { return T; } + QualType getType(ASTContext &C) const { return T; } BinaryOperator::Opcode getOpcode() const { return Op; } - void dumpToStream(llvm::raw_ostream &os) const; + void dumpToStream(raw_ostream &os) const; const SymExpr *getLHS() const { return LHS; } const llvm::APSInt &getRHS() const { return RHS; } @@ -307,12 +310,12 @@ public: } // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr *SE) { return SE->getKind() == SymIntKind; } }; -// SymSymExpr - Represents symbolic expression like 'x' + 'y'. +/// SymSymExpr - Represents symbolic expression like 'x' + 'y'. class SymSymExpr : public SymExpr { const SymExpr *LHS; BinaryOperator::Opcode Op; @@ -330,9 +333,9 @@ public: // FIXME: We probably need to make this out-of-line to avoid redundant // generation of virtual functions. - QualType getType(ASTContext& C) const { return T; } + QualType getType(ASTContext &C) const { return T; } - void dumpToStream(llvm::raw_ostream &os) const; + void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) { @@ -348,48 +351,58 @@ public: } // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr *SE) { return SE->getKind() == SymSymKind; } }; class SymbolManager { typedef llvm::FoldingSet<SymExpr> DataSetTy; + typedef llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy*> SymbolDependTy; + DataSetTy DataSet; + /// Stores the extra dependencies between symbols: the data should be kept + /// alive as long as the key is live. + SymbolDependTy SymbolDependencies; unsigned SymbolCounter; llvm::BumpPtrAllocator& BPAlloc; BasicValueFactory &BV; - ASTContext& Ctx; + ASTContext &Ctx; public: - SymbolManager(ASTContext& ctx, BasicValueFactory &bv, + SymbolManager(ASTContext &ctx, BasicValueFactory &bv, llvm::BumpPtrAllocator& bpalloc) - : SymbolCounter(0), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} + : SymbolDependencies(16), SymbolCounter(0), + BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} ~SymbolManager(); static bool canSymbolicate(QualType T); - /// Make a unique symbol for MemRegion R according to its kind. - const SymbolRegionValue* getRegionValueSymbol(const TypedRegion* R); + /// \brief Make a unique symbol for MemRegion R according to its kind. + const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R); - const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T, + const SymbolConjured* getConjuredSymbol(const Stmt *E, QualType T, unsigned VisitCount, - const void* SymbolTag = 0); + const void *SymbolTag = 0); - const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount, - const void* SymbolTag = 0) { + const SymbolConjured* getConjuredSymbol(const Expr *E, unsigned VisitCount, + const void *SymbolTag = 0) { return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag); } const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol, - const TypedRegion *R); + const TypedValueRegion *R); const SymbolExtent *getExtentSymbol(const SubRegion *R); - const SymbolMetadata* getMetadataSymbol(const MemRegion* R, const Stmt* S, + /// \brief Creates a metadata symbol associated with a specific region. + /// + /// VisitCount can be used to differentiate regions corresponding to + /// different loop iterations, thus, making the symbol path-dependent. + const SymbolMetadata* getMetadataSymbol(const MemRegion* R, const Stmt *S, QualType T, unsigned VisitCount, - const void* SymbolTag = 0); + const void *SymbolTag = 0); const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType t); @@ -406,23 +419,43 @@ public: return SE->getType(Ctx); } + /// \brief Add artificial symbol dependency. + /// + /// The dependent symbol should stay alive as long as the primary is alive. + void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent); + + const SymbolRefSmallVectorTy *getDependentSymbols(const SymbolRef Primary); + ASTContext &getContext() { return Ctx; } BasicValueFactory &getBasicVals() { return BV; } }; class SymbolReaper { - typedef llvm::DenseSet<SymbolRef> SetTy; + enum SymbolStatus { + NotProcessed, + HaveMarkedDependents + }; - SetTy TheLiving; - SetTy MetadataInUse; - SetTy TheDead; + typedef llvm::DenseSet<SymbolRef> SymbolSetTy; + typedef llvm::DenseMap<SymbolRef, SymbolStatus> SymbolMapTy; + typedef llvm::DenseSet<const MemRegion *> RegionSetTy; + + SymbolMapTy TheLiving; + SymbolSetTy MetadataInUse; + SymbolSetTy TheDead; + + RegionSetTy RegionRoots; + const LocationContext *LCtx; const Stmt *Loc; SymbolManager& SymMgr; + StoreRef reapedStore; + llvm::DenseMap<const MemRegion *, unsigned> includedRegionCache; public: - SymbolReaper(const LocationContext *ctx, const Stmt *s, SymbolManager& symmgr) - : LCtx(ctx), Loc(s), SymMgr(symmgr) {} + SymbolReaper(const LocationContext *ctx, const Stmt *s, SymbolManager& symmgr, + StoreManager &storeMgr) + : LCtx(ctx), Loc(s), SymMgr(symmgr), reapedStore(0, storeMgr) {} ~SymbolReaper() {} @@ -430,48 +463,71 @@ public: const Stmt *getCurrentStatement() const { return Loc; } bool isLive(SymbolRef sym); + bool isLiveRegion(const MemRegion *region); bool isLive(const Stmt *ExprVal) const; - bool isLive(const VarRegion *VR) const; + bool isLive(const VarRegion *VR, bool includeStoreBindings = false) const; - // markLive - Unconditionally marks a symbol as live. This should never be - // used by checkers, only by the state infrastructure such as the store and - // environment. Checkers should instead use metadata symbols and markInUse. + /// \brief Unconditionally marks a symbol as live. + /// + /// This should never be + /// used by checkers, only by the state infrastructure such as the store and + /// environment. Checkers should instead use metadata symbols and markInUse. void markLive(SymbolRef sym); - // markInUse - Marks a symbol as important to a checker. For metadata symbols, - // this will keep the symbol alive as long as its associated region is also - // live. For other symbols, this has no effect; checkers are not permitted - // to influence the life of other symbols. This should be used before any - // symbol marking has occurred, i.e. in the MarkLiveSymbols callback. + /// \brief Marks a symbol as important to a checker. + /// + /// For metadata symbols, + /// this will keep the symbol alive as long as its associated region is also + /// live. For other symbols, this has no effect; checkers are not permitted + /// to influence the life of other symbols. This should be used before any + /// symbol marking has occurred, i.e. in the MarkLiveSymbols callback. void markInUse(SymbolRef sym); - // maybeDead - If a symbol is known to be live, marks the symbol as live. - // Otherwise, if the symbol cannot be proven live, it is marked as dead. - // Returns true if the symbol is dead, false if live. + /// \brief If a symbol is known to be live, marks the symbol as live. + /// + /// Otherwise, if the symbol cannot be proven live, it is marked as dead. + /// Returns true if the symbol is dead, false if live. bool maybeDead(SymbolRef sym); - typedef SetTy::const_iterator dead_iterator; + typedef SymbolSetTy::const_iterator dead_iterator; dead_iterator dead_begin() const { return TheDead.begin(); } dead_iterator dead_end() const { return TheDead.end(); } bool hasDeadSymbols() const { return !TheDead.empty(); } - - /// isDead - Returns whether or not a symbol has been confirmed dead. This - /// should only be called once all marking of dead symbols has completed. - /// (For checkers, this means only in the evalDeadSymbols callback.) + + typedef RegionSetTy::const_iterator region_iterator; + region_iterator region_begin() const { return RegionRoots.begin(); } + region_iterator region_end() const { return RegionRoots.end(); } + + /// \brief Returns whether or not a symbol has been confirmed dead. + /// + /// This should only be called once all marking of dead symbols has completed. + /// (For checkers, this means only in the evalDeadSymbols callback.) bool isDead(SymbolRef sym) const { return TheDead.count(sym); } + + void markLive(const MemRegion *region); + + /// \brief Set to the value of the symbolic store after + /// StoreManager::removeDeadBindings has been called. + void setReapedStore(StoreRef st) { reapedStore = st; } + +private: + /// Mark the symbols dependent on the input symbol as live. + void markDependentsLive(SymbolRef sym); }; class SymbolVisitor { public: - // VisitSymbol - A visitor method invoked by - // GRStateManager::scanReachableSymbols. The method returns \c true if - // symbols should continue be scanned and \c false otherwise. + /// \brief A visitor method invoked by ProgramStateManager::scanReachableSymbols. + /// + /// The method returns \c true if symbols should continue be scanned and \c + /// false otherwise. virtual bool VisitSymbol(SymbolRef sym) = 0; + virtual bool VisitMemRegion(const MemRegion *region) { return true; } virtual ~SymbolVisitor(); }; @@ -480,7 +536,7 @@ public: } // end clang namespace namespace llvm { -static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os, +static inline raw_ostream &operator<<(raw_ostream &os, const clang::ento::SymExpr *SE) { SE->dumpToStream(os); return os; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h deleted file mode 100644 index 23ed2be..0000000 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h +++ /dev/null @@ -1,93 +0,0 @@ -//== TransferFuncs.h - Path-Sens. Transfer Functions Interface ---*- C++ -*--=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines TransferFuncs, which provides a base-class that -// defines an interface for transfer functions used by ExprEngine. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_GR_TRANSFERFUNCS -#define LLVM_CLANG_GR_TRANSFERFUNCS - -#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" -#include <vector> - -namespace clang { -class ObjCMessageExpr; - -namespace ento { -class ExplodedNode; -class ExplodedNodeSet; -class EndOfFunctionNodeBuilder; -class ExprEngine; -class StmtNodeBuilder; -class StmtNodeBuilderRef; - -class TransferFuncs { -public: - TransferFuncs() {} - virtual ~TransferFuncs() {} - - virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {} - virtual void RegisterChecks(ExprEngine& Eng) {} - - - // Calls. - - virtual void evalCall(ExplodedNodeSet& Dst, - ExprEngine& Engine, - StmtNodeBuilder& Builder, - const CallExpr* CE, SVal L, - ExplodedNode* Pred) {} - - virtual void evalObjCMessage(ExplodedNodeSet& Dst, - ExprEngine& Engine, - StmtNodeBuilder& Builder, - ObjCMessage msg, - ExplodedNode* Pred, - const GRState *state) {} - - // Stores. - - virtual void evalBind(StmtNodeBuilderRef& B, SVal location, SVal val) {} - - // End-of-path and dead symbol notification. - - virtual void evalEndPath(ExprEngine& Engine, - EndOfFunctionNodeBuilder& Builder) {} - - - virtual void evalDeadSymbols(ExplodedNodeSet& Dst, - ExprEngine& Engine, - StmtNodeBuilder& Builder, - ExplodedNode* Pred, - const GRState* state, - SymbolReaper& SymReaper) {} - - // Return statements. - virtual void evalReturn(ExplodedNodeSet& Dst, - ExprEngine& Engine, - StmtNodeBuilder& Builder, - const ReturnStmt* S, - ExplodedNode* Pred) {} - - // Assumptions. - virtual const GRState* evalAssume(const GRState *state, - SVal Cond, bool Assumption) { - return state; - } -}; - -} // end GR namespace - -} // end clang namespace - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h index 6bc9fe5..fa34075 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h @@ -28,20 +28,20 @@ class ExplodedNode; class ExplodedNodeImpl; class WorkListUnit { - ExplodedNode* node; + ExplodedNode *node; BlockCounter counter; - const CFGBlock* block; + const CFGBlock *block; unsigned blockIdx; // This is the index of the next statement. public: - WorkListUnit(ExplodedNode* N, BlockCounter C, - const CFGBlock* B, unsigned idx) + WorkListUnit(ExplodedNode *N, BlockCounter C, + const CFGBlock *B, unsigned idx) : node(N), counter(C), block(B), blockIdx(idx) {} - explicit WorkListUnit(ExplodedNode* N, BlockCounter C) + explicit WorkListUnit(ExplodedNode *N, BlockCounter C) : node(N), counter(C), block(NULL), diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h index 9d6298f..492edd4 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h @@ -1,4 +1,4 @@ -//===-- CheckerRegistration.h - Checker Registration Function-------*- C++ -*-===// +//===-- CheckerRegistration.h - Checker Registration Function ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,17 +10,21 @@ #ifndef LLVM_CLANG_SA_FRONTEND_CHECKERREGISTRATION_H #define LLVM_CLANG_SA_FRONTEND_CHECKERREGISTRATION_H +#include "clang/Basic/LLVM.h" +#include <string> + namespace clang { class AnalyzerOptions; class LangOptions; - class Diagnostic; + class DiagnosticsEngine; namespace ento { class CheckerManager; -CheckerManager *registerCheckers(const AnalyzerOptions &opts, - const LangOptions &langOpts, - Diagnostic &diags); +CheckerManager *createCheckerManager(const AnalyzerOptions &opts, + const LangOptions &langOpts, + ArrayRef<std::string> plugins, + DiagnosticsEngine &diags); } // end ento namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index f014181..838ac92 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -23,10 +23,10 @@ namespace ento { class AnalysisAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); + StringRef InFile); }; -void printCheckerHelp(llvm::raw_ostream &OS); +void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins); } // end GR namespace |